]> O.S.I.I.S - jp/crow.git/commitdiff
doc, remplated menubar for showcase, disposable cursorParent in slider devel2
authorJean-Philippe Bruyère <jp_bruyere@hotmail.com>
Sun, 7 Nov 2021 10:34:04 +0000 (11:34 +0100)
committerJean-Philippe Bruyère <jp_bruyere@hotmail.com>
Sun, 7 Nov 2021 10:34:04 +0000 (11:34 +0100)
12 files changed:
Crow/Icons/exit.svg
Crow/Templates/MenuItem.itmp
Crow/src/Configuration.cs
Crow/src/Interface.cs
Crow/src/Text/TextLineCollection.cs
Crow/src/Widgets/Slider.cs
Samples/PerfTests/Program.cs
Samples/ShowCase/ui/showcase.crow
Samples/common/src/Extensions.cs
Samples/common/src/ImlParsing/Syntax.cs
Samples/common/src/SampleBaseForEditor.cs
Samples/common/ui/Interfaces/menuItem.itmp

index cb8d1c27328c62eee7a8cd05ae22ab9b3056bd95..e5944ee2dbe684f592a0c6ad02e41541c42393c6 100644 (file)
@@ -8,12 +8,8 @@
   <path
      style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#ff0000;stroke-width:9;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
      d="m 13.884262,15.143117 c 24.231966,13.49131 34.18672,34.186719 34.18672,34.186719"
-     id="path4175"
-     inkscape:connector-curvature="0"
-     sodipodi:nodetypes="cc" />
+     id="path4175"/>
   <path
-     sodipodi:nodetypes="cc"
-     inkscape:connector-curvature="0"
      id="path4177"
      d="M 50.43178,15.408178 C 20.436536,37.282439 16.245061,49.594898 16.245061,49.594898"
      style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#ff0000;stroke-width:9;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
index b1d062ab2ad5c75f3953bdffeea89d97d9926da7..19136fcc8f2d55cd9a2029826f9a99ae54ea7b33 100644 (file)
@@ -2,7 +2,6 @@
 <ItemTemplate DataType="Crow.Command" Path="#Crow.MenuButton.template"/>
 <ItemTemplate DataType="Crow.CommandGroup" Data="Commands">
        <Popper PopDirection="Right" Caption="{Caption}" IsEnabled="{CanExecute}" Width="Stretched"
-                       BubbleEvents="All"
                        MouseEnter="{Background=${ControlHighlight}}"
                        MouseLeave="{Background=Transparent}">
                <Template>
index f3dadd18e7ee332c6730d68726cab043eb17cef7..28a5293af8f0392e97f6d879ae3e021f42842b72 100644 (file)
@@ -46,12 +46,12 @@ namespace Crow
        }
        /// <summary>
        /// Application wide Configuration store utility
-       /// 
-       /// configuration files are automatically stored in **_user/.config/appname/app.config_** on close and every minutes
-       /// if some items have changed.
+       ///
+       /// configuration files are automatically stored in **_user/.config/appname/appname.config_** on close and at interval defined by
+       /// the static field `Configuration.AUTO_SAVE_INTERVAL` but only if some items have changed.
        /// New items are automaticaly added on first use. Configuration class expose one templated Get and one Templated Set, so
        /// creating, storing and retrieving config items is simple as:
-       /// 
+       ///
        /// ```csharp\n
        ///     //storing\n
        ///     Configuration.Global.Set ("Option1", 42);\n
@@ -59,39 +59,61 @@ namespace Crow
        ///     int op1 = Configuration.Global.Get<int> ("Option1");\n
        /// ```\n
        /// </summary>
-       /// 
+       ///
        /// **.config**  file are simple text files with per line, a key/value pair of the form `option=value`. Keys have to be unique
        /// in the application scope.
-       /// 
+       ///
        /// When running the application for the first time, some default options may be necessary. Their can be defined
        /// in a special embedded resource text file with the key '**appname.default.config**'
