]> O.S.I.I.S - jp/crowedit.git/commitdiff
wip extensibleEditor
authorJean-Philippe Bruyère <jp_bruyere@hotmail.com>
Wed, 22 Sep 2021 14:36:12 +0000 (14:36 +0000)
committerJean-Philippe Bruyère <jp_bruyere@hotmail.com>
Wed, 22 Sep 2021 14:36:12 +0000 (14:36 +0000)
38 files changed:
CrowEditBase/CrowEditBase.csproj
CrowEditBase/src/Compiler/SourceDocument.cs
CrowEditBase/src/CrowEditBase.cs
CrowEditBase/src/CrowEditComponent.cs
CrowEditBase/src/Document.cs
CrowEditBase/src/Editor.cs
CrowEditBase/src/Plugin.cs
CrowEditBase/src/PluginsLoadContext.cs
CrowEditBase/src/Project.cs
CrowEditBase/src/SourceEditor.cs
CrowEditBase/src/TextDocument.cs
CrowEditBase/src/TreeNode.cs
CrowEditBase/src/VirtualNode.cs
CrowEditBase/ui/CrowEdit.style
CrowEditBase/ui/TreeExpandable.template
Directory.Build.props
plugins/CECrowPlugin/default.conf
plugins/CECrowPlugin/src/CrowService.cs
plugins/CECrowPlugin/src/DebugInterface.cs
plugins/CECrowPlugin/src/ImlDocument.cs
plugins/CECrowPlugin/src/StyleDocument.cs [new file with mode: 0644]
plugins/CECrowPlugin/src/StyleParsing/StyleDocument.cs [deleted file]
plugins/CECrowPlugin/ui/DbgEventTreeItems.itemp
plugins/CECrowPlugin/ui/winCrowPreview.crow
plugins/CERoslynPlugin/src/CELogger.cs
plugins/CERoslynPlugin/src/CETaskLogHook.cs
plugins/CERoslynPlugin/src/CSDocument.cs
plugins/CERoslynPlugin/src/MSBuildProject.cs
plugins/CERoslynPlugin/src/ProjectTree/ProjectItemNodes.cs
plugins/CERoslynPlugin/src/ProjectTree/ProjectNode.cs [deleted file]
plugins/CERoslynPlugin/src/SolutionProject.cs
plugins/CERoslynPlugin/ui/MSBuildProjectNode.template
plugins/CEXmlPlugin/src/Parsing/XmlDocument.cs
plugins/Directory.Build.props
src/CrowEdit.cs
ui/windows/winEditor.crow
ui/windows/winFileExplorer.crow
ui/windows/winProjects.crow

index f9fd2fa4f9f90360accb6ba5102ca65a0afaab17..2e5c287dc25e17d842fc73eb6060a51e8e342ec2 100644 (file)
@@ -15,7 +15,7 @@
                </EmbeddedResource>
        </ItemGroup>
        <ItemGroup>
-               <ProjectReference Include="/mnt/devel/crow/Crow/Crow.csproj" />
-               <!--<PackageReference Include="Crow" Version="0.9.6-beta" />-->
+               <!--<ProjectReference Include="/mnt/devel/crow/Crow/Crow.csproj" />-->
+               <PackageReference Include="Crow" Version="0.9.7-beta" />
        </ItemGroup>
 </Project>
index f0230140f284a2d93d46dc4a8c61ca40553aea71..25d53964a14235970c1dcae09ba0e63d7eb95836 100644 (file)
@@ -11,8 +11,8 @@ using System.Collections;
 namespace CrowEditBase
 {
        public abstract class SourceDocument : TextDocument {
-               public SourceDocument (string fullPath)
-                       : base (fullPath) {
+               public SourceDocument (string fullPath, string editorPath = "#ui.sourceEditor.itmp")
+                       : base (fullPath, editorPath) {
                }
                protected Token[] tokens;
                protected SyntaxNode RootNode;
index b40fa1858a585e50ffc4d7802f8c74dd4a182000..a34ec0f951146d9a6f4b7220a7568fccfc0fc4b7 100644 (file)
@@ -9,14 +9,13 @@ using Crow;
 using System.Runtime.CompilerServices;
 using System.Collections.Generic;
 using System.Runtime.Loader;
+using System.Text;
 
 namespace CrowEditBase
 {
        public abstract class CrowEditBase : Interface {
-               protected class DocumentClientClassList : List<Type> {
-                       string defaultClass;
-               }
-               protected Dictionary<string, DocumentClientClassList> FileAssociations = new Dictionary<string, DocumentClientClassList> ();
+               protected Dictionary<string, List<Type>> FileAssociations = new Dictionary<string, List<Type>> ();
+               protected Dictionary<Type, List<string>> SupportedEditors = new Dictionary<Type, List<string>> ();
                ObservableList<LogEntry> logs = new ObservableList<LogEntry>();
                public ObservableList<LogEntry> MainLog => logs;
 
@@ -31,10 +30,10 @@ namespace CrowEditBase
 
                public void AddFileAssociation (string extension, Type clientClass) {
                        if (!FileAssociations.ContainsKey (extension))
-                               FileAssociations.Add (extension, new DocumentClientClassList ());
+                               FileAssociations.Add (extension, new List<Type> ());
                        if (!FileAssociations[extension].Contains (clientClass))
                                FileAssociations[extension].Add (clientClass);
-
+                       NotifyValueChanged ("EditorItemTemplates", (object)EditorItemTemplates);
                }
                public void RemoveFileAssociationByType (Type clientClass) {
 
@@ -44,6 +43,18 @@ namespace CrowEditBase
                        clientType = FileAssociations.ContainsKey (extension) ? FileAssociations[extension].FirstOrDefault () : null;
                        return clientType != null;
                }
+               public void AddSupportedEditor (Type clientClass, string editorPath) {
+                       if (!SupportedEditors.ContainsKey (clientClass))
+                               SupportedEditors.Add (clientClass, new List<string> ());
+                       if (!SupportedEditors[clientClass].Contains (editorPath))
+                               SupportedEditors[clientClass].Add (editorPath);
+                       NotifyValueChanged ("EditorItemTemplates", (object)EditorItemTemplates);
+               }
+               public bool TryGetDefaultEditorForDocumentType (Type clientType, out string editorPath) {
+                       editorPath = SupportedEditors.ContainsKey (clientType) ? SupportedEditors[clientType].FirstOrDefault () : null;
+                       return editorPath != null;
+               }
+
 
 
                public static CrowEditBase App;
@@ -84,7 +95,7 @@ namespace CrowEditBase
                //TODO:flattened project
                public IEnumerable<Project> FlattenProjects {
                        get {
-                               foreach (var node in Projects.SelectMany (child => child.Flatten))
+                               foreach (var node in Projects.SelectMany (child => child.FlattenSubProjetcs))
                                        yield return node;
                        }
                }
@@ -100,7 +111,16 @@ namespace CrowEditBase
                        containingProject = FlattenProjects.FirstOrDefault (p => p.ContainsFile (fullPath));
                        return containingProject != null;
                }
-
+               public bool TryFindFileNode (string fullPath, out IFileNode node) {
+                       foreach  (Project prj in Projects) {
+                               if (prj.TryFindFileNode (fullPath, out IFileNode n)) {
+                                       node = n;
+                                       return true;
+                               }
+                       }
+                       node = null;
+                       return false;
+               }
 
                public Document CurrentDocument {
                        get => currentDocument;
@@ -108,7 +128,8 @@ namespace CrowEditBase
                                if (currentDocument == value)
                                        return;
 
-                               currentDocument?.UnselectDocument ();
+                               if (currentDocument != null)
+                                       currentDocument.IsSelected = false;
 
                                currentDocument = value;
                                NotifyValueChanged (currentDocument);
@@ -116,7 +137,7 @@ namespace CrowEditBase
                                if (currentDocument == null)
                                        return;
 
-                               currentDocument.SelectDocument ();
+                               currentDocument.IsSelected = true;
                                FileCommands[2] = currentDocument.CMDSave;
                                FileCommands[3] = currentDocument.CMDSaveAs;
                                EditCommands[0] = currentDocument.CMDUndo;
@@ -185,6 +206,10 @@ namespace CrowEditBase
 
                public bool IsOpened (string filePath) =>
                        string.IsNullOrEmpty (filePath) ? false : OpenedDocuments.Any (d => d.FullPath == filePath);
+               public bool TryGetOpenedDocument (string fullPath, out Document doc) {
+                       doc = OpenedDocuments.FirstOrDefault (d => d.FullPath == fullPath);
+                       return doc != null;
+               }
 
                public Document OpenFile (string filePath) {
                        if (string.IsNullOrEmpty (filePath))
@@ -210,7 +235,7 @@ namespace CrowEditBase
                        openOrCreateFile (Path.Combine (CurFileDir, _defaultFileName));
                }
 
-               protected abstract Document openOrCreateFile (string filePath);
+               protected abstract Document openOrCreateFile (string filePath, string editorPath = null);
                public void CloseDocument (Document doc) {
                        if (doc == null)
                                return;
@@ -271,5 +296,99 @@ namespace CrowEditBase
                        }
                }
 
+
+       #region Editor item templates
+       public string EditorItemTemplates {
+               get {
+                       StringBuilder sb = new StringBuilder (1024);
+                       sb.Append (defaultEditorITemps);
+                       foreach (string editorPath in SupportedEditors.Values.SelectMany (a=>a).Distinct ())
+                               sb.Append ($"<ItemTemplate Path='{editorPath}' DataTest='EditorPath' DataType='{editorPath}'/>");
+                       return sb.ToString ();
+               }
+       }
+       string defaultEditorITemps = @"
+               <ItemTemplate>
+                       <ListItem IsVisible='{IsSelected}' IsSelected='{²IsSelected}' Selected=""{/tb.HasFocus='true'}"">
+                               <VerticalStack Spacing='0'>
+                                       <HorizontalStack Spacing='0'>
+                                               <Editor Name='tb' Font='consolas, 12' Focusable='true' Height='Stretched' Width='Stretched'
+                                                               Margin='50' ClipToClientRect='true'
+                                                               Document='{}' TextChanged='onTextChanged'/>
+                                               <ScrollBar Value='{²../tb.ScrollY}'
+                                                               LargeIncrement='{../tb.PageHeight}' SmallIncrement='1'
+                                                               CursorRatio='{../tb.ChildHeightRatio}' Maximum='{../tb.MaxScrollY}' />
+                                       </HorizontalStack>
+                                       <ScrollBar Style='HScrollBar' Value='{²../tb.ScrollX}'
+                                                       LargeIncrement='{../tb.PageWidth}' SmallIncrement='1'
+                                                       CursorRatio='{../tb.ChildWidthRatio}' Maximum='{../tb.MaxScrollX}' />
+                                       <HorizontalStack Height='Fit'>
+                                               <Widget Width='Stretched'/>
+                                               <Widget Height='5' Width='10'/>
+                                               <Label Text='Line:' Foreground='Grey'/>
+                                               <Label Text='{../../tb.CurrentLine}' Margin='3'/>
+                                               <Label Text='col:' Foreground='Grey'/>
+                                               <Label Text='{../../tb.CurrentColumn}' Margin='3'/>
+                                       </HorizontalStack>
+                               </VerticalStack>
+                       </ListItem>
+               </ItemTemplate>
+       ";
+       #endregion
+
+
+#region main options
+               public virtual Color MarginBackground {
+                       get => Configuration.Global.Get<Color> ("MarginBackground", Colors.Onyx);
+                       set {
+                               if (value == MarginBackground)
+                                       return;
+                               Configuration.Global.Set ("MarginBackground", value);
+                               NotifyValueChanged ("MarginBackground", value);
+
+                               CurrentEditor?.RegisterForRedraw ();
+                       }
+               }
+               public bool PrintLineNumbers {
+                       get => Configuration.Global.Get<bool> ("PrintLineNumbers", true);
+                       set {
+                               if (PrintLineNumbers == value)
+                                       return;
+                               Configuration.Global.Set ("PrintLineNumbers", value);
+                               NotifyValueChanged ("PrintLineNumbers", PrintLineNumbers);
+
+                               CurrentEditor?.RegisterForGraphicUpdate ();
+                       }
+               }
+               //Folding
+               public bool FoldingEnabled {
+                       get => Crow.Configuration.Global.Get<bool> ("FoldingEnabled", true);
+                       set {
+                               if (FoldingEnabled == value)
+                                       return;
+                               Crow.Configuration.Global.Set ("FoldingEnabled", value);
+                               NotifyValueChanged (value);
+                       }
+               }
+               public bool AutoFoldRegions {
+                       get => Crow.Configuration.Global.Get<bool> ("AutoFoldRegions", true);
+                       set {
+                               if (AutoFoldRegions == value)
+                                       return;
+                               Crow.Configuration.Global.Set ("AutoFoldRegions", value);
+                               NotifyValueChanged (value);
+                       }
+               }
+               public bool AutoFoldComments {
+                       get => Crow.Configuration.Global.Get<bool> ("AutoFoldComments", true);
+                       set {
+                               if (AutoFoldComments == value)
+                                       return;
+                               Crow.Configuration.Global.Set ("AutoFoldComments", value);
+                               NotifyValueChanged (value);
+                       }
+               }
+
+#endregion
        }
 }
\ No newline at end of file
index d3995a66bc55f9c0880ba7170e5d5d1e5480ac19..b1a5c30a3a138fe0d267f9bb89797a67d09f61f0 100644 (file)
@@ -23,7 +23,7 @@ namespace CrowEditBase
                #endregion
 
                #region ISelectable implementation
-               bool isSelected;
+               protected bool isSelected;
                public event EventHandler Selected;
                public event EventHandler Unselected;
 
@@ -34,7 +34,6 @@ namespace CrowEditBase
                                        return;
 
                                isSelected = value;
-
                                NotifyValueChanged (isSelected);
                        }
                }
