]> O.S.I.I.S - jp/crow.git/commitdiff
suggestion in IML editor, editor base classe for ShowCase and LogAnalyzer SimplifiedTabView
authorJean-Philippe Bruyère <jp_bruyere@hotmail.com>
Mon, 7 Jun 2021 13:05:30 +0000 (15:05 +0200)
committerJean-Philippe Bruyère <jp_bruyere@hotmail.com>
Mon, 7 Jun 2021 13:05:30 +0000 (15:05 +0200)
24 files changed:
Crow/Crow.csproj
Crow/src/Interface.cs
Crow/src/Text/TextChange.cs
Crow/src/Widgets/Label.cs
Samples/BasicTests/BasicTests.cs
Samples/BindingTest/Program.cs
Samples/DebugLogAnalyzer/src/DebugInterface.cs
Samples/DebugLogAnalyzer/src/Extensions.cs [deleted file]
Samples/DebugLogAnalyzer/src/Program.cs
Samples/ShowCase/ShowCase.cs
Samples/ShowCase/ui/showcase.crow
Samples/common/src/Editor.cs
Samples/common/src/Extensions.cs [new file with mode: 0644]
Samples/common/src/ImlParsing/Syntax.cs
Samples/common/src/ImlParsing/TokenType.cs
Samples/common/src/ImlParsing/XmlSource.cs
Samples/common/src/SampleBase.cs
Samples/common/src/SampleBaseForEditor.cs [new file with mode: 0644]
Samples/common/ui/Interfaces/Experimental/DockWindow.template [deleted file]
Samples/common/ui/Interfaces/Experimental/multiColorPick.crow
Samples/common/ui/Interfaces/Wrapper/1.1.crow
Samples/common/ui/icons/event.png [new file with mode: 0755]
Samples/common/ui/icons/property.png [new file with mode: 0755]
Samples/common/ui/templates/Suggestions.template

index 083b19892f7a5ef5571c7f309bd1ddefe547af99..29aca87801b5ab3043e70e7ec7b51a71c76fa244 100644 (file)
@@ -23,7 +23,7 @@
                <GeneratePackageOnBuild>True</GeneratePackageOnBuild>
                <GenerateDocumentationFile>true</GenerateDocumentationFile>
                <NoWarn>$(NoWarn);1591;1587;1570;1572;1573;1574</NoWarn>
-               <DefineConstants>DESIGN_MODE;_MEASURE_TIME;_DEBUG_HIGHLIGHT_FOCUS</DefineConstants>             
+               <DefineConstants>DESIGN_MODE;MEASURE_TIME;_DEBUG_HIGHLIGHT_FOCUS</DefineConstants>              
                <EnableDefaultItems>false</EnableDefaultItems>
                <EnableDefaultCompileItems>false</EnableDefaultCompileItems>
                <!--<AllowUnsafeBlocks>true</AllowUnsafeBlocks>-->
index 3466b33b75c1779c97a11b43a3fd6a538de0bac5..d39121b04022ca04e2a3c6d391d5205398e84a8d 100644 (file)
@@ -100,6 +100,7 @@ namespace Crow
                public Interface (int width, int height, IntPtr glfwWindowHandle) : this (width, height, false, false)
                {
                        hWin = glfwWindowHandle;
+                       PerformanceMeasure.InitMeasures ();
                }
                public Interface (int width = 800, int height = 600, bool startUIThread = true, bool createSurface = true)
                {
@@ -110,14 +111,14 @@ namespace Crow
                        if (createSurface)
                                initSurface ();
 
+                       PerformanceMeasure.InitMeasures ();
+
                        if (startUIThread) {
                                Thread t = new Thread (InterfaceThread) {
                                        IsBackground = true
                                };
                                t.Start ();
-                       }
-
-                       PerformanceMeasure.InitMeasures ();
+                       }                       
                }
                #endregion
 
index 696699c11d8932cf3009d6f63313002b60a41327..75948da8e11ac87a7ca1381029c5f8adab1d4b7b 100644 (file)
@@ -14,6 +14,8 @@ namespace Crow.Text
         public readonly string ChangedText;
 
         public int End => Start + Length;
