]> O.S.I.I.S - jp/crow.git/commitdiff
TG recursive lock check, IObsList clear evt, sample Editor xml syntax, command IList...
authorJean-Philippe Bruyère <jp_bruyere@hotmail.com>
Fri, 9 Apr 2021 02:51:37 +0000 (04:51 +0200)
committerJean-Philippe Bruyère <jp_bruyere@hotmail.com>
Fri, 9 Apr 2021 02:51:37 +0000 (04:51 +0200)
20 files changed:
Crow/src/Command.cs
Crow/src/DebugUtils/DbgEvent.cs
Crow/src/DebugUtils/DbgEvtType.cs
Crow/src/IML/CompilerServices.cs
Crow/src/IObservableList.cs
Crow/src/Text/SpanCharReader.cs
Crow/src/Widgets/Popper.cs
Crow/src/Widgets/ScrollingObject.cs
Crow/src/Widgets/Slider.cs
Crow/src/Widgets/TemplatedGroup.cs
Samples/DebugLogAnalyzer/src/DebugInterface.cs
Samples/DebugLogAnalyzer/src/DebugInterfaceWidget.cs
Samples/DebugLogAnalyzer/src/Editor.cs [deleted file]
Samples/Directory.Build.props
Samples/ShowCase/Editor.cs [deleted file]
Samples/ShowCase/ui/showcase.crow
Samples/common/Editor.cs [new file with mode: 0644]
Samples/common/SampleBase.cs
Samples/common/ui/Interfaces/Experimental/multiColorPick2.crow
Samples/common/ui/templates/ColorPicker.template

index 51f0bc0a804ed3fa71fe821b261ed7680dbae208..a185e1ad7735da354a83fc49640583493bcf6ad1 100644 (file)
@@ -7,6 +7,7 @@ using System;
 using System.ComponentModel;
 using System.Threading.Tasks;
 using System.Collections;
+using System.Collections.Generic;
 
 namespace Crow {
        public abstract class CommandBase : IValueChange {
@@ -20,7 +21,7 @@ namespace Crow {
                
                #region CTOR
                protected CommandBase() {}
-               protected CommandBase (string _caption, string _icon)
+               protected CommandBase (string _caption, string _icon = null)
                {
                        caption = _caption;                     
                        icon = _icon;
@@ -60,7 +61,7 @@ namespace Crow {
                        NotifyValueChanged ("Caption", caption);
                }
        }
-       public class CommandGroup : CommandBase, IEnumerable
+       public class CommandGroup : CommandBase, IEnumerable, IList<CommandBase>
        {
                public ObservableList<CommandBase> Commands = new ObservableList<CommandBase>();
 
@@ -69,11 +70,44 @@ namespace Crow {
                        base (caption, icon) {
                        Commands.AddRange (commands);
                }
+               public CommandGroup (string caption, params CommandBase[] commands) :
+                       base (caption) {
+                       Commands.AddRange (commands);
+               }
                public CommandGroup (params CommandBase[] commands) {
                        Commands.AddRange (commands);
                }
 
+               
+               public int Count => Commands.Count;
+
+               public bool IsReadOnly => false;
+
+               public CommandBase this[int index] { get => Commands[index]; set => Commands[index] = value; }
+
                public IEnumerator GetEnumerator() => Commands.GetEnumerator ();
+
+               public int IndexOf(CommandBase item) => Commands.IndexOf (item);
+
+               public void Insert(int index, CommandBase item) => Commands.Insert(index, item);
+
+               public void RemoveAt(int index) => Commands.RemoveAt(index);
+
+               public void Add(CommandBase item) => Commands.Add (item);
+
+               public void Clear() => Commands.Clear();
+
+               public bool Contains(CommandBase item) => Commands.Contains (item);
+
+               public void CopyTo(CommandBase[] array, int arrayIndex) => Commands.CopyTo (array, arrayIndex);         
+
+               public bool Remove(CommandBase item) {                  
+                       Commands.Remove (item);
+                       return true;
+               }
+
+               IEnumerator<CommandBase> IEnumerable<CommandBase>.GetEnumerator()
+                       => Commands.GetEnumerator();
        }
 
 
index a9969716db87d621752fc1f38ab9465e9eb1a09b..1c0b79af1b3ab35cf11ef1ef59654e6d09480a4c 100644 (file)
@@ -102,8 +102,10 @@ namespace Crow.DebugLogger
                                case DbgEvtType.Update:
                                        return Colors.Grey;
                                case DbgEvtType.IFaceLoad:
-                                       return Colors.Teal;
+                                       return Colors.Teal;                             
                                default:
+                                       if (type.HasFlag(DbgEvtType.Mouse))
+                                               return Colors.DeepPink;
                                        return Colors.White;
                                }
                        }
index 24fd99fa8d6d063eae34128ae528a023237373fb..99cf1539726dfad57639ebc5e46031891c757907 100644 (file)
@@ -25,6 +25,7 @@ namespace Crow
                Override                                                = 0x020000,
                TemplatedGroup                                  = 0x010000,
                Dispose                                                 = 0x008000,
+               Mouse                                                   = 0x004000,
 
                Update                                                  = IFace | 0x004000,
                ProcessLayouting                                = IFace | Update | Lock | Layouting,
@@ -32,8 +33,8 @@ namespace Crow
                ProcessDrawing                                  = IFace | Update | Lock | Drawing,
                IFaceLoad                                               = IFace | 0x01,
                IFaceInit                                               = IFace | 0x02,
-               CreateITor                                              = IFace | 0x04,
-               IFaceReloadTheme                                = IFace | 0x08,
+               CreateITor                                              = IFace | 0x03,
+               IFaceReloadTheme                                = IFace | 0x04,
 
                HoverWidget                                             = Focus | Widget | 0x01,
                FocusedWidget                                   = Focus | Widget | 0x02,
@@ -43,33 +44,33 @@ namespace Crow
                //10 nth bit set for graphic obj
                GOClassCreation                                 = Widget | 0x01,
                GOInitialization                                = Widget | 0x02,
-               GORegisterForGraphicUpdate              = Widget | 0x04,
-               GOEnqueueForRepaint                             = Widget | 0x08,
-               GONewDataSource                                 = Widget | 0x10,
-               GONewParent                                             = Widget | 0x20,
-               GONewLogicalParent                              = Widget | 0x40,
-               GOAddChild                                              = Widget | 0x80,
+               GORegisterForGraphicUpdate              = Widget | 0x03,
+               GOEnqueueForRepaint                             = Widget | 0x04,
+               GONewDataSource                                 = Widget | 0x05,
+               GONewParent                                             = Widget | 0x06,
+               GONewLogicalParent                              = Widget | 0x07,
+               GOAddChild                                              = Widget | 0x08,
 
-               GOSearchLargestChild                    = Widget | 0x09,
-               GOSearchTallestChild                    = Widget | 0x0A,
-               GORegisterForRedraw                             = Widget | 0x0B,
-               GOComputeChildrenPositions              = Widget | 0x0C,
-               GOOnChildLayoutChange                   = Widget | 0x0D,
+               GOMeasure                                               = Widget | 0x09,
+               GOSearchLargestChild                    = Widget | 0x0A,
+               GOSearchTallestChild                    = Widget | 0x0B,
+               GORegisterForRedraw                             = Widget | 0x0C,
+               GOComputeChildrenPositions              = Widget | 0x0D,
+               GOOnChildLayoutChange                   = Widget | 0x0E,
 
-               AlreadyDisposed                                 = Dispose | Widget | Error | 0x01,
-               DisposedByGC                                    = Dispose | Widget | Error | 0x02,
-               Disposing                                               = Dispose | Widget | 0x01,
+               AlreadyDisposed                                 = Widget | Dispose | Error | 0x01,
+               DisposedByGC                                    = Widget | Dispose | Error | 0x02,
+               Disposing                                               = Widget | Dispose | 0x01,
 
-               GOClippingRegistration                  = Clipping | Widget | 0x01,
-               GORegisterClip                                  = Clipping | Widget | 0x02,
-               GORegisterLayouting                     = Layouting | Widget | 0x01,
-               GOProcessLayouting                              = Layouting | Widget | 0x02,
-               GOProcessLayoutingWithNoParent  = Layouting | Widget | Warning | 0x01,
-               GOMeasure                                               = Widget | 0x03,
-               GODraw                                                  = Drawing | Widget | 0x01,
-               GORecreateCache                                 = Drawing | Widget | 0x02,
-               GOUpdateCache                                   = Drawing | Widget | 0x03,
-               GOPaint                                                 = Drawing | Widget | 0x04,
+               GOClippingRegistration                  = Widget | Clipping | 0x01,
+               GORegisterClip                                  = Widget | Clipping | 0x02,
+               GORegisterLayouting                     = Widget | Layouting | 0x01,
+               GOProcessLayouting                              = Widget | Layouting | 0x02,
+               GOProcessLayoutingWithNoParent  = Widget | Layouting | Warning | 0x01,
+               GODraw                                                  = Widget | Drawing | 0x01,
+               GORecreateCache                                 = Widget | Drawing | 0x02,
+               GOUpdateCache                                   = Widget | Drawing | 0x03,
+               GOPaint                                                 = Widget | Drawing | 0x04,
 
                GOLockUpdate                                    = Widget | Lock | 0x01,
                GOLockClipping                                  = Widget | Lock | 0x02,
@@ -79,6 +80,13 @@ namespace Crow
                TGLoadingThread                                 = Widget | TemplatedGroup | 0x01,
                TGCancelLoadingThread                   = Widget | TemplatedGroup | 0x02,
 
+               MouseDown                                               = IFace | Mouse | 0x01,
+               MouseUp                                                 = IFace | Mouse | 0x02,
+               MouseMove                                               = IFace | Mouse | 0x03,
+               GOMouseDown                                             = Widget | Mouse | 0x01,
+               GOMouseUp                                               = Widget | Mouse | 0x02,
+               GOMouseMove                                             = Widget | Mouse | 0x03,
+
                All = 0x7FFFFF00
        }
 }