+       ///
+       /// You may also provide a default value when you fetch an item:
+       /// ```csharp\n
+       ///     int op1 = Configuration.Global.Get<int> ("Option1", 10);\n
+       /// ```\n
+       ///
        public class Configuration
        {
                volatile bool isDirty = false;
                string configPath;
                Dictionary<string, ConfigItem> items = new Dictionary<string, ConfigItem> ();
                static Configuration  globalConfig;
-
-               public static Configuration Global { get { return globalConfig; } }
-
+               /// <summary>
+               /// Interval in milliseconds between configuration file saving. Save is done only if an item has changed.
+               /// Default value is 200.
+               /// </summary>
+               public static int AUTO_SAVE_INTERVAL = 200;
+               /// <summary>
+               /// Default application wide store for configuration items. It's created and updated automaticaly when needed.
+               /// It's path is: **_user/.config/appname/appname.config_**.
+               /// </summary>
+               public static Configuration Global => globalConfig;
+               /// <summary>
+               /// Create a custom configuration store with the provided path.
+               /// </summary>
+               /// <param name="path">the full path where to save this configuration store.</param>
+               /// <param name="defaultConf">an optional text stream with default values.</param>
                public Configuration (string path, Stream defaultConf = null) {
                        configPath = path;
                        if (File.Exists (configPath)) {
                                using (Stream s = new FileStream (configPath, FileMode.Open))
                                        load (s);
-                               
-                       } else if (defaultConf != null) {                               
+
+                       } else if (defaultConf != null) {
                                load (defaultConf);
                        }
                        startSavingThread ();
                }
                /// <summary>
-               /// Create readonly configuration
+               /// Create readonly configuration
                /// </summary>
                /// <param name="defaultConf"></param>
-               public Configuration (Stream defaultConf = null) {                      
+               public Configuration (Stream defaultConf = null) {
                        load (defaultConf);
                }
+               /// <summary>
+               /// Get the application configuration directory full path.
+               /// </summary>
+               /// <returns>application configuration directory full path</returns>
                public static string AppConfigPath => Path.Combine (
                        Path.Combine (Environment.GetFolderPath (Environment.SpecialFolder.UserProfile), ".config") ,
                        Assembly.GetEntryAssembly ().GetName().Name);
@@ -121,6 +143,10 @@ namespace Crow
                        globalConfig = new Configuration (globalConfigPath);
                }
 
+               /// <summary>
+               /// Get all the configuration item names currently present in this configuration store.
+               /// </summary>
+               /// <value>configuration item names</value>
                public string[] Names {
                        get {
                                return items.Keys.ToArray ();
@@ -139,6 +165,13 @@ namespace Crow
                                Thread.Sleep (100);
                        }
                }
+               /// <summary>
+               /// Try to fetch a configuration item by name.
+               /// </summary>
+               /// <param name="key">the configuration item name</param>
+               /// <param name="result">the current value, or the type default if not found in store.</param>
+               /// <typeparam name="T">The type of the configuration item</typeparam>
+               /// <returns>true if the item was present, false otherwise</returns>
                public bool TryGet<T> (string key, out T result) {
                        if (items.ContainsKey (key)){
                                result = items [key].GetValue<T> ();
@@ -148,21 +181,27 @@ namespace Crow
                        return false;
                }
                /// <summary>
-               /// retrive the value of the configuration key given in parameter
+               /// Retrieve an item from this configuration store identified by the key given in parameter
                /// </summary>
-               /// <param name="key">option name</param>
+               /// <param name="key">configuration item name</param>
+               /// <typeparam name="T">the type of the configuration item</typeparam>
+               /// <returns>The current value or the default one if not yet defined.</returns>
                public T Get<T>(string key)
                {
                        return !items.ContainsKey (key) ? default(T) : items [key].GetValue<T> ();
                }
                /// <summary>
-               /// retrive the value of the configuration key given in parameter
+               /// Retrieve an item from this configuration store identified by the key given in parameter, or
+               /// return the default value provided as parameter.
                /// </summary>
-               /// <param name="key">option name</param>
+               /// <param name="key">configuration item name</param>
+               /// <param name="defaultValue">a default value in case this item is not yet present in the configuration store</param>
+               /// <typeparam name="T">the type of the configuration item</typeparam>
+               /// <returns>The current value or the default one if not yet defined.</returns>
                public T Get<T>(string key, T defaultValue)
                {
                        return !items.ContainsKey (key) ? defaultValue : items [key].GetValue<T> ();
-               }               
+               }
                /// <summary>
                /// store the value of the configuration key given in parameter
                /// </summary>
@@ -177,6 +216,9 @@ namespace Crow
                                items[key].Set (value);
                        isDirty = true;
                }