index 472cbd7b65f1a7452e93d8933d80ca905946647a..8b3343e653f9a3df733af52c05e56a44b629e468 100644 (file)
@@ -13,15 +13,20 @@ using static CrowEditBase.CrowEditBase;
 namespace CrowEditBase
 {
        public abstract class Document : CrowEditComponent {
-               protected Project project;
-               public Document (string fullPath) {
+               public Document (string fullPath, string editorPath) {
                        initCommands ();
+                       EditorPath = editorPath;
                        FullPath = fullPath;
-                       App.TryGetContainingProject (FullPath, out project);
                }
+               /// <summary>
+               /// Editor used to open the document, can't be changed once opened
+               /// </summary>
+               /// <remark>
+               /// The editor path is used as an ID for itemTemplate selection
+               /// </remark>
+               /// <value></value>
+               public string EditorPath { get; private set; }//the ressource path is used as an id for editor template selection.
                public event EventHandler CloseEvent;
-               public void SelectDocument () => IsSelected = true;
-               public void UnselectDocument () => IsSelected = true;
 
                protected ReaderWriterLockSlim editorRWLock = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion);
                public void EnterReadLock () => editorRWLock.EnterReadLock ();
@@ -102,5 +107,16 @@ namespace CrowEditBase
                public abstract bool IsDirty { get; }
 
                public override string ToString() => FullPath;
+
+               public override bool IsSelected {
+                       get => base.IsSelected;
+                       set {
+                               if (isSelected == value)
+                                       return;
+                               base.IsSelected = value;
+                               if (App.TryFindFileNode (FullPath, out IFileNode node))
+                                       (node as TreeNode).IsSelected = isSelected;
+                       }
+               }
        }
 }
\ No newline at end of file
index 92eb65b1cb04e27c940b3eaf8faebadf84a7b734..1d3fdc16e0f218e59015b9d06ba85f757cd31772 100644 (file)
@@ -7,11 +7,7 @@ using Glfw;
 using Crow.Text;
 using System.Collections.Generic;
 using Crow.Drawing;
-using System.Threading.Tasks;
 using System.Linq;
-using System.Diagnostics.CodeAnalysis;
-using System.Reflection;
-using System.Collections;
 using CrowEditBase;
 using System.Threading;
 using System.ComponentModel;
@@ -357,7 +353,7 @@ namespace Crow
                        CharLocation selStart = default, selEnd = default;
                        bool selectionNotEmpty = false;
 
-                       if (HasFocus) {
+                       //if (HasFocus) {
                                if (currentLoc?.Column < 0) {
                                        updateLocation (gr, cb.Width, ref currentLoc);
                                        NotifyValueChanged ("CurrentColumn", CurrentColumn);
@@ -384,7 +380,7 @@ namespace Crow
                                        }
                                } else
                                        IFace.forceTextCursor = true;