+
+               public int CharDiff => ChangedText.Length - Length;
         public TextChange (int position, int length, string changedText) {
             Start = position;
             Length = length;
index 47082698c9e1ab21fcbd33f51701b20278bcd903..17544ec76844fc1b166dcb1054c6203f461d0451 100644 (file)
@@ -396,7 +396,7 @@ namespace Crow
                        }
 
                        if (!string.IsNullOrEmpty (_text)) {
-                               Foreground.SetAsSource (IFace, gr);
+                               Foreground?.SetAsSource (IFace, gr);
 
                                TextExtents extents;
                                Span<byte> bytes = stackalloc byte[128];
index 954d4879d6445954deb5f3468e75b7457b3b9318..13bb41fe4f458182d8c1520c55f649c48c5d71f4 100644 (file)
@@ -5,7 +5,7 @@ using System.Linq;
 using Crow;
 using Glfw;
 
-namespace tests
+namespace Samples
 {
        public class BasicTests : SampleBase
        {
index 469e34735b6a355fb0f1464f556e8fb3e57cb5aa..019e3ce615945d4f240e51b96d32a6db4f79dde5 100644 (file)
@@ -4,6 +4,7 @@
 using System;
 using System.Runtime.CompilerServices;
 using Crow;
+using Samples;
 
 namespace BindingTest
 {
index 26a1eddfec73db0c1983382ebc34476046e5a778..1653f163d264884c30a1f4eca1faec117000c5bc 100644 (file)
@@ -5,6 +5,7 @@
 using System;
 using Crow.Cairo;
 using System.Threading;
+using Samples;
 
 namespace Crow
 {
diff --git a/Samples/DebugLogAnalyzer/src/Extensions.cs b/Samples/DebugLogAnalyzer/src/Extensions.cs
deleted file mode 100644 (file)
index 58047aa..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-
-
-using Crow;
-
-namespace DebugLogAnalyzer {
-       public static class Extensions {
-
-               public static CommandGroup GetCommands (this System.IO.DirectoryInfo di) =>
-                       new CommandGroup(
-                               new Command ("Set as root", ()=> {Program.CurrentProgramInstance.CurrentDir = di.FullName;})                            
-                       );              
-               public static CommandGroup GetCommands (this System.IO.FileInfo fi) =>
-                       new CommandGroup(
-                               new Command ("Delete", (sender0) => {
-                                       MessageBox.ShowModal (Program.CurrentProgramInstance, MessageBox.Type.YesNo, $"Delete {fi.Name}?").Yes += (sender, e) => {
-                                               System.IO.File.Delete(fi.FullName);
-                                               Widget listContainer = ((sender0 as Widget).LogicalParent as Widget).DataSource as Widget;
-                                               (listContainer.Parent as Group).RemoveChild(listContainer);
-                                       };
-                               })
-                       );              
-
-       }
-}
\ No newline at end of file
index 9c2e71174e92794a82436cf0223cec0c0f29d2ad..8cee874a17ba11458793483e310de280545afa8b 100644 (file)
@@ -12,12 +12,13 @@ using System.Collections.Generic;
 using Encoding = System.Text.Encoding;
 using Crow.DebugLogger;
 using System.Linq;
+using Samples;
 
 namespace DebugLogAnalyzer
 {
-       public class Program : SampleBase
+       public class Program : SampleBaseForEditor
        {
-               public static Program CurrentProgramInstance;
+               
                static void Main (string [] args)
                {
                        DbgLogger.IncludeEvents = DbgEvtType.None;
@@ -29,13 +30,8 @@ namespace DebugLogAnalyzer
                        }
                }
                protected override void OnInitialized () {
-                       initCommands ();
-
                        base.OnInitialized ();
 
-                       if (string.IsNullOrEmpty (CurrentDir))
-                               CurrentDir = Path.Combine (Directory.GetCurrentDirectory (), "Interfaces");
-
                        Load ("#Dbg.main.crow").DataSource = this;
                        //crowContainer = FindByName ("CrowContainer") as Container;
                        editor = FindByName ("tb") as TextBox;
@@ -92,25 +88,11 @@ namespace DebugLogAnalyzer
                                NotifyValueChanged (searchWidget);
                        }
                }
-
-
-
-               public Command CMDNew, CMDOpen, CMDSave, CMDSaveAs, CMDQuit, CMDShowLeftPane,
-                                       CMDUndo, CMDRedo, CMDCut, CMDCopy, CMDPaste, CMDHelp, CMDAbout, CMDOptions,
-                                       CMDGotoParentEvent, CMDEventHistoryForward, CMDEventHistoryBackward;
+               public Command CMDGotoParentEvent, CMDEventHistoryForward, CMDEventHistoryBackward;
                public CommandGroup EventCommands, DirectoryCommands;
-               public CommandGroup EditorCommands => new CommandGroup (CMDUndo, CMDRedo, CMDCut, CMDCopy, CMDPaste, CMDSave, CMDSaveAs);
-               void initCommands ()
+               protected override void initCommands ()
                {
-                       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);
+                       base.initCommands ();
 
                        CMDGotoParentEvent = new Command("parent", ()=> { CurrentEvent = CurrentEvent?.parentEvent; }, null, false);
                        CMDEventHistoryBackward = new Command("back.", currentEventHistoryGoBack, null, false);
@@ -212,29 +194,7 @@ namespace DebugLogAnalyzer
                        }
                }
                public List<DbgWidgetEvent> CurWidgetRootEvents => curWidget == null? new List<DbgWidgetEvent>() : curWidget.RootEvents;
-               public DbgEvtType RecordedEvents {
-                       get => Configuration.Global.Get<DbgEvtType> (nameof (RecordedEvents));
-                       set {
-                               if (RecordedEvents == value)
-                                       return;                         
-                               Configuration.Global.Set (nameof (RecordedEvents), value);                              
-                               if (DebugLogRecording)
-                                       DbgLogger.IncludeEvents = RecordedEvents;
-                               NotifyValueChanged(RecordedEvents);
-                       }
-               }
-               public DbgEvtType DiscardedEvents {
-                       get => Configuration.Global.Get<DbgEvtType> (nameof (DiscardedEvents));
-                       set {
-                               if (DiscardedEvents == value)
-                                       return;
-                               Configuration.Global.Set (nameof (DiscardedEvents), value);
-                               if (DebugLogRecording)
-                                       DbgLogger.DiscardEvents = DiscardedEvents;
-                               NotifyValueChanged(DiscardedEvents);
-                       }
-               }
-               public bool DebugLoggingEnabled => DbgLogger.IsEnabled;
+
                public bool DebugLogToFile {
                        get => Configuration.Global.Get<bool> (nameof(DebugLogToFile));
                        set {
@@ -253,15 +213,6 @@ namespace DebugLogAnalyzer
                                NotifyValueChanged (DebugLogFilePath);
                        }
                }*/
-               public bool DebugLogRecording {
-                       get => debugLogRecording;
-                       set {
-                               if (debugLogRecording == value)
-                                       return;
-                               debugLogRecording = value;
-                               NotifyValueChanged(debugLogRecording);
-                       }
-               }
                public bool DebugLogOnStartup {
                        get => Configuration.Global.Get<bool> (nameof(DebugLogOnStartup));
                        set {
@@ -273,45 +224,8 @@ namespace DebugLogAnalyzer
                }                               
 
                
-               const string _defaultFileName = "unnamed.txt";
-               string source = "", origSource;         
-               TextBox editor; 
-               Stack<TextChange> undoStack = new Stack<TextChange> ();
-               Stack<TextChange> redoStack = new Stack<TextChange> ();
-               TextSpan selection;
                Exception currentException;
-               public string CurrentDir {
-                       get => Configuration.Global.Get<string> (nameof (CurrentDir));
-                       set {
-                               if (CurrentDir == value)
-                                       return;
-                               Configuration.Global.Set (nameof (CurrentDir), value);
-                               NotifyValueChanged (CurrentDir);
-                       }
-               }
-               public string CurrentFile {
-                       get => Configuration.Global.Get<string> (nameof (CurrentFile));
-                       set {
-                               if (CurrentFile == value)
-                                       return;
-                               Configuration.Global.Set (nameof (CurrentFile), value);
-                               NotifyValueChanged (CurrentFile);
-                       }
-               }               
-               public new bool IsDirty => source != origSource;
-               public string Source {
-                       get => source;
-                       set {
-                               if (source == value)
-                                       return;
-                               source = value;
-                               CMDSave.CanExecute = IsDirty;
-                               NotifyValueChanged (source);
-                               NotifyValueChanged ("IsDirty", IsDirty);
-                       }
-               }
-               string SelectedText =>  
-                               selection.IsEmpty ? "" : Source.AsSpan (selection.Start, selection.Length).ToString ();
+               
                public Exception CurrentException {
                        get => currentException;
                        set {
@@ -326,195 +240,6 @@ namespace DebugLogAnalyzer
                public bool ShowError => currentException != null;
                public string CurrentExceptionMSG => currentException == null ? "" : currentException.Message;
 
-       
-
-               void undo () {
-                       if (undoStack.TryPop (out TextChange tch)) {
-                               redoStack.Push (tch.Inverse (source));
-                               CMDRedo.CanExecute = true;
-                               apply (tch);
-                               editor.SetCursorPosition (tch.End + tch.ChangedText.Length);
-                       }
-                       if (undoStack.Count == 0)
-                               CMDUndo.CanExecute = false;
-               }
-               void redo () {
-                       if (redoStack.TryPop (out TextChange tch)) {
-                               undoStack.Push (tch.Inverse (source));
-                               CMDUndo.CanExecute = true;
-                               apply (tch);
-                               editor.SetCursorPosition (tch.End + tch.ChangedText.Length);
-                       }
-                       if (redoStack.Count == 0)
-                               CMDRedo.CanExecute = false;
-               }
-               void cut () {
-                       copy ();
-                       applyChange (new TextChange (selection.Start, selection.Length, ""));
-               }
-               void copy () {
-                       Clipboard = SelectedText;
-               }
-               void paste () {                 
-                       applyChange (new TextChange (selection.Start, selection.Length, Clipboard));
-               }
-               bool disableTextChangedEvent = false;
-               void apply (TextChange change) {
-                       Span<char> tmp = stackalloc char[source.Length + (change.ChangedText.Length - change.Length)];
-                       ReadOnlySpan<char> src = source.AsSpan ();
-                       src.Slice (0, change.Start).CopyTo (tmp);
-                       if (!string.IsNullOrEmpty (change.ChangedText))
-                               change.ChangedText.AsSpan ().CopyTo (tmp.Slice (change.Start));
-                       src.Slice (change.End).CopyTo (tmp.Slice (change.Start + change.ChangedText.Length));
-                       disableTextChangedEvent = true;
-                       Source = tmp.ToString ();
-                       disableTextChangedEvent = false;                        
-               }       
-               void applyChange (TextChange change) {
-                       undoStack.Push (change.Inverse (source));
-                       redoStack.Clear ();
-                       CMDUndo.CanExecute = true;
-                       CMDRedo.CanExecute = false;
-                       apply (change);
-               }
-
-               void resetUndoRedo () {
-                       undoStack.Clear ();
-                       redoStack.Clear ();
-                       CMDUndo.CanExecute = false;
-                       CMDRedo.CanExecute = false;                     
-               }               
-
-               void onNewFile () {
-                       if (IsDirty) {                          
-                               MessageBox.ShowModal (this, MessageBox.Type.YesNo, "Current file has unsaved changes, are you sure?").Yes += (sender, e) => newFile ();
-                       } else
-                               newFile ();
-               }
-               void onSave ()
-               {
-                       if (!File.Exists (CurrentFile)) {
-                               onSaveAs ();
-                               return;
-                       }
-                       save ();
-               }
-               void onSaveAs ()
-               {
-                       string dir = Path.GetDirectoryName (CurrentFile);
-                       if (string.IsNullOrEmpty (dir))
-                               dir = Directory.GetCurrentDirectory ();
-                       LoadIMLFragment (@"<FileDialog Width='60%' Height='50%' Caption='Save as ...' CurrentDirectory='" +
-                               dir + "' SelectedFile='" +
-                               Path.GetFileName(CurrentFile) + "' OkClicked='saveFileDialog_OkClicked'/>").DataSource = this;
-               }
-               void saveFileDialog_OkClicked (object sender, EventArgs e)
-               {
-                       FileDialog fd = sender as FileDialog;
-
-                       if (string.IsNullOrEmpty (fd.SelectedFileFullPath))
-                               return;
-
-                       if (File.Exists(fd.SelectedFileFullPath)) {
-                               MessageBox mb = MessageBox.ShowModal (this, MessageBox.Type.YesNo, "File exists, overwrite?");
-                               mb.Yes += (sender2, e2) => {
-                                       CurrentFile = fd.SelectedFileFullPath;
-                                       save ();
-                               };
-                               return;
-                       }
-
-                       CurrentFile = fd.SelectedFileFullPath;
-                       save ();
-               }
-
-               void newFile()
-               {
-                       disableTextChangedEvent = true;
-                       Source = @"<Label Text='Hello World' Background='MediumSeaGreen' Margin='10'/>";
-                       disableTextChangedEvent = false;
-                       resetUndoRedo ();
-                       if (!string.IsNullOrEmpty (CurrentFile))
-                               CurrentFile = Path.Combine (Path.GetDirectoryName (CurrentFile), "newfile.crow");
-                       else
-                               CurrentFile = Path.Combine (CurrentDir, "newfile.crow");
-               }
-
-               void save () {
-                       using (Stream s = new FileStream(CurrentFile, FileMode.Create)) {
-                               s.WriteByte (0xEF);
-                               s.WriteByte (0xBB);
-                               s.WriteByte (0xBF);
-                               byte [] buff = Encoding.UTF8.GetBytes (source);
-                               s.Write (buff, 0, buff.Length);
-                       }
-                       origSource = source;
-                       NotifyValueChanged ("IsDirty", IsDirty);
-                       CMDSave.CanExecute = false;
-               }
-
-               void reloadFromFile () {                        
-                       disableTextChangedEvent = true;
-                       if (File.Exists (CurrentFile)) {
-                               using (Stream s = new FileStream (CurrentFile, FileMode.Open)) {
-                                       using (StreamReader sr = new StreamReader (s))
-                                               Source = origSource = sr.ReadToEnd ();
-                               }
-                       }
-                       disableTextChangedEvent = false;
-                       resetUndoRedo ();
-               }               
-
-               public void goUpDirClick (object sender, MouseButtonEventArgs e)
-               {
-                       string root = Directory.GetDirectoryRoot (CurrentDir);
-                       if (CurrentDir == root)
-                               return;
-                       CurrentDir = Directory.GetParent (CurrentDir).FullName;
-               }
-
-               void Dv_SelectedItemChanged (object sender, SelectionChangeEventArgs e)
-               {
-                       FileSystemInfo fi = e.NewValue as FileSystemInfo;
-                       if (fi == null)
-                               return;
-                       if (fi is DirectoryInfo)
-                               return;
-
-                       if (IsDirty) {
-                               MessageBox mb = MessageBox.ShowModal (this, MessageBox.Type.YesNo, "Current file has unsaved changes, are you sure?");
-                               mb.Yes += (mbsender, mbe) => { CurrentFile = fi.FullName; reloadFromFile (); };
-                               return;
-                       }
-
-                       CurrentFile = fi.FullName;
-                       reloadFromFile ();
-               }
-               void onTextChanged (object sender, TextChangeEventArgs e) {
-                       if (disableTextChangedEvent)
-                               return;
-                       applyChange (e.Change);
-               }               
-               
-               void onSelectedTextChanged (object sender, EventArgs e) {                       
-                       selection = (sender as Label).Selection;
-                       Console.WriteLine($"selection:{selection.Start} length:{selection.Length}");
-                       CMDCut.CanExecute = CMDCopy.CanExecute = !selection.IsEmpty;
-               }
-               void textView_KeyDown (object sender, Crow.KeyEventArgs e) {
-                       if (Ctrl) {
-                               if (e.Key == Glfw.Key.W) {
-                                       if (Shift)
-                                               CMDRedo.Execute ();
-                                       else
-                                               CMDUndo.Execute ();
-                               } else if (e.Key == Glfw.Key.S) {
-                                       onSave ();
-                               }
-                       }
-               }
-
-
 
         public override bool OnKeyDown (Key key) {
 
index ed5d857564b47f3a48a4ad448b5863056448b7d9..95d15a85790515fe647341fde48f73788858c195 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (c) 2013-2019  Bruyère Jean-Philippe <jp_bruyere@hotmail.com>
+// Copyright (c) 2013-2021  Bruyère Jean-Philippe <jp_bruyere@hotmail.com>
 //
 // This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
 
@@ -13,10 +13,11 @@ using System.Diagnostics;
 using Crow.Text;
 using System.Collections.Generic;
 using Encoding = System.Text.Encoding;
+using Samples;
 
 namespace ShowCase
 {
-       class Showcase : SampleBase
+       class Showcase : SampleBaseForEditor
        {
                static void Main ()
                {
@@ -28,42 +29,17 @@ namespace ShowCase
 
                        using (Showcase app = new Showcase ()) {
                                //app.Theme = @"C:\Users\Jean-Philippe\source\Crow\Themes\TestTheme";
+                               CurrentProgramInstance = app;
                                app.Run ();
                        }
                }
 
 
-               public Container crowContainer;
+               public Container crowContainer;         
 
-               public string CurrentDir {
-                       get => Configuration.Global.Get<string> (nameof (CurrentDir));
-                       set {
-                               if (CurrentDir == value)
-                                       return;
-                               Configuration.Global.Set (nameof (CurrentDir), value);
-                               NotifyValueChanged (CurrentDir);
-                       }
-               }
-               public string CurrentFile {
-                       get => Configuration.Global.Get<string> (nameof (CurrentFile));
-                       set {
-                               if (CurrentFile == value)
-                                       return;
-                               Configuration.Global.Set (nameof (CurrentFile), value);
-                               NotifyValueChanged (CurrentFile);
-                       }
-               }
-               
-               public Command CMDNew, CMDOpen, CMDSave, CMDSaveAs, CMDQuit, CMDShowLeftPane,
-                                       CMDUndo, CMDRedo, CMDCut, CMDCopy, CMDPaste, CMDHelp, CMDAbout, CMDOptions;
-
-               const string _defaultFileName = "unnamed.txt";
-               string source = "", origSource;         
-               TextBox editor;
                Stopwatch reloadChrono = new Stopwatch ();
 
-               public new bool IsDirty => source != origSource;
-               public string Source {
+               public override string Source {
                        get => source;
                        set {
                                if (source == value)
@@ -75,153 +51,8 @@ namespace ShowCase
                                NotifyValueChanged (source);
                                NotifyValueChanged ("IsDirty", IsDirty);
                        }
-               }
-               public CommandGroup EditorCommands => new CommandGroup (CMDUndo, CMDRedo, CMDCut, CMDCopy, CMDPaste, CMDSave, CMDSaveAs);
-
-               Stack<TextChange> undoStack = new Stack<TextChange> ();
-               Stack<TextChange> redoStack = new Stack<TextChange> ();
-               TextSpan selection;
-               string SelectedText =>  
-                               selection.IsEmpty ? "" : Source.AsSpan (selection.Start, selection.Length).ToString ();
-
-               void undo () {
-                       if (undoStack.TryPop (out TextChange tch)) {
-                               redoStack.Push (tch.Inverse (source));
-                               CMDRedo.CanExecute = true;
-                               apply (tch);
-                               editor.SetCursorPosition (tch.End + tch.ChangedText.Length);
-                       }
-                       if (undoStack.Count == 0)
-                               CMDUndo.CanExecute = false;
-               }
-               void redo () {
-                       if (redoStack.TryPop (out TextChange tch)) {
-                               undoStack.Push (tch.Inverse (source));
-                               CMDUndo.CanExecute = true;
-                               apply (tch);
-                               editor.SetCursorPosition (tch.End + tch.ChangedText.Length);
-                       }
-                       if (redoStack.Count == 0)
-                               CMDRedo.CanExecute = false;
-               }
-               void cut () {
-                       copy ();
-                       applyChange (new TextChange (selection.Start, selection.Length, ""));
-               }
-               void copy () {
-                       Clipboard = SelectedText;
-               }
-               void paste () {                 
-                       applyChange (new TextChange (selection.Start, selection.Length, Clipboard));
-               }
-               bool disableTextChangedEvent = false;
-               void apply (TextChange change) {
-                       Span<char> tmp = stackalloc char[source.Length + (change.ChangedText.Length - change.Length)];
-                       ReadOnlySpan<char> src = source.AsSpan ();
-                       src.Slice (0, change.Start).CopyTo (tmp);
-                       if (!string.IsNullOrEmpty (change.ChangedText))
-                               change.ChangedText.AsSpan ().CopyTo (tmp.Slice (change.Start));
-                       src.Slice (change.End).CopyTo (tmp.Slice (change.Start + change.ChangedText.Length));
-                       disableTextChangedEvent = true;
-                       Source = tmp.ToString ();
-                       disableTextChangedEvent = false;                        
                }       
-               
-               void initCommands ()
-               {
-                       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 () {
-                       if (IsDirty) {
-                               MessageBox mb = MessageBox.ShowModal (this, MessageBox.Type.YesNo, "Current file has unsaved changes, are you sure?");
-                               mb.Yes += (sender, e) => newFile ();
-                       } else
-                               newFile ();
-               }
-               void onSave ()
-               {
-                       if (!File.Exists (CurrentFile)) {
-                               onSaveAs ();
-                               return;
-                       }
-                       save ();
-               }
-               void onSaveAs ()
-               {
-                       string dir = Path.GetDirectoryName (CurrentFile);
-                       if (string.IsNullOrEmpty (dir))
-                               dir = Directory.GetCurrentDirectory ();
-                       LoadIMLFragment (@"<FileDialog Width='60%' Height='50%' Caption='Save as ...' CurrentDirectory='" +
-                               dir + "' SelectedFile='" +
-                               Path.GetFileName(CurrentFile) + "' OkClicked='saveFileDialog_OkClicked'/>").DataSource = this;
-               }
-               void saveFileDialog_OkClicked (object sender, EventArgs e)
-               {
-                       FileDialog fd = sender as FileDialog;
-
-                       if (string.IsNullOrEmpty (fd.SelectedFileFullPath))
-                               return;
-
-                       if (File.Exists(fd.SelectedFileFullPath)) {
-                               MessageBox mb = MessageBox.ShowModal (this, MessageBox.Type.YesNo, "File exists, overwrite?");
-                               mb.Yes += (sender2, e2) => {
-                                       CurrentFile = fd.SelectedFileFullPath;
-                                       save ();
-                               };
-                               return;
-                       }
-
-                       CurrentFile = fd.SelectedFileFullPath;
-                       save ();
-               }
-
-               void newFile()
-               {
-                       disableTextChangedEvent = true;
-                       Source = @"<Label Text='Hello World' Background='MediumSeaGreen' Margin='10'/>";
-                       disableTextChangedEvent = false;
-                       resetUndoRedo ();
-                       if (!string.IsNullOrEmpty (CurrentFile))
-                               CurrentFile = Path.Combine (Path.GetDirectoryName (CurrentFile), "newfile.crow");
-                       else
-                               CurrentFile = Path.Combine (CurrentDir, "newfile.crow");
-               }
 
-
-               void save () {
-                       using (Stream s = new FileStream(CurrentFile, FileMode.Create)) {
-                               s.WriteByte (0xEF);
-                               s.WriteByte (0xBB);
-                               s.WriteByte (0xBF);
-                               byte [] buff = Encoding.UTF8.GetBytes (source);
-                               s.Write (buff, 0, buff.Length);
-                       }
-                       origSource = source;
-                       NotifyValueChanged ("IsDirty", IsDirty);
-                       CMDSave.CanExecute = false;
-               }
-
-               void reloadFromFile () {
-                       hideError ();
-                       disableTextChangedEvent = true;
-                       if (File.Exists (CurrentFile)) {
-                               using (Stream s = new FileStream (CurrentFile, FileMode.Open)) {
-                                       using (StreamReader sr = new StreamReader (s))
-                                               Source = origSource = sr.ReadToEnd ();
-                               }
-                       }
-                       disableTextChangedEvent = false;
-                       resetUndoRedo ();
-               }
                void reloadFromSource () {
                        hideError ();
                        Widget g = null;
@@ -241,12 +72,6 @@ namespace ShowCase
                        }
                }
 
-               void resetUndoRedo () {
-                       undoStack.Clear ();
-                       redoStack.Clear ();
-                       CMDUndo.CanExecute = false;
-                       CMDRedo.CanExecute = false;                     
-               }
                void showError (Exception ex) {
                        NotifyValueChanged ("ErrorMessage", ex);
                        NotifyValueChanged ("ShowError", true);
@@ -255,70 +80,12 @@ namespace ShowCase
                        NotifyValueChanged ("ShowError", false);
                }
 
-               public void goUpDirClick (object sender, MouseButtonEventArgs e)
-               {
-                       string root = Directory.GetDirectoryRoot (CurrentDir);
-                       if (CurrentDir == root)
-                               return;
-                       CurrentDir = Directory.GetParent (CurrentDir).FullName;
-               }
-
-               void Dv_SelectedItemChanged (object sender, SelectionChangeEventArgs e)
-               {
-                       FileSystemInfo fi = e.NewValue as FileSystemInfo;
-                       if (fi == null)
-                               return;
-                       if (fi is DirectoryInfo)
-                               return;
 
-                       if (IsDirty) {
-                               MessageBox mb = MessageBox.ShowModal (this, MessageBox.Type.YesNo, "Current file has unsaved changes, are you sure?");
-                               mb.Yes += (mbsender, mbe) => { CurrentFile = fi.FullName; reloadFromFile (); };
-                               return;
-                       }
 
-                       CurrentFile = fi.FullName;
-                       reloadFromFile ();
-               }
-               void onTextChanged (object sender, TextChangeEventArgs e) {
-                       if (disableTextChangedEvent)
-                               return;
-                       applyChange (e.Change);
-               }
-               void applyChange (TextChange change) {
-                       undoStack.Push (change.Inverse (source));
-                       redoStack.Clear ();
-                       CMDUndo.CanExecute = true;
-                       CMDRedo.CanExecute = false;
-                       apply (change);
-               }
-               
-               void onSelectedTextChanged (object sender, EventArgs e) {                       
-                       selection = (sender as Label).Selection;
-                       Console.WriteLine($"selection:{selection.Start} length:{selection.Length}");
-                       CMDCut.CanExecute = CMDCopy.CanExecute = !selection.IsEmpty;
-               }
-               void textView_KeyDown (object sender, Crow.KeyEventArgs e) {
-                       if (Ctrl) {
-                               if (e.Key == Glfw.Key.W) {
-                                       if (Shift)
-                                               CMDRedo.Execute ();
-                                       else
-                                               CMDUndo.Execute ();
-                               } else if (e.Key == Glfw.Key.S) {
-                                       onSave ();
-                               }
-                       }
-               }
 
                protected override void OnInitialized () {
-                       initCommands ();
-
                        base.OnInitialized ();
 
-                       if (string.IsNullOrEmpty (CurrentDir))
-                               CurrentDir = Path.Combine (Directory.GetCurrentDirectory (), "Interfaces");
-
                        Load ("#ShowCase.showcase.crow").DataSource = this;
                        crowContainer = FindByName ("CrowContainer") as Container;
                        editor = FindByName ("tb") as TextBox;
@@ -341,29 +108,7 @@ namespace ShowCase
                        reloadChrono.Reset ();
                }
 
-               public DbgEvtType RecordedEvents {
-                       get => Configuration.Global.Get<DbgEvtType> (nameof (RecordedEvents));
-                       set {
-                               if (RecordedEvents == value)
-                                       return;                         
-                               Configuration.Global.Set (nameof (RecordedEvents), value);                              
-                               if (DebugLogRecording)
-                                       DbgLogger.IncludeEvents = RecordedEvents;
-                               NotifyValueChanged(RecordedEvents);
-                       }
-               }
-               public DbgEvtType DiscardedEvents {
-                       get => Configuration.Global.Get<DbgEvtType> (nameof (DiscardedEvents));
-                       set {
-                               if (DiscardedEvents == value)
-                                       return;
-                               Configuration.Global.Set (nameof (DiscardedEvents), value);
-                               if (DebugLogRecording)
-                                       DbgLogger.DiscardEvents = DiscardedEvents;
-                               NotifyValueChanged(DiscardedEvents);
-                       }
-               }
-               public bool DebugLoggingEnabled => DbgLogger.IsEnabled;
+
                public bool DebugLogToFile {
                        get => !DbgLogger.ConsoleOutput;
                        set {
@@ -383,16 +128,6 @@ namespace ShowCase
                                NotifyValueChanged (DebugLogFilePath);
                        }
                }
-               bool debugLogRecording;
-               public bool DebugLogRecording {
-                       get => debugLogRecording;
-                       set {
-                               if (debugLogRecording == value)
-                                       return;
-                               debugLogRecording = value;
-                               NotifyValueChanged(debugLogRecording);
-                       }
-               }               
 
         public override bool OnKeyDown (Key key) {
 
index 529c47722721a18ffa18b3f0eef6f0aae307db9e..1236b705a249cae9cbd3c5198cf6e1d12b656c10 100644 (file)
@@ -6,7 +6,57 @@
                                                 Background="Jet" MouseEnter="{Background=Grey}" MouseLeave="{Background=Jet}" />                       
                        <TextBox Text="{²CurrentDir}" Margin="2"/>
                </HorizontalStack>              
-               <DirectoryView Margin="1" Name="dv" CurrentDirectory="{CurrentDir}" SelectedItemChanged="Dv_SelectedItemChanged"/>
+               <DirectoryView Margin="1" Name="dv" CurrentDirectory="{CurrentDir}" SelectedItemChanged="Dv_SelectedItemChanged">
+                                       <Template>
+                                               <TreeView IsRoot="true" Name="treeView" Data="{./FileSystemEntries}" Background="{./Background}"
+                                                               SelectedItemChanged="./onSelectedItemChanged">
+                                                       <ItemTemplate DataType="System.IO.FileInfo">
+                                                               <ListItem CornerRadius="2" Margin="0" Height="Fit" Width="Stretched"
+                                                                               ContextCommands="{GetCommands}" 
+                                                                               Selected="{Background=${ControlHighlight}}"
+                                                                               Unselected="{Background=Transparent}">
+                                                                       <HorizontalStack>
+                                                                               <Image Margin="1" Width="14" Height="14" Path="#Crow.Icons.file.svg"/>
+                                                                               <Label Text="{Name}" Width="Stretched"/>
+                                                                       </HorizontalStack>
+                                                               </ListItem>
+                                                       </ItemTemplate>
+                                                       <ItemTemplate DataType="System.IO.DirectoryInfo" Data="GetFileSystemInfosOrdered">
+                                                               <ListItem ContextCommands="{GetCommands}"
+                                                                               Selected="{/exp.Background=${ControlHighlight}}"
+                                                                               Unselected="{/exp.Background=Transparent}">
+                                                                       <Expandable Name="exp" Caption="{Name}" MouseDoubleClick="/onClickForExpand">
+                                                                               <Template>
+                                                                                       <VerticalStack>
+                                                                                               <Border CornerRadius="2" Margin="0" Height="Fit" MouseDoubleClick="./onClickForExpand"
+                                                                                                               Foreground="Transparent"
+                                                                                                               MouseEnter="{Foreground=DimGrey}"
+                                                                                                               MouseLeave="{Foreground=Transparent}">
+                                                                                                       <HorizontalStack Background="{./Background}" Spacing="1">
+                                                                                                               <Image Margin="1" Width="9" Height="9" Focusable="true" MouseDown="./onClickForExpand"
+                                                                                                                       Path="{./Image}"
+                                                                                                                       Visible="{./IsExpandable}"
+                                                                                                                       SvgSub="{./IsExpanded}"
+                                                                                                                       MouseEnter="{Background=LightGrey}"
+                                                                                                                       MouseLeave="{Background=Transparent}"/>
+                                                                                                               <Image Margin="1" Width="16" Height="16"
+                                                                                                                       Path="#Crow.Icons.folder.svg" SvgSub="{./IsExpanded}"/>
+                                                                                                               <Label Text="{./Caption}"/>
+                                                                                                       </HorizontalStack>
+                                                                                               </Border>
+                                                                                               <Container Name="Content" Visible="false"/>
+                                                                                       </VerticalStack>
+                                                                               </Template>
+                                                                               <HorizontalStack Height="Fit">
+                                                                                       <Widget Width="12" Height="10"/>
+                                                                                       <VerticalStack Height="Fit" Name="ItemsContainer"/>
+                                                                               </HorizontalStack>
+                                                                       </Expandable>
+                                                               </ListItem>
+                                                       </ItemTemplate>
+                                               </TreeView>
+                                       </Template>             
+                               </DirectoryView>
        </VerticalStack>
        <Splitter Width="6" />
        <VerticalStack>
@@ -31,9 +81,9 @@
                                <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="{CMDCut}" />
                                <Button Style="IcoButton" Command="{CMDCopy}" />
                                <Button Style="IcoButton" Command="{CMDPaste}" />-->
                                <Popper IsVisible="{DebugLoggingEnabled}" Fit="true">
index b9b0ae9078e7c302ff77bb3fb8a1a77094386338..7b9d5c103f53f764c53d18b9d4ff06bcad4e1a24 100644 (file)
@@ -11,6 +11,7 @@ using System.Threading.Tasks;
 using System.Linq;
 using System.Diagnostics.CodeAnalysis;
 using System.Reflection;
+using System.Collections;
 
 namespace Crow
 {
@@ -30,8 +31,8 @@ namespace Crow
 
                }
                ListBox overlay;
-               List<String> suggestions;
-               public List<String> Suggestions {
+               IList suggestions;
+               public IList Suggestions {
                        get => suggestions;
                        set {
                                suggestions = value;
@@ -49,19 +50,25 @@ namespace Crow
                                        .Select (s => s.Name).ToArray ();
 
 
-               string [] getAllCrowTypeMembers (string crowTypeName) {
+               IEnumerable<MemberInfo> getAllCrowTypeMembers (string crowTypeName) {
                        Type crowType = IML.Instantiator.GetWidgetTypeFromName (crowTypeName);
                        return crowType.GetMembers (BindingFlags.Public | BindingFlags.Instance).
                                Where (m=>((m is PropertyInfo pi && pi.CanWrite) || (m is EventInfo)) &&
-                                               m.GetCustomAttribute<XmlIgnoreAttribute>() == null).Select (mb=>mb.Name).ToArray();
+                                               m.GetCustomAttribute<XmlIgnoreAttribute>() == null);
                }
+               MemberInfo getCrowTypeMember (string crowTypeName, string memberName) {
+                       Type crowType = IML.Instantiator.GetWidgetTypeFromName (crowTypeName);                  
+                       return crowType.GetMember (memberName, BindingFlags.Public | BindingFlags.Instance).FirstOrDefault ();
+               }               
+
                public override void OnTextChanged(object sender, TextChangeEventArgs e)
                {
                        base.OnTextChanged(sender, e);
                        //Task.Run(()=>parse());
 
                        parse();
-                       tryGetSuggestions ();
+                       if (HasFocus)
+                               tryGetSuggestions ();
 
                        //Console.WriteLine ($"{pos}: {suggestionTok.AsString (_text)} {suggestionTok}");
                }
@@ -80,13 +87,54 @@ namespace Crow
                                Suggestions = allWidgetNames.Where (s => s.StartsWith (currentToken.AsString (_text), StringComparison.OrdinalIgnoreCase)).ToList ();
                        } else if (currentNode is AttributeSyntax attribNode) {
                                if (currentNode.Parent is ElementTagSyntax eltTag) {
-                                       if (currentToken.Type == TokenType.AttributeName && eltTag.NameToken.HasValue) {
-                                               Suggestions = getAllCrowTypeMembers (eltTag.NameToken.Value.AsString (_text))
-                                                       .Where (s => s.StartsWith (currentToken.AsString (_text), StringComparison.OrdinalIgnoreCase)).ToList ();
+                                       if (eltTag.NameToken.HasValue) {
+                                               if (currentToken.Type == TokenType.AttributeName) {
+                                                       Suggestions = getAllCrowTypeMembers (eltTag.NameToken.Value.AsString (_text))
+                                                               .Where (s => s.Name.StartsWith (currentToken.AsString (_text), StringComparison.OrdinalIgnoreCase)).ToList ();
+                                               } else if (attribNode.NameToken.HasValue) {
+                                                       if (currentToken.Type == TokenType.AttributeValue) {
+                                                               MemberInfo mi = getCrowTypeMember (
+                                                                       eltTag.NameToken.Value.AsString (_text), attribNode.NameToken.Value.AsString (_text));
+                                                               if (mi is PropertyInfo pi) {
+                                                                       if (pi.PropertyType.IsEnum)
+                                                                               Suggestions = Enum.GetNames (pi.PropertyType)
+                                                                                       .Where (s => s.StartsWith (currentToken.AsString (_text), StringComparison.OrdinalIgnoreCase)).ToList ();
+                                                                       else if (pi.PropertyType == typeof(bool))
+                                                                               Suggestions = (new string[] {"true", "false"}).
+                                                                                       Where (s => s.StartsWith (currentToken.AsString (_text), StringComparison.OrdinalIgnoreCase)).ToList ();
+                                                                       else if (pi.PropertyType == typeof (Measure))
+                                                                               Suggestions = (new string[] {"Stretched", "Fit"}).
+                                                                                       Where (s => s.StartsWith (currentToken.AsString (_text), StringComparison.OrdinalIgnoreCase)).ToList ();
+                                                                       else if (pi.PropertyType == typeof (Fill)) 
+                                                                               Suggestions = FastEnumUtility.FastEnum.GetValues<Colors> ()
+                                                                                       .Where (s => s.ToString().StartsWith (currentToken.AsString (_text), StringComparison.OrdinalIgnoreCase)).ToList ();
+                                                               }
+                                                       } else if (currentToken.Type == TokenType.AttributeValueOpen) {
+                                                               MemberInfo mi = getCrowTypeMember (
+                                                                       eltTag.NameToken.Value.AsString (_text), attribNode.NameToken.Value.AsString (_text));
+                                                               if (mi is PropertyInfo pi) {
+                                                                       if (pi.PropertyType.IsEnum)
+                                                                               Suggestions = Enum.GetNames (pi.PropertyType).ToList ();
+                                                                       else if (pi.PropertyType == typeof(bool))
+                                                                               Suggestions = new List<string> (new string[] {"true", "false"});
+                                                                       else if (pi.PropertyType == typeof (Fill)) 
+                                                                               Suggestions = FastEnumUtility.FastEnum.GetValues<Colors> ().ToList ();
+                                                                       else if (pi.PropertyType == typeof (Measure))
+                                                                               Suggestions = new List<string> (new string[] {"Stretched", "Fit"});
+                                                               }
+                                                       }
+                                               }
                                        }
                                }
-                       } else if (currentNode is ElementStartTagSyntax eltStartTag) {
-                               Suggestions = getAllCrowTypeMembers (eltStartTag.NameToken.Value.AsString (_text)).ToList ();
+                       } else if (currentToken.Type != TokenType.AttributeValueClose && 
+                                       currentToken.Type != TokenType.EmptyElementClosing && 
+                                       currentToken.Type != TokenType.ClosingSign && 
+                                       currentNode is ElementStartTagSyntax eltStartTag) {
+                               if (currentToken.Type == TokenType.AttributeName)
+                                       Suggestions = getAllCrowTypeMembers (eltStartTag.NameToken.Value.AsString (_text))
+                                               .Where (s => s.Name.StartsWith (currentToken.AsString (_text), StringComparison.OrdinalIgnoreCase)).ToList ();
+                               else
+                                       Suggestions = getAllCrowTypeMembers (eltStartTag.NameToken.Value.AsString (_text)).ToList ();
                        } else {
                                /*SyntaxNode curNode = source.FindNodeIncludingPosition (pos);
                                Console.WriteLine ($"Current Node: {curNode}");
@@ -101,7 +149,35 @@ namespace Crow
                        lock (IFace.UpdateMutex) {
                                if (overlay == null) {
                                        overlay = IFace.LoadIMLFragment<ListBox>(@"
-                                               <ListBox Style='suggestionsListBox' Data='{Suggestions}' />
+                                               <ListBox Style='suggestionsListBox' Data='{Suggestions}' >
+                                                       <ItemTemplate>
+                                                               <ListItem Height='Fit' Margin='0' Focusable='false' HorizontalAlignment='Left' 
+                                                                                               Selected = '{Background=${ControlHighlight}}'
+                                                                                               Unselected = '{Background=Transparent}'>
+                                                                       <Label Text='{}' HorizontalAlignment='Left' />
+                                                               </ListItem>                                                     
+                                                       </ItemTemplate>
+                                                       <ItemTemplate DataType='MemberInfo'>
+                                                               <ListItem Height='Fit' Margin='0' Focusable='false' HorizontalAlignment='Left' 
+                                                                                               Selected = '{Background=${ControlHighlight}}'
+                                                                                               Unselected = '{Background=Transparent}'>
+                                                                       <HorizontalStack>
+                                                                               <Image Picture='{GetIcon}' Width='16' Height='16'/>
+                                                                               <Label Text='{Name}' HorizontalAlignment='Left' />
+                                                                       </HorizontalStack>
+                                                               </ListItem>                                                     
+                                                       </ItemTemplate>
+                                                       <ItemTemplate DataType='Colors'>
+                                                               <ListItem Height='Fit' Margin='0' Focusable='false' HorizontalAlignment='Left' 
+                                                                                               Selected = '{Background=${ControlHighlight}}'
+                                                                                               Unselected = '{Background=Transparent}'>
+                                                                       <HorizontalStack>
+                                                                               <Widget Background='{}' Width='20' Height='14'/>
+                                                                               <Label Text='{}' HorizontalAlignment='Left' />
+                                                                       </HorizontalStack>
+                                                               </ListItem>                                                     
+                                                       </ItemTemplate>
+                                               </ListBox>
                                        ");
                                        overlay.DataSource = this;
                                        overlay.Loaded += (sender, arg) => (sender as ListBox).SelectedIndex = 0;                               
@@ -116,12 +192,25 @@ namespace Crow
                        overlay.IsVisible = false;
                }
                void completeToken () {                 
-                       string selectedSugg = overlay.SelectedItem as string;
+                       string selectedSugg = overlay.SelectedItem is MemberInfo mi ?
+                               mi.Name : overlay.SelectedItem?.ToString ();
                        if (selectedSugg == null)
                                return;
-                       if (currentToken.Type == TokenType.ElementOpen || currentToken.Type == TokenType.WhiteSpace)
+                       if (currentToken.Type == TokenType.ElementOpen ||
+                               currentToken.Type == TokenType.WhiteSpace ||
+                               currentToken.Type == TokenType.AttributeValueOpen)
                                update (new TextChange (currentToken.End, 0, selectedSugg));
-                       else
+                       else if (currentToken.Type == TokenType.AttributeName && currentNode is AttributeSyntax attrib) {
+                                       if (attrib.ValueToken.HasValue) {
+                                               TextChange tc = new TextChange (currentToken.Start, currentToken.Length, selectedSugg);                                         
+                                               update (tc);
+                                               selectionStart = lines.GetLocation (attrib.ValueToken.Value.Start + tc.CharDiff + 1);
+                                               CurrentLoc = lines.GetLocation (attrib.ValueToken.Value.End + tc.CharDiff - 1);
+                                       } else {
+                                               update (new TextChange (currentToken.Start, currentToken.Length, selectedSugg + "=\"\""));
+                                               MoveLeft ();
+                                       }                                       
+                       } else 
                                update (new TextChange (currentToken.Start, currentToken.Length, selectedSugg));
                        hideOverlay ();
                }
@@ -129,6 +218,7 @@ namespace Crow
                        hideOverlay ();
                        base.onMouseDown (sender, e);
                }
+               
                public override void onKeyDown(object sender, KeyEventArgs e)
                {
                        if (suggestionsActive) {
@@ -149,6 +239,8 @@ namespace Crow
                                        overlay.onKeyDown (this, e);
                                        return;
                                case Key.Tab:
+                               case Key.Enter:
+                               case Key.KeypadEnter:
                                        completeToken ();
                                        return;
                                }
diff --git a/Samples/common/src/Extensions.cs b/Samples/common/src/Extensions.cs
new file mode 100644 (file)
index 0000000..b4b0a1e
--- /dev/null
@@ -0,0 +1,27 @@
+
+
+using System.Reflection;
+using Crow;
+
+namespace Samples {
+       public static class Extensions {
+
+               public static CommandGroup GetCommands (this System.IO.DirectoryInfo di) =>
+                       new CommandGroup(
+                               new Command ("Set as root", ()=> {SampleBaseForEditor.CurrentProgramInstance.CurrentDir = di.FullName;})                                
+                       );              
+               public static CommandGroup GetCommands (this System.IO.FileInfo fi) =>
+                       new CommandGroup(
+                               new Command ("Delete", (sender0) => {
+                                       MessageBox.ShowModal (SampleBaseForEditor.CurrentProgramInstance, MessageBox.Type.YesNo, $"Delete {fi.Name}?").Yes += (sender, e) => {
+                                               System.IO.File.Delete(fi.FullName);
+                                               Widget listContainer = ((sender0 as Widget).LogicalParent as Widget).DataSource as Widget;
+                                               (listContainer.Parent as Group).RemoveChild(listContainer);
+                                       };
+                               })
+                       );
+               public static Picture GetIcon (this MemberInfo mi)
+                       => mi is EventInfo ? new BmpPicture("#Icons.event.png") : new BmpPicture("#Icons.property.png");
+
+       }
+}
\ No newline at end of file
index fd410eafc1ddfcce41c9989a8b138407ef37c26f..a38e1558c464f12fdf99f9a577242c7606554fc8 100644 (file)
@@ -128,8 +128,12 @@ namespace Crow
                                                                Exceptions.Add (new SyntaxException  ("Extra equal sign in attribute syntax", iter.Current));
                                                        else
                                                                attrib.EqualToken = iter.Current;
-                                               else if (iter.Current.Type == TokenType.AttributeValue) {
-                                                       attrib.ValueToken = attrib.EndToken = iter.Current;
+                                               else if (iter.Current.Type == TokenType.AttributeValueOpen)
+                                                       attrib.ValueOpenToken = iter.Current;
+                                               else if (iter.Current.Type == TokenType.AttributeValue)
+                                                       attrib.ValueToken = iter.Current;
+                                               else if (iter.Current.Type == TokenType.AttributeValueClose) {
+                                                       attrib.ValueCloseToken = attrib.EndToken = iter.Current;
                                                        CurrentNode = CurrentNode.Parent;
                                                } else {
                                                        Exceptions.Add (new SyntaxException  ("Unexpected Token", iter.Current));
@@ -232,7 +236,7 @@ namespace Crow
                public  XmlSource Source => Root.source;
                public bool Contains (int pos) =>
                        EndToken.HasValue ?
-                               StartToken.Start <= pos && EndToken.Value.End >= pos : false;
+                               StartToken.Start <= pos && EndToken.Value.End > pos : false;
 
                public void Dump (int level = 0) {
                        Console.WriteLine ($"{new string('\t', level)}{this}");
@@ -303,8 +307,10 @@ namespace Crow
        public class AttributeSyntax : SyntaxNode {
                public Token? NameToken { get; internal set; }
                public Token? EqualToken { get; internal set; }
+               public Token? ValueOpenToken { get; internal set; }             
+               public Token? ValueCloseToken { get; internal set; }            
                public Token? ValueToken { get; internal set; }         
                public AttributeSyntax (Token startTok) : base  (startTok) {}
-               public override bool IsComplete => base.IsComplete & NameToken.HasValue & EqualToken.HasValue & ValueToken.HasValue;
+               public override bool IsComplete => base.IsComplete & NameToken.HasValue & EqualToken.HasValue & ValueToken.HasValue & ValueOpenToken.HasValue & ValueCloseToken.HasValue;
        }
 }
\ No newline at end of file
index f9d7bcc69afde90ab216fe5900c45a2a5d12d63c..3289d5ae633d58c2f280fd8f7a79362f651c7fb7 100644 (file)
@@ -26,7 +26,9 @@ namespace Crow
                PI_End                                  = 0x0402,// '?>'
                Operator                                = 0x0800,
                EqualSign                               = 0x0801,
-               AttributeValue                  = 0x2000,
+               AttributeValue                  = 0x2000,
+               AttributeValueOpen              = 0x2001,
+               AttributeValueClose             = 0x2002,
                Keyword                                 = 0x1000,
                ElementOpen                     = 0x0403,// '<'
                EndElementOpen                  = 0x0404,// '</'
index f520dcf30071948f512ceafe3ebd755e3d87eb47..f70aec24afd93e2926e09eb200007e6c972c4888 100644 (file)
@@ -25,9 +25,10 @@ namespace Crow
                        syntaxAnalyser.Process ();
                        sw.Stop();
 
-                       foreach (Token t in Tokens)
+                       /*foreach (Token t in Tokens)
                                Console.WriteLine ($"{t,-40} {Source.AsSpan(t.Start, t.Length).ToString()}");
-                       syntaxAnalyser.Root.Dump();
+                       syntaxAnalyser.Root.Dump();*/
+                       
                        Console.WriteLine ($"Syntax Analysis done in {sw.ElapsedMilliseconds}(ms) {sw.ElapsedTicks}(ticks)");
                        foreach (SyntaxException ex in syntaxAnalyser.Exceptions)
                                Console.WriteLine ($"{ex}");
@@ -212,9 +213,13 @@ namespace Crow
                                        case '\'':
                                        case '"':
                                                char q = reader.Read();
-                                               if (reader.TryReadUntil (q))
+                                               addTok (ref reader, TokenType.AttributeValueOpen);
+                                               if (reader.TryReadUntil (q)) {
+                                                       addTok (ref reader, TokenType.AttributeValue);
                                                        reader.Advance ();
-                                               addTok (ref reader, TokenType.AttributeValue);                                          
+                                                       addTok (ref reader, TokenType.AttributeValueClose);
+                                               } else
+                                                       addTok (ref reader, TokenType.AttributeValue);
                                                break;
                                        case '=':
                                                reader.Advance();
index 1e849d6fadc3e263b33daddf68e3e00916d3738e..0c381048696b7c1b2a0cd2a00163e5ecdd3bb415 100644 (file)
@@ -10,7 +10,7 @@ using System.Runtime.CompilerServices;
 using System.Runtime.InteropServices;
 using System.Threading;
 
-namespace Crow
+namespace Samples
 {
        public class SampleBase : Interface
        {
@@ -356,6 +356,10 @@ namespace Crow
                        initCommands();
                        base.OnInitialized();
                }
+               protected override void processDrawing(Crow.Cairo.Context ctx)
+               {
+                       base.processDrawing(ctx);
+               }
 
                public override bool OnKeyDown(Key key)
                {
diff --git a/Samples/common/src/SampleBaseForEditor.cs b/Samples/common/src/SampleBaseForEditor.cs
new file mode 100644 (file)
index 0000000..4af718a
--- /dev/null
@@ -0,0 +1,312 @@
+// Copyright (c) 2013-2021  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 Crow;
+using System.IO;
+using System.Text;
+using Crow.IML;
+using System.Runtime.CompilerServices;
+using Glfw;
+using System.Diagnostics;
+using Crow.Text;
+using System.Collections.Generic;
+using Encoding = System.Text.Encoding;
+
+namespace Samples
+{
+       public class SampleBaseForEditor : SampleBase
+       {
+               public static SampleBaseForEditor CurrentProgramInstance;
+
+               protected override void OnInitialized () {
+                       initCommands ();
+
+                       base.OnInitialized ();
+
+                       if (string.IsNullOrEmpty (CurrentDir))
+                               CurrentDir = Path.Combine (Directory.GetCurrentDirectory (), "Interfaces");
+                       
+               }
+
+               protected const string _defaultFileName = "unnamed.txt";
+               protected string source = "", origSource;               
+               protected TextBox editor;
+               bool debugLogRecording;
+
+
+               public string CurrentDir {
+                       get => Configuration.Global.Get<string> (nameof (CurrentDir));
+                       set {
+                               if (CurrentDir == value)
+                                       return;
+                               Configuration.Global.Set (nameof (CurrentDir), value);
+                               NotifyValueChanged (CurrentDir);
+                       }
+               }
+               public string CurrentFile {
+                       get => Configuration.Global.Get<string> (nameof (CurrentFile));
+                       set {
+                               if (CurrentFile == value)
+                                       return;
+                               Configuration.Global.Set (nameof (CurrentFile), value);
+                               NotifyValueChanged (CurrentFile);
+                       }
+               }               
+               public virtual string Source {
+                       get => source;
+                       set {
+                               if (source == value)
+                                       return;
+                               source = value;
+                               CMDSave.CanExecute = IsDirty;
+                               NotifyValueChanged (source);
+                               NotifyValueChanged ("IsDirty", IsDirty);
+                       }
+               }
+               public bool DebugLoggingEnabled => DbgLogger.IsEnabled;
+
+               public DbgEvtType RecordedEvents {
+                       get => Configuration.Global.Get<DbgEvtType> (nameof (RecordedEvents));
+                       set {
+                               if (RecordedEvents == value)
+                                       return;                         
+                               Configuration.Global.Set (nameof (RecordedEvents), value);                              
+                               if (DebugLogRecording)
+                                       DbgLogger.IncludeEvents = RecordedEvents;
+                               NotifyValueChanged(RecordedEvents);
+                       }
+               }
+               public DbgEvtType DiscardedEvents {
+                       get => Configuration.Global.Get<DbgEvtType> (nameof (DiscardedEvents));
+                       set {
+                               if (DiscardedEvents == value)
+                                       return;
+                               Configuration.Global.Set (nameof (DiscardedEvents), value);
+                               if (DebugLogRecording)
+                                       DbgLogger.DiscardEvents = DiscardedEvents;
+                               NotifyValueChanged(DiscardedEvents);
+                       }
+               }
+               public bool DebugLogRecording {
+                       get => debugLogRecording;
+                       set {
+                               if (debugLogRecording == value)
+                                       return;
+                               debugLogRecording = value;
+                               NotifyValueChanged(debugLogRecording);
+                       }
+               }
+
+               public new bool IsDirty => source != origSource;
+
+
+               public Command CMDNew, CMDOpen, CMDSave, CMDSaveAs, CMDQuit, CMDShowLeftPane,
+                                       CMDUndo, CMDRedo, CMDCut, CMDCopy, CMDPaste, CMDHelp, CMDAbout, CMDOptions;
+               public CommandGroup EditorCommands => new CommandGroup (CMDUndo, CMDRedo, CMDCut, CMDCopy, CMDPaste, CMDSave, CMDSaveAs);
+               protected virtual void initCommands ()
+               {
+                       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);
+               }
+
+
+               protected Stack<TextChange> undoStack = new Stack<TextChange> ();
+               protected Stack<TextChange> redoStack = new Stack<TextChange> ();
+               protected TextSpan selection;
+               protected string SelectedText =>        
+                               selection.IsEmpty ? "" : Source.AsSpan (selection.Start, selection.Length).ToString ();
+
+               protected void undo () {
+                       if (undoStack.TryPop (out TextChange tch)) {
+                               redoStack.Push (tch.Inverse (source));
+                               CMDRedo.CanExecute = true;
+                               apply (tch);
+                               editor.SetCursorPosition (tch.End + tch.ChangedText.Length);
+                       }
+                       if (undoStack.Count == 0)
+                               CMDUndo.CanExecute = false;
+               }
+               protected void redo () {
+                       if (redoStack.TryPop (out TextChange tch)) {
+                               undoStack.Push (tch.Inverse (source));
+                               CMDUndo.CanExecute = true;
+                               apply (tch);
+                               editor.SetCursorPosition (tch.End + tch.ChangedText.Length);
+                       }
+                       if (redoStack.Count == 0)
+                               CMDRedo.CanExecute = false;
+               }
+               protected void resetUndoRedo () {
+                       undoStack.Clear ();
+                       redoStack.Clear ();
+                       CMDUndo.CanExecute = false;
+                       CMDRedo.CanExecute = false;                     
+               }
+
+               protected void cut () {
+                       copy ();
+                       applyChange (new TextChange (selection.Start, selection.Length, ""));
+               }
+               protected void copy () {
+                       Clipboard = SelectedText;
+               }
+               protected void paste () {                       
+                       applyChange (new TextChange (selection.Start, selection.Length, Clipboard));
+               }
+               protected void onNewFile () {
+                       if (IsDirty) {                          
+                               MessageBox.ShowModal (this, MessageBox.Type.YesNo, "Current file has unsaved changes, are you sure?").Yes += (sender, e) => newFile ();
+                       } else
+                               newFile ();
+               }
+               protected void onSave ()
+               {
+                       if (!File.Exists (CurrentFile)) {
+                               onSaveAs ();
+                               return;
+                       }
+                       save ();
+               }
+               protected void onSaveAs ()
+               {
+                       string dir = Path.GetDirectoryName (CurrentFile);
+                       if (string.IsNullOrEmpty (dir))
+                               dir = Directory.GetCurrentDirectory ();
+                       LoadIMLFragment (@"<FileDialog Width='60%' Height='50%' Caption='Save as ...' CurrentDirectory='" +
+                               dir + "' SelectedFile='" +
+                               Path.GetFileName(CurrentFile) + "' OkClicked='saveFileDialog_OkClicked'/>").DataSource = this;
+               }
+               protected void saveFileDialog_OkClicked (object sender, EventArgs e)
+               {
+                       FileDialog fd = sender as FileDialog;
+
+                       if (string.IsNullOrEmpty (fd.SelectedFileFullPath))
+                               return;
+
+                       if (File.Exists(fd.SelectedFileFullPath)) {
+                               MessageBox mb = MessageBox.ShowModal (this, MessageBox.Type.YesNo, "File exists, overwrite?");
+                               mb.Yes += (sender2, e2) => {
+                                       CurrentFile = fd.SelectedFileFullPath;
+                                       save ();
+                               };
+                               return;
+                       }
+
+                       CurrentFile = fd.SelectedFileFullPath;
+                       save ();
+               }
+
+               protected void newFile()
+               {
+                       disableTextChangedEvent = true;
+                       Source = @"<Label Text='Hello World' Background='MediumSeaGreen' Margin='10'/>";
+                       disableTextChangedEvent = false;
+                       resetUndoRedo ();
+                       if (!string.IsNullOrEmpty (CurrentFile))
+                               CurrentFile = Path.Combine (Path.GetDirectoryName (CurrentFile), "newfile.crow");
+                       else
+                               CurrentFile = Path.Combine (CurrentDir, "newfile.crow");
+               }
+
+               protected void save () {
+                       using (Stream s = new FileStream(CurrentFile, FileMode.Create)) {
+                               s.WriteByte (0xEF);
+                               s.WriteByte (0xBB);
+                               s.WriteByte (0xBF);
+                               byte [] buff = Encoding.UTF8.GetBytes (source);
+                               s.Write (buff, 0, buff.Length);
+                       }
+                       origSource = source;
+                       NotifyValueChanged ("IsDirty", IsDirty);
+                       CMDSave.CanExecute = false;
+               }
+
+               protected void reloadFromFile () {                      
+                       disableTextChangedEvent = true;
+                       if (File.Exists (CurrentFile)) {
+                               using (Stream s = new FileStream (CurrentFile, FileMode.Open)) {
+                                       using (StreamReader sr = new StreamReader (s))
+                                               Source = origSource = sr.ReadToEnd ();
+                               }
+                       }
+                       disableTextChangedEvent = false;
+                       resetUndoRedo ();
+               }               
+               protected bool disableTextChangedEvent = false;
+               protected void apply (TextChange change) {
+                       Span<char> tmp = stackalloc char[source.Length + (change.ChangedText.Length - change.Length)];
+                       ReadOnlySpan<char> src = source.AsSpan ();
+                       src.Slice (0, change.Start).CopyTo (tmp);
+                       if (!string.IsNullOrEmpty (change.ChangedText))
+                               change.ChangedText.AsSpan ().CopyTo (tmp.Slice (change.Start));
+                       src.Slice (change.End).CopyTo (tmp.Slice (change.Start + change.ChangedText.Length));
+                       disableTextChangedEvent = true;
+                       Source = tmp.ToString ();
+                       disableTextChangedEvent = false;                        
+               }       
+               protected void applyChange (TextChange change) {
+                       undoStack.Push (change.Inverse (source));
+                       redoStack.Clear ();
+                       CMDUndo.CanExecute = true;
+                       CMDRedo.CanExecute = false;
+                       apply (change);
+               }
+               public void goUpDirClick (object sender, MouseButtonEventArgs e)
+               {
+                       string root = Directory.GetDirectoryRoot (CurrentDir);
+                       if (CurrentDir == root)
+                               return;
+                       CurrentDir = Directory.GetParent (CurrentDir).FullName;
+               }
+
+               protected void Dv_SelectedItemChanged (object sender, SelectionChangeEventArgs e)
+               {
+                       FileSystemInfo fi = e.NewValue as FileSystemInfo;
+                       if (fi == null)
+                               return;
+                       if (fi is DirectoryInfo)
+                               return;
+
+                       if (IsDirty) {
+                               MessageBox mb = MessageBox.ShowModal (this, MessageBox.Type.YesNo, "Current file has unsaved changes, are you sure?");
+                               mb.Yes += (mbsender, mbe) => { CurrentFile = fi.FullName; reloadFromFile (); };
+                               return;
+                       }
+
+                       CurrentFile = fi.FullName;
+                       reloadFromFile ();
+               }
+               protected void onTextChanged (object sender, TextChangeEventArgs e) {
+                       if (disableTextChangedEvent)
+                               return;
+                       applyChange (e.Change);
+               }
+               
+               protected void onSelectedTextChanged (object sender, EventArgs e) {                     
+                       selection = (sender as Label).Selection;
+                       Console.WriteLine($"selection:{selection.Start} length:{selection.Length}");
+                       CMDCut.CanExecute = CMDCopy.CanExecute = !selection.IsEmpty;
+               }
+               protected void textView_KeyDown (object sender, Crow.KeyEventArgs e) {
+                       if (Ctrl) {
+                               if (e.Key == Glfw.Key.W) {
+                                       if (Shift)
+                                               CMDRedo.Execute ();
+                                       else
+                                               CMDUndo.Execute ();
+                               } else if (e.Key == Glfw.Key.S) {
+                                       onSave ();
+                               }
+                       }
+               }
+       }
+}
\ No newline at end of file
diff --git a/Samples/common/ui/Interfaces/Experimental/DockWindow.template b/Samples/common/ui/Interfaces/Experimental/DockWindow.template
deleted file mode 100644 (file)
index 6c91312..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-<?xml version="1.0"?>
-<!--<Widget Background="{./Background}"/>-->
-<Border BorderWidth="1" Foreground="Black" CornerRadius="{./CornerRadius}"
-                               Background="{./Background}"
-                               MouseEnter="./onBorderMouseEnter"
-                               MouseLeave="./onBorderMouseLeave">
-       <VerticalStack Spacing="0">
-               <HorizontalStack Height="Fit">
-                       <Label  Text="{./Name}" TextAlignment="Left" Width="Fit"
-                                        Foreground="White" />
-                       <Label  Text="{./DockingPosition}" TextAlignment="Left" Width="Fit"
-                                        Foreground="White" />
-               </HorizontalStack>
-               <Label  Text="{./Width}" TextAlignment="Left" Width="Fit"
-                                Foreground="White" />
-               <Label  Text="{./Height}" TextAlignment="Left" Width="Fit"
-                                Foreground="White" />
-
-               <HorizontalStack Visible="{./IsDocked}" Height="Fit" Margin="1" Background="Grey">
-                       <Label  Text="{./Caption}" TextAlignment="Left" Width="Stretched"
-                                        Foreground="Jet" />
-                       <Image Width="8" Height="8" Focusable="true" Margin="0" Path="#Crow.Icons.exit2.svg"
-                                        MouseClick="./butQuitPress"/>
-               </HorizontalStack>
-               <HorizontalStack Background="vgradient|0:0.5,0.6,0.5,0.5|1:0.2,0.3,0.3,0.7"
-                               Name="hs" Margin="0" Spacing="0" Height="Fit" Visible="{./IsFloating}">
-                       <Widget Width="5"/>
-                       <Image Margin="1" Width="10" Height="10" Path="{./Icon}"/>
-                       <Label Width="Stretched" Foreground="White" Margin="1" TextAlignment="Left" Text="{./Caption}" />
-                       <Border CornerRadius="6" BorderWidth="1" Foreground="Transparent"  Height="10" Width="10"
-                               MouseEnter="{Foreground=White}" MouseLeave="{Foreground=Transparent}">
-                               <Image Focusable="true" Name="Image" Margin="0" Path="#Crow.Icons.exit2.svg"
-                                        MouseClick="./butQuitPress"/>
-                       </Border>
-                       <Widget Width="5"/>
-               </HorizontalStack>
-               <Container Name="Content" MinimumSize="50,50"/>
-       </VerticalStack>
-</Border>
index 5b01c0698548a429fd327647957e0aebb61e7ae8..e30dd7ae2fb7a9f31d40b4cdac9454168257e817 100644 (file)
@@ -19,7 +19,7 @@
                        </ColorPicker>
                </Template>
        </ColorPicker>
-       <Border CornerRadius="5" Width="60" Height="40" Background="{../cp.CurrentColor}">
+       <Border CornerRadius="5" Margin="10" Width="Fit" Height="40" Background="{../cp.CurrentColor}">
                <Label Text="{../../cp.CurrentColor}"/>
        </Border>
 </VerticalStack>
\ No newline at end of file
index e51cf308ae439c161154f990dd7a7edc8d71cd77..6afbff21b23336506e2b5d882e5d524c4fcd7fdd 100644 (file)
@@ -8,7 +8,7 @@
                <Widget Width="50%" Height="50" Background="SeaGreen"/>
                <Widget Width="50" Height="50" Background="SeaGreen"/>
                <Widget Width="50" Height="50" Background="SeaGreen"/>
-               <Widget Width="50" Height="50%" Background="SeaGreen"/>
+               <Widget Width="50%" Height="50" Background="SeaGreen"/>
                <Widget Width="50" Height="50" Background="SeaGreen"/>
        </Wrapper>
 </Window>
\ No newline at end of file
diff --git a/Samples/common/ui/icons/event.png b/Samples/common/ui/icons/event.png
new file mode 100755 (executable)
index 0000000..8a27233
Binary files /dev/null and b/Samples/common/ui/icons/event.png differ
diff --git a/Samples/common/ui/icons/property.png b/Samples/common/ui/icons/property.png
new file mode 100755 (executable)
index 0000000..1226c16
Binary files /dev/null and b/Samples/common/ui/icons/property.png differ
index 5a4349d76658e4fd1ad35b25436d138bebb4c91f..8bc5574720e99afaa49b912ceece5d0f85244048 100644 (file)
@@ -1,13 +1,13 @@
 <?xml version="1.0"?>
-<Border BorderWidth="1" Background="{./Background}" Height="Stretched">
-       <!--<HorizontalStack Margin="1">-->
+<Border BorderWidth="1" Background="{./Background}" Height="Stretched" Focusable="false">
+       <HorizontalStack Margin="1">
                <Scroller Name="ItemsScroller" Margin="2">
                        <VerticalStack Height="Fit" MinimumSize="10,10"
                                Name="ItemsContainer" Margin="0" VerticalAlignment="Top"/>
                </Scroller>
-               <!--<ScrollBar Name="scrollbar1" Value="{²../ItemsScroller.ScrollY}"
+               <ScrollBar Name="scrollbar1" Value="{²../ItemsScroller.ScrollY}"
                        LargeIncrement="{../ItemsScroller.PageHeight}" SmallIncrement="30" CursorSize="{../ItemsScroller.ChildHeightRatio}"
                        Maximum="{../ItemsScroller.MaxScrollY}" Orientation="Vertical" 
                        Width="12" />
-       </HorizontalStack>-->
+       </HorizontalStack>
 </Border>