+               /// <summary>
+               /// Save this configuration store with the path provided on creation. This is done automaticaly normaly.
+               /// </summary>
                public void Save(){
                        using (Stream s = new FileStream(configPath,FileMode.Create)){
                                using (StreamWriter sw = new StreamWriter (s)) {
index 66aa0e69b163745850b848d3d78b36a1c6677007..d3dd99f43bed6becc19cdb6cb30c83bb1656a515 100644 (file)
@@ -85,8 +85,6 @@ namespace Crow
                                {
                                        case "cairo":
                                                return NativeLibrary.Load("cairo-2", assembly, null);
-                                       /*case "glfw3":
-                                               return NativeLibrary.Load("glfw", assembly, null);*/
                                        case "rsvg-2.40":
                                                return NativeLibrary.Load("rsvg-2", assembly, null);
                                }
index 19be9c9e32ca7fded8c2fc6a24222d780bcf1547..ba40e0848917e70d79c6d0147bc411a0fc5ac4fd 100644 (file)
@@ -124,6 +124,7 @@ namespace Crow.Text
                        }
                        return new CharLocation (result, absolutePosition - lines[result].Start);
                }
+               [Obsolete]
                public void UpdateLineLengthInPixel (int index, int lengthInPixel) {
                        lines[index].LengthInPixel = lengthInPixel;
                }
index e1e8d90ed4a6227f8d62cd20b3a2b22f03d37151..8d6615a7c5e7f4129dd56dba784ee9ce38e34f27 100644 (file)
@@ -19,14 +19,21 @@ namespace Crow
                #endregion
 
                #region implemented abstract members of TemplatedControl
+               Widget cursorParent;
                protected override void loadTemplate (Widget template = null)
                {
+                       if (cursorParent != null) {
+                               cursorParent.LayoutChanged -= HandleCursorContainerLayoutChanged;
+                               cursorParent = null;
+                       }
                        base.loadTemplate (template);
 
                        cursor = child.FindByName ("Cursor");
                        if (cursor == null)
                                return;
-                       (cursor.Parent as Widget).LayoutChanged += HandleCursorContainerLayoutChanged;//too difficult to unregister
+                       cursorParent = cursor.Parent as Widget;
+                       cursorParent.LayoutChanged += HandleCursorContainerLayoutChanged;
+
                        updateCursorWidgetProps ();
                }
 
@@ -36,9 +43,6 @@ namespace Crow
                }
                #endregion
 
-
-
-
                protected override void registerUpdate ()
                        => RegisterForLayouting (LayoutingType.ArrangeChildren);
 
@@ -221,20 +225,33 @@ namespace Crow
                        base.onMouseMove (sender, e);
                }
                #endregion
-
-               public void OnDecrease (object sender, MouseButtonEventArgs e)
+               /// <summary>
+               /// Handler to decrease current value by `SmallIncrement`
+               /// </summary>
+               /// <param name="sender">event sender</param>
+               /// <param name="e">event argument</param>
+               public void OnDecrease (object sender, EventArgs e)
                {
                        Value -= SmallIncrement;
                }
-               public void OnIncrease (object sender, MouseButtonEventArgs e)
+               /// <summary>
+               /// Handler to increase current value by `SmallIncrement`
+               /// </summary>
+               /// <param name="sender">event sender</param>
+               /// <param name="e">event argument</param>
+               public void OnIncrease (object sender, EventArgs e)
                {
                        Value += SmallIncrement;
                }
 
                protected override void Dispose(bool disposing)
                {
-                       base.Dispose(disposing);
+                       if (cursorParent != null) {
+                               cursorParent.LayoutChanged -= HandleCursorContainerLayoutChanged;
+                               cursorParent = null;
+                       }
 
+                       base.Dispose(disposing);
                }
        }
 }