\ No newline at end of file
index 224338fb10ea86ce1707a9aad531436fb72a1cbb..11779999750d8c0f495ddf150bd98bc90c1d45a3 100644 (file)
@@ -136,6 +136,7 @@ namespace Crow.IML
                        il.Emit (OpCodes.Stfld, miSetCurIface);
                }
 
+               //TODO: should be able to handle struct in default values.
                public static void EmitSetValue(ILGenerator il, PropertyInfo pi, object val){
                        il.Emit (OpCodes.Ldloc_0);
 
index 311a21a3834d1f7336ab056085a9976637eaecea..4fab1e81a8f6e1c3b727f7e521e5e9cb39294736 100644 (file)
@@ -10,6 +10,7 @@ namespace Crow
                event EventHandler<ListChangedEventArg> ListAdd;
                event EventHandler<ListChangedEventArg> ListRemove;
                event EventHandler<ListChangedEventArg> ListEdit;
+               event EventHandler<ListChangedEventArg> ListClear;
 
                void Insert ();
                void Remove ();
index bab2c4b7c8c942507f30a3bea72e28bb6d84c539..6c6fcde0cb56d454b36680ca476065f58102ca04 100644 (file)
@@ -5,7 +5,7 @@ using System;
 using System.Collections.Generic;
 using System.Text;
 
-namespace Crow.src.Text
+namespace Crow.Text
 {
     public ref struct SpanCharReader
     {
@@ -21,9 +21,82 @@ namespace Crow.src.Text
 
         public void Seek (int position) => curPos = position;
 
-        public Char Peak () => buffer[curPos];
+        public Char Peak => buffer[curPos];
         public Char Read () => buffer[curPos++];
+               public bool TryRead (out char c) {
+                       if (EndOfSpan) {
+                               c = default;
+                               return false;
+                       }
+                       c = Read();
+                       return true;
+               }
+               public bool TryRead (char c) => EndOfSpan ? false : Read() == c;
+                                       
+               public ReadOnlySpan<char> Read (int length) => buffer.Slice (curPos += length, length);
+               public void Advance (int increment = 1) => curPos += increment;
+               public bool TryAdvance (int increment = 1) {                    
+                       curPos += increment;
+                       return curPos < buffer.Length;
+               }
+               
+               public bool TryReadUntil (ReadOnlySpan<char> str, StringComparison comparison = StringComparison.Ordinal) {
+                       int startPos = curPos;
+                       while (curPos < buffer.Length - str.Length) {
+                               if (buffer[curPos] == str[0] && buffer.Slice(curPos + 1, str.Length - 1).Equals(str.Slice (1), comparison))
+                                       return true;
+                               curPos++;                       
+                       }
+                       return false;
+               }
+               public bool TryReadUntil (char c) {
+                       int startPos = curPos;
+                       while (curPos < buffer.Length && buffer[curPos] != c)
+                               curPos++;                       
+                       return curPos < buffer.Length;
+               }
+               public bool TryRead (int length, out ReadOnlySpan<char> str) {
+                       if (length < buffer.Length) {
+                               str = buffer.Slice (curPos += length, length);
+                               return true;
+                       }
+                       str = default;
+                       return false;
+               }
+               
+               /// <summary>
+               /// Try read expected string and advance reader position in any case
+               /// </summary>
+               /// <param name="expectedString">expected string</param>
+               /// <param name="comparison">comparison type</param>
+               /// <returns>true if expected string is found</returns>
+               public bool TryRead (ReadOnlySpan<char> expectedString, StringComparison comparison = StringComparison.OrdinalIgnoreCase) {
+                       if (buffer.Length < curPos + expectedString.Length) {
+                               curPos = buffer.Length;
+                               return false;
+                       }
+                       bool res = buffer.Slice(curPos, expectedString.Length).Equals (expectedString, comparison);
+                       curPos += expectedString.Length;
+                       return res;
+               }
+               public bool TryPeak (ReadOnlySpan<char> expectedString, StringComparison comparison = StringComparison.Ordinal) =>
+                        (buffer.Length < curPos + expectedString.Length)? false :
+                                               buffer.Slice(curPos, expectedString.Length).Equals (expectedString, comparison);                        
+                       
         public ReadOnlySpan<char> Get (int fromPosition) => buffer.Slice (fromPosition, curPos - fromPosition);
         public bool EndOfSpan => curPos >= buffer.Length;
+               public bool TryPeak (char c) => !EndOfSpan && Peak == c;
+               public bool TryPeak (ref char c) {
+                       if (EndOfSpan)
+                               return false;
+                       c = buffer[curPos];
+                       return true;
+               }
+               public bool IsNextCharIn (params char[] chars) {
+                       for (int i = 0; i < chars.Length; i++)
+                               if (chars[i] == buffer[curPos])
+                                       return true;
+                       return false;
+               }
     }
 }
index e99bbcbc0304e4503b0e6a42600d2018c1897bcb..3e2f37cfb07cf32c26b4eb184b94caeedd188c62 100644 (file)
@@ -166,8 +166,9 @@ namespace Crow
                #region GraphicObject overrides
                public override void onMouseLeave (object sender, MouseMoveEventArgs e)
                {
-                       base.onMouseLeave (this, e);
                        IsPopped = false;
+                       e.Handled = true;
+                       base.onMouseLeave (this, e);
                }
                public override bool MouseIsIn (Point m)
                {                       
index 3173996d77eec94797724195ef65c0d225a27bc4..07750bab599f4b9538d144e49d9832ac8cd685b5 100644 (file)
@@ -52,7 +52,7 @@ namespace Crow
                /// <summary> Vertical Scrolling Position </summary>
                [DefaultValue(0)]
                public virtual int ScrollY {
-                       get { return scrollY; }
+                       get => scrollY;
                        set {
                                if (scrollY == value)
                                        return;
@@ -75,7 +75,7 @@ namespace Crow
                /// <summary> Horizontal Scrolling maximum value </summary>
                [DefaultValue(0)]
                public virtual int MaxScrollX {
-                       get { return maxScrollX; }
+                       get => maxScrollX;
                        set {
                                if (maxScrollX == value)
                                        return;
@@ -92,7 +92,7 @@ namespace Crow
                /// <summary> Vertical Scrolling maximum value </summary>
                [DefaultValue(0)]
                public virtual int MaxScrollY {
-                       get { return maxScrollY; }
+                       get => maxScrollY;
                        set {
                                if (maxScrollY == value)
                                        return;
@@ -109,7 +109,7 @@ namespace Crow
                /// <summary> Mouse Wheel Scrolling multiplier </summary>
                [DefaultValue(1)]
                public virtual int MouseWheelSpeed {
-                       get { return mouseWheelSpeed; }
+                       get => mouseWheelSpeed;
                        set {
                                if (mouseWheelSpeed == value)
                                        return;
index ca4089ec74a94d193872721da29f52335f80c0b8..dd977128ae23bcff03296928761738e965ccfdc4 100644 (file)
@@ -190,9 +190,9 @@ namespace Crow
                                        double tmp = mouseDownInitValue + (double)m.Y * unit;
                                        tmp -= tmp % SmallIncrement;
                                        Value = tmp;
-                               }
-                               e.Handled = true;
+                               }                               
                        }
+                       e.Handled = true;
                        
                        base.onMouseMove (sender, e);
                }
index 37d560f339dc5e66e0d2dbcad7984874b1a7708a..d41326727d126ca119c607715f702fd45f85a03a 100644 (file)
@@ -65,7 +65,7 @@ namespace Crow {
                /// Keep track of expanded subnodes and closed time to unload
                /// </summary>
                //Dictionary<GraphicObject, Stopwatch> nodes = new Dictionary<GraphicObject, Stopwatch>();
-               internal List<Widget> nodes = new List<Widget>();
+               internal List<Widget> nodes = new List<Widget>();//TODO:close time tracking
                /// <summary>
                /// Item templates file path, on disk or embedded.
                /// 
@@ -157,6 +157,8 @@ namespace Crow {
                                        ol.ListAdd -= Ol_ListAdd;
                                        ol.ListRemove -= Ol_ListRemove;
                                        ol.ListEdit -= Ol_ListEdit;
+                                       ol.ListClear -= Ol_ListClear;
+                                       
                                }
 
                                data = value;
@@ -166,6 +168,7 @@ namespace Crow {
                                        ol.ListAdd += Ol_ListAdd;
                                        ol.ListRemove += Ol_ListRemove;
                                        ol.ListEdit += Ol_ListEdit;
+                                       ol.ListClear += Ol_ListClear;
                                }
 
                                NotifyValueChangedAuto (data);
@@ -222,6 +225,16 @@ namespace Crow {
                                itemsContainer.Children [e.Index].DataSource = e.Element;
 
                }
+               void Ol_ListClear (object sender, ListChangedEventArg e) {
+                       cancelLoadingThread ();                 
+                       if (this.isPaged) {
+                               throw new NotImplementedException ();
+                       } else {
+                               lock (IFace.UpdateMutex)
+                                       itemsContainer.ClearChildren ();
+                       }
+
+               }
 
 
                protected void raiseSelectedItemChanged(){
@@ -334,24 +347,30 @@ namespace Crow {
                void cancelLoadingThread(){
                        if (loadingThread == null)
                                return;
-                       bool updateMx = Monitor.IsEntered (IFace.UpdateMutex);
-                       bool layoutMx = Monitor.IsEntered (IFace.LayoutMutex);
 
-                       DbgLogger.AddEvent (DbgEvtType.TGCancelLoadingThread, this);
+                       DbgLogger.StartEvent (DbgEvtType.TGCancelLoadingThread, this);
 
-                       if (layoutMx)
-                               Monitor.Exit (IFace.LayoutMutex);
-                       if (updateMx)
+                       int updateMx = 0, layoutMx = 0;
+
+                       while (Monitor.IsEntered (IFace.UpdateMutex)) {
                                Monitor.Exit (IFace.UpdateMutex);
+                               updateMx++;
+                       }
+                       while (Monitor.IsEntered (IFace.LayoutMutex)) {
+                               Monitor.Exit (IFace.LayoutMutex);
+                               layoutMx++;
+                       }                       
 
                        loadingThread.Cancel ();
 
-                       if (layoutMx)
+                       for (int i = 0; i < layoutMx; i++)
                                Monitor.Enter (IFace.LayoutMutex);
-                       if (updateMx)
+                       for (int i = 0; i < updateMx; i++)
                                Monitor.Enter (IFace.UpdateMutex);
 
                        loadingThread = null;
+                       
+                       DbgLogger.EndEvent (DbgEvtType.TGCancelLoadingThread);
                }
                void loadPage(IEnumerable _data, Group page, string _dataTest)
                {
index c0615321c6318765ace8deee1cd0f8b3fa4e814e..8300abb20d3ac4ff59fa850e1fbe57dcbb440094 100644 (file)
@@ -41,11 +41,11 @@ namespace Crow
                                }
                                catch (System.Exception ex)
                                {
-                                       if (Monitor.IsEntered(LayoutMutex))
+                                       while (Monitor.IsEntered(LayoutMutex))
                                                Monitor.Exit (LayoutMutex);
-                                       if (Monitor.IsEntered(UpdateMutex))
+                                       while (Monitor.IsEntered(UpdateMutex))
                                                Monitor.Exit (UpdateMutex);
-                                       if (Monitor.IsEntered(ClippingMutex))
+                                       while (Monitor.IsEntered(ClippingMutex))
                                                Monitor.Exit (ClippingMutex);
                                        delSetCurrentException (ex);                                    
                                        ClearInterface();
index 3f331cf2f95bb16c41b5ee47f0721abb3f123468..ee30d5ed0c1e96167da3eee9ecdd385c9e16a16a 100644 (file)
@@ -216,9 +216,16 @@ namespace Crow
 
                public override void onMouseMove(object sender, MouseMoveEventArgs e)
                {
-                       if (initialized) {                              
-                               Point m = ScreenPointToLocal (e.Position);                      
-                               delMouseMove (m.X, m.Y);                                                                        
+                       if (initialized) {
+                               try
+                               {
+                                       Point m = ScreenPointToLocal (e.Position);
+                                       delMouseMove (m.X, m.Y);
+                               }
+                               catch (System.Exception ex)
+                               {
+                                       Console.WriteLine($"[Error][DebugIFace mouse move]{ex}");
+                               }
                                e.Handled = true;
                        }
                        base.onMouseMove(sender, e);
@@ -226,7 +233,14 @@ namespace Crow
                public override void onMouseDown(object sender, MouseButtonEventArgs e)
                {
                        if (initialized) {                              
-                               delMouseDown (e.Button);
+                               try
+                               {
+                                       delMouseDown (e.Button);
+                               }
+                               catch (System.Exception ex)
+                               {
+                                       Console.WriteLine($"[Error][DebugIFace mouse down]{ex}");
+                               }
                                e.Handled=true;
                        }
                        base.onMouseDown (sender, e);                   
@@ -234,7 +248,14 @@ namespace Crow
                public override void onMouseUp(object sender, MouseButtonEventArgs e)
                {
                        if (initialized) {                              
-                               delMouseUp (e.Button);                  
+                               try
+                               {
+                                       delMouseUp (e.Button);                  
+                               }
+                               catch (System.Exception ex)
+                               {
+                                       Console.WriteLine($"[Error][DebugIFace mouse up]{ex}");
+                               }
                                e.Handled=true;
                        }
                        base.onMouseUp (sender, e);
diff --git a/Samples/DebugLogAnalyzer/src/Editor.cs b/Samples/DebugLogAnalyzer/src/Editor.cs
deleted file mode 100644 (file)
index 315a5a9..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright (c) 2013-2019  Bruyère Jean-Philippe <jp_bruyere@hotmail.com>
-//
-// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
-
-using System;
-using Glfw;
-using Crow.Text;
-
-namespace Crow
-{
-       public class Editor : TextBox {
-               public override void onKeyDown(object sender, KeyEventArgs e)
-               {
-                       TextSpan selection = Selection;
-                       if (e.Key == Key.Tab && !selection.IsEmpty) {
-                               int lineStart = lines.GetLocation (selection.Start).Line;
-                               int lineEnd = lines.GetLocation (selection.End).Line;
-
-                               if (IFace.Shift) {
-                                       for (int l = lineStart; l <= lineEnd; l++) {                            
-                                               if (Text[lines[l].Start] == '\t')
-                                                       update (new TextChange (lines[l].Start, 1, ""));
-                                               else if (Char.IsWhiteSpace (Text[lines[l].Start])) {
-                                                       int i = 1;
-                                                       while (i < lines[l].Length && i < Interface.TAB_SIZE && Char.IsWhiteSpace (Text[i]))
-                                                               i++;
-                                                       update (new TextChange (lines[l].Start, i, ""));
-                                               }
-                                       }
-
-                               }else{
-                                       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);
-
-                               return;
-                       }
-                       base.onKeyDown(sender, e);                      
-               }
-       }
-}
\ No newline at end of file
index c80ed43a89e8fddafe6e3bde2265ebae5468f9d5..8536aaaa0be56539eed16188e39694b07c478676 100644 (file)
@@ -40,7 +40,7 @@
                <EmbeddedResource Include="$(SamplesDir)common\samples.style" >
                        <Link>common\%(Filename)%(Extension)</Link>
                </EmbeddedResource>
-               <Compile Include="$(SamplesDir)common\SampleBase.cs">
+               <Compile Include="$(SamplesDir)common\*.cs">
                        <Link>common\%(Filename)%(Extension)</Link>
                </Compile>
        </ItemGroup>
diff --git a/Samples/ShowCase/Editor.cs b/Samples/ShowCase/Editor.cs
deleted file mode 100644 (file)
index 315a5a9..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright (c) 2013-2019  Bruyère Jean-Philippe <jp_bruyere@hotmail.com>
-//
-// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
-
-using System;
-using Glfw;
-using Crow.Text;
-
-namespace Crow
-{
-       public class Editor : TextBox {
-               public override void onKeyDown(object sender, KeyEventArgs e)
-               {
-                       TextSpan selection = Selection;
-                       if (e.Key == Key.Tab && !selection.IsEmpty) {
-                               int lineStart = lines.GetLocation (selection.Start).Line;
-                               int lineEnd = lines.GetLocation (selection.End).Line;
-
-                               if (IFace.Shift) {
-                                       for (int l = lineStart; l <= lineEnd; l++) {                            
-                                               if (Text[lines[l].Start] == '\t')
-                                                       update (new TextChange (lines[l].Start, 1, ""));
-                                               else if (Char.IsWhiteSpace (Text[lines[l].Start])) {
-                                                       int i = 1;
-                                                       while (i < lines[l].Length && i < Interface.TAB_SIZE && Char.IsWhiteSpace (Text[i]))
-                                                               i++;
-                                                       update (new TextChange (lines[l].Start, i, ""));
-                                               }
-                                       }
-
-                               }else{
-                                       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);
-
-                               return;
-                       }
-                       base.onKeyDown(sender, e);                      
-               }
-       }
-}
\ No newline at end of file
index 3d6b0bad54bae16ff520d9382e82ef29496c8722..915b6b105f110f73c1263fa31b71f74111e19a3e 100644 (file)
@@ -84,7 +84,7 @@
                        <HorizontalStack>
                                <Editor Name="tb" Text="{Source}" Multiline="true" Font="consolas, 12" Focusable="true" Height="Stretched" Width="Stretched"                                            
                                                TextChanged="onTextChanged" KeyDown="textView_KeyDown" ContextCommands="{EditorCommands}"
-                                               Foreground="DarkGrey" Background="White"/>
+                                               Foreground="DarkGrey" Background="White" MouseWheelSpeed="20"/>
                                                <!--SelectionChanged="onSelectedTextChanged"-->
                                <ScrollBar Value="{²../tb.ScrollY}"
                                                LargeIncrement="{../tb.PageHeight}" SmallIncrement="1"
diff --git a/Samples/common/Editor.cs b/Samples/common/Editor.cs
new file mode 100644 (file)
index 0000000..44168b6
--- /dev/null
@@ -0,0 +1,541 @@
+using System.Security.Principal;
+using System.Threading;
+// Copyright (c) 2013-2019  Bruyère Jean-Philippe <jp_bruyere@hotmail.com>
+//
+// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
+
+using System;
+using Glfw;
+using Crow.Text;
+using System.Collections.Generic;
+using Crow.Cairo;
+using System.Threading.Tasks;
+using System.Linq;
+
+namespace Crow
+{
+       [Flags]
+       public enum TokenType {
+               Unknown,
+               Trivia                                  = 0x0100,
+               WhiteSpace                              = 0x4100,
+               Tabulation                              = 0x4101,
+               LineBreak                               = 0x4102,
+               LineComment                             = 0x0103,
+               BlockCommentStart               = 0x0104,
+               BlockComment                    = 0x0105,
+               BlockCommentEnd                 = 0x0106,
+               Name                                    = 0x0200,
+               ElementName                             = 0x0201,
+               AttributeName                   = 0x0202,
+               PI_Target                               = 0x0203,
+               Punctuation                             = 0x0400,
+               PI_Start                                = 0x0401,// '<?'
+               PI_End                                  = 0x0402,// '?>'
+               Operator                                = 0x0800,
+               EqualSign                               = 0x0801,
+               AttributeValue                  = 0x2000,
+               Keyword                                 = 0x1000,
+               ElementOpen                     = 0x0403,// '<'
+               EndElementOpen                  = 0x0404,// '</'
+               EmptyElementClosing             = 0x0405,// '/>'
+               ClosingSign                             = 0x0406,// '>'
+               DTDObjectOpen                   = 0x04A0,// '<!'
+               Content,
+       }
+       
+       public struct Token {
+               public readonly TokenType Type;
+               public int Start;
+               public readonly int Length;
+               public int End => Start + Length;
+               public TextSpan Span => new TextSpan (Start, End);
+
+               public Token (TokenType type, int pos) {
+                       Type = type;
+                       Start = pos;
+                       Length = 1;
+               }
+               public Token (TokenType type, int start, int end) {
+                       Type = type;
+                       Start = start;
+                       Length = end - start;
+               }               
+               public override string ToString() => $"{Type},{Start} {Length}";
+       }
+       public class XmlSource {
+               public Token[] Tokens;
+               public readonly string Source;          
+
+               public XmlSource (string _source) {
+                       Source = _source;
+                       Tokenizer tokenizer = new Tokenizer();
+                       Tokens = tokenizer.Tokenize (Source);
+
+                       foreach (Token t in Tokens)
+                               Console.WriteLine ($"{t,-40} {Source.AsSpan(t.Start, t.Length).ToString()}");
+               }
+               public class TokenizerException : Exception {
+                       public readonly int Position;
+                       public TokenizerException(string message, int position, Exception innerException = null)
+                                       : base (message, innerException) {
+                               Position = position;
+                       }
+               }
+
+               class Tokenizer {
+                       enum States
+                       {
+                               Init,//first statement of prolog, xmldecl should only apear in this state
+                               prolog,//misc before doctypedecl
+                               ProcessingInstrucitons,
+                               DTD,
+                               DTDObject,//doctype finished                            
+                               Xml,
+                               StartTag,//inside start tag
+                               Content,//after start tag with no closing slash
+                               EndTag
+                       }
+
+                       States curState = States.Init;
+                       List<Token> Toks = new List<Token>(100);
+
+                       public Tokenizer  () {}
+
+                       void skipWhiteSpaces (ref SpanCharReader reader) {
+                               while(!reader.EndOfSpan) {
+                                       switch (reader.Peak) {
+                                               case '\x85':
+                                               case '\x2028':
+                                               case '\xA':
+                                                       reader.Read();
+                                                       addTok (ref reader, TokenType.LineBreak);
+                                                       break;
+                                               case '\xD':
+                                                       reader.Read();
+                                                       if (reader.IsNextCharIn ('\xA', '\x85'))
+                                                               reader.Read();
+                                                       addTok (ref reader, TokenType.LineBreak);                                                                                                               
+                                                       break;
+                                               case '\x20':
+                                               case '\x9':
+                                                       char c = reader.Read();                                                                 
+                                                       while (reader.TryPeak (c))
+                                                               reader.Read();
+                                                       addTok (ref reader, c == '\x20' ? TokenType.WhiteSpace : TokenType.Tabulation);
+                                                       break;
+                                               default:
+                                                       return;
+                                       }
+                               }
+                       }
+                       bool readName (ref SpanCharReader reader) {
+                               if (reader.EndOfSpan)
+                                       return false;
+                               char c = reader.Peak;                                   
+                               if (char.IsLetter(c) || c == '_' || c == ':') {
+                                       reader.Advance ();
+                                       while (reader.TryPeak (ref c)) {                                                                        
+                                               if (!(char.IsLetterOrDigit(c) || c == '.' || c == '-' || c == '\xB7'))
+                                                       return true;
+                                               reader.Advance ();
+                                       }
+                                       return true;
+                               }
+                               return false;
+                       }
+
+                       int startOfTok;
+                       void addTok (ref SpanCharReader reader, TokenType tokType) {
+                               if (reader.CurrentPosition == startOfTok)
+                                       return;
+                               Toks.Add (new Token(tokType, startOfTok, reader.CurrentPosition));
+                               startOfTok = reader.CurrentPosition;
+                       }
+                       public Token[] Tokenize (string source) {
+                               SpanCharReader reader = new SpanCharReader(source);
+                               
+                               startOfTok = 0;
+                               int curObjectLevel = 0;
+                               curState = States.Init;
+
+                               while(!reader.EndOfSpan) {
+
+                                       skipWhiteSpaces (ref reader);
+
+                                       if (reader.EndOfSpan)
+                                               break;
+
+                                       switch (reader.Peak) {                          
+                                       case '<':
+                                               reader.Advance ();
+                                               if (reader.TryPeak ('?')) {                                                             
+                                                       reader.Advance ();
+                                                       addTok (ref reader, TokenType.PI_Start);
+                                                       readName (ref reader);
+                                                       addTok (ref reader, TokenType.PI_Target);
+                                                       curState = States.ProcessingInstrucitons;
+                                               } else if (reader.TryPeak ('!')) {
+                                                       reader.Advance ();
+                                                       if (reader.TryPeak ("--")) {
+                                                               reader.Advance (2);
+                                                               addTok (ref reader, TokenType.BlockCommentStart);                                                                               
+                                                               if (reader.TryReadUntil ("-->")) {
+                                                                       addTok (ref reader, TokenType.BlockComment);
+                                                                       reader.Advance (3);                                                                                     
+                                                                       addTok (ref reader, TokenType.BlockCommentEnd);
+                                                               } else if (reader.TryPeak ("-->")) {
+                                                                       reader.Advance (3);                                                                                     
+                                                                       addTok (ref reader, TokenType.BlockCommentEnd);
+                                                               }
+                                                       } else {
+                                                               addTok (ref reader, TokenType.DTDObjectOpen);
+                                                               if (readName (ref reader)) {
+                                                                       addTok (ref reader, TokenType.Keyword);
+                                                                       curState = States.DTDObject;
+                                                               }                                                               
+                                                       }                                                               
+                                               } else if (reader.TryPeak('/')) {
+                                                       reader.Advance ();
+                                                       addTok (ref reader, TokenType.EndElementOpen);
+                                                       if (readName (ref reader)) {
+                                                               addTok (ref reader, TokenType.ElementName);
+                                                               if (reader.TryPeak('>')) {
+                                                                       reader.Advance ();
+                                                                       addTok (ref reader, TokenType.ClosingSign);
+
+                                                                       if (--curObjectLevel > 0)
+                                                                               curState = States.Content;
+                                                                       else
+                                                                               curState = States.Xml;
+                                                               } 
+                                                       }
+                                               }else{                                                  
+                                                       addTok (ref reader, TokenType.ElementOpen);                                                     
+                                                       if (readName (ref reader)) {
+                                                               addTok (ref reader, TokenType.ElementName);                                                             
+                                                               curState = States.StartTag;
+                                                       }
+                                               }
+                                               break;
+                                       case '?':
+                                               reader.Advance ();
+                                               if (reader.TryPeak ('>')){
+                                                       reader.Advance ();
+                                                       addTok (ref reader, TokenType.PI_End);
+                                               }else
+                                                       addTok (ref reader, TokenType.Unknown);                                         
+                                               curState = States.prolog;                                               
+                                               break;
+                                       case '\'':
+                                       case '"':
+                                               char q = reader.Read();
+                                               if (reader.TryReadUntil (q)) {
+                                                       reader.Advance ();
+                                                       addTok (ref reader, TokenType.AttributeValue);
+                                               } else
+                                                       addTok (ref reader, TokenType.Unknown);
+                                               break;
+                                       case '=':
+                                               reader.Advance();
+                                               addTok (ref reader, TokenType.EqualSign);
+                                               break;
+                                       case '>':
+                                               reader.Advance();
+                                               addTok (ref reader, TokenType.ClosingSign);
+                                               curObjectLevel++;
+                                               curState = States.Content;
+                                               break;
+                                       case '/':
+                                               reader.Advance();
+                                               if (reader.TryRead ('>')) {
+                                                       addTok (ref reader, TokenType.EmptyElementClosing);
+                                                       if (--curObjectLevel > 0)
+                                                               curState = States.Content;
+                                                       else
+                                                               curState = States.Xml;
+                                               }else
+                                                       addTok (ref reader, TokenType.Unknown);
+                                               break;
+                                       default:
+                                               if (curState == States.StartTag || curState == States.ProcessingInstrucitons) {
+                                                       if (readName(ref reader))
+                                                               addTok (ref reader, TokenType.AttributeName);
+                                                       else if (reader.TryAdvance())
+                                                               addTok (ref reader, TokenType.Unknown);
+                                               } else {
+                                                       reader.TryReadUntil ('<');
+                                                       addTok (ref reader, TokenType.Content);
+                                               }
+                                               break;
+                                       }
+                               }
+
+                               return Toks.ToArray();
+                       }
+                       
+               }
+
+       }
+       public class Editor : TextBox {
+               XmlSource source;
+               object TokenMutex = new object();
+
+               void parse () {                 
+                       XmlSource tmp = new XmlSource(_text);
+                       lock(TokenMutex)
+                               source = tmp;
+                       RegisterForGraphicUpdate();
+               }
+               protected override void onInitialized(object sender, EventArgs e)
+               {
+                       base.onInitialized(sender, e);
+
+               }
+               Widget overlay;
+               public override void OnTextChanged(object sender, TextChangeEventArgs e)
+               {
+                       base.OnTextChanged(sender, e);
+                       //Task.Run(()=>parse());                        
+                       parse();
+
+                       /*if (overlay == null && HasFocus)
+                               overlay = IFace.LoadIMLFragment(@"<Widget Width='50' Height='50' Background='Jet'/>");*/
+               }
+               public override void onKeyDown(object sender, KeyEventArgs e)
+               {
+                       TextSpan selection = Selection;
+                       if (e.Key == Key.Tab && !selection.IsEmpty) {
+                               int lineStart = lines.GetLocation (selection.Start).Line;
+                               int lineEnd = lines.GetLocation (selection.End).Line;
+
+                               if (IFace.Shift) {
+                                       for (int l = lineStart; l <= lineEnd; l++) {                            
+                                               if (Text[lines[l].Start] == '\t')
+                                                       update (new TextChange (lines[l].Start, 1, ""));
+                                               else if (Char.IsWhiteSpace (Text[lines[l].Start])) {
+                                                       int i = 1;
+                                                       while (i < lines[l].Length && i < Interface.TAB_SIZE && Char.IsWhiteSpace (Text[i]))
+                                                               i++;
+                                                       update (new TextChange (lines[l].Start, i, ""));
+                                               }
+                                       }
+
+                               }else{
+                                       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);
+
+                               return;
+                       }
+                       base.onKeyDown(sender, e);                      
+               }
+               int tabSize = 4;
+
+               protected override void drawContent (Context gr) {
+                       lock(TokenMutex) {
+                               if (source == null || source.Tokens.Length == 0) {
+                                       base.drawContent (gr);
+                                       return;
+                               }
+                       
+                               Rectangle cb = ClientRectangle;
+                               fe = gr.FontExtents;
+                               double lineHeight = fe.Ascent + fe.Descent;
+
+                               CharLocation selStart = default, selEnd = default;
+                               bool selectionNotEmpty = false;
+
+                               if (HasFocus) {
+                                       if (currentLoc?.Column < 0) {
+                                               updateLocation (gr, cb.Width, ref currentLoc);
+                                               NotifyValueChanged ("CurrentColumn", CurrentColumn);
+                                       } else
+                                               updateLocation (gr, cb.Width, ref currentLoc);
+
+                                       if (overlay != null) {
+                                               Point p = new Point((int)currentLoc.Value.VisualCharXPosition, (int)(lineHeight * (currentLoc.Value.Line + 1)));
+                                               p += ScreenCoordinates (Slot).TopLeft;
+                                               overlay.Left = p.X;
+                                               overlay.Top = p.Y;
+                                       }
+                                       if (selectionStart.HasValue) {
+                                               updateLocation (gr, cb.Width, ref selectionStart);
+                                               if (CurrentLoc.Value != selectionStart.Value)
+                                                       selectionNotEmpty = true;
+                                       }
+                                       if (selectionNotEmpty) {
+                                               if (CurrentLoc.Value.Line < selectionStart.Value.Line) {
+                                                       selStart = CurrentLoc.Value;
+                                                       selEnd = selectionStart.Value;
+                                               } else if (CurrentLoc.Value.Line > selectionStart.Value.Line) {
+                                                       selStart = selectionStart.Value;
+                                                       selEnd = CurrentLoc.Value;
+                                               } else if (CurrentLoc.Value.Column < selectionStart.Value.Column) {
+                                                       selStart = CurrentLoc.Value;
+                                                       selEnd = selectionStart.Value;
+                                               } else {
+                                                       selStart = selectionStart.Value;
+                                                       selEnd = CurrentLoc.Value;
+                                               }
+                                       } else
+                                               IFace.forceTextCursor = true;
+                               }
+
+                               double spacePixelWidth = gr.TextExtents (" ").XAdvance;
+                               int x = 0, y = 0;
+                               double pixX = cb.Left;
+
+
+                               Foreground.SetAsSource (IFace, gr);
+                               gr.Translate (-ScrollX, -ScrollY);
+
+
+                               ReadOnlySpan<char> sourceBytes = source.Source.AsSpan();
+                               Span<byte> bytes = stackalloc byte[128];
+                               TextExtents extents;
+                               int tokPtr = 0;
+                               Token tok = source.Tokens[tokPtr];
+                               bool multilineToken = false;                            
+
+                               ReadOnlySpan<char> buff = sourceBytes;
+
+
+                               for (int i = 0; i < lines.Count; i++) {
+                                       //if (!cancelLinePrint (lineHeight, lineHeight * y, cb.Height)) {
+
+                                       if (multilineToken) {
+                                               if (tok.End < lines[i].End) {//last incomplete line of multiline token
+                                                       buff = sourceBytes.Slice (lines[i].Start, tok.End - lines[i].Start);                                                            
+                                               } else {//print full line
+                                                       buff = sourceBytes.Slice (lines[i].Start, lines[i].Length);
+                                               }
+                                       }
+
+                                       while (tok.Start < lines[i].End) {
+                                               if (!multilineToken) {
+                                                       if (tok.End > lines[i].End) {//first line of multiline
+                                                               multilineToken = true;
+                                                               buff = sourceBytes.Slice (tok.Start, lines[i].End - tok.Start);
+                                                       } else
+                                                               buff = sourceBytes.Slice (tok.Start, tok.Length);
+
+                                                       if (tok.Type.HasFlag (TokenType.Punctuation))
+                                                               gr.SetSource(Colors.DarkGrey);
+                                                       else if (tok.Type.HasFlag (TokenType.Trivia))
+                                                               gr.SetSource(Colors.DimGrey);
+                                                       else if (tok.Type == TokenType.ElementName) {
+                                                               gr.SetSource(Colors.Green);
+                                                       }else if (tok.Type == TokenType.AttributeName) {
+                                                               gr.SetSource(Colors.Blue);
+                                                       }else if (tok.Type == TokenType.AttributeValue) {
+                                                               gr.SetSource(Colors.OrangeRed);
+                                                       }else if (tok.Type == TokenType.EqualSign) {
+                                                               gr.SetSource(Colors.Black);
+                                                       }else if (tok.Type == TokenType.PI_Target) {
+                                                               gr.SetSource(Colors.DarkSlateBlue);
+                                                       }else {
+                                                               gr.SetSource(Colors.Red);
+                                                       }                                                                       
+                                               }
+
+                                               int size = buff.Length * 4 + 1;
+                                               if (bytes.Length < size)
+                                                       bytes = size > 512 ? new byte[size] : stackalloc byte[size];
+
+                                               int encodedBytes = Crow.Text.Encoding.ToUtf8 (buff, bytes);
+
+                                               if (encodedBytes > 0) {
+                                                       bytes[encodedBytes++] = 0;
+                                                       gr.TextExtents (bytes.Slice (0, encodedBytes), out extents);
+                                                       gr.MoveTo (pixX, lineHeight * y + fe.Ascent);
+                                                       gr.ShowText (bytes.Slice (0, encodedBytes));
+                                                       pixX += extents.XAdvance;
+                                                       x += buff.Length;                                                               
+                                               }
+
+                                               if (multilineToken) {
+                                                       if (tok.End < lines[i].End)//last incomplete line of multiline token
+                                                               multilineToken = false;
+                                                       else
+                                                               break;
+                                               }
+
+                                               if (++tokPtr >= source.Tokens.Length)
+                                                       break;
+                                               tok = source.Tokens[tokPtr];
+                                       }
+
+                                       if (HasFocus && selectionNotEmpty) {
+                                               RectangleD lineRect = new RectangleD (cb.X,     lineHeight * y + cb.Top, pixX, lineHeight);
+                                               RectangleD selRect = lineRect;
+                                               
+                                               if (i >= selStart.Line && i <= selEnd.Line) {
+                                                       if (selStart.Line == selEnd.Line) {
+                                                               selRect.X = selStart.VisualCharXPosition + cb.X;
+                                                               selRect.Width = selEnd.VisualCharXPosition - selStart.VisualCharXPosition;
+                                                       } else if (i == selStart.Line) {
+                                                               double newX = selStart.VisualCharXPosition + cb.X;
+                                                               selRect.Width -= (newX - selRect.X) - 10.0;
+                                                               selRect.X = newX;
+                                                       } else if (i == selEnd.Line)
+                                                               selRect.Width = selEnd.VisualCharXPosition - selRect.X + cb.X;
+                                                       else
+                                                               selRect.Width += 10.0;
+
+                                                       buff = sourceBytes.Slice(lines[i].Start, lines[i].Length);
+                                                       int size = buff.Length * 4 + 1;
+                                                       if (bytes.Length < size)
+                                                               bytes = size > 512 ? new byte[size] : stackalloc byte[size];
+
+                                                       int encodedBytes = Crow.Text.Encoding.ToUtf8 (buff, bytes);
+
+                                                       gr.SetSource (SelectionBackground);
+                                                       gr.Rectangle (selRect);
+                                                       if (encodedBytes < 0)
+                                                               gr.Fill ();
+                                                       else {
+                                                               gr.FillPreserve ();
+                                                               gr.Save ();
+                                                               gr.Clip ();
+                                                               gr.SetSource (SelectionForeground);
+                                                               gr.MoveTo (lineRect.X, lineRect.Y + fe.Ascent);
+                                                               gr.ShowText (bytes.Slice (0, encodedBytes));
+                                                               gr.Restore ();
+                                                       }
+                                                       Foreground.SetAsSource (IFace, gr);
+                                               }
+                                       }
+
+                                       if (!multilineToken) {
+                                               if (++tokPtr >= source.Tokens.Length)
+                                                       break;
+                                               tok = source.Tokens[tokPtr];
+                                       }
+
+                                       x = 0;
+                                       pixX = 0;
+               
+                                       y++;
+
+
+                                               /*      } else if (tok2.Type == TokenType.Tabulation) {
+                                                               int spaceRounding = x % tabSize;
+                                                               int spaces = spaceRounding == 0 ?
+                                                                       tabSize * tok2.Length :
+                                                                       spaceRounding + tabSize * (tok2.Length - 1);
+                                                               x += spaces;
+                                                               pixX += spacePixelWidth * spaces;
+                                                               continue;
+                                                       } else if (tok2.Type == TokenType.WhiteSpace) {
+                                                               x += tok2.Length;
+                                                               pixX += spacePixelWidth * tok2.Length;*/                                                                                                                                                                
+                               }                                       
+                               gr.Translate (ScrollX, ScrollY);
+                       }
+               }                       
+       }
+}
\ No newline at end of file
index 59244f1b574d76281e05d4adcd83fe967bdb50d6..a17eaf929bd1d04dc5006ac49af3338f29af8c02 100644 (file)
@@ -127,6 +127,9 @@ namespace Crow
             public override string ToString ()
                 => $"{Prop1}, {Prop2}";
 
+                       public void OnValidateCommand (Object sender, ValidateEventArgs e) {
+                               Console.WriteLine ($"Validation: {e.ValidatedText}");
+                       }
         }
         public class TestClassVC : IValueChange
         {
@@ -160,7 +163,7 @@ namespace Crow
                     => $"{Prop1}, {Prop2}";
 
         }
-        TestClass tcInstance;// = new TestClass () { Prop1 = "instance 0 prop1 value", Prop2 = "instance 0 prop2 value" };
+        TestClass tcInstance = new TestClass () { Prop1 = "instance 0 prop1 value", Prop2 = "instance 0 prop2 value" };
         TestClassVC tcVCInstance;// = new TestClassVC () { Prop1 = "instance 0 prop1 value", Prop2 = "instance 0 prop2 value" };
         TestClass tcInstance1 = new TestClass () { Prop1 = "instance 1 prop1 value", Prop2 = "instance 1 prop2 value" };
         TestClassVC tcVCInstance1 = new TestClassVC () { Prop1 = "instance 1 prop1 value", Prop2 = "instance 1 prop2 value" };
index 211937c429b9d05c076089c78403c2290183344d..39721689e81a952120d9c5890310d979fee64223 100644 (file)
@@ -1,5 +1,5 @@
 <VerticalStack>
-       <ColorPicker Name="cp"  Height="20" Background="Grey" >
+       <ColorPicker Name="cp"  >
                <Template>
                        <Popper Margin="0" Caption="{./CurrentColor}" Background="{./Background}" >
                                <Template>
                                                </Template>/>{}
                                        </CheckBox>
                                </Template>
-                               <TabView TabWidth="60" LeftSlope="0" RightSlope="0" MinimumSize="{../../MinimumPopupSize}" Width="Fit" Height="Fit" ActivateNewTab="false">
-                                       <TabItem Template="/mnt/devel/crow/Samples/common/ui/templates/TabItem.template" Caption="HSV" Width="Fit" Height="Fit">
-                                               <ColorPicker CurrentColor="{²../../../../CurrentColor}" />
-                                       </TabItem>
-                                       <TabItem Template="/mnt/devel/crow/Samples/common/ui/templates/TabItem.template" Caption="Names" Width="Fit" Height="Stretched">                                                
-                                               <ColorPicker CurrentColor="{²../../../../CurrentColor}" Height="Stretched" >
-                                                       <Template>
-                                                               <ListBox Margin="0" Width="Stretched" Data="{./AvailableColors}" SelectedItemChanged="./onSelectedItemChanged">
-                                                                       <Template>
-                                                                               <Scroller Name="scroller1" Margin="5" ClipToClientRect="true" >
-                                                                                       <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>
-                                       </TabItem>
-                               </TabView>
+                               <TabView  MinimumSize="{../../MinimumPopupSize}" Width="Fit" Height="Fit"  >
+                                       <ColorPicker Name="HSV" CurrentColor="{²../../../CurrentColor}" Background="Onyx"/>
+                                       <ColorPicker IsVisible="false" Name="Names" CurrentColor="{²../../../CurrentColor}" Height="Stretched" Background="Onyx">
+                                               <Template>
+                                                       <ListBox Width="Stretched" Data="{./AvailableColors}" SelectedItemChanged="./onSelectedItemChanged">
+                                                               <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>
                </Template>
        </ColorPicker>
-       <Border CornerRadius="5" Width="60" Height="40" Background="{../cp.CurrentColor}">
+       <Border CornerRadius="5" Width="100" Height="80" Background="{../cp.CurrentColor}">
                <Label Text="{../../cp.CurrentColor}"/>
        </Border>
 </VerticalStack>
\ No newline at end of file
index 2d963fc48023885f839fb72d1d3600e29f6f61f9..81f1f7cacf2c728463fce9d87a36de3381c63b7b 100644 (file)
@@ -1,60 +1,34 @@
 <?xml version="1.0"?>
-<TabView >
-       <TabItem Caption="HSV">
-               <Border Background="{./Background}"     Foreground="{./Foreground}" Width="Stretched"
-                               CornerRadius="{./CornerRadius}" BorderWidth="1">                
-                       <VerticalStack Margin="2">
-                               <Widget Width="30" Height="16" Background="{./CurrentColor}"/>
-                               <HorizontalStack Height="Fit">
-                                       <Label Style="labColor" Text="R:"/>
-                                       <ColorSlider Name="cs" Component="Red" CurrentColor="{²../../../../../../CurrentColor}"/>
-                                       <Label Style="labColorV" Text="{../cs.CurrentValue}" />
-                               </HorizontalStack>
-                               <HorizontalStack Height="Fit">
-                                       <Label Style="labColor" Text="G:"/>
-                                       <ColorSlider Name="cs" Component="Green" CurrentColor="{²../../../../../../CurrentColor}"/>
-                                       <Label Style="labColorV" Text="{../cs.CurrentValue}" />
-                               </HorizontalStack>
-                               <HorizontalStack Height="Fit">
-                                       <Label Style="labColor" Text="B:"/>
-                                       <ColorSlider Name="cs" Component="Blue" CurrentColor="{²../../../../../../CurrentColor}"/>
-                                       <Label Style="labColorV" Text="{../cs.CurrentValue}" />
-                               </HorizontalStack>
-                               <HorizontalStack Height="Fit">
-                                       <Label Style="labColor" Text="A:"/>
-                                       <ColorSlider Name="cs" Component="Alpha" CurrentColor="{²../../../../../../CurrentColor}"/>
-                                       <Label Style="labColorV" Text="{../cs.CurrentValue}" />
-                               </HorizontalStack>
-                               <HorizontalStack Height="Fit">
-                                       <Label Style="labColor" Text="H:"/>
-                                       <ColorSlider Name="cs" Component="Hue" CurrentColor="{²../../../../../../CurrentColor}"/>
-                                       <Label Style="labColorV" Text="{../cs.CurrentValue}" />
-                               </HorizontalStack>
-                               <HorizontalStack Height="Fit">
-                                       <Label Style="labColor" Text="S:"/>
-                                       <ColorSlider Name="cs" Component="Saturation" CurrentColor="{²../../../../../../CurrentColor}"/>
-                                       <Label Style="labColorV" Text="{../cs.CurrentValue}" />
-                               </HorizontalStack>                      
-                               <HorizontalStack Height="Fit">
-                                       <Label Style="labColor" Text="V:"/>
-                                       <ColorSlider Name="cs" Component="Value" CurrentColor="{²../../../../../../CurrentColor}"/>
-                                       <Label Style="labColorV" Text="{../cs.CurrentValue}" />
-                               </HorizontalStack>
-                       </VerticalStack>                        
-               </Border>
-       </TabItem>
-       <TabItem Caption="List" Height="Stretched">
-               <ListBox Data="{../../../ColorList}" SelectedItem="{²../../../CurrentColor}">
-                       <Template>
-                               <Scroller Name="scroller1" Margin="5">
-                                       <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>
-       </TabItem>
-</TabView>
\ No newline at end of file
+<Popper Margin="0" Caption="{./CurrentColor}" Background="{./Background}" >
+                               <Template>
+                                       <CheckBox Margin="0" Caption="{./Caption}" IsChecked="{²./IsPopped}" 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>/>{}
+                                       </CheckBox>
+                               </Template>
+                               <TabView  MinimumSize="{../../MinimumPopupSize}" Width="Fit" Height="Fit"  >
+                                       <ColorPicker Name="HSV" CurrentColor="{²../../../CurrentColor}" Background="Onyx"/>
+                                       <ColorPicker IsVisible="false" Name="Names" CurrentColor="{²../../../CurrentColor}" Height="Stretched" Background="Onyx">
+                                               <Template>
+                                                       <ListBox Width="Stretched" Data="{./AvailableColors}" SelectedItemChanged="./onSelectedItemChanged">
+                                                               <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