-                       }
+                       //}
 
                        if (!string.IsNullOrEmpty (_text)) {
                                Foreground?.SetAsSource (IFace, gr);
@@ -427,7 +423,7 @@ namespace Crow
                                                Foreground.SetAsSource (IFace, gr);
                                                ********** DEBUG TextLineCollection *************/
 
-                                               if (HasFocus && selectionNotEmpty) {
+                                               if (selectionNotEmpty) {
                                                        RectangleD selRect = lineRect;
 
                                                        if (i >= selStart.Line && i <= selEnd.Line) {
@@ -472,14 +468,14 @@ namespace Crow
                protected virtual void updateHoverLocation (Point mouseLocalPos) {
                        int hoverLine = (int)Math.Min (Math.Max (0, Math.Floor ((mouseLocalPos.Y + ScrollY)/ (fe.Ascent + fe.Descent))), lines.Count - 1);
                        int scrollLine = (int)Math.Ceiling((double)ScrollY / (fe.Ascent + fe.Descent));
-                       if (hoverLine > scrollLine + visibleLines)
-                               ScrollY = (int)((double)(hoverLine - visibleLines) * (fe.Ascent + fe.Descent));
+                       /*if (hoverLine > scrollLine + visibleLines)
+                               ScrollY = (int)((double)(hoverLine - visibleLines) * (fe.Ascent + fe.Descent));*/
                        NotifyValueChanged("MouseY", mouseLocalPos.Y + ScrollY);
                        NotifyValueChanged("ScrollY", ScrollY);
                        NotifyValueChanged("VisibleLines", visibleLines);
                        NotifyValueChanged("HoverLine", hoverLine);
                        NotifyValueChanged("ScrollLine", hoverLine);
-                       hoverLoc = new CharLocation (hoverLine, -1, mouseLocalPos.X);
+                       hoverLoc = new CharLocation (hoverLine, -1, mouseLocalPos.X + ScrollX);
                        using (Context gr = new Context (IFace.surf)) {
                                setFontForContext (gr);
                                updateLocation (gr, ClientRectangle.Width, ref hoverLoc);
@@ -571,8 +567,8 @@ namespace Crow
                        }
                }
 
-               protected void checkShift () {
-                       if (IFace.Shift) {
+               protected void checkShift (KeyEventArgs e) {
+                       if (e.Modifiers.HasFlag (Modifier.Shift)) {
                                if (!selectionStart.HasValue)
                                        selectionStart = CurrentLoc;
                        } else
@@ -599,18 +595,20 @@ namespace Crow
                public override int measureRawSize(LayoutingType lt)
                {
                        DbgLogger.StartEvent(DbgEvtType.GOMeasure, this, lt);
+                       try {
+                               if ((bool)lines?.IsEmpty)
+                                       getLines ();
 
-                       if ((bool)lines?.IsEmpty)
-                               getLines ();
-
-                       if (!textMeasureIsUpToDate) {
-                               using (Context gr = new Context (IFace.surf)) {
-                                       setFontForContext (gr);
-                                       measureTextBounds (gr);
+                               if (!textMeasureIsUpToDate) {
+                                       using (Context gr = new Context (IFace.surf)) {
+                                               setFontForContext (gr);
+                                               measureTextBounds (gr);
+                                       }
                                }
+                               return Margin * 2 + (lt == LayoutingType.Height ? cachedTextSize.Height : cachedTextSize.Width);
+                       } finally {
+                               DbgLogger.EndEvent(DbgEvtType.GOMeasure);
                        }
-                       DbgLogger.EndEvent(DbgEvtType.GOMeasure);
-                       return Margin * 2 + (lt == LayoutingType.Height ? cachedTextSize.Height : cachedTextSize.Width);
                }
 
                protected override void onDraw (Context gr)
@@ -643,33 +641,41 @@ namespace Crow
                {
                        base.onFocused (sender, e);
 
-                       if (CurrentLoc == null) {
-                               selectionStart = new CharLocation (0, 0);
-                               CurrentLoc = new CharLocation (lines.Count - 1, lines[lines.Count - 1].Length);
-                       }
+                       if (CurrentLoc == null)
+                               CurrentLoc = new CharLocation (0, 0);
 
                        RegisterForRedraw ();
 
                        (IFace as CrowEditBase.CrowEditBase).CurrentEditor = this;
                }
-               protected override void onUnfocused (object sender, EventArgs e)
+               /*protected override void onUnfocused (object sender, EventArgs e)
                {
                        base.onUnfocused (sender, e);
                        RegisterForRedraw ();
-               }
+               }*/
         public override void onMouseEnter (object sender, MouseMoveEventArgs e) {
             base.onMouseEnter (sender, e);
+                       HasFocus = true;
                        if (Focusable)
                                IFace.MouseCursor = MouseCursor.ibeam;
                }
         public override void onMouseMove (object sender, MouseMoveEventArgs e)
                {
                        base.onMouseMove (sender, e);
-
-                       updateHoverLocation (ScreenPointToLocal (e.Position));
+                       mouseMove (e);
+               }
+               public override void onMouseWheel(object sender, MouseWheelEventArgs e)
+               {
+                       base.onMouseWheel(sender, e);
+                       mouseMove (e);
+               }
+               void mouseMove (MouseEventArgs e) {
+                       updateHoverLocation (ScreenPointToLocal (IFace.MousePosition));
 
                        if (HasFocus && IFace.IsDown (MouseButton.Left)) {
                                CurrentLoc = hoverLoc;
+                               autoAdjustScroll = true;
+                               IFace.forceTextCursor = true;
                                RegisterForRedraw ();
                        }
                }
@@ -745,9 +751,9 @@ namespace Crow
                                }
                                break;
                        case Key.Insert:
-                               if (IFace.Shift)
+                               if (e.Modifiers.HasFlag (Modifier.Shift))
                                        Paste ();
-                               else if (IFace.Ctrl)
+                               else if (e.Modifiers.HasFlag (Modifier.Control))
                                        Copy ();
                                break;
                        case Key.KeypadEnter:
@@ -765,56 +771,62 @@ namespace Crow
                                update (new TextChange (selection.Start, selection.Length, "\t"));
                                break;
                        case Key.PageUp:
-                               checkShift ();
+                               checkShift (e);
                                LineMove (-visibleLines);
                                RegisterForRedraw ();
                                break;
                        case Key.PageDown:
-                               checkShift ();
+                               checkShift (e);
                                LineMove (visibleLines);
                                RegisterForRedraw ();
                                break;
                        case Key.Home:
                                targetColumn = -1;
-                               checkShift ();
-                               if (IFace.Ctrl)
+                               checkShift (e);
+                               if (e.Modifiers.HasFlag (Modifier.Control))
                                        CurrentLoc = new CharLocation (0, 0);
                                else
                                        CurrentLoc = new CharLocation (CurrentLoc.Value.Line, 0);
                                RegisterForRedraw ();
                                break;
                        case Key.End:
-                               checkShift ();
-                               int l = IFace.Ctrl ? lines.Count - 1 : CurrentLoc.Value.Line;
+                               checkShift (e);
+                               int l = e.Modifiers.HasFlag (Modifier.Control) ? lines.Count - 1 : CurrentLoc.Value.Line;
                                CurrentLoc = new CharLocation (l, lines[l].Length);
                                RegisterForRedraw ();
                                break;
                        case Key.Left:
-                               checkShift ();
-                               if (IFace.Ctrl)
+                               checkShift (e);
+                               if (e.Modifiers.HasFlag (Modifier.Control))
                                        GotoWordStart ();
                                else
                                        MoveLeft ();
                                RegisterForRedraw ();
                                break;
                        case Key.Right:
-                               checkShift ();
-                               if (IFace.Ctrl)
+                               checkShift (e);
+                               if (e.Modifiers.HasFlag (Modifier.Control))
                                        GotoWordEnd ();
                                else
                                        MoveRight ();
                                RegisterForRedraw ();
                                break;
                        case Key.Up:
-                               checkShift ();
+                               checkShift (e);
                                LineMove (-1);
                                RegisterForRedraw ();
                                break;
                        case Key.Down:
-                               checkShift ();
+                               checkShift (e);
                                LineMove (1);
                                RegisterForRedraw ();
                                break;
+                       case Key.A:
+                               if (e.Modifiers.HasFlag (Modifier.Control)) {
+                                       selectionStart = new CharLocation (0, 0);
+                                       CurrentLoc = new CharLocation (lines.Count - 1, lines[lines.Count - 1].Length);
+                               }
+                               break;
                        default:
                                base.onKeyDown (sender, e);
                                return;
@@ -836,10 +848,10 @@ namespace Crow
                        if (autoAdjustScroll) {
                                autoAdjustScroll = false;
                                int goodMsrs = 0;
-                               if (cursor.Right < 0)
-                                       ScrollX += cursor.Right;
+                               if (cursor.Left < 0)
+                                       ScrollX += cursor.Left;
                                else if (cursor.X > cb.Width)
-                                       ScrollX += cursor.X - cb.Width;
+                                       ScrollX += cursor.X - cb.Width + 5;
                                else
                                        goodMsrs++;
 
@@ -858,7 +870,7 @@ namespace Crow
                        return cursor;
                }
 
-               void updateMaxScrolls (LayoutingType layout) {
+               protected virtual void updateMaxScrolls (LayoutingType layout) {
                        Rectangle cb = ClientRectangle;
                        if (layout == LayoutingType.Width) {
                                MaxScrollX = cachedTextSize.Width - cb.Width;
index e9f0dd176aa102836e4a5ebeb1faddb08570359d..e681c801ab43c5de87b70129369d630df999f43a 100644 (file)
@@ -74,9 +74,13 @@ namespace CrowEditBase
                                        {
                                                foreach (string associations in fileAssociations.Split (';')) {
                                                        string[] typeExts = associations.Split (':');
-                                                       Type clientClass = loadContext.MainAssembly.GetType (typeExts[0]);
-                                                       foreach (string ext in typeExts[1].Split (','))
-                                                               App.AddFileAssociation (ext, clientClass);
+                                                       Type clientClass = loadContext.MainAssembly.GetType (typeExts[0].Trim());
+                                                       foreach (string ext in typeExts[1].Split (','))//supported extension comma separated list
+                                                               App.AddFileAssociation (ext.Trim(), clientClass);
+                                                       if (typeExts.Length < 3)
+                                                               continue;
+                                                       foreach (string editorPath in typeExts[2].Split (','))//comma separated list of supported editor path.
+                                                               App.AddSupportedEditor (clientClass, editorPath.Trim());
                                                }
                                        }
                                        catch (System.Exception ex)     {
index 682783936812bc6e0dcec83050af038ec79ff7f3..be4fd16adea6e18cf4bf526a458080461187faea 100644 (file)
@@ -13,7 +13,7 @@ using static CrowEditBase.CrowEditBase;
 
 namespace CrowEditBase
 {
-       
+
        /*public class Plugin {
                string path;
                Assembly assembly;
@@ -35,8 +35,8 @@ namespace CrowEditBase
                        string pluginAssembly = Path.Combine (fullPath, $"{Name}.dll");
                        MainAssembly = LoadFromAssemblyPath (pluginAssembly);
                }
-               protected override Assembly Load(AssemblyName assemblyName) {                   
-                       string assemblyPath = Path.Combine (fullPath, assemblyName.Name + ".dll");                      
+               protected override Assembly Load(AssemblyName assemblyName) {
+                       string assemblyPath = Path.Combine (fullPath, assemblyName.Name + ".dll");
                        return File.Exists (assemblyPath) ? LoadFromAssemblyPath (assemblyPath) : null;
                }
 
index 1c9bb93a8a863ef821099c09e159e40d9a7ec267..0b7c049c18005c1be10ed509c0c7c1da60745bfd 100644 (file)
@@ -2,40 +2,29 @@
 //
 // This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
 
-using System;
-using System.IO;
+using System.Collections.Generic;
 using System.Linq;
-using System.Threading;
 using Crow;
-using System.Reflection;
-using System.Runtime.CompilerServices;
-using System.Collections.Generic;
 using static CrowEditBase.CrowEditBase;
 
 namespace CrowEditBase
 {
-       public abstract class Project : CrowEditComponent {
+       public abstract class Project : TreeNode {
                bool isLoaded;
                protected Project parent;
-               protected IList<Project> subProjects;
-
-               public Project Parent => parent;
-               public IList<Project> SubProjects => subProjects;
-               public IEnumerable<Project> Flatten {
+               public abstract bool ContainsFile (string fullPath);
+               public IEnumerable<Project> SubProjetcs => Childs.OfType<Project> ();
+               public IEnumerable<Project> FlattenSubProjetcs {
                        get {
-                               yield return this;
-                               if (subProjects != null) {
-                                       foreach (var node in subProjects?.SelectMany (child => child.Flatten))
-                                               yield return node;
-                               }
+                               foreach (var node in SubProjetcs.SelectMany (sp => sp.FlattenSubProjetcs))
+                                       yield return node;
                        }
                }
-               public virtual bool ContainsFile (string fullPath) => false;
-               public bool HasChildren => subProjects?.Count > 0;
-
                public string FullPath { get ; private set; }
                public abstract string Name { get; }
-               public string Caption => Name;
+               public override string Caption => Name;
+               public override NodeType NodeType => NodeType.Project;
+
                public bool IsLoaded {
                        get => isLoaded;
                        set {
@@ -55,7 +44,7 @@ namespace CrowEditBase
                        FullPath = fullPath;
                }
                public Command CMDLoad, CMDUnload, CMDReload, CMDClose;
-               public virtual CommandGroup Commands => new CommandGroup (
+               public override CommandGroup Commands => new CommandGroup (
                        CMDLoad, CMDUnload, CMDReload, CMDClose);
 
                void initCommands () {
@@ -75,6 +64,6 @@ namespace CrowEditBase
                        App.Projects.Remove (this);
                        IsLoaded = false;
                }
-               public virtual string Icon => "#icons.question.svg";
+               public override string Icon => "#icons.question.svg";
        }
 }
\ No newline at end of file
index a20f683f5dd12faacd5f39ef36a63b564da655b1..aaa93a45e6b8d9b840ee118aa4dc68908256db67 100644 (file)
@@ -5,23 +5,16 @@
 using System;
 using Glfw;
 using Crow.Text;
-using System.Collections.Generic;
 using Crow.Drawing;
-using System.Threading.Tasks;
-using System.Linq;
-using System.Diagnostics.CodeAnalysis;
-using System.Reflection;
 using System.Collections;
 using CrowEditBase;
+using static CrowEditBase.CrowEditBase;
 
 namespace Crow
 {
        public class SourceEditor : Editor {
                object TokenMutex = new object();
 
-
-
-
                ListBox overlay;
                IList suggestions;
                volatile bool disableSuggestions;
@@ -53,8 +46,6 @@ namespace Crow
                        //Console.WriteLine ($"{pos}: {suggestionTok.AsString (_text)} {suggestionTok}");
                }
 
-
-
                protected void tryGetSuggestions () {
                        if (currentLoc.HasValue && Document is SourceDocument srcDoc)
                                Suggestions = srcDoc.GetSuggestions (lines.GetAbsolutePosition (CurrentLoc.Value));
@@ -121,7 +112,6 @@ namespace Crow
                        hideOverlay ();
                        base.onMouseDown (sender, e);
                }
-
                public override void onKeyDown(object sender, KeyEventArgs e)
                {
                        TextSpan selection = Selection;
@@ -188,22 +178,87 @@ namespace Crow
                        base.onKeyDown(sender, e);
                }
 
+               const int leftMarginGap = 3;//gap between margin start and numbering
+               const int leftMarginRightGap = 3;//gap between items in margin and text
+               const int foldSize = 9;//folding rectangles size
+               const int foldMargin = 9;
+
+               int leftMargin;
+               void updateMargin () {
+                       leftMargin = leftMarginGap;
+                       if (App.PrintLineNumbers)
+                               leftMargin += (int)Math.Ceiling((double)lines.Count.ToString().Length * fe.MaxXAdvance) + 6;
+                       if (App.FoldingEnabled)
+                               leftMargin += foldMargin;
+                       if (leftMargin > 0)
+                               leftMargin += leftMarginRightGap;
+                       //updateVisibleColumns ();
+               }
+               public override int measureRawSize(LayoutingType lt)
+               {
+                       DbgLogger.StartEvent(DbgEvtType.GOMeasure, this, lt);
+                       try {
+                               if ((bool)lines?.IsEmpty)
+                                       getLines ();
+
+                               updateMargin ();
+
+                               if (!textMeasureIsUpToDate) {
+                                       using (Context gr = new Context (IFace.surf)) {
+                                               setFontForContext (gr);
+                                               measureTextBounds (gr);
+                                       }
+                               }
+                               return Margin * 2 + (lt == LayoutingType.Height ? cachedTextSize.Height : cachedTextSize.Width + leftMargin);
+                       } finally {
+                               DbgLogger.EndEvent(DbgEvtType.GOMeasure);
+                       }
+               }
+               protected override void updateMaxScrolls (LayoutingType layout) {
+                       updateMargin();
+                       Rectangle cb = ClientRectangle;
+                       cb.Width -= leftMargin;
+                       if (layout == LayoutingType.Width) {
+                               MaxScrollX = cachedTextSize.Width - cb.Width;
+                               NotifyValueChanged ("PageWidth", ClientRectangle.Width);
+                               if (cachedTextSize.Width > 0)
+                                       NotifyValueChanged ("ChildWidthRatio", Math.Min (1.0, (double)cb.Width / cachedTextSize.Width));
+                       } else if (layout == LayoutingType.Height) {
+                               MaxScrollY = cachedTextSize.Height - cb.Height;
+                               NotifyValueChanged ("PageHeight", ClientRectangle.Height);
+                               if (cachedTextSize.Height > 0)
+                                       NotifyValueChanged ("ChildHeightRatio", Math.Min (1.0, (double)cb.Height / cachedTextSize.Height));
+                       }
+               }
+
                protected override void drawContent (Context gr) {
-                       if (!(Document is SourceDocument xmlDoc)) {
+                       if (!(Document is SourceDocument doc)) {
                                base.drawContent (gr);
                                return;
                        }
                        //lock(TokenMutex) {
-                       xmlDoc.EnterReadLock ();
+                       doc.EnterReadLock ();
                        try {
-                               if (xmlDoc.Tokens == null || xmlDoc.Tokens.Length == 0) {
+                               if (doc.Tokens == null || doc.Tokens.Length == 0) {
                                        base.drawContent (gr);
                                        return;
                                }
 
-                               Rectangle cb = ClientRectangle;
-                               fe = gr.FontExtents;
                                double lineHeight = fe.Ascent + fe.Descent;
+                               updateMargin ();
+
+                               bool printLineNumbers = App.PrintLineNumbers;
+                               Color marginBG = App.MarginBackground;
+                               Color marginFG = Colors.Ivory;
+                               double lineNumWidth = gr.TextExtents (lines.Count.ToString()).Width;
+
+                               Rectangle cb = ClientRectangle;
+                               RectangleD marginRect = new RectangleD (cb.X, cb.Y, leftMargin - leftMarginRightGap, lineHeight);
+                               /*gr.SetSource (App.MarginBackground);
+                               gr.Rectangle (marginRect);
+                               gr.Fill ();*/
+                               cb.Left += leftMargin;
+
 
                                CharLocation selStart = default, selEnd = default;
                                bool selectionNotEmpty = false;
@@ -252,16 +307,17 @@ namespace Crow
                                int x = 0, y = 0;
                                double pixX = cb.Left;
 
-
                                Foreground.SetAsSource (IFace, gr);
                                gr.Translate (-ScrollX, -ScrollY);
 
 
-                               ReadOnlySpan<char> sourceBytes = xmlDoc.Source.AsSpan();
+
+
+                               ReadOnlySpan<char> sourceBytes = doc.Source.AsSpan();
                                Span<byte> bytes = stackalloc byte[128];
                                TextExtents extents;
                                int tokPtr = 0;
-                               Token tok = xmlDoc.Tokens[tokPtr];
+                               Token tok = doc.Tokens[tokPtr];
                                bool multilineToken = false;
 
                                ReadOnlySpan<char> buff = sourceBytes;
@@ -286,7 +342,7 @@ namespace Crow
                                                        } else
                                                                buff = sourceBytes.Slice (tok.Start, tok.Length);
 
-                                                       gr.SetSource(xmlDoc.GetColorForToken (tok.Type));
+                                                       gr.SetSource(doc.GetColorForToken (tok.Type));
                                                }
 
                                                int size = buff.Length * 4 + 1;
@@ -311,13 +367,13 @@ namespace Crow
                                                                break;
                                                }
 
-                                               if (++tokPtr >= xmlDoc.Tokens.Length)
+                                               if (++tokPtr >= doc.Tokens.Length)
                                                        break;
-                                               tok = xmlDoc.Tokens[tokPtr];
+                                               tok = doc.Tokens[tokPtr];
                                        }
 
-                                       if (HasFocus && selectionNotEmpty) {
-                                               RectangleD lineRect = new RectangleD (cb.X,     lineHeight * y + cb.Top, pixX, lineHeight);
+                                       RectangleD lineRect = new RectangleD (cb.X,     lineHeight * y + cb.Top, pixX, lineHeight);
+                                       if (selectionNotEmpty) {
                                                RectangleD selRect = lineRect;
 
                                                if (i >= selStart.Line && i <= selEnd.Line) {
@@ -357,14 +413,29 @@ namespace Crow
                                                }
                                        }
 
+                                       //Draw line numbering
+                                       int curLine = i;
+                                       if (printLineNumbers){
+                                               marginRect.Y = lineRect.Y;
+
+                                               string strLN = (curLine+1).ToString ();
+                                               gr.SetSource (marginBG);
+                                               gr.Rectangle (marginRect);
+                                               gr.Fill();
+                                               gr.SetSource (marginFG);
+                                               gr.MoveTo (marginRect.X + leftMarginGap + lineNumWidth - gr.TextExtents (strLN).Width, marginRect.Y + fe.Ascent);
+                                               gr.ShowText (strLN);
+                                               gr.Fill ();
+                                       }
+
                                        if (!multilineToken) {
-                                               if (++tokPtr >= xmlDoc.Tokens.Length)
+                                               if (++tokPtr >= doc.Tokens.Length)
                                                        break;
-                                               tok = xmlDoc.Tokens[tokPtr];
+                                               tok = doc.Tokens[tokPtr];
                                        }
 
                                        x = 0;
-                                       pixX = 0;
+                                       pixX = cb.Left;
 
                                        y++;
 
@@ -383,7 +454,7 @@ namespace Crow
                                }
                                //gr.Translate (ScrollX, ScrollY);
                        } finally {
-                               xmlDoc.ExitReadLock ();
+                               doc.ExitReadLock ();
                        }
 
                }
index ada9c1b516c936885866c22c4f116b9690cffe94..26828d151933788e2b2ff511e02dd13a9ba88b74 100644 (file)
@@ -13,8 +13,8 @@ using static CrowEditBase.CrowEditBase;
 namespace CrowEditBase
 {
        public class TextDocument : Document {
-               public TextDocument (string fullPath)
-                       : base (fullPath) {
+               public TextDocument (string fullPath, string editorPath = "default")
+                       : base (fullPath, editorPath) {
                        reloadFromFile ();
                }
 
index 7de3c530eff2e36a8d18d91aab3cb680ee05871c..195216f9cf5c333ca86f279d695cc7db9981225e 100644 (file)
@@ -21,27 +21,41 @@ namespace CrowEditBase
                None,
                Compile,
                EmbeddedResource,
-       }       
+               Project,
+               ProjectGroup,
+       }
        public abstract class TreeNode : CrowEditComponent
        {
                #region CTOR
                protected TreeNode () { }
                #endregion
 
-               ObservableList<TreeNode> children = new ObservableList<TreeNode> ();            
+               ObservableList<TreeNode> children = new ObservableList<TreeNode> ();
 
-               protected bool isSelected, isExpanded;
+               protected bool isExpanded;
 
                public TreeNode Parent { get; private set; }
 
                public abstract string Caption { get; }
                public abstract NodeType NodeType { get; }
-               public T GetRoot<T> () where T : TreeNode {
+               public abstract string Icon { get; }
+               public virtual string IconSub => null;
+               public T GetFirstAncestorOfType<T> () where T : TreeNode {
                        TreeNode n = this;
-                       while (n.Parent != null)
+                       while (n.Parent != null && !(n is T))
                                n = n.Parent;
                        return (T)n;
                }
+               public virtual bool TryFindFileNode (string fullPath, out IFileNode node) {
+                       foreach (IFileNode n in Flatten.OfType<IFileNode> ()) {
+                               if (n.FullPath == fullPath) {
+                                       node = n;
+                                       return true;
+                               }
+                       }
+                       node = null;
+                       return false;
+               }
 
                public ObservableList<TreeNode> Childs {
                        get => children;
@@ -64,9 +78,11 @@ namespace CrowEditBase
                        pn.Parent = null;
                        children.Remove (pn);
                }
-               /*public override bool IsSelected {
+               public override bool IsSelected {
                        get => base.IsSelected;
                        set {
+                               if (isSelected == value)
+                                       return;
                                base.IsSelected = value;
                                if (isSelected) {
                                        TreeNode pn = Parent;
@@ -76,9 +92,9 @@ namespace CrowEditBase
                                        }
                                }
                        }
-               }*/
+               }
                public virtual bool IsExpanded {
-                       get { return isExpanded; }
+                       get => isExpanded;
                        set {
                                if (value == isExpanded)
                                        return;
@@ -88,8 +104,7 @@ namespace CrowEditBase
                        }
                }
                public bool HasChildren => children?.Count > 0;
-               public abstract string Icon { get; }
-               public virtual string IconSub => null;
+
 
                public IEnumerable<TreeNode> Flatten {
                        get {
@@ -98,7 +113,6 @@ namespace CrowEditBase
                                        yield return node;
                        }
                }
-
                public virtual void SortChilds ()
                {
                        foreach (TreeNode pn in Childs)
index 7da49915c935ad258bf2c96fde7f820f1703c899..593bf6fa4ab003d26ae1b737fe4628964630869a 100644 (file)
@@ -25,7 +25,7 @@ namespace CrowEditBase
 
                public override CommandGroup Commands {
                        get {
-                               return null; 
+                               return null;
                        }
                }
        }
index 8bdd96d0a4681ccf61bc1895d0b7f14744047e56..f784b956ef165894d65ac1dd485ef617e80b8ad0 100644 (file)
@@ -14,11 +14,18 @@ ControlIdle = "Jet";
 
 DockWindowBackground = "DarkGrey";
 
+TreeItemBorderCornerRadius     = "0";
+TreeItemBorderFG                       = "Transparent";
+TreeItemBorderHighlightFG      = "DimGrey";
+TreeItemBackground                     = "Transparent";
+//TreeItemHighlight                    = "
+
 Editor {
        Background="White";
        Foreground="Black";
        MouseWheelSpeed = "20";
-       BubbleMouseEvent ="None";
+       BubbleEvents ="None";
+       ClipToClientRect = "false";
 }
 
 icon {
index 488f879d6131c52bd257949ba656696d07323158..ea45ddb5a5e174693e2458b0eb29d678bcaa30df 100644 (file)
@@ -1,5 +1,7 @@
 <?xml version="1.0"?>
-<Expandable Caption="{Caption}" IsExpanded="{²IsExpanded}" BubbleMouseEvent="MouseWheel" ContextCommands="{Commands}">
+<Expandable Caption="{Caption}" IsExpanded="{²IsExpanded}" BubbleEvents="MouseWheel"
+               Focusable = "true"
+               MouseClick="{.DataSource.IsSelected='true'}">
        <HorizontalStack Height="Fit">
                <Shape Foreground="DimGrey" Background="Transparent"
                        Path="M 5.5,0 L 5.5,11 G" Size="11,11" Width="11" Height="Stretched" KeepProportions="false" Margin="0"/>
@@ -7,20 +9,26 @@
        </HorizontalStack>
        <Template>
                <VerticalStack>
-                       <ListItem Margin="1" IsSelected="{²IsSelected}"
-                               Selected="{Background=RoyalBlue}"
-                               Unselected="{Background=Transparent}">
-                               <HorizontalStack Spacing="5" MouseDoubleClick="./onClickForExpand">
-                                       <Image Margin="1" Width="9" Height="9" Focusable="true" MouseClick="./onClickForExpand"
-                                               Path="{./Image}"
-                                               Visible="{./IsExpandable}"
-                                               SvgSub="{./IsExpanded}"
-                                               MouseEnter="{Background=LightGrey}"
-                                               MouseLeave="{Background=Transparent}"/>
-                                       <Image Style="TreeIcon"
-                                               Path="{Icon}" SvgSub="{IconSub}"/>
-                                       <Label Style="TreeLabel" Text="{./Caption}"/>
-                               </HorizontalStack>
+                       <ListItem IsSelected="{²IsSelected}" ContextCommands="{Commands}" BubbleEvents="All"
+                                       MouseDoubleClick="./onClickForExpand"
+                                       Selected="{/border.Background=${ControlHighlight}}"
+                                       Unselected="{/border.Background=${TreeItemBackground}}"
+                                       MouseEnter="{/border.Foreground=${TreeItemBorderHighlightFG}}"
+                                       MouseLeave="{/border.Foreground=${TreeItemBorderFG}}">
+                               <Border Name="border" Margin="2" CornerRadius="${TreeItemBorderCornerRadius}"
+                                                                                                       Foreground="${TreeItemBorderFG}">
+                                       <HorizontalStack Spacing="5">
+                                               <Image Margin="1" Width="9" Height="9" Focusable="true" MouseClick="./onClickForExpand"
+                                                       Path="{./Image}"
+                                                       Visible="{./IsExpandable}"
+                                                       SvgSub="{./IsExpanded}"
+                                                       MouseEnter="{Background=LightGrey}"
+                                                       MouseLeave="{Background=Transparent}"/>
+                                               <Image Style="TreeIcon"
+                                                       Path="{Icon}" SvgSub="{IconSub}"/>
+                                               <Label Style="TreeLabel" Text="{./Caption}"/>
+                                       </HorizontalStack>
+                               </Border>
                        </ListItem>
                        <Container Name="Content" Visible="false"/>
                </VerticalStack>
index 92af439c7d35301253184447334abb609085d872..01b6d2496a0c5942fe2683d83e20be1d77220e17 100644 (file)
@@ -3,7 +3,7 @@
                <OutputPath>$(SolutionDir)build\$(Configuration)\</OutputPath>
                <IntermediateOutputPath>$(SolutionDir)build\obj\$(Configuration)\</IntermediateOutputPath>
                <License>MIT</License>
-               <Authors>Jean-Philippe Bruyère</Authors>           
+               <Authors>Jean-Philippe Bruyère</Authors>
                <LangVersion>7.2</LangVersion>
        </PropertyGroup>
 </Project>
index 422639678919041ad28918c0425d5f1dda70348d..f557a312f59864f9966366065c859af2e4501ded 100644 (file)
@@ -1 +1 @@
-FileAssociations=CECrowPlugin.ImlDocument:.crow,.iml,.itmp,.template,.tmp;CECrowPlugin.StyleDocument:.style
\ No newline at end of file
+FileAssociations = CECrowPlugin.ImlDocument:.crow,.iml,.itmp,.template,.tmp:#ui.sourceEditor.itmp;CECrowPlugin.StyleDocument:.style:#ui.sourceEditor.itmp
index 86ff6a4db7cb64ea924ee6091d5bffe11026b198..c146d22e42136836dff9cd07e45b115fa0e239b4 100644 (file)
@@ -498,7 +498,7 @@ namespace Crow
                public IEnumerable<object> GetStyling () {
                        if (App.CurrentProject is CERoslynPlugin.SolutionProject sol) {
                                if (sol.StartupProject is CERoslynPlugin.MSBuildProject csprj) {
-                                       foreach (var style in csprj.RootNode.Flatten.OfType<CERoslynPlugin.ProjectItemNode>()
+                                       foreach (var style in csprj.Flatten.OfType<CERoslynPlugin.ProjectItemNode>()
                                                .Where (pin=>pin.NodeType == NodeType.EmbeddedResource && pin.FullPath.EndsWith (".style", StringComparison.OrdinalIgnoreCase)))
                                                yield return style.FullPath;
                                }
index 9d356817112ec3ba1f8b714773bcf28de8be1ec6..cffbc91a765b2bf7a1dda6de0c52e2190ec1d4c0 100644 (file)
@@ -15,8 +15,6 @@ namespace CECrowPlugin
 {
        public class DebugInterface : Interface {
                static DebugInterface() {
-                       DbgLogger.IncludeEvents = DbgEvtType.None;
-                       DbgLogger.DiscardEvents = DbgEvtType.None;
                        DbgLogger.ConsoleOutput = false;
                }
                public DebugInterface (IntPtr hWin) : base (100, 100, hWin)
index a00de9b19e997872a4b8a22824228e5c2d1933a9..479f1f5bff7923e755ab24b34e5b2c9995d000ae 100644 (file)
@@ -22,7 +22,7 @@ namespace CECrowPlugin
        public class ImlDocument : XmlDocument {
 
 
-               public ImlDocument (string fullPath) : base (fullPath) {
+               public ImlDocument (string fullPath, string editorPath) : base (fullPath, editorPath) {
                        App.GetService<CrowService> ()?.Start ();
 
                        /*if (project is MSBuildProject msbp) {
diff --git a/plugins/CECrowPlugin/src/StyleDocument.cs b/plugins/CECrowPlugin/src/StyleDocument.cs
new file mode 100644 (file)
index 0000000..88b7aba
--- /dev/null
@@ -0,0 +1,58 @@
+// 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 Crow.Text;
+using Crow;
+using System.Collections;
+using CrowEditBase;
+using static CrowEditBase.CrowEditBase;
+
+namespace CECrowPlugin
+{
+       public class StyleDocument : SourceDocument {
+
+
+               public StyleDocument (string fullPath, string editorPath) : base (fullPath, editorPath) {
+                       App.GetService<CrowService> ()?.Start ();
+
+                       /*if (project is MSBuildProject msbp) {
+                               if (msbp.IsCrowProject)
+                       }*/
+               }
+
+               protected override Tokenizer CreateTokenizer() => new StyleTokenizer ();
+               protected override SyntaxAnalyser CreateSyntaxAnalyser() => new StyleSyntaxAnalyser (this);
+
+               public override IList GetSuggestions (int pos) {
+                       currentToken = FindTokenIncludingPosition (pos);
+                       currentNode = FindNodeIncludingPosition (pos);
+                       return null;
+               }
+               public override TextChange? GetCompletionForCurrentToken (object suggestion, out TextSpan? newSelection) {
+                       newSelection = null;
+                       return null;
+               }
+               public override Color GetColorForToken(TokenType tokType)
+               {
+                       StyleTokenType xmlTokType = (StyleTokenType)tokType;
+                       if (xmlTokType.HasFlag (StyleTokenType.Punctuation))
+                               return Colors.DarkGrey;
+                       if (xmlTokType.HasFlag (StyleTokenType.Trivia))
+                               return Colors.DimGrey;
+                       if (xmlTokType == StyleTokenType.MemberName)
+                               return Colors.Blue;
+                       if (xmlTokType == StyleTokenType.ConstantName)
+                               return Colors.DarkCyan;
+                       else if (xmlTokType.HasFlag (StyleTokenType.Name))
+                               return Colors.Green;
+                       if (xmlTokType == StyleTokenType.MemberValuePart)
+                               return Colors.OrangeRed;
+                       if (xmlTokType == StyleTokenType.EqualSign)
+                               return Colors.Black;
+                       if (xmlTokType == StyleTokenType.Unknown)
+                               return Colors.Red;
+                       return Colors.YellowGreen;
+               }
+       }
+}
\ No newline at end of file
diff --git a/plugins/CECrowPlugin/src/StyleParsing/StyleDocument.cs b/plugins/CECrowPlugin/src/StyleParsing/StyleDocument.cs
deleted file mode 100644 (file)
index 9e3692b..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-// 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 System.Linq;
-using Crow.Text;
-using System.Collections.Generic;
-using System.Diagnostics;
-using Crow;
-using IML = Crow.IML;
-using System.Collections;
-using System.Reflection;
-using CrowEditBase;
-using static CrowEditBase.CrowEditBase;
-
-using CERoslynPlugin;
-
-namespace CECrowPlugin
-{
-       public class StyleDocument : SourceDocument {
-
-
-               public StyleDocument (string fullPath) : base (fullPath) {
-                       App.GetService<CrowService> ()?.Start ();
-
-                       /*if (project is MSBuildProject msbp) {
-                               if (msbp.IsCrowProject)
-                       }*/
-               }
-
-               protected override Tokenizer CreateTokenizer() => new StyleTokenizer ();
-               protected override SyntaxAnalyser CreateSyntaxAnalyser() => new StyleSyntaxAnalyser (this);
-
-               public override IList GetSuggestions (int pos) {
-                       currentToken = FindTokenIncludingPosition (pos);
-                       currentNode = FindNodeIncludingPosition (pos);
-                       return null;
-               }
-               public override TextChange? GetCompletionForCurrentToken (object suggestion, out TextSpan? newSelection) {
-                       newSelection = null;
-                       return null;
-               }
-               public override Color GetColorForToken(TokenType tokType)
-               {
-                       StyleTokenType xmlTokType = (StyleTokenType)tokType;
-                       if (xmlTokType.HasFlag (StyleTokenType.Punctuation))
-                               return Colors.DarkGrey;
-                       if (xmlTokType.HasFlag (StyleTokenType.Trivia))
-                               return Colors.DimGrey;
-                       if (xmlTokType == StyleTokenType.MemberName)
-                               return Colors.Blue;
-                       if (xmlTokType == StyleTokenType.ConstantName)
-                               return Colors.DarkCyan;
-                       else if (xmlTokType.HasFlag (StyleTokenType.Name))
-                               return Colors.Green;
-                       if (xmlTokType == StyleTokenType.MemberValuePart)
-                               return Colors.OrangeRed;
-                       if (xmlTokType == StyleTokenType.EqualSign)
-                               return Colors.Black;
-                       if (xmlTokType == StyleTokenType.Unknown)
-                               return Colors.Red;
-                       return Colors.YellowGreen;
-               }
-       }
-}
\ No newline at end of file
index 135b13cd54423973ac44f22a3c0d5452a2ed9828..2a3ee44d1f9eef9f65578189bc546dd125101571 100644 (file)
@@ -3,7 +3,7 @@
        <ListItem Height="Fit"
                                                Selected="{/exp.Background=${ControlHighlight}}"
                                                Unselected="{/exp.Background=Transparent}">
-               <Expandable Name="exp" Caption="{type}" MouseDoubleClick="/onClickForExpand" CacheEnabled="true" BubbleMouseEvent="All">
+               <Expandable Name="exp" Caption="{type}" MouseDoubleClick="/onClickForExpand" CacheEnabled="true" BubbleEvents="All">
                        <Template>
                                        <VerticalStack>
                                                <Border CornerRadius="2" Margin="0" Height="Fit" MouseDoubleClick="./onClickForExpand"
@@ -37,7 +37,7 @@
        <ListItem  Height="Fit"
                                                Selected="{/exp.Background=${ControlHighlight}}"
                                                Unselected="{/exp.Background=Transparent}">
-               <Expandable Name="exp" Caption="{type}" MouseDoubleClick="/onClickForExpand" CacheEnabled="true" BubbleMouseEvent="All">
+               <Expandable Name="exp" Caption="{type}" MouseDoubleClick="/onClickForExpand" CacheEnabled="true" BubbleEvents="All">
                        <Template>
                                <VerticalStack>
                                        <Border CornerRadius="2" Margin="0" Height="Fit" MouseDoubleClick="./onClickForExpand"
index 6b4c574dd5a81d6b4e5ac87faf691b3e8d369573..3f4aeb8f9bf56bd16287a0789389a2496aaf1b86 100644 (file)
@@ -2,11 +2,19 @@
 <DockWindow Caption="Crow Preview"  Width="60%" Commands="{/dbgIfaceWidget.WindowCommands}">
        <VerticalStack Background="Black" >
                <DebugInterfaceWidget Name="dbgIfaceWidget" Focusable="true"
-                                       BubbleMouseEvent="None"
+                                       BubbleEvents="None"
                                        Document="{CurrentDocument}"/>
-               <Label DataSource="{../dbgIfaceWidget.CrowIFaceService}" Text="{CurrentException}" Background="DarkRed" Foreground="White"
-                               IsVisible="{PreviewHasError}"
-                               Width="Stretched" Margin="2" Multiline="true"/>
+               <Popper DataSource="{../dbgIfaceWidget.CrowIFaceService}" IsVisible="{PreviewHasError}" Background="DarkRed">
+                       <Template>
+                               <CheckBox IsChecked="{²./IsPopped}" MouseEnter="{IsChecked='true'}" MouseLeave="{IsChecked='false'}">
+                                       <Template>
+                                               <Label DataSource="{CurrentException}" Text="{Message}" Background="Red" Foreground="White" Width="Stretched" Margin="2"
+                                                       Multiline="true"/>
+                                       </Template>
+                               </CheckBox>
+                       </Template>
+                       <Label Text="{CurrentException}" Background="DarkRed" Foreground="White" Width="90%" Margin="2" Multiline="true"/>
+               </Popper>
        </VerticalStack>
 </DockWindow>
 
index 0a9eaa0d05de6a5a5f8e1b32f664317831e49213..0d41c961a2352f56706c9e51a0c528b24e7a2b30 100644 (file)
@@ -17,6 +17,7 @@ namespace CERoslynPlugin
        {
                IEventSource eventSource;
                LoggerVerbosity verbosity;
+               MessageImportance maxMsgImportance;
 
                public LoggerVerbosity Verbosity {
                        get => verbosity;
@@ -47,18 +48,22 @@ namespace CERoslynPlugin
                        eventSource.ErrorRaised += EventSource_ErrorRaised;
                        eventSource.BuildStarted += EventSource_Progress_BuildStarted;
                        eventSource.BuildFinished += EventSource_Progress_BuildFinished;
+                       eventSource.MessageRaised += EventSource_MessageRaised;
 
                        switch (Verbosity) {
                        case LoggerVerbosity.Minimal:
-                               eventSource.MessageRaised += EventSource_MessageRaised_Minimal;
+                               maxMsgImportance = MessageImportance.High;
+
                                break;
                        case LoggerVerbosity.Normal:
-                               eventSource.MessageRaised += EventSource_MessageRaised_Normal;
+                               maxMsgImportance = MessageImportance.Normal;
+
                                eventSource.ProjectStarted += EventSource_ProjectStarted;
                                eventSource.ProjectFinished += EventSource_ProjectFinished;
                                break;
                        case LoggerVerbosity.Detailed:
-                               eventSource.MessageRaised += EventSource_MessageRaised_All;
+                               maxMsgImportance = MessageImportance.Normal;
+
                                eventSource.ProjectStarted += EventSource_ProjectStarted;
                                eventSource.ProjectFinished += EventSource_ProjectFinished;
                                eventSource.TargetStarted += EventSource_TargetStarted;
@@ -67,7 +72,8 @@ namespace CERoslynPlugin
                                eventSource.TaskFinished += EventSource_TaskFinished;
                                break;
                        case LoggerVerbosity.Diagnostic:
-                               eventSource.MessageRaised += EventSource_MessageRaised_All;
+                               maxMsgImportance = MessageImportance.Low;
+
                                eventSource.AnyEventRaised += EventSource_AnyEventRaised;
                                break;
                        }
@@ -78,18 +84,14 @@ namespace CERoslynPlugin
                        eventSource.ErrorRaised -= EventSource_ErrorRaised;
                        eventSource.BuildStarted -= EventSource_Progress_BuildStarted;
                        eventSource.BuildFinished -= EventSource_Progress_BuildFinished;
+                       eventSource.MessageRaised -= EventSource_MessageRaised;
 
                        switch (Verbosity) {
-                       case LoggerVerbosity.Minimal:
-                               eventSource.MessageRaised -= EventSource_MessageRaised_Minimal;
-                               break;
                        case LoggerVerbosity.Normal:
-                               eventSource.MessageRaised -= EventSource_MessageRaised_Normal;
                                eventSource.ProjectStarted -= EventSource_ProjectStarted;
                                eventSource.ProjectFinished -= EventSource_ProjectFinished;
                                break;
                        case LoggerVerbosity.Detailed:
-                               eventSource.MessageRaised -= EventSource_MessageRaised_All;
                                eventSource.ProjectStarted -= EventSource_ProjectStarted;
                                eventSource.ProjectFinished -= EventSource_ProjectFinished;
                                eventSource.TargetStarted -= EventSource_TargetStarted;
@@ -98,11 +100,9 @@ namespace CERoslynPlugin
                                eventSource.TaskFinished -= EventSource_TaskFinished;
                                break;
                        case LoggerVerbosity.Diagnostic:
-                               //eventSource.MessageRaised -= EventSource_MessageRaised_All;
                                eventSource.AnyEventRaised -= EventSource_AnyEventRaised;
                                break;
                        }
-
                }
                void log (LogType type, string message) {
                        string[] lines = Regex.Split (message, "\r\n|\r|\n");//|\r|\n|\\\\n");
@@ -116,8 +116,7 @@ namespace CERoslynPlugin
                }
                void EventSource_Progress_BuildFinished (object sender, BuildFinishedEventArgs e)
                {
-                       log (LogType.High, "Build Finished.");
-                       //ide.CurrentSolution.RaiseDiagnosticsValueChanged();
+                       log (LogType.High, e.Succeeded ? "Build Succeed." : "Build Failed.");
                }
 
                private void EventSource_TaskFinished (object sender, TaskFinishedEventArgs e) {
@@ -136,51 +135,39 @@ namespace CERoslynPlugin
                        log (LogType.Custom2, e.Message);
                }
                private void EventSource_MessageRaised (object sender, BuildMessageEventArgs e) {
-                       log (LogType.Normal, e.Message);
+                       if (e.Importance > maxMsgImportance)
+                               return;
+                       if (e.Importance == MessageImportance.High)
+                               log (LogType.High, e.Message);
+                       else if (e.Importance == MessageImportance.Normal)
+                               log (LogType.Normal, e.Message);
+                       else
+                               log (LogType.Low, e.Message);
                }
                private void EventSource_AnyEventRaised (object sender, BuildEventArgs e) {
                        if (e is BuildErrorEventArgs ||
                                        e is BuildWarningEventArgs ||
                                        e is BuildStartedEventArgs ||
+                                       e is BuildMessageEventArgs ||
                                        e is BuildFinishedEventArgs)
                                return;
                        else if (e is TargetFinishedEventArgs || e is TargetStartedEventArgs)
                                log (LogType.Custom2, e.Message);
                        else if (e is TaskStartedEventArgs || e is TaskFinishedEventArgs)
                                log (LogType.Custom1, e.Message);
-                       else if (e is BuildMessageEventArgs bmea)
-                               EventSource_MessageRaised_All (sender, bmea);
                        else if (e is BuildStatusEventArgs)
                                log (LogType.High, e.Message);
                        else
                                log (LogType.Custom3, e.Message);
                }
 
-               private void EventSource_MessageRaised_Minimal (object sender, BuildMessageEventArgs e) {
-                       if (e.Importance == MessageImportance.High)
-                               log (LogType.High, e.Message);
-               }
-               private void EventSource_MessageRaised_Normal (object sender, BuildMessageEventArgs e) {
-                       if (e.Importance == MessageImportance.Normal)
-                               log (LogType.Normal, e.Message);
-                       else if(e.Importance == MessageImportance.High)
-                               log (LogType.High, e.Message);
-               }
-               private void EventSource_MessageRaised_All (object sender, BuildMessageEventArgs e) {
-                       if (e.Importance == MessageImportance.Low)
-                               log (LogType.Low, e.Message);
-                       else if(e.Importance == MessageImportance.Normal)
-                               log (LogType.Normal, e.Message);
-                       else if(e.Importance == MessageImportance.High)
-                               log (LogType.High, e.Message);
-               }
                void EventSource_ProjectStarted (object sender, ProjectStartedEventArgs e)
                {
-                       log (LogType.High, e.Message);
+                       log (LogType.Custom3, e.Message);
                }
                void EventSource_ProjectFinished (object sender, ProjectFinishedEventArgs e)
                {
-                       log (LogType.High, e.Message);
+                       log (LogType.Custom3, e.Message);
                }
                void EventSource_ErrorRaised (object sender, BuildErrorEventArgs e)
                {
index 9d8e88f021d3dcfe15da2f6cd0a708bf5269b0d0..d0ef458cef30e122071957b0f156bd8ef595ef0c 100644 (file)
@@ -41,18 +41,18 @@ namespace CERoslynPlugin
                }
 
                private void EventSource_TaskFinished (object sender, TaskFinishedEventArgs e) {
-                       Console.WriteLine ($"Task <- {sender} {e}");
+                       Console.WriteLine ($"Task <- {sender} {e.TaskName}");
                }
 
                private void EventSource_TaskStarted (object sender, TaskStartedEventArgs e) {
                        Console.WriteLine ($"Task -> {sender} {e}");
                }
                private void EventSource_TargetFinished (object sender, TargetFinishedEventArgs e) {
-                       
+
                }
 
                private void EventSource_TargetStarted (object sender, TargetStartedEventArgs e) {
-                       
+
                }
 
                public void Shutdown ()
index 7dd6e96ff13fdc708be764a378f0d59faac08ccd..1f6afc81ce5c592b0c3c62490822990e0f44e0da 100644 (file)
@@ -26,15 +26,15 @@ namespace CERoslynPlugin
                public static void SetTokenType (this Token tok, CSTokenType type) => tok.Type = (TokenType)type;
        }*/
        public class CSDocument : TextDocument {
-               
+
                static CSDocument () {
                        App.GetService<RoslynService> ()?.Start ();
                }
 
                CSharpSyntaxTree tree;
-               public CSDocument (string fullPath)     : base (fullPath) {
+               public CSDocument (string fullPath, string editorPath)  : base (fullPath, editorPath) {
 
-                       //tree = (CSharpSyntaxTree)CSharpSyntaxTree.ParseText (Source, CSharpParseOptions.Default);                     
+                       //tree = (CSharpSyntaxTree)CSharpSyntaxTree.ParseText (Source, CSharpParseOptions.Default);
                }
 
                #region SourceDocument abstract class implementation
@@ -52,12 +52,12 @@ namespace CERoslynPlugin
                }*/
                #endregion
 
-               
+
 
                /*ProjectCollection tree;
                public CSDocument (string fullPath)     : base (fullPath) {
-                       tree = (CSharpSyntaxTree)CSharpSyntaxTree.ParseText (Source, CSharpParseOptions.Default);                       
+                       tree = (CSharpSyntaxTree)CSharpSyntaxTree.ParseText (Source, CSharpParseOptions.Default);
                }*/
-               
-       }       
+
+       }
 }
\ No newline at end of file
index b882c5c7b52fdee2fec18112559542342a0a3c89..1369a2bf9a3e3e07ae850962c9dabfae1d2a61be 100644 (file)
@@ -96,6 +96,9 @@ namespace CERoslynPlugin
                                        if (constants != null)
                                                parseOptions = parseOptions.WithPreprocessorSymbols (constants.EvaluatedValue.Split (';'));
 
+                                       /*ProjectProperty targetPath = project.GetProperty ("TargetPath");
+                                       printEvaluatedProperties(project.CreateProjectInstance());*/
+
                                        populateTreeNodes ();
                                }
 
@@ -111,34 +114,48 @@ namespace CERoslynPlugin
                                Console.WriteLine (ex);
                        }
                }
+               void printEvaluatedProperties (ProjectInstance pi) {
+                       Console.ForegroundColor = ConsoleColor.Green;
+                       Console.WriteLine ($"Evaluated Globals properties for {Name}");
+                       foreach (ProjectPropertyInstance item in pi.Properties.OrderBy (p => p.Name)) {
+                               Console.ForegroundColor = ConsoleColor.White;
+                               Console.Write ($"\t{item.Name,-40} = ");
+                               Console.ForegroundColor = ConsoleColor.Gray;
+                               Console.WriteLine ($"{item.EvaluatedValue}");
+
+                       }
+                       ICollection<ProjectItemInstance> pii = pi.GetItems ("InnerOutput");
+                       ProjectRootElement pre = pi.ToProjectRootElement();
+                       pre.FullPath = "/home/jp/test.csproj";
+                       pre.Save();
+
+               }
                public override void Unload () {
                        CMDSBuild.ToggleAllCommand (false);
                        if (commands.Contains (CMDSetAsStartupProject))
                                commands.Remove (CMDSetAsStartupProject);
+                       if (IsLoaded) {
+                               solutionProject.projectCollection.UnloadProject (project);
+                               project = null;
+                               this.Childs.Clear();
+                       }
                        IsLoaded = false;
                }
                public void Build () => Build ("Build");
                public void Build (params string[] targets)
                {
+                       BuildManager.DefaultBuildManager.ResetCaches ();
                        //using (var ctx = System.Runtime.Loader.AssemblyLoadContext.GetLoadContext (this.GetType().Assembly).EnterContextualReflection()) {
                                ProjectInstance pi = BuildManager.DefaultBuildManager.GetProjectInstanceForBuild (project);
-                               BuildRequestData request = new BuildRequestData (pi, targets,null,BuildRequestDataFlags.ProvideProjectStateAfterBuild);
+                               BuildRequestData request = new BuildRequestData (pi, targets, null,
+                                       BuildRequestDataFlags.ProvideProjectStateAfterBuild);
+
                                BuildResult result = BuildManager.DefaultBuildManager.Build (solutionProject.buildParams, request);
-                       //}
-               }
 
-               TreeNode rootNode;
-               public TreeNode RootNode {
-                       get => rootNode;
-                       set {
-                               if (rootNode == value)
-                                       return;
-                               rootNode = value;
-                               NotifyValueChanged (rootNode);
-                               NotifyValueChanged ("Children", Children);
-                       }
+                               printEvaluatedProperties (result.ProjectStateAfterBuild);
+
+                       //}
                }
-               public IList<TreeNode> Children => rootNode?.Childs;
                public override string Icon {
                        get {
                                switch (Path.GetExtension (FullPath)) {
@@ -152,7 +169,7 @@ namespace CERoslynPlugin
 
                public bool IsCrowProject {
                        get {
-                               foreach (ProjectItemNode reference in rootNode.Childs[0].Flatten.OfType<ProjectItemNode>()) {
+                               foreach (ProjectItemNode reference in Childs[0].Flatten.OfType<ProjectItemNode>()) {
                                        switch (reference.NodeType)     {
                                                case NodeType.PackageReference:
                                                        if (reference.Caption == "Crow")
@@ -169,15 +186,14 @@ namespace CERoslynPlugin
                }
                public bool IsStartupProject => solutionProject.StartupProject == this;
                public override bool ContainsFile (string fullPath) =>
-                       rootNode.Flatten.OfType<ProjectItemNode> ().Any (f => f.FullPath == fullPath);
+                       Flatten.OfType<ProjectItemNode> ().Any (f => f.FullPath == fullPath);
 
                void populateTreeNodes ()
                {
-                       TreeNode root = new ProjectNode (this);
+                       TreeNode root = this;
                        VirtualNode refs = new VirtualNode ("References", NodeType.ReferenceGroup);
                        root.AddChild (refs);
 
-
                        foreach (ProjectItem pn in project.AllEvaluatedItems) {
                                //IDE.ProgressNotify (1);
 
@@ -247,7 +263,6 @@ namespace CERoslynPlugin
                                }
                        }
                        root.SortChilds ();
-                       RootNode = root;
 
                        /*foreach (var item in root.Childs) {
                                Childs.Add (item);
@@ -292,9 +307,8 @@ namespace CERoslynPlugin
                public bool DebugSymbols => bool.Parse (project.GetProperty ("DebugSymbols").EvaluatedValue);
                public int WarningLevel => int.Parse (project.GetProperty ("WarningLevel").EvaluatedValue);
 
-
                public Stream GetStreamFromTargetPath (string targetPath) {
-                       IEnumerable<ProjectItemNode> piNodes = RootNode.Flatten.OfType<CERoslynPlugin.ProjectItemNode>();
+                       IEnumerable<ProjectItemNode> piNodes = Flatten.OfType<CERoslynPlugin.ProjectItemNode>();
                        if (targetPath.StartsWith ('#')) {
                                targetPath = targetPath.Substring (1);
                                ProjectItemNode pin = piNodes.FirstOrDefault (n =>
index f183fd782be09de5451f3df73f89240600c2c868..959bdf5f2c3276e4a10019bf281f7c57de058887 100644 (file)
@@ -40,9 +40,18 @@ namespace CERoslynPlugin
                public string EvaluatedInclude => projectItem.EvaluatedInclude;
                public string FullPath =>
                        NodeType == NodeType.EmbeddedResource || NodeType == NodeType.None || NodeType == NodeType.Compile ?
-                               Path.Combine (GetRoot<ProjectNode>().Project.RootDir, projectItem.EvaluatedInclude) : null;
-
-
+                               Path.Combine (GetFirstAncestorOfType<MSBuildProject>().RootDir, projectItem.EvaluatedInclude) : null;
+
+               public override bool IsSelected {
+                       get => base.IsSelected;
+                       set {
+                               if (isSelected == value)
+                                       return;
+                               base.IsSelected = value;
+                               if (isSelected && App.TryGetOpenedDocument (FullPath, out Document doc))
+                                       doc.IsSelected = true;
+                       }
+               }
 
 
 
diff --git a/plugins/CERoslynPlugin/src/ProjectTree/ProjectNode.cs b/plugins/CERoslynPlugin/src/ProjectTree/ProjectNode.cs
deleted file mode 100644 (file)
index 3c1ebdf..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright (c) 2020  Jean-Philippe Bruyère <jp_bruyere@hotmail.com>
-//
-// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using Crow;
-using CrowEditBase;
-
-namespace CERoslynPlugin
-{
-       public class ProjectNode : TreeNode
-       {
-               public MSBuildProject Project { get; private set;}
-               public ProjectNode (MSBuildProject project)     {
-                       Project = project;
-               }
-
-               public override string Caption => Project.Name;
-               public override string Icon => "#icons.question.svg";
-               public override NodeType NodeType => NodeType.VirtualGroup;
-       }
-
-}
index 374af5844a79541e1ba407de79f8849eeab5194d..ef3f07f722c9ef83e61f5862fa4703f5a4a09b64 100644 (file)
@@ -61,10 +61,12 @@ namespace CERoslynPlugin
                                NotifyValueChanged (value);
                        }*/
                }
+               public override bool ContainsFile (string fullPath) =>
+                               FlattenSubProjetcs.Any (f => f.ContainsFile (fullPath));
                public override string Name => Path.GetFileNameWithoutExtension (FullPath);
                public override string Icon => "#icons.file_type_sln2.svg";
                public Project StartupProject {
-                       get => Flatten.FirstOrDefault (p => p.FullPath == UserConfig.Get<string> ("StartupProject"));
+                       get => FlattenSubProjetcs.FirstOrDefault (p => p.FullPath == UserConfig.Get<string> ("StartupProject"));
                        set {
                                if (value == StartupProject)
                                        return;
@@ -80,6 +82,9 @@ namespace CERoslynPlugin
                                NotifyValueChanged ("StartupProject", StartupProject);
                        }
                }
+
+               public override NodeType NodeType => NodeType.ProjectGroup;
+
                public override void Load () {
                        Dictionary<string,string> globalProperties = new Dictionary<string, string>();
                        globalProperties.Add ("Configuration", "Debug");
@@ -114,7 +119,8 @@ namespace CERoslynPlugin
                                Loggers = projectCollection.Loggers,
                                LogInitialPropertiesAndItems = true,
                                LogTaskInputs = true,
-                               UseSynchronousLogging = true
+                               UseSynchronousLogging = true,
+                               ResetCaches = true
                        };
 
                        //projectCollection.IsBuildEnabled = false;
@@ -130,8 +136,7 @@ namespace CERoslynPlugin
                        //ide.projectCollection.to
                        //------------
 
-                       subProjects = new List<Project> ();
-                       IList<Project> targetChildren = subProjects;
+                       TreeNode targetNode = this;
                        foreach (ProjectInSolution pis in solutionFile.ProjectsInOrder) {
                                /*if (!string.IsNullOrEmpty (pis.ParentProjectGuid))
                                        targetChildren = allSolutionNodes.FirstOrDefault (sn => sn.ProjectGuid == pis.ParentProjectGuid).Childs;
@@ -140,7 +145,7 @@ namespace CERoslynPlugin
 
                                switch (pis.ProjectType) {
                                case SolutionProjectType.KnownToBeMSBuildFormat:
-                                       targetChildren.Add (new MSBuildProject (this, pis));
+                                       targetNode.AddChild (new MSBuildProject (this, pis));
                                        break;
                                /*case SolutionProjectType.SolutionFolder:
                                        targetChildren.Add (new SolutionFolder (this, pis));
index 17d1fc213892901b86fbbdc6e697e54885ee6bde..46cd43892160d48c25be259cede723b60e90c7c0 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0"?>
-<Expandable Caption="{Caption}" IsExpanded="{²IsExpanded}" BubbleMouseEvent="MouseWheel" ContextCommands="{Commands}">
+<Expandable Caption="{Caption}" IsExpanded="{²IsExpanded}" BubbleEvents="MouseWheel" ContextCommands="{Commands}">
        <HorizontalStack Height="Fit">
                <Shape Foreground="DimGrey" Background="Transparent"
                        Path="M 5.5,0 L 5.5,11 G" Size="11,11" Width="11" Height="Stretched" KeepProportions="false" Margin="0"/>
index 7e717966456c3b9d5e0f4b0014bbe08f8d2fac65..bc1a0c0bdda126274395616ed554f97d8f1a6f35 100644 (file)
@@ -26,7 +26,7 @@ namespace CrowEdit.Xml
        }
        public class XmlDocument : SourceDocument {
 
-               public XmlDocument (string fullPath) : base (fullPath) {
+               public XmlDocument (string fullPath, string editorPath) : base (fullPath, editorPath) {
 
                }
                protected override Tokenizer CreateTokenizer() => new XmlTokenizer ();
index 483f6ec640b96d82cf718bb7886aeb1db506b65f..3d2bd9a6a39cf8e8784c122174fc5169437e00b2 100644 (file)
@@ -2,9 +2,9 @@
        <PropertyGroup>
                <SolutionDir>$(MSBuildThisFileDirectory)..\</SolutionDir>
                <License>MIT</License>
-               <Authors>Jean-Philippe Bruyère</Authors>           
+               <Authors>Jean-Philippe Bruyère</Authors>
                <LangVersion>7.2</LangVersion>
-               
+
        </PropertyGroup>
 
        <ItemGroup>
index 74e03eb7a70c1bb9e4fdc81c17b1a3ddcd3aa1e8..0690e539123656e0cfd45573ac723f8705605e27 100644 (file)
@@ -51,6 +51,15 @@ namespace CrowEdit
 #endif
                static void Main ()
                {
+                       /*DbgLogger.IncludedEvents.AddRange ( new DbgEvtType[] {
+                               DbgEvtType.MouseEnter,
+                               DbgEvtType.MouseLeave,
+                               DbgEvtType.WidgetMouseDown,
+                               DbgEvtType.WidgetMouseUp,
+                               DbgEvtType.WidgetMouseClick,
+                               DbgEvtType.HoverWidget
+                       });*/
+
                        CrowEdit.CrowAssemblyNames = new string[] {"CrowEditBase"};
                        using (CrowEdit app = new CrowEdit ())
                                app.Run ();
@@ -167,15 +176,17 @@ namespace CrowEdit
 
                }
 
-               protected override Document openOrCreateFile (string filePath) {
+               protected override Document openOrCreateFile (string filePath, string editorPath = null) {
                        Document doc = null;
                        CurrentFilePath = filePath;
 
                        string ext = Path.GetExtension (CurrentFilePath);
                        if (TryGetDefaultTypeForExtension (ext, out Type clientType)) {
-                               if (typeof(Document).IsAssignableFrom (clientType))
-                                       doc = (Document)Activator.CreateInstance (clientType, new object[] {CurrentFilePath});
-                               else if (typeof(Service).IsAssignableFrom (clientType))
+                               if (typeof(Document).IsAssignableFrom (clientType)) {
+                                       if (editorPath == null)
+                                               TryGetDefaultEditorForDocumentType (clientType, out editorPath);
+                                       doc = (Document)Activator.CreateInstance (clientType, new object[] {CurrentFilePath, editorPath});
+                               }else if (typeof(Service).IsAssignableFrom (clientType))
                                        doc = GetService (clientType)?.OpenDocument (CurrentFilePath);
                                else if (typeof(Project).IsAssignableFrom (clientType)) {
                                        Project prj = (Project)Activator.CreateInstance (clientType, new object[] {CurrentFilePath});
index a3fbdc0a20916ba43f103c0ddf97a07f75245e4a..bd16c817dd136348bbec766a7cca54a4b97f1f16 100644 (file)
@@ -1,16 +1,37 @@
 <?xml version="1.0"?>
 <DockWindow Caption="Editor"  Width="60%">
-       <TabView Data="{OpenedDocuments}" SelectedItem="{²CurrentDocument}"    DataTest="Extension">
+       <TabView ItemTemplate="{EditorItemTemplates}"
+                       Data="{OpenedDocuments}" SelectedItem="{²CurrentDocument}"     DataTest="EditorPath">
                <Template>
                        <VerticalStack Spacing="0" >
-                               <ListBox Data="{./Items}" Fit="true" HorizontalAlignment="Left" VerticalAlignment="Top">
+                               <ListBox Data="{./Items}" Height="Fit" >
                                        <Template>
-                                               <HorizontalStack Name="ItemsContainer" />
+                                               <VerticalStack Spacing="0" >
+                                                       <ScrollBar Orientation="Horizontal" Foreground="RoyalBlue" Height="6" Width="Stretched" CornerRadius="3"
+                                                               Value="{²../ItemsScroller.ScrollX}"
+                                                               LargeIncrement="{../ItemsScroller.PageWidth}" SmallIncrement="1"
+                                                               CursorRatio="{../ItemsScroller.ChildWidthRatio}" Maximum="{../ItemsScroller.MaxScrollX}">
+                                                               <Template>
+                                                                       <Container Margin="1" Background="{./Background}">
+                                                                               <Widget Name="Cursor" Background="{./Foreground}" CornerRadius="{./CornerRadius}"/>
+                                                                       </Container>
+                                                               </Template>
+                                                       </ScrollBar>
+                                                       <Scroller Name="ItemsScroller" Height="Fit" Width="Stretched">
+                                                               <HorizontalStack Name="ItemsContainer" Width="Fit" HorizontalAlignment="Left"/>
+                                                       </Scroller>
+                                               </VerticalStack>
                                        </Template>
                                        <ItemTemplate>
+                                               <!--<ListItem Fit="true" Background="${InactiveTabItem}" IsSelected="{IsVisible}" Margin="5"
+                                                               Selected="{.DataSource.Visible='true'};{Background=.DataSource.Background}"
+                                                               Unselected="{.DataSource.Visible='false'};{Background=${InactiveTabItem}}">
+                                                       <Label Text="{Name}" Width="200" />
+                                               </ListItem>-->
                                                <ListItem RootDataLevel="true" Fit="true" Background="${InactiveTabBackground}" Foreground="${InactiveTabForeground}" IsSelected="{IsVisible}"
                                                                Selected="{.DataSource.IsVisible='true'};{Background=${SelectedTabBackground}};{Foreground=${SelectedTabForeground}}"
-                                                               Unselected="{.DataSource.IsVisible='false'};{Background=${InactiveTabBackground}};{Foreground=${InactiveTabForeground}}">
+                                                               Unselected="{.DataSource.IsVisible='false'};{Background=${InactiveTabBackground}};{Foreground=${InactiveTabForeground}}"
+                                                               BubbleEvents="MouseWheel">
                                                        <HorizontalStack DataSource="{DataSource}" Margin="3" Spacing="5">
 
                                                                <Widget Width="10" Height="10" Background="RoyalBlue" IsVisible="{IsDirty}"/>
                                <Group Name="ItemsContainer" />
                        </VerticalStack>
                </Template>
-               <ItemTemplate>
-                       <ListItem IsVisible="{IsSelected}" IsSelected="{²IsSelected}" Selected="{/tb.HasFocus='true'}">
-                               <VerticalStack Spacing="0">
-                                       <HorizontalStack Spacing="0">
-                                               <Editor Name="tb" Font="consolas, 12" Focusable="true" Height="Stretched" Width="Stretched"
-                                                               Document="{}" TextChanged="onTextChanged"/>
-                                               <ScrollBar Value="{²../tb.ScrollY}"
-                                                               LargeIncrement="{../tb.PageHeight}" SmallIncrement="1"
-                                                               CursorRatio="{../tb.ChildHeightRatio}" Maximum="{../tb.MaxScrollY}" />
-                                       </HorizontalStack>
-                                       <ScrollBar Style="HScrollBar" Value="{²../tb.ScrollX}"
-                                                       LargeIncrement="{../tb.PageWidth}" SmallIncrement="1"
-                                                       CursorRatio="{../tb.ChildWidthRatio}" Maximum="{../tb.MaxScrollX}" />
-                                       <HorizontalStack Height="Fit">
-                                               <Widget Width="Stretched"/>
-                                               <Widget Height="5" Width="10"/>
-                                               <Label Text="Line:" Foreground="Grey"/>
-                                               <Label Text="{../../tb.CurrentLine}" Margin="3"/>
-                                               <Label Text="col:" Foreground="Grey"/>
-                                               <Label Text="{../../tb.CurrentColumn}" Margin="3"/>
-                                       </HorizontalStack>
-                               </VerticalStack>
-                       </ListItem>
-               </ItemTemplate>
-               <ItemTemplate Path="#ui.sourceEditor.itmp" DataType=".crow"/>
-               <ItemTemplate Path="#ui.sourceEditor.itmp" DataType=".style"/>
        </TabView>
 </DockWindow>
 
index cfe7fddd3d99ee3d6c7c9f3947d29d8388f7ac1f..18813f7b0e0bc1f92cebb8b0a8b648452142a82e 100644 (file)
@@ -26,7 +26,7 @@
                                                <ListItem ContextCommands="{GetCommands}"
                                                                Selected="{/exp.Background=${ControlHighlight}}"
                                                                Unselected="{/exp.Background=Transparent}">
-                                                       <Expandable Name="exp" Caption="{Name}" MouseDoubleClick="/onClickForExpand" BubbleMouseEvent="All">
+                                                       <Expandable Name="exp" Caption="{Name}" MouseDoubleClick="/onClickForExpand" BubbleEvents="All">
                                                                <Template>
                                                                        <VerticalStack>
                                                                                <Border CornerRadius="2" Margin="0" Height="Fit" MouseDoubleClick="./onClickForExpand"
index 7e235cb7cefd57baf3871d30b80d46d0eabfecbb..b646c6ec027125561576c0f39316e0af65eea96b 100644 (file)
        <TreeView Name="treeview" IsRoot="true" RootDataLevel="true" Data="{Projects}" Background="Onyx"
                                SelectedItemChanged="tv_projects_SelectedItemChanged" >
                <ItemTemplate DataType="default" >
-                       <ListItem CornerRadius="2" Margin="1" Height="Fit" Width="Stretched"
-                                       BubbleMouseEvent="MouseWheel" ContextCommands="{Commands}"
+                       <ListItem Margin="0" IsSelected="{²IsSelected}" Width="Stretched" ContextCommands="{Commands}"
+                                       BubbleEvents="MouseWheel"
                                        MouseDoubleClick="onDblClick"
-                                       IsSelected="{²IsSelected}"
-                                       Selected="{Background=RoyalBlue}"
-                                       Unselected="{Background=Transparent}" >
-                               <HorizontalStack Spacing="5">
-                                       <Image Style="TreeIcon" Path="{Icon}" SvgSub="{IconSub}"/>
-                                       <Label Text="{Caption}" Width="Stretched"/>
-                               </HorizontalStack>
+                                       Selected="{/border.Background=${ControlHighlight}}"
+                                       Unselected="{/border.Background=${TreeItemBackground}}"
+                                       MouseEnter="{/border.Foreground=${TreeItemBorderHighlightFG}}"
+                                       MouseLeave="{/border.Foreground=${TreeItemBorderFG}}">
+                               <Border Name="border" Margin="2" CornerRadius="${TreeItemBorderCornerRadius}"
+                                                                                                       Foreground="${TreeItemBorderFG}">
+                                       <HorizontalStack Spacing="5">
+                                               <Image Style="TreeIcon" Path="{Icon}" SvgSub="{IconSub}"/>
+                                               <Label Text="{Caption}" Width="Stretched"/>
+                                       </HorizontalStack>
+                               </Border>
                        </ListItem>
 
                </ItemTemplate>
 
-               <ItemTemplate DataType="CERoslynPlugin.MSBuildProject" Data="Children" Path="#CERoslynPlugin.ui.MSBuildProjectNode.template" />
+               <!--<ItemTemplate DataType="CERoslynPlugin.MSBuildProject" Data="Childs" Path="#CERoslynPlugin.ui.MSBuildProjectNode.template" />-->
                <ItemTemplate DataType="CrowEditBase.VirtualNode" Data="Childs" Path="#ui.TreeExpandable.template" />
 
-               <ItemTemplate DataType="CrowEditBase.Project" Data="SubProjects" Path="#ui.TreeExpandable.template" />
+               <ItemTemplate DataType="CrowEditBase.Project" Data="Childs" Path="#ui.TreeExpandable.template" />
                <!--<ItemTemplate DataType="CrowEditBase.TreeNode" DataTest="NodeType" Data="Childs" Path="#ui.TreeExpandable.template" />-->
        </TreeView>
 </DockWindow>