index 222b7e7a4bd5e13a102c6c9e03ad72a088f30c53..d7f6a9be423f27279c3c15f9d39970e265d8f5ce 100644 (file)
@@ -14,26 +14,6 @@ namespace PerfTests
 {
        class TestInterface : Interface
        {
-#if NETCOREAPP
-               static IntPtr resolveUnmanaged (Assembly assembly, String libraryName) {
-
-                       switch (libraryName)
-                       {
-                               case "cairo":
-                                       return NativeLibrary.Load("cairo-2", assembly, null);
-                               case "glfw3":
-                                       return  NativeLibrary.Load("glfw", assembly, null);
-                               case "rsvg-2.40":
-                                       return  NativeLibrary.Load("rsvg-2", assembly, null);
-                       }
-                       Console.WriteLine ($"[UNRESOLVE] {assembly} {libraryName}");
-                       return IntPtr.Zero;
-               }
-
-               static TestInterface () {
-                       System.Runtime.Loader.AssemblyLoadContext.Default.ResolvingUnmanagedDll+=resolveUnmanaged;
-               }
-#endif
                readonly int count = 10, updateCycles = 0;
                readonly bool screenOutput = false;
                readonly string inDirectory = null;//directory to test
index c5b683dabbef087c2b0a11edb64b0ce4a94b7f24..62b676dff30ddc7a2ea7b6a0ec52efc0e1a30f45 100644 (file)
                </VerticalStack>-->
                <Container Name="CrowContainer" Height="60%" Background="Black"/>
                <Splitter/>
+               <Menu Data="{EditorAllCommands}" Height="Fit" Width="Stretched">
+                       <ItemTemplate DataType="Crow.Command" Path="Interfaces/menuCommand.itmp"/>
+                       <ItemTemplate DataType="Crow.CommandGroup" >
+                               <MenuItem Data="{Commands}" Width="Fit" IsEnabled="{CanExecute}"
+                                               Template="Interfaces/menuItem.template"
+                                               ItemTemplate="Interfaces/menuItem.itmp">
+                               </MenuItem>
+                       </ItemTemplate>
+               </Menu>
                <VerticalStack CacheEnabled="true">
-                       <Wrapper Orientation="Vertical" Height="Fit">
+               <!--    <Wrapper Orientation="Vertical" Height="Fit">
                                <Button Style="IcoButton" Command="{CMDNew}" />
                                <Button Style="IcoButton" Command="{CMDSave}" />
                                <Button Style="IcoButton" Command="{CMDSaveAs}" />
                                                        Tooltip="Add '*source* where you want to load the source in the editor."/>
                                        </VerticalStack>
                                </Popper>
-                       </Wrapper>
+                       </Wrapper>-->
                        <HorizontalStack>
                                <Editor Name="tb" Text="{Source}" Multiline="true" Font="consolas, 12" Focusable="true" Height="Stretched" Width="Stretched"
-                                               TextChanged="onTextChanged" KeyDown="textView_KeyDown" ContextCommands="{EditorCommands}"
+                                               TextChanged="onTextChanged" KeyDown="textView_KeyDown" ContextCommands="{EditorEditCommands}"
                                                SelectionChanged="onEditorSelectionChanged"
                                                Foreground="DarkGrey" Background="White" MouseWheelSpeed="20"/>
                                <ScrollBar Value="{²../tb.ScrollY}"
index 7647dbc970f57e8d8b69eeaa91c31aeaf7955323..024330116d996aa3520f1794a10d1c285db3d3e8 100644 (file)
@@ -1,20 +1,25 @@
 
 
+using System.IO;
 using System.Reflection;
 using Crow;
 
 namespace Samples {
        public static class Extensions {
 
-               public static CommandGroup GetCommands (this System.IO.DirectoryInfo di) =>
+               public static CommandGroup GetCommands (this DirectoryInfo di) =>
                        new CommandGroup(
-                               new ActionCommand ("Set as root", ()=> {SampleBaseForEditor.CurrentProgramInstance.CurrentDir = di.FullName;})
+                               new ActionCommand ("Set as root", ()=> {SampleBaseForEditor.CurrentProgramInstance.CurrentDir = di.FullName;})/*,
+                               new ActionCommand ("New Directory", (sender0) => {
+                                       Directory.CreateDirectory (Path.Combine (di.FullName, "new directory"));
+                                       Widget listContainer = ((sender0 as Widget).LogicalParent as Widget).DataSource as Widget;
+                               })*/
                        );
-               public static CommandGroup GetCommands (this System.IO.FileInfo fi) =>
+               public static CommandGroup GetCommands (this FileInfo fi) =>
                        new CommandGroup(
                                new ActionCommand ("Delete", (sender0) => {
                                        MessageBox.ShowModal (SampleBaseForEditor.CurrentProgramInstance, MessageBox.Type.YesNo, $"Delete {fi.Name}?").Yes += (sender, e) => {
-                                               System.IO.File.Delete(fi.FullName);
+                                               File.Delete(fi.FullName);
                                                Widget listContainer = ((sender0 as Widget).LogicalParent as Widget).DataSource as Widget;
                                                (listContainer.Parent as Group).RemoveChild(listContainer);
                                        };
index 92c9eec38b1c6906df703895b366f92426c69420..ddbc6a927395f250888debc2efeb6ebde452f0d3 100644 (file)
@@ -8,13 +8,13 @@ using System.Linq;
 namespace Crow
 {
        public class SyntaxException : Exception {
-               public readonly Token Token;            
+               public readonly Token Token;
                public SyntaxException(string message, Token token = default, Exception innerException = null)
                                : base (message, innerException) {
                        Token = token;
                }
        }
-       public class SyntaxAnalyser {           
+       public class SyntaxAnalyser {
                XmlSource source;
                IEnumerable<Token> tokens => source.Tokens;
                public SyntaxNode Root => CurrentNode;
@@ -44,7 +44,7 @@ namespace Crow
                        throw new SyntaxException ("Unexpected end of source");
                }
 
-               Token accept (IEnumerator<Token> iter, TokenType acceptedTokenType) {                           
+               Token accept (IEnumerator<Token> iter, TokenType acceptedTokenType) {
                        if (iter.Current.Type == acceptedTokenType)
                                return iter.Current;
                        else
@@ -58,7 +58,7 @@ namespace Crow
                        Token eltOpen = iter.Current;
                        moveNextOrThrow (iter);
                        Token eltName = accept (iter, TokenType.ElementName);
-                       
+
                        List<SyntaxNode> attributes = readAttributes (iter);
 
                        if (iter.Current.Type == TokenType.EmptyElementClosing || iter.Current.Type == TokenType.ClosingSign)
@@ -70,7 +70,7 @@ namespace Crow
                        Token eltOpen = iter.Current;
                        moveNextOrThrow (iter);
                        Token eltName = accept (iter, TokenType.ElementName);
-                       moveNextOrThrow (iter);                 
+                       moveNextOrThrow (iter);
                        return new ElementEndTagSyntax(source, eltOpen, eltName, accept (iter, TokenType.ClosingSign));
                }*/
 
@@ -87,7 +87,7 @@ namespace Crow
                        Exceptions = new List<SyntaxException> ();
                        CurrentNode = new IMLRootSyntax (source);
                        previousTok = default;
-                       iter = tokens.GetEnumerator ();                 
+                       iter = tokens.GetEnumerator ();
 
                        bool notEndOfSource = iter.MoveNext ();
                        while (notEndOfSource) {
@@ -100,7 +100,7 @@ namespace Crow
                                                } else if (iter.Current.Type == TokenType.ElementName)
                                                        tag.NameToken = iter.Current;
                                                else if (iter.Current.Type == TokenType.ClosingSign) {
-                                                       tag.EndToken = iter.Current;                                            
+                                                       tag.EndToken = iter.Current;
                                                        CurrentNode = tag.Parent;
                                                        CurrentNode.RemoveChild (tag);
                                                        CurrentNode = CurrentNode.AddChild (new ElementSyntax (tag));
@@ -113,13 +113,13 @@ namespace Crow
                                                        Exceptions.Add (new SyntaxException  ("Unexpected Token", iter.Current));
                                                        CurrentNode.EndToken = previousTok;
                                                        CurrentNode = CurrentNode.Parent;
-                                                       continue;                                               
+                                                       continue;
                                                }
                                        } else if (CurrentNode is ElementSyntax elt) {
                                                if (iter.Current.Type == TokenType.ElementOpen)
                                                        CurrentNode = CurrentNode.AddChild (new ElementStartTagSyntax (iter.Current));
-                                               else if (iter.Current.Type == TokenType.EndElementOpen) {                                               
-                                                       elt.EndTag = new ElementEndTagSyntax (iter.Current);                                            
+                                               else if (iter.Current.Type == TokenType.EndElementOpen) {
+                                                       elt.EndTag = new ElementEndTagSyntax (iter.Current);
                                                        CurrentNode = elt.AddChild (elt.EndTag);
                                                }
                                        } else if (CurrentNode is AttributeSyntax attrib) {
@@ -139,7 +139,7 @@ namespace Crow
                                                        Exceptions.Add (new SyntaxException  ("Unexpected Token", iter.Current));
                                                        CurrentNode.EndToken = previousTok;
                                                        CurrentNode = CurrentNode.Parent;
-                                                       continue;                                               
+                                                       continue;
                                                }
                                        } else if (CurrentNode is ElementEndTagSyntax eltEndTag) {
                                                if (iter.Current.Type == TokenType.ElementName)
@@ -151,7 +151,7 @@ namespace Crow
                                                        Exceptions.Add (new SyntaxException  ("Unexpected Token", iter.Current));
                                                        eltEndTag.EndToken = eltEndTag.Parent.EndToken = previousTok;
                                                        CurrentNode = CurrentNode.Parent.Parent;
-                                                       continue;                                               
+                                                       continue;
                                                }
                                        } else if (CurrentNode is IMLRootSyntax) {
                                                switch (iter.Current.Type) {
@@ -179,11 +179,11 @@ namespace Crow
                                                        Exceptions.Add (new SyntaxException  ("Unexpected Token", iter.Current));
                                                        pi.EndToken = previousTok;
                                                        CurrentNode = CurrentNode.Parent;
-                                                       continue;                                               
+                                                       continue;
                                                }
                                        }
                                }
-                               
+
                                previousTok = iter.Current;
                                notEndOfSource = iter.MoveNext ();
                        }
@@ -191,16 +191,16 @@ namespace Crow
                                if (!CurrentNode.EndToken.HasValue)
                                        CurrentNode.EndToken = previousTok;
                                CurrentNode = CurrentNode.Parent;
-                       }                       
+                       }
                }
        }
        public class SyntaxNode {
                public SyntaxNode Parent { get; private set; }
                List<SyntaxNode> children = new List<SyntaxNode> ();
-               
+
                public readonly Token StartToken;
                public Token? EndToken { get; internal set; }
-               public SyntaxNode (Token tokStart, Token? tokEnd = null) {                      
+               public SyntaxNode (Token tokStart, Token? tokEnd = null) {
                        StartToken = tokStart;
                        EndToken = tokEnd;
                }
@@ -271,7 +271,7 @@ namespace Crow
                protected ElementTagSyntax (Token startTok)
                        : base (startTok) {
                }
-       }       
+       }
        public class ElementStartTagSyntax : ElementTagSyntax {
                public ElementStartTagSyntax (Token startTok)
                        : base (startTok) {
@@ -282,11 +282,11 @@ namespace Crow
                        : base (startTok) {
                }
        }
-       
+
        public class EmptyElementSyntax : SyntaxNode {
                public readonly ElementStartTagSyntax StartTag;
                public EmptyElementSyntax (ElementStartTagSyntax startNode) : base (startNode.StartToken, startNode.EndToken) {
-                       StartTag = startNode;                   
+                       StartTag = startNode;
                        AddChild (StartTag);
                }
        }
@@ -298,7 +298,7 @@ namespace Crow
                public override bool IsComplete => base.IsComplete & StartTag.IsComplete & (EndTag != null && EndTag.IsComplete);
 
                public ElementSyntax (ElementStartTagSyntax startTag)
-                       : base (startTag.StartToken) {                  
+                       : base (startTag.StartToken) {
                        StartTag = startTag;
                        AddChild (StartTag);
                }
@@ -307,9 +307,9 @@ 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 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 & ValueOpenToken.HasValue & ValueCloseToken.HasValue;
        }
index b207eea365fea514f9384b0b059b609c9affff49..5c87226dbc1c5998f9db930ad1fa5bfdf5a4e811 100644 (file)
@@ -127,7 +127,7 @@ namespace Samples
 
                public ActionCommand 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);
+               public CommandGroup EditorFileCommands, EditorEditCommands, EditorAllCommands;
                protected virtual void initCommands ()
                {
                        CMDNew  = new ActionCommand ("New", new Action (onNewFile), "#Icons.blank-file.svg");
@@ -139,6 +139,11 @@ namespace Samples
                        CMDCut  = new ActionCommand ("Cut", new Action (cut), "#Icons.scissors.svg", false);
                        CMDCopy = new ActionCommand ("Copy", new Action (copy), "#Icons.copy-file.svg", false);
                        CMDPaste= new ActionCommand ("Paste", new Action (paste), "#Icons.paste-on-document.svg", false);
+
+                       EditorFileCommands = new CommandGroup ("File", CMDSave, CMDSaveAs, CMDQuit);
+                       EditorEditCommands  = new CommandGroup ("Edit", CMDUndo, CMDRedo, CMDCut, CMDCopy, CMDPaste);
+
+                       EditorAllCommands = new CommandGroup (EditorFileCommands, EditorEditCommands);
                }
 
 
index 04bc10a644a76bc13894e53a249154bf4e0e1a9a..a129769aa7903505004c786b111b4e5694788af0 100644 (file)
@@ -7,7 +7,7 @@
                <Template>
                        <Label Text="{./Caption}" Width="Stretched" Height="Stretched" Margin="3"
                                Background="{./Background}"/>
-               </Template>             
+               </Template>
                <VerticalStack Margin="0" Name="ItemsContainer" Fit="true" Background="Jet"/>
        </Popper>
 </ItemTemplate>