</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>
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;
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;
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) {
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;
//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;
}
}
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;
if (currentDocument == value)
return;
- currentDocument?.UnselectDocument ();
+ if (currentDocument != null)
+ currentDocument.IsSelected = false;
currentDocument = value;
NotifyValueChanged (currentDocument);
if (currentDocument == null)
return;
- currentDocument.SelectDocument ();
+ currentDocument.IsSelected = true;
FileCommands[2] = currentDocument.CMDSave;
FileCommands[3] = currentDocument.CMDSaveAs;
EditCommands[0] = currentDocument.CMDUndo;
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))
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;
}
}
+
+ #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
#endregion
#region ISelectable implementation
- bool isSelected;
+ protected bool isSelected;
public event EventHandler Selected;
public event EventHandler Unselected;
return;
isSelected = value;
-
NotifyValueChanged (isSelected);
}
}
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 ();
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
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;
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);
}
} else
IFace.forceTextCursor = true;
- }
+ //}
if (!string.IsNullOrEmpty (_text)) {
Foreground?.SetAsSource (IFace, gr);
Foreground.SetAsSource (IFace, gr);
********** DEBUG TextLineCollection *************/
- if (HasFocus && selectionNotEmpty) {
+ if (selectionNotEmpty) {
RectangleD selRect = lineRect;
if (i >= selStart.Line && i <= selEnd.Line) {
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);
}
}
- protected void checkShift () {
- if (IFace.Shift) {
+ protected void checkShift (KeyEventArgs e) {
+ if (e.Modifiers.HasFlag (Modifier.Shift)) {
if (!selectionStart.HasValue)
selectionStart = CurrentLoc;
} else
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)
{
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 ();
}
}
}
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:
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;
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++;
return cursor;
}
- void updateMaxScrolls (LayoutingType layout) {
+ protected virtual void updateMaxScrolls (LayoutingType layout) {
Rectangle cb = ClientRectangle;
if (layout == LayoutingType.Width) {
MaxScrollX = cachedTextSize.Width - cb.Width;
{
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) {
namespace CrowEditBase
{
-
+
/*public class Plugin {
string path;
Assembly assembly;
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;
}
//
// 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 {
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 () {
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
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;
//Console.WriteLine ($"{pos}: {suggestionTok.AsString (_text)} {suggestionTok}");
}
-
-
protected void tryGetSuggestions () {
if (currentLoc.HasValue && Document is SourceDocument srcDoc)
Suggestions = srcDoc.GetSuggestions (lines.GetAbsolutePosition (CurrentLoc.Value));
hideOverlay ();
base.onMouseDown (sender, e);
}
-
public override void onKeyDown(object sender, KeyEventArgs e)
{
TextSpan selection = Selection;
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;
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;
} 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;
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) {
}
}
+ //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++;
}
//gr.Translate (ScrollX, ScrollY);
} finally {
- xmlDoc.ExitReadLock ();
+ doc.ExitReadLock ();
}
}
namespace CrowEditBase
{
public class TextDocument : Document {
- public TextDocument (string fullPath)
- : base (fullPath) {
+ public TextDocument (string fullPath, string editorPath = "default")
+ : base (fullPath, editorPath) {
reloadFromFile ();
}
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;
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;
}
}
}
- }*/
+ }
public virtual bool IsExpanded {
- get { return isExpanded; }
+ get => isExpanded;
set {
if (value == isExpanded)
return;
}
}
public bool HasChildren => children?.Count > 0;
- public abstract string Icon { get; }
- public virtual string IconSub => null;
+
public IEnumerable<TreeNode> Flatten {
get {
yield return node;
}
}
-
public virtual void SortChilds ()
{
foreach (TreeNode pn in Childs)
public override CommandGroup Commands {
get {
- return null;
+ return null;
}
}
}
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 {
<?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"/>
</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>
<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>
-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
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;
}
{
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)
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) {
--- /dev/null
+// 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
+++ /dev/null
-// 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
<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"
<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"
<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>
{
IEventSource eventSource;
LoggerVerbosity verbosity;
+ MessageImportance maxMsgImportance;
public LoggerVerbosity Verbosity {
get => verbosity;
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;
eventSource.TaskFinished += EventSource_TaskFinished;
break;
case LoggerVerbosity.Diagnostic:
- eventSource.MessageRaised += EventSource_MessageRaised_All;
+ maxMsgImportance = MessageImportance.Low;
+
eventSource.AnyEventRaised += EventSource_AnyEventRaised;
break;
}
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;
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");
}
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) {
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)
{
}
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 ()
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
}*/
#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
if (constants != null)
parseOptions = parseOptions.WithPreprocessorSymbols (constants.EvaluatedValue.Split (';'));
+ /*ProjectProperty targetPath = project.GetProperty ("TargetPath");
+ printEvaluatedProperties(project.CreateProjectInstance());*/
+
populateTreeNodes ();
}
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)) {
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")
}
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);
}
}
root.SortChilds ();
- RootNode = root;
/*foreach (var item in root.Childs) {
Childs.Add (item);
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 =>
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;
+ }
+ }
+++ /dev/null
-// 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;
- }
-
-}
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;
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");
Loggers = projectCollection.Loggers,
LogInitialPropertiesAndItems = true,
LogTaskInputs = true,
- UseSynchronousLogging = true
+ UseSynchronousLogging = true,
+ ResetCaches = true
};
//projectCollection.IsBuildEnabled = false;
//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;
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));
<?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"/>
}
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 ();
<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>
#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 ();
}
- 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});
<?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>
<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"
<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>