<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
- <TargetFramework>netcoreapp5</TargetFramework>
+ <TargetFramework>netcoreapp3.1</TargetFramework>
<OutputType>WinExe</OutputType>
<EnableDefaultItems>false</EnableDefaultItems>
</PropertyGroup>
</ItemGroup>
<ItemGroup>
<!--<ProjectReference Include="Crow.Coding\Crow.Coding.csproj" />-->
+ <!--<PackageReference Include="Crow" Version="0.9.6-beta" />
+ <ProjectReference Include="/mnt/devel/crow/Crow/Crow.csproj" />-->
<ProjectReference Include="CrowEditBase\CrowEditBase.csproj" />
- <ProjectReference Include="plugins\CECrowDebugLog\CECrowDebugLog.csproj" >
+
+ <ProjectReference Include="plugins\CECrowPlugin\CECrowPlugin.csproj" >
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
</ProjectReference>
<ProjectReference Include="plugins\CEXmlPlugin\CEXmlPlugin.csproj" >
<ProjectReference Include="plugins\CENetcoreDbgPlugin\CENetcoreDbgPlugin.csproj" >
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
</ProjectReference>
- <ProjectReference Include="..\CrowIDE\Crow\Crow\Crow.csproj" />
-
- <!--<PackageReference Include="Crow" Version="0.9.6-beta" />-->
</ItemGroup>
-</Project>
\ No newline at end of file
+</Project>
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Plugins", "Plugins", "{386C459C-4849-40C3-9D5A-4A8802A5A848}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CECrowDebugLog", "plugins\CECrowDebugLog\CECrowDebugLog.csproj", "{1095C2F1-802F-4DE1-8035-EE0AAC4A5E35}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CECrowPlugin", "plugins\CECrowPlugin\CECrowPlugin.csproj", "{1095C2F1-802F-4DE1-8035-EE0AAC4A5E35}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CENetcoreDbgPlugin", "plugins\CENetcoreDbgPlugin\CENetcoreDbgPlugin.csproj", "{14E49365-6E22-4A27-B0E5-C6BBB347A85C}"
EndProject
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CEXmlPlugin", "plugins\CEXmlPlugin\CEXmlPlugin.csproj", "{196D847E-D051-429B-892F-C405F036B8C2}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Crow", "..\CrowIDE\Crow\Crow\Crow.csproj", "{D0487872-E5A5-424A-AB18-3B2F258D51D5}"
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Crow", "..\crow\Crow\Crow.csproj", "{5D8999F6-80D8-44CA-93F2-E18C9E44640C}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
{196D847E-D051-429B-892F-C405F036B8C2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{196D847E-D051-429B-892F-C405F036B8C2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{196D847E-D051-429B-892F-C405F036B8C2}.Release|Any CPU.Build.0 = Release|Any CPU
- {D0487872-E5A5-424A-AB18-3B2F258D51D5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {D0487872-E5A5-424A-AB18-3B2F258D51D5}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {D0487872-E5A5-424A-AB18-3B2F258D51D5}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {D0487872-E5A5-424A-AB18-3B2F258D51D5}.Release|Any CPU.Build.0 = Release|Any CPU
+ {5D8999F6-80D8-44CA-93F2-E18C9E44640C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {5D8999F6-80D8-44CA-93F2-E18C9E44640C}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {5D8999F6-80D8-44CA-93F2-E18C9E44640C}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {5D8999F6-80D8-44CA-93F2-E18C9E44640C}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
SelectedTabBackground = "Onyx";
InactiveTabForeground = "Grey";
SelectedTabForeground = "White";
-MenuIconSize = "14";
+MenuIconSize = "16";
ControlHighlight = "RoyalBlue";
}
MenuIcon {
- Margin = "2";
+ Margin = "1";
Width = "${MenuIconSize}";
Height = "${MenuIconSize}";
}
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
- <ProjectReference Include="..\..\CrowIDE\Crow\Crow\Crow.csproj" />
- <!--<PackageReference Include="Crow" Version="0.9.7-beta" /> -->
+ <ProjectReference Include="/mnt/devel/crow/Crow/Crow.csproj" />
+ <!--<PackageReference Include="Crow" Version="0.9.5-beta" />-->
</ItemGroup>
-</Project>
\ No newline at end of file
+</Project>
--- /dev/null
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"><path d="M29.4 27.6H2.5V4.5h26.9zm-25.9-1h24.9V5.5H3.5z" fill="#cccccc"/><path fill="#ffffff" d="M2.5 5.5h26.9v1.9H2.5zM11.333 9.5H19.5v1h-8.167zM11.333 12.083h12.5v1h-12.5zM11.333 14.75H21.95v1H11.333zM11.333 17.583H25.5v1H11.333zM11.333 20.5h9.834v1h-9.834zM11.5 23.083h12.167v1H11.5zM5.5 9.5h4.333v1H5.5zM5.5 12.083h4.333v1H5.5z"/><path fill="#929292" d="M5.5 12.083h4.333v1H5.5zM5.5 14.667h4.333v1H5.5zM5.5 17.25h4.333v1H5.5zM5.5 20.5h4.333v1H5.5zM5.5 23.083h4.333v1H5.5z"/></svg>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generated by IcoMoon.io -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="16" height="16" viewBox="0 0 16 16">
+<path fill="#dddddd" d="M11 6.6v0-3.8l-4-1.8-4 1.8v4.2l-3 1.3v4.4l4 1.8 3.5-1.5 3.5 1.6 4-1.8v-4.5l-4-1.7zM7 2.1l2.8 1.2-2.7 1.1-2.6-1.2 2.5-1.1zM7 5v2.9l-3-1.3v-3l3 1.4zM4 13.5l-3-1.3v-3l3 1.4v2.9zM4 10l-2.6-1.2 2.6-1.1 2.8 1.2-2.8 1.1zM11 13.5l-3-1.3v-3l3 1.4v2.9zM11 10l-2.6-1.2 2.6-1.1 2.8 1.2-2.8 1.1z"></path>
+</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generated by IcoMoon.io -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="16" height="16" viewBox="0 0 16 16">
+<path fill="#FFFFFF" d="M12 7v-2l-1.2-0.4c-0.1-0.3-0.2-0.7-0.4-1l0.6-1.2-1.5-1.3-1.1 0.5c-0.3-0.2-0.6-0.3-1-0.4l-0.4-1.2h-2l-0.4 1.2c-0.3 0.1-0.7 0.2-1 0.4l-1.1-0.5-1.4 1.4 0.6 1.2c-0.2 0.3-0.3 0.6-0.4 1l-1.3 0.3v2l1.2 0.4c0.1 0.3 0.2 0.7 0.4 1l-0.5 1.1 1.4 1.4 1.2-0.6c0.3 0.2 0.6 0.3 1 0.4l0.3 1.3h2l0.4-1.2c0.3-0.1 0.7-0.2 1-0.4l1.2 0.6 1.4-1.4-0.6-1.2c0.2-0.3 0.3-0.6 0.4-1l1.2-0.4zM3 6c0-1.7 1.3-3 3-3s3 1.3 3 3c0 1.7-1.3 3-3 3s-3-1.3-3-3z"></path>
+<path fill="#FFFFFF" d="M7.5 6c0 0.828-0.672 1.5-1.5 1.5s-1.5-0.672-1.5-1.5c0-0.828 0.672-1.5 1.5-1.5s1.5 0.672 1.5 1.5z"></path>
+<path fill="#FFFFFF" d="M16 3v-1h-0.6c0-0.2-0.1-0.4-0.2-0.5l0.4-0.4-0.7-0.7-0.4 0.4c-0.2-0.1-0.3-0.2-0.5-0.2v-0.6h-1v0.6c-0.2 0-0.4 0.1-0.5 0.2l-0.4-0.4-0.7 0.7 0.4 0.4c-0.1 0.2-0.2 0.3-0.2 0.5h-0.6v1h0.6c0 0.2 0.1 0.4 0.2 0.5l-0.4 0.4 0.7 0.7 0.4-0.4c0.2 0.1 0.3 0.2 0.5 0.2v0.6h1v-0.6c0.2 0 0.4-0.1 0.5-0.2l0.4 0.4 0.7-0.7-0.4-0.4c0.1-0.2 0.2-0.3 0.2-0.5h0.6zM13.5 3.5c-0.6 0-1-0.4-1-1s0.4-1 1-1 1 0.4 1 1c0 0.6-0.4 1-1 1z"></path>
+<path fill="#FFFFFF" d="M15.4 11.8c-0.1-0.3-0.2-0.6-0.4-0.9l0.3-0.6-0.7-0.7-0.5 0.4c-0.3-0.2-0.6-0.3-0.9-0.4l-0.2-0.6h-1l-0.2 0.6c-0.3 0.1-0.6 0.2-0.9 0.4l-0.6-0.3-0.7 0.7 0.3 0.6c-0.2 0.3-0.3 0.6-0.4 0.9l-0.5 0.1v1l0.6 0.2c0.1 0.3 0.2 0.6 0.4 0.9l-0.3 0.6 0.7 0.7 0.6-0.3c0.3 0.2 0.6 0.3 0.9 0.4l0.1 0.5h1l0.2-0.6c0.3-0.1 0.6-0.2 0.9-0.4l0.6 0.3 0.7-0.7-0.4-0.5c0.2-0.3 0.3-0.6 0.4-0.9l0.6-0.2v-1l-0.6-0.2zM12.5 14c-0.8 0-1.5-0.7-1.5-1.5s0.7-1.5 1.5-1.5 1.5 0.7 1.5 1.5-0.7 1.5-1.5 1.5z"></path>
+</svg>
Document currentDocument;
Editor currentEditor;
Project currentProject;
- public CommandGroup FileCommands, EditCommands;
+ public CommandGroup CommandsRoot, FileCommands, EditCommands, ViewCommands;
public ObservableList<Document> OpenedDocuments = new ObservableList<Document> ();
public ObservableList<Service> Services = new ObservableList<Service> ();
public ObservableList<Plugin> Plugins = new ObservableList<Plugin> ();
plugin = Plugins.FirstOrDefault (p=>p.Name == pluginName);
return plugin != null;
}
+ //TODO:flattened project
+ public IEnumerable<Project> FlattenProjects {
+ get {
+ foreach (var node in Projects.SelectMany (child => child.Flatten))
+ yield return node;
+ }
+ }
+ public bool TryGetProject<T> (string projectFullPath, out T proj) where T : Project {
+ proj = FlattenProjects.FirstOrDefault (p=>p.FullPath == projectFullPath) as T;
+ return proj != null;
+ }
+ public bool TryGetProject (string projectFullPath, out Project proj) {
+ proj = FlattenProjects.FirstOrDefault (p=>p.FullPath == projectFullPath);
+ return proj != null;
+ }
+
public Document CurrentDocument {
get => currentDocument;
set {
using Glfw;
using Crow.Text;
using System.Collections.Generic;
-using Crow.Cairo;
+using Crow.Drawing;
using System.Threading.Tasks;
using System.Linq;
using System.Diagnostics.CodeAnalysis;
-// Copyright (c) 2020 Jean-Philippe Bruyère <jp_bruyere@hotmail.com>
+// Copyright (c) 2021 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.Xml.Serialization;
using System.ComponentModel;
using System.Collections;
-using Crow.Cairo;
+using Crow.Drawing;
namespace Crow
{
+ public enum LogLevel
+ {
+ Minimal, Normal, Full, Debug
+ }
public enum LogType {
Low,
Normal,
MaxScrollY = lines == null ? 0 : lines.Count - visibleLines;
}
}
- protected override void onDraw (Cairo.Context gr)
+ protected override void onDraw (Context gr)
{
base.onDraw (gr);
public Project Parent => parent;
public IList<Project> SubProjects => subProjects;
+ public IEnumerable<Project> Flatten {
+ get {
+ yield return this;
+ if (subProjects != null) {
+ foreach (var node in subProjects?.SelectMany (child => child.Flatten))
+ yield return node;
+ }
+ }
+ }
public bool HasChildren => subProjects?.Count > 0;
public string FullPath { get ; private set; }
initCommands ();
FullPath = fullPath;
}
- public Command CMDLoad, CMDUnload, CMDReload;
+ public Command CMDLoad, CMDUnload, CMDReload, CMDClose;
public virtual CommandGroup Commands => new CommandGroup (
- CMDLoad, CMDUnload, CMDReload);
+ CMDLoad, CMDUnload, CMDReload, CMDClose);
void initCommands () {
CMDLoad = new Command ("Load", Load, "#icons.reply.svg", false);
CMDUnload = new Command ("Unload", Unload, "#icons.share-arrow.svg", false);
CMDReload = new Command ("Reload", () => { Unload(); Load();}, "#icons.refresh.svg", false);
+ CMDClose = new Command ("Close", Close, "#icons.share-arrow.svg", true);
}
public abstract void Load ();
- public abstract void Unload ();
+ public virtual void Unload () {
+ IsLoaded = false;
+ }
+ public virtual void Close () {
+ if (App.CurrentProject == this)
+ App.CurrentProject = null;
+ App.Projects.Remove (this);
+ IsLoaded = false;
+ }
public virtual string Icon => "#icons.question.svg";
}
}
\ No newline at end of file
using Glfw;
using Crow.Text;
using System.Collections.Generic;
-using Crow.Cairo;
+using Crow.Drawing;
using System.Threading.Tasks;
using System.Linq;
using System.Diagnostics.CodeAnalysis;
lock (IFace.UpdateMutex) {
if (overlay == null) {
overlay = IFace.LoadIMLFragment<ListBox>(@"
- <ListBox Style='suggestionsListBox' Data='{Suggestions}' >
+ <ListBox Style='suggestionsListBox' Data='{Suggestions}' UseLoadingThread = 'false'>
<ItemTemplate>
<ListItem Height='Fit' Margin='0' Focusable='false' HorizontalAlignment='Left'
Selected = '{Background=${ControlHighlight}}'
<Label Text='{}' HorizontalAlignment='Left' />
</ListItem>
</ItemTemplate>
- <ItemTemplate DataType='MemberInfo'>
+ <ItemTemplate DataType='System.Reflection.MemberInfo'>
<ListItem Height='Fit' Margin='0' Focusable='false' HorizontalAlignment='Left'
Selected = '{Background=${ControlHighlight}}'
Unselected = '{Background=Transparent}'>
</HorizontalStack>
</ListItem>
</ItemTemplate>
- <ItemTemplate DataType='Colors'>
+ <ItemTemplate DataType='Crow.Colors'>
<ListItem Height='Fit' Margin='0' Focusable='false' HorizontalAlignment='Left'
Selected = '{Background=${ControlHighlight}}'
Unselected = '{Background=Transparent}'>
public override string Caption => caption;
public override NodeType NodeType => nodeType;
+
+ public override CommandGroup Commands {
+ get {
+ return null;
+ }
+ }
}
}
<?xml version="1.0"?>
-<Expandable Caption="{Caption}" IsExpanded="{²IsExpanded}" BubbleMouseEvent="All" ContextCommands="{Commands}">
+<Expandable Caption="{Caption}" IsExpanded="{²IsExpanded}" BubbleMouseEvent="None" 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"/>
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-<Project Sdk="Microsoft.NET.Sdk">
- <PropertyGroup>
- <TargetFrameworks>netcoreapp5</TargetFrameworks>
- <EnableDefaultItems>false</EnableDefaultItems>
- </PropertyGroup>
-
- <ItemGroup>
- <Compile Include="src\**\*.cs" />
- <EmbeddedResource Include="ui\**\*.*" />
- </ItemGroup>
- <ItemGroup>
- <ProjectReference Include="../CERoslynPlugin\CERoslynPlugin.csproj" />
- </ItemGroup>
-</Project>
+++ /dev/null
-// Copyright (c) 2013-2019 Bruyère Jean-Philippe <jp_bruyere@hotmail.com>
-//
-// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
-
-using System;
-using Glfw;
-using System.Reflection;
-using System.Runtime.Loader;
-using System.IO;
-using Crow.Cairo;
-using System.Diagnostics;
-using System.Collections.Generic;
-using Crow.DebugLogger;
-using System.Linq;
-using CrowEditBase;
-using System.Threading;
-using Crow.Text;
-using System.Runtime.InteropServices;
-using System.Runtime.CompilerServices;
-using System.Runtime.Loader;
-
-using static CrowEditBase.CrowEditBase;
-namespace Crow
-{
- public class CrowService : Service {
- public CrowService () : base () {
-
- initCommands ();
-
- //resolve other plugins dependencies
- //AssemblyLoadContext.GetLoadContext (Assembly.GetExecutingAssembly ()).Resolving += resolvePluginRefs;
-
- if (CrowEditBase.CrowEditBase.App.TryGetWindow ("#CECrowDebugLog.ui.winLogGraph.crow", out Window win))
- win.DataSource = this;
- }
- Assembly resolvePluginRefs (AssemblyLoadContext ctx, AssemblyName assemblyName)
- => App.TryGetPlugin ("CERoslynPlugin", out Plugin roslynPlugin) ?
- roslynPlugin.Load (assemblyName) : null;
-
- static IntPtr resolveUnmanaged(Assembly assembly, String libraryName)
- {
-
- switch (libraryName)
- {
- case "glfw3":
- return NativeLibrary.Load("glfw", assembly, null);
- case "rsvg-2.40":
- return NativeLibrary.Load("rsvg-2", assembly, null);
- }
- Console.WriteLine($"[UNRESOLVE] {assembly} {libraryName}");
- return IntPtr.Zero;
- }
-
- void updateCrowApp () {
- if (App.CurrentProject is CERoslynPlugin.SolutionProject sol) {
- CERoslynPlugin.SolutionProject project = App.CurrentProject as CERoslynPlugin.SolutionProject;
- Console.WriteLine (project.Name);
- }else if (App.CurrentProject is CERoslynPlugin.MSBuildProject csprj){
- CERoslynPlugin.MSBuildProject project = App.CurrentProject as CERoslynPlugin.MSBuildProject;
- Console.WriteLine (project.Name);
- }
-
-
- }
-
-
- public Command CMDStartRecording, CMDStopRecording, CMDRefresh;
- public Command CMDGotoParentEvent, CMDEventHistoryForward, CMDEventHistoryBackward;
- public CommandGroup LoggerCommands => new CommandGroup (CMDRefresh, CMDStartRecording, CMDStopRecording);
- public CommandGroup EventCommands => new CommandGroup(
- CMDGotoParentEvent, CMDEventHistoryBackward, CMDEventHistoryForward);
- void initCommands ()
- {
- CMDRefresh = new Command ("Refresh", refresh, "#icons.refresh.svg", IsRunning);
- CMDStartRecording = new Command ("Start Recording", () => Recording = true, "#icons.circle.svg", false);
- CMDStopRecording = new Command ("Stop Recording", stopRecording, "#icons.circle-red.svg", false);
-
- CMDGotoParentEvent = new Command("parent", ()=> { CurrentEvent = CurrentEvent?.parentEvent; }, "#icons.level-up.svg", false);
- CMDEventHistoryBackward = new Command("back.", currentEventHistoryGoBack, "#icons.previous.svg", false);
- CMDEventHistoryForward = new Command("forw.", currentEventHistoryGoForward, "#icons.forward-arrow.svg", false);
- }
-
- public Command CMDOptions_SelectCrowAssemblyLocation => new Command ("...",
- () => {
- FileDialog dlg = App.LoadIMLFragment<FileDialog> (@"
- <FileDialog Caption='Select Crow.dll assembly' CurrentDirectory='{CrowDbgAssemblyLocation}'
- ShowFiles='true' ShowHidden='true' />");
- dlg.OkClicked += (sender, e) => CrowDbgAssemblyLocation = (sender as FileDialog).SelectedFileFullPath;
- dlg.DataSource = this;
- }
- );
-
- public void LoadIML (string imlSource) {
- if (CurrentState == Status.Running)
- delSetSource (imlSource);
- }
- Exception currentException;
- object dbgIFace;
- AssemblyLoadContext crowLoadCtx;
- Assembly crowAssembly, thisAssembly;
- Type dbgIfaceType;
-
- #region dbgIface delegates
- Action<int, int> delResize;
- Func<int, int, bool> delMouseMove;
- Func<float, bool> delMouseWheelChanged;
- Func<MouseButton, bool> delMouseDown, delMouseUp;
- Func<char, bool> delKeyPress;
- Func<Key, bool> delKeyDown, delKeyUp;
- FieldInfo fiDbgIFace_IsDirty;
- Action delResetDebugger;
- Action<object, string> delSaveDebugLog;
- Func<IntPtr> delGetSurfacePointer;
- Action<string> delSetSource;
- Action delReloadIml;
-
- FieldInfo fiDbg_IncludeEvents, fiDbg_DiscardEvents, fiDbg_ConsoleOutput, fiDbgIFace_MaxLayoutingTries, fiDbgIFace_MaxDiscardCount;
- #endregion
-
- bool recording, debugLogIsEnabled;
- DbgEvtType recordedEvents = DbgEvtType.Widget, discardedEvents;
- public int RefreshRate {
- get => Configuration.Global.Get<int> ("RefreshRate", 10);
- set {
- if (RefreshRate == value)
- return;
- Configuration.Global.Set ("RefreshRate", value);
- NotifyValueChanged(value);
- }
- }
- public int MaxLayoutingTries {
- get => Configuration.Global.Get<int> ("MaxLayoutingTries", 3);
- set {
- if (MaxLayoutingTries == value)
- return;
- Configuration.Global.Set ("MaxLayoutingTries", value);
- NotifyValueChanged(value);
- fiDbgIFace_MaxLayoutingTries.SetValue (null, value);
- }
- }
- public int MaxDiscardCount {
- get => Configuration.Global.Get<int> ("MaxDiscardCount", 5);
- set {
- if (MaxDiscardCount == value)
- return;
- Configuration.Global.Set ("MaxDiscardCount", value);
- NotifyValueChanged(value);
- fiDbgIFace_MaxDiscardCount.SetValue (null, value);
- }
- }
- public bool PreviewHasError => currentException != null;
- public Exception CurrentException {
- get => currentException;
- set {
- if (currentException == value)
- return;
- currentException = value;
- NotifyValueChanged (currentException);
- NotifyValueChanged ("PreviewHasError", PreviewHasError);
- }
- }
- public string CrowDbgAssemblyLocation {
- get => Configuration.Global.Get<string> ("CrowDbgAssemblyLocation");
- set {
- if (CrowDbgAssemblyLocation == value)
- return;
- Configuration.Global.Set ("CrowDbgAssemblyLocation", value);
- NotifyValueChanged(value);
- }
- }
- public bool DebugLogIsEnabled {
- get => debugLogIsEnabled;
- set {
- if (debugLogIsEnabled == value)
- return;
- debugLogIsEnabled = value;
- CMDStartRecording.CanExecute = debugLogIsEnabled & !Recording;
- CMDStopRecording.CanExecute = debugLogIsEnabled & Recording;
- NotifyValueChanged (debugLogIsEnabled);
- }
- }
- public bool Recording {
- get => recording;
- set {
- if (recording == value)
- return;
- recording = IsRunning & DebugLogIsEnabled & value;
- if (recording) {
- fiDbg_DiscardEvents.SetValue (dbgIFace, DiscardedEvents);
- fiDbg_IncludeEvents.SetValue (dbgIFace, RecordedEvents);
- CMDStartRecording.CanExecute = false;
- CMDStopRecording.CanExecute = true;
- } else {
- fiDbg_DiscardEvents.SetValue (dbgIFace, DbgEvtType.All);
- fiDbg_IncludeEvents.SetValue (dbgIFace, DbgEvtType.None);
- CMDStartRecording.CanExecute = debugLogIsEnabled;
- CMDStopRecording.CanExecute = false;
- }
- NotifyValueChanged(recording);
- }
- }
- public DbgEvtType RecordedEvents {
- get => recordedEvents;
- set {
- if (recordedEvents == value)
- return;
- recordedEvents = value;
- if (Recording)
- fiDbg_IncludeEvents.SetValue (dbgIFace, value);
- NotifyValueChanged (recordedEvents);
- }
- }
- public DbgEvtType DiscardedEvents {
- get => discardedEvents;
- set {
- if (discardedEvents == value)
- return;
- discardedEvents = value;
- if (Recording)
- fiDbg_DiscardEvents.SetValue (dbgIFace, value);
- NotifyValueChanged (discardedEvents);
- }
- }
- public string DebugLogFilePath {
- get => Configuration.Global.Get<string> ("DebugLogFilePath");
- set {
- if (DebugLogFilePath == value)
- return;
- Configuration.Global.Set ("DebugLogFilePath", value);
- NotifyValueChanged (value);
- }
- }
- public string ErrorMessage = "";
- public bool ServiceIsInError;
- void updateCrowDebuggerState (string errorMsg = null) {
- ErrorMessage = errorMsg;
- ServiceIsInError = errorMsg != null;
- NotifyValueChanged ("ServiceErrorMessage", (object)ErrorMessage);
- NotifyValueChanged ("ServiceIsInError", ServiceIsInError);
- }
- public override void Start()
- {
- if (CurrentState == Status.Running)
- return;
-
-
- if (!File.Exists (CrowDbgAssemblyLocation)) {
- DebugLogIsEnabled = false;
- updateCrowDebuggerState($"Crow.dll for debugging file not found");
- return;
- }
-
- crowLoadCtx = new AssemblyLoadContext("CrowDebuggerLoadContext");
- crowLoadCtx.ResolvingUnmanagedDll += resolveUnmanaged;
- //crowLoadCtx.Resolving += (ctx,name) => AssemblyLoadContext.Default.LoadFromAssemblyName (name);
-
- //using (crowLoadCtx.EnterContextualReflection()) {
- crowAssembly = crowLoadCtx.LoadFromAssemblyPath (CrowDbgAssemblyLocation);
- thisAssembly = crowLoadCtx.LoadFromAssemblyPath (new Uri(Assembly.GetExecutingAssembly().CodeBase).LocalPath);
-
- Type debuggerType = crowAssembly.GetType("Crow.DbgLogger");
- DebugLogIsEnabled = (bool)debuggerType.GetField("IsEnabled").GetValue(null);
-
- dbgIfaceType = thisAssembly.GetType("CECrowDebugLog.DebugInterface");
-
- dbgIFace = Activator.CreateInstance (dbgIfaceType, new object[] {CrowEditBase.CrowEditBase.App.WindowHandle});
-
- delResize = (Action<int, int>)Delegate.CreateDelegate(typeof(Action<int, int>),
- dbgIFace, dbgIfaceType.GetMethod("Resize"));
-
- delMouseMove = (Func<int, int, bool>)Delegate.CreateDelegate(typeof(Func<int, int, bool>),
- dbgIFace, dbgIfaceType.GetMethod("OnMouseMove"));
-
- delMouseWheelChanged = (Func<float, bool>)Delegate.CreateDelegate(typeof(Func<float, bool>),
- dbgIFace, dbgIfaceType.GetMethod("OnMouseWheelChanged"));
-
-
- delMouseDown = (Func<MouseButton, bool>)Delegate.CreateDelegate(typeof(Func<MouseButton, bool>),
- dbgIFace, dbgIfaceType.GetMethod("OnMouseButtonDown"));
-
- delMouseUp = (Func<MouseButton, bool>)Delegate.CreateDelegate(typeof(Func<MouseButton, bool>),
- dbgIFace, dbgIfaceType.GetMethod("OnMouseButtonUp"));
-
- delKeyDown = (Func<Key, bool>)Delegate.CreateDelegate(typeof(Func<Key, bool>),
- dbgIFace, dbgIfaceType.GetMethod("OnKeyDown"));
- delKeyUp = (Func<Key, bool>)Delegate.CreateDelegate(typeof(Func<Key, bool>),
- dbgIFace, dbgIfaceType.GetMethod("OnKeyUp"));
- delKeyPress = (Func<char, bool>)Delegate.CreateDelegate(typeof(Func<char, bool>),
- dbgIFace, dbgIfaceType.GetMethod("OnKeyPress"));
-
-
- delGetSurfacePointer = (Func<IntPtr>)Delegate.CreateDelegate(typeof(Func<IntPtr>),
- dbgIFace, dbgIfaceType.GetProperty("SurfacePointer").GetGetMethod());
- delSetSource = (Action<string>)Delegate.CreateDelegate(typeof(Action<string>),
- dbgIFace, dbgIfaceType.GetProperty("Source").GetSetMethod());
- delReloadIml = (Action)Delegate.CreateDelegate(typeof(Action), dbgIFace, dbgIfaceType.GetMethod("ReloadIml"));
-
- fiDbgIFace_IsDirty = dbgIfaceType.GetField("IsDirty");
- fiDbgIFace_MaxLayoutingTries = dbgIfaceType.GetField("MaxLayoutingTries", BindingFlags.Static | BindingFlags.Public | BindingFlags.FlattenHierarchy);
- fiDbgIFace_MaxDiscardCount = dbgIfaceType.GetField("MaxDiscardCount", BindingFlags.Static | BindingFlags.Public | BindingFlags.FlattenHierarchy);
-
- fiDbg_IncludeEvents = debuggerType.GetField("IncludeEvents");
- fiDbg_DiscardEvents = debuggerType.GetField("DiscardEvents");
- fiDbg_ConsoleOutput = debuggerType.GetField("ConsoleOutput");
- delResetDebugger = (Action)Delegate.CreateDelegate(typeof(Action), null, debuggerType.GetMethod("Reset"));
- /*delSaveDebugLog = (Action<object, string>)Delegate.CreateDelegate(typeof(Action<object, string>),
- null, debuggerType.GetMethod("Save", new Type[] {dbgIfaceType, typeof(string)}));*/
-
- dbgIfaceType.GetMethod("RegisterDebugInterfaceCallback").Invoke (dbgIFace, new object[] {this} );
- dbgIfaceType.GetMethod("Run").Invoke (dbgIFace, null);
-
- fiDbgIFace_MaxLayoutingTries.SetValue (null, MaxLayoutingTries);
- fiDbgIFace_MaxDiscardCount.SetValue (null, MaxDiscardCount);
-
- CurrentState = Status.Running;
-
- updateCrowDebuggerState();
- }
- public override void Stop()
- {
- Recording = false;
- DebugLogIsEnabled = false;
- crowLoadCtx = null;
- CurrentState = Status.Stopped;
- }
- public override void Pause()
- {
- CurrentState = Status.Paused;
- }
- public override string ConfigurationWindowPath => "#CECrowDebugLog.ui.winConfiguration.crow";
-
- protected override void onStateChange(Status previousState, Status newState)
- {
- base.onStateChange(previousState, newState);
- CMDRefresh.CanExecute = IsRunning;
- }
-
- public void onKeyDown(KeyEventArgs e)
- {
- if (CurrentState == Status.Running) {
- try
- {
- e.Handled = delKeyDown (e.Key);
- }
- catch (System.Exception ex)
- {
- Console.WriteLine($"[Error][DebugIFace key down]{ex}");
- }
- }
- }
- public void onKeyUp(KeyEventArgs e)
- {
- if (CurrentState == Status.Running) {
- try
- {
- e.Handled = delKeyUp (e.Key);
- }
- catch (System.Exception ex)
- {
- Console.WriteLine($"[Error][DebugIFace key up]{ex}");
- }
- }
- }
- public void onKeyPress(KeyPressEventArgs e)
- {
- if (CurrentState == Status.Running) {
- try
- {
- e.Handled = delKeyPress (e.KeyChar);
- }
- catch (System.Exception ex)
- {
- Console.WriteLine($"[Error][DebugIFace key press]{ex}");
- }
- }
- }
- public void onMouseMove(MouseMoveEventArgs e)
- {
- if (CurrentState == Status.Running) {
- try
- {
- e.Handled = delMouseMove (e.X, e.Y);
- }
- catch (System.Exception ex)
- {
- Console.WriteLine($"[Error][DebugIFace mouse move]{ex}");
- }
- }
- }
- public void onMouseDown(MouseButtonEventArgs e)
- {
- if (CurrentState == Status.Running) {
- try
- {
- e.Handled = delMouseDown (e.Button);
- }
- catch (System.Exception ex)
- {
- Console.WriteLine($"[Error][DebugIFace mouse down]{ex}");
- }
- }
- }
- public void onMouseUp(MouseButtonEventArgs e)
- {
- if (CurrentState == Status.Running) {
- try
- {
- e.Handled = delMouseUp (e.Button);
- }
- catch (System.Exception ex)
- {
- Console.WriteLine($"[Error][DebugIFace mouse up]{ex}");
- }
- }
- }
- public void onMouseWheel(MouseWheelEventArgs e)
- {
- if (CurrentState == Status.Running) {
- try
- {
- e.Handled = delMouseWheelChanged (e.Delta);
- }
- catch (System.Exception ex)
- {
- Console.WriteLine($"[Error][DebugIFace mouse wheel change]{ex}");
- }
- }
- }
-
-
- public IntPtr SurfacePointer => IsRunning ? delGetSurfacePointer() : IntPtr.Zero;
- public void Resize (int width, int height) {
- if (IsRunning)
- delResize (width, height);
- }
- public void ResetDirtyState () {
- if (IsRunning)
- fiDbgIFace_IsDirty.SetValue (dbgIFace, false);
- }
- public bool GetDirtyState => IsRunning ? (bool)fiDbgIFace_IsDirty.GetValue (dbgIFace) : false;
-
-
- IList<DbgEvent> events;
- IList<DbgWidgetRecord> widgets;
- public IList<DbgEvent> Events {
- get => events;
- set {
- if (events == value)
- return;
- events = value;
- NotifyValueChanged (nameof (Events), events);
- }
- }
- public IList<DbgWidgetRecord> Widgets {
- get => widgets;
- set {
- if (widgets == value)
- return;
- widgets = value;
- NotifyValueChanged (nameof (Widgets), widgets);
- }
- }
- void refresh () {
- if (IsRunning)
- delReloadIml ();
- updateCrowApp();
- }
- void stopRecording () {
- if (!Recording)
- return;
- Recording = false;
- getLog ();
- CrowEditBase.CrowEditBase.App.LoadWindow ("#CECrowDebugLog.ui.winDebugLog.crow", this);
- }
- int firstWidgetIndexToGet = 0;
- public object LogMutex = new object ();
- void getLog () {
-
- using (Stream stream = new MemoryStream (1024)) {
- Type debuggerType = crowAssembly.GetType("Crow.DbgLogger");
- MethodInfo miSave = debuggerType.GetMethod("Save",
- new Type[] {
- dbgIfaceType,
- typeof(Stream),
- typeof(int),
- typeof(bool)
- });
-
-
- List<DbgWidgetRecord> widgets = new List<DbgWidgetRecord>();
- List<DbgEvent> events = new List<DbgEvent>();
- miSave.Invoke(null, new object[] {dbgIFace, stream, firstWidgetIndexToGet, true});
- stream.Seek(0, SeekOrigin.Begin);
- DbgLogger.Load (stream, events, widgets);
-
- lock (LogMutex) {
- for (int i = 0; i < widgets.Count; i++) {
- widgets[i].listIndex = i;
- //Widgets.Add (widgets[i]);
- }
- for (int i = 0; i < events.Count; i++) {
- //Events.Add (events[i]);
- updateWidgetEvents (widgets, events[i]);
- }
- }
- Events = events;
- Widgets = widgets;
- firstWidgetIndexToGet += widgets.Count;
- /*if (widgets.Count > 0 && firstWidgetIndexToGet != widgets.Last().InstanceIndex + 1)
- Debugger.Break ();*/
- }
- }
- void updateWidgetEvents (IList<DbgWidgetRecord> widgets, DbgEvent evt) {
- if (evt is DbgWidgetEvent we)
- widgets.FirstOrDefault (w => w.InstanceIndex == we.InstanceIndex)?.Events.Add (we);
- if (evt.Events == null)
- return;
- foreach (DbgEvent e in evt.Events)
- updateWidgetEvents (widgets, e);
- }
- void saveLogToDebugLogFilePath () {
-
- }
- void loadLogFromDebugLogFilePath () {
-
- }
-
- //public virtual object GetScreenCoordinates () => ScreenCoordinates(Slot).TopLeft;
- DbgEvent curEvent;
- bool disableCurrentEventHistory;
- Stack<DbgEvent> CurrentEventHistoryForward = new Stack<DbgEvent>();
- Stack<DbgEvent> CurrentEventHistoryBackward = new Stack<DbgEvent>();
- DbgWidgetRecord curWidget = new DbgWidgetRecord();
- public string[] AllEventTypes => Enum.GetNames (typeof(DbgEvtType));
- string searchEventType;
- DbgWidgetRecord searchWidget;
- public string SearchEventType {
- get => searchEventType;
- set {
- if (searchEventType == value)
- return;
- searchEventType = value;
- NotifyValueChanged (searchEventType);
- }
- }
-
- public DbgWidgetRecord SearchWidget {
- get => searchWidget;
- set {
- if (searchWidget == value)
- return;
- searchWidget = value;
- NotifyValueChanged (searchWidget);
- }
- }
- public DbgEvent CurrentEvent {
- get => curEvent;
- set {
- if (curEvent == value)
- return;
-
- if (!disableCurrentEventHistory) {
- CurrentEventHistoryForward.Clear ();
- CMDEventHistoryForward.CanExecute = false;
- if (!(value == null || curEvent == null)) {
- CurrentEventHistoryBackward.Push (curEvent);
- CMDEventHistoryBackward.CanExecute = true;
- }
- }
-
- curEvent = value;
-
- NotifyValueChanged (nameof (CurrentEvent), curEvent);
- NotifyValueChanged ("CurEventChildEvents", curEvent?.Events);
- NotifyValueChanged ("CurWidgetProperties", CurWidgetProperties);
-
- if (CurrentEvent != null && CurrentEvent.parentEvent != null)
- CMDGotoParentEvent.CanExecute = true;
- else
- CMDGotoParentEvent.CanExecute = false;
- }
- }
- void currentEventHistoryGoBack () {
- disableCurrentEventHistory = true;
- if (CurrentEvent != null) {
- CurrentEventHistoryForward.Push (CurrentEvent);
- CMDEventHistoryForward.CanExecute = true;
- }
- CurrentEvent = CurrentEventHistoryBackward.Pop ();
- CMDEventHistoryBackward.CanExecute = CurrentEventHistoryBackward.Count > 0;
-
- disableCurrentEventHistory = false;
- }
-
- void currentEventHistoryGoForward () {
- disableCurrentEventHistory = true;
- CurrentEventHistoryBackward.Push (CurrentEvent);
- CMDEventHistoryBackward.CanExecute = true;
- CurrentEvent = CurrentEventHistoryForward.Pop ();
- CMDEventHistoryForward.CanExecute = CurrentEventHistoryForward.Count > 0;
-
- disableCurrentEventHistory = false;
- }
-
- public DbgWidgetRecord CurrentWidget {
- get => curWidget;
- set {
- if (curWidget == value)
- return;
- curWidget = value;
- NotifyValueChanged (nameof (CurrentWidget), curWidget);
- NotifyValueChanged ("CurWidgetRootEvents", curWidget?.RootEvents);
- NotifyValueChanged ("CurrentWidgetEvents", curWidget?.Events);
- NotifyValueChanged ("CurWidgetProperties", CurWidgetProperties);
- }
- }
- public List<DbgWidgetEvent> CurWidgetRootEvents => curWidget == null? new List<DbgWidgetEvent>() : curWidget.RootEvents;
-
- public IEnumerable<KeyValuePair<string, string>> CurWidgetProperties {
- get {
- if (curWidget == null)
- return null;
- long endTime = curEvent == null ? long.MaxValue : curEvent.end;
- Dictionary<string, string> result = new Dictionary<string, string> ();
- foreach (DbgWidgetEvent evt in curWidget?.Events?.Where (e => e.type == DbgEvtType.GOSetProperty && e.begin <= endTime)){
- string[] tmp = evt.Message.Split('=');
- if (result.ContainsKey (tmp[0]))
- result[tmp[0]] = tmp[1];
- else
- result.Add (tmp[0], tmp[1]);
- }
- return result;
- }
- }
-
- }
-}
\ No newline at end of file
+++ /dev/null
-// Copyright (c) 2021 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.ComponentModel;
-using Crow.Cairo;
-using Crow.DebugLogger;
-
-namespace Crow
-{
- public class DbgEventView : TemplatedContainer {
- DbgEvent evt;
- public DbgEvent Event {
- get => evt;
- set {
- if (evt == value)
- return;
- evt = value;
- NotifyValueChangedAuto (evt);
- }
- }
- }
- public class DbgEventWidget : Widget
- {
- public DbgEventWidget (){}
-
- DbgEvent evt, hoverEvt;
- long ticksPerPixel;
- double pixelPerTick;
-
- object dataMutex = new object();
-
- public DbgEvent Event {
- get => evt;
- set {
- if (evt == value)
- return;
- lock (dataMutex)
- evt = value;
- updatePixelPerTicks ();
- NotifyValueChangedAuto (evt);
- RegisterForRedraw ();
- }
- }
- public DbgEvent HoverEvent {
- get => hoverEvt;
- private set {
- if (hoverEvt == value)
- return;
- lock (dataMutex)
- evt = value;
- hoverEvt = value;
- NotifyValueChangedAuto (hoverEvt);
- }
- }
-
- [DefaultValue ("1000")]
- public long TicksPerPixel {
- get => ticksPerPixel;
- set {
- if (ticksPerPixel == value)
- return;
- ticksPerPixel = value;
- NotifyValueChangedAuto (ticksPerPixel);
- if (Width == Measure.Fit)
- RegisterForLayouting (LayoutingType.Width);
- }
- }
-
- public override int measureRawSize (LayoutingType lt)
- {
- updatePixelPerTicks ();
- if (lt == LayoutingType.Width)
- contentSize.Width = Event == null ? 0 : (int)Math.Max(pixelPerTick * Event.Duration, 2);
-
- return base.measureRawSize (lt);
- }
-
- public override void OnLayoutChanges (LayoutingType layoutType)
- {
- if (layoutType == LayoutingType.Width)
- updatePixelPerTicks ();
-
- base.OnLayoutChanges (layoutType);
- }
-
- protected override void onDraw (Context gr)
- {
- lock (dataMutex) {
-
- if (Event == null) {
- base.onDraw (gr);
- return;
- }
-
- gr.LineWidth = 1;
- gr.SetDash (new double [] { 1.0, 3.0 }, 0);
-
- Rectangle cb = ClientRectangle;
-
- if (Event.Duration == 0) {
- gr.SetSource (Event.Color);
- gr.Rectangle (cb);
- gr.Fill ();
- return;
- }
-
- drawEvent (gr, cb.Height, Event);
- }
- }
- void drawEvent (Context ctx, int h, DbgEvent dbge)
- {
- double w = Math.Max(dbge.Duration * pixelPerTick, 2.0);
- double x = (dbge.begin - Event.begin) * pixelPerTick;
-
- ctx.Rectangle (x, 0, w, h);
- ctx.SetSource (dbge.Color);
- /*if (dbge.IsSelected) {
- ctx.FillPreserve ();
- ctx.SetSource (1, 1, 1);
- ctx.Stroke ();
- }else*/
- ctx.Fill ();
-
- if (dbge.Events == null)
- return;
- foreach (DbgEvent e in dbge.Events)
- drawEvent (ctx, h, e);
- }
-
- public override void onMouseMove (object sender, MouseMoveEventArgs e)
- {
- if (Event != null) {
- Point m = ScreenPointToLocal (e.Position);
- long curTick = (long)(m.X / pixelPerTick) + Event.begin;
- HoverEvent = hoverEvent (Event, curTick);
-
- e.Handled = true;
- }
- base.onMouseMove (sender, e);
- }
-
- DbgEvent hoverEvent (DbgEvent hevt, long curTick){
- if (hevt.Events != null) {
- foreach (DbgEvent e in hevt.Events) {
- if (curTick >= e.begin && curTick <= e.end)
- return hoverEvent (e, curTick);
- }
- }
- return hevt;
- }
- void updatePixelPerTicks ()
- {
- if (Width == Measure.Fit)
- pixelPerTick = 1.0 / ticksPerPixel;
- else
- pixelPerTick = Event == null ? 0 : (double)ClientRectangle.Width / Event.Duration;
- }
- }
-}
\ No newline at end of file
+++ /dev/null
-// Copyright (c) 2013-2021 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.ComponentModel;
-using System.IO;
-using System.Linq;
-using System.Threading.Tasks;
-using Crow.Cairo;
-using Crow.DebugLogger;
-using System.Diagnostics;
-
-namespace Crow
-{
- public class DbgLogViewer : Widget
- {
- public static Dictionary<DbgEvtType, Color> colors;
-
- #region CTOR
- protected DbgLogViewer () : base(){}
- public DbgLogViewer (Interface iface, string style = null) : base(iface, style){}
- #endregion
-
- FontExtents fe;
-
-
- double xScale = 1.0/1024.0, yScale = 1.0, leftMargin, topMargin = 0.0;
- DbgWidgetRecord curWidget, hoverWidget;
- DbgEvent curEvent, hoverEvent;
-
- IList<DbgEvent> events = new List<DbgEvent> ();
- IList<DbgWidgetRecord> widgets = new List<DbgWidgetRecord> ();
-
-
- public DbgEvtType Filter {
- get => Configuration.Global.Get<DbgEvtType> ("DbgLogViewFilter");
- set {
- if (Filter == value)
- return;
- Configuration.Global.Set ("DbgLogViewFilter", value);
- NotifyValueChangedAuto(Filter);
- RegisterForGraphicUpdate();
- }
- }
- public IList<DbgEvent> Events {
- get => events;
- set {
- if (events == value)
- return;
- events = value;
- NotifyValueChanged (nameof (Events), events);
-
- maxTicks = minTicks = 0;
- if (events != null && events.Count > 0) {
- minTicks = long.MaxValue;
- foreach (DbgEvent e in events) {
- if (e.begin < minTicks)
- minTicks = e.begin;
- if (e.end > maxTicks)
- maxTicks = e.end;
- }
- visibleTicks = maxTicks - minTicks;
- XScale = (ClientRectangle.Width - leftMargin)/visibleTicks;
- ScrollX = 0;
- ScrollY = 0;
- } else {
- maxTicks = 1;
- XScale = 1.0/1024.0;
- }
-
-
- RegisterForGraphicUpdate ();
- }
- }
- public IList<DbgWidgetRecord> Widgets {
- get => widgets;
- set {
- if (widgets == value)
- return;
- widgets = value;
- NotifyValueChanged (nameof (Widgets), widgets);
- updateMargins ();
- updateMaxScrollX ();
- updateMaxScrollY ();
- }
- }
- public DbgWidgetRecord CurrentWidget {
- get => curWidget;
- set {
- if (curWidget == value)
- return;
- curWidget = value;
- NotifyValueChanged (nameof (CurrentWidget), curWidget);
- if (CurrentWidget == null)
- return;
- if (CurrentWidget.listIndex < scrollY || CurrentWidget.listIndex > scrollY + visibleLines)
- ScrollY = CurrentWidget.listIndex - (visibleLines / 2);
-
- currentLine = CurrentWidget.listIndex;
- RegisterForRedraw();
- }
- }
- public DbgEvent CurrentEvent {
- get => curEvent;
- set {
- if (curEvent == value)
- return;
- /*if (curEvent != null)
- curEvent.IsSelected = false;*/
- curEvent = value;
- if (curEvent != null) {
- //curEvent.IsSelected = true;
- if (curEvent is DbgWidgetEvent we) {
- //CurrentWidget = Widgets [we.InstanceIndex];
- hoverLine = we.InstanceIndex;
- }
- currentTick = curEvent.begin;
- if (curEvent.begin > minTicks + ScrollX + visibleTicks ||
- curEvent.end < minTicks + ScrollX)
- ScrollX = curEvent.begin - minTicks - visibleTicks / 2;
- }
- NotifyValueChanged (nameof (CurrentEvent), curEvent);
- RegisterForRedraw ();
- }
- }
- public DbgWidgetRecord HoverWidget {
- get => hoverWidget;
- internal set {
- if (hoverWidget == value)
- return;
- hoverWidget = value;
- NotifyValueChanged (nameof (HoverWidget), hoverWidget);
- }
- }
-
- public DbgEvent HoverEvent {
- get => hoverEvent;
- set {
- if (hoverEvent == value)
- return;
- hoverEvent = value;
- NotifyValueChanged (nameof (HoverEvent), hoverEvent);
- RegisterForRepaint ();
- }
- }
-
- long hoverTick = 0, currentTick, selStart = -1, selEnd = -1, minTicks = 0, maxTicks = 0, visibleTicks = 0;
- int hoverLine = -1, currentLine = -1;
- int visibleLines = 1;
- Point mousePos;
-
- public double XScale {
- get => xScale;
- set {
- if (xScale == value)
- return;
- xScale = value;
- NotifyValueChanged ("XScale", xScale);
- updateVisibleTicks ();
- RegisterForGraphicUpdate ();
- }
- }
- public double YScale {
- get => yScale;
- set {
- if (yScale == value)
- return;
- yScale = value;
- NotifyValueChanged ("YScale", yScale);
- RegisterForGraphicUpdate ();
- }
- }
- public override Font Font {
- get { return base.Font; }
- set {
- base.Font = value;
- using (Context gr = new Context (IFace.surf)) {
- gr.SelectFontFace (Font.Name, Font.Slant, Font.Wheight);
- gr.SetFontSize (Font.Size);
-
- fe = gr.FontExtents;
- }
- updateMargins ();
- }
- }
- RectangleD getWidgetEvtBounds (DbgEvent evt, ref Rectangle cb, double penY) {
- double x = xScale * (evt.begin - minTicks - ScrollX);
- double w = Math.Max (Math.Max (2.0, 2.0 * xScale), (double)(evt.end - evt.begin) * xScale);
- if (x < 0.0) {
- w += x;
- x = 0.0;
- }
- x += leftMargin + cb.Left;
- double rightDiff = x + w - cb.Right;
- if (rightDiff > 0)
- w -= rightDiff;
- return new RectangleD(x, penY, w, fe.Height);
- }
- void drawEvents (Context ctx, IList<DbgEvent> evts)
- {
- if (evts == null || evts.Count == 0)
- return;
- Rectangle cb = ClientRectangle;
-
- foreach (DbgEvent evt in evts) {
- if ((evt.Category & currentFilter) == currentFilter) {
- if (evt.end - minTicks <= ScrollX)
- continue;
- if (evt.begin - minTicks > ScrollX + visibleTicks)
- break;
- double penY = topMargin + ClientRectangle.Top;
-
- if (evt.type.HasFlag (DbgEvtType.Widget)) {
- DbgWidgetEvent eW = evt as DbgWidgetEvent;
- int lIdx = eW.InstanceIndex - ScrollY;
- if (lIdx >= 0 && lIdx <= visibleLines) {
-
- penY += (lIdx) * fe.Height;
-
- ctx.SetSource (evt.Color);
- ctx.Rectangle (getWidgetEvtBounds (evt, ref cb, penY));
- ctx.Fill ();
- }
- } else if (evt.type.HasFlag (DbgEvtType.IFace)) {
- double x = xScale * (evt.begin - minTicks - ScrollX);
- double w = Math.Max (Math.Max (2.0, 2.0 * xScale), (double)(evt.end - evt.begin) * xScale);
- if (x < 0.0) {
- w += x;
- x = 0.0;
- }
- x += leftMargin + cb.Left;
- double rightDiff = x + w - cb.Right;
- if (rightDiff > 0)
- w -= rightDiff;
- //ctx.SetSource (0.9,0.9,0.0,0.1);
- ctx.SetSource (evt.Color.AdjustAlpha(0.15));
- ctx.Rectangle (x, cb.Top + topMargin, w, cb.Height);
- ctx.Fill ();
- }
- }
- drawEvents (ctx, evt.Events);
- }
- }
-
- DbgEvtType currentFilter;
- protected override void onDraw (Cairo.Context gr)
- {
- base.onDraw (gr);
-
- setFontForContext (gr);
-
- if (widgets == null)
- return;
-
- gr.LineWidth = 1.0;
-
- Rectangle cb = ClientRectangle;
-
- double penY = topMargin + ClientRectangle.Top;
-
- for (int i = 0; i < visibleLines; i++) {
- if (i + ScrollY >= widgets.Count)
- break;
- int gIdx = i + ScrollY;
- DbgWidgetRecord g = widgets [gIdx];
-
- penY += fe.Height;
-
- gr.SetSource (Crow.Colors.Jet);
- gr.MoveTo (cb.X, penY - 0.5);
- gr.LineTo (cb.Right, penY - 0.5);
- gr.Stroke ();
-
- double penX = 5.0 * g.xLevel + cb.Left;
-
- if (g.xLevel == 0)
- gr.SetSource (Crow.Colors.LightSalmon);
- else if (currentLine == g.listIndex)
- gr.SetSource(Colors.RoyalBlue);
- else
- Foreground.SetAsSource (IFace, gr);
-
- gr.MoveTo (penX, penY - gr.FontExtents.Descent);
- gr.ShowText (g.name + gIdx);
- }
-
- currentFilter = Filter;
- drawEvents (gr, events);
-
- gr.MoveTo (cb.Left, topMargin - 0.5 + cb.Top);
- gr.LineTo (cb.Right, topMargin - 0.5 + cb.Top);
-
- gr.MoveTo (leftMargin + cb.Left, cb.Top);
- gr.LineTo (leftMargin + cb.Left, cb.Bottom);
- gr.SetSource (Crow.Colors.Grey);
-
- penY = topMargin + ClientRectangle.Top;
-
- //graduation
- long largeGrad = long.Parse ("1" + new string ('0', visibleTicks.ToString ().Length - 1));
- long smallGrad = Math.Max (1, largeGrad / 10);
-
- long firstVisibleTicks = minTicks + ScrollX;
- long curGrad = firstVisibleTicks - firstVisibleTicks % smallGrad + smallGrad;
-
- long gg = curGrad - ScrollX - minTicks;
- while (gg < visibleTicks ) {
- double x = (double)gg * xScale + leftMargin + cb.Left;
-
- gr.MoveTo (x, penY - 0.5);
- if (curGrad % largeGrad == 0) {
- gr.LineTo (x, penY - 8.5);
- string str = ticksToMS(curGrad);
- TextExtents te = gr.TextExtents (str);
- gr.RelMoveTo (-0.5 * te.Width, -2.0);
- gr.ShowText (str);
- }else
- gr.LineTo (x, penY - 2.5);
-
- curGrad += smallGrad;
- gg = curGrad - ScrollX - minTicks;
- }
-
- gr.Stroke ();
-
-
-
- }
- string ticksToMS(long ticks) => Math.Round ((double)ticks / Stopwatch.Frequency * 1000.0, 2).ToString();
- public override void Paint (Cairo.Context ctx)
- {
- base.Paint (ctx);
-
- Rectangle r = new Rectangle(mousePos.X, 0, 1, Slot.Height);
- Rectangle ctxR = ContextCoordinates (r);
- Rectangle cb = ClientRectangle;
- ctx.LineWidth = 1.0;
- if (hoverTick >= 0) {
- double x = xScale * (hoverTick - minTicks - ScrollX) + leftMargin;
- if (x - Math.Truncate (x) > 0.5)
- x = Math.Truncate (x) + 0.5;
- else
- x = Math.Truncate (x) - 0.5;
- ctx.MoveTo (x, cb.Top + topMargin - 4.0);
- ctx.LineTo (x, cb.Bottom);
- ctx.SetSource (0.7,0.7,0.7,0.5);
- ctx.Stroke();
- }
- if (currentTick >= 0) {
- double x = xScale * (currentTick - minTicks - ScrollX) + leftMargin;
- if (x > leftMargin && x < cb.Right) {
- if (x - Math.Truncate (x) > 0.5)
- x = Math.Truncate (x) + 0.5;
- else
- x = Math.Truncate (x) - 0.5;
- ctx.MoveTo (x, cb.Top);
- ctx.LineTo (x, cb.Bottom);
- ctx.SetSource (0.2,0.7,1.0,0.6);
- ctx.Stroke();
- }
- }
-
- setFontForContext (ctx);
-
- string str = ticksToMS(hoverTick);
-
- ctx.MoveTo (ctxR.X - ctx.TextExtents (str).Width / 2, ctxR.Y + fe.Height);
- ctx.ShowText (str);
-
- ctx.Operator = Cairo.Operator.Add;
-
- if (hoverLine >= 0) {
- double y = fe.Height * (hoverLine - ScrollY) + topMargin + cb.Top;
- r = new Rectangle (cb.Left, (int)y, cb.Width, (int)fe.Height);
-
- ctx.SetSource (0.1, 0.1, 0.1, 0.4);
- ctx.Rectangle (ContextCoordinates (r));
- ctx.Fill ();
-
- if (hoverEvent is DbgWidgetEvent wevt) {
- ctx.SetSource (1.0,1.0,1.0,0.7);
- ctx.SetDash (new double[] {1, 2});
- ctx.Rectangle ((Rectangle)getWidgetEvtBounds (wevt, ref cb, y).Inflated (1), 1);
- }
- }
-
- if (currentLine >= ScrollY && currentLine < scrollY + visibleLines) {
- double y = fe.Height * (currentLine - ScrollY) + topMargin + cb.Top;
- r = new Rectangle (cb.Left, (int)y, cb.Width, (int)fe.Height);
-
- ctx.SetSource (0.1, 0.1, 0.7, 0.2);
- ctx.Rectangle (ContextCoordinates (r));
- ctx.Fill ();
- }
-
- if (selStart < 0 || selEnd < 0) {
- ctx.Operator = Cairo.Operator.Over;
- return;
- }
- double selStartX = (double)(selStart - ScrollX - minTicks) * xScale + leftMargin + cb.Left;
- double selEndX = (double)(selEnd - ScrollX - minTicks) * xScale + leftMargin + cb.Left;
-
- if (selStartX < selEndX) {
- ctxR.X = (int)selStartX;
- ctxR.Width = (int)(selEndX - selStartX);
- } else {
- ctxR.X = (int)selEndX;
- ctxR.Width = (int)(selStartX - selEndX);
- }
-
- ctxR.Width = Math.Max (1, ctxR.Width);
- ctx.Rectangle (ctxR);
- ctx.SetSource (0.0,0.2,0.8,0.15);
- //ctx.SetSource (Colors.Jet);
- ctx.Fill();
- ctx.Operator = Cairo.Operator.Over;
-
- str = $"{ticksToMS(Math.Abs (selEnd - selStart))} (ms)";
-
- ctx.MoveTo (ctxR.Center.X - ctx.TextExtents (str).Width / 2, ctxR.Y + fe.Height);
- ctx.SetSource (Colors.Black);
- ctx.ShowText (str);
-
-
-
- }
- public override void OnLayoutChanges (LayoutingType layoutType)
- {
- base.OnLayoutChanges (layoutType);
- switch (layoutType) {
- case LayoutingType.Width:
- if (xScale < 0) {
- visibleTicks = maxTicks - minTicks;
- XScale = (ClientRectangle.Width - leftMargin) / visibleTicks;
- }
- updateVisibleTicks ();
- break;
- case LayoutingType.Height:
- updateVisibleLines ();
- break;
- }
- }
-
- public override void onMouseLeave (object sender, MouseMoveEventArgs e)
- {
- base.onMouseLeave (sender, e);
- hoverLine = -1;
- hoverTick = 0;
- }
- public override void onMouseMove (object sender, MouseMoveEventArgs e)
- {
- long lastTick = hoverTick;
- int lastLine = hoverLine;
- updateMouseLocalPos (e.Position);
-
- if ((IFace.IsDown (Glfw.MouseButton.Left) || IFace.IsDown (Glfw.MouseButton.Middle)) && selStart >= 0)
- selEnd = hoverTick;
- else if (IFace.IsDown(Glfw.MouseButton.Right)) {
- if (lastTick >= 0 && hoverTick >= 0)
- ScrollX += lastTick - hoverTick;
- if (lastLine >= 0 && hoverLine >= 0)
- ScrollY += lastLine - hoverLine;
- updateMouseLocalPos (e.Position);
- } else if (widgets != null) {
- HoverWidget = (hoverLine < 0 || hoverLine >= widgets.Count) ? null : widgets [hoverLine];
- //HoverEvent = hoverWidget?.Events.FirstOrDefault (ev => ev.begin <= hoverTick && ev.end >= hoverTick);
- double tickPerPixel = (double)visibleTicks / ClientRectangle.Width;
- //Console.WriteLine ($"ticks per pixel: {tickPerPixel}");
- Task.Run (() => findHoverEvent (hoverWidget, hoverTick, (int)tickPerPixel));
- }
-
- RegisterForRepaint();
-
- e.Handled = true;
- base.onMouseMove (sender, e);
- }
- void findHoverEvent (DbgWidgetRecord widget, long tick, long precision = 0) {
- DbgEvent tmp = widget?.Events.FirstOrDefault (ev => ev.begin - precision <= tick && ev.end + precision >= tick);
- if (tmp == null) {
- tmp = Events.Where(e=>e.type.HasFlag(DbgEvtType.IFace)).Where (ev => ev.begin - precision <= tick && ev.end + precision >= tick).FirstOrDefault();
- while(tmp != null) {
- DbgEvent che = tmp.Events?.Where(e=>e.type.HasFlag(DbgEvtType.IFace)).Where (ev => ev.begin - precision <= tick && ev.end + precision >= tick).FirstOrDefault();
- if (che == null)
- break;
- tmp = che;
- }
- } else {
- while(tmp != null) {
- DbgEvent che = tmp.Events?.OfType<DbgWidgetEvent>()?.Where(ev=>ev.InstanceIndex == widget.listIndex && ev.begin - precision <= tick && ev.end + precision >= tick).FirstOrDefault();
- if (che == null)
- break;
- tmp = che;
- }
- }
- HoverEvent = tmp;
- }
- public override void onMouseClick(object sender, MouseButtonEventArgs e)
- {
- if (e.Button == Glfw.MouseButton.Left) {
- if (selEnd < 0) {
- currentTick = hoverTick;
- currentLine = hoverLine;
- CurrentWidget = hoverWidget;
- CurrentEvent = hoverEvent;
- }
- selStart = -1;
- selEnd = -1;
- }
-
- e.Handled = true;
- base.onMouseClick(sender, e);
- }
- public override void onMouseDown (object sender, MouseButtonEventArgs e)
- {
- if (e.Button == Glfw.MouseButton.Left || e.Button == Glfw.MouseButton.Middle) {
- selStart = hoverTick;
- selEnd = -1;
- }
-
- RegisterForRedraw ();
- e.Handled = true;
- base.onMouseDown (sender, e);
- }
- public override void onMouseUp (object sender, MouseButtonEventArgs e)
- {
-
- if (e.Button == Glfw.MouseButton.Left && selEnd > 0 && selEnd != selStart) {
- long scrX = 0;
- if (selStart < selEnd) {
- visibleTicks = selEnd - selStart;
- scrX = selStart - minTicks;
- } else {
- visibleTicks = selStart - selEnd;
- scrX = selEnd - minTicks;
- }
- XScale = (ClientRectangle.Width - leftMargin) / visibleTicks;
- ScrollX = scrX;
- }
-
- RegisterForRedraw ();
- e.Handled = true;
- base.onMouseUp (sender, e);
- }
-
- /// <summary> Process scrolling vertically, or if shift is down, vertically </summary>
- public override void onMouseWheel (object sender, MouseWheelEventArgs e)
- {
- //base.onMouseWheel (sender, e);
-
- if (IFace.Shift)
- ScrollX -= (int)((double)(e.Delta * MouseWheelSpeed) / xScale);
- else if (IFace.Ctrl)
- ScrollY -= e.Delta * MouseWheelSpeed;
- else {
- if (e.Delta > 0) {
- XScale *= 2.0;
- } else {
- if (MaxScrollX > 0)
- XScale *= 0.5;
- }
- ScrollX = (long)(hoverTick - (long)((double)Math.Max(0, mousePos.X - (long)leftMargin) / xScale) - minTicks);
- }
- }
-
- public override void onKeyDown (object sender, KeyEventArgs e)
- {
- base.onKeyDown (sender, e);
-
- if (e.Key == Glfw.Key.F3) {
- if (selEnd < 0)
- return;
- if (selEnd < selStart)
- zoom (selEnd, selStart);
- else
- zoom (selStart, selEnd);
- selEnd = selStart = -1;
- }
- }
-
- void updateMargins ()
- {
- leftMargin = topMargin = 0.0;
-
- if (widgets == null)
- return;
-
- using (Context gr = new Context (IFace.surf)) {
- double maxNameWidth = 0.0;
-
- setFontForContext (gr);
-
- foreach (DbgWidgetRecord o in widgets) {
- double nameWidth = gr.TextExtents (o.name).Width + 5.0 * o.xLevel;
- if (nameWidth > maxNameWidth)
- maxNameWidth = nameWidth;
- }
-
- leftMargin = 10.5 + maxNameWidth;
- topMargin = 2.0 * fe.Height;
-
- RegisterForGraphicUpdate ();
- }
- }
-
- void updateVisibleLines ()
- {
- visibleLines = fe.Height < 1 ? 1 : (int)Math.Ceiling (((double)ClientRectangle.Height - topMargin) / fe.Height);
- NotifyValueChanged ("VisibleLines", visibleLines);
- updateMaxScrollY ();
- }
- void updateVisibleTicks ()
- {
- visibleTicks = Math.Max (0, (long)((double)(ClientRectangle.Width - leftMargin) / XScale));
- NotifyValueChanged ("VisibleTicks", visibleTicks);
- updateMaxScrollX ();
- }
-
- void updateMaxScrollX ()
- {
- if (widgets == null) {
- MaxScrollX = 0;
- } else {
- long tot = maxTicks - minTicks;
- MaxScrollX = Math.Max (0L, tot - visibleTicks);
- NotifyValueChanged ("ChildWidthRatio", (double)visibleTicks / tot);
- }
- }
- void updateMaxScrollY ()
- {
- if (widgets == null)
- MaxScrollY = 0;
- else {
- MaxScrollY = Math.Max (0, widgets.Count + 1 - visibleLines);
- NotifyValueChanged ("ChildHeightRatio", (double)visibleLines / (widgets.Count + 1));
- }
- }
-
- void updateMouseLocalPos (Point mPos)
- {
- Rectangle r = ScreenCoordinates (Slot);
- Rectangle cb = ClientRectangle;
- cb.Left += (int)leftMargin;
- cb.Width -= (int)leftMargin;
- cb.Y += (int)topMargin;
- cb.Height -= (int)topMargin;
-
- mousePos = mPos - r.Position;
-
- mousePos.X = Math.Max (cb.X, mousePos.X);
- mousePos.X = Math.Min (cb.Right, mousePos.X);
-
- if (mousePos.Y < cb.Top || mousePos.Y > cb.Bottom)
- hoverLine = -1;
- else
- hoverLine = (int)((double)(mousePos.Y - cb.Top) / fe.Height) + ScrollY;
-
- NotifyValueChanged ("CurrentLine", hoverLine);
-
- mousePos.Y = Math.Max (cb.Y, mousePos.Y);
- mousePos.Y = Math.Min (cb.Bottom, mousePos.Y);
-
- hoverTick = (long)((double)(mousePos.X - cb.X) / xScale) + minTicks + ScrollX;
- RegisterForRedraw ();
- }
- void zoom (long start, long end) {
- //Rectangle cb = ClientRectangle;
- //cb.X += (int)leftMargin;
- XScale = ((double)ClientRectangle.Width - leftMargin)/(end - start);
- ScrollX = (int)(start - minTicks);
- }
-
-
- long scrollX, maxScrollX;
- int scrollY, maxScrollY, mouseWheelSpeed;
-
- /// <summary>
- /// if true, key stroke are handled in derrived class
- /// </summary>
- protected bool KeyEventsOverrides = false;
-
- /// <summary> Horizontal Scrolling Position </summary>
- [DefaultValue(0)]
- public virtual long ScrollX {
- get => scrollX;
- set {
- if (scrollX == value)
- return;
-
- long newS = value;
- if (newS < 0)
- newS = 0;
- else if (newS > maxScrollX)
- newS = maxScrollX;
-
- if (newS == scrollX)
- return;
-
- scrollX = newS;
-
- NotifyValueChangedAuto (scrollX);
- RegisterForGraphicUpdate ();
- }
- }
- /// <summary> Vertical Scrolling Position </summary>
- [DefaultValue(0)]
- public virtual int ScrollY {
- get => scrollY;
- set {
- if (scrollY == value)
- return;
-
- int newS = value;
- if (newS < 0)
- newS = 0;
- else if (newS > maxScrollY)
- newS = maxScrollY;
-
- if (newS == scrollY)
- return;
-
- scrollY = newS;
-
- NotifyValueChangedAuto (scrollY);
- RegisterForGraphicUpdate ();
-
- if (widgets == null)
- return;
-
- Rectangle cb = ClientRectangle;
- cb.Left += (int)leftMargin;
- cb.Width -= (int)leftMargin;
- cb.Y += (int)topMargin;
- cb.Height -= (int)topMargin;
-
- if (mousePos.Y < cb.Top || mousePos.Y > cb.Bottom)
- hoverLine = -1;
- else
- hoverLine = (int)((double)(mousePos.Y - cb.Top) / fe.Height) + ScrollY;
-
- NotifyValueChanged ("CurrentLine", hoverLine);
- }
- }
- /// <summary> Horizontal Scrolling maximum value </summary>
- [DefaultValue(0)]
- public virtual long MaxScrollX {
- get => maxScrollX;
- set {
- if (maxScrollX == value)
- return;
-
- maxScrollX = Math.Max(0, value);
-
- if (scrollX > maxScrollX)
- ScrollX = maxScrollX;
-
- NotifyValueChangedAuto (maxScrollX);
- RegisterForGraphicUpdate ();
- }
- }
- /// <summary> Vertical Scrolling maximum value </summary>
- [DefaultValue(0)]
- public virtual int MaxScrollY {
- get => maxScrollY;
- set {
- if (maxScrollY == value)
- return;
-
- maxScrollY = Math.Max (0, value);
-
- if (scrollY > maxScrollY)
- ScrollY = maxScrollY;
-
- NotifyValueChangedAuto (maxScrollY);
- RegisterForGraphicUpdate ();
- }
- }
- /// <summary> Mouse Wheel Scrolling multiplier </summary>
- [DefaultValue(1)]
- public virtual int MouseWheelSpeed {
- get => mouseWheelSpeed;
- set {
- if (mouseWheelSpeed == value)
- return;
-
- mouseWheelSpeed = value;
-
- NotifyValueChangedAuto (mouseWheelSpeed);
- }
- }
- }
-}
-
-
+++ /dev/null
-// Copyright (c) 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.Threading;
-using Crow;
-using Crow.Cairo;
-using IML = Crow.IML;
-
-namespace CECrowDebugLog
-{
- public class DebugInterface : Interface {
- static DebugInterface() {
- DbgLogger.IncludeEvents = DbgEvtType.None;
- DbgLogger.DiscardEvents = DbgEvtType.None;
- DbgLogger.ConsoleOutput = false;
- Interface.MaxLayoutingTries = 3;
- Interface.MaxDiscardCount = 25;
- }
- public DebugInterface (IntPtr hWin) : base (100, 100, hWin)
- {
- SolidBackground = false;
- surf = new ImageSurface (Format.Argb32, 100, 100);
- }
-
- public override void Run()
- {
- Init();
-
- Thread t = new Thread (interfaceThread) {
- IsBackground = true
- };
- t.Start ();
- }
- public bool Terminate;
- string source;
- Action delRegisterForRepaint;//call RegisterForRepaint in the container widget (DebugInterfaceWidget)
- Action<Exception> delSetCurrentException;
- //Func<object> delGetScreenCoordinate;
-
- void interfaceThread () {
- while (!Terminate) {
- try
- {
- Update();
- }
- catch (System.Exception ex)
- {
- while (Monitor.IsEntered(LayoutMutex)) {
- Console.WriteLine ($"[DebugIFace] trying to exit LayoutMutex on error");
- Monitor.Exit (LayoutMutex);
- }
- while (Monitor.IsEntered(UpdateMutex)) {
- Console.WriteLine ($"[DebugIFace] trying to exit UpdateMutex on error");
- Monitor.Exit (UpdateMutex);
- }
- while (Monitor.IsEntered(ClippingMutex)) {
- Console.WriteLine ($"[DebugIFace] trying to exit ClippingMutex on error");
- Monitor.Exit (ClippingMutex);
- }
-
-
- /*while (Monitor.IsEntered(LayoutMutex))
- Monitor.Exit (LayoutMutex);
- while (Monitor.IsEntered(UpdateMutex))
- Monitor.Exit (UpdateMutex);
- while (Monitor.IsEntered(ClippingMutex))
- Monitor.Exit (ClippingMutex);*/
- delSetCurrentException (ex);
- Console.WriteLine ($"[DbgIFace] {ex}");
- ClearInterface();
- Thread.Sleep(1000);
- }
-
- /*if (IsDirty)
- delRegisterForRepaint(); */
-
- Thread.Sleep (UPDATE_INTERVAL);
- }
- }
- public IntPtr SurfacePointer {
- get {
- lock(UpdateMutex)
- return surf.Handle;
- }
- }
- public void RegisterDebugInterfaceCallback (object w){
- Type t = w.GetType();
- //delRegisterForRepaint = (Action)Delegate.CreateDelegate(typeof(Action), w, t.GetMethod("RegisterForRepaint"));
- delSetCurrentException = (Action<Exception>)Delegate.CreateDelegate(typeof(Action<Exception>), w, t.GetProperty("CurrentException").GetSetMethod());
- //delGetScreenCoordinate = (Func<object>)Delegate.CreateDelegate(typeof(Func<object>), w, t.GetMethod("GetScreenCoordinates"));
- }
- /*public void ResetDirtyState () {
- IsDirty = false;
- }*/
- public string Source {
- set {
- if (source == value)
- return;
- source = value;
- if (string.IsNullOrEmpty(source))
- return;
- delSetCurrentException(null);
- try
- {
- lock (UpdateMutex) {
- Widget tmp = CreateITorFromIMLFragment (source).CreateInstance();
- ClearInterface();
- AddWidget (tmp);
- tmp.DataSource = this;
- }
- }
- catch (IML.InstantiatorException iTorEx)
- {
- delSetCurrentException(iTorEx.InnerException);
- }
- catch (System.Exception ex)
- {
- delSetCurrentException(ex);
- }
- }
- }
- public void ReloadIml () {
- if (string.IsNullOrEmpty (source))
- return;
- string src = source;
- Source = null;
- Source = src;
- }
- public void Resize (int width, int height) {
-
- lock (UpdateMutex) {
- clientRectangle = new Rectangle (0, 0, width, height);
- surf?.Dispose();
- surf = new ImageSurface (Format.Argb32, width, height);
- foreach (Widget g in GraphicTree)
- g.RegisterForLayouting (LayoutingType.All);
- RegisterClip (clientRectangle);
- }
- }
- /*public override void ForceMousePosition()
- {
- Point p = (Point)delGetScreenCoordinate();
- Glfw.Glfw3.SetCursorPosition (WindowHandle, p.X + MousePosition.X, p.Y + MousePosition.Y);
- }*/
- }
-}
\ No newline at end of file
+++ /dev/null
-// Copyright (c) 2013-2019 Bruyère Jean-Philippe <jp_bruyere@hotmail.com>
-//
-// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
-
-using System;
-using Glfw;
-using System.Reflection;
-using System.Runtime.Loader;
-using System.IO;
-using Crow.Cairo;
-using System.Diagnostics;
-using System.Collections.Generic;
-using Crow.DebugLogger;
-using System.Linq;
-using CrowEditBase;
-using System.Threading;
-using Crow.Text;
-using System.Runtime.InteropServices;
-
-using static CrowEditBase.CrowEditBase;
-
-namespace Crow
-{
- public class DebugInterfaceWidget : Widget {
- CrowService crowIFaceService;
- public CrowService CrowIFaceService {
- get => crowIFaceService;
- set {
- if (crowIFaceService == value)
- return;
- crowIFaceService = value;
- NotifyValueChangedAuto (crowIFaceService);
- }
- }
- public DebugInterfaceWidget () : base () {
- Thread t = new Thread (backgroundThreadFunc);
- t.IsBackground = true;
- t.Start ();
- }
- protected void backgroundThreadFunc () {
- Stopwatch sw = Stopwatch.StartNew ();
- int refreshRate = crowIFaceService == null ? 10 : crowIFaceService.RefreshRate;
- while (true) {
- if (sw.ElapsedMilliseconds > 200) {
- if (Document != null && document.TryGetState (this, out List<TextChange> changes)) {
- foreach (TextChange tc in changes)
- updateIMLSource (tc);
- }
- refreshRate = crowIFaceService == null ? 10 : crowIFaceService.RefreshRate;
- sw.Restart ();
- }
- if (crowIFaceService != null && crowIFaceService.GetDirtyState)
- RegisterForRepaint ();
- Thread.Sleep (refreshRate);
- }
- }
- void updateIMLSource (TextChange change) {
- ReadOnlySpan<char> src = imlSource.AsSpan ();
- Span<char> tmp = stackalloc char[src.Length + (change.ChangedText.Length - change.Length)];
- //Console.WriteLine ($"{Text.Length,-4} {change.Start,-4} {change.Length,-4} {change.ChangedText.Length,-4} tmp:{tmp.Length,-4}");
- src.Slice (0, change.Start).CopyTo (tmp);
- change.ChangedText.AsSpan ().CopyTo (tmp.Slice (change.Start));
- src.Slice (change.End).CopyTo (tmp.Slice (change.Start + change.ChangedText.Length));
-
- imlSource = tmp.ToString ();
-
- crowIFaceService?.LoadIML (imlSource);
-
- RegisterForRedraw ();
- }
- string imlSource;
-
- TextDocument document;
- public TextDocument Document {
- get => document;
- set {
- if (document == value)
- return;
-
- document?.UnregisterClient (this);
- imlSource = "";
- document = value;
- document?.RegisterClient (this);
-
- NotifyValueChangedAuto (document);
- RegisterForGraphicUpdate ();
- }
- }
-
- protected override void onInitialized(object sender, EventArgs e)
- {
- base.onInitialized(sender, e);
-
-
- CrowIFaceService = App.GetService<CrowService> ();
- crowIFaceService?.Start ();
- }
- /*public CommandGroup LoggerCommands =>
- new CommandGroup(
- new Command("Get logs", () => getLog ()),
- //new Command("Reset logs", () => delResetDebugger ()),
- new Command("Save to file", () => saveLogToDebugLogFilePath ()),
- new Command("Load from file", () => loadLogFromDebugLogFilePath ())
- );*/
- public CommandGroup WindowCommands => new CommandGroup (
- crowIFaceService.CMDRefresh,
- crowIFaceService.CMDStartRecording,
- crowIFaceService.CMDStopRecording,
- crowIFaceService.CMDOpenConfig,
- (Parent.LogicalParent as DockWindow).CMDClose
- );
-
-
- protected override void onDraw(Context gr)
- {
- Console.WriteLine("onDraw");
- gr.SetSource(Colors.RoyalBlue);
- gr.Paint();
- }
- public override bool CacheEnabled { get => true; set => base.CacheEnabled = true; }
-
- public override void onKeyDown(object sender, KeyEventArgs e) => crowIFaceService?.onKeyDown(e);
- public override void onKeyUp(object sender, KeyEventArgs e) => crowIFaceService?.onKeyUp(e);
- public override void onKeyPress(object sender, KeyPressEventArgs e) => crowIFaceService?.onKeyPress(e);
- public override void onMouseMove(object sender, MouseMoveEventArgs e) {
- Point m = ScreenPointToLocal (e.Position);
- crowIFaceService?.onMouseMove(new MouseMoveEventArgs(m.X,m.Y, e.XDelta, e.YDelta));
- }
- public override void onMouseDown(object sender, MouseButtonEventArgs e) => crowIFaceService?.onMouseDown(e);
- public override void onMouseUp(object sender, MouseButtonEventArgs e) => crowIFaceService?.onMouseUp(e);
- public override void onMouseWheel(object sender, MouseWheelEventArgs e) => crowIFaceService?.onMouseWheel(e);
-
- protected override void RecreateCache()
- {
- bmp?.Dispose ();
-
- if (crowIFaceService != null && crowIFaceService.IsRunning) {
- crowIFaceService.Resize (Slot.Width, Slot.Height);
- bmp = Crow.Cairo.Surface.Lookup (crowIFaceService.SurfacePointer, false);
- } else
- bmp = IFace.surf.CreateSimilar (Content.ColorAlpha, Slot.Width, Slot.Height);
-
- IsDirty = false;
- }
- protected override void UpdateCache(Context ctx)
- {
- if (bmp != null) {
- paintCache (ctx, Slot + Parent.ClientRectangle.Position);
- crowIFaceService?.ResetDirtyState ();
- }
- }
-
-
- protected override void Dispose(bool disposing)
- {
- crowIFaceService?.Stop ();
- base.Dispose(disposing);
- }
-
- }
-}
\ No newline at end of file
+++ /dev/null
-<?xml version="1.0"?>
-<Border Background="{./Background}" MinimumSize="50,20" Name="Content"
- Foreground="Transparent" CornerRadius="{../CornerRadius}" BorderWidth="1"
- MouseEnter="{Foreground=vgradient|0:White|0.2:Grey|0.9:Grey|1:Black};{caption.Foreground=White}"
- MouseLeave="{Foreground=Transparent};{caption.Foreground=LightGrey}"
- MouseDown="{Foreground=vgradient|0:Black|0.05:Grey|0.85:Grey|1:White}"
- MouseUp="{Foreground=vgradient|0:White|0.2:Grey|0.9:Grey|1:Black}">
- <HorizontalStack Margin="2">
- <Image Style="Icon" Path="{./Icon}"/>
- <Label Font="{./Font}" Name="caption" Margin="3" Foreground="LightGrey" Text="{./Caption}"/>
- </HorizontalStack>
-</Border>
\ No newline at end of file
+++ /dev/null
-<Label Font="{./Font}" Text="{./Caption}" Width="Stretched"
- Margin="5"
- Background="{./Background}"
- Foreground="DimGrey"
- TextAlignment="Center"
- MouseEnter="{Foreground=White}"
- MouseLeave="{Foreground=DimGrey}"/>
\ No newline at end of file
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8" ?>
-<ItemTemplate Data="Events">
- <ListItem Height="Fit"
- Selected="{/exp.Background=${ControlHighlight}}"
- Unselected="{/exp.Background=Transparent}">
- <Expandable Name="exp" Caption="{type}" MouseDoubleClick="/onClickForExpand" CacheEnabled="true" BubbleMouseEvent="All">
- <Template>
- <VerticalStack>
- <Border CornerRadius="2" Margin="0" Height="Fit" MouseDoubleClick="./onClickForExpand"
- Foreground="Transparent"
- Background="{./Background}"
- MouseEnter="{Foreground=DimGrey}"
- MouseLeave="{Foreground=Transparent}">
- <HorizontalStack Spacing="2" >
- <Image Margin="1" Width="9" Height="9" Focusable="true" MouseDown="./onClickForExpand"
- Path="{./Image}"
- Visible="{HasChildEvents}"
- SvgSub="{./IsExpanded}"
- MouseEnter="{Background=LightGrey}"
- MouseLeave="{Background=Transparent}"/>
- <Label Text="{./Caption}" Width="80" Font="mono, 8" />
- <Label Text="{DurationMS}" Width="40" Font="mono, 8" TextAlignment="Center" Background="DimGrey"/>
- <DbgEventWidget Event="{}" Tooltip="#CECrowDebugLog.ui.DbgEvtTooltip.crow" Width="Stretched" Height="5"/>
- </HorizontalStack>
- </Border>
- <Container Name="Content" Visible="false"/>
- </VerticalStack>
- </Template>
- <HorizontalStack Height="Fit">
- <Widget Width="12" Height="10"/>
- <VerticalStack Height="Fit" Name="ItemsContainer"/>
- </HorizontalStack>
- </Expandable>
- </ListItem>
-</ItemTemplate>
-<ItemTemplate Data="Events" DataType="DbgWidgetEvent">
- <ListItem Height="Fit"
- Selected="{/exp.Background=${ControlHighlight}}"
- Unselected="{/exp.Background=Transparent}">
- <Expandable Name="exp" Caption="{type}" MouseDoubleClick="/onClickForExpand" CacheEnabled="true" BubbleMouseEvent="All">
- <Template>
- <VerticalStack>
- <Border CornerRadius="2" Margin="0" Height="Fit" MouseDoubleClick="./onClickForExpand"
- Foreground="Transparent"
- Background="{./Background}"
- MouseEnter="{Foreground=DimGrey}"
- MouseLeave="{Foreground=Transparent}">
- <HorizontalStack Spacing="2" >
- <Image Margin="1" Width="9" Height="9" Focusable="true" MouseDown="./onClickForExpand"
- Path="{./Image}"
- Visible="{HasChildEvents}"
- SvgSub="{./IsExpanded}"
- MouseEnter="{Background=LightGrey}"
- MouseLeave="{Background=Transparent}"/>
- <Label Text="{./Caption}" Width="80" Font="mono, 8" />
- <Label Text="{DurationMS}" Width="40" Font="mono, 8" TextAlignment="Center" Background="DimGrey"/>
- <Label Text="{InstanceIndex}" Width="40" Font="mono, 8" TextAlignment="Center" Background="DimGrey"/>
- <DbgEventWidget Event="{}" Tooltip="#CECrowDebugLog.ui.DbgEvtTooltip.crow" Width="Stretched" Height="5"/>
- </HorizontalStack>
- </Border>
- <Container Name="Content" Visible="false"/>
- </VerticalStack>
- </Template>
- <HorizontalStack Height="Fit">
- <Widget Width="12" Height="10"/>
- <VerticalStack Height="Fit" Name="ItemsContainer"/>
- </HorizontalStack>
- </Expandable>
- </ListItem>
-</ItemTemplate>
\ No newline at end of file
+++ /dev/null
-<?xml version="1.0"?>
-<VerticalStack Margin="${TooltipMargin}" DataSource="{./Event}">
- <Label Text="{type}" Background="{Color}" Foreground="Black" Width="200" TextAlignment="Center" Margin="6"/>
- <HorizontalStack Height="Fit" Width="Stretched" Spacing="2" Visible="{IsWidgetEvent}" Background="DimGrey" Margin="2">
- <Label Text="Instance:" Foreground="White" Width="50%" />
- <Label Text="{InstanceIndex}" Foreground="White" Background="Onyx" Width="Stretched" TextAlignment="Center"/>
- </HorizontalStack>
- <Label Text="{Message}" Foreground="White" Background="Onyx" Width="Stretched" Visible="{HasMessage}" Margin="2" Tooltip="{}"/>
- <HorizontalStack Height="Fit" Width="Stretched" Spacing="2" Background="DimGrey" Margin="2">
- <Label Text="Duration(ms):" Foreground="White" Width="50%" />
- <Label Text="{DurationMS}" Foreground="White" Background="Onyx" Width="Stretched" TextAlignment="Right"/>
- </HorizontalStack>
- <HorizontalStack Height="Fit" Width="Stretched" Spacing="2">
- <Label Text="Begin(s):" Foreground="${TooltipForeground}" Width="50%"/>
- <Label Text="{BeginMS}" Foreground="${TooltipForeground}" Width="Stretched" TextAlignment="Right"/>
- </HorizontalStack>
- <HorizontalStack Height="Fit" Width="Stretched" Spacing="2">
- <Label Text="End(s):" Foreground="${TooltipForeground}" Width="50%"/>
- <Label Text="{EndMS}" Foreground="${TooltipForeground}" Width="Stretched" TextAlignment="Right"/>
- </HorizontalStack>
- <VerticalStack Height="Fit" Width="Stretched" IsVisible="{IsLayoutEvent}" >
- <HorizontalStack Height="Fit" Width="Stretched" Spacing="2" Background="DimGrey" Margin="2">
- <Label Text="Layout:" Foreground="White" Width="50%" />
- <Label Text="{layouting}" Foreground="White" Background="Onyx" Width="Stretched" TextAlignment="Center"/>
- </HorizontalStack>
- <HorizontalStack Height="Fit" Width="Stretched" Spacing="2" Background="DimGrey" Margin="2">
- <Label Text="Result:" Foreground="White" Width="50%" />
- <Label Text="{result}" Foreground="White" Background="Onyx" Width="Stretched" TextAlignment="Center"/>
- </HorizontalStack>
- <HorizontalStack Height="Fit" Width="Stretched" Spacing="2" Background="DimGrey" Margin="2">
- <Label Text="Old Slot:" Foreground="White" Width="50%" />
- <Label Text="{OldSlot}" Foreground="White" Background="Onyx" Width="Stretched" TextAlignment="Center"/>
- </HorizontalStack>
- <HorizontalStack Height="Fit" Width="Stretched" Spacing="2" Background="DimGrey" Margin="2">
- <Label Text="New Slot:" Foreground="White" Width="50%" />
- <Label Text="{NewSlot}" Foreground="White" Background="Onyx" Width="Stretched" TextAlignment="Center"/>
- </HorizontalStack>
- </VerticalStack>
- <DbgEventWidget Height="10" Width="Stretched" Event="{}" Tooltip="#CECrowDebugLog.ui.DbgEvtTooltip.crow" />
- <GroupBox Caption="Parent Event" Height="Fit" >
- <DbgEventWidget Height="10" Width="Stretched" Event="{parentEvent}" Tooltip="#CECrowDebugLog.ui.DbgEvtTooltip.crow" />
- </GroupBox>
- <!--<Label Text="{}" Foreground="${TooltipForeground}"/>-->
-</VerticalStack>
\ No newline at end of file
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8" ?>
-<Border Fit="true" Foreground="${TooltipForeground}" Background="${TooltipBackground}">
- <VerticalStack Fit="true" Margin="${TooltipMargin}" DataSource="{HoverEvent}">
- <Label Text="{type}" Background="{Color}" Foreground="Black" Width="200" TextAlignment="Center" Margin="6"/>
- <HorizontalStack Height="Fit" Width="Stretched" Spacing="2" Visible="{IsWidgetEvent}" Background="DimGrey" Margin="2">
- <Label Text="Instance:" Foreground="White" Width="50%" />
- <Label Text="{InstanceIndex}" Foreground="White" Background="Onyx" Width="Stretched" TextAlignment="Center"/>
- </HorizontalStack>
- <Label Text="{Message}" Foreground="White" Background="Onyx" Width="Stretched" Visible="{HasMessage}" Margin="2" Tooltip="{}"/>
- <HorizontalStack Height="Fit" Width="Stretched" Spacing="2" Background="DimGrey" Margin="2">
- <Label Text="Duration:" Foreground="White" Width="50%" />
- <Label Text="{DurationMS}" Foreground="White" Background="Onyx" Width="Stretched" TextAlignment="Right"/>
- </HorizontalStack>
- <HorizontalStack Height="Fit" Width="Stretched" Spacing="2">
- <Label Text="Begin:" Foreground="${TooltipForeground}" Width="50%"/>
- <Label Text="{BeginMS}" Foreground="${TooltipForeground}" Width="Stretched" TextAlignment="Right"/>
- </HorizontalStack>
- <HorizontalStack Height="Fit" Width="Stretched" Spacing="2">
- <Label Text="End:" Foreground="${TooltipForeground}" Width="50%"/>
- <Label Text="{EndMS}" Foreground="${TooltipForeground}" Width="Stretched" TextAlignment="Right"/>
- </HorizontalStack>
- <VerticalStack Height="Fit" Width="Stretched" IsVisible="{IsLayoutEvent}" >
- <HorizontalStack Height="Fit" Width="Stretched" Spacing="2" Background="DimGrey" Margin="2">
- <Label Text="Layout:" Foreground="White" Width="50%" />
- <Label Text="{layouting}" Foreground="White" Background="Onyx" Width="Stretched" TextAlignment="Center"/>
- </HorizontalStack>
- <HorizontalStack Height="Fit" Width="Stretched" Spacing="2" Background="DimGrey" Margin="2">
- <Label Text="Result:" Foreground="White" Width="50%" />
- <Label Text="{result}" Foreground="White" Background="Onyx" Width="Stretched" TextAlignment="Center"/>
- </HorizontalStack>
- <HorizontalStack Height="Fit" Width="Stretched" Spacing="2" Background="DimGrey" Margin="2">
- <Label Text="Old Slot:" Foreground="White" Width="50%" />
- <Label Text="{OldSlot}" Foreground="White" Background="Onyx" Width="Stretched" TextAlignment="Center"/>
- </HorizontalStack>
- <HorizontalStack Height="Fit" Width="Stretched" Spacing="2" Background="DimGrey" Margin="2">
- <Label Text="New Slot:" Foreground="White" Width="50%" />
- <Label Text="{NewSlot}" Foreground="White" Background="Onyx" Width="Stretched" TextAlignment="Center"/>
- </HorizontalStack>
- </VerticalStack>
- <!--<Label Text="{}" Foreground="${TooltipForeground}"/>-->
- </VerticalStack>
-</Border>
\ No newline at end of file
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8" ?>
-<ListItem Height="Fit"
- Selected="{Background=${ControlHighlight}}"
- Unselected="{Background=Transparent}">
- <HorizontalStack Spacing="2" >
- <Label Text="{BeginMS}" Width="70" TextAlignment="Right" Background="DimGrey"/>
- <Label Text="{type}" Width="160" Background="{Color}" Foreground="Black"/>
- <Label Text="{Message}" Width="Stretched" />
- <Label Text="{DurationMS}" Width="70" TextAlignment="Right" Background="DimGrey"/>
- </HorizontalStack>
-</ListItem>
+++ /dev/null
-<?xml version="1.0"?>
-<Window Caption="Debug Log" Background="0.05,0.05,0.1,0.9" Width="80%" Height="80%">
- <VerticalStack>
- <TabView>
- <VerticalStack Name="LogGraph" Background="DarkGrey">
- <EnumSelector RadioButtonStyle="CheckBox2" Template="#CECrowDebugLog.ui.EnumSelector.template"
- Caption="Discarded Events" EnumValue="{²../dbv.Filter}" BitFieldExcludeMask="255" />
- <HorizontalStack>
- <DbgLogViewer Visible="true" Name="dbv" Events="{Events}" Widgets="{Widgets}"
- CurrentEvent="{²CurrentEvent}" CurrentWidget="{²CurrentWidget}" />
- <ScrollBar Maximum="{../dbv.MaxScrollY}" Value="{²../dbv.ScrollY}" SmallIncrement="1" LargeIncrement="10"
- CursorRatio="{../dbv.ChildHeightRatio}"/>
- </HorizontalStack>
- <ScrollBar Style="HScrollBar" Maximum="{../dbv.MaxScrollX}" Value="{²../dbv.ScrollX}" SmallIncrement="1" LargeIncrement="10"
- CursorRatio="{../dbv.ChildWidthRatio}"/>
- <HorizontalStack Height="Fit" DataSource="{CurrentWidget}" Spacing="3">
- <Label Style="smallLabValue" Text="{name}"/>
- <Label Style="smallLabValue" Text="{listIndex}" Tooltip="List index"/>
- <Label Style="smallLabValue" Text="{treeIndex}" Tooltip="tree index"/>
- <Label Style="smallLabValue" Text="{yIndex}" Tooltip="yIndex"/>
- <Label Style="smallLabValue" Text="{xLevel}" Tooltip="xLevel"/>
- <Label Style="smallLabCaption" Text="Width:"/>
- <Label Style="smallLabValue" Text="{Width}"/>
- <Label Style="smallLabCaption" Text="Height:" />
- <Label Style="smallLabValue" Text="{Height}"/>
- <Label Style="smallLabCaption" Text="ScrollX:" />
- <Label Style="smallLabValue" Text="{../../dbv.ScrollX}"/>
- <Label Style="smallLabCaption" Text="MaxScrollX:" />
- <Label Style="smallLabValue" Text="{../../dbv.MaxScrollX}"/>
- <Label Style="smallLabValue" Tooltip="XScale" Text="{../../dbv.XScale}"/>
- <Label Style="smallLabValue" Tooltip="VisibleTicks" Text="{../../dbv.VisibleTicks}"/>
- </HorizontalStack>
- </VerticalStack>
- <VerticalStack Name="AllEvents" Width="Stretched" IsVisible="false">
- <TreeView Height="Stretched" Name="dbgTV" Data="{Events}" SelectedItem="{²CurrentEvent}" Background="DarkGrey"
- ItemTemplate="#CECrowDebugLog.ui.DbgEventTreeItems.itemp"/>
- <ListBox Data="{CurWidgetEvents}" Height="100" SelectedItem="{²CurrentEvent}">
- <ItemTemplate>
- <ListItem Margin="0" Height="16" Width="Fit"
- Selected="{Background=${ControlHighlight}}"
- Unselected="{Background=Transparent}">
- <DbgEventWidget Height="10" Width="Fit" Event="{}" Tooltip="#CECrowDebugLog.ui.DbgEvtTooltip.crow" TicksPerPixel="20" VerticalAlignment="Center"/>
- </ListItem>
- </ItemTemplate>
- <Template>
- <Wrapper Name="ItemsContainer" Spacing="1" Background="DarkGrey"/>
- </Template>
- </ListBox>
- </VerticalStack>
- <VerticalStack Name="CurWidgetEvents" Width="Stretched" IsVisible="false">
- <TreeView Height="Stretched" Data="{CurrentWidgetEvents}" Background="DarkGrey"
- ItemTemplate="#CECrowDebugLog.ui.DbgWidgetEventTreeItems.itemp"/>
- </VerticalStack>
- </TabView>
- <Splitter/>
- <HorizontalStack Height="30%">
- <ListBox Data="{Widgets}" Width="200" SelectedItem="{²CurrentWidget}"
- ItemTemplate="#CECrowDebugLog.ui.WidgetRecord.itemp">
- </ListBox>
- <Splitter/>
- <VerticalStack>
- <HorizontalStack Height="Fit" Background="Onyx" Spacing="5">
- <Label Text="{CurrentWidget}"/>
- <Label Text="events"/>
- </HorizontalStack>
- <ListBox Data="{CurrentWidgetEvents}" Background="Black" SelectedItem="{²CurrentEvent}">
- <ItemTemplate>
- <ListItem Margin="0" Height="16" IsSelected="{²IsSelected}" Width="Fit"
- Selected="{Background=${ControlHighlight}}" Template="Crow.ScrollingListBox.template"
- Unselected="{Background=Transparent}">
- <DbgEventWidget Height="10" Width="Fit" Event="{}" Tooltip="#CECrowDebugLog.ui.DbgEvtTooltip.crow" TicksPerPixel="50" VerticalAlignment="Center"/>
- </ListItem>
- </ItemTemplate>
- <Template>
- <Wrapper Name="ItemsContainer" Spacing="1" Background="{./Background}"/>
- </Template>
- </ListBox>
- <!--<TreeView Data="{Events}" SelectedItem="{²CurrentEvent}" Background="DarkGrey"
- ItemTemplate="#Dbg.DbgEventTreeItems.itemp"/>-->
- </VerticalStack>
- <Splitter/>
- <DbgEventView Template="#CECrowDebugLog.ui.DbgEventView.template" Event="{../../dbv.HoverEvent}"/>
- <Splitter/>
- <DbgEventView Template="#CECrowDebugLog.ui.DbgEventView.template" Event="{CurrentEvent}"/>
- </HorizontalStack>
- <HorizontalStack Height="Fit" Background="Onyx" Margin="1">
- <HorizontalStack Height="Fit" DataSource="{CurrentEvent}">
- <Label Foreground="Black" Text="Current Event:" Background="{Color}" Margin="2" />
- <DbgEventWidget Height="14" Width="Stretched" Event="{}" Tooltip="#Dbg.DbgEvtTooltip.crow" />
- </HorizontalStack>
- <Menu Fit="true" Data="{EventCommands}">
- <ItemTemplate>
- <Button Command="{}"/>
- </ItemTemplate>
- </Menu>
- <Popper Caption="Search...">
- <VerticalStack Fit="true" Background="Onyx" Margin="10">
- <ComboBox Caption="Event Type" Data="{AllEventTypes}" SelectedItem="{²SearchEventType}"/>
- <ComboBox Caption="Widget" Data="{Widgets}" SelectedItem="{²SearchWidget}"/>
- </VerticalStack>
- </Popper>
- </HorizontalStack>
- </VerticalStack>
-</Window>
\ No newline at end of file
+++ /dev/null
-<?xml version="1.0"?>
-<Popper >
- <Template>
- <HorizontalStack Background="{../../Background}" Margin="5" Spacing="10">
- <Label Text="{../../../Caption}" Width="Stretched"/>
- <Label Background="SeaGreen" Text="{../../../EnumValue}" Margin="3"/>
- </HorizontalStack>
- </Template>
- <Wrapper Name="Content" Height="Fit" Width="420" Background="Jet" Orientation="Vertical" />
-</Popper>
\ No newline at end of file
+++ /dev/null
-<ListItem Height="Fit" Margin="1" Focusable="true" HorizontalAlignment="Left"
- Selected = "{Background=${ControlHighlight}}"
- Unselected = "{Background=Transparent}">
- <HorizontalStack>
- <Label Text="{name}" Width="Stretched"/>
- <Label Style="labWidgetRecordList" Text="{listIndex}" Tooltip="List index"/>
- <Label Style="labWidgetRecordList" Text="{treeIndex}" Tooltip="tree index"/>
- <Label Style="labWidgetRecordList" Text="{yIndex}" Tooltip="yIndex"/>
- <Label Style="labWidgetRecordList" Text="{xLevel}" Tooltip="xLevel"/>
- </HorizontalStack>
-</ListItem>
\ No newline at end of file
+++ /dev/null
-IcoButton {
- Template = "#CECrowDebugLog.ui.Button.template";
- Background = "Onyx";
-}
-CheckBox2 {
- Template= "#CECrowDebugLog.ui.CheckBox2.imlt";
- Background = "Jet";
- Checked="{Background=MediumSeaGreen}";
- Unchecked = "{Background=Jet}";
- Width = "200";
-}
-smallLabCaption {
- Font="mono, 8";
- Foreground="Grey";
-}
-smallLabValue {
- Font="mono, 10";
- Foreground="White";
-}
-DbgLogViewer {
- MouseWheelSpeed="3";
- Font="mono, 8";
- Background="Onyx";
- CacheEnabled = "true";
-}
-DbgEventView {
- Height="Fit";
- Width="150";
-}
-labWidgetRecordList {
- Font="mono, 11";
- Background="Grey";
- Foreground="Jet";
- Margin="0";
- Width="24";
- TextAlignment="Right";
-}
-
-DbgEventWidget {
- CacheEnabled = "true";
-}
\ No newline at end of file
+++ /dev/null
-<Window Width="80%" Movable="false">
- <VerticalStack>
- <HorizontalStack Height="Fit">
- <Label Text="Hover:" Width="50" Foreground="Grey"/>
- <Label Text="{HoverWidget}" Font="mono, 8"/>
- </HorizontalStack>
- <HorizontalStack Height="Fit">
- <Label Text="Focus:" Width="50" Foreground="Grey"/>
- <Label Text="{FocusedWidget}" Font="mono, 8"/>
- </HorizontalStack>
- <HorizontalStack Height="Fit">
- <Label Text="Active:" Width="50" Foreground="Grey"/>
- <Label Text="{ActiveWidget}" Font="mono, 8"/>
- </HorizontalStack>
- </VerticalStack>
-</Window>
-
+++ /dev/null
-<?xml version="1.0"?>
-<VerticalStack Background="DarkGrey">
- <HorizontalStack >
- <TabView Width="25%" >
- <VerticalStack Name="Explorer" Background="Onyx">
- <HorizontalStack Height="Fit" Margin="2" >
- <Image Margin="2" Width="16" Height="16" Path="#Crow.Icons.level-up.svg" MouseClick="goUpDirClick"
- Background="Jet" MouseEnter="{Background=Grey}" MouseLeave="{Background=Jet}" />
- <TextBox Text="{²CurrentDir}" Margin="2"/>
- </HorizontalStack>
- <DirectoryView Margin="1" Name="dv" CurrentDirectory="{CurrentDir}" SelectedItemChanged="Dv_SelectedItemChanged">
- <Template>
- <TreeView IsRoot="true" Name="treeView" Data="{./FileSystemEntries}" Background="{./Background}"
- SelectedItemChanged="./onSelectedItemChanged">
- <ItemTemplate DataType="System.IO.FileInfo">
- <ListItem CornerRadius="2" Margin="0" Height="Fit" Width="Stretched"
- ContextCommands="{GetCommands}"
- Selected="{Background=${ControlHighlight}}"
- Unselected="{Background=Transparent}">
- <HorizontalStack>
- <Image Margin="1" Width="14" Height="14" Path="#Crow.Icons.file.svg"/>
- <Label Text="{Name}" Width="Stretched"/>
- </HorizontalStack>
- </ListItem>
- </ItemTemplate>
- <ItemTemplate DataType="System.IO.DirectoryInfo" Data="GetFileSystemInfosOrdered">
- <ListItem ContextCommands="{GetCommands}"
- Selected="{/exp.Background=${ControlHighlight}}"
- Unselected="{/exp.Background=Transparent}">
- <Expandable Name="exp" Caption="{Name}" MouseDoubleClick="/onClickForExpand">
- <Template>
- <VerticalStack>
- <Border CornerRadius="2" Margin="0" Height="Fit" MouseDoubleClick="./onClickForExpand"
- Foreground="Transparent"
- MouseEnter="{Foreground=DimGrey}"
- MouseLeave="{Foreground=Transparent}">
- <HorizontalStack Background="{./Background}" Spacing="1">
- <Image Margin="1" Width="9" Height="9" Focusable="true" MouseDown="./onClickForExpand"
- Path="{./Image}"
- Visible="{./IsExpandable}"
- SvgSub="{./IsExpanded}"
- MouseEnter="{Background=LightGrey}"
- MouseLeave="{Background=Transparent}"/>
- <Image Margin="1" Width="16" Height="16"
- Path="#Crow.Icons.folder.svg" SvgSub="{./IsExpanded}"/>
- <Label Text="{./Caption}"/>
- </HorizontalStack>
- </Border>
- <Container Name="Content" Visible="false"/>
- </VerticalStack>
- </Template>
- <HorizontalStack Height="Fit">
- <Widget Width="12" Height="10"/>
- <VerticalStack Height="Fit" Name="ItemsContainer"/>
- </HorizontalStack>
- </Expandable>
- </ListItem>
- </ItemTemplate>
- </TreeView>
- </Template>
- </DirectoryView>
- </VerticalStack>
- <VerticalStack Name="DebugLogger" Margin="5" IsVisible="false" Background="Onyx">
- <HorizontalStack Height="Fit">
- <Image Width="30" Height="20" Path="#Crow.Icons.IconAlerte.svg" Visible="{../../../../dbgIfaceWidget.CrowDebuggerNOK}"/>
- <Label Fit="true" Text="Crow debug assembly path:"/>
- <Widget Width="5" Height="5" Background="SeaGreen" IsVisible="{../../../../dbgIfaceWidget.HasFocus}"/>
- <Widget Width="5" Height="5" Background="Yellow" IsVisible="{../../../../dbgIfaceWidget.IsHover}"/>
- <TextBox Text="{²CrowDbgAssemblyLocation}" Margin="2"/>
- </HorizontalStack>
- <Label Background="Red" Foreground="White" Margin="5" Width="Stretched" Text="{../../../dbgIfaceWidget.CrowDebuggerErrorMessage}"
- IsVisible="{../../../dbgIfaceWidget.CrowDebuggerNOK}"/>
- <HorizontalStack Height="Fit" Width="Stretched" Background="Onyx" Margin="5">
- <Label Text="Debug log output file:" Fit="true"/>
- <TextBox Text="{²../../../../dbgIfaceWidget.DebugLogFilePath}" />
- </HorizontalStack>
- <EnumSelector RadioButtonStyle="CheckBox2" Template="#Dbg.EnumSelector.template"
- Background="Grey"
- Caption="Recorded Events" EnumValue="{²RecordedEvents}" BitFieldExcludeMask="255" />
- <EnumSelector RadioButtonStyle="CheckBox2" Template="#Dbg.EnumSelector.template"
- Background="Onyx"
- Caption="Discarded Events" EnumValue="{²DiscardedEvents}" BitFieldExcludeMask="255" />
- <CheckBox Caption="Begin recording on startup" IsChecked="{²DebugLogOnStartup}" Background="Onyx"/>
- <HorizontalStack Height="Fit">
- <CheckBox Caption="Recording" IsChecked="{²DebugLogRecording}" Height="40" Width="60"
- Checked="{sh.Path='A 8,8,7.5,0,6.3 O 0.8,0,0,1 f O 0,0,0,0.5 G'}"
- Unchecked="{sh.Path='R 0.5,0.5,15,15 f O 0,0,0,1 G'}">
- <Template>
- <Border Background="Onyx" Margin="10" CornerRadius="5">
- <Shape Name="sh" Foreground="Grey" Size="16,16" Path="R 0.5,0.5,15,15 f O 0,0,0,1 G"/>
- </Border>
- </Template>
- </CheckBox>
- <Menu Data="{../../../../dbgIfaceWidget.LoggerCommands}" Height="Fit" Width="Stretched">
- <Template>
- <Wrapper Orientation="Vertical" Name="ItemsContainer" Margin="0" Background="{./Background}"/>
- </Template>
- <ItemTemplate>
- <Button Command="{}" Height="Fit" Width="Fit"/>
- </ItemTemplate>
- </Menu>
- </HorizontalStack>
- </VerticalStack>
- </TabView>
- <Splitter Width="6" />
- <VerticalStack>
- <DebugInterfaceWidget Name="dbgIfaceWidget" Height="60%" Background="Black" Focusable="true"
- CrowDbgAssemblyLocation="{²CrowDbgAssemblyLocation}"
- Recording="{²DebugLogRecording}"
- IMLSource="{Source}"
- CurrentException="{²CurrentException}"
- DiscardedEvents="{DiscardedEvents}" RecordedEvents="{RecordedEvents}"/>
- <Splitter/>
- <!--<TabView>-->
- <VerticalStack Name="Editor" Spacing="0">
- <HorizontalStack Height="Fit">
- <Button Style="IcoButton" Command="{CMDNew}" />
- <Button Style="IcoButton" Command="{CMDSave}" />
- <Button Style="IcoButton" Command="{CMDSaveAs}" />
- <Button Style="IcoButton" Command="{CMDUndo}" />
- <Button Style="IcoButton" Command="{CMDRedo}" />
- <!--<Button Style="IcoButton" Command="{CMDCut}" />
- <Button Style="IcoButton" Command="{CMDCopy}" />
- <Button Style="IcoButton" Command="{CMDPaste}" />-->
- <Widget Width="Stretched" />
- <Widget Background="Red" IsVisible="{DebugLogRecording}" CornerRadius="10" Width="12" Height="12"/>
- </HorizontalStack>
-
- <HorizontalStack>
- <Editor Name="tb" Text="{Source}" Multiline="true" Font="consolas, 12" Focusable="true" Height="Stretched" Width="Stretched"
- TextChanged="onTextChanged" KeyDown="textView_KeyDown" ContextCommands="{EditorCommands}"
- Foreground="DarkGrey" Background="White"/>
- <!--SelectionChanged="onSelectedTextChanged"-->
- <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" Spacing="10" Background="DarkGrey">
- <Widget Width="10" Height="10" Background="RoyalBlue" Visible="{IsDirty}"/>
- <Label Text="{CurrentFile}" Width="Stretched"/>
- <Widget Width="Stretched"/>
- <Label Text="Line:" Foreground="Grey"/>
- <Label Text="{../../tb.CurrentLine}" Margin="2"/>
- <Label Text="Col:" Foreground="Grey"/>
- <Label Text="{../../tb.CurrentColumn}" Margin="2"/>
- </HorizontalStack>
- <Popper IsVisible="{ShowError}" Background="Red">
- <Template>
- <CheckBox IsChecked="{²./IsPopped}" MouseEnter="{IsChecked='true'}" MouseLeave="{IsChecked='false'}">
- <Template>
- <Label Text="{CurrentExceptionMSG}" Background="Red" Foreground="White" Width="Stretched" Margin="2"
- Multiline="true"/>
- </Template>
- </CheckBox>
- </Template>
- <Label Text="{CurrentException}" Background="DarkRed" Foreground="White" Width="Stretched" Margin="2" Multiline="true"/>
- </Popper>
- </VerticalStack>
-
- <!--</TabView>-->
- </VerticalStack>
- </HorizontalStack>
-</VerticalStack>
\ No newline at end of file
+++ /dev/null
-<?xml version="1.0"?>
-<DockWindow Caption="Crow Preview Configuration" Width="80%" Height="400" Resizable="false">
- <VerticalStack RootDataLevel="true" Margin="5">
- <HorizontalStack Height="Fit" Margin="5">
- <Label Text="Crow Service" Width="Stretched"/>
- <ListBox Data="{Commands}" Fit="true">
- <Template>
- <HorizontalStack Name="ItemsContainer" />
- </Template>
- <ItemTemplate Path="#CrowEditBase.ui.IconCommand.itmp"/>
- </ListBox>
- </HorizontalStack>
- <HorizontalStack Height="Fit">
- <Label Width="200" Text="Crow assembly path:"/>
- <TextBox Width="Stretched" Text="{²CrowDbgAssemblyLocation}"/>
- <Image Width="30" Height="20" Path="#Crow.Icons.IconAlerte.svg" Visible="{ServiceIsInError}"/>
- <Button Command="{CMDOptions_SelectCrowAssemblyLocation}" MinimumSize="0,0"/>
- </HorizontalStack>
- <Label Background="Red" Foreground="White" Margin="5" Width="Stretched" Text="{ServiceErrorMessage}"
- IsVisible="{ServiceIsInError}"/>
- <Spinner Caption="Refresh Rate (ms)" Value="{²RefreshRate}" Maximum="1000"/>
- <Spinner Caption="Max Layout Try" Value="{²MaxLayoutingTries}" Maximum="1000"/>
- <Spinner Caption="Max Layout Discard" Value="{²MaxDiscardCount}" Maximum="1000"/>
- <GroupBox Caption="Debug Logger" IsEnabled="{DebugLogIsEnabled}">
- <VerticalStack>
- <EnumSelector RadioButtonStyle="CheckBox2" Template="#CECrowDebugLog.ui.EnumSelector.template" Width="Stretched"
- Caption="Recorded Events" EnumValue="{²RecordedEvents}" BitFieldExcludeMask="255" />
- <EnumSelector RadioButtonStyle="CheckBox2" Template="#CECrowDebugLog.ui.EnumSelector.template" Width="Stretched"
- Caption="Discarded Events" EnumValue="{²DiscardedEvents}" BitFieldExcludeMask="255" />
- <!--<HorizontalStack Height="Fit">
- <CheckBox Caption="Recording" IsChecked="{²Recording}" Height="24" Width="30"
- Checked="{sh.Path='A 8,8,7.5,0,6.3 O 0.8,0,0,1 f O 0,0,0,0.5 G'}"
- Unchecked="{sh.Path='R 0.5,0.5,15,15 f O 0,0,0,1 G'}">
- <Template>
- <Border Background="Onyx" Margin="2" CornerRadius="5">
- <Shape Name="sh" Foreground="Grey" Size="16,16" Path="R 0.5,0.5,15,15 f O 0,0,0,1 G"/>
- </Border>
- </Template>
- </CheckBox>
- <Menu Data="{LoggerCommands}" Height="Fit" Width="Stretched">
- <Template>
- <Wrapper Orientation="Vertical" Name="ItemsContainer" Margin="0" Background="{./Background}"/>
- </Template>
- <ItemTemplate>
- <Button Command="{}" Height="Fit" Width="Fit"/>
- </ItemTemplate>
- </Menu>
- </HorizontalStack>-->
- </VerticalStack>
- </GroupBox>
- </VerticalStack>
-</DockWindow>
-
-
+++ /dev/null
-<?xml version="1.0"?>
-<DockWindow Caption="Crow Preview" Width="60%" Commands="{/dbgIfaceWidget.WindowCommands}">
- <VerticalStack Background="Black" >
- <DebugInterfaceWidget Name="dbgIfaceWidget" Focusable="true"
- BubbleMouseEvent="None"
- Document="{CurrentDocument}"/>
- <Label DataSource="{../dbgIfaceWidget.CrowIFaceService}" Text="{CurrentException}" Background="DarkRed" Foreground="White"
- IsVisible="{PreviewHasError}"
- Width="Stretched" Margin="2" Multiline="true"/>
- </VerticalStack>
-</DockWindow>
-
-
+++ /dev/null
-<?xml version="1.0"?>
-<Window Caption="Debug Log" Background="0.05,0.05,0.1,0.9" Width="95%" Height="95%">
- <VerticalStack RootDataLevel="true">
- <TabView>
- <VerticalStack Name="LogGraph" Background="DarkGrey">
- <EnumSelector RadioButtonStyle="CheckBox2" Template="#CECrowDebugLog.ui.EnumSelector.template"
- Caption="Discarded Events" EnumValue="{²../dbv.Filter}" BitFieldExcludeMask="255" />
- <HorizontalStack>
- <DbgLogViewer Visible="true" Name="dbv" Events="{Events}" Widgets="{Widgets}"
- CurrentEvent="{²CurrentEvent}" CurrentWidget="{²CurrentWidget}" />
- <ScrollBar Maximum="{../dbv.MaxScrollY}" Value="{²../dbv.ScrollY}" SmallIncrement="1" LargeIncrement="10"
- CursorRatio="{../dbv.ChildHeightRatio}"/>
- </HorizontalStack>
- <ScrollBar Style="HScrollBar" Maximum="{../dbv.MaxScrollX}" Value="{²../dbv.ScrollX}" SmallIncrement="1" LargeIncrement="10"
- CursorRatio="{../dbv.ChildWidthRatio}"/>
- <HorizontalStack Height="Fit" DataSource="{CurrentWidget}" Spacing="3">
- <Label Style="smallLabValue" Text="{name}"/>
- <Label Style="smallLabValue" Text="{listIndex}" Tooltip="List index"/>
- <Label Style="smallLabValue" Text="{treeIndex}" Tooltip="tree index"/>
- <Label Style="smallLabValue" Text="{yIndex}" Tooltip="yIndex"/>
- <Label Style="smallLabValue" Text="{xLevel}" Tooltip="xLevel"/>
- <Label Style="smallLabCaption" Text="Width:"/>
- <Label Style="smallLabValue" Text="{Width}"/>
- <Label Style="smallLabCaption" Text="Height:" />
- <Label Style="smallLabValue" Text="{Height}"/>
- <Label Style="smallLabCaption" Text="ScrollX:" />
- <Label Style="smallLabValue" Text="{../../dbv.ScrollX}"/>
- <Label Style="smallLabCaption" Text="MaxScrollX:" />
- <Label Style="smallLabValue" Text="{../../dbv.MaxScrollX}"/>
- <Label Style="smallLabValue" Tooltip="XScale" Text="{../../dbv.XScale}"/>
- <Label Style="smallLabValue" Tooltip="VisibleTicks" Text="{../../dbv.VisibleTicks}"/>
- </HorizontalStack>
- </VerticalStack>
- <VerticalStack Name="AllEvents" Width="Stretched" IsVisible="false" RootDataLevel="true">
- <TreeView Height="Stretched" Name="dbgTV" Data="{Events}" SelectedItem="{²CurrentEvent}" Background="DarkGrey"
- ItemTemplate="#CECrowDebugLog.ui.DbgEventTreeItems.itemp"/>
- </VerticalStack>
- <VerticalStack Name="CurWidgetEvents" Width="Stretched" IsVisible="false" RootDataLevel="true">
- <ListBox Data="{CurrentWidgetEvents}" Background="Black" SelectedItem="{²CurrentEvent}">
- <ItemTemplate>
- <ListItem Margin="0" Height="16" IsSelected="{²IsSelected}" Width="Fit"
- Selected="{Background=${ControlHighlight}}" Template="Crow.ScrollingListBox.template"
- Unselected="{Background=Transparent}">
- <DbgEventWidget Height="10" Width="Fit" Event="{}" Tooltip="#CECrowDebugLog.ui.DbgEvtTooltip.crow" TicksPerPixel="1000" VerticalAlignment="Center"/>
- </ListItem>
- </ItemTemplate>
- <Template>
- <Wrapper Name="ItemsContainer" Spacing="1" Background="{./Background}"/>
- </Template>
- </ListBox>
- </VerticalStack>
- </TabView>
- <Splitter/>
- <HorizontalStack Height="30%">
- <!--<ListBox Data="{Widgets}" Width="200" SelectedItem="{²CurrentWidget}"
- ItemTemplate="#CECrowDebugLog.ui.WidgetRecord.itemp">
- </ListBox>-->
- <ListBox Data="{CurWidgetProperties}" Width="25%" >
- <ItemTemplate>
- <ListItem Height="Fit" Margin="1" Focusable="true" HorizontalAlignment="Left"
- Selected = "{Background=${ControlHighlight}}"
- Unselected = "{Background=Transparent}">
- <HorizontalStack>
- <Label Text="{Key}" Width="140"/>
- <Label Text="{Value}" Width="Stretched" Background="White" Foreground="Black" TextAlignment="Left"/>
- </HorizontalStack>
- </ListItem>
- </ItemTemplate>
- </ListBox>
- <Splitter/>
- <VerticalStack>
- <HorizontalStack Height="Fit" Background="Onyx" Spacing="5">
- <Label Text="{CurrentWidget}"/>
- <Label Text="events"/>
- </HorizontalStack>
- <ListBox Height="Stretched" Data="{CurrentWidgetEvents}" SelectedItem="{²CurrentEvent}" Background="DarkGrey"
- ItemTemplate="#CECrowDebugLog.ui.DbgWidgetEventListItems.itemp"/>
- </VerticalStack>
- <Splitter/>
- <DbgEventView Template="#CECrowDebugLog.ui.DbgEventView.template" Event="{../../dbv.HoverEvent}"/>
- <Splitter/>
- <DbgEventView Template="#CECrowDebugLog.ui.DbgEventView.template" Event="{CurrentEvent}"/>
- </HorizontalStack>
- <HorizontalStack Height="Fit" Background="Onyx" Margin="1">
- <HorizontalStack Height="Fit" DataSource="{CurrentEvent}">
- <Label Foreground="Black" Text="Current Event:" Background="{Color}" Margin="2" />
- <DbgEventWidget Height="14" Width="Stretched" Event="{}" Tooltip="#CECrowDebugLog.ui.DbgEvtTooltip.crow" />
- </HorizontalStack>
- <ListBox Data="{EventCommands}" Fit="true">
- <Template>
- <HorizontalStack Name="ItemsContainer" />
- </Template>
- <ItemTemplate Path="#CrowEditBase.ui.IconCommand.itmp"/>
- </ListBox>
- <Popper Caption="Search...">
- <VerticalStack Fit="true" Background="Onyx" Margin="10">
- <ComboBox Caption="Event Type" Data="{AllEventTypes}" SelectedItem="{²SearchEventType}"/>
- <ComboBox Caption="Widget" Data="{Widgets}" SelectedItem="{²SearchWidget}"/>
- </VerticalStack>
- </Popper>
- </HorizontalStack>
- </VerticalStack>
-</Window>
\ No newline at end of file
+++ /dev/null
-<?xml version="1.0"?>
-<DockWindow Caption="Debug Log Graph" Width="90%" Height="90%">
- <VerticalStack Name="LogGraph" >
- <EnumSelector RadioButtonStyle="CheckBox2" Template="#CECrowDebugLog.ui.EnumSelector.template"
- Caption="Discarded Events" EnumValue="{²../dbv.Filter}" BitFieldExcludeMask="255" />
- <HorizontalStack>
- <DbgLogViewer Visible="true" Name="dbv" Events="{Events}" Widgets="{Widgets}"
- CurrentEvent="{²CurrentEvent}" CurrentWidget="{²CurrentWidget}" />
- <ScrollBar Maximum="{../dbv.MaxScrollY}" Value="{²../dbv.ScrollY}" SmallIncrement="1" LargeIncrement="10"
- CursorRatio="{../dbv.ChildHeightRatio}"/>
- </HorizontalStack>
- <ScrollBar Style="HScrollBar" Maximum="{../dbv.MaxScrollX}" Value="{²../dbv.ScrollX}" SmallIncrement="1" LargeIncrement="10"
- CursorRatio="{../dbv.ChildWidthRatio}"/>
- <HorizontalStack Height="Fit" DataSource="{CurrentWidget}" Spacing="3">
- <Label Style="smallLabValue" Text="{name}"/>
- <Label Style="smallLabValue" Text="{listIndex}" Tooltip="List index"/>
- <Label Style="smallLabValue" Text="{treeIndex}" Tooltip="tree index"/>
- <Label Style="smallLabValue" Text="{yIndex}" Tooltip="yIndex"/>
- <Label Style="smallLabValue" Text="{xLevel}" Tooltip="xLevel"/>
- <Label Style="smallLabCaption" Text="ScrollX:" />
- <Label Style="smallLabValue" Text="{../../dbv.ScrollX}"/>
- <Label Style="smallLabCaption" Text="MaxScrollX:" />
- <Label Style="smallLabValue" Text="{../../dbv.MaxScrollX}"/>
- <Label Style="smallLabValue" Tooltip="XScale" Text="{../../dbv.XScale}"/>
- <Label Style="smallLabValue" Tooltip="VisibleTicks" Text="{../../dbv.VisibleTicks}"/>
- </HorizontalStack>
- </VerticalStack>
-</DockWindow>
-
-
+++ /dev/null
-<?xml version="1.0"?>
-<DockWindow Caption="Debug Log Navigation" Width="90%" Height="Fit">
- <VerticalStack Name="LogGraph" >
- <ListBox Name="lbAllEvents" Data="{Events}" Height="Fit" >
- <ItemTemplate>
- <ListItem Margin="0" Height="16" Width="Fit"
- Selected="{Background=Yellow}"
- Unselected="{Background=Transparent}">
- <DbgEventWidget CacheEnabled="true" Height="10" Width="Fit" Event="{}" Tooltip="#CECrowDebugLog.ui.DbgEvtTooltip.crow" TicksPerPixel="3000" VerticalAlignment="Center"/>
- </ListItem>
- </ItemTemplate>
- <Template>
- <VerticalStack Width="Stretched" >
- <Scroller Name="scroller" >
- <HorizontalStack Name="ItemsContainer" Width="Fit" HorizontalAlignment="Left"/>
- </Scroller>
- <ScrollBar Style="HScrollBar" Name="scrollbar1" Value="{²../scroller.ScrollX}"
- LargeIncrement="{../scroller.PageWidth}" SmallIncrement="30" CursorRatio="{../scroller.ChildWidthRatio}"
- Maximum="{../scroller.MaxScrollX}" Height="12" />
- </VerticalStack>
- </Template>
- </ListBox>
- <ListBox DataSource="{../lbAllEvents.SelectedItem}" Data="{Events}" Height="Fit" >
- <ItemTemplate>
- <ListItem Margin="0" Height="16" Width="Fit"
- Selected="{Background=Yellow}"
- Unselected="{Background=Transparent}">
- <DbgEventWidget CacheEnabled="true" Height="10" Width="Fit" Event="{}" Tooltip="#CECrowDebugLog.ui.DbgEvtTooltip.crow" TicksPerPixel="3000" VerticalAlignment="Center"/>
- </ListItem>
- </ItemTemplate>
- <Template>
- <VerticalStack Width="Stretched" >
- <Scroller Name="scroller" >
- <HorizontalStack Name="ItemsContainer" Width="Fit" HorizontalAlignment="Left"/>
- </Scroller>
- <ScrollBar Style="HScrollBar" Name="scrollbar1" Value="{²../scroller.ScrollX}"
- LargeIncrement="{../scroller.PageWidth}" SmallIncrement="30" CursorRatio="{../scroller.ChildWidthRatio}"
- Maximum="{../scroller.MaxScrollX}" Height="12" />
- </VerticalStack>
- </Template>
- </ListBox>
- </VerticalStack>
-</DockWindow>
-
-
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<Project Sdk="Microsoft.NET.Sdk">
+ <PropertyGroup>
+ <TargetFrameworks>netcoreapp3.1</TargetFrameworks>
+ <EnableDefaultItems>false</EnableDefaultItems>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <Compile Include="src\**\*.cs" />
+ <EmbeddedResource Include="ui\**\*.*" />
+ <EmbeddedResource Include="default.conf" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\CERoslynPlugin\CERoslynPlugin.csproj" />
+ <ProjectReference Include="..\CEXmlPlugin\CEXmlPlugin.csproj" />
+ </ItemGroup>
+</Project>
--- /dev/null
+FileAssociations=CECrowPlugin.ImlDocument:.crow,.iml,.itmp,.template
\ No newline at end of file
--- /dev/null
+// Copyright (c) 2013-2019 Bruyère Jean-Philippe <jp_bruyere@hotmail.com>
+//
+// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
+
+using System;
+using Glfw;
+using System.Reflection;
+using System.Runtime.Loader;
+using System.IO;
+using Crow.Drawing;
+using System.Diagnostics;
+using System.Collections.Generic;
+using Crow.DebugLogger;
+using System.Linq;
+using CrowEditBase;
+using System.Threading;
+using Crow.Text;
+using System.Runtime.InteropServices;
+using System.Runtime.CompilerServices;
+using static CrowEditBase.CrowEditBase;
+
+namespace Crow
+{
+ public class CrowService : Service {
+ public CrowService () : base () {
+
+ initCommands ();
+
+ //resolve other plugins dependencies
+ //AssemblyLoadContext.GetLoadContext (Assembly.GetExecutingAssembly ()).Resolving += resolvePluginRefs;
+
+ if (CrowEditBase.CrowEditBase.App.TryGetWindow ("#CECrowPlugin.ui.winLogGraph.crow", out Window win))
+ win.DataSource = this;
+ }
+ /*Assembly resolvePluginRefs (AssemblyLoadContext ctx, AssemblyName assemblyName)
+ => App.TryGetPlugin ("CERoslynPlugin", out Plugin roslynPlugin) ?
+ roslynPlugin.Load (assemblyName) : null;*/
+
+ static IntPtr resolveUnmanaged(Assembly assembly, String libraryName)
+ {
+
+ switch (libraryName)
+ {
+ case "glfw3":
+ return NativeLibrary.Load("glfw", assembly, null);
+ case "rsvg-2.40":
+ return NativeLibrary.Load("rsvg-2", assembly, null);
+ }
+ Console.WriteLine($"[UNRESOLVE] {assembly} {libraryName}");
+ return IntPtr.Zero;
+ }
+
+ void updateCrowApp () {
+ if (App.CurrentProject is CERoslynPlugin.SolutionProject sol) {
+ CERoslynPlugin.SolutionProject project = App.CurrentProject as CERoslynPlugin.SolutionProject;
+ Console.WriteLine (project.Name);
+ }else if (App.CurrentProject is CERoslynPlugin.MSBuildProject csprj){
+ CERoslynPlugin.MSBuildProject project = App.CurrentProject as CERoslynPlugin.MSBuildProject;
+ Console.WriteLine ($"{project.Name}: {project.IsCrowProject}");
+
+ }
+
+
+ }
+
+
+ public Command CMDStartRecording, CMDStopRecording, CMDRefresh;
+ public Command CMDGotoParentEvent, CMDEventHistoryForward, CMDEventHistoryBackward;
+ public CommandGroup LoggerCommands => new CommandGroup (CMDRefresh, CMDStartRecording, CMDStopRecording);
+ public CommandGroup EventCommands => new CommandGroup(
+ CMDGotoParentEvent, CMDEventHistoryBackward, CMDEventHistoryForward);
+ void initCommands ()
+ {
+ App.ViewCommands.Add (
+ new Command("Crow Preview", () => App.LoadWindow ("#CECrowPlugin.ui.winCrowPreview.crow", App)));
+ CMDRefresh = new Command ("Refresh", refresh, "#icons.refresh.svg", IsRunning);
+ CMDStartRecording = new Command ("Start Recording", () => Recording = true, "#icons.circle.svg", false);
+ CMDStopRecording = new Command ("Stop Recording", stopRecording, "#icons.circle-red.svg", false);
+
+ CMDGotoParentEvent = new Command("parent", ()=> { CurrentEvent = CurrentEvent?.parentEvent; }, "#icons.level-up.svg", false);
+ CMDEventHistoryBackward = new Command("back.", currentEventHistoryGoBack, "#icons.previous.svg", false);
+ CMDEventHistoryForward = new Command("forw.", currentEventHistoryGoForward, "#icons.forward-arrow.svg", false);
+ }
+
+ public Command CMDOptions_SelectCrowAssemblyLocation => new Command ("...",
+ () => {
+ FileDialog dlg = App.LoadIMLFragment<FileDialog> (@"
+ <FileDialog Caption='Select Crow.dll assembly' CurrentDirectory='{CrowDbgAssemblyLocation}'
+ ShowFiles='true' ShowHidden='true' />");
+ dlg.OkClicked += (sender, e) => CrowDbgAssemblyLocation = (sender as FileDialog).SelectedFileFullPath;
+ dlg.DataSource = this;
+ }
+ );
+
+ public void LoadIML (string imlSource) {
+ if (CurrentState == Status.Running)
+ delSetSource (imlSource);
+ }
+ Exception currentException;
+ object dbgIFace;
+ AssemblyLoadContext crowLoadCtx;
+ Assembly crowAssembly, thisAssembly;
+ Type dbgIfaceType;
+
+ #region dbgIface delegates
+ Action<int, int> delResize;
+ Func<int, int, bool> delMouseMove;
+ Func<float, bool> delMouseWheelChanged;
+ Func<MouseButton, bool> delMouseDown, delMouseUp;
+ Func<char, bool> delKeyPress;
+ Func<Key, bool> delKeyDown, delKeyUp;
+ FieldInfo fiDbgIFace_IsDirty;
+ Action delResetDebugger;
+ Action<object, string> delSaveDebugLog;
+ Func<IntPtr> delGetSurfacePointer;
+ Action<string> delSetSource;
+ Action delReloadIml;
+
+ FieldInfo fiDbg_IncludeEvents, fiDbg_DiscardEvents, fiDbg_ConsoleOutput, fiDbgIFace_MaxLayoutingTries, fiDbgIFace_MaxDiscardCount;
+ #endregion
+
+ bool recording, debugLogIsEnabled;
+ DbgEvtType recordedEvents = DbgEvtType.Widget, discardedEvents;
+ public bool HasVkvgBackend { get; private set; }
+ public int RefreshRate {
+ get => Configuration.Global.Get<int> ("RefreshRate", 10);
+ set {
+ if (RefreshRate == value)
+ return;
+ Configuration.Global.Set ("RefreshRate", value);
+ NotifyValueChanged(value);
+ }
+ }
+ public int MaxLayoutingTries {
+ get => Configuration.Global.Get<int> ("MaxLayoutingTries", 30);
+ set {
+ if (MaxLayoutingTries == value)
+ return;
+ Configuration.Global.Set ("MaxLayoutingTries", value);
+ NotifyValueChanged(value);
+ fiDbgIFace_MaxLayoutingTries.SetValue (null, value);
+ }
+ }
+ public int MaxDiscardCount {
+ get => Configuration.Global.Get<int> ("MaxDiscardCount", 5);
+ set {
+ if (MaxDiscardCount == value)
+ return;
+ Configuration.Global.Set ("MaxDiscardCount", value);
+ NotifyValueChanged(value);
+ fiDbgIFace_MaxDiscardCount.SetValue (null, value);
+ }
+ }
+ public bool PreviewHasError => currentException != null;
+ public Exception CurrentException {
+ get => currentException;
+ set {
+ if (currentException == value)
+ return;
+ currentException = value;
+ NotifyValueChanged (currentException);
+ NotifyValueChanged ("PreviewHasError", PreviewHasError);
+ }
+ }
+ public string CrowDbgAssemblyLocation {
+ get => Configuration.Global.Get<string> ("CrowDbgAssemblyLocation");
+ set {
+ if (CrowDbgAssemblyLocation == value)
+ return;
+ Configuration.Global.Set ("CrowDbgAssemblyLocation", value);
+ NotifyValueChanged(value);
+ }
+ }
+ public bool DebugLogIsEnabled {
+ get => debugLogIsEnabled;
+ set {
+ if (debugLogIsEnabled == value)
+ return;
+ debugLogIsEnabled = value;
+ CMDStartRecording.CanExecute = debugLogIsEnabled & !Recording;
+ CMDStopRecording.CanExecute = debugLogIsEnabled & Recording;
+ NotifyValueChanged (debugLogIsEnabled);
+ }
+ }
+ public bool Recording {
+ get => recording;
+ set {
+ if (recording == value)
+ return;
+ recording = IsRunning & DebugLogIsEnabled & value;
+ if (recording) {
+ fiDbg_DiscardEvents.SetValue (dbgIFace, DiscardedEvents);
+ fiDbg_IncludeEvents.SetValue (dbgIFace, RecordedEvents);
+ CMDStartRecording.CanExecute = false;
+ CMDStopRecording.CanExecute = true;
+ } else {
+ fiDbg_DiscardEvents.SetValue (dbgIFace, DbgEvtType.All);
+ fiDbg_IncludeEvents.SetValue (dbgIFace, DbgEvtType.None);
+ CMDStartRecording.CanExecute = debugLogIsEnabled;
+ CMDStopRecording.CanExecute = false;
+ }
+ NotifyValueChanged(recording);
+ }
+ }
+ public DbgEvtType RecordedEvents {
+ get => recordedEvents;
+ set {
+ if (recordedEvents == value)
+ return;
+ recordedEvents = value;
+ if (Recording)
+ fiDbg_IncludeEvents.SetValue (dbgIFace, value);
+ NotifyValueChanged (recordedEvents);
+ }
+ }
+ public DbgEvtType DiscardedEvents {
+ get => discardedEvents;
+ set {
+ if (discardedEvents == value)
+ return;
+ discardedEvents = value;
+ if (Recording)
+ fiDbg_DiscardEvents.SetValue (dbgIFace, value);
+ NotifyValueChanged (discardedEvents);
+ }
+ }
+ public string DebugLogFilePath {
+ get => Configuration.Global.Get<string> ("DebugLogFilePath");
+ set {
+ if (DebugLogFilePath == value)
+ return;
+ Configuration.Global.Set ("DebugLogFilePath", value);
+ NotifyValueChanged (value);
+ }
+ }
+ public string ErrorMessage = "";
+ public bool ServiceIsInError;
+ void updateCrowDebuggerState (string errorMsg = null) {
+ ErrorMessage = errorMsg;
+ ServiceIsInError = errorMsg != null;
+ NotifyValueChanged ("ServiceErrorMessage", (object)ErrorMessage);
+ NotifyValueChanged ("ServiceIsInError", ServiceIsInError);
+ }
+ public override void Start()
+ {
+ if (CurrentState == Status.Running)
+ return;
+
+
+ if (!File.Exists (CrowDbgAssemblyLocation)) {
+ DebugLogIsEnabled = false;
+ updateCrowDebuggerState($"Crow.dll for debugging file not found");
+ return;
+ }
+
+ crowLoadCtx = new AssemblyLoadContext("CrowDebuggerLoadContext");
+ crowLoadCtx.ResolvingUnmanagedDll += resolveUnmanaged;
+ crowLoadCtx.Resolving += (context, assemblyName) => {
+ return crowLoadCtx.LoadFromAssemblyPath (
+ System.IO.Path.Combine (
+ System.IO.Path.GetDirectoryName(CrowDbgAssemblyLocation), assemblyName.Name + ".dll"));
+ };
+ //crowLoadCtx.Resolving += (ctx,name) => AssemblyLoadContext.Default.LoadFromAssemblyName (name);
+
+ //using (crowLoadCtx.EnterContextualReflection()) {
+ crowAssembly = crowLoadCtx.LoadFromAssemblyPath (CrowDbgAssemblyLocation);
+ thisAssembly = crowLoadCtx.LoadFromAssemblyPath (new Uri(Assembly.GetExecutingAssembly().CodeBase).LocalPath);
+
+ Type debuggerType = crowAssembly.GetType("Crow.DbgLogger");
+ DebugLogIsEnabled = (bool)debuggerType.GetField("IsEnabled").GetValue(null);
+
+ dbgIfaceType = thisAssembly.GetType("CECrowPlugin.DebugInterface");
+
+ dbgIFace = Activator.CreateInstance (dbgIfaceType, new object[] {CrowEditBase.CrowEditBase.App.WindowHandle});
+
+ delResize = (Action<int, int>)Delegate.CreateDelegate(typeof(Action<int, int>),
+ dbgIFace, dbgIfaceType.GetMethod("Resize"));
+
+ delMouseMove = (Func<int, int, bool>)Delegate.CreateDelegate(typeof(Func<int, int, bool>),
+ dbgIFace, dbgIfaceType.GetMethod("OnMouseMove"));
+
+ delMouseWheelChanged = (Func<float, bool>)Delegate.CreateDelegate(typeof(Func<float, bool>),
+ dbgIFace, dbgIfaceType.GetMethod("OnMouseWheelChanged"));
+
+
+ delMouseDown = (Func<MouseButton, bool>)Delegate.CreateDelegate(typeof(Func<MouseButton, bool>),
+ dbgIFace, dbgIfaceType.GetMethod("OnMouseButtonDown"));
+
+ delMouseUp = (Func<MouseButton, bool>)Delegate.CreateDelegate(typeof(Func<MouseButton, bool>),
+ dbgIFace, dbgIfaceType.GetMethod("OnMouseButtonUp"));
+
+ delKeyDown = (Func<Key, bool>)Delegate.CreateDelegate(typeof(Func<Key, bool>),
+ dbgIFace, dbgIfaceType.GetMethod("OnKeyDown"));
+ delKeyUp = (Func<Key, bool>)Delegate.CreateDelegate(typeof(Func<Key, bool>),
+ dbgIFace, dbgIfaceType.GetMethod("OnKeyUp"));
+ delKeyPress = (Func<char, bool>)Delegate.CreateDelegate(typeof(Func<char, bool>),
+ dbgIFace, dbgIfaceType.GetMethod("OnKeyPress"));
+
+
+ delGetSurfacePointer = (Func<IntPtr>)Delegate.CreateDelegate(typeof(Func<IntPtr>),
+ dbgIFace, dbgIfaceType.GetProperty("SurfacePointer").GetGetMethod());
+ delSetSource = (Action<string>)Delegate.CreateDelegate(typeof(Action<string>),
+ dbgIFace, dbgIfaceType.GetProperty("Source").GetSetMethod());
+ delReloadIml = (Action)Delegate.CreateDelegate(typeof(Action), dbgIFace, dbgIfaceType.GetMethod("ReloadIml"));
+
+ fiDbgIFace_IsDirty = dbgIfaceType.GetField("IsDirty");
+ fiDbgIFace_MaxLayoutingTries = dbgIfaceType.GetField("MaxLayoutingTries", BindingFlags.Static | BindingFlags.Public | BindingFlags.FlattenHierarchy);
+ fiDbgIFace_MaxDiscardCount = dbgIfaceType.GetField("MaxDiscardCount", BindingFlags.Static | BindingFlags.Public | BindingFlags.FlattenHierarchy);
+
+ fiDbg_IncludeEvents = debuggerType.GetField("IncludeEvents");
+ fiDbg_DiscardEvents = debuggerType.GetField("DiscardEvents");
+ fiDbg_ConsoleOutput = debuggerType.GetField("ConsoleOutput");
+ delResetDebugger = (Action)Delegate.CreateDelegate(typeof(Action), null, debuggerType.GetMethod("Reset"));
+ /*delSaveDebugLog = (Action<object, string>)Delegate.CreateDelegate(typeof(Action<object, string>),
+ null, debuggerType.GetMethod("Save", new Type[] {dbgIfaceType, typeof(string)}));*/
+ HasVkvgBackend = (bool)dbgIfaceType.GetField ("HaveVkvgBackend", BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy).GetValue (null);
+ dbgIfaceType.GetMethod("RegisterDebugInterfaceCallback").Invoke (dbgIFace, new object[] {this} );
+ dbgIfaceType.GetMethod("Run").Invoke (dbgIFace, null);
+
+ fiDbgIFace_MaxLayoutingTries.SetValue (null, MaxLayoutingTries);
+ fiDbgIFace_MaxDiscardCount.SetValue (null, MaxDiscardCount);
+
+ CurrentState = Status.Running;
+
+ updateCrowDebuggerState();
+ }
+ public override void Stop()
+ {
+ Recording = false;
+ DebugLogIsEnabled = false;
+ crowLoadCtx = null;
+ CurrentState = Status.Stopped;
+ }
+ public override void Pause()
+ {
+ CurrentState = Status.Paused;
+ }
+ public override string ConfigurationWindowPath => "#CECrowPlugin.ui.winConfiguration.crow";
+ public Command CMDOptions_SelectCrowDbgAssemblyLocation => new Command ("...",
+ () => {
+ FileDialog dlg = App.LoadIMLFragment<FileDialog> (@"
+ <FileDialog Caption='Select Crow dll' CurrentDirectory='{CrowDbgAssemblyLocation}'
+ ShowFiles='true' ShowHidden='true' />");
+ dlg.OkClicked += (sender, e) => CrowDbgAssemblyLocation = (sender as FileDialog).SelectedFileFullPath;
+ dlg.DataSource = this;
+ }
+ );
+ protected override void onStateChange(Status previousState, Status newState)
+ {
+ base.onStateChange(previousState, newState);
+ CMDRefresh.CanExecute = IsRunning;
+ }
+
+ public void onKeyDown(KeyEventArgs e)
+ {
+ if (CurrentState == Status.Running) {
+ try
+ {
+ e.Handled = delKeyDown (e.Key);
+ }
+ catch (System.Exception ex)
+ {
+ Console.WriteLine($"[Error][DebugIFace key down]{ex}");
+ }
+ }
+ }
+ public void onKeyUp(KeyEventArgs e)
+ {
+ if (CurrentState == Status.Running) {
+ try
+ {
+ e.Handled = delKeyUp (e.Key);
+ }
+ catch (System.Exception ex)
+ {
+ Console.WriteLine($"[Error][DebugIFace key up]{ex}");
+ }
+ }
+ }
+ public void onKeyPress(KeyPressEventArgs e)
+ {
+ if (CurrentState == Status.Running) {
+ try
+ {
+ e.Handled = delKeyPress (e.KeyChar);
+ }
+ catch (System.Exception ex)
+ {
+ Console.WriteLine($"[Error][DebugIFace key press]{ex}");
+ }
+ }
+ }
+ public void onMouseMove(MouseMoveEventArgs e)
+ {
+ if (CurrentState == Status.Running) {
+ try
+ {
+ e.Handled = delMouseMove (e.X, e.Y);
+ }
+ catch (System.Exception ex)
+ {
+ Console.WriteLine($"[Error][DebugIFace mouse move]{ex}");
+ }
+ }
+ }
+ public void onMouseDown(MouseButtonEventArgs e)
+ {
+ if (CurrentState == Status.Running) {
+ try
+ {
+ e.Handled = delMouseDown (e.Button);
+ }
+ catch (System.Exception ex)
+ {
+ Console.WriteLine($"[Error][DebugIFace mouse down]{ex}");
+ }
+ }
+ }
+ public void onMouseUp(MouseButtonEventArgs e)
+ {
+ if (CurrentState == Status.Running) {
+ try
+ {
+ e.Handled = delMouseUp (e.Button);
+ }
+ catch (System.Exception ex)
+ {
+ Console.WriteLine($"[Error][DebugIFace mouse up]{ex}");
+ }
+ }
+ }
+ public void onMouseWheel(MouseWheelEventArgs e)
+ {
+ if (CurrentState == Status.Running) {
+ try
+ {
+ e.Handled = delMouseWheelChanged (e.Delta);
+ }
+ catch (System.Exception ex)
+ {
+ Console.WriteLine($"[Error][DebugIFace mouse wheel change]{ex}");
+ }
+ }
+ }
+ public IntPtr SurfacePointer => IsRunning ? delGetSurfacePointer() : IntPtr.Zero;
+ public void Resize (int width, int height) {
+ if (IsRunning)
+ delResize (width, height);
+ }
+ public void ResetDirtyState () {
+ if (IsRunning)
+ fiDbgIFace_IsDirty.SetValue (dbgIFace, false);
+ }
+ public bool GetDirtyState => IsRunning ? (bool)fiDbgIFace_IsDirty.GetValue (dbgIFace) : false;
+
+
+ IList<DbgEvent> events;
+ IList<DbgWidgetRecord> widgets;
+ public IList<DbgEvent> Events {
+ get => events;
+ set {
+ if (events == value)
+ return;
+ events = value;
+ NotifyValueChanged (nameof (Events), events);
+ }
+ }
+ public IList<DbgWidgetRecord> Widgets {
+ get => widgets;
+ set {
+ if (widgets == value)
+ return;
+ widgets = value;
+ NotifyValueChanged (nameof (Widgets), widgets);
+ }
+ }
+ void refresh () {
+ if (IsRunning)
+ delReloadIml ();
+ updateCrowApp();
+ }
+ void stopRecording () {
+ if (!Recording)
+ return;
+ Recording = false;
+ getLog ();
+ CrowEditBase.CrowEditBase.App.LoadWindow ("#CECrowPlugin.ui.winDebugLog.crow", this);
+ }
+ int firstWidgetIndexToGet = 0;
+ public object LogMutex = new object ();
+ void getLog () {
+
+ using (Stream stream = new MemoryStream (1024)) {
+ Type debuggerType = crowAssembly.GetType("Crow.DbgLogger");
+ MethodInfo miSave = debuggerType.GetMethod("Save",
+ new Type[] {
+ dbgIfaceType,
+ typeof(Stream),
+ typeof(int),
+ typeof(bool)
+ });
+
+
+ List<DbgWidgetRecord> widgets = new List<DbgWidgetRecord>();
+ List<DbgEvent> events = new List<DbgEvent>();
+ miSave.Invoke(null, new object[] {dbgIFace, stream, firstWidgetIndexToGet, true});
+ stream.Seek(0, SeekOrigin.Begin);
+ DbgLogger.Load (stream, events, widgets);
+
+ lock (LogMutex) {
+ for (int i = 0; i < widgets.Count; i++) {
+ widgets[i].listIndex = i;
+ //Widgets.Add (widgets[i]);
+ }
+ for (int i = 0; i < events.Count; i++) {
+ //Events.Add (events[i]);
+ updateWidgetEvents (widgets, events[i]);
+ }
+ }
+ Events = events;
+ Widgets = widgets;
+ firstWidgetIndexToGet += widgets.Count;
+ /*if (widgets.Count > 0 && firstWidgetIndexToGet != widgets.Last().InstanceIndex + 1)
+ Debugger.Break ();*/
+ }
+ }
+ void updateWidgetEvents (IList<DbgWidgetRecord> widgets, DbgEvent evt) {
+ if (evt is DbgWidgetEvent we)
+ widgets.FirstOrDefault (w => w.InstanceIndex == we.InstanceIndex)?.Events.Add (we);
+ if (evt.Events == null)
+ return;
+ foreach (DbgEvent e in evt.Events)
+ updateWidgetEvents (widgets, e);
+ }
+ void saveLogToDebugLogFilePath () {
+
+ }
+ void loadLogFromDebugLogFilePath () {
+
+ }
+
+ //public virtual object GetScreenCoordinates () => ScreenCoordinates(Slot).TopLeft;
+ DbgEvent curEvent;
+ bool disableCurrentEventHistory;
+ Stack<DbgEvent> CurrentEventHistoryForward = new Stack<DbgEvent>();
+ Stack<DbgEvent> CurrentEventHistoryBackward = new Stack<DbgEvent>();
+ DbgWidgetRecord curWidget = new DbgWidgetRecord();
+ public string[] AllEventTypes => Enum.GetNames (typeof(DbgEvtType));
+ string searchEventType;
+ DbgWidgetRecord searchWidget;
+ public string SearchEventType {
+ get => searchEventType;
+ set {
+ if (searchEventType == value)
+ return;
+ searchEventType = value;
+ NotifyValueChanged (searchEventType);
+ }
+ }
+
+ public DbgWidgetRecord SearchWidget {
+ get => searchWidget;
+ set {
+ if (searchWidget == value)
+ return;
+ searchWidget = value;
+ NotifyValueChanged (searchWidget);
+ }
+ }
+ public DbgEvent CurrentEvent {
+ get => curEvent;
+ set {
+ if (curEvent == value)
+ return;
+
+ if (!disableCurrentEventHistory) {
+ CurrentEventHistoryForward.Clear ();
+ CMDEventHistoryForward.CanExecute = false;
+ if (!(value == null || curEvent == null)) {
+ CurrentEventHistoryBackward.Push (curEvent);
+ CMDEventHistoryBackward.CanExecute = true;
+ }
+ }
+
+ curEvent = value;
+
+ NotifyValueChanged (nameof (CurrentEvent), curEvent);
+ NotifyValueChanged ("CurEventChildEvents", curEvent?.Events);
+ NotifyValueChanged ("CurWidgetProperties", CurWidgetProperties);
+
+ if (CurrentEvent != null && CurrentEvent.parentEvent != null)
+ CMDGotoParentEvent.CanExecute = true;
+ else
+ CMDGotoParentEvent.CanExecute = false;
+ }
+ }
+ void currentEventHistoryGoBack () {
+ disableCurrentEventHistory = true;
+ if (CurrentEvent != null) {
+ CurrentEventHistoryForward.Push (CurrentEvent);
+ CMDEventHistoryForward.CanExecute = true;
+ }
+ CurrentEvent = CurrentEventHistoryBackward.Pop ();
+ CMDEventHistoryBackward.CanExecute = CurrentEventHistoryBackward.Count > 0;
+
+ disableCurrentEventHistory = false;
+ }
+
+ void currentEventHistoryGoForward () {
+ disableCurrentEventHistory = true;
+ CurrentEventHistoryBackward.Push (CurrentEvent);
+ CMDEventHistoryBackward.CanExecute = true;
+ CurrentEvent = CurrentEventHistoryForward.Pop ();
+ CMDEventHistoryForward.CanExecute = CurrentEventHistoryForward.Count > 0;
+
+ disableCurrentEventHistory = false;
+ }
+
+ public DbgWidgetRecord CurrentWidget {
+ get => curWidget;
+ set {
+ if (curWidget == value)
+ return;
+ curWidget = value;
+ NotifyValueChanged (nameof (CurrentWidget), curWidget);
+ NotifyValueChanged ("CurWidgetRootEvents", curWidget?.RootEvents);
+ NotifyValueChanged ("CurrentWidgetEvents", curWidget?.Events);
+ NotifyValueChanged ("CurWidgetProperties", CurWidgetProperties);
+ }
+ }
+ public List<DbgWidgetEvent> CurWidgetRootEvents => curWidget == null? new List<DbgWidgetEvent>() : curWidget.RootEvents;
+
+ public IEnumerable<KeyValuePair<string, string>> CurWidgetProperties {
+ get {
+ if (curWidget == null)
+ return null;
+ long endTime = curEvent == null ? long.MaxValue : curEvent.end;
+ Dictionary<string, string> result = new Dictionary<string, string> ();
+ foreach (DbgWidgetEvent evt in curWidget?.Events?.Where (e => e.type == DbgEvtType.GOSetProperty && e.begin <= endTime)){
+ string[] tmp = evt.Message.Split('=');
+ if (result.ContainsKey (tmp[0]))
+ result[tmp[0]] = tmp[1];
+ else
+ result.Add (tmp[0], tmp[1]);
+ }
+ return result;
+ }
+ }
+
+ }
+}
\ No newline at end of file
--- /dev/null
+// Copyright (c) 2021 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.ComponentModel;
+using Crow.Drawing;
+using Crow.DebugLogger;
+
+namespace Crow
+{
+ public class DbgEventView : TemplatedContainer {
+ DbgEvent evt;
+ public DbgEvent Event {
+ get => evt;
+ set {
+ if (evt == value)
+ return;
+ evt = value;
+ NotifyValueChangedAuto (evt);
+ }
+ }
+ }
+ public class DbgEventWidget : Widget
+ {
+ public DbgEventWidget (){}
+
+ DbgEvent evt, hoverEvt;
+ long ticksPerPixel;
+ double pixelPerTick;
+
+ object dataMutex = new object();
+
+ public DbgEvent Event {
+ get => evt;
+ set {
+ if (evt == value)
+ return;
+ lock (dataMutex)
+ evt = value;
+ updatePixelPerTicks ();
+ NotifyValueChangedAuto (evt);
+ RegisterForRedraw ();
+ }
+ }
+ public DbgEvent HoverEvent {
+ get => hoverEvt;
+ private set {
+ if (hoverEvt == value)
+ return;
+ lock (dataMutex)
+ evt = value;
+ hoverEvt = value;
+ NotifyValueChangedAuto (hoverEvt);
+ }
+ }
+
+ [DefaultValue ("1000")]
+ public long TicksPerPixel {
+ get => ticksPerPixel;
+ set {
+ if (ticksPerPixel == value)
+ return;
+ ticksPerPixel = value;
+ NotifyValueChangedAuto (ticksPerPixel);
+ if (Width == Measure.Fit)
+ RegisterForLayouting (LayoutingType.Width);
+ }
+ }
+
+ public override int measureRawSize (LayoutingType lt)
+ {
+ updatePixelPerTicks ();
+ if (lt == LayoutingType.Width)
+ contentSize.Width = Event == null ? 0 : (int)Math.Max(pixelPerTick * Event.Duration, 2);
+
+ return base.measureRawSize (lt);
+ }
+
+ public override void OnLayoutChanges (LayoutingType layoutType)
+ {
+ if (layoutType == LayoutingType.Width)
+ updatePixelPerTicks ();
+
+ base.OnLayoutChanges (layoutType);
+ }
+
+ protected override void onDraw (Context gr)
+ {
+ lock (dataMutex) {
+
+ if (Event == null) {
+ base.onDraw (gr);
+ return;
+ }
+
+ gr.LineWidth = 1;
+ gr.SetDash (new double [] { 1.0, 3.0 }, 0);
+
+ Rectangle cb = ClientRectangle;
+
+ if (Event.Duration == 0) {
+ gr.SetSource (Event.Color);
+ gr.Rectangle (cb);
+ gr.Fill ();
+ return;
+ }
+
+ drawEvent (gr, cb.Height, Event);
+ }
+ }
+ void drawEvent (Context ctx, int h, DbgEvent dbge)
+ {
+ double w = Math.Max(dbge.Duration * pixelPerTick, 2.0);
+ double x = (dbge.begin - Event.begin) * pixelPerTick;
+
+ ctx.Rectangle (x, 0, w, h);
+ ctx.SetSource (dbge.Color);
+ /*if (dbge.IsSelected) {
+ ctx.FillPreserve ();
+ ctx.SetSource (1, 1, 1);
+ ctx.Stroke ();
+ }else*/
+ ctx.Fill ();
+
+ if (dbge.Events == null)
+ return;
+ foreach (DbgEvent e in dbge.Events)
+ drawEvent (ctx, h, e);
+ }
+
+ public override void onMouseMove (object sender, MouseMoveEventArgs e)
+ {
+ if (Event != null) {
+ Point m = ScreenPointToLocal (e.Position);
+ long curTick = (long)(m.X / pixelPerTick) + Event.begin;
+ HoverEvent = hoverEvent (Event, curTick);
+
+ e.Handled = true;
+ }
+ base.onMouseMove (sender, e);
+ }
+
+ DbgEvent hoverEvent (DbgEvent hevt, long curTick){
+ if (hevt.Events != null) {
+ foreach (DbgEvent e in hevt.Events) {
+ if (curTick >= e.begin && curTick <= e.end)
+ return hoverEvent (e, curTick);
+ }
+ }
+ return hevt;
+ }
+ void updatePixelPerTicks ()
+ {
+ if (Width == Measure.Fit)
+ pixelPerTick = 1.0 / ticksPerPixel;
+ else
+ pixelPerTick = Event == null ? 0 : (double)ClientRectangle.Width / Event.Duration;
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+// Copyright (c) 2013-2021 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.ComponentModel;
+using System.IO;
+using System.Linq;
+using System.Threading.Tasks;
+using Crow.Drawing;
+using Crow.DebugLogger;
+using System.Diagnostics;
+
+namespace Crow
+{
+ public class DbgLogViewer : Widget
+ {
+ public static Dictionary<DbgEvtType, Color> colors;
+
+ #region CTOR
+ protected DbgLogViewer () : base(){}
+ public DbgLogViewer (Interface iface, string style = null) : base(iface, style){}
+ #endregion
+
+ FontExtents fe;
+
+
+ double xScale = 1.0/1024.0, yScale = 1.0, leftMargin, topMargin = 0.0;
+ DbgWidgetRecord curWidget, hoverWidget;
+ DbgEvent curEvent, hoverEvent;
+
+ IList<DbgEvent> events = new List<DbgEvent> ();
+ IList<DbgWidgetRecord> widgets = new List<DbgWidgetRecord> ();
+
+
+ public DbgEvtType Filter {
+ get => Configuration.Global.Get<DbgEvtType> ("DbgLogViewFilter");
+ set {
+ if (Filter == value)
+ return;
+ Configuration.Global.Set ("DbgLogViewFilter", value);
+ NotifyValueChangedAuto(Filter);
+ RegisterForGraphicUpdate();
+ }
+ }
+ public IList<DbgEvent> Events {
+ get => events;
+ set {
+ if (events == value)
+ return;
+ events = value;
+ NotifyValueChanged (nameof (Events), events);
+
+ maxTicks = minTicks = 0;
+ if (events != null && events.Count > 0) {
+ minTicks = long.MaxValue;
+ foreach (DbgEvent e in events) {
+ if (e.begin < minTicks)
+ minTicks = e.begin;
+ if (e.end > maxTicks)
+ maxTicks = e.end;
+ }
+ visibleTicks = maxTicks - minTicks;
+ XScale = (ClientRectangle.Width - leftMargin)/visibleTicks;
+ ScrollX = 0;
+ ScrollY = 0;
+ } else {
+ maxTicks = 1;
+ XScale = 1.0/1024.0;
+ }
+
+
+ RegisterForGraphicUpdate ();
+ }
+ }
+ public IList<DbgWidgetRecord> Widgets {
+ get => widgets;
+ set {
+ if (widgets == value)
+ return;
+ widgets = value;
+ NotifyValueChanged (nameof (Widgets), widgets);
+ updateMargins ();
+ updateMaxScrollX ();
+ updateMaxScrollY ();
+ }
+ }
+ public DbgWidgetRecord CurrentWidget {
+ get => curWidget;
+ set {
+ if (curWidget == value)
+ return;
+ curWidget = value;
+ NotifyValueChanged (nameof (CurrentWidget), curWidget);
+ if (CurrentWidget == null)
+ return;
+ if (CurrentWidget.listIndex < scrollY || CurrentWidget.listIndex > scrollY + visibleLines)
+ ScrollY = CurrentWidget.listIndex - (visibleLines / 2);
+
+ currentLine = CurrentWidget.listIndex;
+ RegisterForRedraw();
+ }
+ }
+ public DbgEvent CurrentEvent {
+ get => curEvent;
+ set {
+ if (curEvent == value)
+ return;
+ /*if (curEvent != null)
+ curEvent.IsSelected = false;*/
+ curEvent = value;
+ if (curEvent != null) {
+ //curEvent.IsSelected = true;
+ if (curEvent is DbgWidgetEvent we) {
+ //CurrentWidget = Widgets [we.InstanceIndex];
+ hoverLine = we.InstanceIndex;
+ }
+ currentTick = curEvent.begin;
+ if (curEvent.begin > minTicks + ScrollX + visibleTicks ||
+ curEvent.end < minTicks + ScrollX)
+ ScrollX = curEvent.begin - minTicks - visibleTicks / 2;
+ }
+ NotifyValueChanged (nameof (CurrentEvent), curEvent);
+ RegisterForRedraw ();
+ }
+ }
+ public DbgWidgetRecord HoverWidget {
+ get => hoverWidget;
+ internal set {
+ if (hoverWidget == value)
+ return;
+ hoverWidget = value;
+ NotifyValueChanged (nameof (HoverWidget), hoverWidget);
+ }
+ }
+
+ public DbgEvent HoverEvent {
+ get => hoverEvent;
+ set {
+ if (hoverEvent == value)
+ return;
+ hoverEvent = value;
+ NotifyValueChanged (nameof (HoverEvent), hoverEvent);
+ RegisterForRepaint ();
+ }
+ }
+
+ long hoverTick = 0, currentTick, selStart = -1, selEnd = -1, minTicks = 0, maxTicks = 0, visibleTicks = 0;
+ int hoverLine = -1, currentLine = -1;
+ int visibleLines = 1;
+ Point mousePos;
+
+ public double XScale {
+ get => xScale;
+ set {
+ if (xScale == value)
+ return;
+ xScale = value;
+ NotifyValueChanged ("XScale", xScale);
+ updateVisibleTicks ();
+ RegisterForGraphicUpdate ();
+ }
+ }
+ public double YScale {
+ get => yScale;
+ set {
+ if (yScale == value)
+ return;
+ yScale = value;
+ NotifyValueChanged ("YScale", yScale);
+ RegisterForGraphicUpdate ();
+ }
+ }
+ public override Font Font {
+ get { return base.Font; }
+ set {
+ base.Font = value;
+ using (Context gr = new Context (IFace.surf)) {
+ gr.SelectFontFace (Font.Name, Font.Slant, Font.Wheight);
+ gr.SetFontSize (Font.Size);
+
+ fe = gr.FontExtents;
+ }
+ updateMargins ();
+ }
+ }
+ RectangleD getWidgetEvtBounds (DbgEvent evt, ref Rectangle cb, double penY) {
+ double x = xScale * (evt.begin - minTicks - ScrollX);
+ double w = Math.Max (Math.Max (2.0, 2.0 * xScale), (double)(evt.end - evt.begin) * xScale);
+ if (x < 0.0) {
+ w += x;
+ x = 0.0;
+ }
+ x += leftMargin + cb.Left;
+ double rightDiff = x + w - cb.Right;
+ if (rightDiff > 0)
+ w -= rightDiff;
+ return new RectangleD(x, penY, w, fe.Height);
+ }
+ void drawEvents (Context ctx, IList<DbgEvent> evts)
+ {
+ if (evts == null || evts.Count == 0)
+ return;
+ Rectangle cb = ClientRectangle;
+
+ foreach (DbgEvent evt in evts) {
+ if ((evt.Category & currentFilter) == currentFilter) {
+ if (evt.end - minTicks <= ScrollX)
+ continue;
+ if (evt.begin - minTicks > ScrollX + visibleTicks)
+ break;
+ double penY = topMargin + ClientRectangle.Top;
+
+ if (evt.type.HasFlag (DbgEvtType.Widget)) {
+ DbgWidgetEvent eW = evt as DbgWidgetEvent;
+ int lIdx = eW.InstanceIndex - ScrollY;
+ if (lIdx >= 0 && lIdx <= visibleLines) {
+
+ penY += (lIdx) * fe.Height;
+
+ ctx.SetSource (evt.Color);
+ ctx.Rectangle (getWidgetEvtBounds (evt, ref cb, penY));
+ ctx.Fill ();
+ }
+ } else if (evt.type.HasFlag (DbgEvtType.IFace)) {
+ double x = xScale * (evt.begin - minTicks - ScrollX);
+ double w = Math.Max (Math.Max (2.0, 2.0 * xScale), (double)(evt.end - evt.begin) * xScale);
+ if (x < 0.0) {
+ w += x;
+ x = 0.0;
+ }
+ x += leftMargin + cb.Left;
+ double rightDiff = x + w - cb.Right;
+ if (rightDiff > 0)
+ w -= rightDiff;
+ //ctx.SetSource (0.9,0.9,0.0,0.1);
+ ctx.SetSource (evt.Color.AdjustAlpha(0.15));
+ ctx.Rectangle (x, cb.Top + topMargin, w, cb.Height);
+ ctx.Fill ();
+ }
+ }
+ drawEvents (ctx, evt.Events);
+ }
+ }
+
+ DbgEvtType currentFilter;
+ protected override void onDraw (Context gr)
+ {
+ base.onDraw (gr);
+
+ setFontForContext (gr);
+
+ if (widgets == null)
+ return;
+
+ gr.LineWidth = 1.0;
+
+ Rectangle cb = ClientRectangle;
+
+ double penY = topMargin + ClientRectangle.Top;
+
+ for (int i = 0; i < visibleLines; i++) {
+ if (i + ScrollY >= widgets.Count)
+ break;
+ int gIdx = i + ScrollY;
+ DbgWidgetRecord g = widgets [gIdx];
+
+ penY += fe.Height;
+
+ gr.SetSource (Crow.Colors.Jet);
+ gr.MoveTo (cb.X, penY - 0.5);
+ gr.LineTo (cb.Right, penY - 0.5);
+ gr.Stroke ();
+
+ double penX = 5.0 * g.xLevel + cb.Left;
+
+ if (g.xLevel == 0)
+ gr.SetSource (Crow.Colors.LightSalmon);
+ else if (currentLine == g.listIndex)
+ gr.SetSource(Colors.RoyalBlue);
+ else
+ Foreground.SetAsSource (IFace, gr);
+
+ gr.MoveTo (penX, penY - gr.FontExtents.Descent);
+ gr.ShowText (g.name + gIdx);
+ }
+
+ currentFilter = Filter;
+ drawEvents (gr, events);
+
+ gr.MoveTo (cb.Left, topMargin - 0.5 + cb.Top);
+ gr.LineTo (cb.Right, topMargin - 0.5 + cb.Top);
+
+ gr.MoveTo (leftMargin + cb.Left, cb.Top);
+ gr.LineTo (leftMargin + cb.Left, cb.Bottom);
+ gr.SetSource (Crow.Colors.Grey);
+
+ penY = topMargin + ClientRectangle.Top;
+
+ //graduation
+ long largeGrad = long.Parse ("1" + new string ('0', visibleTicks.ToString ().Length - 1));
+ long smallGrad = Math.Max (1, largeGrad / 10);
+
+ long firstVisibleTicks = minTicks + ScrollX;
+ long curGrad = firstVisibleTicks - firstVisibleTicks % smallGrad + smallGrad;
+
+ long gg = curGrad - ScrollX - minTicks;
+ while (gg < visibleTicks ) {
+ double x = (double)gg * xScale + leftMargin + cb.Left;
+
+ gr.MoveTo (x, penY - 0.5);
+ if (curGrad % largeGrad == 0) {
+ gr.LineTo (x, penY - 8.5);
+ string str = ticksToMS(curGrad);
+ TextExtents te = gr.TextExtents (str);
+ gr.RelMoveTo (-0.5 * te.Width, -2.0);
+ gr.ShowText (str);
+ }else
+ gr.LineTo (x, penY - 2.5);
+
+ curGrad += smallGrad;
+ gg = curGrad - ScrollX - minTicks;
+ }
+
+ gr.Stroke ();
+
+
+
+ }
+ string ticksToMS(long ticks) => Math.Round ((double)ticks / Stopwatch.Frequency * 1000.0, 2).ToString();
+ public override void Paint (Context ctx)
+ {
+ base.Paint (ctx);
+
+ Rectangle r = new Rectangle(mousePos.X, 0, 1, Slot.Height);
+ Rectangle ctxR = ContextCoordinates (r);
+ Rectangle cb = ClientRectangle;
+ ctx.LineWidth = 1.0;
+ if (hoverTick >= 0) {
+ double x = xScale * (hoverTick - minTicks - ScrollX) + leftMargin;
+ if (x - Math.Truncate (x) > 0.5)
+ x = Math.Truncate (x) + 0.5;
+ else
+ x = Math.Truncate (x) - 0.5;
+ ctx.MoveTo (x, cb.Top + topMargin - 4.0);
+ ctx.LineTo (x, cb.Bottom);
+ ctx.SetSource (0.7,0.7,0.7,0.5);
+ ctx.Stroke();
+ }
+ if (currentTick >= 0) {
+ double x = xScale * (currentTick - minTicks - ScrollX) + leftMargin;
+ if (x > leftMargin && x < cb.Right) {
+ if (x - Math.Truncate (x) > 0.5)
+ x = Math.Truncate (x) + 0.5;
+ else
+ x = Math.Truncate (x) - 0.5;
+ ctx.MoveTo (x, cb.Top);
+ ctx.LineTo (x, cb.Bottom);
+ ctx.SetSource (0.2,0.7,1.0,0.6);
+ ctx.Stroke();
+ }
+ }
+
+ setFontForContext (ctx);
+
+ string str = ticksToMS(hoverTick);
+
+ ctx.MoveTo (ctxR.X - ctx.TextExtents (str).Width / 2, ctxR.Y + fe.Height);
+ ctx.ShowText (str);
+
+ ctx.Operator = Operator.Add;
+
+ if (hoverLine >= 0) {
+ double y = fe.Height * (hoverLine - ScrollY) + topMargin + cb.Top;
+ r = new Rectangle (cb.Left, (int)y, cb.Width, (int)fe.Height);
+
+ ctx.SetSource (0.1, 0.1, 0.1, 0.4);
+ ctx.Rectangle (ContextCoordinates (r));
+ ctx.Fill ();
+
+ if (hoverEvent is DbgWidgetEvent wevt) {
+ ctx.SetSource (1.0,1.0,1.0,0.7);
+ ctx.SetDash (new double[] {1, 2});
+ ctx.Rectangle ((Rectangle)getWidgetEvtBounds (wevt, ref cb, y).Inflated (1), 1);
+ }
+ }
+
+ if (currentLine >= ScrollY && currentLine < scrollY + visibleLines) {
+ double y = fe.Height * (currentLine - ScrollY) + topMargin + cb.Top;
+ r = new Rectangle (cb.Left, (int)y, cb.Width, (int)fe.Height);
+
+ ctx.SetSource (0.1, 0.1, 0.7, 0.2);
+ ctx.Rectangle (ContextCoordinates (r));
+ ctx.Fill ();
+ }
+
+ if (selStart < 0 || selEnd < 0) {
+ ctx.Operator = Operator.Over;
+ return;
+ }
+ double selStartX = (double)(selStart - ScrollX - minTicks) * xScale + leftMargin + cb.Left;
+ double selEndX = (double)(selEnd - ScrollX - minTicks) * xScale + leftMargin + cb.Left;
+
+ if (selStartX < selEndX) {
+ ctxR.X = (int)selStartX;
+ ctxR.Width = (int)(selEndX - selStartX);
+ } else {
+ ctxR.X = (int)selEndX;
+ ctxR.Width = (int)(selStartX - selEndX);
+ }
+
+ ctxR.Width = Math.Max (1, ctxR.Width);
+ ctx.Rectangle (ctxR);
+ ctx.SetSource (0.0,0.2,0.8,0.15);
+ //ctx.SetSource (Colors.Jet);
+ ctx.Fill();
+ ctx.Operator = Operator.Over;
+
+ str = $"{ticksToMS(Math.Abs (selEnd - selStart))} (ms)";
+
+ ctx.MoveTo (ctxR.Center.X - ctx.TextExtents (str).Width / 2, ctxR.Y + fe.Height);
+ ctx.SetSource (Colors.Black);
+ ctx.ShowText (str);
+
+
+
+ }
+ public override void OnLayoutChanges (LayoutingType layoutType)
+ {
+ base.OnLayoutChanges (layoutType);
+ switch (layoutType) {
+ case LayoutingType.Width:
+ if (xScale < 0) {
+ visibleTicks = maxTicks - minTicks;
+ XScale = (ClientRectangle.Width - leftMargin) / visibleTicks;
+ }
+ updateVisibleTicks ();
+ break;
+ case LayoutingType.Height:
+ updateVisibleLines ();
+ break;
+ }
+ }
+
+ public override void onMouseLeave (object sender, MouseMoveEventArgs e)
+ {
+ base.onMouseLeave (sender, e);
+ hoverLine = -1;
+ hoverTick = 0;
+ }
+ public override void onMouseMove (object sender, MouseMoveEventArgs e)
+ {
+ long lastTick = hoverTick;
+ int lastLine = hoverLine;
+ updateMouseLocalPos (e.Position);
+
+ if ((IFace.IsDown (Glfw.MouseButton.Left) || IFace.IsDown (Glfw.MouseButton.Middle)) && selStart >= 0)
+ selEnd = hoverTick;
+ else if (IFace.IsDown(Glfw.MouseButton.Right)) {
+ if (lastTick >= 0 && hoverTick >= 0)
+ ScrollX += lastTick - hoverTick;
+ if (lastLine >= 0 && hoverLine >= 0)
+ ScrollY += lastLine - hoverLine;
+ updateMouseLocalPos (e.Position);
+ } else if (widgets != null) {
+ HoverWidget = (hoverLine < 0 || hoverLine >= widgets.Count) ? null : widgets [hoverLine];
+ //HoverEvent = hoverWidget?.Events.FirstOrDefault (ev => ev.begin <= hoverTick && ev.end >= hoverTick);
+ double tickPerPixel = (double)visibleTicks / ClientRectangle.Width;
+ //Console.WriteLine ($"ticks per pixel: {tickPerPixel}");
+ Task.Run (() => findHoverEvent (hoverWidget, hoverTick, (int)tickPerPixel));
+ }
+
+ RegisterForRepaint();
+
+ e.Handled = true;
+ base.onMouseMove (sender, e);
+ }
+ void findHoverEvent (DbgWidgetRecord widget, long tick, long precision = 0) {
+ DbgEvent tmp = widget?.Events.FirstOrDefault (ev => ev.begin - precision <= tick && ev.end + precision >= tick);
+ if (tmp == null) {
+ tmp = Events.Where(e=>e.type.HasFlag(DbgEvtType.IFace)).Where (ev => ev.begin - precision <= tick && ev.end + precision >= tick).FirstOrDefault();
+ while(tmp != null) {
+ DbgEvent che = tmp.Events?.Where(e=>e.type.HasFlag(DbgEvtType.IFace)).Where (ev => ev.begin - precision <= tick && ev.end + precision >= tick).FirstOrDefault();
+ if (che == null)
+ break;
+ tmp = che;
+ }
+ } else {
+ while(tmp != null) {
+ DbgEvent che = tmp.Events?.OfType<DbgWidgetEvent>()?.Where(ev=>ev.InstanceIndex == widget.listIndex && ev.begin - precision <= tick && ev.end + precision >= tick).FirstOrDefault();
+ if (che == null)
+ break;
+ tmp = che;
+ }
+ }
+ HoverEvent = tmp;
+ }
+ public override void onMouseClick(object sender, MouseButtonEventArgs e)
+ {
+ if (e.Button == Glfw.MouseButton.Left) {
+ if (selEnd < 0) {
+ currentTick = hoverTick;
+ currentLine = hoverLine;
+ CurrentWidget = hoverWidget;
+ CurrentEvent = hoverEvent;
+ }
+ selStart = -1;
+ selEnd = -1;
+ }
+
+ e.Handled = true;
+ base.onMouseClick(sender, e);
+ }
+ public override void onMouseDown (object sender, MouseButtonEventArgs e)
+ {
+ if (e.Button == Glfw.MouseButton.Left || e.Button == Glfw.MouseButton.Middle) {
+ selStart = hoverTick;
+ selEnd = -1;
+ }
+
+ RegisterForRedraw ();
+ e.Handled = true;
+ base.onMouseDown (sender, e);
+ }
+ public override void onMouseUp (object sender, MouseButtonEventArgs e)
+ {
+
+ if (e.Button == Glfw.MouseButton.Left && selEnd > 0 && selEnd != selStart) {
+ long scrX = 0;
+ if (selStart < selEnd) {
+ visibleTicks = selEnd - selStart;
+ scrX = selStart - minTicks;
+ } else {
+ visibleTicks = selStart - selEnd;
+ scrX = selEnd - minTicks;
+ }
+ XScale = (ClientRectangle.Width - leftMargin) / visibleTicks;
+ ScrollX = scrX;
+ }
+
+ RegisterForRedraw ();
+ e.Handled = true;
+ base.onMouseUp (sender, e);
+ }
+
+ /// <summary> Process scrolling vertically, or if shift is down, vertically </summary>
+ public override void onMouseWheel (object sender, MouseWheelEventArgs e)
+ {
+ //base.onMouseWheel (sender, e);
+
+ if (IFace.Shift)
+ ScrollX -= (int)((double)(e.Delta * MouseWheelSpeed) / xScale);
+ else if (IFace.Ctrl)
+ ScrollY -= e.Delta * MouseWheelSpeed;
+ else {
+ if (e.Delta > 0) {
+ XScale *= 2.0;
+ } else {
+ if (MaxScrollX > 0)
+ XScale *= 0.5;
+ }
+ ScrollX = (long)(hoverTick - (long)((double)Math.Max(0, mousePos.X - (long)leftMargin) / xScale) - minTicks);
+ }
+ }
+
+ public override void onKeyDown (object sender, KeyEventArgs e)
+ {
+ base.onKeyDown (sender, e);
+
+ if (e.Key == Glfw.Key.F3) {
+ if (selEnd < 0)
+ return;
+ if (selEnd < selStart)
+ zoom (selEnd, selStart);
+ else
+ zoom (selStart, selEnd);
+ selEnd = selStart = -1;
+ }
+ }
+
+ void updateMargins ()
+ {
+ leftMargin = topMargin = 0.0;
+
+ if (widgets == null)
+ return;
+
+ using (Context gr = new Context (IFace.surf)) {
+ double maxNameWidth = 0.0;
+
+ setFontForContext (gr);
+
+ foreach (DbgWidgetRecord o in widgets) {
+ double nameWidth = gr.TextExtents (o.name).Width + 5.0 * o.xLevel;
+ if (nameWidth > maxNameWidth)
+ maxNameWidth = nameWidth;
+ }
+
+ leftMargin = 10.5 + maxNameWidth;
+ topMargin = 2.0 * fe.Height;
+
+ RegisterForGraphicUpdate ();
+ }
+ }
+
+ void updateVisibleLines ()
+ {
+ visibleLines = fe.Height < 1 ? 1 : (int)Math.Ceiling (((double)ClientRectangle.Height - topMargin) / fe.Height);
+ NotifyValueChanged ("VisibleLines", visibleLines);
+ updateMaxScrollY ();
+ }
+ void updateVisibleTicks ()
+ {
+ visibleTicks = Math.Max (0, (long)((double)(ClientRectangle.Width - leftMargin) / XScale));
+ NotifyValueChanged ("VisibleTicks", visibleTicks);
+ updateMaxScrollX ();
+ }
+
+ void updateMaxScrollX ()
+ {
+ if (widgets == null) {
+ MaxScrollX = 0;
+ } else {
+ long tot = maxTicks - minTicks;
+ MaxScrollX = Math.Max (0L, tot - visibleTicks);
+ NotifyValueChanged ("ChildWidthRatio", (double)visibleTicks / tot);
+ }
+ }
+ void updateMaxScrollY ()
+ {
+ if (widgets == null)
+ MaxScrollY = 0;
+ else {
+ MaxScrollY = Math.Max (0, widgets.Count + 1 - visibleLines);
+ NotifyValueChanged ("ChildHeightRatio", (double)visibleLines / (widgets.Count + 1));
+ }
+ }
+
+ void updateMouseLocalPos (Point mPos)
+ {
+ Rectangle r = ScreenCoordinates (Slot);
+ Rectangle cb = ClientRectangle;
+ cb.Left += (int)leftMargin;
+ cb.Width -= (int)leftMargin;
+ cb.Y += (int)topMargin;
+ cb.Height -= (int)topMargin;
+
+ mousePos = mPos - r.Position;
+
+ mousePos.X = Math.Max (cb.X, mousePos.X);
+ mousePos.X = Math.Min (cb.Right, mousePos.X);
+
+ if (mousePos.Y < cb.Top || mousePos.Y > cb.Bottom)
+ hoverLine = -1;
+ else
+ hoverLine = (int)((double)(mousePos.Y - cb.Top) / fe.Height) + ScrollY;
+
+ NotifyValueChanged ("CurrentLine", hoverLine);
+
+ mousePos.Y = Math.Max (cb.Y, mousePos.Y);
+ mousePos.Y = Math.Min (cb.Bottom, mousePos.Y);
+
+ hoverTick = (long)((double)(mousePos.X - cb.X) / xScale) + minTicks + ScrollX;
+ RegisterForRedraw ();
+ }
+ void zoom (long start, long end) {
+ //Rectangle cb = ClientRectangle;
+ //cb.X += (int)leftMargin;
+ XScale = ((double)ClientRectangle.Width - leftMargin)/(end - start);
+ ScrollX = (int)(start - minTicks);
+ }
+
+
+ long scrollX, maxScrollX;
+ int scrollY, maxScrollY, mouseWheelSpeed;
+
+ /// <summary>
+ /// if true, key stroke are handled in derrived class
+ /// </summary>
+ protected bool KeyEventsOverrides = false;
+
+ /// <summary> Horizontal Scrolling Position </summary>
+ [DefaultValue(0)]
+ public virtual long ScrollX {
+ get => scrollX;
+ set {
+ if (scrollX == value)
+ return;
+
+ long newS = value;
+ if (newS < 0)
+ newS = 0;
+ else if (newS > maxScrollX)
+ newS = maxScrollX;
+
+ if (newS == scrollX)
+ return;
+
+ scrollX = newS;
+
+ NotifyValueChangedAuto (scrollX);
+ RegisterForGraphicUpdate ();
+ }
+ }
+ /// <summary> Vertical Scrolling Position </summary>
+ [DefaultValue(0)]
+ public virtual int ScrollY {
+ get => scrollY;
+ set {
+ if (scrollY == value)
+ return;
+
+ int newS = value;
+ if (newS < 0)
+ newS = 0;
+ else if (newS > maxScrollY)
+ newS = maxScrollY;
+
+ if (newS == scrollY)
+ return;
+
+ scrollY = newS;
+
+ NotifyValueChangedAuto (scrollY);
+ RegisterForGraphicUpdate ();
+
+ if (widgets == null)
+ return;
+
+ Rectangle cb = ClientRectangle;
+ cb.Left += (int)leftMargin;
+ cb.Width -= (int)leftMargin;
+ cb.Y += (int)topMargin;
+ cb.Height -= (int)topMargin;
+
+ if (mousePos.Y < cb.Top || mousePos.Y > cb.Bottom)
+ hoverLine = -1;
+ else
+ hoverLine = (int)((double)(mousePos.Y - cb.Top) / fe.Height) + ScrollY;
+
+ NotifyValueChanged ("CurrentLine", hoverLine);
+ }
+ }
+ /// <summary> Horizontal Scrolling maximum value </summary>
+ [DefaultValue(0)]
+ public virtual long MaxScrollX {
+ get => maxScrollX;
+ set {
+ if (maxScrollX == value)
+ return;
+
+ maxScrollX = Math.Max(0, value);
+
+ if (scrollX > maxScrollX)
+ ScrollX = maxScrollX;
+
+ NotifyValueChangedAuto (maxScrollX);
+ RegisterForGraphicUpdate ();
+ }
+ }
+ /// <summary> Vertical Scrolling maximum value </summary>
+ [DefaultValue(0)]
+ public virtual int MaxScrollY {
+ get => maxScrollY;
+ set {
+ if (maxScrollY == value)
+ return;
+
+ maxScrollY = Math.Max (0, value);
+
+ if (scrollY > maxScrollY)
+ ScrollY = maxScrollY;
+
+ NotifyValueChangedAuto (maxScrollY);
+ RegisterForGraphicUpdate ();
+ }
+ }
+ /// <summary> Mouse Wheel Scrolling multiplier </summary>
+ [DefaultValue(1)]
+ public virtual int MouseWheelSpeed {
+ get => mouseWheelSpeed;
+ set {
+ if (mouseWheelSpeed == value)
+ return;
+
+ mouseWheelSpeed = value;
+
+ NotifyValueChangedAuto (mouseWheelSpeed);
+ }
+ }
+ }
+}
+
+
--- /dev/null
+// Copyright (c) 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.Threading;
+using Crow;
+using Crow.Drawing;
+using IML = Crow.IML;
+
+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)
+ {
+ SolidBackground = false;
+ initBackend (true);
+
+ clientRectangle = new Rectangle (0, 0, 100, 100);
+ CreateMainSurface (ref clientRectangle);
+ }
+
+ public override void Run()
+ {
+ Init();
+
+ Thread t = new Thread (interfaceThread) {
+ IsBackground = true
+ };
+ t.Start ();
+ }
+ public bool Terminate;
+ string source;
+ Action delRegisterForRepaint;//call RegisterForRepaint in the container widget (DebugInterfaceWidget)
+ Action<Exception> delSetCurrentException;
+ //Func<object> delGetScreenCoordinate;
+
+ void interfaceThread () {
+ while (!Terminate) {
+ try
+ {
+ Update();
+ }
+ catch (System.Exception ex)
+ {
+ while (Monitor.IsEntered(LayoutMutex)) {
+ Console.WriteLine ($"[DebugIFace] trying to exit LayoutMutex on error");
+ Monitor.Exit (LayoutMutex);
+ }
+ while (Monitor.IsEntered(UpdateMutex)) {
+ Console.WriteLine ($"[DebugIFace] trying to exit UpdateMutex on error");
+ Monitor.Exit (UpdateMutex);
+ }
+ while (Monitor.IsEntered(ClippingMutex)) {
+ Console.WriteLine ($"[DebugIFace] trying to exit ClippingMutex on error");
+ Monitor.Exit (ClippingMutex);
+ }
+
+
+ /*while (Monitor.IsEntered(LayoutMutex))
+ Monitor.Exit (LayoutMutex);
+ while (Monitor.IsEntered(UpdateMutex))
+ Monitor.Exit (UpdateMutex);
+ while (Monitor.IsEntered(ClippingMutex))
+ Monitor.Exit (ClippingMutex);*/
+ delSetCurrentException (ex);
+ Console.WriteLine ($"[DbgIFace] {ex}");
+ ClearInterface();
+ Thread.Sleep(1000);
+ }
+
+ /*if (IsDirty)
+ delRegisterForRepaint(); */
+
+ Thread.Sleep (UPDATE_INTERVAL);
+ }
+ }
+ public IntPtr SurfacePointer {
+ get {
+ lock(UpdateMutex)
+ return surf.Handle;
+ }
+ }
+ public void RegisterDebugInterfaceCallback (object w){
+ Type t = w.GetType();
+ //delRegisterForRepaint = (Action)Delegate.CreateDelegate(typeof(Action), w, t.GetMethod("RegisterForRepaint"));
+ delSetCurrentException = (Action<Exception>)Delegate.CreateDelegate(typeof(Action<Exception>), w, t.GetProperty("CurrentException").GetSetMethod());
+ //delGetScreenCoordinate = (Func<object>)Delegate.CreateDelegate(typeof(Func<object>), w, t.GetMethod("GetScreenCoordinates"));
+ }
+ /*public void ResetDirtyState () {
+ IsDirty = false;
+ }*/
+ public string Source {
+ set {
+ if (source == value)
+ return;
+ source = value;
+ if (string.IsNullOrEmpty(source))
+ return;
+ delSetCurrentException(null);
+ try
+ {
+ lock (UpdateMutex) {
+ Widget tmp = CreateITorFromIMLFragment (source).CreateInstance();
+ ClearInterface();
+ AddWidget (tmp);
+ tmp.DataSource = this;
+ }
+ }
+ catch (IML.InstantiatorException iTorEx)
+ {
+ delSetCurrentException(iTorEx.InnerException);
+ }
+ catch (System.Exception ex)
+ {
+ delSetCurrentException(ex);
+ }
+ }
+ }
+ public void ReloadIml () {
+ if (string.IsNullOrEmpty (source))
+ return;
+ string src = source;
+ Source = null;
+ Source = src;
+ }
+ public void Resize (int width, int height) {
+ if (!HaveVkvgBackend)
+ ProcessResize (new Rectangle(0,0,width, height));
+ }
+ public override void ProcessResize(Rectangle bounds) {
+ lock (UpdateMutex) {
+ clientRectangle = bounds.Size;
+
+ CreateMainSurface (ref clientRectangle);
+
+ foreach (Widget g in GraphicTree)
+ g.RegisterForLayouting (LayoutingType.All);
+
+ RegisterClip (clientRectangle);
+ }
+ }
+ /*public override void ForceMousePosition()
+ {
+ Point p = (Point)delGetScreenCoordinate();
+ Glfw.Glfw3.SetCursorPosition (WindowHandle, p.X + MousePosition.X, p.Y + MousePosition.Y);
+ }*/
+ }
+}
\ No newline at end of file
--- /dev/null
+// Copyright (c) 2013-2019 Bruyère Jean-Philippe <jp_bruyere@hotmail.com>
+//
+// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
+
+using System;
+using Glfw;
+using System.Reflection;
+using System.Runtime.Loader;
+using System.IO;
+using Crow.Drawing;
+using System.Diagnostics;
+using System.Collections.Generic;
+using Crow.DebugLogger;
+using System.Linq;
+using CrowEditBase;
+using System.Threading;
+using Crow.Text;
+using System.Runtime.InteropServices;
+
+using static CrowEditBase.CrowEditBase;
+using CECrowPlugin;
+
+namespace Crow
+{
+ public class DebugInterfaceWidget : Widget {
+ CrowService crowIFaceService;
+ public CrowService CrowIFaceService {
+ get => crowIFaceService;
+ set {
+ if (crowIFaceService == value)
+ return;
+ crowIFaceService = value;
+ NotifyValueChangedAuto (crowIFaceService);
+ }
+ }
+ public DebugInterfaceWidget () : base () {
+ Thread t = new Thread (backgroundThreadFunc);
+ t.IsBackground = true;
+ t.Start ();
+ }
+ protected void backgroundThreadFunc () {
+ Stopwatch sw = Stopwatch.StartNew ();
+ int refreshRate = crowIFaceService == null ? 10 : crowIFaceService.RefreshRate;
+ while (true) {
+ if (sw.ElapsedMilliseconds > 200) {
+ if (Document != null && document.TryGetState (this, out List<TextChange> changes)) {
+ foreach (TextChange tc in changes)
+ updateIMLSource (tc);
+ }
+ refreshRate = crowIFaceService == null ? 10 : crowIFaceService.RefreshRate;
+ sw.Restart ();
+ }
+ if (crowIFaceService != null && crowIFaceService.GetDirtyState)
+ RegisterForRepaint ();
+ Thread.Sleep (refreshRate);
+ }
+ }
+ void updateIMLSource (TextChange change) {
+ ReadOnlySpan<char> src = imlSource.AsSpan ();
+ Span<char> tmp = stackalloc char[src.Length + (change.ChangedText.Length - change.Length)];
+ //Console.WriteLine ($"{Text.Length,-4} {change.Start,-4} {change.Length,-4} {change.ChangedText.Length,-4} tmp:{tmp.Length,-4}");
+ src.Slice (0, change.Start).CopyTo (tmp);
+ change.ChangedText.AsSpan ().CopyTo (tmp.Slice (change.Start));
+ src.Slice (change.End).CopyTo (tmp.Slice (change.Start + change.ChangedText.Length));
+
+ imlSource = tmp.ToString ();
+
+ crowIFaceService?.LoadIML (imlSource);
+
+ RegisterForRedraw ();
+ }
+ string imlSource;
+
+ ImlDocument document;
+ public TextDocument Document {
+ get => document;
+ set {
+ if (document == value)
+ return;
+
+ if (value is ImlDocument imlDoc) {
+ document?.UnregisterClient (this);
+ imlSource = "";
+ document = imlDoc;
+ document?.RegisterClient (this);
+
+ NotifyValueChangedAuto (document);
+ RegisterForGraphicUpdate ();
+ }
+ }
+ }
+
+ protected override void onInitialized(object sender, EventArgs e)
+ {
+ base.onInitialized(sender, e);
+
+
+ CrowIFaceService = App.GetService<CrowService> ();
+ crowIFaceService?.Start ();
+ }
+ /*public CommandGroup LoggerCommands =>
+ new CommandGroup(
+ new Command("Get logs", () => getLog ()),
+ //new Command("Reset logs", () => delResetDebugger ()),
+ new Command("Save to file", () => saveLogToDebugLogFilePath ()),
+ new Command("Load from file", () => loadLogFromDebugLogFilePath ())
+ );*/
+ public CommandGroup WindowCommands => new CommandGroup (
+ crowIFaceService.CMDRefresh,
+ crowIFaceService.CMDStartRecording,
+ crowIFaceService.CMDStopRecording,
+ crowIFaceService.CMDOpenConfig,
+ (Parent.LogicalParent as DockWindow).CMDClose
+ );
+
+
+ protected override void onDraw(Context gr)
+ {
+ Console.WriteLine("onDraw");
+ gr.SetSource(Colors.RoyalBlue);
+ gr.Paint();
+ }
+ public override bool CacheEnabled { get => true; set => base.CacheEnabled = true; }
+
+ public override void onKeyDown(object sender, KeyEventArgs e) => crowIFaceService?.onKeyDown(e);
+ public override void onKeyUp(object sender, KeyEventArgs e) => crowIFaceService?.onKeyUp(e);
+ public override void onKeyPress(object sender, KeyPressEventArgs e) => crowIFaceService?.onKeyPress(e);
+ public override void onMouseMove(object sender, MouseMoveEventArgs e) {
+ Point m = ScreenPointToLocal (e.Position);
+ crowIFaceService?.onMouseMove(new MouseMoveEventArgs(m.X,m.Y, e.XDelta, e.YDelta));
+ }
+ public override void onMouseDown(object sender, MouseButtonEventArgs e) => crowIFaceService?.onMouseDown(e);
+ public override void onMouseUp(object sender, MouseButtonEventArgs e) => crowIFaceService?.onMouseUp(e);
+ public override void onMouseWheel(object sender, MouseWheelEventArgs e) => crowIFaceService?.onMouseWheel(e);
+
+ protected override void RecreateCache()
+ {
+ bmp?.Dispose ();
+
+ if (crowIFaceService != null && crowIFaceService.IsRunning) {
+ crowIFaceService.Resize (Slot.Width, Slot.Height);
+ if (crowIFaceService.HasVkvgBackend)
+ bmp = IFace.CreateSurfaceForData (crowIFaceService.SurfacePointer, Slot.Width, Slot.Height);
+ else
+ bmp = IFace.CreateSurface (crowIFaceService.SurfacePointer);
+ bmp = Crow.Drawing.Surface.Lookup (crowIFaceService.SurfacePointer, false);
+ }
+
+ IsDirty = false;
+ }
+ protected override void UpdateCache(Context ctx)
+ {
+ if (bmp != null) {
+ paintCache (ctx, Slot + Parent.ClientRectangle.Position);
+ crowIFaceService?.ResetDirtyState ();
+ }
+ }
+
+
+ protected override void Dispose(bool disposing)
+ {
+ crowIFaceService?.Stop ();
+ base.Dispose(disposing);
+ }
+
+ }
+}
\ 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 CrowEdit.Xml;
+
+namespace CECrowPlugin
+{
+ public class ImlDocument : XmlDocument {
+
+ public ImlDocument (string fullPath) : base (fullPath) {
+ App.GetService<CrowService> ()?.Start ();
+ }
+
+ string[] allWidgetNames = typeof (Widget).Assembly.GetExportedTypes ().Where(t=>typeof(Widget).IsAssignableFrom (t))
+ .Select (s => s.Name).ToArray ();
+
+
+ IEnumerable<MemberInfo> getAllCrowTypeMembers (string crowTypeName) {
+ Type crowType = IML.Instantiator.GetWidgetTypeFromName (crowTypeName);
+ return crowType.GetMembers (BindingFlags.Public | BindingFlags.Instance).
+ Where (m=>((m is PropertyInfo pi && pi.CanWrite) || (m is EventInfo)) &&
+ m.GetCustomAttribute<XmlIgnoreAttribute>() == null);
+ }
+ MemberInfo getCrowTypeMember (string crowTypeName, string memberName) {
+ Type crowType = IML.Instantiator.GetWidgetTypeFromName (crowTypeName);
+ return crowType.GetMember (memberName, BindingFlags.Public | BindingFlags.Instance).FirstOrDefault ();
+ }
+ public override IList GetSuggestions (int pos) {
+ base.GetSuggestions (pos);
+#if DEBUG
+ Console.WriteLine ($"Current Token: {currentToken} Current Node: {currentNode}");
+#endif
+
+ if (currentToken.GetTokenType() == XmlTokenType.ElementOpen)
+ return new List<string> (allWidgetNames);
+ if (currentToken.GetTokenType() == XmlTokenType.ElementName)
+ return allWidgetNames.Where (s => s.StartsWith (currentToken.AsString (Source), StringComparison.OrdinalIgnoreCase)).ToList ();
+ if (currentNode is AttributeSyntax attribNode) {
+ if (currentNode.Parent is ElementTagSyntax eltTag) {
+ if (eltTag.NameToken.HasValue) {
+ if (currentToken.GetTokenType() == XmlTokenType.AttributeName) {
+ return getAllCrowTypeMembers (eltTag.NameToken.Value.AsString (Source))
+ .Where (s => s.Name.StartsWith (currentToken.AsString (Source), StringComparison.OrdinalIgnoreCase)).ToList ();
+ } else if (attribNode.NameToken.HasValue) {
+ if (currentToken.GetTokenType() == XmlTokenType.AttributeValue) {
+ MemberInfo mi = getCrowTypeMember (
+ eltTag.NameToken.Value.AsString (Source), attribNode.NameToken.Value.AsString (Source));
+ if (mi is PropertyInfo pi) {
+ if (pi.Name == "Style")
+ return App.Styling.Keys
+ .Where (s => s.StartsWith (currentToken.AsString (Source), StringComparison.OrdinalIgnoreCase)).ToList ();
+ if (pi.PropertyType.IsEnum)
+ return Enum.GetNames (pi.PropertyType)
+ .Where (s => s.StartsWith (currentToken.AsString (Source), StringComparison.OrdinalIgnoreCase)).ToList ();
+ if (pi.PropertyType == typeof(bool))
+ return (new string[] {"true", "false"}).
+ Where (s => s.StartsWith (currentToken.AsString (Source), StringComparison.OrdinalIgnoreCase)).ToList ();
+ if (pi.PropertyType == typeof (Measure))
+ return (new string[] {"Stretched", "Fit"}).
+ Where (s => s.StartsWith (currentToken.AsString (Source), StringComparison.OrdinalIgnoreCase)).ToList ();
+ if (pi.PropertyType == typeof (Fill))
+ return EnumsNET.Enums.GetValues<Colors> ()
+ .Where (s => s.ToString().StartsWith (currentToken.AsString (Source), StringComparison.OrdinalIgnoreCase)).ToList ();
+ }
+ } else if (currentToken.GetTokenType() == XmlTokenType.AttributeValueOpen) {
+ MemberInfo mi = getCrowTypeMember (
+ eltTag.NameToken.Value.AsString (Source), attribNode.NameToken.Value.AsString (Source));
+ if (mi is PropertyInfo pi) {
+ if (pi.Name == "Style")
+ return App.Styling.Keys.ToList ();
+ if (pi.PropertyType.IsEnum)
+ return Enum.GetNames (pi.PropertyType).ToList ();
+ if (pi.PropertyType == typeof(bool))
+ return new List<string> (new string[] {"true", "false"});
+ if (pi.PropertyType == typeof (Fill))
+ return EnumsNET.Enums.GetValues<Colors> ().ToList ();
+ if (pi.PropertyType == typeof (Measure))
+ return new List<string> (new string[] {"Stretched", "Fit"});
+ }
+ }
+ }
+ }
+ }
+ } else if (currentToken.GetTokenType() != XmlTokenType.AttributeValueClose &&
+ currentToken.GetTokenType() != XmlTokenType.EmptyElementClosing &&
+ currentToken.GetTokenType() != XmlTokenType.ClosingSign &&
+ currentNode is ElementStartTagSyntax eltStartTag) {
+ if (currentToken.GetTokenType() == XmlTokenType.AttributeName)
+ return getAllCrowTypeMembers (eltStartTag.NameToken.Value.AsString (Source))
+ .Where (s => s.Name.StartsWith (currentToken.AsString (Source), StringComparison.OrdinalIgnoreCase)).ToList ();
+ //else if (currentToken.Type == TokenType.ElementName)
+ // Suggestions = getAllCrowTypeMembers (eltStartTag.NameToken.Value.AsString (Source)).ToList ();
+ } else {
+ /*SyntaxNode curNode = source.FindNodeIncludingPosition (pos);
+ Console.WriteLine ($"Current Node: {curNode}");
+ if (curNode is ElementStartTagSyntax eltStartTag &&
+ (currentToken.Type != TokenType.ClosingSign && currentToken.Type != TokenType.EmptyElementClosing && currentToken.Type != TokenType.Unknown)) {
+ Suggestions = getAllCrowTypeMembers (eltStartTag.NameToken.Value.AsString (Source)).ToList ();
+ } else*/
+
+ }
+ return null;
+ }
+ public override TextChange? GetCompletionForCurrentToken (object suggestion, out TextSpan? newSelection) {
+ newSelection = null;
+
+ string selectedSugg = suggestion is MemberInfo mi ?
+ mi.Name : suggestion?.ToString ();
+ if (selectedSugg == null)
+ return null;
+
+ if (currentToken.GetTokenType() == XmlTokenType.ElementOpen ||
+ currentToken.GetTokenType() == XmlTokenType.WhiteSpace ||
+ currentToken.GetTokenType() == XmlTokenType.AttributeValueOpen)
+ return new TextChange (currentToken.End, 0, selectedSugg);
+
+ if (currentToken.GetTokenType() == XmlTokenType.AttributeName && currentNode is AttributeSyntax attrib) {
+ if (attrib.ValueToken.HasValue) {
+ TextChange tc = new TextChange (currentToken.Start, currentToken.Length, selectedSugg);
+ newSelection = new TextSpan(
+ attrib.ValueToken.Value.Start + tc.CharDiff + 1,
+ attrib.ValueToken.Value.End + tc.CharDiff - 1
+ );
+ return tc;
+ } else {
+ newSelection = TextSpan.FromStartAndLength (currentToken.Start + selectedSugg.Length + 2);
+ return new TextChange (currentToken.Start, currentToken.Length, selectedSugg + "=\"\"");
+ }
+ }
+
+ return new TextChange (currentToken.Start, currentToken.Length, selectedSugg);
+ }
+
+ public override Color GetColorForToken(TokenType tokType)
+ {
+ return base.GetColorForToken (tokType);
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+<?xml version="1.0"?>
+<Border Background="{./Background}" MinimumSize="50,20" Name="Content"
+ Foreground="Transparent" CornerRadius="{../CornerRadius}" BorderWidth="1"
+ MouseEnter="{Foreground=vgradient|0:White|0.2:Grey|0.9:Grey|1:Black};{caption.Foreground=White}"
+ MouseLeave="{Foreground=Transparent};{caption.Foreground=LightGrey}"
+ MouseDown="{Foreground=vgradient|0:Black|0.05:Grey|0.85:Grey|1:White}"
+ MouseUp="{Foreground=vgradient|0:White|0.2:Grey|0.9:Grey|1:Black}">
+ <HorizontalStack Margin="2">
+ <Image Style="Icon" Path="{./Icon}"/>
+ <Label Font="{./Font}" Name="caption" Margin="3" Foreground="LightGrey" Text="{./Caption}"/>
+ </HorizontalStack>
+</Border>
\ No newline at end of file
--- /dev/null
+<Label Font="{./Font}" Text="{./Caption}" Width="Stretched"
+ Margin="5"
+ Background="{./Background}"
+ Foreground="DimGrey"
+ TextAlignment="Center"
+ MouseEnter="{Foreground=White}"
+ MouseLeave="{Foreground=DimGrey}"/>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" ?>
+<ItemTemplate Data="Events">
+ <ListItem Height="Fit"
+ Selected="{/exp.Background=${ControlHighlight}}"
+ Unselected="{/exp.Background=Transparent}">
+ <Expandable Name="exp" Caption="{type}" MouseDoubleClick="/onClickForExpand" CacheEnabled="true" BubbleMouseEvent="All">
+ <Template>
+ <VerticalStack>
+ <Border CornerRadius="2" Margin="0" Height="Fit" MouseDoubleClick="./onClickForExpand"
+ Foreground="Transparent"
+ Background="{./Background}"
+ MouseEnter="{Foreground=DimGrey}"
+ MouseLeave="{Foreground=Transparent}">
+ <HorizontalStack Spacing="2" >
+ <Image Margin="1" Width="9" Height="9" Focusable="true" MouseDown="./onClickForExpand"
+ Path="{./Image}"
+ Visible="{HasChildEvents}"
+ SvgSub="{./IsExpanded}"
+ MouseEnter="{Background=LightGrey}"
+ MouseLeave="{Background=Transparent}"/>
+ <Label Text="{./Caption}" Width="80" Font="mono, 8" />
+ <Label Text="{DurationMS}" Width="40" Font="mono, 8" TextAlignment="Center" Background="DimGrey"/>
+ <DbgEventWidget Event="{}" Tooltip="#CECrowPlugin.ui.DbgEvtTooltip.crow" Width="Stretched" Height="5"/>
+ </HorizontalStack>
+ </Border>
+ <Container Name="Content" Visible="false"/>
+ </VerticalStack>
+ </Template>
+ <HorizontalStack Height="Fit">
+ <Widget Width="12" Height="10"/>
+ <VerticalStack Height="Fit" Name="ItemsContainer"/>
+ </HorizontalStack>
+ </Expandable>
+ </ListItem>
+</ItemTemplate>
+<ItemTemplate Data="Events" DataType="DbgWidgetEvent">
+ <ListItem Height="Fit"
+ Selected="{/exp.Background=${ControlHighlight}}"
+ Unselected="{/exp.Background=Transparent}">
+ <Expandable Name="exp" Caption="{type}" MouseDoubleClick="/onClickForExpand" CacheEnabled="true" BubbleMouseEvent="All">
+ <Template>
+ <VerticalStack>
+ <Border CornerRadius="2" Margin="0" Height="Fit" MouseDoubleClick="./onClickForExpand"
+ Foreground="Transparent"
+ Background="{./Background}"
+ MouseEnter="{Foreground=DimGrey}"
+ MouseLeave="{Foreground=Transparent}">
+ <HorizontalStack Spacing="2" >
+ <Image Margin="1" Width="9" Height="9" Focusable="true" MouseDown="./onClickForExpand"
+ Path="{./Image}"
+ Visible="{HasChildEvents}"
+ SvgSub="{./IsExpanded}"
+ MouseEnter="{Background=LightGrey}"
+ MouseLeave="{Background=Transparent}"/>
+ <Label Text="{./Caption}" Width="80" Font="mono, 8" />
+ <Label Text="{DurationMS}" Width="40" Font="mono, 8" TextAlignment="Center" Background="DimGrey"/>
+ <Label Text="{InstanceIndex}" Width="40" Font="mono, 8" TextAlignment="Center" Background="DimGrey"/>
+ <DbgEventWidget Event="{}" Tooltip="#CECrowPlugin.ui.DbgEvtTooltip.crow" Width="Stretched" Height="5"/>
+ </HorizontalStack>
+ </Border>
+ <Container Name="Content" Visible="false"/>
+ </VerticalStack>
+ </Template>
+ <HorizontalStack Height="Fit">
+ <Widget Width="12" Height="10"/>
+ <VerticalStack Height="Fit" Name="ItemsContainer"/>
+ </HorizontalStack>
+ </Expandable>
+ </ListItem>
+</ItemTemplate>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0"?>
+<VerticalStack Margin="${TooltipMargin}" DataSource="{./Event}">
+ <Label Text="{type}" Background="{Color}" Foreground="Black" Width="200" TextAlignment="Center" Margin="6"/>
+ <HorizontalStack Height="Fit" Width="Stretched" Spacing="2" Visible="{IsWidgetEvent}" Background="DimGrey" Margin="2">
+ <Label Text="Instance:" Foreground="White" Width="50%" />
+ <Label Text="{InstanceIndex}" Foreground="White" Background="Onyx" Width="Stretched" TextAlignment="Center"/>
+ </HorizontalStack>
+ <Label Text="{Message}" Foreground="White" Background="Onyx" Width="Stretched" Visible="{HasMessage}" Margin="2" Tooltip="{}"/>
+ <HorizontalStack Height="Fit" Width="Stretched" Spacing="2" Background="DimGrey" Margin="2">
+ <Label Text="Duration(ms):" Foreground="White" Width="50%" />
+ <Label Text="{DurationMS}" Foreground="White" Background="Onyx" Width="Stretched" TextAlignment="Right"/>
+ </HorizontalStack>
+ <HorizontalStack Height="Fit" Width="Stretched" Spacing="2">
+ <Label Text="Begin(s):" Foreground="${TooltipForeground}" Width="50%"/>
+ <Label Text="{BeginMS}" Foreground="${TooltipForeground}" Width="Stretched" TextAlignment="Right"/>
+ </HorizontalStack>
+ <HorizontalStack Height="Fit" Width="Stretched" Spacing="2">
+ <Label Text="End(s):" Foreground="${TooltipForeground}" Width="50%"/>
+ <Label Text="{EndMS}" Foreground="${TooltipForeground}" Width="Stretched" TextAlignment="Right"/>
+ </HorizontalStack>
+ <VerticalStack Height="Fit" Width="Stretched" IsVisible="{IsLayoutEvent}" >
+ <HorizontalStack Height="Fit" Width="Stretched" Spacing="2" Background="DimGrey" Margin="2">
+ <Label Text="Layout:" Foreground="White" Width="50%" />
+ <Label Text="{layouting}" Foreground="White" Background="Onyx" Width="Stretched" TextAlignment="Center"/>
+ </HorizontalStack>
+ <HorizontalStack Height="Fit" Width="Stretched" Spacing="2" Background="DimGrey" Margin="2">
+ <Label Text="Result:" Foreground="White" Width="50%" />
+ <Label Text="{result}" Foreground="White" Background="Onyx" Width="Stretched" TextAlignment="Center"/>
+ </HorizontalStack>
+ <HorizontalStack Height="Fit" Width="Stretched" Spacing="2" Background="DimGrey" Margin="2">
+ <Label Text="Old Slot:" Foreground="White" Width="50%" />
+ <Label Text="{OldSlot}" Foreground="White" Background="Onyx" Width="Stretched" TextAlignment="Center"/>
+ </HorizontalStack>
+ <HorizontalStack Height="Fit" Width="Stretched" Spacing="2" Background="DimGrey" Margin="2">
+ <Label Text="New Slot:" Foreground="White" Width="50%" />
+ <Label Text="{NewSlot}" Foreground="White" Background="Onyx" Width="Stretched" TextAlignment="Center"/>
+ </HorizontalStack>
+ </VerticalStack>
+ <DbgEventWidget Height="10" Width="Stretched" Event="{}" Tooltip="#CECrowPlugin.ui.DbgEvtTooltip.crow" />
+ <GroupBox Caption="Parent Event" Height="Fit" >
+ <DbgEventWidget Height="10" Width="Stretched" Event="{parentEvent}" Tooltip="#CECrowPlugin.ui.DbgEvtTooltip.crow" />
+ </GroupBox>
+ <!--<Label Text="{}" Foreground="${TooltipForeground}"/>-->
+</VerticalStack>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" ?>
+<Border Fit="true" Foreground="${TooltipForeground}" Background="${TooltipBackground}">
+ <VerticalStack Fit="true" Margin="${TooltipMargin}" DataSource="{HoverEvent}">
+ <Label Text="{type}" Background="{Color}" Foreground="Black" Width="200" TextAlignment="Center" Margin="6"/>
+ <HorizontalStack Height="Fit" Width="Stretched" Spacing="2" Visible="{IsWidgetEvent}" Background="DimGrey" Margin="2">
+ <Label Text="Instance:" Foreground="White" Width="50%" />
+ <Label Text="{InstanceIndex}" Foreground="White" Background="Onyx" Width="Stretched" TextAlignment="Center"/>
+ </HorizontalStack>
+ <Label Text="{Message}" Foreground="White" Background="Onyx" Width="Stretched" Visible="{HasMessage}" Margin="2" Tooltip="{}"/>
+ <HorizontalStack Height="Fit" Width="Stretched" Spacing="2" Background="DimGrey" Margin="2">
+ <Label Text="Duration:" Foreground="White" Width="50%" />
+ <Label Text="{DurationMS}" Foreground="White" Background="Onyx" Width="Stretched" TextAlignment="Right"/>
+ </HorizontalStack>
+ <HorizontalStack Height="Fit" Width="Stretched" Spacing="2">
+ <Label Text="Begin:" Foreground="${TooltipForeground}" Width="50%"/>
+ <Label Text="{BeginMS}" Foreground="${TooltipForeground}" Width="Stretched" TextAlignment="Right"/>
+ </HorizontalStack>
+ <HorizontalStack Height="Fit" Width="Stretched" Spacing="2">
+ <Label Text="End:" Foreground="${TooltipForeground}" Width="50%"/>
+ <Label Text="{EndMS}" Foreground="${TooltipForeground}" Width="Stretched" TextAlignment="Right"/>
+ </HorizontalStack>
+ <VerticalStack Height="Fit" Width="Stretched" IsVisible="{IsLayoutEvent}" >
+ <HorizontalStack Height="Fit" Width="Stretched" Spacing="2" Background="DimGrey" Margin="2">
+ <Label Text="Layout:" Foreground="White" Width="50%" />
+ <Label Text="{layouting}" Foreground="White" Background="Onyx" Width="Stretched" TextAlignment="Center"/>
+ </HorizontalStack>
+ <HorizontalStack Height="Fit" Width="Stretched" Spacing="2" Background="DimGrey" Margin="2">
+ <Label Text="Result:" Foreground="White" Width="50%" />
+ <Label Text="{result}" Foreground="White" Background="Onyx" Width="Stretched" TextAlignment="Center"/>
+ </HorizontalStack>
+ <HorizontalStack Height="Fit" Width="Stretched" Spacing="2" Background="DimGrey" Margin="2">
+ <Label Text="Old Slot:" Foreground="White" Width="50%" />
+ <Label Text="{OldSlot}" Foreground="White" Background="Onyx" Width="Stretched" TextAlignment="Center"/>
+ </HorizontalStack>
+ <HorizontalStack Height="Fit" Width="Stretched" Spacing="2" Background="DimGrey" Margin="2">
+ <Label Text="New Slot:" Foreground="White" Width="50%" />
+ <Label Text="{NewSlot}" Foreground="White" Background="Onyx" Width="Stretched" TextAlignment="Center"/>
+ </HorizontalStack>
+ </VerticalStack>
+ <!--<Label Text="{}" Foreground="${TooltipForeground}"/>-->
+ </VerticalStack>
+</Border>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" ?>
+<ListItem Height="Fit"
+ Selected="{Background=${ControlHighlight}}"
+ Unselected="{Background=Transparent}">
+ <HorizontalStack Spacing="2" >
+ <Label Text="{BeginMS}" Width="70" TextAlignment="Right" Background="DimGrey"/>
+ <Label Text="{type}" Width="160" Background="{Color}" Foreground="Black"/>
+ <Label Text="{Message}" Width="Stretched" />
+ <Label Text="{DurationMS}" Width="70" TextAlignment="Right" Background="DimGrey"/>
+ </HorizontalStack>
+</ListItem>
--- /dev/null
+<?xml version="1.0"?>
+<Window Caption="Debug Log" Background="0.05,0.05,0.1,0.9" Width="80%" Height="80%">
+ <VerticalStack>
+ <TabView>
+ <VerticalStack Name="LogGraph" Background="DarkGrey">
+ <EnumSelector RadioButtonStyle="CheckBox2" Template="#CECrowPlugin.ui.EnumSelector.template"
+ Caption="Discarded Events" EnumValue="{²../dbv.Filter}" BitFieldExcludeMask="255" />
+ <HorizontalStack>
+ <DbgLogViewer Visible="true" Name="dbv" Events="{Events}" Widgets="{Widgets}"
+ CurrentEvent="{²CurrentEvent}" CurrentWidget="{²CurrentWidget}" />
+ <ScrollBar Maximum="{../dbv.MaxScrollY}" Value="{²../dbv.ScrollY}" SmallIncrement="1" LargeIncrement="10"
+ CursorRatio="{../dbv.ChildHeightRatio}"/>
+ </HorizontalStack>
+ <ScrollBar Style="HScrollBar" Maximum="{../dbv.MaxScrollX}" Value="{²../dbv.ScrollX}" SmallIncrement="1" LargeIncrement="10"
+ CursorRatio="{../dbv.ChildWidthRatio}"/>
+ <HorizontalStack Height="Fit" DataSource="{CurrentWidget}" Spacing="3">
+ <Label Style="smallLabValue" Text="{name}"/>
+ <Label Style="smallLabValue" Text="{listIndex}" Tooltip="List index"/>
+ <Label Style="smallLabValue" Text="{treeIndex}" Tooltip="tree index"/>
+ <Label Style="smallLabValue" Text="{yIndex}" Tooltip="yIndex"/>
+ <Label Style="smallLabValue" Text="{xLevel}" Tooltip="xLevel"/>
+ <Label Style="smallLabCaption" Text="Width:"/>
+ <Label Style="smallLabValue" Text="{Width}"/>
+ <Label Style="smallLabCaption" Text="Height:" />
+ <Label Style="smallLabValue" Text="{Height}"/>
+ <Label Style="smallLabCaption" Text="ScrollX:" />
+ <Label Style="smallLabValue" Text="{../../dbv.ScrollX}"/>
+ <Label Style="smallLabCaption" Text="MaxScrollX:" />
+ <Label Style="smallLabValue" Text="{../../dbv.MaxScrollX}"/>
+ <Label Style="smallLabValue" Tooltip="XScale" Text="{../../dbv.XScale}"/>
+ <Label Style="smallLabValue" Tooltip="VisibleTicks" Text="{../../dbv.VisibleTicks}"/>
+ </HorizontalStack>
+ </VerticalStack>
+ <VerticalStack Name="AllEvents" Width="Stretched" IsVisible="false">
+ <TreeView Height="Stretched" Name="dbgTV" Data="{Events}" SelectedItem="{²CurrentEvent}" Background="DarkGrey"
+ ItemTemplate="#CECrowPlugin.ui.DbgEventTreeItems.itemp"/>
+ <ListBox Data="{CurWidgetEvents}" Height="100" SelectedItem="{²CurrentEvent}">
+ <ItemTemplate>
+ <ListItem Margin="0" Height="16" Width="Fit"
+ Selected="{Background=${ControlHighlight}}"
+ Unselected="{Background=Transparent}">
+ <DbgEventWidget Height="10" Width="Fit" Event="{}" Tooltip="#CECrowPlugin.ui.DbgEvtTooltip.crow" TicksPerPixel="20" VerticalAlignment="Center"/>
+ </ListItem>
+ </ItemTemplate>
+ <Template>
+ <Wrapper Name="ItemsContainer" Spacing="1" Background="DarkGrey"/>
+ </Template>
+ </ListBox>
+ </VerticalStack>
+ <VerticalStack Name="CurWidgetEvents" Width="Stretched" IsVisible="false">
+ <TreeView Height="Stretched" Data="{CurrentWidgetEvents}" Background="DarkGrey"
+ ItemTemplate="#CECrowPlugin.ui.DbgWidgetEventTreeItems.itemp"/>
+ </VerticalStack>
+ </TabView>
+ <Splitter/>
+ <HorizontalStack Height="30%">
+ <ListBox Data="{Widgets}" Width="200" SelectedItem="{²CurrentWidget}"
+ ItemTemplate="#CECrowPlugin.ui.WidgetRecord.itemp">
+ </ListBox>
+ <Splitter/>
+ <VerticalStack>
+ <HorizontalStack Height="Fit" Background="Onyx" Spacing="5">
+ <Label Text="{CurrentWidget}"/>
+ <Label Text="events"/>
+ </HorizontalStack>
+ <ListBox Data="{CurrentWidgetEvents}" Background="Black" SelectedItem="{²CurrentEvent}">
+ <ItemTemplate>
+ <ListItem Margin="0" Height="16" IsSelected="{²IsSelected}" Width="Fit"
+ Selected="{Background=${ControlHighlight}}" Template="Crow.ScrollingListBox.template"
+ Unselected="{Background=Transparent}">
+ <DbgEventWidget Height="10" Width="Fit" Event="{}" Tooltip="#CECrowPlugin.ui.DbgEvtTooltip.crow" TicksPerPixel="50" VerticalAlignment="Center"/>
+ </ListItem>
+ </ItemTemplate>
+ <Template>
+ <Wrapper Name="ItemsContainer" Spacing="1" Background="{./Background}"/>
+ </Template>
+ </ListBox>
+ <!--<TreeView Data="{Events}" SelectedItem="{²CurrentEvent}" Background="DarkGrey"
+ ItemTemplate="#Dbg.DbgEventTreeItems.itemp"/>-->
+ </VerticalStack>
+ <Splitter/>
+ <DbgEventView Template="#CECrowPlugin.ui.DbgEventView.template" Event="{../../dbv.HoverEvent}"/>
+ <Splitter/>
+ <DbgEventView Template="#CECrowPlugin.ui.DbgEventView.template" Event="{CurrentEvent}"/>
+ </HorizontalStack>
+ <HorizontalStack Height="Fit" Background="Onyx" Margin="1">
+ <HorizontalStack Height="Fit" DataSource="{CurrentEvent}">
+ <Label Foreground="Black" Text="Current Event:" Background="{Color}" Margin="2" />
+ <DbgEventWidget Height="14" Width="Stretched" Event="{}" Tooltip="#Dbg.DbgEvtTooltip.crow" />
+ </HorizontalStack>
+ <Menu Fit="true" Data="{EventCommands}">
+ <ItemTemplate>
+ <Button Command="{}"/>
+ </ItemTemplate>
+ </Menu>
+ <Popper Caption="Search...">
+ <VerticalStack Fit="true" Background="Onyx" Margin="10">
+ <ComboBox Caption="Event Type" Data="{AllEventTypes}" SelectedItem="{²SearchEventType}"/>
+ <ComboBox Caption="Widget" Data="{Widgets}" SelectedItem="{²SearchWidget}"/>
+ </VerticalStack>
+ </Popper>
+ </HorizontalStack>
+ </VerticalStack>
+</Window>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0"?>
+<Popper >
+ <Template>
+ <HorizontalStack Background="{../../Background}" Margin="5" Spacing="10">
+ <Label Text="{../../../Caption}" Width="Stretched"/>
+ <Label Background="SeaGreen" Text="{../../../EnumValue}" Margin="3"/>
+ </HorizontalStack>
+ </Template>
+ <Wrapper Name="Content" Height="Fit" Width="420" Background="Jet" Orientation="Vertical" />
+</Popper>
\ No newline at end of file
--- /dev/null
+<ListItem Height="Fit" Margin="1" Focusable="true" HorizontalAlignment="Left"
+ Selected = "{Background=${ControlHighlight}}"
+ Unselected = "{Background=Transparent}">
+ <HorizontalStack>
+ <Label Text="{name}" Width="Stretched"/>
+ <Label Style="labWidgetRecordList" Text="{listIndex}" Tooltip="List index"/>
+ <Label Style="labWidgetRecordList" Text="{treeIndex}" Tooltip="tree index"/>
+ <Label Style="labWidgetRecordList" Text="{yIndex}" Tooltip="yIndex"/>
+ <Label Style="labWidgetRecordList" Text="{xLevel}" Tooltip="xLevel"/>
+ </HorizontalStack>
+</ListItem>
\ No newline at end of file
--- /dev/null
+IcoButton {
+ Template = "#CECrowPlugin.ui.Button.template";
+ Background = "Onyx";
+}
+CheckBox2 {
+ Template= "#CECrowPlugin.ui.CheckBox2.imlt";
+ Background = "Jet";
+ Checked="{Background=MediumSeaGreen}";
+ Unchecked = "{Background=Jet}";
+ Width = "200";
+}
+smallLabCaption {
+ Font="mono, 8";
+ Foreground="Grey";
+}
+smallLabValue {
+ Font="mono, 10";
+ Foreground="White";
+}
+DbgLogViewer {
+ MouseWheelSpeed="3";
+ Font="mono, 8";
+ Background="Onyx";
+ CacheEnabled = "true";
+}
+DbgEventView {
+ Height="Fit";
+ Width="150";
+}
+labWidgetRecordList {
+ Font="mono, 11";
+ Background="Grey";
+ Foreground="Jet";
+ Margin="0";
+ Width="24";
+ TextAlignment="Right";
+}
+
+DbgEventWidget {
+ CacheEnabled = "true";
+}
\ No newline at end of file
--- /dev/null
+<Window Width="80%" Movable="false">
+ <VerticalStack>
+ <HorizontalStack Height="Fit">
+ <Label Text="Hover:" Width="50" Foreground="Grey"/>
+ <Label Text="{HoverWidget}" Font="mono, 8"/>
+ </HorizontalStack>
+ <HorizontalStack Height="Fit">
+ <Label Text="Focus:" Width="50" Foreground="Grey"/>
+ <Label Text="{FocusedWidget}" Font="mono, 8"/>
+ </HorizontalStack>
+ <HorizontalStack Height="Fit">
+ <Label Text="Active:" Width="50" Foreground="Grey"/>
+ <Label Text="{ActiveWidget}" Font="mono, 8"/>
+ </HorizontalStack>
+ </VerticalStack>
+</Window>
+
--- /dev/null
+<?xml version="1.0"?>
+<VerticalStack Background="DarkGrey">
+ <HorizontalStack >
+ <TabView Width="25%" >
+ <VerticalStack Name="Explorer" Background="Onyx">
+ <HorizontalStack Height="Fit" Margin="2" >
+ <Image Margin="2" Width="16" Height="16" Path="#Crow.Icons.level-up.svg" MouseClick="goUpDirClick"
+ Background="Jet" MouseEnter="{Background=Grey}" MouseLeave="{Background=Jet}" />
+ <TextBox Text="{²CurrentDir}" Margin="2"/>
+ </HorizontalStack>
+ <DirectoryView Margin="1" Name="dv" CurrentDirectory="{CurrentDir}" SelectedItemChanged="Dv_SelectedItemChanged">
+ <Template>
+ <TreeView IsRoot="true" Name="treeView" Data="{./FileSystemEntries}" Background="{./Background}"
+ SelectedItemChanged="./onSelectedItemChanged">
+ <ItemTemplate DataType="System.IO.FileInfo">
+ <ListItem CornerRadius="2" Margin="0" Height="Fit" Width="Stretched"
+ ContextCommands="{GetCommands}"
+ Selected="{Background=${ControlHighlight}}"
+ Unselected="{Background=Transparent}">
+ <HorizontalStack>
+ <Image Margin="1" Width="14" Height="14" Path="#Crow.Icons.file.svg"/>
+ <Label Text="{Name}" Width="Stretched"/>
+ </HorizontalStack>
+ </ListItem>
+ </ItemTemplate>
+ <ItemTemplate DataType="System.IO.DirectoryInfo" Data="GetFileSystemInfosOrdered">
+ <ListItem ContextCommands="{GetCommands}"
+ Selected="{/exp.Background=${ControlHighlight}}"
+ Unselected="{/exp.Background=Transparent}">
+ <Expandable Name="exp" Caption="{Name}" MouseDoubleClick="/onClickForExpand">
+ <Template>
+ <VerticalStack>
+ <Border CornerRadius="2" Margin="0" Height="Fit" MouseDoubleClick="./onClickForExpand"
+ Foreground="Transparent"
+ MouseEnter="{Foreground=DimGrey}"
+ MouseLeave="{Foreground=Transparent}">
+ <HorizontalStack Background="{./Background}" Spacing="1">
+ <Image Margin="1" Width="9" Height="9" Focusable="true" MouseDown="./onClickForExpand"
+ Path="{./Image}"
+ Visible="{./IsExpandable}"
+ SvgSub="{./IsExpanded}"
+ MouseEnter="{Background=LightGrey}"
+ MouseLeave="{Background=Transparent}"/>
+ <Image Margin="1" Width="16" Height="16"
+ Path="#Crow.Icons.folder.svg" SvgSub="{./IsExpanded}"/>
+ <Label Text="{./Caption}"/>
+ </HorizontalStack>
+ </Border>
+ <Container Name="Content" Visible="false"/>
+ </VerticalStack>
+ </Template>
+ <HorizontalStack Height="Fit">
+ <Widget Width="12" Height="10"/>
+ <VerticalStack Height="Fit" Name="ItemsContainer"/>
+ </HorizontalStack>
+ </Expandable>
+ </ListItem>
+ </ItemTemplate>
+ </TreeView>
+ </Template>
+ </DirectoryView>
+ </VerticalStack>
+ <VerticalStack Name="DebugLogger" Margin="5" IsVisible="false" Background="Onyx">
+ <HorizontalStack Height="Fit">
+ <Image Width="30" Height="20" Path="#Crow.Icons.IconAlerte.svg" Visible="{../../../../dbgIfaceWidget.CrowDebuggerNOK}"/>
+ <Label Fit="true" Text="Crow debug assembly path:"/>
+ <Widget Width="5" Height="5" Background="SeaGreen" IsVisible="{../../../../dbgIfaceWidget.HasFocus}"/>
+ <Widget Width="5" Height="5" Background="Yellow" IsVisible="{../../../../dbgIfaceWidget.IsHover}"/>
+ <TextBox Text="{²CrowDbgAssemblyLocation}" Margin="2"/>
+ </HorizontalStack>
+ <Label Background="Red" Foreground="White" Margin="5" Width="Stretched" Text="{../../../dbgIfaceWidget.CrowDebuggerErrorMessage}"
+ IsVisible="{../../../dbgIfaceWidget.CrowDebuggerNOK}"/>
+ <HorizontalStack Height="Fit" Width="Stretched" Background="Onyx" Margin="5">
+ <Label Text="Debug log output file:" Fit="true"/>
+ <TextBox Text="{²../../../../dbgIfaceWidget.DebugLogFilePath}" />
+ </HorizontalStack>
+ <EnumSelector RadioButtonStyle="CheckBox2" Template="#Dbg.EnumSelector.template"
+ Background="Grey"
+ Caption="Recorded Events" EnumValue="{²RecordedEvents}" BitFieldExcludeMask="255" />
+ <EnumSelector RadioButtonStyle="CheckBox2" Template="#Dbg.EnumSelector.template"
+ Background="Onyx"
+ Caption="Discarded Events" EnumValue="{²DiscardedEvents}" BitFieldExcludeMask="255" />
+ <CheckBox Caption="Begin recording on startup" IsChecked="{²DebugLogOnStartup}" Background="Onyx"/>
+ <HorizontalStack Height="Fit">
+ <CheckBox Caption="Recording" IsChecked="{²DebugLogRecording}" Height="40" Width="60"
+ Checked="{sh.Path='A 8,8,7.5,0,6.3 O 0.8,0,0,1 f O 0,0,0,0.5 G'}"
+ Unchecked="{sh.Path='R 0.5,0.5,15,15 f O 0,0,0,1 G'}">
+ <Template>
+ <Border Background="Onyx" Margin="10" CornerRadius="5">
+ <Shape Name="sh" Foreground="Grey" Size="16,16" Path="R 0.5,0.5,15,15 f O 0,0,0,1 G"/>
+ </Border>
+ </Template>
+ </CheckBox>
+ <Menu Data="{../../../../dbgIfaceWidget.LoggerCommands}" Height="Fit" Width="Stretched">
+ <Template>
+ <Wrapper Orientation="Vertical" Name="ItemsContainer" Margin="0" Background="{./Background}"/>
+ </Template>
+ <ItemTemplate>
+ <Button Command="{}" Height="Fit" Width="Fit"/>
+ </ItemTemplate>
+ </Menu>
+ </HorizontalStack>
+ </VerticalStack>
+ </TabView>
+ <Splitter Width="6" />
+ <VerticalStack>
+ <DebugInterfaceWidget Name="dbgIfaceWidget" Height="60%" Background="Black" Focusable="true"
+ CrowDbgAssemblyLocation="{²CrowDbgAssemblyLocation}"
+ Recording="{²DebugLogRecording}"
+ IMLSource="{Source}"
+ CurrentException="{²CurrentException}"
+ DiscardedEvents="{DiscardedEvents}" RecordedEvents="{RecordedEvents}"/>
+ <Splitter/>
+ <!--<TabView>-->
+ <VerticalStack Name="Editor" Spacing="0">
+ <HorizontalStack Height="Fit">
+ <Button Style="IcoButton" Command="{CMDNew}" />
+ <Button Style="IcoButton" Command="{CMDSave}" />
+ <Button Style="IcoButton" Command="{CMDSaveAs}" />
+ <Button Style="IcoButton" Command="{CMDUndo}" />
+ <Button Style="IcoButton" Command="{CMDRedo}" />
+ <!--<Button Style="IcoButton" Command="{CMDCut}" />
+ <Button Style="IcoButton" Command="{CMDCopy}" />
+ <Button Style="IcoButton" Command="{CMDPaste}" />-->
+ <Widget Width="Stretched" />
+ <Widget Background="Red" IsVisible="{DebugLogRecording}" CornerRadius="10" Width="12" Height="12"/>
+ </HorizontalStack>
+
+ <HorizontalStack>
+ <Editor Name="tb" Text="{Source}" Multiline="true" Font="consolas, 12" Focusable="true" Height="Stretched" Width="Stretched"
+ TextChanged="onTextChanged" KeyDown="textView_KeyDown" ContextCommands="{EditorCommands}"
+ Foreground="DarkGrey" Background="White"/>
+ <!--SelectionChanged="onSelectedTextChanged"-->
+ <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" Spacing="10" Background="DarkGrey">
+ <Widget Width="10" Height="10" Background="RoyalBlue" Visible="{IsDirty}"/>
+ <Label Text="{CurrentFile}" Width="Stretched"/>
+ <Widget Width="Stretched"/>
+ <Label Text="Line:" Foreground="Grey"/>
+ <Label Text="{../../tb.CurrentLine}" Margin="2"/>
+ <Label Text="Col:" Foreground="Grey"/>
+ <Label Text="{../../tb.CurrentColumn}" Margin="2"/>
+ </HorizontalStack>
+ <Popper IsVisible="{ShowError}" Background="Red">
+ <Template>
+ <CheckBox IsChecked="{²./IsPopped}" MouseEnter="{IsChecked='true'}" MouseLeave="{IsChecked='false'}">
+ <Template>
+ <Label Text="{CurrentExceptionMSG}" Background="Red" Foreground="White" Width="Stretched" Margin="2"
+ Multiline="true"/>
+ </Template>
+ </CheckBox>
+ </Template>
+ <Label Text="{CurrentException}" Background="DarkRed" Foreground="White" Width="Stretched" Margin="2" Multiline="true"/>
+ </Popper>
+ </VerticalStack>
+
+ <!--</TabView>-->
+ </VerticalStack>
+ </HorizontalStack>
+</VerticalStack>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0"?>
+<DockWindow Caption="Crow Preview Configuration" Width="80%" Height="400" Resizable="false">
+ <VerticalStack RootDataLevel="true" Margin="5">
+ <HorizontalStack Height="Fit" Margin="5">
+ <Label Text="Crow Service" Width="Stretched"/>
+ <ListBox Data="{Commands}" Fit="true">
+ <Template>
+ <HorizontalStack Name="ItemsContainer" />
+ </Template>
+ <ItemTemplate Path="#CrowEditBase.ui.IconCommand.itmp"/>
+ </ListBox>
+ </HorizontalStack>
+ <HorizontalStack Height="Fit">
+ <Label Fit="true" Text="Crow assembly path:"/>
+ <Image Width="30" Height="20" Path="#Crow.Icons.IconAlerte.svg" Visible="{ServiceIsInError}"/>
+ </HorizontalStack>
+ <HorizontalStack Height="Fit">
+ <TextBox Height="Fit" Text="{²CrowDbgAssemblyLocation}" Margin="2"/>
+ <Button Command="{CMDOptions_SelectCrowDbgAssemblyLocation}" MinimumSize="0,0"/>
+ </HorizontalStack>
+ <Label Background="Red" Foreground="White" Margin="5" Width="Stretched" Text="{ServiceErrorMessage}"
+ IsVisible="{ServiceIsInError}"/>
+ <Spinner Caption="Refresh Rate (ms)" Value="{²RefreshRate}" Maximum="1000"/>
+ <Spinner Caption="Max Layout Try" Value="{²MaxLayoutingTries}" Maximum="1000"/>
+ <Spinner Caption="Max Layout Discard" Value="{²MaxDiscardCount}" Maximum="1000"/>
+ <GroupBox Caption="Debug Logger" IsEnabled="{DebugLogIsEnabled}">
+ <VerticalStack>
+ <EnumSelector RadioButtonStyle="CheckBox2" Template="#CECrowPlugin.ui.EnumSelector.template" Width="Stretched"
+ Caption="Recorded Events" EnumValue="{²RecordedEvents}" BitFieldExcludeMask="255" />
+ <EnumSelector RadioButtonStyle="CheckBox2" Template="#CECrowPlugin.ui.EnumSelector.template" Width="Stretched"
+ Caption="Discarded Events" EnumValue="{²DiscardedEvents}" BitFieldExcludeMask="255" />
+ <!--<HorizontalStack Height="Fit">
+ <CheckBox Caption="Recording" IsChecked="{²Recording}" Height="24" Width="30"
+ Checked="{sh.Path='A 8,8,7.5,0,6.3 O 0.8,0,0,1 f O 0,0,0,0.5 G'}"
+ Unchecked="{sh.Path='R 0.5,0.5,15,15 f O 0,0,0,1 G'}">
+ <Template>
+ <Border Background="Onyx" Margin="2" CornerRadius="5">
+ <Shape Name="sh" Foreground="Grey" Size="16,16" Path="R 0.5,0.5,15,15 f O 0,0,0,1 G"/>
+ </Border>
+ </Template>
+ </CheckBox>
+ <Menu Data="{LoggerCommands}" Height="Fit" Width="Stretched">
+ <Template>
+ <Wrapper Orientation="Vertical" Name="ItemsContainer" Margin="0" Background="{./Background}"/>
+ </Template>
+ <ItemTemplate>
+ <Button Command="{}" Height="Fit" Width="Fit"/>
+ </ItemTemplate>
+ </Menu>
+ </HorizontalStack>-->
+ </VerticalStack>
+ </GroupBox>
+ </VerticalStack>
+</DockWindow>
+
+
--- /dev/null
+<?xml version="1.0"?>
+<DockWindow Caption="Crow Preview" Width="60%" Commands="{/dbgIfaceWidget.WindowCommands}">
+ <VerticalStack Background="Black" >
+ <DebugInterfaceWidget Name="dbgIfaceWidget" Focusable="true"
+ BubbleMouseEvent="None"
+ Document="{CurrentDocument}"/>
+ <Label DataSource="{../dbgIfaceWidget.CrowIFaceService}" Text="{CurrentException}" Background="DarkRed" Foreground="White"
+ IsVisible="{PreviewHasError}"
+ Width="Stretched" Margin="2" Multiline="true"/>
+ </VerticalStack>
+</DockWindow>
+
+
--- /dev/null
+<?xml version="1.0"?>
+<Window Caption="Debug Log" Background="0.05,0.05,0.1,0.9" Width="95%" Height="95%">
+ <VerticalStack RootDataLevel="true">
+ <TabView>
+ <VerticalStack Name="LogGraph" Background="DarkGrey">
+ <EnumSelector RadioButtonStyle="CheckBox2" Template="#CECrowPlugin.ui.EnumSelector.template"
+ Caption="Discarded Events" EnumValue="{²../dbv.Filter}" BitFieldExcludeMask="255" />
+ <HorizontalStack>
+ <DbgLogViewer Visible="true" Name="dbv" Events="{Events}" Widgets="{Widgets}"
+ CurrentEvent="{²CurrentEvent}" CurrentWidget="{²CurrentWidget}" />
+ <ScrollBar Maximum="{../dbv.MaxScrollY}" Value="{²../dbv.ScrollY}" SmallIncrement="1" LargeIncrement="10"
+ CursorRatio="{../dbv.ChildHeightRatio}"/>
+ </HorizontalStack>
+ <ScrollBar Style="HScrollBar" Maximum="{../dbv.MaxScrollX}" Value="{²../dbv.ScrollX}" SmallIncrement="1" LargeIncrement="10"
+ CursorRatio="{../dbv.ChildWidthRatio}"/>
+ <HorizontalStack Height="Fit" DataSource="{CurrentWidget}" Spacing="3">
+ <Label Style="smallLabValue" Text="{name}"/>
+ <Label Style="smallLabValue" Text="{listIndex}" Tooltip="List index"/>
+ <Label Style="smallLabValue" Text="{treeIndex}" Tooltip="tree index"/>
+ <Label Style="smallLabValue" Text="{yIndex}" Tooltip="yIndex"/>
+ <Label Style="smallLabValue" Text="{xLevel}" Tooltip="xLevel"/>
+ <Label Style="smallLabCaption" Text="Width:"/>
+ <Label Style="smallLabValue" Text="{Width}"/>
+ <Label Style="smallLabCaption" Text="Height:" />
+ <Label Style="smallLabValue" Text="{Height}"/>
+ <Label Style="smallLabCaption" Text="ScrollX:" />
+ <Label Style="smallLabValue" Text="{../../dbv.ScrollX}"/>
+ <Label Style="smallLabCaption" Text="MaxScrollX:" />
+ <Label Style="smallLabValue" Text="{../../dbv.MaxScrollX}"/>
+ <Label Style="smallLabValue" Tooltip="XScale" Text="{../../dbv.XScale}"/>
+ <Label Style="smallLabValue" Tooltip="VisibleTicks" Text="{../../dbv.VisibleTicks}"/>
+ </HorizontalStack>
+ </VerticalStack>
+ <VerticalStack Name="AllEvents" Width="Stretched" IsVisible="false" RootDataLevel="true">
+ <TreeView Height="Stretched" Name="dbgTV" Data="{Events}" SelectedItem="{²CurrentEvent}" Background="DarkGrey"
+ ItemTemplate="#CECrowPlugin.ui.DbgEventTreeItems.itemp"/>
+ </VerticalStack>
+ <VerticalStack Name="CurWidgetEvents" Width="Stretched" IsVisible="false" RootDataLevel="true">
+ <ListBox Data="{CurrentWidgetEvents}" Background="Black" SelectedItem="{²CurrentEvent}">
+ <ItemTemplate>
+ <ListItem Margin="0" Height="16" IsSelected="{²IsSelected}" Width="Fit"
+ Selected="{Background=${ControlHighlight}}" Template="Crow.ScrollingListBox.template"
+ Unselected="{Background=Transparent}">
+ <DbgEventWidget Height="10" Width="Fit" Event="{}" Tooltip="#CECrowPlugin.ui.DbgEvtTooltip.crow" TicksPerPixel="1000" VerticalAlignment="Center"/>
+ </ListItem>
+ </ItemTemplate>
+ <Template>
+ <Wrapper Name="ItemsContainer" Spacing="1" Background="{./Background}"/>
+ </Template>
+ </ListBox>
+ </VerticalStack>
+ </TabView>
+ <Splitter/>
+ <HorizontalStack Height="30%">
+ <!--<ListBox Data="{Widgets}" Width="200" SelectedItem="{²CurrentWidget}"
+ ItemTemplate="#CECrowPlugin.ui.WidgetRecord.itemp">
+ </ListBox>-->
+ <ListBox Data="{CurWidgetProperties}" Width="25%" >
+ <ItemTemplate>
+ <ListItem Height="Fit" Margin="1" Focusable="true" HorizontalAlignment="Left"
+ Selected = "{Background=${ControlHighlight}}"
+ Unselected = "{Background=Transparent}">
+ <HorizontalStack>
+ <Label Text="{Key}" Width="140"/>
+ <Label Text="{Value}" Width="Stretched" Background="White" Foreground="Black" TextAlignment="Left"/>
+ </HorizontalStack>
+ </ListItem>
+ </ItemTemplate>
+ </ListBox>
+ <Splitter/>
+ <VerticalStack>
+ <HorizontalStack Height="Fit" Background="Onyx" Spacing="5">
+ <Label Text="{CurrentWidget}"/>
+ <Label Text="events"/>
+ </HorizontalStack>
+ <ListBox Height="Stretched" Data="{CurrentWidgetEvents}" SelectedItem="{²CurrentEvent}" Background="DarkGrey"
+ ItemTemplate="#CECrowPlugin.ui.DbgWidgetEventListItems.itemp"/>
+ </VerticalStack>
+ <Splitter/>
+ <DbgEventView Template="#CECrowPlugin.ui.DbgEventView.template" Event="{../../dbv.HoverEvent}"/>
+ <Splitter/>
+ <DbgEventView Template="#CECrowPlugin.ui.DbgEventView.template" Event="{CurrentEvent}"/>
+ </HorizontalStack>
+ <HorizontalStack Height="Fit" Background="Onyx" Margin="1">
+ <HorizontalStack Height="Fit" DataSource="{CurrentEvent}">
+ <Label Foreground="Black" Text="Current Event:" Background="{Color}" Margin="2" />
+ <DbgEventWidget Height="14" Width="Stretched" Event="{}" Tooltip="#CECrowPlugin.ui.DbgEvtTooltip.crow" />
+ </HorizontalStack>
+ <ListBox Data="{EventCommands}" Fit="true">
+ <Template>
+ <HorizontalStack Name="ItemsContainer" />
+ </Template>
+ <ItemTemplate Path="#CrowEditBase.ui.IconCommand.itmp"/>
+ </ListBox>
+ <Popper Caption="Search...">
+ <VerticalStack Fit="true" Background="Onyx" Margin="10">
+ <ComboBox Caption="Event Type" Data="{AllEventTypes}" SelectedItem="{²SearchEventType}"/>
+ <ComboBox Caption="Widget" Data="{Widgets}" SelectedItem="{²SearchWidget}"/>
+ </VerticalStack>
+ </Popper>
+ </HorizontalStack>
+ </VerticalStack>
+</Window>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0"?>
+<DockWindow Caption="Debug Log Graph" Width="90%" Height="90%">
+ <VerticalStack Name="LogGraph" >
+ <EnumSelector RadioButtonStyle="CheckBox2" Template="#CECrowPlugin.ui.EnumSelector.template"
+ Caption="Discarded Events" EnumValue="{²../dbv.Filter}" BitFieldExcludeMask="255" />
+ <HorizontalStack>
+ <DbgLogViewer Visible="true" Name="dbv" Events="{Events}" Widgets="{Widgets}"
+ CurrentEvent="{²CurrentEvent}" CurrentWidget="{²CurrentWidget}" />
+ <ScrollBar Maximum="{../dbv.MaxScrollY}" Value="{²../dbv.ScrollY}" SmallIncrement="1" LargeIncrement="10"
+ CursorRatio="{../dbv.ChildHeightRatio}"/>
+ </HorizontalStack>
+ <ScrollBar Style="HScrollBar" Maximum="{../dbv.MaxScrollX}" Value="{²../dbv.ScrollX}" SmallIncrement="1" LargeIncrement="10"
+ CursorRatio="{../dbv.ChildWidthRatio}"/>
+ <HorizontalStack Height="Fit" DataSource="{CurrentWidget}" Spacing="3">
+ <Label Style="smallLabValue" Text="{name}"/>
+ <Label Style="smallLabValue" Text="{listIndex}" Tooltip="List index"/>
+ <Label Style="smallLabValue" Text="{treeIndex}" Tooltip="tree index"/>
+ <Label Style="smallLabValue" Text="{yIndex}" Tooltip="yIndex"/>
+ <Label Style="smallLabValue" Text="{xLevel}" Tooltip="xLevel"/>
+ <Label Style="smallLabCaption" Text="ScrollX:" />
+ <Label Style="smallLabValue" Text="{../../dbv.ScrollX}"/>
+ <Label Style="smallLabCaption" Text="MaxScrollX:" />
+ <Label Style="smallLabValue" Text="{../../dbv.MaxScrollX}"/>
+ <Label Style="smallLabValue" Tooltip="XScale" Text="{../../dbv.XScale}"/>
+ <Label Style="smallLabValue" Tooltip="VisibleTicks" Text="{../../dbv.VisibleTicks}"/>
+ </HorizontalStack>
+ </VerticalStack>
+</DockWindow>
+
+
--- /dev/null
+<?xml version="1.0"?>
+<DockWindow Caption="Debug Log Navigation" Width="90%" Height="Fit">
+ <VerticalStack Name="LogGraph" >
+ <ListBox Name="lbAllEvents" Data="{Events}" Height="Fit" >
+ <ItemTemplate>
+ <ListItem Margin="0" Height="16" Width="Fit"
+ Selected="{Background=Yellow}"
+ Unselected="{Background=Transparent}">
+ <DbgEventWidget CacheEnabled="true" Height="10" Width="Fit" Event="{}" Tooltip="#CECrowPlugin.ui.DbgEvtTooltip.crow" TicksPerPixel="3000" VerticalAlignment="Center"/>
+ </ListItem>
+ </ItemTemplate>
+ <Template>
+ <VerticalStack Width="Stretched" >
+ <Scroller Name="scroller" >
+ <HorizontalStack Name="ItemsContainer" Width="Fit" HorizontalAlignment="Left"/>
+ </Scroller>
+ <ScrollBar Style="HScrollBar" Name="scrollbar1" Value="{²../scroller.ScrollX}"
+ LargeIncrement="{../scroller.PageWidth}" SmallIncrement="30" CursorRatio="{../scroller.ChildWidthRatio}"
+ Maximum="{../scroller.MaxScrollX}" Height="12" />
+ </VerticalStack>
+ </Template>
+ </ListBox>
+ <ListBox DataSource="{../lbAllEvents.SelectedItem}" Data="{Events}" Height="Fit" >
+ <ItemTemplate>
+ <ListItem Margin="0" Height="16" Width="Fit"
+ Selected="{Background=Yellow}"
+ Unselected="{Background=Transparent}">
+ <DbgEventWidget CacheEnabled="true" Height="10" Width="Fit" Event="{}" Tooltip="#CECrowPlugin.ui.DbgEvtTooltip.crow" TicksPerPixel="3000" VerticalAlignment="Center"/>
+ </ListItem>
+ </ItemTemplate>
+ <Template>
+ <VerticalStack Width="Stretched" >
+ <Scroller Name="scroller" >
+ <HorizontalStack Name="ItemsContainer" Width="Fit" HorizontalAlignment="Left"/>
+ </Scroller>
+ <ScrollBar Style="HScrollBar" Name="scrollbar1" Value="{²../scroller.ScrollX}"
+ LargeIncrement="{../scroller.PageWidth}" SmallIncrement="30" CursorRatio="{../scroller.ChildWidthRatio}"
+ Maximum="{../scroller.MaxScrollX}" Height="12" />
+ </VerticalStack>
+ </Template>
+ </ListBox>
+ </VerticalStack>
+</DockWindow>
+
+
<?xml version="1.0" encoding="utf-8"?>
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
- <TargetFrameworks>netcoreapp5</TargetFrameworks>
+ <TargetFrameworks>netcoreapp3.1</TargetFrameworks>
<EnableDefaultItems>false</EnableDefaultItems>
</PropertyGroup>
CurrentState = Status.Paused;
}
+ /*public Command CMDOptions_SelectNetcoredbgPath = new Command ("...",
+ () => {
+ FileDialog dlg = App.LoadIMLFragment<FileDialog> (@"
+ <FileDialog Caption='Select netcoredbg executable path' CurrentDirectory='{NetcoredbgPath}'
+ ShowFiles='true' ShowHidden='true'/>
+ ");
+ dlg.OkClicked += (sender, e) => NetcoredbgPath = (sender as FileDialog).SelectedFileFullPath;
+ dlg.DataSource = this;
+ }
+ );*/
+
public override string ConfigurationWindowPath => "#CENetcoreDbgPlugin.ui.winConfiguration.crow";
}
}
\ No newline at end of file
<?xml version="1.0"?>
<DockWindow Caption="Roslyn plugin configuration" Width="300" Height="400" Resizable="false">
<VerticalStack RootDataLevel="true" Margin="5">
- <HorizontalStack Height="Fit">
- <Label Width="200" Text="DotNet SDK folder"/>
- <TextBox Width="Stretched" Text="{²SDKFolder}"/>
- <Button Command="{CMDOptions_SelectSDKFolder}" MinimumSize="0,0"/>
- </HorizontalStack>
- <HorizontalStack Height="Fit">
- <Label Width="200" Text="MSBuild root folder"/>
- <TextBox Width="Stretched" Text="{²MSBuildRoot}"/>
- <Button Command="{CMDOptions_SelectMSBuildRoot}" MinimumSize="0,0"/>
- </HorizontalStack>
<HorizontalStack Height="Fit">
<Label Width="200" Text="Netcoredbg path"/>
<TextBox Width="Stretched" Text="{²NetcoredbgPath}"/>
<?xml version="1.0" encoding="utf-8"?>
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
- <TargetFrameworks>netcoreapp5</TargetFrameworks>
+ <TargetFrameworks>netcoreapp3.1</TargetFrameworks>
<EnableDefaultItems>false</EnableDefaultItems>
</PropertyGroup>
public CSDocument (string fullPath) : base (fullPath) {
- tree = (CSharpSyntaxTree)CSharpSyntaxTree.ParseText (Source, CSharpParseOptions.Default);
+ //tree = (CSharpSyntaxTree)CSharpSyntaxTree.ParseText (Source, CSharpParseOptions.Default);
}
/*ProjectCollection tree;
public string RootDir => project.DirectoryPath;
- static string[] defaultTargets = { "Restore", "Build", "Rebuild", "Pack", "Publish"};
+ static string[] defaultTargets = { "Clean", "Restore", "Build", "Rebuild", "Pack", "Publish"};
internal MSBuildProject (SolutionProject solution, ProjectInSolution projectInSolution) : base (projectInSolution.AbsolutePath) {
this.projectInSolution = projectInSolution;
return "#icons.file_type_vscode.svg";
}
}
+ }
+
+ public bool IsCrowProject {
+ get {
+ foreach (ProjectItemNode reference in rootNode.Childs[0].Flatten.OfType<ProjectItemNode>()) {
+ switch (reference.NodeType) {
+ case NodeType.PackageReference:
+ if (reference.Caption == "Crow")
+ return true;
+ break;
+ case NodeType.ProjectReference:
+ if (App.TryGetProject<MSBuildProject> (reference.FullPath, out MSBuildProject msbp) && msbp.IsCrowProject)
+ return true;
+ break;
+ }
+ }
+ return false;
+ }
}
using CrowEditBase;
using Crow;
using static CrowEditBase.CrowEditBase;
+using System;
namespace CERoslynPlugin
{
}
}
}
+ public void onDblClick (object sender, EventArgs e) => App.OpenFile (FullPath);
+
public override string IconSub {
get {
switch (NodeType) {
namespace CERoslynPlugin
{
public class RoslynService : Service {
+ internal CELogger Logger { get; private set; }
+ public LogLevel LogLevel {
+ get => Crow.Configuration.Global.Get<LogLevel>("LogLevel");
+ set {
+ if (LogLevel == value)
+ return;
+ Crow.Configuration.Global.Set ("LogLevel", value);
+ updateLogLevel ();
+ NotifyValueChanged ("LogLevel", value);
+ }
+ }
+ void updateLogLevel () {
+ switch (LogLevel){
+ case LogLevel.Minimal:
+ Logger.Verbosity = Microsoft.Build.Framework.LoggerVerbosity.Minimal;
+ break;
+ case LogLevel.Normal:
+ Logger.Verbosity = Microsoft.Build.Framework.LoggerVerbosity.Normal;
+ break;
+ case LogLevel.Full:
+ Logger.Verbosity = Microsoft.Build.Framework.LoggerVerbosity.Detailed;
+ break;
+ case LogLevel.Debug:
+ Logger.Verbosity = Microsoft.Build.Framework.LoggerVerbosity.Diagnostic;
+ break;
+ }
+ }
public RoslynService () : base () {
configureDefaultSDKPathes ();
foreach (string dll in Directory.GetFiles (MSBuildRoot, "*.dll"))
pluginCtx.LoadFromAssemblyPath (dll);
string capath = Path.Combine (MSBuildRoot, "Roslyn", "bincore");
- foreach (string dll in Directory.GetFiles (capath, "*.dll"))
- pluginCtx.LoadFromAssemblyPath (dll);
+ foreach (string dll in Directory.GetFiles (capath, "*.dll")) {
+ try {
+ pluginCtx.LoadFromAssemblyPath (dll);
+ }
+ catch (Exception ex) {
+ Console.WriteLine ($"[RoslynService]{ex}");
+ }
+
+ }
}
Assembly msbuildResolve (AssemblyLoadContext context, AssemblyName assemblyName) {
string assemblyPath = Path.Combine (MSBuildRoot, assemblyName.Name + ".dll");
}
public override void Start() {
+ Logger = new CELogger ();
+ updateLogLevel ();
Environment.SetEnvironmentVariable ("MSBUILD_EXE_PATH", Path.Combine (MSBuildRoot, "MSBuild.dll"));
Environment.SetEnvironmentVariable ("MSBuildSDKsPath", Path.Combine (MSBuildRoot, "Sdks"));
dlg.DataSource = this;
}
);
- /*public Command CMDOptions_SelectNetcoredbgPath = new Command ("...",
- (sender) => {
- FileDialog dlg = App.LoadIMLFragment<FileDialog> (@"
- <FileDialog Caption='Select netcoredbg executable path' CurrentDirectory='{NetcoredbgPath}'
- ShowFiles='true' ShowHidden='true'/>
- ");
- dlg.OkClicked += (sender, e) => ide.NetcoredbgPath = (sender as FileDialog).SelectedFileFullPath;
- dlg.DataSource = ide;
- }
- );*/
-
void configureDefaultSDKPathes ()
{
namespace CERoslynPlugin
{
- public class SolutionProject : Project {
+ public class SolutionProject : Project {
RoslynService roslynService;
public SolutionProject (string fullPath) : base (fullPath) {
roslynService = App.GetService<RoslynService> ();
roslynService?.Start ();
Load();
+
+ if (Flatten.OfType<MSBuildProject>().Any (msb => msb.IsCrowProject)) {
+ Console.WriteLine ("Is crow project!!");
+ }
}
SolutionFile solutionFile;
public override void Load () {
projectCollection = new ProjectCollection (
null,
- new ILogger [] { new CELogger () },
+ new ILogger [] { roslynService.Logger },
ToolsetDefinitionLocations.Default
);
//IDE.ProgressNotify (10);
}
- IsLoaded = true;
- }
- public override void Unload () {
-
IsLoaded = true;
}
}
<TextBox Width="Stretched" Text="{²MSBuildRoot}"/>
<Button Command="{CMDOptions_SelectMSBuildRoot}" MinimumSize="0,0"/>
</HorizontalStack>
- <HorizontalStack Height="Fit">
- <Label Width="200" Text="Netcoredbg path"/>
- <TextBox Width="Stretched" Text="{²NetcoredbgPath}"/>
- <Button Command="{CMDOptions_SelectNetcoredbgPath}" MinimumSize="0,0"/>
- </HorizontalStack>
+ <EnumSelector RadioButtonStyle="CheckBoxAlt" Caption="Log Level" EnumValue="{²LogLevel}" Fit="true" Background="DarkGrey">
+ <Template>
+ <Popper Caption="{./Caption}" CornerRadius="{./CornerRadius}" Foreground="{./Foreground}" Background="{./Background}">
+ <Template>
+ <Border Style="ControlBorder" Background="{./Background}" CornerRadius="{./CornerRadius}">
+ <HorizontalStack Spacing="1">
+ <Image Style="Icon"
+ MouseEnter="{Background=White}" MouseLeave="{Background=Transparent}"
+ Background="{./Background}"
+ Path="#Crow.Icons.expandable.svg" SvgSub="{./IsChecked}"/>
+ <Label Style="ControlCaption" Text="{./Caption}" Width="60" />
+ <Label Style="ControlCaption" Text="{²LogLevel}" />
+ </HorizontalStack>
+ </Border>
+ </Template>
+ <VerticalStack Name="Content" Width="200" Height="Fit" Background="DarkGrey"/>
+ </Popper>
+ </Template>
+ </EnumSelector>
+
</VerticalStack>
</DockWindow>
-FileAssociations=CrowEdit.Xml.XmlDocument:.xml,.crow,.iml,.itmp,.template
\ No newline at end of file
+FileAssociations=CrowEdit.Xml.XmlDocument:.xml
\ No newline at end of file
protected override Tokenizer CreateTokenizer() => new XmlTokenizer ();
protected override SyntaxAnalyser CreateSyntaxAnalyser() => new XmlSyntaxAnalyser (this);
- string[] allWidgetNames = typeof (Widget).Assembly.GetExportedTypes ().Where(t=>typeof(Widget).IsAssignableFrom (t))
- .Select (s => s.Name).ToArray ();
-
-
- IEnumerable<MemberInfo> getAllCrowTypeMembers (string crowTypeName) {
- Type crowType = IML.Instantiator.GetWidgetTypeFromName (crowTypeName);
- return crowType.GetMembers (BindingFlags.Public | BindingFlags.Instance).
- Where (m=>((m is PropertyInfo pi && pi.CanWrite) || (m is EventInfo)) &&
- m.GetCustomAttribute<XmlIgnoreAttribute>() == null);
- }
- MemberInfo getCrowTypeMember (string crowTypeName, string memberName) {
- Type crowType = IML.Instantiator.GetWidgetTypeFromName (crowTypeName);
- return crowType.GetMember (memberName, BindingFlags.Public | BindingFlags.Instance).FirstOrDefault ();
- }
public override IList GetSuggestions (int pos) {
currentToken = FindTokenIncludingPosition (pos);
currentNode = FindNodeIncludingPosition (pos);
-#if DEBUG
- Console.WriteLine ($"Current Token: {currentToken} Current Node: {currentNode}");
-#endif
-
- if (currentToken.GetTokenType() == XmlTokenType.ElementOpen)
- return new List<string> (allWidgetNames);
- if (currentToken.GetTokenType() == XmlTokenType.ElementName)
- return allWidgetNames.Where (s => s.StartsWith (currentToken.AsString (Source), StringComparison.OrdinalIgnoreCase)).ToList ();
- if (currentNode is AttributeSyntax attribNode) {
- if (currentNode.Parent is ElementTagSyntax eltTag) {
- if (eltTag.NameToken.HasValue) {
- if (currentToken.GetTokenType() == XmlTokenType.AttributeName) {
- return getAllCrowTypeMembers (eltTag.NameToken.Value.AsString (Source))
- .Where (s => s.Name.StartsWith (currentToken.AsString (Source), StringComparison.OrdinalIgnoreCase)).ToList ();
- } else if (attribNode.NameToken.HasValue) {
- if (currentToken.GetTokenType() == XmlTokenType.AttributeValue) {
- MemberInfo mi = getCrowTypeMember (
- eltTag.NameToken.Value.AsString (Source), attribNode.NameToken.Value.AsString (Source));
- if (mi is PropertyInfo pi) {
- if (pi.Name == "Style")
- return App.Styling.Keys
- .Where (s => s.StartsWith (currentToken.AsString (Source), StringComparison.OrdinalIgnoreCase)).ToList ();
- if (pi.PropertyType.IsEnum)
- return Enum.GetNames (pi.PropertyType)
- .Where (s => s.StartsWith (currentToken.AsString (Source), StringComparison.OrdinalIgnoreCase)).ToList ();
- if (pi.PropertyType == typeof(bool))
- return (new string[] {"true", "false"}).
- Where (s => s.StartsWith (currentToken.AsString (Source), StringComparison.OrdinalIgnoreCase)).ToList ();
- if (pi.PropertyType == typeof (Measure))
- return (new string[] {"Stretched", "Fit"}).
- Where (s => s.StartsWith (currentToken.AsString (Source), StringComparison.OrdinalIgnoreCase)).ToList ();
- if (pi.PropertyType == typeof (Fill))
- return EnumsNET.Enums.GetValues<Colors> ()
- .Where (s => s.ToString().StartsWith (currentToken.AsString (Source), StringComparison.OrdinalIgnoreCase)).ToList ();
- }
- } else if (currentToken.GetTokenType() == XmlTokenType.AttributeValueOpen) {
- MemberInfo mi = getCrowTypeMember (
- eltTag.NameToken.Value.AsString (Source), attribNode.NameToken.Value.AsString (Source));
- if (mi is PropertyInfo pi) {
- if (pi.Name == "Style")
- return App.Styling.Keys.ToList ();
- if (pi.PropertyType.IsEnum)
- return Enum.GetNames (pi.PropertyType).ToList ();
- if (pi.PropertyType == typeof(bool))
- return new List<string> (new string[] {"true", "false"});
- if (pi.PropertyType == typeof (Fill))
- return EnumsNET.Enums.GetValues<Colors> ().ToList ();
- if (pi.PropertyType == typeof (Measure))
- return new List<string> (new string[] {"Stretched", "Fit"});
- }
- }
- }
- }
- }
- } else if (currentToken.GetTokenType() != XmlTokenType.AttributeValueClose &&
- currentToken.GetTokenType() != XmlTokenType.EmptyElementClosing &&
- currentToken.GetTokenType() != XmlTokenType.ClosingSign &&
- currentNode is ElementStartTagSyntax eltStartTag) {
- if (currentToken.GetTokenType() == XmlTokenType.AttributeName)
- return getAllCrowTypeMembers (eltStartTag.NameToken.Value.AsString (Source))
- .Where (s => s.Name.StartsWith (currentToken.AsString (Source), StringComparison.OrdinalIgnoreCase)).ToList ();
- //else if (currentToken.Type == TokenType.ElementName)
- // Suggestions = getAllCrowTypeMembers (eltStartTag.NameToken.Value.AsString (Source)).ToList ();
- } else {
- /*SyntaxNode curNode = source.FindNodeIncludingPosition (pos);
- Console.WriteLine ($"Current Node: {curNode}");
- if (curNode is ElementStartTagSyntax eltStartTag &&
- (currentToken.Type != TokenType.ClosingSign && currentToken.Type != TokenType.EmptyElementClosing && currentToken.Type != TokenType.Unknown)) {
- Suggestions = getAllCrowTypeMembers (eltStartTag.NameToken.Value.AsString (Source)).ToList ();
- } else*/
-
- }
return null;
}
public override TextChange? GetCompletionForCurrentToken (object suggestion, out TextSpan? newSelection) {
newSelection = null;
-
- string selectedSugg = suggestion is MemberInfo mi ?
- mi.Name : suggestion?.ToString ();
- if (selectedSugg == null)
- return null;
-
- if (currentToken.GetTokenType() == XmlTokenType.ElementOpen ||
- currentToken.GetTokenType() == XmlTokenType.WhiteSpace ||
- currentToken.GetTokenType() == XmlTokenType.AttributeValueOpen)
- return new TextChange (currentToken.End, 0, selectedSugg);
-
- if (currentToken.GetTokenType() == XmlTokenType.AttributeName && currentNode is AttributeSyntax attrib) {
- if (attrib.ValueToken.HasValue) {
- TextChange tc = new TextChange (currentToken.Start, currentToken.Length, selectedSugg);
- newSelection = new TextSpan(
- attrib.ValueToken.Value.Start + tc.CharDiff + 1,
- attrib.ValueToken.Value.End + tc.CharDiff - 1
- );
- return tc;
- } else {
- newSelection = TextSpan.FromStartAndLength (currentToken.Start + selectedSugg.Length + 2);
- return new TextChange (currentToken.Start, currentToken.Length, selectedSugg + "=\"\"");
- }
- }
-
- return new TextChange (currentToken.Start, currentToken.Length, selectedSugg);
+ return null;
}
public override Color GetColorForToken(TokenType tokType)
DockStack mainDock;
public Command CMDSave, CMDSaveAs, CMDQuit, CMDHelp, CMDAbout, CMDOptions;
- public CommandGroup AllCommands => new CommandGroup (
- FileCommands,
- EditCommands,
- ViewCommands
- );
- public CommandGroup ViewCommands = new CommandGroup ("View",
- new Command("Explorer", (sender) => loadWindowWithThisDataSource (sender, "#CrowEdit.ui.windows.winFileExplorer.crow")),
- new Command("Editors", (sender) => loadWindowWithThisDataSource (sender, "#CrowEdit.ui.windows.winEditor.crow")),
- new Command("Projects", (sender) => loadWindowWithThisDataSource (sender, "#CrowEdit.ui.windows.winProjects.crow")),
- new Command("Logs", (sender) => loadWindowWithThisDataSource (sender, "#CrowEdit.ui.windows.winLogs.crow")),
- new Command("Crow Preview", (sender) => loadWindowWithThisDataSource (sender, "#CECrowDebugLog.ui.winCrowPreview.crow")),
- new Command("Services", (sender) => loadWindowWithThisDataSource (sender, "#CrowEdit.ui.windows.winServices.crow")),
- new Command("Plugins", (sender) => loadWindowWithThisDataSource (sender, "#CrowEdit.ui.windows.winPlugins.crow"))
- );
void initCommands (){
FileCommands = new CommandGroup ("File",
new Command("New", createNewFile, "#icons.blank-file.svg"),
new Command ("Paste", default(Action), "#icons.paste-on-document.svg", false)
);
-
- CMDHelp = new Command(new Action(() => System.Diagnostics.Debug.WriteLine("help"))) { Caption = "Help", Icon = new SvgPicture("#CrowEdit.ui.icons.question.svg")};
+ ViewCommands = new CommandGroup ("View",
+ new Command("Explorer", () => LoadWindow ("#CrowEdit.ui.windows.winFileExplorer.crow", this)),
+ new Command("Editors", () => LoadWindow ("#CrowEdit.ui.windows.winEditor.crow", this)),
+ new Command("Projects", () => LoadWindow ("#CrowEdit.ui.windows.winProjects.crow", this)),
+ new Command("Logs", () => LoadWindow ("#CrowEdit.ui.windows.winLogs.crow", this), "#icons.log.svg"),
+ new Command("Services", () => LoadWindow ("#CrowEdit.ui.windows.winServices.crow", this), "#icons.services.svg"),
+ new Command("Plugins", () => LoadWindow ("#CrowEdit.ui.windows.winPlugins.crow", this), "#icons.plugins.svg")
+ );
+ CMDHelp = new Command("Help", () => System.Diagnostics.Debug.WriteLine("help"), "#icons.question.svg");
+
+ CommandsRoot = new CommandGroup (
+ FileCommands,
+ EditCommands,
+ ViewCommands,
+ new CommandGroup ("Help", CMDHelp)
+ );
}
+
static void loadWindowWithThisDataSource(object sender, string path) {
Widget w = sender as Widget;
void openFileDialog_OkClicked (object sender, EventArgs e)
{
- if (OpenFile ((sender as FileDialog).SelectedFile) is Document doc)
+ if (OpenFile ((sender as FileDialog).SelectedFileFullPath) is Document doc)
CurrentDocument = doc;
}
CurrentDocument = doc;
}
void tv_projects_SelectedItemChanged (object sender, SelectionChangeEventArgs e) {
- if (e.NewValue is IFileNode fi) {
+ if (e.NewValue is Project prj) {
+ CurrentProject = prj;
+ }
+ /*if (e.NewValue is IFileNode fi) {
if (string.IsNullOrEmpty (fi.FullPath) || ! File.Exists (fi.FullPath))
return;
if (TryGetDefaultTypeForExtension (Path.GetExtension (fi.FullPath), out Type clientType)) {
if (typeof(Document).IsAssignableFrom (clientType)) {
if (OpenedDocuments.FirstOrDefault (d => d.FullPath == fi.FullPath) is Document doc)
CurrentDocument = doc;
- /*} else if (typeof(Service).IsAssignableFrom (clientType))
- doc = GetService (clientType)?.OpenDocument (CurrentFilePath);*/
+ //} else if (typeof(Service).IsAssignableFrom (clientType))
+ // doc = GetService (clientType)?.OpenDocument (CurrentFilePath);
} else if (typeof(Project).IsAssignableFrom (clientType)) {
if (Projects.FirstOrDefault (p=>p.FullPath == fi.FullPath) is Project prj)
CurrentProject = prj;
}
}
- }
+ }*/
}
void saveOpenedDocumentList () {
<?xml version="1.0"?>
<Button Command="{}" Width="Stretched">
<Template>
- <HorizontalStack Background="{./Background}" Width="Stretched" Height="Stretched" Margin="3"
+ <HorizontalStack Background="{./Background}" Width="Stretched" Height="Stretched" Margin="3" Spacing="2"
MouseEnter="{Background=${ControlHighlight}}"
MouseLeave="{Background=Transparent}">
<Image Style="MenuIcon" Picture="{./Icon}" />
- <Label Text="{./Caption}" Width="Stretched" Height="Stretched"/>
+ <Label Text="{./Caption}" Width="Stretched" Height="Stretched" Margin="1"/>
</HorizontalStack>
</Template>
</Button>
<?xml version="1.0"?>
<VerticalStack DataSourceType="CrowEdit" Spacing="0" >
- <Menu Data="{AllCommands}" >
+ <Menu Data="{CommandsRoot}" >
<ItemTemplate DataType="Crow.Command" Path="#CrowEdit.ui.MenuButton.template"/>
<ItemTemplate DataType="Crow.CommandGroup" >
<MenuItem Data="{Commands}" Width="Fit" IsEnabled="{CanExecute}"
<TreeView Name="treeview" IsRoot="true" RootDataLevel="true" Data="{Projects}" Background="Onyx"
SelectedItemChanged="tv_projects_SelectedItemChanged" >
+ <ItemTemplate DataType="default" >
+ <!--<ItemTemplate DataType="CrowEditBase.Document" >-->
+ <ListItem CornerRadius="2" Margin="1" Height="Fit" Width="Stretched"
+ BubbleMouseEvent="None" ContextCommands="{Commands}"
+ 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>
+ </ListItem>
+
+ </ItemTemplate>
- <ItemTemplate DataType="default" Data="Childs" Path="#CrowEditBase.ui.TreeExpandable.template" />
<ItemTemplate DataType="CERoslynPlugin.MSBuildProject" Data="Children" Path="#CrowEditBase.ui.TreeExpandable.template" />
- <ItemTemplate DataType="CrowEditBase.Project" Data="SubProjects" Path="#CrowEditBase.ui.TreeExpandable.template" />
+ <ItemTemplate DataType="CrowEditBase.VirtualNode" Data="Childs" Path="#CrowEditBase.ui.TreeExpandable.template" />
+ <ItemTemplate DataType="CrowEditBase.Project" Data="SubProjects" Path="#CrowEditBase.ui.TreeExpandable.template" />
+ <!--<ItemTemplate DataType="CrowEditBase.TreeNode" DataTest="NodeType" Data="Childs" Path="#CrowEditBase.ui.TreeExpandable.template" />-->
</TreeView>
</DockWindow>