EMM
This commit is contained in:
parent
5a48d4041d
commit
66a3c6526f
|
@ -1,3 +0,0 @@
|
|||
{
|
||||
"help":"https://go.microsoft.com/fwlink/?linkid=866610"
|
||||
}
|
|
@ -5,15 +5,17 @@ VisualStudioVersion = 17.10.34928.147
|
|||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RustTools", "RustTools\RustTools.csproj", "{2B938A8C-2116-4961-A9D7-5A755FFC1943}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{64F47B2C-DECA-42CB-AE37-EE7DC9F0035E}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TextControlBox", "TextControlBox\TextControlBox.csproj", "{70FED101-CE0C-4B8E-90BD-DC56C2ACA86F}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Debug|ARM = Debug|ARM
|
||||
Debug|arm64 = Debug|arm64
|
||||
Debug|x64 = Debug|x64
|
||||
Debug|x86 = Debug|x86
|
||||
Release|Any CPU = Release|Any CPU
|
||||
Release|ARM = Release|ARM
|
||||
Release|arm64 = Release|arm64
|
||||
Release|x64 = Release|x64
|
||||
Release|x86 = Release|x86
|
||||
|
@ -22,6 +24,9 @@ Global
|
|||
{2B938A8C-2116-4961-A9D7-5A755FFC1943}.Debug|Any CPU.ActiveCfg = Debug|x64
|
||||
{2B938A8C-2116-4961-A9D7-5A755FFC1943}.Debug|Any CPU.Build.0 = Debug|x64
|
||||
{2B938A8C-2116-4961-A9D7-5A755FFC1943}.Debug|Any CPU.Deploy.0 = Debug|x64
|
||||
{2B938A8C-2116-4961-A9D7-5A755FFC1943}.Debug|ARM.ActiveCfg = Debug|x64
|
||||
{2B938A8C-2116-4961-A9D7-5A755FFC1943}.Debug|ARM.Build.0 = Debug|x64
|
||||
{2B938A8C-2116-4961-A9D7-5A755FFC1943}.Debug|ARM.Deploy.0 = Debug|x64
|
||||
{2B938A8C-2116-4961-A9D7-5A755FFC1943}.Debug|arm64.ActiveCfg = Debug|arm64
|
||||
{2B938A8C-2116-4961-A9D7-5A755FFC1943}.Debug|arm64.Build.0 = Debug|arm64
|
||||
{2B938A8C-2116-4961-A9D7-5A755FFC1943}.Debug|arm64.Deploy.0 = Debug|arm64
|
||||
|
@ -34,6 +39,9 @@ Global
|
|||
{2B938A8C-2116-4961-A9D7-5A755FFC1943}.Release|Any CPU.ActiveCfg = Release|x64
|
||||
{2B938A8C-2116-4961-A9D7-5A755FFC1943}.Release|Any CPU.Build.0 = Release|x64
|
||||
{2B938A8C-2116-4961-A9D7-5A755FFC1943}.Release|Any CPU.Deploy.0 = Release|x64
|
||||
{2B938A8C-2116-4961-A9D7-5A755FFC1943}.Release|ARM.ActiveCfg = Release|x64
|
||||
{2B938A8C-2116-4961-A9D7-5A755FFC1943}.Release|ARM.Build.0 = Release|x64
|
||||
{2B938A8C-2116-4961-A9D7-5A755FFC1943}.Release|ARM.Deploy.0 = Release|x64
|
||||
{2B938A8C-2116-4961-A9D7-5A755FFC1943}.Release|arm64.ActiveCfg = Release|arm64
|
||||
{2B938A8C-2116-4961-A9D7-5A755FFC1943}.Release|arm64.Build.0 = Release|arm64
|
||||
{2B938A8C-2116-4961-A9D7-5A755FFC1943}.Release|arm64.Deploy.0 = Release|arm64
|
||||
|
@ -43,6 +51,26 @@ Global
|
|||
{2B938A8C-2116-4961-A9D7-5A755FFC1943}.Release|x86.ActiveCfg = Release|x86
|
||||
{2B938A8C-2116-4961-A9D7-5A755FFC1943}.Release|x86.Build.0 = Release|x86
|
||||
{2B938A8C-2116-4961-A9D7-5A755FFC1943}.Release|x86.Deploy.0 = Release|x86
|
||||
{70FED101-CE0C-4B8E-90BD-DC56C2ACA86F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{70FED101-CE0C-4B8E-90BD-DC56C2ACA86F}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{70FED101-CE0C-4B8E-90BD-DC56C2ACA86F}.Debug|ARM.ActiveCfg = Debug|Any CPU
|
||||
{70FED101-CE0C-4B8E-90BD-DC56C2ACA86F}.Debug|ARM.Build.0 = Debug|Any CPU
|
||||
{70FED101-CE0C-4B8E-90BD-DC56C2ACA86F}.Debug|arm64.ActiveCfg = Debug|Any CPU
|
||||
{70FED101-CE0C-4B8E-90BD-DC56C2ACA86F}.Debug|arm64.Build.0 = Debug|Any CPU
|
||||
{70FED101-CE0C-4B8E-90BD-DC56C2ACA86F}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{70FED101-CE0C-4B8E-90BD-DC56C2ACA86F}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{70FED101-CE0C-4B8E-90BD-DC56C2ACA86F}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{70FED101-CE0C-4B8E-90BD-DC56C2ACA86F}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{70FED101-CE0C-4B8E-90BD-DC56C2ACA86F}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{70FED101-CE0C-4B8E-90BD-DC56C2ACA86F}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{70FED101-CE0C-4B8E-90BD-DC56C2ACA86F}.Release|ARM.ActiveCfg = Release|Any CPU
|
||||
{70FED101-CE0C-4B8E-90BD-DC56C2ACA86F}.Release|ARM.Build.0 = Release|Any CPU
|
||||
{70FED101-CE0C-4B8E-90BD-DC56C2ACA86F}.Release|arm64.ActiveCfg = Release|Any CPU
|
||||
{70FED101-CE0C-4B8E-90BD-DC56C2ACA86F}.Release|arm64.Build.0 = Release|Any CPU
|
||||
{70FED101-CE0C-4B8E-90BD-DC56C2ACA86F}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{70FED101-CE0C-4B8E-90BD-DC56C2ACA86F}.Release|x64.Build.0 = Release|Any CPU
|
||||
{70FED101-CE0C-4B8E-90BD-DC56C2ACA86F}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{70FED101-CE0C-4B8E-90BD-DC56C2ACA86F}.Release|x86.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
|
|
@ -47,10 +47,6 @@ public partial class App : Microsoft.UI.Xaml.Application
|
|||
public App()
|
||||
{
|
||||
InitializeComponent();
|
||||
//if (!Directory.Exists(wj.CD))
|
||||
//{
|
||||
// Directory.CreateDirectory(wj.CD);
|
||||
//}
|
||||
// 注册激活事件处理程序
|
||||
Host = Microsoft.Extensions.Hosting.Host.
|
||||
CreateDefaultBuilder().
|
||||
|
@ -136,26 +132,18 @@ public partial class App : Microsoft.UI.Xaml.Application
|
|||
}
|
||||
return;
|
||||
}
|
||||
// If this is the first instance launched, then register it as the "main" instance.
|
||||
// If this isn't the first instance launched, then "main" will already be registered,
|
||||
// so retrieve it.
|
||||
var mainInstance = Microsoft.Windows.AppLifecycle.AppInstance.FindOrRegisterForKey("main");
|
||||
// If the instance that's executing the OnLaunched handler right now
|
||||
// isn't the "main" instance.
|
||||
if (!mainInstance.IsCurrent)
|
||||
{
|
||||
// Redirect the activation (and args) to the "main" instance, and exit.
|
||||
await mainInstance.RedirectActivationToAsync(activatedEventArgs);
|
||||
System.Diagnostics.Process.GetCurrentProcess().Kill();
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
//MainWindow.Activate();
|
||||
new Editor.EditorWin().Activate();
|
||||
//MainWindow = new MainWindow();
|
||||
//new Editor.EditorWin().Activate();
|
||||
MainWindow = new MainWindow();
|
||||
await App.GetService<IActivationService>().ActivateAsync(args);
|
||||
//await App.GetService<IActivationService>().ActivateAsync(args);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 44 KiB |
|
@ -1 +0,0 @@
|
|||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1721905357214" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="26869" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M298.666667 896a32 32 0 0 1 32-32h362.666666a32 32 0 0 1 0 64h-362.666666A32 32 0 0 1 298.666667 896zM382.72 340.053333a32 32 0 0 1 45.226667 0L512 424.106667l84.053333-84.053334a32 32 0 1 1 45.226667 45.226667l-97.28 97.28v136.106667a32 32 0 0 1-64 0v-136.106667L382.72 385.28a32 32 0 0 1 0-45.226667z" fill="#777A80" p-id="26870"></path><path d="M661.333333 662.4l23.978667-19.2a277.333333 277.333333 0 1 0-346.624 0l23.978667 19.2V725.333333a21.333333 21.333333 0 0 0 21.333333 21.333334h256a21.333333 21.333333 0 0 0 21.333333-21.333334v-62.933333z m64 30.72V725.333333a85.333333 85.333333 0 0 1-85.333333 85.333334H384a85.333333 85.333333 0 0 1-85.333333-85.333334v-32.213333a341.333333 341.333333 0 1 1 426.666666 0z" fill="#777A80" p-id="26871"></path></svg>
|
Before Width: | Height: | Size: 1.1 KiB |
|
@ -73,6 +73,7 @@
|
|||
Grid.Column="0"
|
||||
Margin="16,0,0,0" />
|
||||
</Grid>
|
||||
|
||||
<ScrollViewer
|
||||
Grid.Row="2"
|
||||
Grid.Column="0"
|
||||
|
@ -96,7 +97,48 @@
|
|||
SelectionMode="Single" />
|
||||
</ScrollViewer>
|
||||
|
||||
<Grid Grid.Row="1" Grid.Column="1" />
|
||||
<ScrollViewer
|
||||
Grid.Row="1"
|
||||
Grid.Column="1"
|
||||
HorizontalScrollBarVisibility="Visible"
|
||||
HorizontalScrollMode="Auto"
|
||||
IsHorizontalRailEnabled="True"
|
||||
IsHorizontalScrollChainingEnabled="True">
|
||||
|
||||
<Grid
|
||||
x:Name="gridedit"
|
||||
Grid.Row="1"
|
||||
Grid.Column="1">
|
||||
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<ListBox
|
||||
Grid.Column="0"
|
||||
Margin="0,0,10,0"
|
||||
Background="Transparent"
|
||||
ItemsSource="{x:Bind lineNumberList}"
|
||||
ScrollViewer.IsVerticalRailEnabled="False">
|
||||
<ListBox.ItemContainerStyle>
|
||||
<Style TargetType="ListBoxItem">
|
||||
<Setter Property="Padding" Value="0" />
|
||||
</Style>
|
||||
</ListBox.ItemContainerStyle>
|
||||
<ListBox.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<TextBlock Name="listboxtext" Text="{Binding}" />
|
||||
</DataTemplate>
|
||||
</ListBox.ItemTemplate>
|
||||
</ListBox>
|
||||
<RichEditBox
|
||||
x:Name="editor"
|
||||
Grid.Column="1"
|
||||
Background="Transparent"
|
||||
TextChanged="editor_TextChanged" />
|
||||
</Grid>
|
||||
</ScrollViewer>
|
||||
</Grid>
|
||||
</Page>
|
||||
</windowex:WindowEx>
|
||||
|
|
|
@ -3,27 +3,14 @@ using System.ComponentModel;
|
|||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Reflection.Metadata;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
using Microsoft.UI;
|
||||
using Microsoft.UI.Text;
|
||||
using Microsoft.UI.Windowing;
|
||||
using Microsoft.UI.Xaml;
|
||||
using Microsoft.UI.Xaml.Controls;
|
||||
using Microsoft.UI.Xaml.Documents;
|
||||
using Microsoft.UI.Xaml.Input;
|
||||
using Microsoft.UI.Xaml.Media;
|
||||
using Microsoft.UI.Xaml.Media.Imaging;
|
||||
using RustTools.muqing;
|
||||
using Windows.ApplicationModel.Core;
|
||||
using Windows.ApplicationModel.DataTransfer;
|
||||
using Windows.Foundation;
|
||||
using Windows.Graphics.Imaging;
|
||||
using Windows.Storage.Pickers;
|
||||
using Windows.Storage;
|
||||
using Windows.UI.Core;
|
||||
using Windows.UI.Core.Preview;
|
||||
using Windows.UI.Popups;
|
||||
using Windows.UI.WindowManagement;
|
||||
using WinRT.Interop;
|
||||
namespace RustTools.Editor;
|
||||
/// <summary>
|
||||
|
@ -31,9 +18,10 @@ namespace RustTools.Editor;
|
|||
/// </summary>
|
||||
public sealed partial class EditorWin : WindowEx
|
||||
{
|
||||
|
||||
private readonly ObservableCollection<string> lineNumberList = new();
|
||||
//目录列表
|
||||
public ObservableCollection<ExplorerItem> DataSource=new ();
|
||||
private Microsoft.UI.Windowing.AppWindow? app;
|
||||
public EditorWin()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
@ -45,7 +33,8 @@ public sealed partial class EditorWin : WindowEx
|
|||
gj.UpdateTitleBar(this, frame.ActualTheme);
|
||||
page.RequestedTheme = frame.ActualTheme;
|
||||
}
|
||||
|
||||
//new CodeEditorControl();
|
||||
//new Editor.
|
||||
//WindowManager.Get(this).IsMinimizable = false;
|
||||
//app = GetAppWindowForCurrentWindow();
|
||||
//app.Closing += OnClosing;
|
||||
|
@ -56,14 +45,38 @@ public sealed partial class EditorWin : WindowEx
|
|||
TitleText.Text = directoryInfo.Name;
|
||||
Closed += EditorWin_Closed;
|
||||
var v = wj.dqwb("D:\\steam\\steamapps\\common\\Rusted Warfare\\mods\\units\\赤道·联合进攻0.9补丁版0.2\\侵蚀者共和国\\指挥中心\\corrode_command.ini");
|
||||
//CodeEditor.Document.SetText(TextSetOptions.None,v);
|
||||
//EditorView.Editor.SetText(v);
|
||||
//CodeEditorControl.HighlightingLanguage.
|
||||
editor.Document.SetText(Microsoft.UI.Text.TextSetOptions.None,v);
|
||||
|
||||
// »ñÈ¡µÚÒ»¸ö¶ÎÂä
|
||||
//listboxtext
|
||||
gj.sc(editor.Document.Selection.CharacterFormat.Size);
|
||||
TextLine();
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void editor_TextChanged(object sender, RoutedEventArgs e)
|
||||
{
|
||||
TextLine();
|
||||
|
||||
}
|
||||
public void TextLine()
|
||||
{
|
||||
lineNumberList.Clear();
|
||||
editor.Document.GetText(Microsoft.UI.Text.TextGetOptions.NoHidden, out var a);
|
||||
var lineCount = a.Split(new[] { "\r\n", "\n", "\r" }, StringSplitOptions.None).Length;
|
||||
if (lineCount < 1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
for (var i = 1; i <= lineCount; i++)
|
||||
{
|
||||
lineNumberList.Add((i).ToString());
|
||||
}
|
||||
}
|
||||
|
||||
//用户有没有保存
|
||||
private bool IsSave = false;
|
||||
private bool IsSave = true;
|
||||
private ContentDialog? ClosedDialog;
|
||||
private async void EditorWin_Closed(object sender, WindowEventArgs e)
|
||||
{
|
||||
|
@ -211,5 +224,4 @@ public sealed partial class EditorWin : WindowEx
|
|||
{
|
||||
sender.TabItems.Remove(args.Tab);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
<RootNamespace>RustTools</RootNamespace>
|
||||
<Platform>x64</Platform>
|
||||
<Platforms>x86;x64;arm64</Platforms>
|
||||
<EnablePreviewMsixTooling>true</EnablePreviewMsixTooling>
|
||||
<WindowsAppSDKSelfContained>true</WindowsAppSDKSelfContained>
|
||||
<RuntimeIdentifiers>win10-x86;win10-x64;win10-arm64</RuntimeIdentifiers>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
|
@ -28,14 +29,11 @@
|
|||
<GenerateTestArtifacts>True</GenerateTestArtifacts>
|
||||
<AppxBundle>Never</AppxBundle>
|
||||
<AppxPackageDir>D:\RustTools</AppxPackageDir>
|
||||
|
||||
</PropertyGroup>
|
||||
|
||||
|
||||
<ItemGroup>
|
||||
<Manifest Include="$(ApplicationManifest)" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.1.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Hosting" Version="6.0.1" />
|
||||
<PackageReference Include="Microsoft.WindowsAppSDK" Version="1.4.231008000" />
|
||||
|
@ -48,15 +46,19 @@
|
|||
<PackageReference Include="Microsoft.Windows.CsWinRT" Version="2.0.7" />
|
||||
<PackageReference Include="Microsoft.WindowsAppSDK" Version="1.5.240227000" />
|
||||
<PackageReference Include="Microsoft.Windows.SDK.BuildTools" Version="10.0.22621.3233" />
|
||||
|
||||
<Manifest Include="$(ApplicationManifest)" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="Assets\**">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\TextControlBox\TextControlBox.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition="'$(DisableMsixProjectCapabilityAddedByProject)'!='true' and '$(EnableMsixTooling)'=='true'">
|
||||
<ProjectCapability Include="Msix" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
28
TextControlBox/Enums/LineEnding.cs
Normal file
28
TextControlBox/Enums/LineEnding.cs
Normal file
|
@ -0,0 +1,28 @@
|
|||
namespace TextControlBoxNS
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the three default line endings: LF (Line Feed), CRLF (Carriage Return + Line Feed), and CR (Carriage Return).
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The LineEnding enum represents the different line ending formats that can be used in the textbox.
|
||||
/// The enum defines three values: LF, CRLF, and CR, corresponding to the different line ending formats.
|
||||
/// - LF: Represents the Line Feed character '\n' used for line breaks in Unix-based systems.
|
||||
/// - CRLF: Represents the Carriage Return + Line Feed sequence '\r\n' used for line breaks in Windows-based systems.
|
||||
/// - CR: Represents the Carriage Return character '\r' used for line breaks in older Macintosh systems.
|
||||
/// </remarks>
|
||||
public enum LineEnding
|
||||
{
|
||||
/// <summary>
|
||||
/// Line Feed ('\n')
|
||||
/// </summary>
|
||||
LF,
|
||||
/// <summary>
|
||||
/// Carriage Return + Line Feed ('\r\n')
|
||||
/// </summary>
|
||||
CRLF,
|
||||
/// <summary>
|
||||
/// Carriage Return ('\r')
|
||||
/// </summary>
|
||||
CR
|
||||
}
|
||||
}
|
7
TextControlBox/Enums/LineMoveDirection.cs
Normal file
7
TextControlBox/Enums/LineMoveDirection.cs
Normal file
|
@ -0,0 +1,7 @@
|
|||
namespace TextControlBoxNS
|
||||
{
|
||||
internal enum LineMoveDirection
|
||||
{
|
||||
Up, Down
|
||||
}
|
||||
}
|
39
TextControlBox/Enums/SearchResult.cs
Normal file
39
TextControlBox/Enums/SearchResult.cs
Normal file
|
@ -0,0 +1,39 @@
|
|||
namespace TextControlBoxNS
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the result of a search operation in the textbox.
|
||||
/// </summary>
|
||||
public enum SearchResult
|
||||
{
|
||||
/// <summary>
|
||||
/// The target text was found during the search operation.
|
||||
/// </summary>
|
||||
Found,
|
||||
|
||||
/// <summary>
|
||||
/// The target text was not found during the search operation.
|
||||
/// </summary>
|
||||
NotFound,
|
||||
|
||||
/// <summary>
|
||||
/// The search input provided for the search operation was invalid or empty.
|
||||
/// </summary>
|
||||
InvalidInput,
|
||||
|
||||
/// <summary>
|
||||
/// The search operation reached the beginning of the text without finding the target text.
|
||||
/// </summary>
|
||||
ReachedBegin,
|
||||
|
||||
/// <summary>
|
||||
/// The search operation reached the end of the text without finding the target text.
|
||||
/// </summary>
|
||||
ReachedEnd,
|
||||
|
||||
/// <summary>
|
||||
/// The search operation was attempted, but the search was not started.
|
||||
/// </summary>
|
||||
SearchNotOpened
|
||||
}
|
||||
|
||||
}
|
13
TextControlBox/Extensions/ColorExtension.cs
Normal file
13
TextControlBox/Extensions/ColorExtension.cs
Normal file
|
@ -0,0 +1,13 @@
|
|||
using Windows.UI;
|
||||
|
||||
namespace TextControlBoxNS.Extensions
|
||||
{
|
||||
internal static class ColorExtension
|
||||
{
|
||||
public static Windows.UI.Color ToMediaColor(this System.Drawing.Color drawingColor)
|
||||
{
|
||||
return Windows.UI.Color.FromArgb(drawingColor.A, drawingColor.R, drawingColor.G, drawingColor.B);
|
||||
}
|
||||
public static string ToHex(this Color c) => $"#{c.R:X2}{c.G:X2}{c.B:X2}";
|
||||
}
|
||||
}
|
10
TextControlBox/Extensions/IntExtension.cs
Normal file
10
TextControlBox/Extensions/IntExtension.cs
Normal file
|
@ -0,0 +1,10 @@
|
|||
namespace TextControlBoxNS.Extensions
|
||||
{
|
||||
internal static class IntExtension
|
||||
{
|
||||
public static bool IsInRange(this int value, int start, int count)
|
||||
{
|
||||
return value >= start && value <= start + count;
|
||||
}
|
||||
}
|
||||
}
|
137
TextControlBox/Extensions/ListExtension.cs
Normal file
137
TextControlBox/Extensions/ListExtension.cs
Normal file
|
@ -0,0 +1,137 @@
|
|||
using Collections.Pooled;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using TextControlBoxNS.Helper;
|
||||
|
||||
namespace TextControlBoxNS.Extensions
|
||||
{
|
||||
internal static class ListExtension
|
||||
{
|
||||
private static int CurrentLineIndex = 0;
|
||||
|
||||
public static string GetLineText(this PooledList<string> list, int index)
|
||||
{
|
||||
if (list.Count == 0)
|
||||
return "";
|
||||
|
||||
if (index == -1 && list.Count > 0)
|
||||
return list[list.Count - 1];
|
||||
|
||||
index = index >= list.Count ? list.Count - 1 : index > 0 ? index : 0;
|
||||
return list[index];
|
||||
}
|
||||
|
||||
public static int GetLineLength(this PooledList<string> list, int index)
|
||||
{
|
||||
return GetLineText(list, index).Length;
|
||||
}
|
||||
|
||||
public static void AddLine(this PooledList<string> list, string content = "")
|
||||
{
|
||||
list.Add(content);
|
||||
}
|
||||
public static void SetLineText(this PooledList<string> list, int line, string text)
|
||||
{
|
||||
if (line == -1)
|
||||
line = list.Count - 1;
|
||||
|
||||
line = Math.Clamp(line, 0, list.Count - 1);
|
||||
|
||||
list[line] = text;
|
||||
}
|
||||
public static string GetCurrentLineText(this PooledList<string> list)
|
||||
{
|
||||
return list[CurrentLineIndex < list.Count ? CurrentLineIndex : list.Count - 1 < 0 ? 0 : list.Count - 1];
|
||||
}
|
||||
public static void SetCurrentLineText(this PooledList<string> list, string text)
|
||||
{
|
||||
list[CurrentLineIndex < list.Count ? CurrentLineIndex : list.Count - 1] = text;
|
||||
}
|
||||
public static int CurrentLineLength(this PooledList<string> list)
|
||||
{
|
||||
return GetCurrentLineText(list).Length;
|
||||
}
|
||||
public static void UpdateCurrentLine(this PooledList<string> _, int currentLine)
|
||||
{
|
||||
CurrentLineIndex = currentLine;
|
||||
}
|
||||
public static void String_AddToEnd(this PooledList<string> list, int line, string add)
|
||||
{
|
||||
list[line] = list[line] + add;
|
||||
}
|
||||
public static void InsertOrAdd(this PooledList<string> list, int index, string lineText)
|
||||
{
|
||||
if (index >= list.Count || index == -1)
|
||||
list.Add(lineText);
|
||||
else
|
||||
list.Insert(index, lineText);
|
||||
}
|
||||
public static void InsertOrAddRange(this PooledList<string> list, IEnumerable<string> lines, int index)
|
||||
{
|
||||
if (index >= list.Count)
|
||||
list.AddRange(lines);
|
||||
else
|
||||
list.InsertRange(index < 0 ? 0 : index, lines);
|
||||
}
|
||||
public static void InsertNewLine(this PooledList<string> list, int index, string content = "")
|
||||
{
|
||||
list.InsertOrAdd(index, content);
|
||||
}
|
||||
public static void DeleteAt(this PooledList<string> list, int index)
|
||||
{
|
||||
if (index >= list.Count)
|
||||
index = list.Count - 1 < 0 ? list.Count - 1 : 0;
|
||||
|
||||
list.RemoveAt(index);
|
||||
list.TrimExcess();
|
||||
}
|
||||
private static IEnumerable<string> GetLines_Small(this PooledList<string> totalLines, int start, int count)
|
||||
{
|
||||
var res = ListHelper.CheckValues(totalLines, start, count);
|
||||
|
||||
for (int i = 0; i < res.Count; i++)
|
||||
{
|
||||
yield return totalLines[i + res.Index];
|
||||
}
|
||||
}
|
||||
|
||||
public static IEnumerable<string> GetLines(this PooledList<string> totalLines, int start, int count)
|
||||
{
|
||||
//use different algorithm for small amount of lines:
|
||||
if (start + count < 400)
|
||||
{
|
||||
return GetLines_Small(totalLines, start, count);
|
||||
}
|
||||
|
||||
return totalLines.Skip(start).Take(count);
|
||||
}
|
||||
|
||||
public static string GetString(this IEnumerable<string> lines, string NewLineCharacter)
|
||||
{
|
||||
return string.Join(NewLineCharacter, lines);
|
||||
}
|
||||
|
||||
public static void Safe_RemoveRange(this PooledList<string> totalLines, int index, int count)
|
||||
{
|
||||
var res = ListHelper.CheckValues(totalLines, index, count);
|
||||
totalLines.RemoveRange(res.Index, res.Count);
|
||||
totalLines.TrimExcess();
|
||||
|
||||
//clear up the memory of the list when more than 1mio items are removed
|
||||
if (res.Count > 1_000_000)
|
||||
ListHelper.GCList(totalLines);
|
||||
}
|
||||
public static string[] GetLines(this string[] lines, int start, int count)
|
||||
{
|
||||
return lines.Skip(start).Take(count).ToArray();
|
||||
}
|
||||
|
||||
public static void SwapLines(this PooledList<string> lines, int originalindex, int newindex)
|
||||
{
|
||||
string oldLine = lines.GetLineText(originalindex);
|
||||
lines.SetLineText(originalindex, lines.GetLineText(newindex));
|
||||
lines.SetLineText(newindex, oldLine);
|
||||
}
|
||||
}
|
||||
}
|
16
TextControlBox/Extensions/PointExtension.cs
Normal file
16
TextControlBox/Extensions/PointExtension.cs
Normal file
|
@ -0,0 +1,16 @@
|
|||
using Windows.Foundation;
|
||||
|
||||
namespace TextControlBoxNS.Extensions
|
||||
{
|
||||
internal static class PointExtension
|
||||
{
|
||||
public static Point Subtract(this Point point, double subtractX, double subtractY)
|
||||
{
|
||||
return new Point(point.X - subtractX, point.Y - subtractY);
|
||||
}
|
||||
public static Point Subtract(this Point point, Point subtract)
|
||||
{
|
||||
return new Point(point.X - subtract.X, point.Y - subtract.Y);
|
||||
}
|
||||
}
|
||||
}
|
63
TextControlBox/Extensions/StringExtension.cs
Normal file
63
TextControlBox/Extensions/StringExtension.cs
Normal file
|
@ -0,0 +1,63 @@
|
|||
using System;
|
||||
using System.Text.RegularExpressions;
|
||||
using TextControlBoxNS.Helper;
|
||||
|
||||
namespace TextControlBoxNS.Extensions
|
||||
{
|
||||
internal static class StringExtension
|
||||
{
|
||||
public static string RemoveFirstOccurence(this string value, string removeString)
|
||||
{
|
||||
int index = value.IndexOf(removeString, StringComparison.Ordinal);
|
||||
return index < 0 ? value : value.Remove(index, removeString.Length);
|
||||
}
|
||||
|
||||
public static string AddToEnd(this string text, string add)
|
||||
{
|
||||
return text + add;
|
||||
}
|
||||
public static string AddToStart(this string text, string add)
|
||||
{
|
||||
return add + text;
|
||||
}
|
||||
public static string AddText(this string text, string add, int position)
|
||||
{
|
||||
if (position < 0)
|
||||
position = 0;
|
||||
|
||||
if (position >= text.Length || text.Length <= 0)
|
||||
return text + add;
|
||||
else
|
||||
return text.Insert(position, add);
|
||||
}
|
||||
public static string SafeRemove(this string text, int start, int count = -1)
|
||||
{
|
||||
if (start >= text.Length || start < 0)
|
||||
return text;
|
||||
|
||||
if (count <= -1)
|
||||
return text.Remove(start);
|
||||
else
|
||||
return text.Remove(start, count);
|
||||
}
|
||||
public static bool Contains(this string text, SearchParameter parameter)
|
||||
{
|
||||
if (parameter.WholeWord)
|
||||
return Regex.IsMatch(text, parameter.SearchExpression, RegexOptions.Compiled);
|
||||
|
||||
if (parameter.MatchCase)
|
||||
return text.Contains(parameter.Word, StringComparison.Ordinal);
|
||||
else
|
||||
return text.Contains(parameter.Word, StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
public static string Safe_Substring(this string text, int index, int count = -1)
|
||||
{
|
||||
if (index >= text.Length)
|
||||
return "";
|
||||
else if (count == -1)
|
||||
return text.Substring(index);
|
||||
else
|
||||
return text.Substring(index, count);
|
||||
}
|
||||
}
|
||||
}
|
41
TextControlBox/Helper/CanvasHelper.cs
Normal file
41
TextControlBox/Helper/CanvasHelper.cs
Normal file
|
@ -0,0 +1,41 @@
|
|||
using Microsoft.Graphics.Canvas.UI.Xaml;
|
||||
using Windows.UI.Core;
|
||||
|
||||
namespace TextControlBoxNS.Helper
|
||||
{
|
||||
internal class CanvasHelper
|
||||
{
|
||||
public CanvasControl Canvas_Selection = null;
|
||||
public CanvasControl Canvas_Linenumber = null;
|
||||
public CanvasControl Canvas_Text = null;
|
||||
public CanvasControl Canvas_Cursor = null;
|
||||
|
||||
public CanvasHelper(CanvasControl canvas_selection, CanvasControl canvas_linenumber, CanvasControl canvas_text, CanvasControl canvas_cursor)
|
||||
{
|
||||
this.Canvas_Text = canvas_text;
|
||||
this.Canvas_Linenumber = canvas_linenumber;
|
||||
this.Canvas_Cursor = canvas_cursor;
|
||||
this.Canvas_Selection = canvas_selection;
|
||||
}
|
||||
|
||||
public void UpdateCursor()
|
||||
{
|
||||
Canvas_Cursor.Invalidate();
|
||||
}
|
||||
public void UpdateText()
|
||||
{
|
||||
//TODO: Utils.ChangeCursor(CoreCursorType.IBeam);
|
||||
Canvas_Text.Invalidate();
|
||||
}
|
||||
public void UpdateSelection()
|
||||
{
|
||||
Canvas_Selection.Invalidate();
|
||||
}
|
||||
public void UpdateAll()
|
||||
{
|
||||
UpdateText();
|
||||
UpdateSelection();
|
||||
UpdateCursor();
|
||||
}
|
||||
}
|
||||
}
|
41
TextControlBox/Helper/FlyoutHelper.cs
Normal file
41
TextControlBox/Helper/FlyoutHelper.cs
Normal file
|
@ -0,0 +1,41 @@
|
|||
using Microsoft.UI.Xaml.Controls;
|
||||
using System;
|
||||
|
||||
namespace TextControlBoxNS.Helper
|
||||
{
|
||||
internal class FlyoutHelper
|
||||
{
|
||||
public MenuFlyout MenuFlyout;
|
||||
|
||||
public FlyoutHelper(TextControlBox sender)
|
||||
{
|
||||
CreateFlyout(sender);
|
||||
}
|
||||
|
||||
public void CreateFlyout(TextControlBox sender)
|
||||
{
|
||||
MenuFlyout = new MenuFlyout();
|
||||
MenuFlyout.Items.Add(CreateItem(() => { sender.Copy(); }, "Copy", Symbol.Copy, "Ctrl + C"));
|
||||
MenuFlyout.Items.Add(CreateItem(() => { sender.Paste(); }, "Paste", Symbol.Paste, "Ctrl + V"));
|
||||
MenuFlyout.Items.Add(CreateItem(() => { sender.Cut(); }, "Cut", Symbol.Cut, "Ctrl + X"));
|
||||
MenuFlyout.Items.Add(new MenuFlyoutSeparator());
|
||||
MenuFlyout.Items.Add(CreateItem(() => { sender.Undo(); }, "Undo", Symbol.Undo, "Ctrl + Z"));
|
||||
MenuFlyout.Items.Add(CreateItem(() => { sender.Redo(); }, "Redo", Symbol.Redo, "Ctrl + Y"));
|
||||
}
|
||||
|
||||
public MenuFlyoutItem CreateItem(Action action, string text, Symbol icon, string key)
|
||||
{
|
||||
var item = new MenuFlyoutItem
|
||||
{
|
||||
Text = text,
|
||||
KeyboardAcceleratorTextOverride = key,
|
||||
Icon = new SymbolIcon { Symbol = icon }
|
||||
};
|
||||
item.Click += delegate
|
||||
{
|
||||
action();
|
||||
};
|
||||
return item;
|
||||
}
|
||||
}
|
||||
}
|
13
TextControlBox/Helper/InputHandlerControl.cs
Normal file
13
TextControlBox/Helper/InputHandlerControl.cs
Normal file
|
@ -0,0 +1,13 @@
|
|||
using Microsoft.UI.Xaml.Controls;
|
||||
using Microsoft.UI.Xaml.Input;
|
||||
|
||||
namespace TextControlBoxNS.Helper
|
||||
{
|
||||
internal class InputHandlerControl : TextBox
|
||||
{
|
||||
protected override void OnKeyDown(KeyRoutedEventArgs e)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
75
TextControlBox/Helper/ListHelper.cs
Normal file
75
TextControlBox/Helper/ListHelper.cs
Normal file
|
@ -0,0 +1,75 @@
|
|||
using Collections.Pooled;
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
||||
namespace TextControlBoxNS.Helper
|
||||
{
|
||||
internal class ListHelper
|
||||
{
|
||||
public struct ValueResult
|
||||
{
|
||||
public ValueResult(int index, int count)
|
||||
{
|
||||
this.Index = index;
|
||||
this.Count = count;
|
||||
}
|
||||
public int Index;
|
||||
public int Count;
|
||||
}
|
||||
public static ValueResult CheckValues(PooledList<string> totalLines, int index, int count)
|
||||
{
|
||||
if (index >= totalLines.Count)
|
||||
{
|
||||
index = totalLines.Count - 1 < 0 ? 0 : totalLines.Count - 1;
|
||||
count = 0;
|
||||
}
|
||||
if (index + count >= totalLines.Count)
|
||||
{
|
||||
int difference = totalLines.Count - index;
|
||||
if (difference >= 0)
|
||||
count = difference;
|
||||
}
|
||||
|
||||
if (count < 0)
|
||||
count = 0;
|
||||
if (index < 0)
|
||||
index = 0;
|
||||
|
||||
return new ValueResult(index, count);
|
||||
}
|
||||
|
||||
public static void GCList(PooledList<string> totalLines)
|
||||
{
|
||||
int id = GC.GetGeneration(totalLines);
|
||||
GC.Collect(id, GCCollectionMode.Forced);
|
||||
}
|
||||
|
||||
public static void Clear(PooledList<string> totalLines, bool addNewLine = false)
|
||||
{
|
||||
totalLines.Clear();
|
||||
GCList(totalLines);
|
||||
|
||||
if (addNewLine)
|
||||
totalLines.Add("");
|
||||
}
|
||||
|
||||
public static string GetLinesAsString(PooledList<string> lines, string newLineCharacter)
|
||||
{
|
||||
return string.Join(newLineCharacter, lines);
|
||||
}
|
||||
public static string[] GetLinesFromString(string content, string newLineCharacter)
|
||||
{
|
||||
return content.Split(newLineCharacter);
|
||||
}
|
||||
public static string[] CreateLines(string[] lines, int start, string beginning, string end)
|
||||
{
|
||||
if (start > 0)
|
||||
lines = lines.Skip(start).ToArray();
|
||||
|
||||
lines[0] = beginning + lines[0];
|
||||
if (lines.Length - 1 > 0)
|
||||
lines[lines.Length - 1] = lines[lines.Length - 1] + end;
|
||||
return lines;
|
||||
}
|
||||
}
|
||||
}
|
218
TextControlBox/Helper/SearchHelper.cs
Normal file
218
TextControlBox/Helper/SearchHelper.cs
Normal file
|
@ -0,0 +1,218 @@
|
|||
using Collections.Pooled;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using TextControlBoxNS.Extensions;
|
||||
using TextControlBoxNS.Text;
|
||||
|
||||
namespace TextControlBoxNS.Helper
|
||||
{
|
||||
internal class SearchHelper
|
||||
{
|
||||
public int CurrentSearchLine = 0;
|
||||
public int CurrentSearchArrayIndex = 0;
|
||||
public int OldSearchArrayIndex = 0;
|
||||
public int[] MatchingSearchLines = null;
|
||||
public bool IsSearchOpen = false;
|
||||
public SearchParameter SearchParameter = null;
|
||||
public MatchCollection CurrentLineMatches = null;
|
||||
private int RegexIndexInLine = 0;
|
||||
|
||||
private int CheckIndexValue(int i)
|
||||
{
|
||||
return i >= MatchingSearchLines.Length ? MatchingSearchLines.Length - 1 : i < 0 ? 0 : i;
|
||||
}
|
||||
|
||||
public InternSearchResult FindNext(PooledList<string> totalLines, CursorPosition cursorPosition)
|
||||
{
|
||||
if (IsSearchOpen && MatchingSearchLines != null && MatchingSearchLines.Length > 0)
|
||||
{
|
||||
CurrentSearchLine = cursorPosition.LineNumber;
|
||||
int indexInList = Array.IndexOf(MatchingSearchLines, CurrentSearchLine);
|
||||
//When in a line without a match search for the next line with a match
|
||||
if (indexInList == -1)
|
||||
{
|
||||
for (int i = 0; i < MatchingSearchLines.Length; i++)
|
||||
{
|
||||
if (MatchingSearchLines[i] > CurrentSearchLine)
|
||||
{
|
||||
CurrentSearchArrayIndex = i - 1 < 0 ? 0 : i - 1;
|
||||
CurrentSearchLine = MatchingSearchLines[CurrentSearchArrayIndex];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
CurrentSearchArrayIndex = indexInList;
|
||||
CurrentSearchLine = MatchingSearchLines[CurrentSearchArrayIndex];
|
||||
if (OldSearchArrayIndex != CurrentSearchArrayIndex)
|
||||
{
|
||||
OldSearchArrayIndex = CurrentSearchArrayIndex;
|
||||
CurrentLineMatches = null;
|
||||
}
|
||||
}
|
||||
|
||||
//Search went through all matches in the current line:
|
||||
if (CurrentLineMatches == null || RegexIndexInLine >= CurrentLineMatches.Count)
|
||||
{
|
||||
RegexIndexInLine = 0;
|
||||
//back at start
|
||||
if (CurrentSearchLine < MatchingSearchLines[MatchingSearchLines.Length - 1])
|
||||
{
|
||||
CurrentSearchArrayIndex++;
|
||||
CurrentSearchLine = cursorPosition.LineNumber = MatchingSearchLines[CurrentSearchArrayIndex];
|
||||
CurrentLineMatches = Regex.Matches(totalLines[CurrentSearchLine], SearchParameter.SearchExpression);
|
||||
}
|
||||
else
|
||||
return new InternSearchResult(SearchResult.ReachedEnd, null);
|
||||
}
|
||||
|
||||
RegexIndexInLine = Math.Clamp(RegexIndexInLine, 0, CurrentLineMatches.Count - 1);
|
||||
|
||||
RegexIndexInLine++;
|
||||
if (RegexIndexInLine > CurrentLineMatches.Count || RegexIndexInLine < 0)
|
||||
return new InternSearchResult(SearchResult.NotFound, null);
|
||||
|
||||
return new InternSearchResult(SearchResult.Found, new TextSelection(
|
||||
new CursorPosition(CurrentLineMatches[RegexIndexInLine - 1].Index, cursorPosition.LineNumber),
|
||||
new CursorPosition(CurrentLineMatches[RegexIndexInLine - 1].Index + CurrentLineMatches[RegexIndexInLine - 1].Length, cursorPosition.LineNumber)));
|
||||
}
|
||||
return new InternSearchResult(SearchResult.NotFound, null);
|
||||
}
|
||||
public InternSearchResult FindPrevious(PooledList<string> totalLines, CursorPosition cursorPosition)
|
||||
{
|
||||
if (IsSearchOpen && MatchingSearchLines != null)
|
||||
{
|
||||
//Find the next linnenumber with a match if the line is not in the array of matching lines
|
||||
CurrentSearchLine = cursorPosition.LineNumber;
|
||||
int indexInList = Array.IndexOf(MatchingSearchLines, CurrentSearchLine);
|
||||
if (indexInList == -1)
|
||||
{
|
||||
//Find the first line with matches which is smaller than the current line:
|
||||
var lines = MatchingSearchLines.Where(x => x < CurrentSearchLine);
|
||||
if (lines.Count() < 1)
|
||||
{
|
||||
return new InternSearchResult(SearchResult.ReachedBegin, null);
|
||||
}
|
||||
|
||||
CurrentSearchArrayIndex = Array.IndexOf(MatchingSearchLines, lines.Last());
|
||||
CurrentSearchLine = MatchingSearchLines[CurrentSearchArrayIndex];
|
||||
CurrentLineMatches = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
CurrentSearchArrayIndex = indexInList;
|
||||
CurrentSearchLine = MatchingSearchLines[CurrentSearchArrayIndex];
|
||||
|
||||
if (OldSearchArrayIndex != CurrentSearchArrayIndex)
|
||||
{
|
||||
OldSearchArrayIndex = CurrentSearchArrayIndex;
|
||||
CurrentLineMatches = null;
|
||||
}
|
||||
}
|
||||
|
||||
//Search went through all matches in the current line:
|
||||
if (CurrentLineMatches == null || RegexIndexInLine < 0)
|
||||
{
|
||||
//back at start
|
||||
if (CurrentSearchLine == MatchingSearchLines[0])
|
||||
{
|
||||
return new InternSearchResult(SearchResult.ReachedBegin, null);
|
||||
}
|
||||
if (CurrentSearchLine < MatchingSearchLines[MatchingSearchLines.Length - 1])
|
||||
{
|
||||
CurrentSearchLine = cursorPosition.LineNumber = MatchingSearchLines[CheckIndexValue(CurrentSearchArrayIndex - 1)];
|
||||
CurrentLineMatches = Regex.Matches(totalLines[CurrentSearchLine], SearchParameter.SearchExpression);
|
||||
RegexIndexInLine = CurrentLineMatches.Count - 1;
|
||||
CurrentSearchArrayIndex--;
|
||||
}
|
||||
}
|
||||
|
||||
if (CurrentLineMatches == null)
|
||||
return new InternSearchResult(SearchResult.NotFound, null);
|
||||
|
||||
RegexIndexInLine = Math.Clamp(RegexIndexInLine, 0, CurrentLineMatches.Count - 1);
|
||||
|
||||
//RegexIndexInLine--;
|
||||
if (RegexIndexInLine >= CurrentLineMatches.Count || RegexIndexInLine < 0)
|
||||
return new InternSearchResult(SearchResult.NotFound, null);
|
||||
|
||||
return new InternSearchResult(SearchResult.Found, new TextSelection(
|
||||
new CursorPosition(CurrentLineMatches[RegexIndexInLine].Index, cursorPosition.LineNumber),
|
||||
new CursorPosition(CurrentLineMatches[RegexIndexInLine].Index + CurrentLineMatches[RegexIndexInLine--].Length, cursorPosition.LineNumber)));
|
||||
}
|
||||
return new InternSearchResult(SearchResult.NotFound, null);
|
||||
}
|
||||
|
||||
public void UpdateSearchLines(PooledList<string> totalLines)
|
||||
{
|
||||
MatchingSearchLines = FindIndexes(totalLines);
|
||||
}
|
||||
|
||||
public SearchResult BeginSearch(PooledList<string> totalLines, string word, bool matchCase, bool wholeWord)
|
||||
{
|
||||
SearchParameter = new SearchParameter(word, wholeWord, matchCase);
|
||||
UpdateSearchLines(totalLines);
|
||||
|
||||
if (word == "" || word == null)
|
||||
return SearchResult.InvalidInput;
|
||||
|
||||
//A result was found
|
||||
if (MatchingSearchLines.Length > 0)
|
||||
{
|
||||
IsSearchOpen = true;
|
||||
}
|
||||
|
||||
return MatchingSearchLines.Length > 0 ? SearchResult.Found : SearchResult.NotFound;
|
||||
}
|
||||
public void EndSearch()
|
||||
{
|
||||
IsSearchOpen = false;
|
||||
MatchingSearchLines = null;
|
||||
}
|
||||
|
||||
private int[] FindIndexes(PooledList<string> totalLines)
|
||||
{
|
||||
List<int> results = new List<int>();
|
||||
for (int i = 0; i < totalLines.Count; i++)
|
||||
{
|
||||
if (totalLines[i].Contains(SearchParameter))
|
||||
results.Add(i);
|
||||
};
|
||||
return results.ToArray();
|
||||
}
|
||||
}
|
||||
internal class SearchParameter
|
||||
{
|
||||
public SearchParameter(string word, bool wholeWord = false, bool matchCase = false)
|
||||
{
|
||||
this.Word = word;
|
||||
this.WholeWord = wholeWord;
|
||||
this.MatchCase = matchCase;
|
||||
|
||||
if (wholeWord)
|
||||
SearchExpression += @"\b" + (matchCase ? "" : "(?i)") + Regex.Escape(word) + @"\b";
|
||||
else
|
||||
SearchExpression += (matchCase ? "" : "(?i)") + Regex.Escape(word);
|
||||
}
|
||||
|
||||
public bool WholeWord { get; set; }
|
||||
public bool MatchCase { get; set; }
|
||||
public string Word { get; set; }
|
||||
public string SearchExpression { get; set; } = "";
|
||||
}
|
||||
|
||||
internal struct InternSearchResult
|
||||
{
|
||||
public InternSearchResult(SearchResult result, TextSelection selection)
|
||||
{
|
||||
this.Result = result;
|
||||
this.Selection = selection;
|
||||
}
|
||||
|
||||
public TextSelection Selection;
|
||||
public SearchResult Result;
|
||||
}
|
||||
}
|
74
TextControlBox/Helper/TabSpaceHelper.cs
Normal file
74
TextControlBox/Helper/TabSpaceHelper.cs
Normal file
|
@ -0,0 +1,74 @@
|
|||
using Collections.Pooled;
|
||||
using System;
|
||||
|
||||
namespace TextControlBoxNS.Helper
|
||||
{
|
||||
internal class TabSpaceHelper
|
||||
{
|
||||
private int _NumberOfSpaces = 4;
|
||||
private string OldSpaces = " ";
|
||||
|
||||
public int NumberOfSpaces
|
||||
{
|
||||
get => _NumberOfSpaces;
|
||||
set
|
||||
{
|
||||
if (value != _NumberOfSpaces)
|
||||
{
|
||||
OldSpaces = Spaces;
|
||||
_NumberOfSpaces = value;
|
||||
Spaces = new string(' ', _NumberOfSpaces);
|
||||
}
|
||||
}
|
||||
}
|
||||
public bool UseSpacesInsteadTabs = false;
|
||||
public string TabCharacter { get => UseSpacesInsteadTabs ? Spaces : Tab; }
|
||||
private string Spaces = " ";
|
||||
private string Tab = "\t";
|
||||
|
||||
public void UpdateNumberOfSpaces(PooledList<string> totalLines)
|
||||
{
|
||||
ReplaceSpacesToSpaces(totalLines);
|
||||
}
|
||||
|
||||
public void UpdateTabs(PooledList<string> totalLines)
|
||||
{
|
||||
if (UseSpacesInsteadTabs)
|
||||
ReplaceTabsToSpaces(totalLines);
|
||||
else
|
||||
ReplaceSpacesToTabs(totalLines);
|
||||
}
|
||||
public string UpdateTabs(string input)
|
||||
{
|
||||
if (UseSpacesInsteadTabs)
|
||||
return Replace(input, Tab, Spaces);
|
||||
return Replace(input, Spaces, Tab);
|
||||
}
|
||||
|
||||
private void ReplaceSpacesToSpaces(PooledList<string> totalLines)
|
||||
{
|
||||
for (int i = 0; i < totalLines.Count; i++)
|
||||
{
|
||||
totalLines[i] = Replace(totalLines[i], OldSpaces, Spaces);
|
||||
}
|
||||
}
|
||||
private void ReplaceSpacesToTabs(PooledList<string> TotalLines)
|
||||
{
|
||||
for (int i = 0; i < TotalLines.Count; i++)
|
||||
{
|
||||
TotalLines[i] = Replace(TotalLines[i], Spaces, Tab);
|
||||
}
|
||||
}
|
||||
private void ReplaceTabsToSpaces(PooledList<string> totalLines)
|
||||
{
|
||||
for (int i = 0; i < totalLines.Count; i++)
|
||||
{
|
||||
totalLines[i] = Replace(totalLines[i], "\t", Spaces);
|
||||
}
|
||||
}
|
||||
public string Replace(string input, string find, string replace)
|
||||
{
|
||||
return input.Replace(find, replace, StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
}
|
||||
}
|
64
TextControlBox/Helper/TextLayoutHelper.cs
Normal file
64
TextControlBox/Helper/TextLayoutHelper.cs
Normal file
|
@ -0,0 +1,64 @@
|
|||
using Microsoft.Graphics.Canvas;
|
||||
using Microsoft.Graphics.Canvas.Text;
|
||||
using Microsoft.UI.Xaml.Media;
|
||||
using Windows.Foundation;
|
||||
|
||||
namespace TextControlBoxNS.Helper
|
||||
{
|
||||
internal class TextLayoutHelper
|
||||
{
|
||||
public static CanvasTextLayout CreateTextResource(ICanvasResourceCreatorWithDpi resourceCreator, CanvasTextLayout textLayout, CanvasTextFormat textFormat, string text, Size targetSize)
|
||||
{
|
||||
if (textLayout != null)
|
||||
textLayout.Dispose();
|
||||
|
||||
textLayout = CreateTextLayout(resourceCreator, textFormat, text, targetSize);
|
||||
textLayout.Options = CanvasDrawTextOptions.EnableColorFont;
|
||||
return textLayout;
|
||||
}
|
||||
public static CanvasTextFormat CreateCanvasTextFormat(float zoomedFontSize, FontFamily fontFamily)
|
||||
{
|
||||
return CreateCanvasTextFormat(zoomedFontSize, zoomedFontSize + 2, fontFamily);
|
||||
}
|
||||
|
||||
public static CanvasTextFormat CreateCanvasTextFormat(float zoomedFontSize, float lineSpacing, FontFamily fontFamily)
|
||||
{
|
||||
CanvasTextFormat textFormat = new CanvasTextFormat()
|
||||
{
|
||||
FontSize = zoomedFontSize,
|
||||
HorizontalAlignment = CanvasHorizontalAlignment.Left,
|
||||
VerticalAlignment = CanvasVerticalAlignment.Top,
|
||||
WordWrapping = CanvasWordWrapping.NoWrap,
|
||||
LineSpacing = lineSpacing,
|
||||
};
|
||||
textFormat.IncrementalTabStop = zoomedFontSize * 3; //default 137px
|
||||
textFormat.FontFamily = fontFamily.Source;
|
||||
textFormat.TrimmingGranularity = CanvasTextTrimmingGranularity.None;
|
||||
textFormat.TrimmingSign = CanvasTrimmingSign.None;
|
||||
return textFormat;
|
||||
}
|
||||
public static CanvasTextLayout CreateTextLayout(ICanvasResourceCreator resourceCreator, CanvasTextFormat textFormat, string text, Size canvasSize)
|
||||
{
|
||||
return new CanvasTextLayout(resourceCreator, text, textFormat, (float)canvasSize.Width, (float)canvasSize.Height);
|
||||
}
|
||||
public static CanvasTextLayout CreateTextLayout(ICanvasResourceCreator resourceCreator, CanvasTextFormat textFormat, string text, float width, float height)
|
||||
{
|
||||
return new CanvasTextLayout(resourceCreator, text, textFormat, width, height);
|
||||
}
|
||||
public static CanvasTextFormat CreateLinenumberTextFormat(float fontSize, FontFamily fontFamily)
|
||||
{
|
||||
CanvasTextFormat textFormat = new CanvasTextFormat()
|
||||
{
|
||||
FontSize = fontSize,
|
||||
HorizontalAlignment = CanvasHorizontalAlignment.Right,
|
||||
VerticalAlignment = CanvasVerticalAlignment.Top,
|
||||
WordWrapping = CanvasWordWrapping.NoWrap,
|
||||
LineSpacing = fontSize + 2,
|
||||
};
|
||||
textFormat.FontFamily = fontFamily.Source;
|
||||
textFormat.TrimmingGranularity = CanvasTextTrimmingGranularity.None;
|
||||
textFormat.TrimmingSign = CanvasTrimmingSign.None;
|
||||
return textFormat;
|
||||
}
|
||||
}
|
||||
}
|
160
TextControlBox/Helper/Utils.cs
Normal file
160
TextControlBox/Helper/Utils.cs
Normal file
|
@ -0,0 +1,160 @@
|
|||
using Collections.Pooled;
|
||||
using Microsoft.Graphics.Canvas;
|
||||
using Microsoft.Graphics.Canvas.Text;
|
||||
using Microsoft.UI.Xaml;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Threading.Tasks;
|
||||
using TextControlBoxNS.Extensions;
|
||||
using Windows.Foundation;
|
||||
using Windows.System;
|
||||
using Windows.UI.Core;
|
||||
using Windows.UI.Popups;
|
||||
|
||||
namespace TextControlBoxNS.Helper
|
||||
{
|
||||
internal class Utils
|
||||
{
|
||||
public static Size MeasureTextSize(CanvasDevice device, string text, CanvasTextFormat textFormat, float limitedToWidth = 0.0f, float limitedToHeight = 0.0f)
|
||||
{
|
||||
CanvasTextLayout layout = new CanvasTextLayout(device, text, textFormat, limitedToWidth, limitedToHeight);
|
||||
return new Size(layout.DrawBounds.Width, layout.DrawBounds.Height);
|
||||
}
|
||||
|
||||
public static Size MeasureLineLenght(CanvasDevice device, string text, CanvasTextFormat textFormat)
|
||||
{
|
||||
if (text.Length == 0)
|
||||
return new Size(0, 0);
|
||||
|
||||
//If the text starts with a tab or a whitespace, replace it with the last character of the line, to
|
||||
//get the actual width of the line, because tabs and whitespaces at the beginning are not counted to the lenght
|
||||
//Do the same for the end
|
||||
double placeholderWidth = 0;
|
||||
if (text.StartsWith('\t') || text.StartsWith(' '))
|
||||
{
|
||||
text = text.Insert(0, "|");
|
||||
placeholderWidth += MeasureTextSize(device, "|", textFormat).Width;
|
||||
}
|
||||
if (text.EndsWith('\t') || text.EndsWith(' '))
|
||||
{
|
||||
text = text += "|";
|
||||
placeholderWidth += MeasureTextSize(device, "|", textFormat).Width;
|
||||
}
|
||||
|
||||
CanvasTextLayout layout = new CanvasTextLayout(device, text, textFormat, 0, 0);
|
||||
return new Size(layout.DrawBounds.Width - placeholderWidth, layout.DrawBounds.Height);
|
||||
}
|
||||
|
||||
//Get the longest line in the textbox
|
||||
public static int GetLongestLineIndex(PooledList<string> totalLines)
|
||||
{
|
||||
int longestIndex = 0;
|
||||
int oldLenght = 0;
|
||||
for (int i = 0; i < totalLines.Count; i++)
|
||||
{
|
||||
var lenght = totalLines[i].Length;
|
||||
if (lenght > oldLenght)
|
||||
{
|
||||
longestIndex = i;
|
||||
oldLenght = lenght;
|
||||
}
|
||||
}
|
||||
return longestIndex;
|
||||
}
|
||||
public static int GetLongestLineLength(string text)
|
||||
{
|
||||
var splitted = text.Split("\n");
|
||||
int oldLenght = 0;
|
||||
for (int i = 0; i < splitted.Length; i++)
|
||||
{
|
||||
var lenght = splitted[i].Length;
|
||||
if (lenght > oldLenght)
|
||||
{
|
||||
oldLenght = lenght;
|
||||
}
|
||||
}
|
||||
return oldLenght;
|
||||
}
|
||||
|
||||
public static bool CursorPositionsAreEqual(CursorPosition first, CursorPosition second)
|
||||
{
|
||||
return first.LineNumber == second.LineNumber && first.CharacterPosition == second.CharacterPosition;
|
||||
}
|
||||
|
||||
public static string[] SplitAt(string text, int index)
|
||||
{
|
||||
string first = index < text.Length ? text.SafeRemove(index) : text;
|
||||
string second = index < text.Length ? text.Safe_Substring(index) : "";
|
||||
return new string[] { first, second };
|
||||
}
|
||||
|
||||
public static int CountCharacters(PooledList<string> totalLines)
|
||||
{
|
||||
int count = 0;
|
||||
for (int i = 0; i < totalLines.Count; i++)
|
||||
{
|
||||
count += totalLines[i].Length + 1;
|
||||
}
|
||||
return count - 1;
|
||||
}
|
||||
public static bool IsKeyPressed(VirtualKey key)
|
||||
{
|
||||
return Microsoft.UI.Input.InputKeyboardSource.GetKeyStateForCurrentThread(key).HasFlag(CoreVirtualKeyStates.Down);
|
||||
}
|
||||
public static async Task<bool> IsOverTextLimit(int textLength)
|
||||
{
|
||||
if (textLength > 100000000)
|
||||
{
|
||||
await new MessageDialog("Current textlimit is 100 million characters, but your file has " + textLength + " characters").ShowAsync();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
public static void Benchmark(Action action, string text)
|
||||
{
|
||||
Stopwatch sw = new Stopwatch();
|
||||
sw.Start();
|
||||
action.Invoke();
|
||||
sw.Stop();
|
||||
|
||||
Debug.WriteLine(text + " took " + sw.ElapsedMilliseconds + "::" + sw.ElapsedTicks);
|
||||
}
|
||||
|
||||
public static ApplicationTheme ConvertTheme(ElementTheme theme)
|
||||
{
|
||||
switch (theme)
|
||||
{
|
||||
case ElementTheme.Light: return ApplicationTheme.Light;
|
||||
case ElementTheme.Dark: return ApplicationTheme.Dark;
|
||||
case ElementTheme.Default:
|
||||
var defaultTheme = new Windows.UI.ViewManagement.UISettings();
|
||||
return defaultTheme.GetColorValue(Windows.UI.ViewManagement.UIColorType.Background).ToString() == "#FF000000"
|
||||
? ApplicationTheme.Dark : ApplicationTheme.Light;
|
||||
|
||||
default: return ApplicationTheme.Light;
|
||||
}
|
||||
}
|
||||
|
||||
public static Point GetTextboxstartingPoint(UIElement relativeTo)
|
||||
{
|
||||
return relativeTo.TransformToVisual(Window.Current.Content).TransformPoint(new Point(0, 0));
|
||||
}
|
||||
|
||||
public static int CountLines(string text, string newLineCharacter)
|
||||
{
|
||||
return (text.Length - text.Replace(newLineCharacter, "").Length) / newLineCharacter.Length + 1;
|
||||
}
|
||||
|
||||
public static Rect CreateRect(Rect rect, float marginLeft = 0, float marginTop = 0)
|
||||
{
|
||||
return new Rect(
|
||||
new Point(
|
||||
Math.Floor(rect.Left + marginLeft),//X
|
||||
Math.Floor(rect.Top + marginTop)), //Y
|
||||
new Point(
|
||||
Math.Ceiling(rect.Right + marginLeft), //Width
|
||||
Math.Ceiling(rect.Bottom + marginTop))); //Height
|
||||
}
|
||||
|
||||
}
|
||||
}
|
511
TextControlBox/Languages/Languages.cs
Normal file
511
TextControlBox/Languages/Languages.cs
Normal file
|
@ -0,0 +1,511 @@
|
|||
namespace TextControlBoxNS.Languages
|
||||
{
|
||||
internal class Batch : CodeLanguage
|
||||
{
|
||||
public Batch()
|
||||
{
|
||||
this.Name = "Batch";
|
||||
this.Author = "Julius Kirsch";
|
||||
this.Filter = new string[1] { ".bat" };
|
||||
this.Description = "Syntax highlighting for Batch language";
|
||||
this.Highlights = new SyntaxHighlights[]
|
||||
{
|
||||
new SyntaxHighlights("\\b([+-]?(?=\\.\\d|\\d)(?:\\d+)?(?:\\.?\\d*))(?:[eE]([+-]?\\d+))?\\b", "#dd00dd", "#ff00ff"),
|
||||
new SyntaxHighlights("(?i)(set|echo|for|pushd|popd|pause|exit|cd|if|else|goto|del)\\s", "#dd00dd", "#dd00dd"),
|
||||
new SyntaxHighlights("(:.*)", "#00C000", "#ffff00"),
|
||||
new SyntaxHighlights("(\\\".+?\\\"|\\'.+?\\')", "#00C000", "#ffff00"),
|
||||
new SyntaxHighlights("(@|%)", "#dd0077", "#dd0077"),
|
||||
new SyntaxHighlights("(\\*)", "#dd0077", "#dd0077"),
|
||||
new SyntaxHighlights("((?i)rem.*)", "#888888", "#888888"),
|
||||
};
|
||||
}
|
||||
}
|
||||
internal class ConfigFile : CodeLanguage
|
||||
{
|
||||
public ConfigFile()
|
||||
{
|
||||
this.Name = "ConfigFile";
|
||||
this.Author = "Finn Freitag";
|
||||
this.Filter = new string[1] { ".ini" };
|
||||
this.Description = "Syntax highlighting for configuration files";
|
||||
this.AutoPairingPair = new AutoPairingPair[]
|
||||
{
|
||||
new AutoPairingPair("[", "]")
|
||||
};
|
||||
this.Highlights = new SyntaxHighlights[]
|
||||
{
|
||||
new SyntaxHighlights("[\\[\\]]", "#0000FF", "#0000FF"),
|
||||
new SyntaxHighlights("\\[[\\t\\s]*(\\w+)[\\t\\s]*\\]", "#9900FF", "#9900FF"),
|
||||
new SyntaxHighlights("(\\w+)\\=", "#DDDD00", "#DDDD00"),
|
||||
new SyntaxHighlights("\\=(.+)", "#EE0000", "#EE0000"),
|
||||
new SyntaxHighlights(";.*", "#888888", "#888888"),
|
||||
};
|
||||
}
|
||||
}
|
||||
internal class Cpp : CodeLanguage
|
||||
{
|
||||
public Cpp()
|
||||
{
|
||||
this.Name = "C++";
|
||||
this.Author = "Julius Kirsch";
|
||||
this.Filter = new string[6] { ".cpp", ".cxx", ".cc", ".hpp", ".h", ".c" };
|
||||
this.Description = "Syntax highlighting for C++ language";
|
||||
this.AutoPairingPair = new AutoPairingPair[5]
|
||||
{
|
||||
new AutoPairingPair("{", "}"),
|
||||
new AutoPairingPair("[", "]"),
|
||||
new AutoPairingPair("(", ")"),
|
||||
new AutoPairingPair("\""),
|
||||
new AutoPairingPair("\'")
|
||||
};
|
||||
this.Highlights = new SyntaxHighlights[]
|
||||
{
|
||||
new SyntaxHighlights("\\b([+-]?(?=\\.\\d|\\d)(?:\\d+)?(?:\\.?\\d*))(?:[eE]([+-]?\\d+))?\\b", "#dd00dd", "#00ff00"),
|
||||
new SyntaxHighlights("(?<!(def\\s))(?<=^|\\s|.)[a-zA-Z_][\\w_]*(?=\\()", "#4455ff", "#ffbb00"),
|
||||
new SyntaxHighlights("\\b(string|uint16_t|uint8_t|alignas|alignof|and|and_eq|asm|auto|bitand|bitor|bool|break|case|catch|char|char8_t|char16_t|char32_t|class|compl|concept|const|const_cast|consteval|constexpr|constinit|continue|co_await|co_return|co_yield|decltype|default|delete|do|double|dynamic_cast|else|enum|explicit|export|extern|false|float|for|friend|goto|if|inline|int|long|mutable|namespace|new|noexcept|not|not_eq|nullptr|operator|or|or_eq|private|protected|public|register|reinterpret_cast|requires|return|short|signed|sizeof|static|static_assert|static_cast|struct|switch|template|this|thread_local|throw|true|try|typedef|typeid|typename|union|unsigned|using|virtual|void|volatile|wchar_t|while|xor|xor_eq)\\b", "#dd00dd", "#dd00dd"),
|
||||
new SyntaxHighlights("\\B#(define|elif|else|endif|error|ifndef|ifdef|if|import|include|line|pragma|region|undef|using)", "#bbbbbb", "#999999"),
|
||||
new SyntaxHighlights("(\\\".+?\\\"|\\'.+?\\')", "#ffff00", "#ff000f"),
|
||||
new SyntaxHighlights("\"[^\\n]*?\"", "#00CA00", "#00FF00"),
|
||||
new SyntaxHighlights("'[^\\n]*?'", "#00CA00", "#00FF00"),
|
||||
new SyntaxHighlights("/\\*[^*]*\\*+(?:[^/*][^*]*\\*+)*/", "#888888", "#646464"),
|
||||
new SyntaxHighlights("\\/\\/.*", "#888888", "#646464"),
|
||||
};
|
||||
}
|
||||
}
|
||||
internal class CSharp : CodeLanguage
|
||||
{
|
||||
public CSharp()
|
||||
{
|
||||
this.Name = "C#";
|
||||
this.Author = "Julius Kirsch";
|
||||
this.Filter = new string[1] { ".cs" };
|
||||
this.Description = "Syntax highlighting for C# language";
|
||||
this.AutoPairingPair = new AutoPairingPair[5]
|
||||
{
|
||||
new AutoPairingPair("{", "}"),
|
||||
new AutoPairingPair("[", "]"),
|
||||
new AutoPairingPair("(", ")"),
|
||||
new AutoPairingPair("\""),
|
||||
new AutoPairingPair("\'")
|
||||
};
|
||||
this.Highlights = new SyntaxHighlights[]
|
||||
{
|
||||
new SyntaxHighlights("\\b([+-]?(?=\\.\\d|\\d)(?:\\d+)?(?:\\.?\\d*))(?:[eE]([+-]?\\d+))?\\b", "#ff00ff", "#ff00ff"),
|
||||
new SyntaxHighlights("(?<!(def\\s))(?<=^|\\s|.)[a-zA-Z_][\\w_]*(?=\\()", "#880088", "#ffbb00"),
|
||||
new SyntaxHighlights("\\b(abstract|as|base|bool|break|byte|case|catch|char|checked|class|const|continue|decimal|default|delegate|do|double|else|enum|event|explicit|extern|external|false|final|finally|fixed|float|for|foreach|get|goto|if|implicit|in|int|interface|internal|is|lock|long|namespace|new|null|object|operator|out|override|params|partial|private|protected|public|readonly|ref|return|sbyte|sealed|set|short|sizeof|stackalloc|static|string|struct|switch|this|throw|true|try|typeof|uint|ulong|unchecked|unsafe|ushort|using|value|var|virtual|void|volatile|while)\\b", "#0066bb", "#00ffff"),
|
||||
new SyntaxHighlights("\\b(List|Color|Console|Debug|Dictionary|Stack|Queue|GC)\\b", "#008000", "#ff9900"),
|
||||
new SyntaxHighlights("\\b(try|catch|finally)\\b", "#9922ff", "#6666ff"),
|
||||
new SyntaxHighlights("(#region)+(.*?)($|\n)", "#ff0000", "#ff0000", true),
|
||||
new SyntaxHighlights("#endregion", "#ff0000", "#ff0000", true),
|
||||
new SyntaxHighlights("\"[^\\n]*?\"", "#ff5500", "#00FF00"),
|
||||
new SyntaxHighlights("'[^\\n]*?'", "#00CA00", "#00FF00"),
|
||||
new SyntaxHighlights("\\/\\/.*", "#888888", "#646464"),
|
||||
new SyntaxHighlights("/\\*[^*]*\\*+(?:[^/*][^*]*\\*+)*/", "#888888", "#646464"),
|
||||
};
|
||||
}
|
||||
}
|
||||
internal class GCode : CodeLanguage
|
||||
{
|
||||
public GCode()
|
||||
{
|
||||
this.Name = "GCode";
|
||||
this.Author = "Julius Kirsch";
|
||||
this.Filter = new string[5] { ".ngc", ".tap", ".gcode", ".nc", ".cnc" };
|
||||
this.Description = "Syntax highlighting for GCode language";
|
||||
this.Highlights = new SyntaxHighlights[]
|
||||
{
|
||||
new SyntaxHighlights("\\bY(?=([0-9]|(\\+|\\-)[0-9]))", "#00ff00", "#00ff00"),
|
||||
new SyntaxHighlights("\\bX(?=([0-9]|(\\+|\\-)[0-9]))", "#ff0000", "#ff0000"),
|
||||
new SyntaxHighlights("\\bZ(?=([0-9]|(\\+|\\-)[0-9]))", "#0077ff", "#0077ff"),
|
||||
new SyntaxHighlights("\\bA(?=([0-9]|(\\+|\\-)[0-9]))", "#ff00ff", "#ff00ff"),
|
||||
new SyntaxHighlights("\\b(E|F)(?=([0-9]|(\\+|\\-)[0-9]))", "#ffAA00", "#ffAA00"),
|
||||
new SyntaxHighlights("\\b(S|T)(?=([0-9]|(\\+|\\-)[0-9]))", "#ffff00", "#ffff00"),
|
||||
new SyntaxHighlights("([+-]?(?=\\.\\d|\\d)(?:\\d+)?(?:\\.?\\d*))(?:[eE]([+-]?\\d+))?", "#ff00ff", "#9f009f"),
|
||||
new SyntaxHighlights("[G|M][0-999].*?[\\s|\\n]", "#00aaaa", "#00ffff"),
|
||||
new SyntaxHighlights("(;|\\/\\/|\\brem\\b).*", "#888888", "#888888"),
|
||||
};
|
||||
}
|
||||
}
|
||||
internal class HexFile : CodeLanguage
|
||||
{
|
||||
public HexFile()
|
||||
{
|
||||
this.Name = "HexFile";
|
||||
this.Author = "Finn Freitag";
|
||||
this.Filter = new string[2] { ".hex", ".bin" };
|
||||
this.Description = "Syntaxhighlighting for hex and binary code.";
|
||||
this.Highlights = new SyntaxHighlights[]
|
||||
{
|
||||
new SyntaxHighlights("\\:", "#FFFF00", "#FFFF00"),
|
||||
new SyntaxHighlights("\\:([0-9A-Fa-f]{2})", "#00FF00", "#00FF00"),
|
||||
new SyntaxHighlights("\\:[0-9A-Fa-f]{2}([0-9A-Fa-f]{4})", "#00FF00", "#00FF00"),
|
||||
new SyntaxHighlights("\\:[0-9A-Fa-f]{6}([0-9A-Fa-f]{2})", "#FF5500", "#FF5500"),
|
||||
new SyntaxHighlights("\\:[0-9A-Fa-f]{8}([0-9A-Fa-f]*)[0-9A-Fa-f]{2}", "#00FFFF", "#00FFFF"),
|
||||
new SyntaxHighlights("\\:[0-9A-Fa-f]{8}[0-9A-Fa-f]*([0-9A-Fa-f]{2})", "#666666", "#666666"),
|
||||
new SyntaxHighlights("//.*", "#666666", "#666666"),
|
||||
new SyntaxHighlights("[^0-9A-Fa-f\\:\\n]", "#FF0000", "#FF0000", false, false, true),
|
||||
};
|
||||
}
|
||||
}
|
||||
internal class Html : CodeLanguage
|
||||
{
|
||||
public Html()
|
||||
{
|
||||
this.Name = "Html";
|
||||
this.Author = "Julius Kirsch";
|
||||
this.Filter = new string[2] { ".html", ".htm" };
|
||||
this.Description = "Syntax highlighting for Html language";
|
||||
|
||||
this.Highlights = new SyntaxHighlights[]
|
||||
{
|
||||
new SyntaxHighlights("\\b([+-]?(?=\\.\\d|\\d)(?:\\d+)?(?:\\.?\\d*))(?:[eE]([+-]?\\d+))?\\b", "#dd00dd", "#ff00ff"),
|
||||
new SyntaxHighlights("[-A-Za-z_]+\\=", "#00CA00", "#Ff0000"),
|
||||
new SyntaxHighlights("<([^ >!\\/]+)[^>]*>", "#969696", "#0099ff"),
|
||||
new SyntaxHighlights("<+[/]+[a-zA-Z0-9:?\\-_]+>", "#969696", "#0099ff"),
|
||||
new SyntaxHighlights("<[a-zA-Z0-9:?\\-]+?.*\\/>", "#969696", "#0099ff"),
|
||||
new SyntaxHighlights("\"[^\\n]*?\"", "#00CA00", "#00FF00"),
|
||||
new SyntaxHighlights("'[^\\n]*?'", "#00CA00", "#00FF00"),
|
||||
new SyntaxHighlights("[0-9]+(px|rem|em|vh|vw|px|pt|pc|in|mm|cm|deg|%)", "#ff00ff", "#dd00dd"),
|
||||
new SyntaxHighlights("<!--[\\s\\S]*?-->", "#888888", "#888888"),
|
||||
};
|
||||
}
|
||||
}
|
||||
internal class Java : CodeLanguage
|
||||
{
|
||||
public Java()
|
||||
{
|
||||
this.Name = "Java";
|
||||
this.Author = "Julius Kirsch";
|
||||
this.Filter = new string[2] { ".java", ".class" };
|
||||
this.Description = "Syntax highlighting for Java language";
|
||||
this.AutoPairingPair = new AutoPairingPair[5]
|
||||
{
|
||||
new AutoPairingPair("{", "}"),
|
||||
new AutoPairingPair("[", "]"),
|
||||
new AutoPairingPair("(", ")"),
|
||||
new AutoPairingPair("\""),
|
||||
new AutoPairingPair("\'")
|
||||
};
|
||||
this.Highlights = new SyntaxHighlights[]
|
||||
{
|
||||
new SyntaxHighlights("\\b([+-]?(?=\\.\\d|\\d)(?:\\d+)?(?:\\.?\\d*))(?:[eE]([+-]?\\d+))?\\b", "#ff00ff", "#ff00ff"),
|
||||
new SyntaxHighlights("(?<!(def\\s))(?<=^|\\s|.)[a-zA-Z_][\\w_]*(?=\\()", "#880088", "#ffbb00"),
|
||||
new SyntaxHighlights("\\b(System.out|System|Math)\\b", "#008000", "#ff9900"),
|
||||
new SyntaxHighlights("\\b(abstract|assert|boolean|break|byte|case|catch|char|class|const|continue|default|do|double|else|enum|extends|final|finally|float|for|goto|if|implements|import|instanceof|int|interface|long|native|new|package|private|protected|public|return|short|static|super|switch|synchronized|this|throw|throws|transient|try|void|volatile|while|exports|modle|non-sealed|open|opens|permits|provides|record|requires|sealed|to|transitive|uses|var|with|yield|true|false|null)\\b", "#0066bb", "#00ffff"),
|
||||
new SyntaxHighlights("\"[^\\n]*?\"", "#ff5500", "#00FF00"),
|
||||
new SyntaxHighlights("'[^\\n]*?'", "#00CA00", "#00FF00"),
|
||||
new SyntaxHighlights("/\\*[^*]*\\*+(?:[^/*][^*]*\\*+)*/", "#888888", "#646464"),
|
||||
new SyntaxHighlights("\\/\\/.*", "#888888", "#646464"),
|
||||
};
|
||||
}
|
||||
}
|
||||
internal class Javascript : CodeLanguage
|
||||
{
|
||||
public Javascript()
|
||||
{
|
||||
this.Name = "Javascript";
|
||||
this.Author = "Finn Freitag";
|
||||
this.Filter = new string[1] { ".js" };
|
||||
this.Description = "Syntax highlighting for Javascript language";
|
||||
this.AutoPairingPair = new AutoPairingPair[6]
|
||||
{
|
||||
new AutoPairingPair("{", "}"),
|
||||
new AutoPairingPair("[", "]"),
|
||||
new AutoPairingPair("(", ")"),
|
||||
new AutoPairingPair("`", "`"),
|
||||
new AutoPairingPair("\""),
|
||||
new AutoPairingPair("\'")
|
||||
};
|
||||
|
||||
this.Highlights = new SyntaxHighlights[]
|
||||
{
|
||||
new SyntaxHighlights("\\W", "#990033", "#CC0066"),
|
||||
new SyntaxHighlights("(\\+|\\-|\\*|/|%|\\=|\\:|\\!|>|\\<|\\?|&|\\||\\~|\\^)", "#77FF77", "#77FF77"),
|
||||
new SyntaxHighlights("\\b([+-]?(?=\\.\\d|\\d)(?:\\d+)?(?:\\.?\\d*))(?:[eE]([+-]?\\d+))?\\b", "#ff00ff", "#ff00ff"),
|
||||
new SyntaxHighlights("(?<!(def\\s))(?<=^|\\s|.)[a-zA-Z_][\\w_]*(?=\\()", "#880088", "#ffbb00"),
|
||||
new("\\b(goto|in|instanceof|static|arguments|public|do|else|const|function|class|return|let|eval|for|if|this|break|debugger|yield|extends|enum|continue|export|null|switch|private|new|throw|while|case|await|delete|super|default|void|var|protected|package|interface|false|typeof|implements|with|import|true)\\b", "#0066bb", "#00ffff"),
|
||||
new SyntaxHighlights("\\b(document|window|screen)\\b", "#008000", "#33BB00"),
|
||||
new SyntaxHighlights("\\b(try|catch|finally)\\b", "#9922ff", "#6666ff"),
|
||||
new SyntaxHighlights("/[^\\n]*/i{0,1}", "#FFFF00", "#FFFF00"),
|
||||
new SyntaxHighlights("[\"'][^\\n]*?[\"']", "#ff5500", "#00FF00"),
|
||||
new SyntaxHighlights("/\\*[^*]*\\*+(?:[^/*][^*]*\\*+)*/", "#888888", "#646464"),
|
||||
new SyntaxHighlights("\\/\\/.*", "#888888", "#646464"),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
internal class INI : CodeLanguage
|
||||
{
|
||||
public INI()
|
||||
{
|
||||
Name = "INI";
|
||||
Author = "Rust";
|
||||
Filter = new string[1] { ".ini" };
|
||||
Description = "Ini语法突出显示";
|
||||
AutoPairingPair = new AutoPairingPair[]
|
||||
{
|
||||
new("[", "]"),
|
||||
new(" ",":")
|
||||
};
|
||||
|
||||
Highlights = new SyntaxHighlights[]
|
||||
{
|
||||
new("\\b([+-]?(?=\\.\\d|\\d)(?:\\d+)?(?:\\.?\\d*))(?:[eE]([+-]?\\d+))?\\b", "#dd00dd", "#ff00ff"),//数字?
|
||||
//new("\\b(true|false)\\b","#00AADD", "#0099ff"),//bool值
|
||||
new("\\[.*?\\]", "#e91e63", "#e91e63"),
|
||||
new("(.*?):","#2196f3","#00ff00"),
|
||||
new(":","#000000","#ffffff"),
|
||||
new("\\b(false|true|if|=)\\b", "#0066bb", "#00ffff"),
|
||||
new("##.*", "#888888", "#646464"),// 单行注释
|
||||
};
|
||||
}
|
||||
}
|
||||
internal class Json : CodeLanguage
|
||||
{
|
||||
public Json()
|
||||
{
|
||||
this.Name = "Json";
|
||||
this.Author = "Julius Kirsch";
|
||||
this.Filter = new string[1] { ".json" };
|
||||
this.Description = "Syntax highlighting for Json language";
|
||||
this.AutoPairingPair = new AutoPairingPair[4]
|
||||
{
|
||||
new AutoPairingPair("{", "}"),
|
||||
new AutoPairingPair("[", "]"),
|
||||
new AutoPairingPair("\""),
|
||||
new AutoPairingPair("\'")
|
||||
};
|
||||
|
||||
this.Highlights = new SyntaxHighlights[]
|
||||
{
|
||||
new SyntaxHighlights("\\b([+-]?(?=\\.\\d|\\d)(?:\\d+)?(?:\\.?\\d*))(?:[eE]([+-]?\\d+))?\\b", "#dd00dd", "#ff00ff"),
|
||||
new SyntaxHighlights("(null|true|false)", "#00AADD", "#0099ff"),
|
||||
new SyntaxHighlights("(,|{|}|\\[|\\])", "#969696", "#646464"),
|
||||
new SyntaxHighlights("(\".+\")\\:", "#00CA00", "#dddd00"),
|
||||
new SyntaxHighlights("/\\*[^*]*\\*+(?:[^/*][^*]*\\*+)*/", "#888888", "#646464"),
|
||||
new SyntaxHighlights("\\/\\/.*", "#888888", "#646464"),
|
||||
new SyntaxHighlights("'[^\\n]*?'", "#00CA00", "#00FF00"),
|
||||
new SyntaxHighlights("\"[^\\n]*?\"", "#00CA00", "#00FF00"),
|
||||
};
|
||||
}
|
||||
}
|
||||
internal class PHP : CodeLanguage
|
||||
{
|
||||
public PHP()
|
||||
{
|
||||
this.Name = "PHP";
|
||||
this.Author = "Finn Freitag";
|
||||
this.Filter = new string[1] { ".php" };
|
||||
this.Description = "Syntax highlighting for PHP language";
|
||||
this.AutoPairingPair = new AutoPairingPair[2]
|
||||
{
|
||||
new AutoPairingPair("\""),
|
||||
new AutoPairingPair("\'")
|
||||
};
|
||||
|
||||
this.Highlights = new SyntaxHighlights[]
|
||||
{
|
||||
new SyntaxHighlights("\\<\\?php", "#FF0000", "#FF0000"),
|
||||
new SyntaxHighlights("\\?\\>", "#FF0000", "#FF0000"),
|
||||
new SyntaxHighlights("(?<!(def\\s))(?<=^|\\s|.)[a-zA-Z_][\\w_]*(?=\\()", "#3300FF", "#aa00FF"),
|
||||
new SyntaxHighlights("\\b(echo|if|case|while|else|switch|foreach|function|default|break|null|true|false)\\b", "#0077FF", "#0077FF"),
|
||||
new SyntaxHighlights("\\b([+-]?(?=\\.\\d|\\d)(?:\\d+)?(?:\\.?\\d*))(?:[eE]([+-]?\\d+))?\\b", "#ff00ff", "#ff00ff"),
|
||||
new SyntaxHighlights("(\\+|\\-|\\*|/|%|\\=|\\:|\\!|>|\\<|\\?|&|\\||\\~|\\^)", "#77FF77", "#77FF77"),
|
||||
new SyntaxHighlights("\\$\\w+", "#440044", "#FFBBFF"),
|
||||
new SyntaxHighlights("\"[^\\n]*?\"", "#ff5500", "#00FF00"),
|
||||
new SyntaxHighlights("\\'[^\\n]*?\\'", "#ff5500", "#00FF00"),
|
||||
new SyntaxHighlights("\"/[^\\n]*/i{0,1}\"", "#ff5500", "#00FF00"),
|
||||
new SyntaxHighlights("/\\*[^*]*\\*+(?:[^/*][^*]*\\*+)*/", "#888888", "#646464"),
|
||||
new SyntaxHighlights("\\/\\/.*", "#888888", "#646464"),
|
||||
};
|
||||
}
|
||||
}
|
||||
internal class QSharp : CodeLanguage
|
||||
{
|
||||
public QSharp()
|
||||
{
|
||||
this.Name = "QSharp";
|
||||
this.Author = "Finn Freitag";
|
||||
this.Filter = new string[1] { ".qs" };
|
||||
this.Description = "Syntax highlighting for QSharp language";
|
||||
this.AutoPairingPair = new AutoPairingPair[5]
|
||||
{
|
||||
new AutoPairingPair("{", "}"),
|
||||
new AutoPairingPair("[", "]"),
|
||||
new AutoPairingPair("(", ")"),
|
||||
new AutoPairingPair("\""),
|
||||
new AutoPairingPair("\'")
|
||||
};
|
||||
|
||||
this.Highlights = new SyntaxHighlights[]
|
||||
{
|
||||
new SyntaxHighlights("\\W", "#BB0000", "#BB0000"),
|
||||
new SyntaxHighlights("\\/\\/.*", "#888888", "#646464"),
|
||||
new SyntaxHighlights("\\b(namespace|open|operation|using|let|H|M|Reset|return)\\b", "#0066bb", "#00ffff"),
|
||||
new SyntaxHighlights("\\b(Qubit|Result)\\b", "#00bb66", "#00ff00"),
|
||||
};
|
||||
}
|
||||
}
|
||||
internal class XML : CodeLanguage
|
||||
{
|
||||
public XML()
|
||||
{
|
||||
this.Name = "XML";
|
||||
this.Author = "Julius Kirsch";
|
||||
this.Filter = new string[2] { ".xml", ".xaml" };
|
||||
this.Description = "Syntax highlighting for Xml language";
|
||||
this.Highlights = new SyntaxHighlights[]
|
||||
{
|
||||
new SyntaxHighlights("\\b([+-]?(?=\\.\\d|\\d)(?:\\d+)?(?:\\.?\\d*))(?:[eE]([+-]?\\d+))?\\b", "#dd00dd", "#ff00ff"),
|
||||
new SyntaxHighlights("<([^ >!\\/]+)[^>]*>", "#969696", "#0099ff"),
|
||||
new SyntaxHighlights("<+[/]+[a-zA-Z0-9:?\\-_]+>", "#969696", "#0099ff"),
|
||||
new SyntaxHighlights("<[a-zA-Z0-9:?\\-]+?.*\\/>", "#969696", "#0099ff"),
|
||||
new SyntaxHighlights("[-A-Za-z_]+\\=", "#00CA00", "#Ff0000"),
|
||||
new SyntaxHighlights("\"[^\\n]*?\"", "#00CA00", "#00FF00"),
|
||||
new SyntaxHighlights("'[^\\n]*?'", "#00CA00", "#00FF00"),
|
||||
new SyntaxHighlights("<!--[\\s\\S]*?-->", "#888888", "#888888"),
|
||||
};
|
||||
}
|
||||
}
|
||||
internal class Python : CodeLanguage
|
||||
{
|
||||
public Python()
|
||||
{
|
||||
this.Name = "Python";
|
||||
this.Author = "Julius Kirsch";
|
||||
this.Filter = new string[1] { ".py" };
|
||||
this.Description = "Syntax highlighting for Python language";
|
||||
this.AutoPairingPair = new AutoPairingPair[6]
|
||||
{
|
||||
new AutoPairingPair("{", "}"),
|
||||
new AutoPairingPair("[", "]"),
|
||||
new AutoPairingPair("(", ")"),
|
||||
new AutoPairingPair("`", "`"),
|
||||
new AutoPairingPair("\""),
|
||||
new AutoPairingPair("\'")
|
||||
};
|
||||
|
||||
this.Highlights = new SyntaxHighlights[]
|
||||
{
|
||||
new SyntaxHighlights("\\b([+-]?(?=\\.\\d|\\d)(?:\\d+)?(?:\\.?\\d*))(?:[eE]([+-]?\\d+))?\\b", "#dd00dd", "#ff00ff"),
|
||||
new SyntaxHighlights("\\b(and|as|assert|break|class|continue|def|del|elif|else|except|False|finally|for|from|global|if|import|in|is|lambda|None|nonlocal|not|or|pass|raise|return|True|try|while|with|yield)\\b", "#aa00cc", "#cc00ff"),
|
||||
new SyntaxHighlights("(?<!(def\\s))(?<=^|\\s|.)[a-zA-Z_][\\w_]*(?=\\()", "#cc9900", "#ffbb00"),
|
||||
new SyntaxHighlights("\"[^\\n]*?\"", "#ff5500", "#00FF00"),
|
||||
new SyntaxHighlights("'[^\\n]*?'", "#00CA00", "#00FF00"),
|
||||
new SyntaxHighlights("\\#.*", "#888888", "#646464"),
|
||||
new SyntaxHighlights("\\\"\"\"(.|[\\r\\n])*\\\"\"\"", "#888888", "#646464"),
|
||||
};
|
||||
}
|
||||
}
|
||||
internal class CSV : CodeLanguage
|
||||
{
|
||||
public CSV()
|
||||
{
|
||||
this.Name = "CSV";
|
||||
this.Author = "Finn Freitag";
|
||||
this.Filter = new string[1] { ".csv" };
|
||||
this.Description = "Syntax highlighting for CSV language";
|
||||
this.Highlights = new SyntaxHighlights[]
|
||||
{
|
||||
new SyntaxHighlights("[\\:\\,\\;]", "#1b9902", "#1b9902")
|
||||
};
|
||||
}
|
||||
}
|
||||
internal class LaTex : CodeLanguage
|
||||
{
|
||||
public LaTex()
|
||||
{
|
||||
this.Name = "LaTex";
|
||||
this.Author = "Finn Freitag";
|
||||
this.Filter = new string[2] { ".latex", ".tex" };
|
||||
this.Description = "Syntax highlighting for LaTex language";
|
||||
this.Highlights = new SyntaxHighlights[]
|
||||
{
|
||||
new SyntaxHighlights("\\\\[a-z]+", "#0033aa", "#0088ff"),
|
||||
new SyntaxHighlights("%.*", "#888888", "#646464"),
|
||||
new SyntaxHighlights("[\\[\\]]", "#FFFF00", "#FFFF00"),
|
||||
new SyntaxHighlights("[\\{\\}]", "#FF0000", "#FF0000"),
|
||||
new SyntaxHighlights("\\$", "#00bb00", "#00FF00")
|
||||
};
|
||||
}
|
||||
}
|
||||
internal class TOML : CodeLanguage
|
||||
{
|
||||
public TOML()
|
||||
{
|
||||
this.Name = "TOML";
|
||||
this.Author = "Finn Freitag";
|
||||
this.Filter = new string[1] { ".toml" };
|
||||
this.Description = "Syntax highlighting for TOML language";
|
||||
this.AutoPairingPair = new AutoPairingPair[]
|
||||
{
|
||||
new AutoPairingPair("[", "]"),
|
||||
new AutoPairingPair("\""),
|
||||
};
|
||||
this.Highlights = new SyntaxHighlights[]
|
||||
{
|
||||
new SyntaxHighlights("\\[.*\\]", "#0000FF", "#0000FF"),
|
||||
new SyntaxHighlights("\\[[\\t\\s]*(\\w+)[\\t\\s]*\\]", "#9900FF", "#9900FF"),
|
||||
new SyntaxHighlights("(\\w+)[\\s\\t]*\\=", "#DDDD00", "#DDDD00"),
|
||||
new SyntaxHighlights("\\=\\s+(.+)", "#EE0000", "#EE0000"),
|
||||
new SyntaxHighlights("[\\[\\]]", "#FFFF00", "#FFFF00"),
|
||||
new SyntaxHighlights("\\b(true|false)\\b", "#00bb66", "#00ff00"),
|
||||
new SyntaxHighlights("[\"'][^\\n]*?[\"']", "#D69D84", "#D69D84"),
|
||||
new SyntaxHighlights("#.*", "#888888", "#888888")
|
||||
};
|
||||
}
|
||||
}
|
||||
internal class Markdown : CodeLanguage
|
||||
{
|
||||
public Markdown()
|
||||
{
|
||||
this.Name = "Markdown";
|
||||
this.Author = "Finn Freitag";
|
||||
this.Filter = new string[1] { ".md" };
|
||||
this.Description = "Syntax highlighting for Markdown language";
|
||||
this.Highlights = new SyntaxHighlights[]
|
||||
{
|
||||
new SyntaxHighlights("[>~\"'`\\-\\+|\\^\\!_]", "#FF0000", "#FF0000"),
|
||||
new SyntaxHighlights("#", "#0000FF", "#0000FF"),
|
||||
new SyntaxHighlights("\\*.*\\*", "#000000", "#FFFFFF", false, true),
|
||||
new SyntaxHighlights("_.*_", "#000000", "#FFFFFF", false, true),
|
||||
new SyntaxHighlights("\\*\\*.*\\*\\*", "#000000", "#FFFFFF", true),
|
||||
new SyntaxHighlights("__.*__", "#000000", "#FFFFFF", true),
|
||||
new SyntaxHighlights("\\d+\\.", "#00FF00", "#00FF00"),
|
||||
new SyntaxHighlights("[\\[\\]\\(\\)]", "#FFFF00", "#FFFF00")
|
||||
};
|
||||
}
|
||||
}
|
||||
internal class CSS : CodeLanguage
|
||||
{
|
||||
public CSS()
|
||||
{
|
||||
this.Name = "CSS";
|
||||
this.Author = "Julius Kirsch";
|
||||
this.Filter = new string[2] { ".css", ".scss" };
|
||||
this.Description = "Syntax highlighting for CSS language";
|
||||
this.AutoPairingPair = new AutoPairingPair[5]
|
||||
{
|
||||
new AutoPairingPair("{", "}"),
|
||||
new AutoPairingPair("[", "]"),
|
||||
new AutoPairingPair("(", ")"),
|
||||
new AutoPairingPair("\""),
|
||||
new AutoPairingPair("\'")
|
||||
};
|
||||
this.Highlights = new SyntaxHighlights[]
|
||||
{
|
||||
new SyntaxHighlights("[a-zA-Z-]+.*;", "#ff5500", "#00ffff"),//properties
|
||||
new SyntaxHighlights("\\b([a-zA-Z_-][a-zA-Z0-9_-]*)(?=\\()", "#bb00bb", "#00ff99"),//functions
|
||||
new SyntaxHighlights(":[a-z].*(?={)", "#0033ff", "#fffd00"),//pseudo classes/elements
|
||||
new SyntaxHighlights("(.|#|^).*\\s*{", "#227700", "#44ff00"),//classname
|
||||
new SyntaxHighlights("(?<=\\d)(?:px|%|em|rem|in|cm|mm|pt|pc|ex|ch|vw|vh|vmin|vmax|ms|s)", "#cc0000", "#ff0000"),//units
|
||||
new SyntaxHighlights("\\b-?\\d+(?:\\.\\d+)?", "#0000ff", "#cc00ff"),//numbers
|
||||
new SyntaxHighlights("@([^ ]+)", "#8800ff", "#ff0000"),//first word after the @
|
||||
new SyntaxHighlights("#[0-9A-Fa-f]{1,8}\\b", "#00bb55", "#cc00ff"),//hexadecimal
|
||||
new SyntaxHighlights("(\".+?\"|\'.+?\')", "#00aaff", "#ff8800"),//strings
|
||||
new SyntaxHighlights("(;|:|{|}|,)", "#777777", "#bbbbbb"),//special characters
|
||||
new SyntaxHighlights("\\/\\*(.|\\n)*?\\*\\/", "#555555", "#888888"),//comments
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
45
TextControlBox/Models/AutoPairingPair.cs
Normal file
45
TextControlBox/Models/AutoPairingPair.cs
Normal file
|
@ -0,0 +1,45 @@
|
|||
namespace TextControlBoxNS
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a pair of characters used for auto-pairing in text.
|
||||
/// </summary>
|
||||
public class AutoPairingPair
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the AutoPairingPair class with the same value for both the opening and closing characters.
|
||||
/// </summary>
|
||||
/// <param name="value">The character value to be used for both opening and closing.</param>
|
||||
public AutoPairingPair(string value)
|
||||
{
|
||||
this.Value = this.Pair = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the AutoPairingPair class with different values for the opening and closing characters.
|
||||
/// </summary>
|
||||
/// <param name="value">The character value to be used as the opening character.</param>
|
||||
/// <param name="pair">The character value to be used as the closing character.</param>
|
||||
public AutoPairingPair(string value, string pair)
|
||||
{
|
||||
this.Value = value;
|
||||
this.Pair = pair;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks if the provided input contains the opening character of the pair.
|
||||
/// </summary>
|
||||
/// <param name="input">The input string to check for the opening character.</param>
|
||||
/// <returns>True if the input contains the opening character; otherwise, false.</returns>
|
||||
public bool Matches(string input) => input.Contains(this.Value);
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the character value used for the opening part of the auto-pairing pair.
|
||||
/// </summary>
|
||||
public string Value { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the character value used for the closing part of the auto-pairing pair.
|
||||
/// </summary>
|
||||
public string Pair { get; set; }
|
||||
}
|
||||
}
|
37
TextControlBox/Models/CodeFontStyle.cs
Normal file
37
TextControlBox/Models/CodeFontStyle.cs
Normal file
|
@ -0,0 +1,37 @@
|
|||
namespace TextControlBoxNS
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the font style settings for a code element in the text.
|
||||
/// </summary>
|
||||
public class CodeFontStyle
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the CodeFontStyle class with the specified font style settings.
|
||||
/// </summary>
|
||||
/// <param name="underlined">true if the code element should be displayed with an underline; otherwise, false.</param>
|
||||
/// <param name="italic">true if the code element should be displayed in italic font; otherwise, false.</param>
|
||||
/// <param name="bold">true if the code element should be displayed in bold font; otherwise, false.</param>
|
||||
public CodeFontStyle(bool underlined, bool italic, bool bold)
|
||||
{
|
||||
this.Italic = italic;
|
||||
this.Bold = bold;
|
||||
this.Underlined = underlined;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether the code element should be displayed with an underline.
|
||||
/// </summary>
|
||||
public bool Underlined { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether the code element should be displayed in bold font.
|
||||
/// </summary>
|
||||
public bool Bold { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether the code element should be displayed in italic font.
|
||||
/// </summary>
|
||||
public bool Italic { get; set; }
|
||||
}
|
||||
|
||||
}
|
39
TextControlBox/Models/CodeLanguage.cs
Normal file
39
TextControlBox/Models/CodeLanguage.cs
Normal file
|
@ -0,0 +1,39 @@
|
|||
namespace TextControlBoxNS
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a code language configuration used for syntax highlighting and auto-pairing in the text content.
|
||||
/// </summary>
|
||||
public class CodeLanguage
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the name of the code language.
|
||||
/// </summary>
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the description of the code language.
|
||||
/// </summary>
|
||||
public string Description { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets an array of file filters for the code language.
|
||||
/// </summary>
|
||||
public string[] Filter { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the author of the code language definition.
|
||||
/// </summary>
|
||||
public string Author { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets an array of syntax highlights for the code language.
|
||||
/// </summary>
|
||||
public SyntaxHighlights[] Highlights { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets an array of auto-pairing pairs for the code language.
|
||||
/// </summary>
|
||||
public AutoPairingPair[] AutoPairingPair { get; set; }
|
||||
}
|
||||
|
||||
}
|
116
TextControlBox/Models/CodeLanguageId.cs
Normal file
116
TextControlBox/Models/CodeLanguageId.cs
Normal file
|
@ -0,0 +1,116 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using TextControlBoxNS.Languages;
|
||||
|
||||
namespace TextControlBoxNS
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the unique identifiers for different code languages used for syntax highlighting.
|
||||
/// </summary>
|
||||
public enum CodeLanguageId
|
||||
{
|
||||
INI,
|
||||
/// <summary>
|
||||
/// Identifier for Batch code language.
|
||||
/// </summary>
|
||||
Batch,
|
||||
|
||||
/// <summary>
|
||||
/// Identifier for C++ code language.
|
||||
/// </summary>
|
||||
Cpp,
|
||||
|
||||
/// <summary>
|
||||
/// Identifier for C# code language.
|
||||
/// </summary>
|
||||
CSharp,
|
||||
|
||||
/// <summary>
|
||||
/// Identifier for configuration file code language.
|
||||
/// </summary>
|
||||
ConfigFile,
|
||||
|
||||
/// <summary>
|
||||
/// Identifier for CSS code language.
|
||||
/// </summary>
|
||||
CSS,
|
||||
|
||||
/// <summary>
|
||||
/// Identifier for CSV code language.
|
||||
/// </summary>
|
||||
CSV,
|
||||
|
||||
/// <summary>
|
||||
/// Identifier for GCode code language.
|
||||
/// </summary>
|
||||
GCode,
|
||||
|
||||
/// <summary>
|
||||
/// Identifier for HexFile code language.
|
||||
/// </summary>
|
||||
HexFile,
|
||||
|
||||
/// <summary>
|
||||
/// Identifier for HTML code language.
|
||||
/// </summary>
|
||||
Html,
|
||||
|
||||
/// <summary>
|
||||
/// Identifier for Java code language.
|
||||
/// </summary>
|
||||
Java,
|
||||
|
||||
/// <summary>
|
||||
/// Identifier for JavaScript code language.
|
||||
/// </summary>
|
||||
Javascript,
|
||||
|
||||
/// <summary>
|
||||
/// Identifier for JSON code language.
|
||||
/// </summary>
|
||||
Json,
|
||||
|
||||
/// <summary>
|
||||
/// Identifier for LaTeX code language.
|
||||
/// </summary>
|
||||
Latex,
|
||||
|
||||
/// <summary>
|
||||
/// Identifier for Markdown code language.
|
||||
/// </summary>
|
||||
Markdown,
|
||||
|
||||
/// <summary>
|
||||
/// Identifier for PHP code language.
|
||||
/// </summary>
|
||||
PHP,
|
||||
|
||||
/// <summary>
|
||||
/// Identifier for Python code language.
|
||||
/// </summary>
|
||||
Python,
|
||||
|
||||
/// <summary>
|
||||
/// Identifier for Q# code language.
|
||||
/// </summary>
|
||||
QSharp,
|
||||
|
||||
/// <summary>
|
||||
/// Identifier for TOML code language.
|
||||
/// </summary>
|
||||
TOML,
|
||||
|
||||
/// <summary>
|
||||
/// Identifier for XML code language.
|
||||
/// </summary>
|
||||
XML,
|
||||
|
||||
/// <summary>
|
||||
/// Identifier for no code language.
|
||||
/// </summary>
|
||||
None,
|
||||
}
|
||||
}
|
51
TextControlBox/Models/CursorPosition.cs
Normal file
51
TextControlBox/Models/CursorPosition.cs
Normal file
|
@ -0,0 +1,51 @@
|
|||
namespace TextControlBoxNS
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the position of the cursor in the textbox.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The CursorPosition class stores the position of the cursor within the textbox.
|
||||
/// It consists of two properties: CharacterPosition and LineNumber.
|
||||
/// The CharacterPosition property indicates the index of the cursor within the current line (zero-based index).
|
||||
/// The LineNumber property represents the line number on which the cursor is currently positioned (zero-based index).
|
||||
/// </remarks>
|
||||
public class CursorPosition
|
||||
{
|
||||
internal CursorPosition(int characterPosition = 0, int lineNumber = 0)
|
||||
{
|
||||
this.CharacterPosition = characterPosition;
|
||||
this.LineNumber = lineNumber;
|
||||
}
|
||||
internal CursorPosition(CursorPosition currentCursorPosition)
|
||||
{
|
||||
if (currentCursorPosition == null)
|
||||
return;
|
||||
|
||||
this.CharacterPosition = currentCursorPosition.CharacterPosition;
|
||||
this.LineNumber = currentCursorPosition.LineNumber;
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets the character position of the cursor within the current line.
|
||||
/// </summary>
|
||||
public int CharacterPosition { get; internal set; } = 0;
|
||||
/// <summary>
|
||||
/// Gets the line number in which the cursor is currently positioned.
|
||||
/// </summary>
|
||||
public int LineNumber { get; internal set; } = 0;
|
||||
|
||||
internal void AddToCharacterPos(int add)
|
||||
{
|
||||
CharacterPosition += add;
|
||||
}
|
||||
internal void SubtractFromCharacterPos(int subtract)
|
||||
{
|
||||
CharacterPosition -= subtract;
|
||||
if (CharacterPosition < 0)
|
||||
CharacterPosition = 0;
|
||||
}
|
||||
internal static CursorPosition ChangeLineNumber(CursorPosition currentCursorPosition, int lineNumber)
|
||||
{
|
||||
return new CursorPosition(currentCursorPosition.CharacterPosition, lineNumber);
|
||||
}
|
||||
}
|
||||
}
|
43
TextControlBox/Models/CursorSize.cs
Normal file
43
TextControlBox/Models/CursorSize.cs
Normal file
|
@ -0,0 +1,43 @@
|
|||
namespace TextControlBoxNS
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the size of the cursor in the textbox.
|
||||
/// </summary>
|
||||
public class CursorSize
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates a new instance of the CursorSize class
|
||||
/// </summary>
|
||||
/// <param name="width">The width of the cursor</param>
|
||||
/// <param name="height">The height of the cursor</param>
|
||||
/// <param name="offsetX">The x-offset from the actual cursor position</param>
|
||||
/// <param name="offsetY">The y-offset from the actual cursor position</param>
|
||||
public CursorSize(float width = 0, float height = 0, float offsetX = 0, float offsetY = 0)
|
||||
{
|
||||
this.Width = width;
|
||||
this.Height = height;
|
||||
this.OffsetX = offsetX;
|
||||
this.OffsetY = offsetY;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The width of the cursor
|
||||
/// </summary>
|
||||
public float Width { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The height of the cursor
|
||||
/// </summary>
|
||||
public float Height { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The left/right offset from the actual cursor position
|
||||
/// </summary>
|
||||
public float OffsetX { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The top/bottom offset from the actual cursor position
|
||||
/// </summary>
|
||||
public float OffsetY { get; private set; }
|
||||
}
|
||||
}
|
11
TextControlBox/Models/JsonCodeLanguage.cs
Normal file
11
TextControlBox/Models/JsonCodeLanguage.cs
Normal file
|
@ -0,0 +1,11 @@
|
|||
namespace TextControlBoxNS
|
||||
{
|
||||
internal class JsonCodeLanguage
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public string Description { get; set; }
|
||||
public string Filter { get; set; }
|
||||
public string Author { get; set; }
|
||||
public SyntaxHighlights[] Highlights;
|
||||
}
|
||||
}
|
29
TextControlBox/Models/JsonLoadResult.cs
Normal file
29
TextControlBox/Models/JsonLoadResult.cs
Normal file
|
@ -0,0 +1,29 @@
|
|||
namespace TextControlBoxNS
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the result of a JSON load operation for a code language in the textbox.
|
||||
/// </summary>
|
||||
public class JsonLoadResult
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the JsonLoadResult class with the specified loading status and CodeLanguage.
|
||||
/// </summary>
|
||||
/// <param name="succeed">true if the loading operation succeeded; otherwise, false.</param>
|
||||
/// <param name="codeLanguage">The CodeLanguage loaded from the JSON data.</param>
|
||||
public JsonLoadResult(bool succeed, CodeLanguage codeLanguage)
|
||||
{
|
||||
this.Succeed = succeed;
|
||||
this.CodeLanguage = codeLanguage;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether the loading operation succeeded.
|
||||
/// </summary>
|
||||
public bool Succeed { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the CodeLanguage that was loaded from the JSON data.
|
||||
/// </summary>
|
||||
public CodeLanguage CodeLanguage { get; set; }
|
||||
}
|
||||
}
|
40
TextControlBox/Models/ScrollBarPosition.cs
Normal file
40
TextControlBox/Models/ScrollBarPosition.cs
Normal file
|
@ -0,0 +1,40 @@
|
|||
namespace TextControlBoxNS
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the position of a scrollbar, containing the horizontal and vertical scroll positions.
|
||||
/// </summary>
|
||||
public class ScrollBarPosition
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the ScrollBarPosition class with the provided values.
|
||||
/// </summary>
|
||||
/// <param name="scrollBarPosition">The existing ScrollBarPosition object from which to copy the values.</param>
|
||||
|
||||
public ScrollBarPosition(ScrollBarPosition scrollBarPosition)
|
||||
{
|
||||
this.ValueX = scrollBarPosition.ValueX;
|
||||
this.ValueY = scrollBarPosition.ValueY;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the ScrollBarPosition class
|
||||
/// </summary>
|
||||
/// <param name="valueX">The horizontal amount scrolled</param>
|
||||
/// <param name="valueY">The vertical amount scrolled</param>
|
||||
public ScrollBarPosition(double valueX = 0, double valueY = 0)
|
||||
{
|
||||
this.ValueX = valueX;
|
||||
this.ValueY = valueY;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The amount scrolled horizontally
|
||||
/// </summary>
|
||||
public double ValueX { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The amount scrolled vertically
|
||||
/// </summary>
|
||||
public double ValueY { get; set; }
|
||||
}
|
||||
}
|
28
TextControlBox/Models/SelectionChangedEventHandler.cs
Normal file
28
TextControlBox/Models/SelectionChangedEventHandler.cs
Normal file
|
@ -0,0 +1,28 @@
|
|||
namespace TextControlBoxNS
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the class that will be returned by the SelectionChanged event of the TextControlBox.
|
||||
/// </summary>
|
||||
public class SelectionChangedEventHandler
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the position of the cursor within the current line.
|
||||
/// </summary>
|
||||
public int CharacterPositionInLine { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Represents the line number where the cursor is currently located.
|
||||
/// </summary>
|
||||
public int LineNumber { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Represents the starting index of the selection.
|
||||
/// </summary>
|
||||
public int SelectionStartIndex { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Represents the length of the selection.
|
||||
/// </summary>
|
||||
public int SelectionLength { get; set; }
|
||||
}
|
||||
}
|
71
TextControlBox/Models/SyntaxHighlights.cs
Normal file
71
TextControlBox/Models/SyntaxHighlights.cs
Normal file
|
@ -0,0 +1,71 @@
|
|||
using System.Drawing;
|
||||
using TextControlBoxNS.Extensions;
|
||||
|
||||
namespace TextControlBoxNS
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a syntax highlight definition for a specific pattern in the text.
|
||||
/// </summary>
|
||||
public class SyntaxHighlights
|
||||
{
|
||||
private readonly ColorConverter ColorConverter = new ColorConverter();
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the SyntaxHighlights class with the specified pattern, colors, and font styles.
|
||||
/// </summary>
|
||||
/// <param name="pattern">The pattern to be highlighted in the text content.</param>
|
||||
/// <param name="colorLight">The color representation for the pattern in the light theme (e.g., "#RRGGBB" format).</param>
|
||||
/// <param name="colorDark">The color representation for the pattern in the dark theme (e.g., "#RRGGBB" format).</param>
|
||||
/// <param name="bold">true if the pattern should be displayed in bold font; otherwise, false.</param>
|
||||
/// <param name="italic">true if the pattern should be displayed in italic font; otherwise, false.</param>
|
||||
/// <param name="underlined">true if the pattern should be displayed with an underline; otherwise, false.</param>
|
||||
public SyntaxHighlights(string pattern, string colorLight, string colorDark, bool bold = false, bool italic = false, bool underlined = false)
|
||||
{
|
||||
this.Pattern = pattern;
|
||||
this.ColorDark = colorDark;
|
||||
this.ColorLight = colorLight;
|
||||
|
||||
if (underlined || italic || bold)
|
||||
this.CodeStyle = new CodeFontStyle(underlined, italic, bold);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the font style for the pattern.
|
||||
/// </summary>
|
||||
public CodeFontStyle CodeStyle { get; set; } = null;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the pattern to be highlighted in the text content.
|
||||
/// </summary>
|
||||
public string Pattern { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the color representation for the pattern in the dark theme.
|
||||
/// </summary>
|
||||
public Windows.UI.Color ColorDark_Clr { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the color representation for the pattern in the light theme.
|
||||
/// </summary>
|
||||
public Windows.UI.Color ColorLight_Clr { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Sets the color representation for the pattern in the dark theme.
|
||||
/// </summary>
|
||||
/// <param name="value">The color representation for the pattern in the dark theme (e.g., "#RRGGBB" format).</param>
|
||||
public string ColorDark
|
||||
{
|
||||
set => ColorDark_Clr = ((Color)ColorConverter.ConvertFromString(value)).ToMediaColor();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the color representation for the pattern in the light theme.
|
||||
/// </summary>
|
||||
/// <param name="value">The color representation for the pattern in the light theme (e.g., "#RRGGBB" format).</param>
|
||||
public string ColorLight
|
||||
{
|
||||
set => ColorLight_Clr = ((Color)ColorConverter.ConvertFromString(value)).ToMediaColor();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
89
TextControlBox/Models/TextControlBoxDesign.cs
Normal file
89
TextControlBox/Models/TextControlBoxDesign.cs
Normal file
|
@ -0,0 +1,89 @@
|
|||
using Microsoft.UI.Xaml.Media;
|
||||
using Windows.UI;
|
||||
|
||||
namespace TextControlBoxNS
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the design settings for the textbox.
|
||||
/// </summary>
|
||||
public class TextControlBoxDesign
|
||||
{
|
||||
/// <summary>
|
||||
/// Create an instance of the TextControlBoxDesign from a given design
|
||||
/// </summary>
|
||||
/// <param name="design">The design to create a new instance from</param>
|
||||
public TextControlBoxDesign(TextControlBoxDesign design)
|
||||
{
|
||||
this.Background = design.Background;
|
||||
this.TextColor = design.TextColor;
|
||||
this.SelectionColor = design.SelectionColor;
|
||||
this.CursorColor = design.CursorColor;
|
||||
this.LineHighlighterColor = design.LineHighlighterColor;
|
||||
this.LineNumberColor = design.LineNumberColor;
|
||||
this.LineNumberBackground = design.LineNumberBackground;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create a new instance of the TextControlBoxDesign class
|
||||
/// </summary>
|
||||
/// <param name="background">The background color of the textbox</param>
|
||||
/// <param name="textColor">The color of the text</param>
|
||||
/// <param name="selectionColor">The color of the selection</param>
|
||||
/// <param name="cursorColor">The color of the cursor</param>
|
||||
/// <param name="lineHighlighterColor">The color of the linehighlighter</param>
|
||||
/// <param name="lineNumberColor">The color of the linenumber</param>
|
||||
/// <param name="lineNumberBackground">The background color of the linenumbers</param>
|
||||
/// <param name="searchHighlightColor">The color of the search highlights</param>
|
||||
public TextControlBoxDesign(Brush background, Color textColor, Color selectionColor, Color cursorColor, Color lineHighlighterColor, Color lineNumberColor, Color lineNumberBackground, Color searchHighlightColor)
|
||||
{
|
||||
this.Background = background;
|
||||
this.TextColor = textColor;
|
||||
this.SelectionColor = selectionColor;
|
||||
this.CursorColor = cursorColor;
|
||||
this.LineHighlighterColor = lineHighlighterColor;
|
||||
this.LineNumberColor = lineNumberColor;
|
||||
this.LineNumberBackground = lineNumberBackground;
|
||||
this.SearchHighlightColor = searchHighlightColor;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the background color of the textbox.
|
||||
/// </summary>
|
||||
public Brush Background { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the text color of the textbox.
|
||||
/// </summary>
|
||||
public Color TextColor { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the color of the selected text in the textbox.
|
||||
/// </summary>
|
||||
public Color SelectionColor { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the color of the cursor in the textbox.
|
||||
/// </summary>
|
||||
public Color CursorColor { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the color of the line highlighter in the textbox.
|
||||
/// </summary>
|
||||
public Color LineHighlighterColor { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the color of the line numbers in the textbox.
|
||||
/// </summary>
|
||||
public Color LineNumberColor { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the background color of the line numbers in the textbox.
|
||||
/// </summary>
|
||||
public Color LineNumberBackground { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the color used to highlight search results in the textbox.
|
||||
/// </summary>
|
||||
public Color SearchHighlightColor { get; set; }
|
||||
}
|
||||
}
|
52
TextControlBox/Models/TextSelection.cs
Normal file
52
TextControlBox/Models/TextSelection.cs
Normal file
|
@ -0,0 +1,52 @@
|
|||
namespace TextControlBoxNS.Text
|
||||
{
|
||||
internal class TextSelection
|
||||
{
|
||||
public TextSelection()
|
||||
{
|
||||
Index = 0;
|
||||
Length = 0;
|
||||
StartPosition = null;
|
||||
EndPosition = null;
|
||||
}
|
||||
public TextSelection(int index = 0, int length = 0, CursorPosition startPosition = null, CursorPosition endPosition = null)
|
||||
{
|
||||
Index = index;
|
||||
Length = length;
|
||||
StartPosition = startPosition;
|
||||
EndPosition = endPosition;
|
||||
}
|
||||
public TextSelection(CursorPosition startPosition = null, CursorPosition endPosition = null)
|
||||
{
|
||||
StartPosition = startPosition;
|
||||
EndPosition = endPosition;
|
||||
}
|
||||
public TextSelection(TextSelection textSelection)
|
||||
{
|
||||
StartPosition = new CursorPosition(textSelection.StartPosition);
|
||||
EndPosition = new CursorPosition(textSelection.EndPosition);
|
||||
Index = textSelection.Index;
|
||||
Length = textSelection.Length;
|
||||
}
|
||||
|
||||
public int Index { get; set; }
|
||||
public int Length { get; set; }
|
||||
|
||||
public CursorPosition StartPosition { get; set; }
|
||||
public CursorPosition EndPosition { get; set; }
|
||||
|
||||
public bool IsLineInSelection(int line)
|
||||
{
|
||||
if (this.StartPosition != null && this.EndPosition != null)
|
||||
{
|
||||
if (this.StartPosition.LineNumber > this.EndPosition.LineNumber)
|
||||
return this.StartPosition.LineNumber < line && this.EndPosition.LineNumber > line;
|
||||
else if (this.StartPosition.LineNumber == this.EndPosition.LineNumber)
|
||||
return this.StartPosition.LineNumber != line;
|
||||
else
|
||||
return this.StartPosition.LineNumber > line && this.EndPosition.LineNumber < line;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
29
TextControlBox/Models/TextSelectionPosition.cs
Normal file
29
TextControlBox/Models/TextSelectionPosition.cs
Normal file
|
@ -0,0 +1,29 @@
|
|||
namespace TextControlBoxNS
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the position and length of a text selection in the textbox.
|
||||
/// </summary>
|
||||
public class TextSelectionPosition
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the TextSelectionPosition class with the specified index and length.
|
||||
/// </summary>
|
||||
/// <param name="index">The start index of the text selection.</param>
|
||||
/// <param name="length">The length of the text selection.</param>
|
||||
public TextSelectionPosition(int index = 0, int length = 0)
|
||||
{
|
||||
this.Index = index;
|
||||
this.Length = length;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the start index of the text selection.
|
||||
/// </summary>
|
||||
public int Index { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the length of the text selection.
|
||||
/// </summary>
|
||||
public int Length { get; set; }
|
||||
}
|
||||
}
|
14
TextControlBox/Models/UndoRedoItem.cs
Normal file
14
TextControlBox/Models/UndoRedoItem.cs
Normal file
|
@ -0,0 +1,14 @@
|
|||
using TextControlBoxNS.Text;
|
||||
|
||||
namespace TextControlBoxNS.Models
|
||||
{
|
||||
internal struct UndoRedoItem
|
||||
{
|
||||
public int StartLine { get; set; }
|
||||
public string UndoText { get; set; }
|
||||
public string RedoText { get; set; }
|
||||
public int UndoCount { get; set; }
|
||||
public int RedoCount { get; set; }
|
||||
public TextSelection Selection { get; set; }
|
||||
}
|
||||
}
|
52
TextControlBox/Renderer/CursorRenderer.cs
Normal file
52
TextControlBox/Renderer/CursorRenderer.cs
Normal file
|
@ -0,0 +1,52 @@
|
|||
using Microsoft.Graphics.Canvas.Brushes;
|
||||
using Microsoft.Graphics.Canvas.Text;
|
||||
using Microsoft.Graphics.Canvas.UI.Xaml;
|
||||
using System;
|
||||
using System.Numerics;
|
||||
using Windows.Foundation;
|
||||
|
||||
namespace TextControlBoxNS.Renderer
|
||||
{
|
||||
internal class CursorRenderer
|
||||
{
|
||||
public static int GetCursorLineFromPoint(Point point, float singleLineHeight, int numberOfRenderedLines, int numberOfStartLine)
|
||||
{
|
||||
//Calculate the relative linenumber, where the pointer was pressed at
|
||||
int linenumber = (int)(point.Y / singleLineHeight);
|
||||
linenumber += numberOfStartLine;
|
||||
return Math.Clamp(linenumber, 0, numberOfStartLine + numberOfRenderedLines - 1);
|
||||
}
|
||||
public static int GetCharacterPositionFromPoint(string currentLine, CanvasTextLayout textLayout, Point cursorPosition, float marginLeft)
|
||||
{
|
||||
if (currentLine == null || textLayout == null)
|
||||
return 0;
|
||||
|
||||
textLayout.HitTest(
|
||||
(float)cursorPosition.X - marginLeft, 0,
|
||||
out var textLayoutRegion);
|
||||
return textLayoutRegion.CharacterIndex;
|
||||
}
|
||||
|
||||
//Return the position in pixels of the cursor in the current line
|
||||
public static float GetCursorPositionInLine(CanvasTextLayout currentLineTextLayout, CursorPosition cursorPosition, float xOffset)
|
||||
{
|
||||
if (currentLineTextLayout == null)
|
||||
return 0;
|
||||
|
||||
return currentLineTextLayout.GetCaretPosition(cursorPosition.CharacterPosition < 0 ? 0 : cursorPosition.CharacterPosition, false).X + xOffset;
|
||||
}
|
||||
|
||||
//Return the cursor Width
|
||||
public static void RenderCursor(CanvasTextLayout textLayout, int characterPosition, float xOffset, float y, float fontSize, CursorSize customSize, CanvasDrawEventArgs args, CanvasSolidColorBrush cursorColorBrush)
|
||||
{
|
||||
if (textLayout == null)
|
||||
return;
|
||||
|
||||
Vector2 vector = textLayout.GetCaretPosition(characterPosition < 0 ? 0 : characterPosition, false);
|
||||
if (customSize == null)
|
||||
args.DrawingSession.FillRectangle(vector.X + xOffset, y, 1, fontSize, cursorColorBrush);
|
||||
else
|
||||
args.DrawingSession.FillRectangle(vector.X + xOffset + customSize.OffsetX, y + customSize.OffsetY, (float)customSize.Width, (float)customSize.Height, cursorColorBrush);
|
||||
}
|
||||
}
|
||||
}
|
17
TextControlBox/Renderer/LineHighlighterRenderer.cs
Normal file
17
TextControlBox/Renderer/LineHighlighterRenderer.cs
Normal file
|
@ -0,0 +1,17 @@
|
|||
using Microsoft.Graphics.Canvas.Brushes;
|
||||
using Microsoft.Graphics.Canvas.Text;
|
||||
using Microsoft.Graphics.Canvas.UI.Xaml;
|
||||
|
||||
namespace TextControlBoxNS.Renderer
|
||||
{
|
||||
internal class LineHighlighterRenderer
|
||||
{
|
||||
public static void Render(float canvasWidth, CanvasTextLayout textLayout, float y, float fontSize, CanvasDrawEventArgs args, CanvasSolidColorBrush backgroundBrush)
|
||||
{
|
||||
if (textLayout == null)
|
||||
return;
|
||||
|
||||
args.DrawingSession.FillRectangle(0, y, canvasWidth, fontSize, backgroundBrush);
|
||||
}
|
||||
}
|
||||
}
|
47
TextControlBox/Renderer/SearchHighlightsRenderer.cs
Normal file
47
TextControlBox/Renderer/SearchHighlightsRenderer.cs
Normal file
|
@ -0,0 +1,47 @@
|
|||
using Microsoft.Graphics.Canvas.Text;
|
||||
using Microsoft.Graphics.Canvas.UI.Xaml;
|
||||
using System;
|
||||
using System.Text.RegularExpressions;
|
||||
using TextControlBoxNS.Helper;
|
||||
using Windows.UI;
|
||||
|
||||
namespace TextControlBoxNS.Renderer
|
||||
{
|
||||
internal class SearchHighlightsRenderer
|
||||
{
|
||||
public static void RenderHighlights(
|
||||
CanvasDrawEventArgs args,
|
||||
CanvasTextLayout drawnTextLayout,
|
||||
string renderedText,
|
||||
int[] possibleLines,
|
||||
string searchRegex,
|
||||
float scrollOffsetX,
|
||||
float offsetTop,
|
||||
Color searchHighlightColor)
|
||||
{
|
||||
if (searchRegex == null || possibleLines == null || possibleLines.Length == 0)
|
||||
return;
|
||||
|
||||
MatchCollection matches;
|
||||
try
|
||||
{
|
||||
matches = Regex.Matches(renderedText, searchRegex);
|
||||
}
|
||||
catch (ArgumentException)
|
||||
{
|
||||
return;
|
||||
}
|
||||
for (int j = 0; j < matches.Count; j++)
|
||||
{
|
||||
var match = matches[j];
|
||||
|
||||
var layoutRegion = drawnTextLayout.GetCharacterRegions(match.Index, match.Length);
|
||||
if (layoutRegion.Length > 0)
|
||||
{
|
||||
args.DrawingSession.FillRectangle(Utils.CreateRect(layoutRegion[0].LayoutBounds, scrollOffsetX, offsetTop), searchHighlightColor);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
209
TextControlBox/Renderer/SelectionRenderer.cs
Normal file
209
TextControlBox/Renderer/SelectionRenderer.cs
Normal file
|
@ -0,0 +1,209 @@
|
|||
using Microsoft.Graphics.Canvas.Text;
|
||||
using Microsoft.Graphics.Canvas.UI.Xaml;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using TextControlBoxNS.Helper;
|
||||
using TextControlBoxNS.Text;
|
||||
using Windows.Foundation;
|
||||
using Windows.UI;
|
||||
|
||||
namespace TextControlBoxNS.Renderer
|
||||
{
|
||||
internal class SelectionRenderer
|
||||
{
|
||||
public bool HasSelection = false;
|
||||
public bool IsSelecting = false;
|
||||
public bool IsSelectingOverLinenumbers = false;
|
||||
public CursorPosition SelectionStartPosition = null;
|
||||
public CursorPosition SelectionEndPosition = null;
|
||||
public int SelectionLength = 0;
|
||||
public int SelectionStart = 0;
|
||||
|
||||
|
||||
//Draw the actual selection and return the cursorposition. Return -1 if no selection was drawn
|
||||
public TextSelection DrawSelection(
|
||||
CanvasTextLayout textLayout,
|
||||
IEnumerable<string> renderedLines,
|
||||
CanvasDrawEventArgs args,
|
||||
float marginLeft,
|
||||
float marginTop,
|
||||
int unrenderedLinesToRenderStart,
|
||||
int numberOfRenderedLines,
|
||||
float fontSize,
|
||||
Color selectionColor
|
||||
)
|
||||
{
|
||||
if (HasSelection && SelectionEndPosition != null && SelectionStartPosition != null)
|
||||
{
|
||||
int selStartIndex = 0;
|
||||
int selEndIndex = 0;
|
||||
int characterPosStart = SelectionStartPosition.CharacterPosition;
|
||||
int characterPosEnd = SelectionEndPosition.CharacterPosition;
|
||||
|
||||
//Render the selection on position 0 if the user scrolled the start away
|
||||
if (SelectionEndPosition.LineNumber < SelectionStartPosition.LineNumber)
|
||||
{
|
||||
if (SelectionEndPosition.LineNumber < unrenderedLinesToRenderStart)
|
||||
characterPosEnd = 0;
|
||||
if (SelectionStartPosition.LineNumber < unrenderedLinesToRenderStart + 1)
|
||||
characterPosStart = 0;
|
||||
}
|
||||
else if (SelectionEndPosition.LineNumber == SelectionStartPosition.LineNumber)
|
||||
{
|
||||
if (SelectionStartPosition.LineNumber < unrenderedLinesToRenderStart)
|
||||
characterPosStart = 0;
|
||||
if (SelectionEndPosition.LineNumber < unrenderedLinesToRenderStart)
|
||||
characterPosEnd = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (SelectionStartPosition.LineNumber < unrenderedLinesToRenderStart)
|
||||
characterPosStart = 0;
|
||||
if (SelectionEndPosition.LineNumber < unrenderedLinesToRenderStart + 1)
|
||||
characterPosEnd = 0;
|
||||
}
|
||||
|
||||
if (SelectionStartPosition.LineNumber == SelectionEndPosition.LineNumber)
|
||||
{
|
||||
int lenghtToLine = 0;
|
||||
for (int i = 0; i < SelectionStartPosition.LineNumber - unrenderedLinesToRenderStart; i++)
|
||||
{
|
||||
if (i < numberOfRenderedLines)
|
||||
{
|
||||
lenghtToLine += renderedLines.ElementAt(i).Length + 1;
|
||||
}
|
||||
}
|
||||
|
||||
selStartIndex = characterPosStart + lenghtToLine;
|
||||
selEndIndex = characterPosEnd + lenghtToLine;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < SelectionStartPosition.LineNumber - unrenderedLinesToRenderStart; i++)
|
||||
{
|
||||
if (i >= numberOfRenderedLines) //Out of range of the List (do nothing)
|
||||
break;
|
||||
selStartIndex += renderedLines.ElementAt(i).Length + 1;
|
||||
}
|
||||
selStartIndex += characterPosStart;
|
||||
|
||||
for (int i = 0; i < SelectionEndPosition.LineNumber - unrenderedLinesToRenderStart; i++)
|
||||
{
|
||||
if (i >= numberOfRenderedLines) //Out of range of the List (do nothing)
|
||||
break;
|
||||
|
||||
selEndIndex += renderedLines.ElementAt(i).Length + 1;
|
||||
}
|
||||
selEndIndex += characterPosEnd;
|
||||
}
|
||||
|
||||
SelectionStart = Math.Min(selStartIndex, selEndIndex);
|
||||
|
||||
if (SelectionStart < 0)
|
||||
SelectionStart = 0;
|
||||
if (SelectionLength < 0)
|
||||
SelectionLength = 0;
|
||||
|
||||
if (selEndIndex > selStartIndex)
|
||||
SelectionLength = selEndIndex - selStartIndex;
|
||||
else
|
||||
SelectionLength = selStartIndex - selEndIndex;
|
||||
|
||||
CanvasTextLayoutRegion[] descriptions = textLayout.GetCharacterRegions(SelectionStart, SelectionLength);
|
||||
for (int i = 0; i < descriptions.Length; i++)
|
||||
{
|
||||
//Change the width if selection in an emty line or starts at a line end
|
||||
if (descriptions[i].LayoutBounds.Width == 0 && descriptions.Length > 1)
|
||||
{
|
||||
var bounds = descriptions[i].LayoutBounds;
|
||||
descriptions[i].LayoutBounds = new Rect { Width = fontSize / 4, Height = bounds.Height, X = bounds.X, Y = bounds.Y };
|
||||
}
|
||||
|
||||
args.DrawingSession.FillRectangle(Utils.CreateRect(descriptions[i].LayoutBounds, marginLeft, marginTop), selectionColor);
|
||||
}
|
||||
return new TextSelection(SelectionStart, SelectionLength, new CursorPosition(SelectionStartPosition), new CursorPosition(SelectionEndPosition));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
//returns whether the pointer is over a selection
|
||||
public bool PointerIsOverSelection(Point pointerPosition, TextSelection selection, CanvasTextLayout textLayout)
|
||||
{
|
||||
if (textLayout == null || selection == null)
|
||||
return false;
|
||||
|
||||
CanvasTextLayoutRegion[] regions = textLayout.GetCharacterRegions(selection.Index, selection.Length);
|
||||
for (int i = 0; i < regions.Length; i++)
|
||||
{
|
||||
if (regions[i].LayoutBounds.Contains(pointerPosition))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool CursorIsInSelection(CursorPosition cursorPosition, TextSelection textSelection)
|
||||
{
|
||||
if (textSelection == null)
|
||||
return false;
|
||||
|
||||
textSelection = Selection.OrderTextSelection(textSelection);
|
||||
|
||||
//Cursorposition is smaller than the start of selection
|
||||
if (textSelection.StartPosition.LineNumber > cursorPosition.LineNumber)
|
||||
return false;
|
||||
|
||||
//Selectionend is smaller than Cursorposition -> not in selection
|
||||
if (textSelection.EndPosition.LineNumber < cursorPosition.LineNumber)
|
||||
return false;
|
||||
|
||||
//Selection-start line equals Cursor line:
|
||||
if (cursorPosition.LineNumber == textSelection.StartPosition.LineNumber)
|
||||
return cursorPosition.CharacterPosition > textSelection.StartPosition.CharacterPosition;
|
||||
|
||||
//Selection-end line equals Cursor line
|
||||
else if (cursorPosition.LineNumber == textSelection.EndPosition.LineNumber)
|
||||
return cursorPosition.CharacterPosition < textSelection.EndPosition.CharacterPosition;
|
||||
return true;
|
||||
}
|
||||
|
||||
//Clear the selection
|
||||
public void ClearSelection()
|
||||
{
|
||||
HasSelection = false;
|
||||
IsSelecting = false;
|
||||
SelectionEndPosition = null;
|
||||
SelectionStartPosition = null;
|
||||
}
|
||||
|
||||
public void SetSelection(TextSelection selection)
|
||||
{
|
||||
if (selection == null)
|
||||
return;
|
||||
|
||||
SetSelection(selection.StartPosition, selection.EndPosition);
|
||||
}
|
||||
public void SetSelection(CursorPosition startPosition, CursorPosition endPosition)
|
||||
{
|
||||
IsSelecting = true;
|
||||
SelectionStartPosition = startPosition;
|
||||
SelectionEndPosition = endPosition;
|
||||
IsSelecting = false;
|
||||
HasSelection = true;
|
||||
}
|
||||
public void SetSelectionStart(CursorPosition startPosition)
|
||||
{
|
||||
IsSelecting = true;
|
||||
SelectionStartPosition = startPosition;
|
||||
IsSelecting = false;
|
||||
HasSelection = true;
|
||||
}
|
||||
public void SetSelectionEnd(CursorPosition endPosition)
|
||||
{
|
||||
IsSelecting = true;
|
||||
SelectionEndPosition = endPosition;
|
||||
IsSelecting = false;
|
||||
HasSelection = true;
|
||||
}
|
||||
}
|
||||
}
|
73
TextControlBox/Renderer/SyntaxHighlightingRenderer.cs
Normal file
73
TextControlBox/Renderer/SyntaxHighlightingRenderer.cs
Normal file
|
@ -0,0 +1,73 @@
|
|||
using Microsoft.Graphics.Canvas.Text;
|
||||
using Microsoft.UI.Xaml;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Text.RegularExpressions;
|
||||
using Windows.UI.Text;
|
||||
using Windows.UI.Xaml;
|
||||
|
||||
namespace TextControlBoxNS.Renderer
|
||||
{
|
||||
internal class SyntaxHighlightingRenderer
|
||||
{
|
||||
public static FontWeight BoldFont = new FontWeight { Weight = 600 };
|
||||
public static FontStyle ItalicFont = FontStyle.Italic;
|
||||
|
||||
public static void UpdateSyntaxHighlighting(CanvasTextLayout drawnTextLayout, ApplicationTheme theme, CodeLanguage codeLanguage, bool syntaxHighlighting, string renderedText)
|
||||
{
|
||||
if (codeLanguage == null || !syntaxHighlighting)
|
||||
return;
|
||||
|
||||
var highlights = codeLanguage.Highlights;
|
||||
for (int i = 0; i < highlights.Length; i++)
|
||||
{
|
||||
var matches = Regex.Matches(renderedText, highlights[i].Pattern, RegexOptions.Compiled);
|
||||
var highlight = highlights[i];
|
||||
var color = theme == ApplicationTheme.Light ? highlight.ColorLight_Clr : highlight.ColorDark_Clr;
|
||||
|
||||
for (int j = 0; j < matches.Count; j++)
|
||||
{
|
||||
var match = matches[j];
|
||||
int index = match.Index;
|
||||
int length = match.Length;
|
||||
drawnTextLayout.SetColor(index, length, color);
|
||||
if (highlight.CodeStyle != null)
|
||||
{
|
||||
if (highlight.CodeStyle.Italic)
|
||||
drawnTextLayout.SetFontStyle(index, length, ItalicFont);
|
||||
if (highlight.CodeStyle.Bold)
|
||||
drawnTextLayout.SetFontWeight(index, length, BoldFont);
|
||||
if (highlight.CodeStyle.Underlined)
|
||||
drawnTextLayout.SetUnderline(index, length, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static JsonLoadResult GetCodeLanguageFromJson(string json)
|
||||
{
|
||||
try
|
||||
{
|
||||
var jsonCodeLanguage = JsonConvert.DeserializeObject<JsonCodeLanguage>(json);
|
||||
//Apply the filter as an array
|
||||
var codelanguage = new CodeLanguage
|
||||
{
|
||||
Author = jsonCodeLanguage.Author,
|
||||
Description = jsonCodeLanguage.Description,
|
||||
Highlights = jsonCodeLanguage.Highlights,
|
||||
Name = jsonCodeLanguage.Name,
|
||||
Filter = jsonCodeLanguage.Filter.Split("|", StringSplitOptions.RemoveEmptyEntries),
|
||||
};
|
||||
return new JsonLoadResult(true, codelanguage);
|
||||
}
|
||||
catch (JsonReaderException)
|
||||
{
|
||||
return new JsonLoadResult(false, null);
|
||||
}
|
||||
catch (JsonSerializationException)
|
||||
{
|
||||
return new JsonLoadResult(false, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
38
TextControlBox/Text/AutoPairing.cs
Normal file
38
TextControlBox/Text/AutoPairing.cs
Normal file
|
@ -0,0 +1,38 @@
|
|||
using System.Linq;
|
||||
|
||||
namespace TextControlBoxNS.Text
|
||||
{
|
||||
internal class AutoPairing
|
||||
{
|
||||
public static (string text, int length) AutoPair(TextControlBox textbox, string inputtext)
|
||||
{
|
||||
if (!textbox.DoAutoPairing || inputtext.Length != 1 || textbox.CodeLanguage == null || textbox.CodeLanguage.AutoPairingPair == null)
|
||||
return (inputtext, inputtext.Length);
|
||||
|
||||
var res = textbox.CodeLanguage.AutoPairingPair.Where(x => x.Matches(inputtext));
|
||||
if (res.Count() == 0)
|
||||
return (inputtext, inputtext.Length);
|
||||
|
||||
if (res.ElementAt(0) is AutoPairingPair pair)
|
||||
return (inputtext + pair.Pair, inputtext.Length);
|
||||
return (inputtext, inputtext.Length);
|
||||
}
|
||||
|
||||
public static string AutoPairSelection(TextControlBox textbox, string inputtext)
|
||||
{
|
||||
if (!textbox.DoAutoPairing || inputtext.Length != 1 || textbox.CodeLanguage == null || textbox.CodeLanguage.AutoPairingPair == null)
|
||||
return inputtext;
|
||||
|
||||
var res = textbox.CodeLanguage.AutoPairingPair.Where(x => x.Value.Equals(inputtext));
|
||||
if (res.Count() == 0)
|
||||
return inputtext;
|
||||
|
||||
if (res.ElementAt(0) is AutoPairingPair pair)
|
||||
{
|
||||
textbox.SurroundSelectionWith(inputtext, pair.Pair);
|
||||
return null;
|
||||
}
|
||||
return inputtext;
|
||||
}
|
||||
}
|
||||
}
|
170
TextControlBox/Text/Cursor.cs
Normal file
170
TextControlBox/Text/Cursor.cs
Normal file
|
@ -0,0 +1,170 @@
|
|||
using Collections.Pooled;
|
||||
using System;
|
||||
using TextControlBoxNS.Extensions;
|
||||
using TextControlBoxNS.Helper;
|
||||
|
||||
namespace TextControlBoxNS.Text
|
||||
{
|
||||
internal class Cursor
|
||||
{
|
||||
private static int CheckIndex(string str, int index) => Math.Clamp(index, 0, str.Length - 1);
|
||||
public static int CursorPositionToIndex(PooledList<string> totalLines, CursorPosition cursorPosition)
|
||||
{
|
||||
int cursorIndex = cursorPosition.CharacterPosition;
|
||||
int lineNumber = cursorPosition.LineNumber < totalLines.Count ? cursorIndex : totalLines.Count - 1;
|
||||
for (int i = 0; i < lineNumber; i++)
|
||||
{
|
||||
cursorIndex += totalLines.GetLineLength(i) + 1;
|
||||
}
|
||||
return cursorIndex;
|
||||
}
|
||||
public static bool Equals(CursorPosition curPos1, CursorPosition curPos2)
|
||||
{
|
||||
if (curPos1 == null || curPos2 == null)
|
||||
return false;
|
||||
|
||||
if (curPos1.LineNumber == curPos2.LineNumber)
|
||||
return curPos1.CharacterPosition == curPos2.CharacterPosition;
|
||||
return false;
|
||||
}
|
||||
|
||||
//Calculate the number of characters from the cursorposition to the next character or digit to the left and to the right
|
||||
public static int CalculateStepsToMoveLeft2(string currentLine, int cursorCharPosition)
|
||||
{
|
||||
if (currentLine.Length == 0)
|
||||
return 0;
|
||||
|
||||
int stepsToMove = 0;
|
||||
for (int i = cursorCharPosition - 1; i >= 0; i--)
|
||||
{
|
||||
char currentCharacter = currentLine[CheckIndex(currentLine, i)];
|
||||
if (char.IsLetterOrDigit(currentCharacter) || currentCharacter == '_')
|
||||
stepsToMove++;
|
||||
else if (i == cursorCharPosition - 1 && char.IsWhiteSpace(currentCharacter))
|
||||
return 0;
|
||||
else
|
||||
break;
|
||||
}
|
||||
return stepsToMove;
|
||||
}
|
||||
public static int CalculateStepsToMoveRight2(string currentLine, int cursorCharPosition)
|
||||
{
|
||||
if (currentLine.Length == 0)
|
||||
return 0;
|
||||
|
||||
int stepsToMove = 0;
|
||||
for (int i = cursorCharPosition; i < currentLine.Length; i++)
|
||||
{
|
||||
char currentCharacter = currentLine[CheckIndex(currentLine, i)];
|
||||
if (char.IsLetterOrDigit(currentCharacter) || currentCharacter == '_')
|
||||
stepsToMove++;
|
||||
else if (i == cursorCharPosition && char.IsWhiteSpace(currentCharacter))
|
||||
return 0;
|
||||
else
|
||||
break;
|
||||
}
|
||||
return stepsToMove;
|
||||
}
|
||||
|
||||
//Calculates how many characters the cursor needs to move if control is pressed
|
||||
//Returns 1 when control is not pressed
|
||||
public static int CalculateStepsToMoveLeft(string currentLine, int cursorCharPosition)
|
||||
{
|
||||
if (!Utils.IsKeyPressed(Windows.System.VirtualKey.Control))
|
||||
return 1;
|
||||
|
||||
int stepsToMove = 0;
|
||||
for (int i = cursorCharPosition - 1; i >= 0; i--)
|
||||
{
|
||||
char CurrentCharacter = currentLine[CheckIndex(currentLine, i)];
|
||||
if (char.IsLetterOrDigit(CurrentCharacter) || CurrentCharacter == '_')
|
||||
stepsToMove++;
|
||||
else if (i == cursorCharPosition - 1 && char.IsWhiteSpace(CurrentCharacter))
|
||||
stepsToMove++;
|
||||
else
|
||||
break;
|
||||
}
|
||||
//If it ignores the ControlKey return the real value of stepsToMove otherwise
|
||||
//return 1 if stepsToMove is 0
|
||||
return stepsToMove == 0 ? 1 : stepsToMove;
|
||||
}
|
||||
public static int CalculateStepsToMoveRight(string currentLine, int cursorCharPosition)
|
||||
{
|
||||
if (!Utils.IsKeyPressed(Windows.System.VirtualKey.Control))
|
||||
return 1;
|
||||
|
||||
int stepsToMove = 0;
|
||||
for (int i = cursorCharPosition; i < currentLine.Length; i++)
|
||||
{
|
||||
char CurrentCharacter = currentLine[CheckIndex(currentLine, i)];
|
||||
if (char.IsLetterOrDigit(CurrentCharacter) || CurrentCharacter == '_')
|
||||
stepsToMove++;
|
||||
else if (i == cursorCharPosition && char.IsWhiteSpace(CurrentCharacter))
|
||||
stepsToMove++;
|
||||
else
|
||||
break;
|
||||
}
|
||||
//If it ignores the ControlKey return the real value of stepsToMove otherwise
|
||||
//return 1 if stepsToMove is 0
|
||||
return stepsToMove == 0 ? 1 : stepsToMove;
|
||||
}
|
||||
|
||||
//Move cursor:
|
||||
public static void MoveLeft(CursorPosition currentCursorPosition, PooledList<string> totalLines, string currentLine)
|
||||
{
|
||||
if (currentCursorPosition.LineNumber < 0)
|
||||
return;
|
||||
|
||||
int currentLineLength = totalLines.GetLineLength(currentCursorPosition.LineNumber);
|
||||
if (currentCursorPosition.CharacterPosition == 0 && currentCursorPosition.LineNumber > 0)
|
||||
{
|
||||
currentCursorPosition.CharacterPosition = totalLines.GetLineLength(currentCursorPosition.LineNumber - 1);
|
||||
currentCursorPosition.LineNumber -= 1;
|
||||
}
|
||||
else if (currentCursorPosition.CharacterPosition > currentLineLength)
|
||||
currentCursorPosition.CharacterPosition = currentLineLength - 1;
|
||||
else if (currentCursorPosition.CharacterPosition > 0)
|
||||
currentCursorPosition.CharacterPosition -= CalculateStepsToMoveLeft(currentLine, currentCursorPosition.CharacterPosition);
|
||||
}
|
||||
public static void MoveRight(CursorPosition currentCursorPosition, PooledList<string> totalLines, string currentLine)
|
||||
{
|
||||
int lineLength = totalLines.GetLineLength(currentCursorPosition.LineNumber);
|
||||
|
||||
if (currentCursorPosition.LineNumber > totalLines.Count - 1)
|
||||
return;
|
||||
|
||||
if (currentCursorPosition.CharacterPosition == lineLength && currentCursorPosition.LineNumber < totalLines.Count - 1)
|
||||
{
|
||||
currentCursorPosition.CharacterPosition = 0;
|
||||
currentCursorPosition.LineNumber += 1;
|
||||
}
|
||||
else if (currentCursorPosition.CharacterPosition < lineLength)
|
||||
currentCursorPosition.CharacterPosition += CalculateStepsToMoveRight(currentLine, currentCursorPosition.CharacterPosition);
|
||||
|
||||
if (currentCursorPosition.CharacterPosition > lineLength)
|
||||
currentCursorPosition.CharacterPosition = lineLength;
|
||||
}
|
||||
public static CursorPosition MoveDown(CursorPosition currentCursorPosition, int totalLinesLength)
|
||||
{
|
||||
CursorPosition returnValue = new CursorPosition(currentCursorPosition);
|
||||
if (currentCursorPosition.LineNumber < totalLinesLength - 1)
|
||||
returnValue = CursorPosition.ChangeLineNumber(currentCursorPosition, currentCursorPosition.LineNumber + 1);
|
||||
return returnValue;
|
||||
}
|
||||
public static CursorPosition MoveUp(CursorPosition currentCursorPosition)
|
||||
{
|
||||
CursorPosition returnValue = new CursorPosition(currentCursorPosition);
|
||||
if (currentCursorPosition.LineNumber > 0)
|
||||
returnValue = CursorPosition.ChangeLineNumber(returnValue, currentCursorPosition.LineNumber - 1);
|
||||
return returnValue;
|
||||
}
|
||||
public static void MoveToLineEnd(CursorPosition cursorPosition, string currentLine)
|
||||
{
|
||||
cursorPosition.CharacterPosition = currentLine.Length;
|
||||
}
|
||||
public static void MoveToLineStart(CursorPosition cursorPosition)
|
||||
{
|
||||
cursorPosition.CharacterPosition = 0;
|
||||
}
|
||||
}
|
||||
}
|
31
TextControlBox/Text/LineEndings.cs
Normal file
31
TextControlBox/Text/LineEndings.cs
Normal file
|
@ -0,0 +1,31 @@
|
|||
using System;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace TextControlBoxNS.Text
|
||||
{
|
||||
internal class LineEndings
|
||||
{
|
||||
public static string LineEndingToString(LineEnding lineEnding)
|
||||
{
|
||||
return
|
||||
lineEnding == LineEnding.LF ? "\n" :
|
||||
lineEnding == LineEnding.CRLF ? "\r\n" :
|
||||
"\r";
|
||||
}
|
||||
public static LineEnding FindLineEnding(string text)
|
||||
{
|
||||
if (text.IndexOf("\r\n", StringComparison.Ordinal) > -1)
|
||||
return LineEnding.CRLF;
|
||||
else if (text.IndexOf("\n", StringComparison.Ordinal) > -1)
|
||||
return LineEnding.LF;
|
||||
else if (text.IndexOf("\r", StringComparison.Ordinal) > -1)
|
||||
return LineEnding.CR;
|
||||
return LineEnding.CRLF;
|
||||
}
|
||||
public static string CleanLineEndings(string text, LineEnding lineEnding)
|
||||
{
|
||||
return Regex.Replace(text, "(\r\n|\r|\n)", LineEndingToString(lineEnding));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
35
TextControlBox/Text/MoveLine.cs
Normal file
35
TextControlBox/Text/MoveLine.cs
Normal file
|
@ -0,0 +1,35 @@
|
|||
using Collections.Pooled;
|
||||
|
||||
namespace TextControlBoxNS.Text
|
||||
{
|
||||
internal class MoveLine
|
||||
{
|
||||
public static void Move(PooledList<string> totalLines, TextSelection selection, CursorPosition cursorposition, UndoRedo undoredo, string newLineCharacter, LineMoveDirection direction)
|
||||
{
|
||||
if (selection != null)
|
||||
return;
|
||||
|
||||
//move down:
|
||||
if (direction == LineMoveDirection.Down)
|
||||
{
|
||||
if (cursorposition.LineNumber >= totalLines.Count - 1)
|
||||
return;
|
||||
|
||||
undoredo.RecordUndoAction(() =>
|
||||
{
|
||||
Selection.MoveLinesDown(totalLines, selection, cursorposition);
|
||||
}, totalLines, cursorposition.LineNumber, 2, 2, newLineCharacter, cursorposition);
|
||||
return;
|
||||
}
|
||||
|
||||
//move up:
|
||||
if (cursorposition.LineNumber <= 0)
|
||||
return;
|
||||
|
||||
undoredo.RecordUndoAction(() =>
|
||||
{
|
||||
Selection.MoveLinesUp(totalLines, selection, cursorposition);
|
||||
}, totalLines, cursorposition.LineNumber - 1, 2, 2, newLineCharacter, cursorposition);
|
||||
}
|
||||
}
|
||||
}
|
527
TextControlBox/Text/Selection.cs
Normal file
527
TextControlBox/Text/Selection.cs
Normal file
|
@ -0,0 +1,527 @@
|
|||
using Collections.Pooled;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using TextControlBoxNS.Extensions;
|
||||
using TextControlBoxNS.Helper;
|
||||
using TextControlBoxNS.Renderer;
|
||||
|
||||
namespace TextControlBoxNS.Text
|
||||
{
|
||||
internal class Selection
|
||||
{
|
||||
public static bool Equals(TextSelection sel1, TextSelection sel2)
|
||||
{
|
||||
if (sel1 == null || sel2 == null)
|
||||
return false;
|
||||
|
||||
return Cursor.Equals(sel1.StartPosition, sel2.StartPosition) &&
|
||||
Cursor.Equals(sel1.EndPosition, sel2.EndPosition);
|
||||
}
|
||||
|
||||
//Order the selection that StartPosition is always smaller than EndPosition
|
||||
public static TextSelection OrderTextSelection(TextSelection selection)
|
||||
{
|
||||
if (selection == null)
|
||||
return selection;
|
||||
|
||||
int startLine = Math.Min(selection.StartPosition.LineNumber, selection.EndPosition.LineNumber);
|
||||
int endLine = Math.Max(selection.StartPosition.LineNumber, selection.EndPosition.LineNumber);
|
||||
int startPosition;
|
||||
int endPosition;
|
||||
if (startLine == endLine)
|
||||
{
|
||||
startPosition = Math.Min(selection.StartPosition.CharacterPosition, selection.EndPosition.CharacterPosition);
|
||||
endPosition = Math.Max(selection.StartPosition.CharacterPosition, selection.EndPosition.CharacterPosition);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (selection.StartPosition.LineNumber < selection.EndPosition.LineNumber)
|
||||
{
|
||||
endPosition = selection.EndPosition.CharacterPosition;
|
||||
startPosition = selection.StartPosition.CharacterPosition;
|
||||
}
|
||||
else
|
||||
{
|
||||
endPosition = selection.StartPosition.CharacterPosition;
|
||||
startPosition = selection.EndPosition.CharacterPosition;
|
||||
}
|
||||
}
|
||||
|
||||
return new TextSelection(selection.Index, selection.Length, new CursorPosition(startPosition, startLine), new CursorPosition(endPosition, endLine));
|
||||
}
|
||||
|
||||
public static bool WholeTextSelected(TextSelection selection, PooledList<string> totalLines)
|
||||
{
|
||||
if (selection == null)
|
||||
return false;
|
||||
|
||||
var sel = OrderTextSelection(selection);
|
||||
return Utils.CursorPositionsAreEqual(sel.StartPosition, new CursorPosition(0, 0)) &&
|
||||
Utils.CursorPositionsAreEqual(sel.EndPosition, new CursorPosition(totalLines.GetLineLength(-1), totalLines.Count - 1));
|
||||
}
|
||||
|
||||
//returns whether the selection starts at character zero and ends
|
||||
public static bool WholeLinesAreSelected(TextSelection selection, PooledList<string> totalLines)
|
||||
{
|
||||
if (selection == null)
|
||||
return false;
|
||||
|
||||
var sel = OrderTextSelection(selection);
|
||||
return Utils.CursorPositionsAreEqual(sel.StartPosition, new CursorPosition(0, sel.StartPosition.LineNumber)) &&
|
||||
Utils.CursorPositionsAreEqual(sel.EndPosition, new CursorPosition(totalLines.GetLineText(sel.EndPosition.LineNumber).Length, sel.EndPosition.LineNumber));
|
||||
}
|
||||
|
||||
public static CursorPosition GetMax(CursorPosition pos1, CursorPosition pos2)
|
||||
{
|
||||
if (pos1.LineNumber == pos2.LineNumber)
|
||||
return pos1.CharacterPosition > pos2.CharacterPosition ? pos1 : pos2;
|
||||
return pos1.LineNumber > pos2.LineNumber ? pos1 : pos2;
|
||||
}
|
||||
public static CursorPosition GetMin(CursorPosition pos1, CursorPosition pos2)
|
||||
{
|
||||
if (pos1.LineNumber == pos2.LineNumber)
|
||||
return pos1.CharacterPosition > pos2.CharacterPosition ? pos2 : pos1;
|
||||
return pos1.LineNumber > pos2.LineNumber ? pos2 : pos1;
|
||||
}
|
||||
public static CursorPosition GetMin(TextSelection selection)
|
||||
{
|
||||
return GetMin(selection.StartPosition, selection.EndPosition);
|
||||
}
|
||||
public static CursorPosition GetMax(TextSelection selection)
|
||||
{
|
||||
return GetMax(selection.StartPosition, selection.EndPosition);
|
||||
}
|
||||
|
||||
public static CursorPosition InsertText(TextSelection selection, CursorPosition cursorPosition, PooledList<string> totalLines, string text, string newLineCharacter)
|
||||
{
|
||||
if (selection != null)
|
||||
return Replace(selection, totalLines, text, newLineCharacter);
|
||||
|
||||
string curLine = totalLines.GetLineText(cursorPosition.LineNumber);
|
||||
|
||||
string[] lines = text.Split(newLineCharacter);
|
||||
|
||||
//Singleline
|
||||
if (lines.Length == 1 && text != string.Empty)
|
||||
{
|
||||
text = text.Replace("\r", string.Empty).Replace("\n", string.Empty);
|
||||
totalLines.SetLineText(-1, totalLines.GetLineText(-1).AddText(text, cursorPosition.CharacterPosition));
|
||||
cursorPosition.AddToCharacterPos(text.Length);
|
||||
return cursorPosition;
|
||||
}
|
||||
|
||||
//Multiline:
|
||||
int curPos = cursorPosition.CharacterPosition;
|
||||
if (curPos > curLine.Length)
|
||||
curPos = curLine.Length;
|
||||
|
||||
//GEt the text in front of the cursor
|
||||
string textInFrontOfCursor = curLine.Substring(0, curPos < 0 ? 0 : curPos);
|
||||
//Get the text behind the cursor
|
||||
string textBehindCursor = curLine.SafeRemove(0, curPos < 0 ? 0 : curPos);
|
||||
|
||||
totalLines.DeleteAt(cursorPosition.LineNumber);
|
||||
totalLines.InsertOrAddRange(ListHelper.CreateLines(lines, 0, textInFrontOfCursor, textBehindCursor), cursorPosition.LineNumber);
|
||||
|
||||
return new CursorPosition(cursorPosition.CharacterPosition + lines.Length > 0 ? lines[lines.Length - 1].Length : 0, cursorPosition.LineNumber + lines.Length - 1);
|
||||
}
|
||||
|
||||
public static CursorPosition Replace(TextSelection selection, PooledList<string> totalLines, string text, string newLineCharacter)
|
||||
{
|
||||
//Just delete the text if the string is emty
|
||||
if (text == "")
|
||||
return Remove(selection, totalLines);
|
||||
|
||||
selection = OrderTextSelection(selection);
|
||||
int startLine = selection.StartPosition.LineNumber;
|
||||
int endLine = selection.EndPosition.LineNumber;
|
||||
int startPosition = selection.StartPosition.CharacterPosition;
|
||||
int endPosition = selection.EndPosition.CharacterPosition;
|
||||
|
||||
string[] lines = text.Split(newLineCharacter);
|
||||
string start_Line = totalLines.GetLineText(startLine);
|
||||
|
||||
//Selection is singleline and text to paste is also singleline
|
||||
if (startLine == endLine && lines.Length == 1)
|
||||
{
|
||||
start_Line =
|
||||
(startPosition == 0 && endPosition == totalLines.GetLineLength(endLine)) ?
|
||||
"" :
|
||||
start_Line.SafeRemove(startPosition, endPosition - startPosition
|
||||
);
|
||||
|
||||
totalLines.SetLineText(startLine, start_Line.AddText(text, startPosition));
|
||||
|
||||
return new CursorPosition(startPosition + text.Length, selection.StartPosition.LineNumber);
|
||||
}
|
||||
else if (startLine == endLine && lines.Length > 1 && (startPosition != 0 && endPosition != start_Line.Length))
|
||||
{
|
||||
string textTo = start_Line == "" ? "" : startPosition >= start_Line.Length ? start_Line : start_Line.Safe_Substring(0, startPosition);
|
||||
string textFrom = start_Line == "" ? "" : endPosition >= start_Line.Length ? start_Line : start_Line.Safe_Substring(endPosition);
|
||||
|
||||
totalLines.SetLineText(startLine, (textTo + lines[0]));
|
||||
totalLines.InsertOrAddRange(ListHelper.CreateLines(lines, 1, "", textFrom), startLine + 1);
|
||||
|
||||
return new CursorPosition(endPosition + text.Length, startLine + lines.Length - 1);
|
||||
}
|
||||
else if (WholeTextSelected(selection, totalLines))
|
||||
{
|
||||
if (lines.Length < totalLines.Count)
|
||||
{
|
||||
ListHelper.Clear(totalLines);
|
||||
totalLines.InsertOrAddRange(lines, 0);
|
||||
}
|
||||
else
|
||||
ReplaceLines(totalLines, 0, totalLines.Count, lines);
|
||||
|
||||
return new CursorPosition(totalLines.GetLineLength(-1), totalLines.Count - 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
string end_Line = totalLines.GetLineText(endLine);
|
||||
|
||||
//All lines are selected from start to finish
|
||||
if (startPosition == 0 && endPosition == end_Line.Length)
|
||||
{
|
||||
totalLines.Safe_RemoveRange(startLine, endLine - startLine + 1);
|
||||
totalLines.InsertOrAddRange(lines, startLine);
|
||||
}
|
||||
//Only the startline is completely selected
|
||||
else if (startPosition == 0 && endPosition != end_Line.Length)
|
||||
{
|
||||
totalLines.SetLineText(endLine, end_Line.Substring(endPosition).AddToStart(lines[lines.Length - 1]));
|
||||
|
||||
totalLines.Safe_RemoveRange(startLine, endLine - startLine);
|
||||
totalLines.InsertOrAddRange(lines.Take(lines.Length - 1), startLine);
|
||||
}
|
||||
//Only the endline is completely selected
|
||||
else if (startPosition != 0 && endPosition == end_Line.Length)
|
||||
{
|
||||
totalLines.SetLineText(startLine, start_Line.SafeRemove(startPosition).AddToEnd(lines[0]));
|
||||
|
||||
totalLines.Safe_RemoveRange(startLine + 1, endLine - startLine);
|
||||
totalLines.InsertOrAddRange(lines.Skip(1), startLine + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
//Delete the selected parts
|
||||
start_Line = start_Line.SafeRemove(startPosition);
|
||||
end_Line = end_Line.Safe_Substring(endPosition);
|
||||
|
||||
//Only one line to insert
|
||||
if (lines.Length == 1)
|
||||
{
|
||||
totalLines.SetLineText(startLine, start_Line.AddToEnd(lines[0] + end_Line));
|
||||
totalLines.Safe_RemoveRange(startLine + 1, endLine - startLine < 0 ? 0 : endLine - startLine);
|
||||
}
|
||||
else
|
||||
{
|
||||
totalLines.SetLineText(startLine, start_Line.AddToEnd(lines[0]));
|
||||
totalLines.SetLineText(endLine, end_Line.AddToStart(lines[lines.Length - 1]));
|
||||
|
||||
totalLines.Safe_RemoveRange(startLine + 1, endLine - startLine - 1 < 0 ? 0 : endLine - startLine - 1);
|
||||
if (lines.Length > 2)
|
||||
totalLines.InsertOrAddRange(lines.GetLines(1, lines.Length - 2), startLine + 1);
|
||||
}
|
||||
}
|
||||
return new CursorPosition(start_Line.Length + end_Line.Length - 1, startLine + lines.Length - 1);
|
||||
}
|
||||
}
|
||||
|
||||
public static CursorPosition Remove(TextSelection selection, PooledList<string> totalLines)
|
||||
{
|
||||
selection = OrderTextSelection(selection);
|
||||
int startLine = selection.StartPosition.LineNumber;
|
||||
int endLine = selection.EndPosition.LineNumber;
|
||||
int startPosition = selection.StartPosition.CharacterPosition;
|
||||
int endPosition = selection.EndPosition.CharacterPosition;
|
||||
|
||||
string start_Line = totalLines.GetLineText(startLine);
|
||||
string end_Line = totalLines.GetLineText(endLine);
|
||||
|
||||
if (startLine == endLine)
|
||||
{
|
||||
totalLines.SetLineText(startLine,
|
||||
(startPosition == 0 && endPosition == end_Line.Length ?
|
||||
"" :
|
||||
start_Line.SafeRemove(startPosition, endPosition - startPosition))
|
||||
);
|
||||
}
|
||||
else if (WholeTextSelected(selection, totalLines))
|
||||
{
|
||||
ListHelper.Clear(totalLines, true);
|
||||
return new CursorPosition(0, totalLines.Count - 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
//Whole lines are selected from start to finish
|
||||
if (startPosition == 0 && endPosition == end_Line.Length)
|
||||
{
|
||||
totalLines.Safe_RemoveRange(startLine, endLine - startLine + 1);
|
||||
}
|
||||
//Only the startline is completely selected
|
||||
else if (startPosition == 0 && endPosition != end_Line.Length)
|
||||
{
|
||||
totalLines.SetLineText(endLine, end_Line.Safe_Substring(endPosition));
|
||||
totalLines.Safe_RemoveRange(startLine, endLine - startLine);
|
||||
}
|
||||
//Only the endline is completely selected
|
||||
else if (startPosition != 0 && endPosition == end_Line.Length)
|
||||
{
|
||||
totalLines.SetLineText(startLine, start_Line.SafeRemove(startPosition));
|
||||
totalLines.Safe_RemoveRange(startLine + 1, endLine - startLine);
|
||||
}
|
||||
//Both startline and endline are not completely selected
|
||||
else
|
||||
{
|
||||
totalLines.SetLineText(startLine, start_Line.SafeRemove(startPosition) + end_Line.Safe_Substring(endPosition));
|
||||
totalLines.Safe_RemoveRange(startLine + 1, endLine - startLine);
|
||||
}
|
||||
}
|
||||
|
||||
if (totalLines.Count == 0)
|
||||
totalLines.AddLine();
|
||||
|
||||
return new CursorPosition(startPosition, startLine);
|
||||
}
|
||||
|
||||
public static TextSelectionPosition GetIndexOfSelection(PooledList<string> totalLines, TextSelection selection)
|
||||
{
|
||||
var sel = OrderTextSelection(selection);
|
||||
int startIndex = Cursor.CursorPositionToIndex(totalLines, sel.StartPosition);
|
||||
int endIndex = Cursor.CursorPositionToIndex(totalLines, sel.EndPosition);
|
||||
|
||||
if (endIndex > startIndex)
|
||||
return new TextSelectionPosition(Math.Min(startIndex, endIndex), endIndex - startIndex);
|
||||
else
|
||||
return new TextSelectionPosition(Math.Min(startIndex, endIndex), startIndex - endIndex);
|
||||
}
|
||||
|
||||
public static TextSelection GetSelectionFromPosition(PooledList<string> totalLines, int startPosition, int length, int numberOfCharacters)
|
||||
{
|
||||
TextSelection returnValue = new TextSelection();
|
||||
|
||||
if (startPosition + length > numberOfCharacters)
|
||||
{
|
||||
if (startPosition > numberOfCharacters)
|
||||
{
|
||||
startPosition = numberOfCharacters;
|
||||
length = 0;
|
||||
}
|
||||
else
|
||||
length = numberOfCharacters - startPosition;
|
||||
}
|
||||
|
||||
void GetIndexInLine(int currentIndex, int currentTotalLength)
|
||||
{
|
||||
int position = Math.Abs(currentTotalLength - startPosition);
|
||||
|
||||
returnValue.StartPosition =
|
||||
new CursorPosition(position, currentIndex);
|
||||
|
||||
if (length == 0)
|
||||
returnValue.EndPosition = new CursorPosition(returnValue.StartPosition);
|
||||
else
|
||||
{
|
||||
int lengthCount = 0;
|
||||
for (int i = currentIndex; i < totalLines.Count; i++)
|
||||
{
|
||||
int lineLength = totalLines[i].Length + 1;
|
||||
if (lengthCount + lineLength > length)
|
||||
{
|
||||
returnValue.EndPosition = new CursorPosition(Math.Abs(lengthCount - length) + position, i);
|
||||
break;
|
||||
}
|
||||
lengthCount += lineLength;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Get the Length
|
||||
int totalLength = 0;
|
||||
for (int i = 0; i < totalLines.Count; i++)
|
||||
{
|
||||
int lineLength = totalLines[i].Length + 1;
|
||||
if (totalLength + lineLength > startPosition)
|
||||
{
|
||||
GetIndexInLine(i, totalLength);
|
||||
break;
|
||||
}
|
||||
|
||||
totalLength += lineLength;
|
||||
}
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
public static string GetSelectedText(PooledList<string> totalLines, TextSelection textSelection, int currentLineIndex, string newLineCharacter)
|
||||
{
|
||||
//return the current line, if no text is selected:
|
||||
if (textSelection == null)
|
||||
return totalLines.GetLineText(currentLineIndex) + newLineCharacter;
|
||||
|
||||
int startLine = Math.Min(textSelection.StartPosition.LineNumber, textSelection.EndPosition.LineNumber);
|
||||
int endLine = Math.Max(textSelection.StartPosition.LineNumber, textSelection.EndPosition.LineNumber);
|
||||
int endIndex = Math.Max(textSelection.StartPosition.CharacterPosition, textSelection.EndPosition.CharacterPosition);
|
||||
int startIndex = Math.Min(textSelection.StartPosition.CharacterPosition, textSelection.EndPosition.CharacterPosition);
|
||||
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
|
||||
if (startLine == endLine) //Singleline
|
||||
{
|
||||
string line = totalLines.GetLineText(startLine < totalLines.Count ? startLine : totalLines.Count - 1);
|
||||
|
||||
if (startIndex == 0 && endIndex != line.Length)
|
||||
stringBuilder.Append(line.SafeRemove(endIndex));
|
||||
else if (endIndex == line.Length && startIndex != 0)
|
||||
stringBuilder.Append(line.Safe_Substring(startIndex));
|
||||
else if (startIndex == 0 && endIndex == line.Length)
|
||||
stringBuilder.Append(line);
|
||||
else stringBuilder.Append(line.SafeRemove(endIndex).Substring(startIndex));
|
||||
}
|
||||
else if (WholeTextSelected(textSelection, totalLines))
|
||||
{
|
||||
stringBuilder.Append(ListHelper.GetLinesAsString(totalLines, newLineCharacter));
|
||||
}
|
||||
else //Multiline
|
||||
{
|
||||
//StartLine
|
||||
stringBuilder.Append(totalLines.GetLineText(startLine).Substring(startIndex) + newLineCharacter);
|
||||
|
||||
//Other lines
|
||||
if (endLine - startLine > 1)
|
||||
stringBuilder.Append(totalLines.GetLines(startLine + 1, endLine - startLine - 1).GetString(newLineCharacter) + newLineCharacter);
|
||||
|
||||
//Endline
|
||||
string currentLine = totalLines.GetLineText(endLine);
|
||||
|
||||
stringBuilder.Append(endIndex >= currentLine.Length ? currentLine : currentLine.SafeRemove(endIndex));
|
||||
}
|
||||
return stringBuilder.ToString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Replaces the lines in TotalLines, starting by Start replacing Count number of items, with the string in SplittedText
|
||||
/// All lines that can be replaced get replaced all lines that are needed additionally get added
|
||||
/// </summary>
|
||||
/// <param name="totalLines"></param>
|
||||
/// <param name="start"></param>
|
||||
/// <param name="count"></param>
|
||||
/// <param name="splittedText"></param>
|
||||
public static void ReplaceLines(PooledList<string> totalLines, int start, int count, string[] splittedText)
|
||||
{
|
||||
if (splittedText.Length == 0)
|
||||
{
|
||||
totalLines.Safe_RemoveRange(start, count);
|
||||
return;
|
||||
}
|
||||
|
||||
//Same line-length -> check for any differences in the individual lines
|
||||
if (count == splittedText.Length)
|
||||
{
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
if (!totalLines.GetLineText(i).Equals(splittedText[i], StringComparison.Ordinal))
|
||||
{
|
||||
totalLines.SetLineText(start + i, splittedText[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
//Delete items from start to count; Insert splittedText at start
|
||||
else if (count > splittedText.Length)
|
||||
{
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
if (i < splittedText.Length)
|
||||
{
|
||||
totalLines.SetLineText(start + i, splittedText[i]);
|
||||
}
|
||||
else
|
||||
{
|
||||
totalLines.Safe_RemoveRange(start + i, count - i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
//Replace all items from start - count with existing (add more if out of range)
|
||||
else //SplittedText.Length > Count:
|
||||
{
|
||||
for (int i = 0; i < splittedText.Length; i++)
|
||||
{
|
||||
//replace all possible lines
|
||||
if (i < count)
|
||||
{
|
||||
totalLines.SetLineText(start + i, splittedText[i]);
|
||||
}
|
||||
else //Add new lines
|
||||
{
|
||||
totalLines.InsertOrAddRange(splittedText.Skip(start + i), start + i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static bool MoveLinesUp(PooledList<string> totalLines, TextSelection selection, CursorPosition cursorposition)
|
||||
{
|
||||
//Move single line
|
||||
if (selection != null)
|
||||
return false;
|
||||
|
||||
if (cursorposition.LineNumber > 0)
|
||||
{
|
||||
totalLines.SwapLines(cursorposition.LineNumber, cursorposition.LineNumber - 1);
|
||||
cursorposition.LineNumber -= 1;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
public static bool MoveLinesDown(PooledList<string> totalLines, TextSelection selection, CursorPosition cursorposition)
|
||||
{
|
||||
//Move single line
|
||||
if (selection != null || selection.StartPosition.LineNumber != selection.EndPosition.LineNumber)
|
||||
return false;
|
||||
|
||||
if (cursorposition.LineNumber < totalLines.Count)
|
||||
{
|
||||
totalLines.SwapLines(cursorposition.LineNumber, cursorposition.LineNumber + 1);
|
||||
cursorposition.LineNumber += 1;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
public static void ClearSelectionIfNeeded(TextControlBox textbox, SelectionRenderer selectionrenderer)
|
||||
{
|
||||
//If the selection is visible, but is not getting set, clear the selection
|
||||
if (selectionrenderer.HasSelection && !selectionrenderer.IsSelecting)
|
||||
{
|
||||
textbox.ClearSelection();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static bool SelectionIsNull(SelectionRenderer selectionrenderer, TextSelection selection)
|
||||
{
|
||||
if (selection == null)
|
||||
return true;
|
||||
return selectionrenderer.SelectionStartPosition == null || selectionrenderer.SelectionEndPosition == null;
|
||||
}
|
||||
public static void SelectSingleWord(CanvasHelper canvashelper, SelectionRenderer selectionrenderer, CursorPosition cursorPosition, string currentLine)
|
||||
{
|
||||
int characterpos = cursorPosition.CharacterPosition;
|
||||
//Update variables
|
||||
selectionrenderer.SelectionStartPosition =
|
||||
new CursorPosition(characterpos - Cursor.CalculateStepsToMoveLeft2(currentLine, characterpos), cursorPosition.LineNumber);
|
||||
|
||||
selectionrenderer.SelectionEndPosition =
|
||||
new CursorPosition(characterpos + Cursor.CalculateStepsToMoveRight2(currentLine, characterpos), cursorPosition.LineNumber);
|
||||
|
||||
cursorPosition.CharacterPosition = selectionrenderer.SelectionEndPosition.CharacterPosition;
|
||||
selectionrenderer.HasSelection = true;
|
||||
|
||||
//Render it
|
||||
canvashelper.UpdateSelection();
|
||||
canvashelper.UpdateCursor();
|
||||
}
|
||||
}
|
||||
}
|
20
TextControlBox/Text/StringManager.cs
Normal file
20
TextControlBox/Text/StringManager.cs
Normal file
|
@ -0,0 +1,20 @@
|
|||
using TextControlBoxNS.Helper;
|
||||
|
||||
namespace TextControlBoxNS.Text
|
||||
{
|
||||
internal class StringManager
|
||||
{
|
||||
private TabSpaceHelper tabSpaceHelper;
|
||||
public LineEnding lineEnding;
|
||||
|
||||
public StringManager(TabSpaceHelper tabSpaceHelper)
|
||||
{
|
||||
this.tabSpaceHelper = tabSpaceHelper;
|
||||
}
|
||||
public string CleanUpString(string input)
|
||||
{
|
||||
//Fix tabs and lineendings
|
||||
return tabSpaceHelper.UpdateTabs(LineEndings.CleanLineEndings(input, lineEnding));
|
||||
}
|
||||
}
|
||||
}
|
92
TextControlBox/Text/TabKey.cs
Normal file
92
TextControlBox/Text/TabKey.cs
Normal file
|
@ -0,0 +1,92 @@
|
|||
using Collections.Pooled;
|
||||
using TextControlBoxNS.Extensions;
|
||||
|
||||
namespace TextControlBoxNS.Text
|
||||
{
|
||||
internal class TabKey
|
||||
{
|
||||
public static TextSelection MoveTabBack(PooledList<string> totalLines, TextSelection textSelection, CursorPosition cursorPosition, string tabCharacter, string newLineCharacter, UndoRedo undoRedo)
|
||||
{
|
||||
if (textSelection == null)
|
||||
{
|
||||
string line = totalLines.GetLineText(cursorPosition.LineNumber);
|
||||
if (line.Contains(tabCharacter, System.StringComparison.Ordinal) && cursorPosition.CharacterPosition > 0)
|
||||
cursorPosition.SubtractFromCharacterPos(tabCharacter.Length);
|
||||
|
||||
undoRedo.RecordUndoAction(() =>
|
||||
{
|
||||
totalLines.SetLineText(cursorPosition.LineNumber, line.RemoveFirstOccurence(tabCharacter));
|
||||
}, totalLines, cursorPosition.LineNumber, 1, 1, newLineCharacter);
|
||||
|
||||
return new TextSelection(cursorPosition, null);
|
||||
}
|
||||
|
||||
textSelection = Selection.OrderTextSelection(textSelection);
|
||||
int selectedLinesCount = textSelection.EndPosition.LineNumber - textSelection.StartPosition.LineNumber;
|
||||
|
||||
TextSelection tempSel = new TextSelection(textSelection);
|
||||
tempSel.StartPosition.CharacterPosition = 0;
|
||||
tempSel.EndPosition.CharacterPosition = totalLines.GetLineText(textSelection.EndPosition.LineNumber).Length + tabCharacter.Length;
|
||||
|
||||
undoRedo.RecordUndoAction(() =>
|
||||
{
|
||||
for (int i = 0; i < selectedLinesCount + 1; i++)
|
||||
{
|
||||
int lineIndex = i + textSelection.StartPosition.LineNumber;
|
||||
string currentLine = totalLines.GetLineText(lineIndex);
|
||||
|
||||
if (i == 0 && currentLine.Contains(tabCharacter, System.StringComparison.Ordinal) && cursorPosition.CharacterPosition > 0)
|
||||
textSelection.StartPosition.CharacterPosition -= tabCharacter.Length;
|
||||
else if (i == selectedLinesCount && currentLine.Contains(tabCharacter, System.StringComparison.Ordinal))
|
||||
{
|
||||
textSelection.EndPosition.CharacterPosition -= tabCharacter.Length;
|
||||
}
|
||||
|
||||
totalLines.SetLineText(lineIndex, currentLine.RemoveFirstOccurence(tabCharacter));
|
||||
}
|
||||
}, totalLines, tempSel, selectedLinesCount, newLineCharacter);
|
||||
|
||||
return new TextSelection(new CursorPosition(textSelection.StartPosition), new CursorPosition(textSelection.EndPosition));
|
||||
}
|
||||
|
||||
public static TextSelection MoveTab(PooledList<string> totalLines, TextSelection textSelection, CursorPosition cursorPosition, string tabCharacter, string newLineCharacter, UndoRedo undoRedo)
|
||||
{
|
||||
if (textSelection == null)
|
||||
{
|
||||
string line = totalLines.GetLineText(cursorPosition.LineNumber);
|
||||
|
||||
undoRedo.RecordUndoAction(() =>
|
||||
{
|
||||
totalLines.SetLineText(cursorPosition.LineNumber, line.AddText(tabCharacter, cursorPosition.CharacterPosition));
|
||||
}, totalLines, cursorPosition.LineNumber, 1, 1, newLineCharacter);
|
||||
|
||||
cursorPosition.AddToCharacterPos(tabCharacter.Length);
|
||||
return new TextSelection(cursorPosition, null);
|
||||
}
|
||||
|
||||
textSelection = Selection.OrderTextSelection(textSelection);
|
||||
int selectedLinesCount = textSelection.EndPosition.LineNumber - textSelection.StartPosition.LineNumber;
|
||||
|
||||
if (textSelection.StartPosition.LineNumber == textSelection.EndPosition.LineNumber) //Singleline
|
||||
textSelection.StartPosition = Selection.Replace(textSelection, totalLines, tabCharacter, newLineCharacter);
|
||||
else
|
||||
{
|
||||
TextSelection tempSel = new TextSelection(textSelection);
|
||||
tempSel.StartPosition.CharacterPosition = 0;
|
||||
tempSel.EndPosition.CharacterPosition = totalLines.GetLineText(textSelection.EndPosition.LineNumber).Length + tabCharacter.Length;
|
||||
|
||||
textSelection.EndPosition.CharacterPosition += tabCharacter.Length;
|
||||
textSelection.StartPosition.CharacterPosition += tabCharacter.Length;
|
||||
|
||||
undoRedo.RecordUndoAction(() =>
|
||||
{
|
||||
for (int i = textSelection.StartPosition.LineNumber; i < selectedLinesCount + textSelection.StartPosition.LineNumber + 1; i++)
|
||||
{
|
||||
totalLines.SetLineText(i, totalLines.GetLineText(i).AddToStart(tabCharacter));
|
||||
}
|
||||
}, totalLines, tempSel, selectedLinesCount + 1, newLineCharacter);
|
||||
}
|
||||
return new TextSelection(new CursorPosition(textSelection.StartPosition), new CursorPosition(textSelection.EndPosition));
|
||||
}
|
||||
}
|
||||
}
|
176
TextControlBox/Text/UndoRedo.cs
Normal file
176
TextControlBox/Text/UndoRedo.cs
Normal file
|
@ -0,0 +1,176 @@
|
|||
using Collections.Pooled;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using TextControlBoxNS.Extensions;
|
||||
using TextControlBoxNS.Helper;
|
||||
using TextControlBoxNS.Models;
|
||||
|
||||
namespace TextControlBoxNS.Text
|
||||
{
|
||||
internal class UndoRedo
|
||||
{
|
||||
private Stack<UndoRedoItem> UndoStack = new Stack<UndoRedoItem>();
|
||||
private Stack<UndoRedoItem> RedoStack = new Stack<UndoRedoItem>();
|
||||
|
||||
private bool HasRedone = false;
|
||||
|
||||
private void RecordRedo(UndoRedoItem item)
|
||||
{
|
||||
RedoStack.Push(item);
|
||||
}
|
||||
private void RecordUndo(UndoRedoItem item)
|
||||
{
|
||||
UndoStack.Push(item);
|
||||
}
|
||||
|
||||
private void AddUndoItem(TextSelection selection, int startLine, string undoText, string redoText, int undoCount, int redoCount)
|
||||
{
|
||||
UndoStack.Push(new UndoRedoItem
|
||||
{
|
||||
RedoText = redoText,
|
||||
UndoText = undoText,
|
||||
Selection = selection,
|
||||
StartLine = startLine,
|
||||
UndoCount = undoCount,
|
||||
RedoCount = redoCount,
|
||||
});
|
||||
}
|
||||
|
||||
private void RecordSingleLine(Action action, PooledList<string> totalLines, int startline)
|
||||
{
|
||||
var lineBefore = totalLines.GetLineText(startline);
|
||||
action.Invoke();
|
||||
var lineAfter = totalLines.GetLineText(startline);
|
||||
AddUndoItem(null, startline, lineBefore, lineAfter, 1, 1);
|
||||
}
|
||||
|
||||
public void RecordUndoAction(Action action, PooledList<string> totalLines, int startline, int undocount, int redoCount, string newLineCharacter, CursorPosition cursorposition = null)
|
||||
{
|
||||
if (undocount == redoCount && redoCount == 1)
|
||||
{
|
||||
RecordSingleLine(action, totalLines, startline);
|
||||
return;
|
||||
}
|
||||
|
||||
var linesBefore = totalLines.GetLines(startline, undocount).GetString(newLineCharacter);
|
||||
action.Invoke();
|
||||
var linesAfter = totalLines.GetLines(startline, redoCount).GetString(newLineCharacter);
|
||||
|
||||
AddUndoItem(cursorposition == null ? null : new TextSelection(new CursorPosition(cursorposition), null), startline, linesBefore, linesAfter, undocount, redoCount);
|
||||
}
|
||||
public void RecordUndoAction(Action action, PooledList<string> totalLines, TextSelection selection, int numberOfAddedLines, string newLineCharacter)
|
||||
{
|
||||
var orderedSel = Selection.OrderTextSelection(selection);
|
||||
if (orderedSel.StartPosition.LineNumber == orderedSel.EndPosition.LineNumber && orderedSel.StartPosition.LineNumber == 1)
|
||||
{
|
||||
RecordSingleLine(action, totalLines, orderedSel.StartPosition.LineNumber);
|
||||
return;
|
||||
}
|
||||
|
||||
int numberOfRemovedLines = orderedSel.EndPosition.LineNumber - orderedSel.StartPosition.LineNumber + 1;
|
||||
|
||||
if (numberOfAddedLines == 0 && !Selection.WholeLinesAreSelected(selection, totalLines) ||
|
||||
orderedSel.StartPosition.LineNumber == orderedSel.EndPosition.LineNumber && orderedSel.Length == totalLines.GetLineLength(orderedSel.StartPosition.LineNumber))
|
||||
numberOfAddedLines += 1;
|
||||
|
||||
var linesBefore = totalLines.GetLines(orderedSel.StartPosition.LineNumber, numberOfRemovedLines).GetString(newLineCharacter);
|
||||
action.Invoke();
|
||||
var linesAfter = totalLines.GetLines(orderedSel.StartPosition.LineNumber, numberOfAddedLines).GetString(newLineCharacter);
|
||||
|
||||
AddUndoItem(
|
||||
selection,
|
||||
orderedSel.StartPosition.LineNumber,
|
||||
linesBefore,
|
||||
linesAfter,
|
||||
numberOfRemovedLines,
|
||||
numberOfAddedLines
|
||||
);
|
||||
}
|
||||
|
||||
public TextSelection Undo(PooledList<string> totalLines, StringManager stringManager, string newLineCharacter)
|
||||
{
|
||||
if (UndoStack.Count < 1)
|
||||
return null;
|
||||
|
||||
if (HasRedone)
|
||||
{
|
||||
HasRedone = false;
|
||||
while (RedoStack.Count > 0)
|
||||
{
|
||||
var redoItem = RedoStack.Pop();
|
||||
redoItem.UndoText = redoItem.RedoText = null;
|
||||
}
|
||||
}
|
||||
|
||||
UndoRedoItem item = UndoStack.Pop();
|
||||
RecordRedo(item);
|
||||
|
||||
//Faster for singleline
|
||||
if (item.UndoCount == 1 && item.RedoCount == 1)
|
||||
{
|
||||
totalLines.SetLineText(item.StartLine, stringManager.CleanUpString(item.UndoText));
|
||||
}
|
||||
else
|
||||
{
|
||||
totalLines.Safe_RemoveRange(item.StartLine, item.RedoCount);
|
||||
if (item.UndoCount > 0)
|
||||
totalLines.InsertOrAddRange(ListHelper.GetLinesFromString(stringManager.CleanUpString(item.UndoText), newLineCharacter), item.StartLine);
|
||||
}
|
||||
|
||||
return item.Selection;
|
||||
}
|
||||
|
||||
public TextSelection Redo(PooledList<string> totalLines, StringManager stringmanager, string newLineCharacter)
|
||||
{
|
||||
if (RedoStack.Count < 1)
|
||||
return null;
|
||||
|
||||
UndoRedoItem item = RedoStack.Pop();
|
||||
RecordUndo(item);
|
||||
HasRedone = true;
|
||||
|
||||
//Faster for singleline
|
||||
if (item.UndoCount == 1 && item.RedoCount == 1)
|
||||
{
|
||||
totalLines.SetLineText(item.StartLine, stringmanager.CleanUpString(item.RedoText));
|
||||
}
|
||||
else
|
||||
{
|
||||
totalLines.Safe_RemoveRange(item.StartLine, item.UndoCount);
|
||||
if (item.RedoCount > 0)
|
||||
totalLines.InsertOrAddRange(ListHelper.GetLinesFromString(stringmanager.CleanUpString(item.RedoText), newLineCharacter), item.StartLine);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clears all the items in the undo and redo stack
|
||||
/// </summary>
|
||||
public void ClearAll()
|
||||
{
|
||||
UndoStack.Clear();
|
||||
RedoStack.Clear();
|
||||
UndoStack.TrimExcess();
|
||||
RedoStack.TrimExcess();
|
||||
|
||||
GC.Collect(GC.GetGeneration(UndoStack), GCCollectionMode.Optimized);
|
||||
GC.Collect(GC.GetGeneration(RedoStack), GCCollectionMode.Optimized);
|
||||
}
|
||||
|
||||
public void NullAll()
|
||||
{
|
||||
UndoStack = null;
|
||||
RedoStack = null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets if the undo stack contains actions
|
||||
/// </summary>
|
||||
public bool CanUndo { get => UndoStack.Count > 0; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets if the redo stack contains actions
|
||||
/// </summary>
|
||||
public bool CanRedo { get => RedoStack.Count > 0; }
|
||||
}
|
||||
}
|
32
TextControlBox/TextControlBox.csproj
Normal file
32
TextControlBox/TextControlBox.csproj
Normal file
|
@ -0,0 +1,32 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0-windows10.0.19041.0</TargetFramework>
|
||||
<TargetPlatformMinVersion>10.0.17763.0</TargetPlatformMinVersion>
|
||||
<RootNamespace>TextControlBoxNS</RootNamespace>
|
||||
<RuntimeIdentifiers>win10-x86;win10-x64;win10-arm64</RuntimeIdentifiers>
|
||||
<UseWinUI>true</UseWinUI>
|
||||
<GenerateDocumentationFile>True</GenerateDocumentationFile>
|
||||
<DocumentationFile></DocumentationFile>
|
||||
<GeneratePackageOnBuild>False</GeneratePackageOnBuild>
|
||||
<PackageId>TextControlBox.WinUI.JuliusKirsch</PackageId>
|
||||
<Title>TextControlBox WinUI</Title>
|
||||
<Version>1.0.0</Version>
|
||||
<Authors>Julius Kirsch</Authors>
|
||||
<Product>TextControlBox WinUI</Product>
|
||||
<Description>A textbox for WinUI3 with syntax highlighting, line numbering, and support for a large amount of text</Description>
|
||||
<Copyright>Julius Kirsch</Copyright>
|
||||
<PackageProjectUrl>https://github.com/FrozenAssassine/TextControlBox-WinUI</PackageProjectUrl>
|
||||
<RepositoryUrl>https://github.com/FrozenAssassine/TextControlBox-WinUI</RepositoryUrl>
|
||||
<PackageTags>TextControlBox; Textbox; WinUI; C#; SyntaxHighlighting; LineNumbers</PackageTags>
|
||||
<PackageReleaseNotes>Migrated from UWP to WinUI.</PackageReleaseNotes>
|
||||
<PackageIcon>Icon1.png</PackageIcon>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Collections.Pooled" Version="1.0.82" />
|
||||
<PackageReference Include="Microsoft.Graphics.Win2D" Version="1.0.5.1" />
|
||||
<PackageReference Include="Microsoft.WindowsAppSDK" Version="1.2.221109.1" />
|
||||
<PackageReference Include="Microsoft.Windows.SDK.BuildTools" Version="10.0.22621.755" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||
</ItemGroup>
|
||||
</Project>
|
117
TextControlBox/TextControlBox.xaml
Normal file
117
TextControlBox/TextControlBox.xaml
Normal file
|
@ -0,0 +1,117 @@
|
|||
<UserControl
|
||||
x:Class="TextControlBoxNS.TextControlBox"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:helper="using:TextControlBoxNS.Helper"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:xaml="using:Microsoft.Graphics.Canvas.UI.Xaml"
|
||||
d:DesignHeight="300"
|
||||
d:DesignWidth="400"
|
||||
AllowDrop="True"
|
||||
AllowFocusOnInteraction="false"
|
||||
DragOver="UserControl_DragOver"
|
||||
Drop="UserControl_Drop"
|
||||
GotFocus="UserControl_GotFocus"
|
||||
IsTabStop="True"
|
||||
LosingFocus="UserControl_LosingFocus"
|
||||
LostFocus="UserControl_LostFocus"
|
||||
PointerEntered="UserControl_PointerEntered"
|
||||
PointerExited="UserControl_PointerExited"
|
||||
PointerWheelChanged="Canvas_Selection_PointerWheelChanged"
|
||||
TabIndex="0"
|
||||
Tapped="UserControl_Tapped"
|
||||
mc:Ignorable="d">
|
||||
<Grid x:Name="MainGrid">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="auto" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<xaml:CanvasControl
|
||||
x:Name="Canvas_LineNumber"
|
||||
Grid.Column="0"
|
||||
Width="100"
|
||||
HorizontalAlignment="Left"
|
||||
VerticalAlignment="Stretch"
|
||||
Draw="Canvas_LineNumber_Draw"
|
||||
PointerEntered="Canvas_LineNumber_PointerEntered"
|
||||
PointerExited="Canvas_LineNumber_PointerExited"
|
||||
PointerPressed="Canvas_LineNumber_PointerPressed"
|
||||
PointerReleased="Canvas_Selection_PointerReleased"
|
||||
PointerWheelChanged="Canvas_Selection_PointerWheelChanged" />
|
||||
|
||||
<Grid x:Name="Scroll" Grid.Column="1">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="auto" />
|
||||
<ColumnDefinition Width="auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<xaml:CanvasControl
|
||||
x:Name="Canvas_Cursor"
|
||||
Grid.Column="0"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Stretch"
|
||||
Draw="Canvas_Cursor_Draw" />
|
||||
|
||||
<xaml:CanvasControl
|
||||
x:Name="Canvas_Text"
|
||||
Grid.Column="0"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Stretch"
|
||||
Draw="Canvas_Text_Draw" />
|
||||
|
||||
<xaml:CanvasControl
|
||||
x:Name="Canvas_Selection"
|
||||
Grid.Column="0"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Stretch"
|
||||
Draw="Canvas_Selection_Draw"
|
||||
PointerMoved="Canvas_Selection_PointerMoved"
|
||||
PointerPressed="Canvas_Selection_PointerPressed"
|
||||
PointerReleased="Canvas_Selection_PointerReleased" />
|
||||
|
||||
<ScrollBar
|
||||
x:Name="VerticalScrollbar"
|
||||
Grid.Column="2"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Stretch"
|
||||
Background="Transparent"
|
||||
IndicatorMode="MouseIndicator"
|
||||
LargeChange="100"
|
||||
Loaded="VerticalScrollbar_Loaded"
|
||||
Maximum="0"
|
||||
Minimum="0"
|
||||
Orientation="Vertical"
|
||||
PointerEntered="Scrollbar_PointerEntered"
|
||||
PointerExited="Scrollbar_PointerExited"
|
||||
Scroll="VerticalScrollbar_Scroll"
|
||||
SmallChange="10"
|
||||
Value="0" />
|
||||
<ScrollBar
|
||||
x:Name="HorizontalScrollbar"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Bottom"
|
||||
Background="Transparent"
|
||||
IndicatorMode="MouseIndicator"
|
||||
LargeChange="100"
|
||||
Maximum="0"
|
||||
Minimum="0"
|
||||
Orientation="Horizontal"
|
||||
PointerEntered="Scrollbar_PointerEntered"
|
||||
PointerExited="Scrollbar_PointerExited"
|
||||
Scroll="HorizontalScrollbar_Scroll"
|
||||
SmallChange="10"
|
||||
Value="0" />
|
||||
</Grid>
|
||||
<helper:InputHandlerControl
|
||||
x:Name="inputHandler"
|
||||
Grid.Column="1"
|
||||
Width="0"
|
||||
Height="0"
|
||||
GotFocus="UserControl_GotFocus"
|
||||
LostFocus="UserControl_LostFocus"
|
||||
Opacity="0"
|
||||
PreviewKeyDown="InputHandler_KeyDown"
|
||||
TextChanged="InputHandler_TextChanged" />
|
||||
</Grid>
|
||||
</UserControl>
|
2674
TextControlBox/TextControlBox.xaml.cs
Normal file
2674
TextControlBox/TextControlBox.xaml.cs
Normal file
File diff suppressed because it is too large
Load Diff
|
@ -1 +0,0 @@
|
|||
true
|
|
@ -1,336 +0,0 @@
|
|||
#include "pch.h"
|
||||
#include "CodeEditorControl.h"
|
||||
#if __has_include("CodeEditorControl.g.cpp")
|
||||
#include "CodeEditorControl.g.cpp"
|
||||
#endif
|
||||
#include "Helpers.h"
|
||||
|
||||
using namespace ::WinUIEditor;
|
||||
using namespace winrt;
|
||||
using namespace Windows::UI::Core;
|
||||
using namespace Windows::Foundation;
|
||||
using namespace Windows::System;
|
||||
using namespace DUD;
|
||||
using namespace DUX;
|
||||
using namespace DUX::Controls;
|
||||
using namespace DUX::Input;
|
||||
|
||||
using namespace winrt;
|
||||
|
||||
namespace winrt::WinUIEditor::implementation
|
||||
{
|
||||
CodeEditorControl::CodeEditorControl()
|
||||
{
|
||||
DefaultStyleKey(winrt::box_value(L"WinUIEditor.CodeEditorControl"));
|
||||
|
||||
_editor = make_self<EditorBaseControl>();
|
||||
_call = _editor->Call();
|
||||
SetScintilla(_call);
|
||||
SetLexilla(CreateLexer);
|
||||
Initialize();
|
||||
_editor->DpiChanged({ this, &CodeEditorControl::Editor_DpiChanged });
|
||||
_editor->InternalNotifyMessageReceived.add({ this, &CodeEditorControl::Editor_NotifyMessageReceived });
|
||||
|
||||
Loaded({ this, &CodeEditorControl::OnLoaded });
|
||||
Unloaded({ this, &CodeEditorControl::OnUnloaded });
|
||||
GettingFocus({ this, &CodeEditorControl::OnGettingFocus });
|
||||
|
||||
#ifndef WINUI3
|
||||
if (_hasFcu)
|
||||
{
|
||||
#endif
|
||||
_dispatcherQueue = DUD::DispatcherQueue::GetForCurrentThread();
|
||||
#ifndef WINUI3
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static constexpr CodeEditorTheme XamlToCodeEditorTheme(ElementTheme theme)
|
||||
{
|
||||
return static_cast<CodeEditorTheme>(theme);
|
||||
}
|
||||
|
||||
static constexpr ElementTheme CodeEditorToXamlTheme(CodeEditorTheme theme)
|
||||
{
|
||||
return static_cast<ElementTheme>(theme);
|
||||
}
|
||||
|
||||
void CodeEditorControl::OnApplyTemplate()
|
||||
{
|
||||
__super::OnApplyTemplate();
|
||||
|
||||
#ifndef WINUI3
|
||||
if (_hasFcu)
|
||||
{
|
||||
#endif
|
||||
UpdateColors(XamlToCodeEditorTheme(ActualTheme()));
|
||||
#ifndef WINUI3
|
||||
}
|
||||
else
|
||||
{
|
||||
UpdateColors(XamlToCodeEditorTheme(LegacyActualTheme()));
|
||||
}
|
||||
#endif
|
||||
|
||||
if (const auto presenter{ GetTemplateChild(L"EditorContainer").try_as<ContentPresenter>() })
|
||||
{
|
||||
presenter.Content(_editor.as<WinUIEditor::EditorBaseControl>());
|
||||
}
|
||||
}
|
||||
|
||||
void CodeEditorControl::OnKeyDown(KeyRoutedEventArgs const &e)
|
||||
{
|
||||
__super::OnKeyDown(e);
|
||||
|
||||
const auto modifiers{ GetKeyModifiersForCurrentThread() }; // Todo: Can we avoid calling this every time?
|
||||
|
||||
if ((modifiers & VirtualKeyModifiers::Control) == VirtualKeyModifiers::Control)
|
||||
{
|
||||
switch (e.Key())
|
||||
{
|
||||
case VirtualKey::F2: // Todo: make customizable
|
||||
{
|
||||
if (_call->Focus())
|
||||
{
|
||||
ChangeAllOccurrences();
|
||||
e.Handled(true);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CodeEditorControl::OnLoaded(IInspectable const &sender, DUX::RoutedEventArgs const &args)
|
||||
{
|
||||
#ifndef WINUI3
|
||||
_isLoaded = true;
|
||||
#endif
|
||||
|
||||
if (!IsLoadedCompat())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
#ifndef WINUI3
|
||||
if (_hasFcu)
|
||||
{
|
||||
#endif
|
||||
UpdateColors(XamlToCodeEditorTheme(ActualTheme()));
|
||||
_actualThemeChangedRevoker = ActualThemeChanged(auto_revoke, { this, &CodeEditorControl::OnActualThemeChanged });
|
||||
#ifndef WINUI3
|
||||
}
|
||||
else
|
||||
{
|
||||
UpdateColors(XamlToCodeEditorTheme(LegacyActualTheme()));
|
||||
// Todo: Add fallback for ActualThemeChanged
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void CodeEditorControl::OnUnloaded(IInspectable const &sender, DUX::RoutedEventArgs const &args)
|
||||
{
|
||||
#ifndef WINUI3
|
||||
_isLoaded = false;
|
||||
#endif
|
||||
|
||||
if (IsLoadedCompat())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
#ifndef WINUI3
|
||||
if (_hasFcu)
|
||||
{
|
||||
#endif
|
||||
_actualThemeChangedRevoker.revoke();
|
||||
#ifndef WINUI3
|
||||
}
|
||||
else
|
||||
{
|
||||
// Todo: Add fallback
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
bool CodeEditorControl::IsLoadedCompat()
|
||||
{
|
||||
#ifndef WINUI3
|
||||
if (_hasIsLoaded)
|
||||
{
|
||||
#endif
|
||||
return IsLoaded();
|
||||
#ifndef WINUI3
|
||||
}
|
||||
else
|
||||
{
|
||||
return _isLoaded;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void CodeEditorControl::OnGettingFocus(IInspectable const &sender, GettingFocusEventArgs const &e)
|
||||
{
|
||||
if (e.NewFocusedElement() == *this && (
|
||||
#ifndef WINUI3
|
||||
!_has1803 ||
|
||||
#endif
|
||||
!e.TrySetNewFocusedElement(*_editor)))
|
||||
{
|
||||
const auto focusState{ e.FocusState() };
|
||||
#ifndef WINUI3
|
||||
if (_hasFcu)
|
||||
{
|
||||
#endif
|
||||
_dispatcherQueue.TryEnqueue([this, focusState]()
|
||||
{
|
||||
_editor->Focus(focusState);
|
||||
});
|
||||
#ifndef WINUI3
|
||||
}
|
||||
else
|
||||
{
|
||||
Dispatcher().RunAsync(CoreDispatcherPriority::Normal, [this, focusState]()
|
||||
{
|
||||
_editor->Focus(focusState);
|
||||
});
|
||||
}
|
||||
#endif
|
||||
e.Handled(true);
|
||||
}
|
||||
}
|
||||
|
||||
int64_t CodeEditorControl::SendMessage(ScintillaMessage const &message, uint64_t wParam, int64_t lParam)
|
||||
{
|
||||
return _editor->PublicWndProc(static_cast<Scintilla::Message>(message), wParam, lParam);
|
||||
}
|
||||
|
||||
WinUIEditor::Editor CodeEditorControl::Editor()
|
||||
{
|
||||
return _editor->Editor();
|
||||
}
|
||||
|
||||
void CodeEditorControl::OnActualThemeChanged(IInspectable const &sender, IInspectable const &e)
|
||||
{
|
||||
UpdateColors(XamlToCodeEditorTheme(ActualTheme()));
|
||||
}
|
||||
|
||||
void CodeEditorControl::Editor_DpiChanged(IInspectable const &sender, double value)
|
||||
{
|
||||
UpdateDpi(value);
|
||||
}
|
||||
|
||||
void CodeEditorControl::Editor_NotifyMessageReceived(IInspectable const &sender, int64_t value)
|
||||
{
|
||||
ProcessNotification(reinterpret_cast<Scintilla::NotificationData *>(value));
|
||||
}
|
||||
|
||||
hstring CodeEditorControl::HighlightingLanguage()
|
||||
{
|
||||
return hstring{ CodeEditorHandler::HighlightingLanguage() };
|
||||
}
|
||||
|
||||
void CodeEditorControl::HighlightingLanguage(hstring const &value)
|
||||
{
|
||||
CodeEditorHandler::HighlightingLanguage(value);
|
||||
}
|
||||
|
||||
event_token CodeEditorControl::DefaultColorsChanged(EventHandler<ElementTheme> const &handler)
|
||||
{
|
||||
return _defaultColorsChangedEvent.add(handler);
|
||||
}
|
||||
|
||||
void CodeEditorControl::DefaultColorsChanged(event_token const &token) noexcept
|
||||
{
|
||||
_defaultColorsChangedEvent.remove(token);
|
||||
}
|
||||
|
||||
event_token CodeEditorControl::SyntaxHighlightingApplied(EventHandler<ElementTheme> const &handler)
|
||||
{
|
||||
return _syntaxHighlightingAppliedEvent.add(handler);
|
||||
}
|
||||
|
||||
void CodeEditorControl::SyntaxHighlightingApplied(event_token const &token) noexcept
|
||||
{
|
||||
_syntaxHighlightingAppliedEvent.remove(token);
|
||||
}
|
||||
|
||||
void CodeEditorControl::ApplyDefaultsToDocument()
|
||||
{
|
||||
ChangeDocumentDefaults();
|
||||
UpdateZoom();
|
||||
}
|
||||
|
||||
void CodeEditorControl::ResetLexer()
|
||||
{
|
||||
SetLexer();
|
||||
}
|
||||
|
||||
#ifndef WINUI3
|
||||
DUX::ElementTheme CodeEditorControl::LegacyActualTheme()
|
||||
{
|
||||
// Todo: Fully implement
|
||||
const auto requestedTheme{ RequestedTheme() };
|
||||
if (requestedTheme == ElementTheme::Default)
|
||||
{
|
||||
return Application::Current().RequestedTheme() == ApplicationTheme::Dark
|
||||
? ElementTheme::Dark
|
||||
: ElementTheme::Light;
|
||||
}
|
||||
else
|
||||
{
|
||||
return requestedTheme;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void CodeEditorControl::StyleSetFore(int style, Scintilla::ColourAlpha color)
|
||||
{
|
||||
_editor->StyleSetForeTransparent(style, Scintilla::Internal::ColourRGBA{ color });
|
||||
}
|
||||
|
||||
void CodeEditorControl::StyleSetBack(int style, Scintilla::ColourAlpha color)
|
||||
{
|
||||
_editor->StyleSetBackTransparent(style, Scintilla::Internal::ColourRGBA{ color });
|
||||
}
|
||||
|
||||
void CodeEditorControl::InvalidateStyleRedraw()
|
||||
{
|
||||
_editor->InvalidateStyleRedraw();
|
||||
}
|
||||
|
||||
void CodeEditorControl::StyleClearCustom()
|
||||
{
|
||||
_editor->StyleClearCustom();
|
||||
}
|
||||
|
||||
void CodeEditorControl::SetFoldMarginColor(bool useSetting, Scintilla::ColourAlpha back)
|
||||
{
|
||||
_editor->SetFoldMarginColorTransparent(useSetting, Scintilla::Internal::ColourRGBA{ back });
|
||||
}
|
||||
|
||||
void CodeEditorControl::SetFoldMarginHiColor(bool useSetting, Scintilla::ColourAlpha fore)
|
||||
{
|
||||
_editor->SetFoldMarginHiColorTransparent(useSetting, Scintilla::Internal::ColourRGBA{ fore });
|
||||
}
|
||||
|
||||
void CodeEditorControl::DefaultColorsChanged(CodeEditorTheme theme)
|
||||
{
|
||||
_defaultColorsChangedEvent(*this, CodeEditorToXamlTheme(theme));
|
||||
}
|
||||
|
||||
void CodeEditorControl::SyntaxHighlightingApplied(CodeEditorTheme theme)
|
||||
{
|
||||
_syntaxHighlightingAppliedEvent(*this, CodeEditorToXamlTheme(theme));
|
||||
}
|
||||
|
||||
event_token CodeEditorControl::NotifyMessageReceived(EventHandler<int64_t> const &handler)
|
||||
{
|
||||
return _editor->NotifyMessageReceived(handler);
|
||||
}
|
||||
|
||||
void CodeEditorControl::NotifyMessageReceived(event_token const &token) noexcept
|
||||
{
|
||||
_editor->NotifyMessageReceived(token);
|
||||
}
|
||||
}
|
|
@ -1,75 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include "CodeEditorControl.g.h"
|
||||
|
||||
#include "CodeEditorHandler.h"
|
||||
#include "EditorBaseControl.h"
|
||||
|
||||
namespace winrt::WinUIEditor::implementation
|
||||
{
|
||||
struct CodeEditorControl : CodeEditorControlT<CodeEditorControl>, ::WinUIEditor::CodeEditorHandler
|
||||
{
|
||||
CodeEditorControl();
|
||||
int64_t SendMessage(ScintillaMessage const &message, uint64_t wParam, int64_t lParam);
|
||||
WinUIEditor::Editor Editor();
|
||||
void OnApplyTemplate();
|
||||
void OnKeyDown(DUX::Input::KeyRoutedEventArgs const &e);
|
||||
|
||||
hstring HighlightingLanguage();
|
||||
void HighlightingLanguage(hstring const &value);
|
||||
|
||||
event_token NotifyMessageReceived(Windows::Foundation::EventHandler<int64_t> const &handler);
|
||||
void NotifyMessageReceived(event_token const &token) noexcept;
|
||||
|
||||
event_token DefaultColorsChanged(Windows::Foundation::EventHandler<DUX::ElementTheme> const &handler);
|
||||
void DefaultColorsChanged(event_token const &token) noexcept;
|
||||
|
||||
event_token SyntaxHighlightingApplied(Windows::Foundation::EventHandler<DUX::ElementTheme> const &handler);
|
||||
void SyntaxHighlightingApplied(event_token const &token) noexcept;
|
||||
|
||||
void ApplyDefaultsToDocument();
|
||||
void ResetLexer();
|
||||
|
||||
private:
|
||||
com_ptr<EditorBaseControl> _editor{ nullptr };
|
||||
std::shared_ptr<Scintilla::ScintillaCall> _call{ nullptr };
|
||||
event<Windows::Foundation::EventHandler<int64_t>> _notifyMessageReceived;
|
||||
|
||||
event<Windows::Foundation::EventHandler<DUX::ElementTheme>> _defaultColorsChangedEvent;
|
||||
event<Windows::Foundation::EventHandler<DUX::ElementTheme>> _syntaxHighlightingAppliedEvent;
|
||||
DUD::DispatcherQueue _dispatcherQueue{ nullptr };
|
||||
#ifndef WINUI3
|
||||
bool _hasFcu{ Windows::Foundation::Metadata::ApiInformation::IsApiContractPresent(L"Windows.Foundation.UniversalApiContract", 5) }; // Todo: Make static
|
||||
bool _has1803{ Windows::Foundation::Metadata::ApiInformation::IsApiContractPresent(L"Windows.Foundation.UniversalApiContract", 6) }; // Todo: Make static
|
||||
bool _hasIsLoaded{ Windows::Foundation::Metadata::ApiInformation::IsPropertyPresent(L"Windows.UI.Xaml.FrameworkElement", L"IsLoaded") }; // Todo: Make static
|
||||
bool _isLoaded{ false };
|
||||
#endif
|
||||
void OnLoaded(Windows::Foundation::IInspectable const &sender, DUX::RoutedEventArgs const &args);
|
||||
void OnUnloaded(Windows::Foundation::IInspectable const &sender, DUX::RoutedEventArgs const &args);
|
||||
bool IsLoadedCompat();
|
||||
void OnGettingFocus(Windows::Foundation::IInspectable const &sender, DUX::Input::GettingFocusEventArgs const &e);
|
||||
DUX::FrameworkElement::ActualThemeChanged_revoker _actualThemeChangedRevoker{};
|
||||
void OnActualThemeChanged(Windows::Foundation::IInspectable const &sender, Windows::Foundation::IInspectable const &e);
|
||||
void Editor_DpiChanged(Windows::Foundation::IInspectable const &sender, double value);
|
||||
void Editor_NotifyMessageReceived(Windows::Foundation::IInspectable const &sender, int64_t value);
|
||||
#ifndef WINUI3
|
||||
DUX::ElementTheme LegacyActualTheme();
|
||||
#endif
|
||||
void StyleSetFore(int style, Scintilla::ColourAlpha color) override;
|
||||
void StyleSetBack(int style, Scintilla::ColourAlpha color) override;
|
||||
void InvalidateStyleRedraw() override;
|
||||
void StyleClearCustom() override;
|
||||
void SetFoldMarginColor(bool useSetting, Scintilla::ColourAlpha back) override;
|
||||
void SetFoldMarginHiColor(bool useSetting, Scintilla::ColourAlpha fore) override;
|
||||
|
||||
void DefaultColorsChanged(::WinUIEditor::CodeEditorTheme theme) override;
|
||||
void SyntaxHighlightingApplied(::WinUIEditor::CodeEditorTheme theme) override;
|
||||
};
|
||||
}
|
||||
|
||||
namespace winrt::WinUIEditor::factory_implementation
|
||||
{
|
||||
struct CodeEditorControl : CodeEditorControlT<CodeEditorControl, implementation::CodeEditorControl>
|
||||
{
|
||||
};
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
#include "Defines.idl"
|
||||
import "EditorWrapper.idl";
|
||||
import "IEditorAccess.idl";
|
||||
|
||||
namespace WinUIEditor
|
||||
{
|
||||
[default_interface]
|
||||
[webhosthidden]
|
||||
runtimeclass CodeEditorControl : DUX.Controls.Control, IEditorAccess
|
||||
{
|
||||
CodeEditorControl();
|
||||
Editor Editor { get; };
|
||||
String HighlightingLanguage { get; set; };
|
||||
event Windows.Foundation.EventHandler<DUX.ElementTheme> DefaultColorsChanged;
|
||||
event Windows.Foundation.EventHandler<DUX.ElementTheme> SyntaxHighlightingApplied;
|
||||
void ApplyDefaultsToDocument();
|
||||
void ResetLexer();
|
||||
}
|
||||
}
|
|
@ -1,669 +0,0 @@
|
|||
// This file includes code derived from SciTEBase.cxx and StyleWriter.cxx
|
||||
// Copyright 1998-2011 by Neil Hodgson <neilh@scintilla.org>
|
||||
// The scintilla\License.txt file describes the conditions under which this software may be distributed.
|
||||
|
||||
// Notable changes:
|
||||
// Modifications to StyleAndWords:
|
||||
// - Added constructor that is not string-based
|
||||
// - Changed functions (IsSingleChar, IsCharacter, Includes) to support multiple characters for indent blocks
|
||||
// Modifications to TextReader
|
||||
// - Removed InternalIsLeadByte
|
||||
// - Removed IsLeadByte (header)
|
||||
|
||||
#include "CodeEditorHandler.h"
|
||||
#include <stdexcept>
|
||||
#include "SciLexer.h"
|
||||
|
||||
using namespace WinUIEditor::Internal;
|
||||
using namespace Scintilla;
|
||||
|
||||
namespace WinUIEditor
|
||||
{
|
||||
static constexpr bool IsBrace(char ch) noexcept
|
||||
{
|
||||
return ch == '[' || ch == ']' || ch == '(' || ch == ')' || ch == '{' || ch == '}';
|
||||
}
|
||||
|
||||
static constexpr bool IsAlphabetic(int ch) noexcept
|
||||
{
|
||||
return ((ch >= 'A') && (ch <= 'Z')) || ((ch >= 'a') && (ch <= 'z'));
|
||||
}
|
||||
|
||||
static int IntegerFromString(const std::string &val, int defaultValue)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (val.length())
|
||||
{
|
||||
return std::stoi(val);
|
||||
}
|
||||
}
|
||||
catch (std::logic_error &)
|
||||
{
|
||||
// Ignore bad values, either non-numeric or out of range numeric
|
||||
}
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
static std::set<std::string> SetFromString(std::string_view text, char separator)
|
||||
{
|
||||
std::set<std::string> result;
|
||||
|
||||
while (!text.empty())
|
||||
{
|
||||
const size_t after = text.find_first_of(separator);
|
||||
const std::string_view symbol(text.substr(0, after));
|
||||
if (!symbol.empty())
|
||||
{
|
||||
result.emplace(symbol);
|
||||
}
|
||||
if (after == std::string_view::npos)
|
||||
{
|
||||
break;
|
||||
}
|
||||
text.remove_prefix(after + 1);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
StyleAndWords::StyleAndWords() noexcept
|
||||
{
|
||||
};
|
||||
|
||||
// Set of words separated by spaces. First is style number, rest are symbols.
|
||||
// <styleNumber> [symbol]*
|
||||
StyleAndWords::StyleAndWords(const std::string &definition)
|
||||
{
|
||||
styleNumber = IntegerFromString(definition, 0);
|
||||
|
||||
std::string_view symbols(definition);
|
||||
|
||||
// Remove initial style number
|
||||
const size_t endNumber = symbols.find_first_of(' ');
|
||||
if (endNumber == std::string::npos)
|
||||
{
|
||||
return;
|
||||
}
|
||||
symbols.remove_prefix(endNumber + 1);
|
||||
|
||||
words = SetFromString(symbols, ' ');
|
||||
}
|
||||
|
||||
StyleAndWords::StyleAndWords(int style, const std::set<std::string> &words)
|
||||
{
|
||||
styleNumber = style;
|
||||
this->words = words;
|
||||
}
|
||||
|
||||
bool StyleAndWords::IsEmpty() const noexcept
|
||||
{
|
||||
return words.empty();
|
||||
}
|
||||
|
||||
// WinUI modified
|
||||
bool StyleAndWords::IsSingleChar() const noexcept
|
||||
{
|
||||
//if (words.size() != 1)
|
||||
if (words.size() == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
const std::string &first = *words.begin();
|
||||
return first.length() == 1;
|
||||
}
|
||||
|
||||
// WinUI modified
|
||||
bool StyleAndWords::IsCharacter(char ch) const noexcept
|
||||
{
|
||||
//if (words.size() != 1)
|
||||
if (words.size() == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
for (std::string word : words)
|
||||
{
|
||||
if (word.size() == 1 && ch == word[0])
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
//const std::string &first = *words.begin();
|
||||
//return (first.length() == 1) && (ch == first[0]);
|
||||
}
|
||||
|
||||
int StyleAndWords::Style() const noexcept
|
||||
{
|
||||
return styleNumber;
|
||||
}
|
||||
|
||||
// WinUI modified
|
||||
bool StyleAndWords::Includes(const std::string &value) const
|
||||
{
|
||||
if (words.empty())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
const std::string &first = *words.begin();
|
||||
if (first.empty())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (IsAlphabetic(first[0]))
|
||||
{
|
||||
return words.count(value) != 0;
|
||||
}
|
||||
// Set of individual characters. Only one character allowed for now
|
||||
//const char ch = first[0];
|
||||
//return value.find(ch) != std::string::npos;
|
||||
for (std::string ch : words)
|
||||
{
|
||||
if (ch.size() == 1 && value.find(ch[0]) != std::string::npos)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
TextReader::TextReader(ScintillaCall &sc_) noexcept :
|
||||
startPos(extremePosition),
|
||||
endPos(0),
|
||||
codePage(0),
|
||||
sc(sc_),
|
||||
lenDoc(-1)
|
||||
{
|
||||
buf[0] = 0;
|
||||
}
|
||||
|
||||
void TextReader::Fill(Position position)
|
||||
{
|
||||
if (lenDoc == -1)
|
||||
lenDoc = sc.Length();
|
||||
startPos = position - slopSize;
|
||||
if (startPos + bufferSize > lenDoc)
|
||||
startPos = lenDoc - bufferSize;
|
||||
if (startPos < 0)
|
||||
startPos = 0;
|
||||
endPos = startPos + bufferSize;
|
||||
if (endPos > lenDoc)
|
||||
endPos = lenDoc;
|
||||
sc.SetTarget(Span(startPos, endPos));
|
||||
sc.TargetText(buf);
|
||||
}
|
||||
|
||||
bool TextReader::Match(Position pos, const char *s)
|
||||
{
|
||||
for (int i = 0; *s; i++)
|
||||
{
|
||||
if (*s != SafeGetCharAt(pos + i))
|
||||
return false;
|
||||
s++;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
int TextReader::StyleAt(Position position)
|
||||
{
|
||||
return sc.UnsignedStyleAt(position);
|
||||
}
|
||||
|
||||
Line TextReader::GetLine(Position position)
|
||||
{
|
||||
return sc.LineFromPosition(position);
|
||||
}
|
||||
|
||||
Position TextReader::LineStart(Line line)
|
||||
{
|
||||
return sc.LineStart(line);
|
||||
}
|
||||
|
||||
FoldLevel TextReader::LevelAt(Line line)
|
||||
{
|
||||
return sc.FoldLevel(line);
|
||||
}
|
||||
|
||||
Position TextReader::Length()
|
||||
{
|
||||
if (lenDoc == -1)
|
||||
lenDoc = sc.Length();
|
||||
return lenDoc;
|
||||
}
|
||||
|
||||
int TextReader::GetLineState(Line line)
|
||||
{
|
||||
return sc.LineState(line);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find if there is a brace next to the caret, checking before caret first, then
|
||||
* after caret. If brace found also find its matching brace.
|
||||
* @return @c true if inside a bracket pair.
|
||||
*/
|
||||
bool CodeEditorHandler::SciFindMatchingBracePosition(Position &braceAtCaret, Position &braceOpposite, bool sloppy)
|
||||
{
|
||||
// Config
|
||||
const auto bracesStyle{ 0 };
|
||||
const int lexLanguage{ _call->Lexer() };
|
||||
|
||||
bool isInside = false;
|
||||
|
||||
const int mainSel = _call->MainSelection();
|
||||
if (_call->SelectionNCaretVirtualSpace(mainSel) > 0)
|
||||
return false;
|
||||
|
||||
const int bracesStyleCheck = bracesStyle;
|
||||
Position caretPos = _call->CurrentPos();
|
||||
braceAtCaret = -1;
|
||||
braceOpposite = -1;
|
||||
char charBefore = '\0';
|
||||
int styleBefore = 0;
|
||||
const Position lengthDoc = _call->Length();
|
||||
TextReader acc(*_call);
|
||||
if ((lengthDoc > 0) && (caretPos > 0))
|
||||
{
|
||||
// Check to ensure not matching brace that is part of a multibyte character
|
||||
if (_call->PositionBefore(caretPos) == (caretPos - 1))
|
||||
{
|
||||
charBefore = acc[caretPos - 1];
|
||||
styleBefore = acc.StyleAt(caretPos - 1);
|
||||
}
|
||||
}
|
||||
// Priority goes to character before caret
|
||||
if (charBefore && IsBrace(charBefore) &&
|
||||
((styleBefore == bracesStyleCheck) || (!bracesStyle)))
|
||||
{
|
||||
braceAtCaret = caretPos - 1;
|
||||
}
|
||||
bool colonMode = false;
|
||||
if ((lexLanguage == SCLEX_PYTHON) &&
|
||||
(':' == charBefore) && (SCE_P_OPERATOR == styleBefore))
|
||||
{
|
||||
braceAtCaret = caretPos - 1;
|
||||
colonMode = true;
|
||||
}
|
||||
bool isAfter = true;
|
||||
if (lengthDoc > 0 && sloppy && (braceAtCaret < 0) && (caretPos < lengthDoc))
|
||||
{
|
||||
// No brace found so check other side
|
||||
// Check to ensure not matching brace that is part of a multibyte character
|
||||
if (_call->PositionAfter(caretPos) == (caretPos + 1))
|
||||
{
|
||||
const char charAfter = acc[caretPos];
|
||||
const int styleAfter = acc.StyleAt(caretPos);
|
||||
if (charAfter && IsBrace(charAfter) && ((styleAfter == bracesStyleCheck) || (!bracesStyle)))
|
||||
{
|
||||
braceAtCaret = caretPos;
|
||||
isAfter = false;
|
||||
}
|
||||
if ((lexLanguage == SCLEX_PYTHON) &&
|
||||
(':' == charAfter) && (SCE_P_OPERATOR == styleAfter))
|
||||
{
|
||||
braceAtCaret = caretPos;
|
||||
colonMode = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (braceAtCaret >= 0)
|
||||
{
|
||||
if (colonMode)
|
||||
{
|
||||
const Line lineStart = _call->LineFromPosition(braceAtCaret);
|
||||
const Line lineMaxSubord = _call->LastChild(lineStart, static_cast<FoldLevel>(-1));
|
||||
braceOpposite = _call->LineEnd(lineMaxSubord);
|
||||
}
|
||||
else
|
||||
{
|
||||
braceOpposite = _call->BraceMatch(braceAtCaret, 0);
|
||||
}
|
||||
if (braceOpposite > braceAtCaret)
|
||||
{
|
||||
isInside = isAfter;
|
||||
}
|
||||
else
|
||||
{
|
||||
isInside = !isAfter;
|
||||
}
|
||||
}
|
||||
return isInside;
|
||||
}
|
||||
|
||||
void CodeEditorHandler::SciBraceMatch()
|
||||
{
|
||||
// Config
|
||||
const auto bracesCheck{ true };
|
||||
const auto bracesSloppy{ true };
|
||||
|
||||
if (!bracesCheck)
|
||||
return;
|
||||
Position braceAtCaret = -1;
|
||||
Position braceOpposite = -1;
|
||||
SciFindMatchingBracePosition(braceAtCaret, braceOpposite, bracesSloppy);
|
||||
if ((braceAtCaret != -1) && (braceOpposite == -1))
|
||||
{
|
||||
//_call->BraceBadLight(braceAtCaret);
|
||||
_call->BraceBadLight(-1);
|
||||
_call->SetHighlightGuide(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
char chBrace = 0;
|
||||
if (braceAtCaret >= 0)
|
||||
chBrace = _call->CharacterAt(braceAtCaret);
|
||||
_call->BraceHighlight(braceAtCaret, braceOpposite);
|
||||
Position columnAtCaret = _call->Column(braceAtCaret);
|
||||
Position columnOpposite = _call->Column(braceOpposite);
|
||||
if (chBrace == ':')
|
||||
{
|
||||
const Line lineStart = _call->LineFromPosition(braceAtCaret);
|
||||
const Position indentPos = _call->LineIndentPosition(lineStart);
|
||||
const Position indentPosNext = _call->LineIndentPosition(lineStart + 1);
|
||||
columnAtCaret = _call->Column(indentPos);
|
||||
const Position columnAtCaretNext = _call->Column(indentPosNext);
|
||||
const int indentSize = _call->Indent();
|
||||
if (columnAtCaretNext - indentSize > 1)
|
||||
columnAtCaret = columnAtCaretNext - indentSize;
|
||||
if (columnOpposite == 0) // If the final line of the structure is empty
|
||||
columnOpposite = columnAtCaret;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_call->LineFromPosition(braceAtCaret) == _call->LineFromPosition(braceOpposite))
|
||||
{
|
||||
// Avoid attempting to draw a highlight guide
|
||||
columnAtCaret = 0;
|
||||
columnOpposite = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Todo: has rendering issues
|
||||
//if (props.GetInt("highlight.indentation.guides"))
|
||||
//_call->SetHighlightGuide(std::min(columnAtCaret, columnOpposite));
|
||||
}
|
||||
}
|
||||
|
||||
Line CodeEditorHandler::SciGetCurrentLineNumber()
|
||||
{
|
||||
return _call->LineFromPosition(
|
||||
_call->CurrentPos());
|
||||
}
|
||||
|
||||
int CodeEditorHandler::SciGetLineIndentation(Line line)
|
||||
{
|
||||
return _call->LineIndentation(line);
|
||||
}
|
||||
|
||||
Position CodeEditorHandler::SciGetLineIndentPosition(Line line)
|
||||
{
|
||||
return _call->LineIndentPosition(line);
|
||||
}
|
||||
|
||||
std::vector<std::string> CodeEditorHandler::SciGetLinePartsInStyle(Line line, const StyleAndWords &saw)
|
||||
{
|
||||
std::vector<std::string> sv;
|
||||
TextReader acc(*_call);
|
||||
std::string s;
|
||||
const bool separateCharacters = saw.IsSingleChar();
|
||||
const Position thisLineStart = _call->LineStart(line);
|
||||
const Position nextLineStart = _call->LineStart(line + 1);
|
||||
for (Position pos = thisLineStart; pos < nextLineStart; pos++)
|
||||
{
|
||||
if (acc.StyleAt(pos) == saw.Style())
|
||||
{
|
||||
if (separateCharacters)
|
||||
{
|
||||
// Add one character at a time, even if there is an adjacent character in the same style
|
||||
if (s.length() > 0)
|
||||
{
|
||||
sv.push_back(s);
|
||||
}
|
||||
s = "";
|
||||
}
|
||||
s += acc[pos];
|
||||
}
|
||||
else if (s.length() > 0)
|
||||
{
|
||||
sv.push_back(s);
|
||||
s = "";
|
||||
}
|
||||
}
|
||||
if (s.length() > 0)
|
||||
{
|
||||
sv.push_back(s);
|
||||
}
|
||||
return sv;
|
||||
}
|
||||
|
||||
IndentationStatus CodeEditorHandler::SciGetIndentState(Line line)
|
||||
{
|
||||
// C like language indentation defined by braces and keywords
|
||||
IndentationStatus indentState = IndentationStatus::none;
|
||||
const std::vector<std::string> controlIndents = SciGetLinePartsInStyle(line, _sciStatementIndent);
|
||||
for (const std::string &sIndent : controlIndents)
|
||||
{
|
||||
if (_sciStatementIndent.Includes(sIndent))
|
||||
indentState = IndentationStatus::keyWordStart;
|
||||
}
|
||||
const std::vector<std::string> controlEnds = SciGetLinePartsInStyle(line, _sciStatementEnd);
|
||||
for (const std::string &sEnd : controlEnds)
|
||||
{
|
||||
if (_sciStatementEnd.Includes(sEnd))
|
||||
indentState = IndentationStatus::none;
|
||||
}
|
||||
// Braces override keywords
|
||||
const std::vector<std::string> controlBlocks = SciGetLinePartsInStyle(line, _sciBlockEnd);
|
||||
for (const std::string &sBlock : controlBlocks)
|
||||
{
|
||||
if (_sciBlockEnd.Includes(sBlock))
|
||||
indentState = IndentationStatus::blockEnd;
|
||||
if (_sciBlockStart.Includes(sBlock))
|
||||
indentState = IndentationStatus::blockStart;
|
||||
}
|
||||
return indentState;
|
||||
}
|
||||
|
||||
int CodeEditorHandler::SciIndentOfBlock(Line line)
|
||||
{
|
||||
if (line < 0)
|
||||
return 0;
|
||||
const int indentSize = _call->Indent();
|
||||
int indentBlock = SciGetLineIndentation(line);
|
||||
Line backLine = line;
|
||||
IndentationStatus indentState = IndentationStatus::none;
|
||||
if (_sciStatementIndent.IsEmpty() && _sciBlockStart.IsEmpty() && _sciBlockEnd.IsEmpty())
|
||||
indentState = IndentationStatus::blockStart; // Don't bother searching backwards
|
||||
|
||||
Line lineLimit = line - _sciStatementLookback;
|
||||
if (lineLimit < 0)
|
||||
lineLimit = 0;
|
||||
while ((backLine >= lineLimit) && (indentState == IndentationStatus::none))
|
||||
{
|
||||
indentState = SciGetIndentState(backLine);
|
||||
if (indentState != IndentationStatus::none)
|
||||
{
|
||||
indentBlock = SciGetLineIndentation(backLine);
|
||||
if (indentState == IndentationStatus::blockStart)
|
||||
{
|
||||
if (!_sciIndentOpening)
|
||||
indentBlock += indentSize;
|
||||
}
|
||||
if (indentState == IndentationStatus::blockEnd)
|
||||
{
|
||||
if (_sciIndentClosing)
|
||||
indentBlock -= indentSize;
|
||||
if (indentBlock < 0)
|
||||
indentBlock = 0;
|
||||
}
|
||||
if ((indentState == IndentationStatus::keyWordStart) && (backLine == line))
|
||||
indentBlock += indentSize;
|
||||
}
|
||||
backLine--;
|
||||
}
|
||||
return indentBlock;
|
||||
}
|
||||
|
||||
Span CodeEditorHandler::SciGetSelection()
|
||||
{
|
||||
return _call->SelectionSpan();
|
||||
}
|
||||
|
||||
void CodeEditorHandler::SciSetSelection(Position anchor, Position currentPos)
|
||||
{
|
||||
_call->SetSel(anchor, currentPos);
|
||||
}
|
||||
|
||||
void CodeEditorHandler::SciSetLineIndentation(Line line, int indent)
|
||||
{
|
||||
if (indent < 0)
|
||||
return;
|
||||
const Span rangeStart = SciGetSelection();
|
||||
Span range = rangeStart;
|
||||
const Position posBefore = SciGetLineIndentPosition(line);
|
||||
_call->SetLineIndentation(line, indent);
|
||||
const Position posAfter = SciGetLineIndentPosition(line);
|
||||
const Position posDifference = posAfter - posBefore;
|
||||
if (posAfter > posBefore)
|
||||
{
|
||||
// Move selection on
|
||||
if (range.start >= posBefore)
|
||||
{
|
||||
range.start += posDifference;
|
||||
}
|
||||
if (range.end >= posBefore)
|
||||
{
|
||||
range.end += posDifference;
|
||||
}
|
||||
}
|
||||
else if (posAfter < posBefore)
|
||||
{
|
||||
// Move selection back
|
||||
if (range.start >= posAfter)
|
||||
{
|
||||
if (range.start >= posBefore)
|
||||
range.start += posDifference;
|
||||
else
|
||||
range.start = posAfter;
|
||||
}
|
||||
if (range.end >= posAfter)
|
||||
{
|
||||
if (range.end >= posBefore)
|
||||
range.end += posDifference;
|
||||
else
|
||||
range.end = posAfter;
|
||||
}
|
||||
}
|
||||
if (!(rangeStart == range))
|
||||
{
|
||||
SciSetSelection(range.start, range.end);
|
||||
}
|
||||
}
|
||||
|
||||
bool CodeEditorHandler::SciRangeIsAllWhitespace(Position start, Position end)
|
||||
{
|
||||
TextReader acc(*_call);
|
||||
for (Position i = start; i < end; i++)
|
||||
{
|
||||
if ((acc[i] != ' ') && (acc[i] != '\t'))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void CodeEditorHandler::SciAutomaticIndentation(char ch)
|
||||
{
|
||||
const Span range = _call->SelectionSpan();
|
||||
const Position selStart = range.start;
|
||||
const Line curLine = SciGetCurrentLineNumber();
|
||||
const Position thisLineStart = _call->LineStart(curLine);
|
||||
const int indentSize = _call->Indent();
|
||||
int indentBlock = SciIndentOfBlock(curLine - 1);
|
||||
|
||||
if ((_call->Lexer() == SCLEX_PYTHON) &&
|
||||
/*(props.GetInt("indent.python.colon") == 1)*/ true)
|
||||
{
|
||||
const EndOfLine eolMode = _call->EOLMode();
|
||||
const int eolChar = (eolMode == EndOfLine::Cr ? '\r' : '\n');
|
||||
const int eolChars = (eolMode == EndOfLine::CrLf ? 2 : 1);
|
||||
const Position prevLineStart = _call->LineStart(curLine - 1);
|
||||
const Position prevIndentPos = SciGetLineIndentPosition(curLine - 1);
|
||||
const int indentExisting = SciGetLineIndentation(curLine);
|
||||
|
||||
if (ch == eolChar)
|
||||
{
|
||||
// Find last noncomment, nonwhitespace character on previous line
|
||||
char character = '\0';
|
||||
int style = 0;
|
||||
for (Position p = selStart - eolChars - 1; p > prevLineStart; p--)
|
||||
{
|
||||
style = _call->UnsignedStyleAt(p);
|
||||
if (style != SCE_P_DEFAULT && style != SCE_P_COMMENTLINE &&
|
||||
style != SCE_P_COMMENTBLOCK)
|
||||
{
|
||||
character = _call->CharacterAt(p);
|
||||
break;
|
||||
}
|
||||
}
|
||||
indentBlock = SciGetLineIndentation(curLine - 1);
|
||||
if (style == SCE_P_OPERATOR && character == ':')
|
||||
{
|
||||
SciSetLineIndentation(curLine, indentBlock + indentSize);
|
||||
}
|
||||
else if (selStart == prevIndentPos + eolChars)
|
||||
{
|
||||
// Preserve the indentation of preexisting text beyond the caret
|
||||
SciSetLineIndentation(curLine, indentBlock + indentExisting);
|
||||
}
|
||||
else
|
||||
{
|
||||
SciSetLineIndentation(curLine, indentBlock);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (_sciBlockEnd.IsCharacter(ch))
|
||||
{ // Dedent maybe
|
||||
if (!_sciIndentClosing)
|
||||
{
|
||||
if (SciRangeIsAllWhitespace(thisLineStart, selStart - 1))
|
||||
{
|
||||
SciSetLineIndentation(curLine, indentBlock - indentSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (!_sciBlockEnd.IsSingleChar() && (ch == ' '))
|
||||
{ // Dedent maybe
|
||||
if (!_sciIndentClosing && (SciGetIndentState(curLine) == IndentationStatus::blockEnd)) {}
|
||||
}
|
||||
else if (_sciBlockStart.IsCharacter(ch))
|
||||
{
|
||||
// Dedent maybe if first on line and previous line was starting keyword
|
||||
if (!_sciIndentOpening && (SciGetIndentState(curLine - 1) == IndentationStatus::keyWordStart))
|
||||
{
|
||||
if (SciRangeIsAllWhitespace(thisLineStart, selStart - 1))
|
||||
{
|
||||
SciSetLineIndentation(curLine, indentBlock - indentSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ((ch == '\r' || ch == '\n') && (selStart == thisLineStart))
|
||||
{
|
||||
if (!_sciIndentClosing && !_sciBlockEnd.IsSingleChar())
|
||||
{ // Dedent previous line maybe
|
||||
const std::vector<std::string> controlWords = SciGetLinePartsInStyle(curLine - 1, _sciBlockEnd);
|
||||
if (!controlWords.empty())
|
||||
{
|
||||
if (_sciBlockEnd.Includes(controlWords[0]))
|
||||
{
|
||||
// Check if first keyword on line is an ender
|
||||
SciSetLineIndentation(curLine - 1, SciIndentOfBlock(curLine - 2) - indentSize);
|
||||
// Recalculate as may have changed previous line
|
||||
indentBlock = SciIndentOfBlock(curLine - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
SciSetLineIndentation(curLine, indentBlock);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,91 +0,0 @@
|
|||
// This file includes code derived from SciTEBase.h and StyleWriter.h
|
||||
// Copyright 1998-2011 by Neil Hodgson <neilh@scintilla.org>
|
||||
// The scintilla\License.txt file describes the conditions under which this software may be distributed.
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace WinUIEditor::Internal
|
||||
{
|
||||
enum class IndentationStatus
|
||||
{
|
||||
none, // no effect on indentation
|
||||
blockStart, // indentation block begin such as "{" or VB "function"
|
||||
blockEnd, // indentation end indicator such as "}" or VB "end"
|
||||
keyWordStart, // Keywords that cause indentation
|
||||
};
|
||||
|
||||
class StyleAndWords
|
||||
{
|
||||
int styleNumber = 0;
|
||||
std::set<std::string> words;
|
||||
public:
|
||||
StyleAndWords() noexcept;
|
||||
explicit StyleAndWords(const std::string &definition);
|
||||
StyleAndWords(int style, const std::set<std::string> &words);
|
||||
[[nodiscard]] bool IsEmpty() const noexcept;
|
||||
[[nodiscard]] bool IsSingleChar() const noexcept;
|
||||
[[nodiscard]] bool IsCharacter(char ch) const noexcept;
|
||||
[[nodiscard]] int Style() const noexcept;
|
||||
[[nodiscard]] bool Includes(const std::string &value) const;
|
||||
};
|
||||
|
||||
// Read only access to a document, its styles and other data
|
||||
class TextReader
|
||||
{
|
||||
protected:
|
||||
static constexpr Scintilla::Position extremePosition = INTPTR_MAX;
|
||||
/** @a bufferSize is a trade off between time taken to copy the characters
|
||||
* and retrieval overhead.
|
||||
* @a slopSize positions the buffer before the desired position
|
||||
* in case there is some backtracking. */
|
||||
static constexpr Scintilla::Position bufferSize = 4000;
|
||||
static constexpr Scintilla::Position slopSize = bufferSize / 8;
|
||||
char buf[bufferSize + 1];
|
||||
Scintilla::Position startPos;
|
||||
Scintilla::Position endPos;
|
||||
int codePage;
|
||||
|
||||
Scintilla::ScintillaCall ≻
|
||||
Scintilla::Position lenDoc;
|
||||
|
||||
void Fill(Scintilla::Position position);
|
||||
public:
|
||||
explicit TextReader(Scintilla::ScintillaCall &sc_) noexcept;
|
||||
// Deleted so TextReader objects can not be copied.
|
||||
TextReader(const TextReader &source) = delete;
|
||||
TextReader &operator=(const TextReader &) = delete;
|
||||
char operator[](Scintilla::Position position)
|
||||
{
|
||||
if (position < startPos || position >= endPos)
|
||||
{
|
||||
Fill(position);
|
||||
}
|
||||
return buf[position - startPos];
|
||||
}
|
||||
/** Safe version of operator[], returning a defined value for invalid position. */
|
||||
char SafeGetCharAt(Scintilla::Position position, char chDefault = ' ')
|
||||
{
|
||||
if (position < startPos || position >= endPos)
|
||||
{
|
||||
Fill(position);
|
||||
if (position < startPos || position >= endPos)
|
||||
{
|
||||
// Position is outside range of document
|
||||
return chDefault;
|
||||
}
|
||||
}
|
||||
return buf[position - startPos];
|
||||
}
|
||||
void SetCodePage(int codePage_) noexcept
|
||||
{
|
||||
codePage = codePage_;
|
||||
}
|
||||
bool Match(Scintilla::Position pos, const char *s);
|
||||
int StyleAt(Scintilla::Position position);
|
||||
Scintilla::Line GetLine(Scintilla::Position position);
|
||||
Scintilla::Position LineStart(Scintilla::Line line);
|
||||
Scintilla::FoldLevel LevelAt(Scintilla::Line line);
|
||||
Scintilla::Position Length();
|
||||
int GetLineState(Scintilla::Line line);
|
||||
};
|
||||
}
|
|
@ -1,395 +0,0 @@
|
|||
#include "CodeEditorHandler.h"
|
||||
#include "SciLexer.h"
|
||||
#include "TextMateScope.h"
|
||||
#include "DarkPlus.h"
|
||||
#include "LightPlus.h"
|
||||
|
||||
using namespace Scintilla;
|
||||
|
||||
namespace WinUIEditor
|
||||
{
|
||||
static constexpr auto WINUI_SCE_HJ_KEYWORD2{ 53 };
|
||||
|
||||
void CodeEditorHandler::SetLexer()
|
||||
{
|
||||
if (_highlightingLanguage == L"cpp")
|
||||
{
|
||||
const auto lexer{ _createLexer("cpp") };
|
||||
lexer->PropertySet("fold", "1");
|
||||
_call->SetILexer(lexer);
|
||||
// This list of keywords from SciTe (cpp.properties)
|
||||
_call->SetKeyWords(0,
|
||||
"alignas alignof and and_eq asm audit auto axiom bitand bitor bool "
|
||||
"char char8_t char16_t char32_t class compl concept "
|
||||
"const consteval constexpr const_cast "
|
||||
"decltype default delete double dynamic_cast enum explicit export extern false final float "
|
||||
"friend import inline int long module mutable namespace new noexcept not not_eq nullptr "
|
||||
"operator or or_eq override private protected public "
|
||||
"register reinterpret_cast requires "
|
||||
"short signed sizeof static static_assert static_cast struct "
|
||||
"template this thread_local true typedef typeid typename union unsigned using "
|
||||
"virtual void volatile wchar_t xor xor_eq");
|
||||
_call->SetKeyWords(1,
|
||||
"break case catch co_await co_return co_yield continue do else for goto if return switch throw try while");
|
||||
_call->SetKeyWords(2,
|
||||
"a addindex addtogroup anchor arg attention"
|
||||
"author b brief bug c class code date def defgroup deprecated dontinclude"
|
||||
"e em endcode endhtmlonly endif endlatexonly endlink endverbatim enum example exception"
|
||||
"f$ f[ f] file fn hideinitializer htmlinclude htmlonly"
|
||||
"if image include ingroup internal invariant interface latexonly li line link"
|
||||
"mainpage name namespace nosubgrouping note overload"
|
||||
"p page par param param[in] param[out]"
|
||||
"post pre ref relates remarks return retval"
|
||||
"sa section see showinitializer since skip skipline struct subsection"
|
||||
"test throw throws todo typedef union until"
|
||||
"var verbatim verbinclude version warning weakgroup $ @ \\ & < > # { }");
|
||||
SetLanguageIndentMode(
|
||||
SCE_C_WORD2, { "case", "default", "do", "else", "for", "if", "while", },
|
||||
SCE_C_OPERATOR, { ";", },
|
||||
SCE_C_OPERATOR, { "{", },
|
||||
SCE_C_OPERATOR, { "}", });
|
||||
}
|
||||
else if (_highlightingLanguage == L"csharp")
|
||||
{
|
||||
const auto lexer{ _createLexer("cpp") };
|
||||
lexer->PropertySet("fold", "1");
|
||||
_call->SetILexer(lexer);
|
||||
// This list of keywords from SciTe (cpp.properties) and https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/
|
||||
_call->SetKeyWords(0,
|
||||
"abstract as ascending async await base bool by byte char checked "
|
||||
"class const decimal default delegate descending double enum "
|
||||
"equals event explicit extern false fixed float from get group "
|
||||
"implicit in int interface internal into is join lock let long nameof namespace new nint null "
|
||||
"object on operator orderby out override params partial private protected public "
|
||||
"readonly ref sbyte sealed select set short sizeof stackalloc static "
|
||||
"string struct this true typeof uint ulong"
|
||||
"unchecked unsafe ushort var virtual void volatile where");
|
||||
_call->SetKeyWords(1,
|
||||
"break case catch continue do else finally for foreach goto if return switch throw try using while yield");
|
||||
// XML document comments from https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/language-specification/documentation-comments#d31-general
|
||||
_call->SetKeyWords(2,
|
||||
"c code example exception include list para param paramref permission remarks returns see seealso summary typeparam typeparamref value");
|
||||
SetLanguageIndentMode(
|
||||
SCE_C_WORD2, { "case", "default", "do", "else", "for", "foreach", "if", "using", "while", },
|
||||
SCE_C_OPERATOR, { ";", },
|
||||
SCE_C_OPERATOR, { "{", },
|
||||
SCE_C_OPERATOR, { "}", });
|
||||
}
|
||||
else if (_highlightingLanguage == L"javascript")
|
||||
{
|
||||
const auto lexer{ _createLexer("cpp") };
|
||||
lexer->PropertySet("fold", "1");
|
||||
_call->SetILexer(lexer);
|
||||
SetJavaScriptDefaults(0, 1, SCE_C_WORD2, SCE_C_OPERATOR);
|
||||
}
|
||||
else if (_highlightingLanguage == L"json")
|
||||
{
|
||||
const auto lexer{ _createLexer("json") };
|
||||
lexer->PropertySet("fold", "1");
|
||||
lexer->PropertySet("lexer.json.allow.comments", "1");
|
||||
lexer->PropertySet("lexer.json.escape.sequence", "1");
|
||||
_call->SetILexer(lexer);
|
||||
// This list of keywords from SciTe (json.properties)
|
||||
_call->SetKeyWords(0, "false true null");
|
||||
_call->SetKeyWords(1,
|
||||
"@id @context @type @value @language @container @list @set @reverse @index @base @vocab @graph");
|
||||
SetLanguageIndentMode(
|
||||
0, { },
|
||||
0, { },
|
||||
SCE_JSON_OPERATOR, { "{", "[", },
|
||||
SCE_JSON_OPERATOR, { "}", "]", });
|
||||
}
|
||||
else if (_highlightingLanguage == L"xml" || _highlightingLanguage == L"html")
|
||||
{
|
||||
const auto lexer{ _createLexer(_highlightingLanguage == L"xml" ? "xml" : "hypertext") };
|
||||
lexer->PropertySet("fold", "1");
|
||||
lexer->PropertySet("fold.html", "1");
|
||||
lexer->PropertySet("winuiedit.style.tag.brackets.as.tag.end", "1");
|
||||
_call->SetILexer(lexer);
|
||||
if (_highlightingLanguage == L"html")
|
||||
{
|
||||
_call->SetKeyWords(5, "ELEMENT DOCTYPE doctype ATTLIST ENTITY NOTATION");
|
||||
|
||||
SetJavaScriptDefaults(1, 6, WINUI_SCE_HJ_KEYWORD2, SCE_HJ_SYMBOLS);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetLanguageIndentMode(0, { }, 0, { }, 0, { }, 0, { });
|
||||
}
|
||||
}
|
||||
else if (_highlightingLanguage == L"plaintext")
|
||||
{
|
||||
_call->SetILexer(_createLexer("null"));
|
||||
SetLanguageIndentMode(0, { }, 0, { }, 0, { }, 0, { });
|
||||
}
|
||||
else
|
||||
{
|
||||
_call->SetILexer(nullptr);
|
||||
SetLanguageIndentMode(0, { }, 0, { }, 0, { }, 0, { });
|
||||
}
|
||||
if (_highlightingLanguage == L"cpp" || _highlightingLanguage == L"csharp" || _highlightingLanguage == L"javascript")
|
||||
{
|
||||
_call->SetKeyWords(5, "todo toDo Todo ToDo TODO fixme fixMe Fixme FixMe FIXME");
|
||||
}
|
||||
}
|
||||
|
||||
void CodeEditorHandler::SetJavaScriptDefaults(int wordList1, int wordList2, int indentKeywordStyle, int symbolStyle)
|
||||
{
|
||||
// This list of keywords from MDN https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Lexical_grammar#keywords
|
||||
// Note additional words like undefined
|
||||
_call->SetKeyWords(wordList1,
|
||||
"class const debugger delete export extends false function in instanceof "
|
||||
"new null super this true typeof var void let static enum implements "
|
||||
"interface private protected public arguments async get of set Infinity NaN undefined");
|
||||
_call->SetKeyWords(wordList2,
|
||||
"break case catch continue default do else finally for if import return "
|
||||
"switch throw try while with yield await package as from");
|
||||
SetLanguageIndentMode(
|
||||
indentKeywordStyle, { "case", "default", "do", "else", "for", "if", "while", },
|
||||
symbolStyle, { ";", },
|
||||
symbolStyle, { "{", "[" },
|
||||
symbolStyle, { "}", "]" });
|
||||
}
|
||||
|
||||
void CodeEditorHandler::UpdateLanguageStyles()
|
||||
{
|
||||
if (_highlightingLanguage == L"cpp" || _highlightingLanguage == L"csharp" || _highlightingLanguage == L"javascript")
|
||||
{
|
||||
switch (_theme)
|
||||
{
|
||||
case CodeEditorTheme::Dark:
|
||||
StyleSetFore(static_cast<int>(StylesCommon::Default), DarkPlusEditorForeground);
|
||||
StyleClearCustom();
|
||||
|
||||
StyleSetFore(static_cast<int>(StylesCommon::BraceLight), DarkPlusEditorForeground);
|
||||
|
||||
StyleSetFore(SCE_C_COMMENT, DarkPlus2(Scope::Comment));
|
||||
StyleSetFore(SCE_C_COMMENTLINE, DarkPlus2(Scope::Comment));
|
||||
StyleSetFore(SCE_C_COMMENTDOC, DarkPlus2(Scope::Comment));
|
||||
StyleSetFore(SCE_C_NUMBER, DarkPlus2(Scope::ConstantNumeric));
|
||||
StyleSetFore(SCE_C_WORD, DarkPlus2(Scope::Keyword));
|
||||
StyleSetFore(SCE_C_STRING, DarkPlus2(Scope::String));
|
||||
StyleSetFore(SCE_C_CHARACTER, DarkPlus2(Scope::String));
|
||||
StyleSetFore(SCE_C_UUID, DarkPlus2(Scope::ConstantNumeric));
|
||||
StyleSetFore(SCE_C_PREPROCESSOR, DarkPlus2(Scope::MetaPreprocessor));
|
||||
StyleSetFore(SCE_C_OPERATOR, DarkPlus2(Scope::KeywordOperator));
|
||||
if (_highlightingLanguage != L"cpp")
|
||||
{
|
||||
StyleSetFore(SCE_C_IDENTIFIER, DarkPlus2(Scope::Variable));
|
||||
}
|
||||
StyleSetFore(SCE_C_STRINGEOL, DarkPlus2(Scope::String));
|
||||
StyleSetFore(SCE_C_VERBATIM, DarkPlus2(Scope::String));
|
||||
StyleSetFore(SCE_C_REGEX, DarkPlus2(Scope::StringRegexp));
|
||||
StyleSetFore(SCE_C_COMMENTLINEDOC, DarkPlus2(Scope::Comment));
|
||||
StyleSetFore(SCE_C_WORD2, DarkPlus2(Scope::KeywordControl));
|
||||
StyleSetFore(SCE_C_COMMENTDOCKEYWORD, DarkPlus2(Scope::Keyword));
|
||||
StyleSetFore(SCE_C_COMMENTDOCKEYWORDERROR, DarkPlus2(Scope::Comment));
|
||||
StyleSetFore(SCE_C_GLOBALCLASS, DarkPlus2(Scope::EntityNameType));
|
||||
StyleSetFore(SCE_C_STRINGRAW, DarkPlus2(Scope::String));
|
||||
StyleSetFore(SCE_C_TRIPLEVERBATIM, DarkPlus2(Scope::String));
|
||||
StyleSetFore(SCE_C_HASHQUOTEDSTRING, DarkPlus2(Scope::String));
|
||||
StyleSetFore(SCE_C_PREPROCESSORCOMMENT, DarkPlus2(Scope::Comment));
|
||||
StyleSetFore(SCE_C_PREPROCESSORCOMMENTDOC, DarkPlus2(Scope::Comment));
|
||||
StyleSetFore(SCE_C_USERLITERAL, DarkPlus2(Scope::KeywordOtherUnit));
|
||||
StyleSetFore(SCE_C_TASKMARKER, DarkPlus2(Scope::Comment));
|
||||
_call->StyleSetItalic(SCE_C_TASKMARKER, true);
|
||||
_call->StyleSetBold(SCE_C_TASKMARKER, true);
|
||||
StyleSetFore(SCE_C_ESCAPESEQUENCE, DarkPlus2(Scope::ConstantCharacterEscape));
|
||||
break;
|
||||
|
||||
case CodeEditorTheme::Light:
|
||||
StyleSetFore(static_cast<int>(StylesCommon::Default), LightPlusEditorForeground);
|
||||
StyleClearCustom();
|
||||
|
||||
StyleSetFore(static_cast<int>(StylesCommon::BraceLight), LightPlusEditorForeground);
|
||||
|
||||
StyleSetFore(SCE_C_COMMENT, LightPlus2(Scope::Comment));
|
||||
StyleSetFore(SCE_C_COMMENTLINE, LightPlus2(Scope::Comment));
|
||||
StyleSetFore(SCE_C_COMMENTDOC, LightPlus2(Scope::Comment));
|
||||
StyleSetFore(SCE_C_NUMBER, LightPlus2(Scope::ConstantNumeric));
|
||||
StyleSetFore(SCE_C_WORD, LightPlus2(Scope::Keyword));
|
||||
StyleSetFore(SCE_C_STRING, LightPlus2(Scope::String));
|
||||
StyleSetFore(SCE_C_CHARACTER, LightPlus2(Scope::String));
|
||||
StyleSetFore(SCE_C_UUID, LightPlus2(Scope::ConstantNumeric));
|
||||
StyleSetFore(SCE_C_PREPROCESSOR, LightPlus2(Scope::MetaPreprocessor));
|
||||
StyleSetFore(SCE_C_OPERATOR, LightPlus2(Scope::KeywordOperator));
|
||||
if (_highlightingLanguage != L"cpp")
|
||||
{
|
||||
StyleSetFore(SCE_C_IDENTIFIER, LightPlus2(Scope::Variable));
|
||||
}
|
||||
StyleSetFore(SCE_C_STRINGEOL, LightPlus2(Scope::String));
|
||||
StyleSetFore(SCE_C_VERBATIM, LightPlus2(Scope::String));
|
||||
StyleSetFore(SCE_C_REGEX, LightPlus2(Scope::StringRegexp));
|
||||
StyleSetFore(SCE_C_COMMENTLINEDOC, LightPlus2(Scope::Comment));
|
||||
StyleSetFore(SCE_C_WORD2, LightPlus2(Scope::KeywordControl));
|
||||
StyleSetFore(SCE_C_COMMENTDOCKEYWORD, LightPlus2(Scope::Keyword));
|
||||
StyleSetFore(SCE_C_COMMENTDOCKEYWORDERROR, LightPlus2(Scope::Comment));
|
||||
StyleSetFore(SCE_C_GLOBALCLASS, LightPlus2(Scope::EntityNameType));
|
||||
StyleSetFore(SCE_C_STRINGRAW, LightPlus2(Scope::String));
|
||||
StyleSetFore(SCE_C_TRIPLEVERBATIM, LightPlus2(Scope::String));
|
||||
StyleSetFore(SCE_C_HASHQUOTEDSTRING, LightPlus2(Scope::String));
|
||||
StyleSetFore(SCE_C_PREPROCESSORCOMMENT, LightPlus2(Scope::Comment));
|
||||
StyleSetFore(SCE_C_PREPROCESSORCOMMENTDOC, LightPlus2(Scope::Comment));
|
||||
StyleSetFore(SCE_C_USERLITERAL, LightPlus2(Scope::KeywordOtherUnit));
|
||||
StyleSetFore(SCE_C_TASKMARKER, LightPlus2(Scope::Comment));
|
||||
_call->StyleSetItalic(SCE_C_TASKMARKER, true);
|
||||
_call->StyleSetBold(SCE_C_TASKMARKER, true);
|
||||
StyleSetFore(SCE_C_ESCAPESEQUENCE, LightPlus2(Scope::ConstantCharacterEscape));
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (_highlightingLanguage == L"json")
|
||||
{
|
||||
switch (_theme)
|
||||
{
|
||||
case CodeEditorTheme::Dark:
|
||||
StyleSetFore(static_cast<int>(StylesCommon::Default), DarkPlusEditorForeground);
|
||||
StyleClearCustom();
|
||||
|
||||
StyleSetFore(static_cast<int>(StylesCommon::BraceLight), DarkPlusEditorForeground);
|
||||
|
||||
StyleSetFore(SCE_JSON_NUMBER, DarkPlus2(Scope::ConstantNumeric));
|
||||
StyleSetFore(SCE_JSON_STRING, DarkPlus2(Scope::String));
|
||||
StyleSetFore(SCE_JSON_STRINGEOL, DarkPlus2(Scope::String));
|
||||
StyleSetFore(SCE_JSON_PROPERTYNAME, DarkPlus2(Scope::SupportTypeProperty_NameJson));
|
||||
StyleSetFore(SCE_JSON_ESCAPESEQUENCE, DarkPlus2(Scope::ConstantCharacterEscape));
|
||||
StyleSetFore(SCE_JSON_LINECOMMENT, DarkPlus2(Scope::Comment));
|
||||
StyleSetFore(SCE_JSON_BLOCKCOMMENT, DarkPlus2(Scope::Comment));
|
||||
StyleSetFore(SCE_JSON_OPERATOR, DarkPlus2(Scope::KeywordOperator));
|
||||
StyleSetFore(SCE_JSON_URI, DarkPlus2(Scope::String));
|
||||
_call->StyleSetUnderline(SCE_JSON_URI, true);
|
||||
StyleSetFore(SCE_JSON_COMPACTIRI, DarkPlus2(Scope::String));
|
||||
StyleSetFore(SCE_JSON_KEYWORD, DarkPlus2(Scope::ConstantLanguage));
|
||||
StyleSetFore(SCE_JSON_LDKEYWORD, DarkPlus2(Scope::KeywordControl));
|
||||
StyleSetFore(SCE_JSON_ERROR, DarkPlus2(Scope::Invalid));
|
||||
break;
|
||||
|
||||
case CodeEditorTheme::Light:
|
||||
StyleSetFore(static_cast<int>(StylesCommon::Default), LightPlusEditorForeground);
|
||||
StyleClearCustom();
|
||||
|
||||
StyleSetFore(static_cast<int>(StylesCommon::BraceLight), LightPlusEditorForeground);
|
||||
|
||||
StyleSetFore(SCE_JSON_NUMBER, LightPlus2(Scope::ConstantNumeric));
|
||||
StyleSetFore(SCE_JSON_STRING, LightPlus2(Scope::String));
|
||||
StyleSetFore(SCE_JSON_STRINGEOL, LightPlus2(Scope::String));
|
||||
StyleSetFore(SCE_JSON_PROPERTYNAME, LightPlus2(Scope::SupportTypeProperty_NameJson));
|
||||
StyleSetFore(SCE_JSON_ESCAPESEQUENCE, LightPlus2(Scope::ConstantCharacterEscape));
|
||||
StyleSetFore(SCE_JSON_LINECOMMENT, LightPlus2(Scope::Comment));
|
||||
StyleSetFore(SCE_JSON_BLOCKCOMMENT, LightPlus2(Scope::Comment));
|
||||
StyleSetFore(SCE_JSON_OPERATOR, LightPlus2(Scope::KeywordOperator));
|
||||
StyleSetFore(SCE_JSON_URI, LightPlus2(Scope::String));
|
||||
_call->StyleSetUnderline(SCE_JSON_URI, true);
|
||||
StyleSetFore(SCE_JSON_COMPACTIRI, LightPlus2(Scope::String));
|
||||
StyleSetFore(SCE_JSON_KEYWORD, LightPlus2(Scope::ConstantLanguage));
|
||||
StyleSetFore(SCE_JSON_LDKEYWORD, LightPlus2(Scope::KeywordControl));
|
||||
StyleSetFore(SCE_JSON_ERROR, LightPlus2(Scope::Invalid));
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (_highlightingLanguage == L"xml" || _highlightingLanguage == L"html")
|
||||
{
|
||||
const auto isHtml{ _highlightingLanguage == L"html" };
|
||||
switch (_theme)
|
||||
{
|
||||
case CodeEditorTheme::Dark:
|
||||
StyleSetFore(static_cast<int>(StylesCommon::Default), DarkPlusEditorForeground);
|
||||
StyleClearCustom();
|
||||
|
||||
StyleSetFore(static_cast<int>(StylesCommon::BraceLight), DarkPlusEditorForeground);
|
||||
|
||||
StyleSetFore(SCE_H_TAG, DarkPlus2(Scope::EntityNameTag));
|
||||
StyleSetFore(SCE_H_TAGUNKNOWN, DarkPlus2(Scope::EntityNameTag));
|
||||
StyleSetFore(SCE_H_ATTRIBUTE, DarkPlus2(Scope::EntityOtherAttribute_Name));
|
||||
StyleSetFore(SCE_H_ATTRIBUTEUNKNOWN, DarkPlus2(Scope::EntityOtherAttribute_Name));
|
||||
StyleSetFore(SCE_H_NUMBER, DarkPlus2(Scope::ConstantNumeric));
|
||||
StyleSetFore(SCE_H_DOUBLESTRING, DarkPlus2(Scope::String));
|
||||
StyleSetFore(SCE_H_SINGLESTRING, DarkPlus2(Scope::String));
|
||||
// ...
|
||||
StyleSetFore(SCE_H_COMMENT, DarkPlus2(Scope::Comment));
|
||||
StyleSetFore(SCE_H_ENTITY, DarkPlus2(Scope::ConstantCharacter));
|
||||
StyleSetFore(SCE_H_TAGEND, DarkPlus2(Scope::PunctuationDefinitionTag));
|
||||
StyleSetFore(SCE_H_XMLSTART, DarkPlus2(Scope::PunctuationDefinitionTag));
|
||||
StyleSetFore(SCE_H_XMLEND, DarkPlus2(Scope::PunctuationDefinitionTag));
|
||||
// ...
|
||||
StyleSetFore(SCE_H_CDATA, DarkPlus2(Scope::String));
|
||||
StyleSetFore(SCE_H_SGML_DEFAULT, DarkPlus2(Scope::PunctuationDefinitionTag));
|
||||
StyleSetFore(SCE_H_SGML_COMMAND, DarkPlus2(Scope::EntityNameTag));
|
||||
StyleSetFore(SCE_H_SGML_1ST_PARAM, DarkPlus2(Scope::EntityOtherAttribute_Name));
|
||||
StyleSetFore(SCE_H_SGML_DOUBLESTRING, DarkPlus2(Scope::String));
|
||||
// ...
|
||||
StyleSetFore(SCE_H_SGML_COMMENT, DarkPlus2(Scope::Comment));
|
||||
// ...
|
||||
if (isHtml)
|
||||
{
|
||||
StyleSetFore(SCE_H_VALUE, DarkPlus2(Scope::String));
|
||||
|
||||
StyleSetFore(SCE_HJ_COMMENT, DarkPlus2(Scope::Comment));
|
||||
StyleSetFore(SCE_HJ_COMMENTLINE, DarkPlus2(Scope::Comment));
|
||||
StyleSetFore(SCE_HJ_COMMENTDOC, DarkPlus2(Scope::Comment));
|
||||
StyleSetFore(SCE_HJ_NUMBER, DarkPlus2(Scope::ConstantNumeric));
|
||||
StyleSetFore(SCE_HJ_WORD, DarkPlus2(Scope::Variable));
|
||||
StyleSetFore(SCE_HJ_KEYWORD, DarkPlus2(Scope::Keyword));
|
||||
StyleSetFore(WINUI_SCE_HJ_KEYWORD2, DarkPlus2(Scope::KeywordControl));
|
||||
StyleSetFore(SCE_HJ_DOUBLESTRING, DarkPlus2(Scope::String));
|
||||
StyleSetFore(SCE_HJ_SINGLESTRING, DarkPlus2(Scope::String));
|
||||
StyleSetFore(SCE_HJ_SYMBOLS, DarkPlus2(Scope::KeywordOperator));
|
||||
StyleSetFore(SCE_HJ_STRINGEOL, DarkPlus2(Scope::String));
|
||||
StyleSetFore(SCE_HJ_REGEX, DarkPlus2(Scope::StringRegexp));
|
||||
}
|
||||
break;
|
||||
|
||||
case CodeEditorTheme::Light:
|
||||
StyleSetFore(static_cast<int>(StylesCommon::Default), LightPlusEditorForeground);
|
||||
StyleClearCustom();
|
||||
|
||||
StyleSetFore(static_cast<int>(StylesCommon::BraceLight), LightPlusEditorForeground);
|
||||
|
||||
StyleSetFore(SCE_H_TAG, LightPlus2(Scope::EntityNameTag));
|
||||
StyleSetFore(SCE_H_TAGUNKNOWN, LightPlus2(Scope::EntityNameTag));
|
||||
StyleSetFore(SCE_H_ATTRIBUTE, LightPlus2(Scope::EntityOtherAttribute_Name));
|
||||
StyleSetFore(SCE_H_ATTRIBUTEUNKNOWN, LightPlus2(Scope::EntityOtherAttribute_Name));
|
||||
StyleSetFore(SCE_H_NUMBER, LightPlus2(Scope::ConstantNumeric));
|
||||
StyleSetFore(SCE_H_DOUBLESTRING, isHtml ? LightPlus2(Scope::StringQuotedDoubleHtml) : LightPlus2(Scope::StringQuotedDoubleXml));
|
||||
StyleSetFore(SCE_H_SINGLESTRING, isHtml ? LightPlus2(Scope::StringQuotedSingleHtml) : LightPlus2(Scope::StringQuotedSingleXml));
|
||||
// ...
|
||||
StyleSetFore(SCE_H_COMMENT, LightPlus2(Scope::Comment));
|
||||
StyleSetFore(SCE_H_ENTITY, LightPlus2(Scope::ConstantCharacter));
|
||||
StyleSetFore(SCE_H_TAGEND, LightPlus2(Scope::PunctuationDefinitionTag));
|
||||
StyleSetFore(SCE_H_XMLSTART, LightPlus2(Scope::PunctuationDefinitionTag));
|
||||
StyleSetFore(SCE_H_XMLEND, LightPlus2(Scope::PunctuationDefinitionTag));
|
||||
// ...
|
||||
StyleSetFore(SCE_H_CDATA, isHtml ? LightPlus2(Scope::String) : LightPlus2(Scope::StringUnquotedCdataXml));
|
||||
StyleSetFore(SCE_H_SGML_DEFAULT, LightPlus2(Scope::PunctuationDefinitionTag));
|
||||
StyleSetFore(SCE_H_SGML_COMMAND, LightPlus2(Scope::EntityNameTag));
|
||||
StyleSetFore(SCE_H_SGML_1ST_PARAM, LightPlus2(Scope::EntityOtherAttribute_Name));
|
||||
StyleSetFore(SCE_H_SGML_DOUBLESTRING, LightPlus2(Scope::StringQuotedDoubleHtml));
|
||||
// ...
|
||||
StyleSetFore(SCE_H_SGML_COMMENT, LightPlus2(Scope::Comment));
|
||||
// ...
|
||||
if (isHtml)
|
||||
{
|
||||
StyleSetFore(SCE_H_VALUE, LightPlus2(Scope::StringUnquotedHtml));
|
||||
|
||||
StyleSetFore(SCE_HJ_COMMENT, LightPlus2(Scope::Comment));
|
||||
StyleSetFore(SCE_HJ_COMMENTLINE, LightPlus2(Scope::Comment));
|
||||
StyleSetFore(SCE_HJ_COMMENTDOC, LightPlus2(Scope::Comment));
|
||||
StyleSetFore(SCE_HJ_NUMBER, LightPlus2(Scope::ConstantNumeric));
|
||||
StyleSetFore(SCE_HJ_WORD, LightPlus2(Scope::Variable));
|
||||
StyleSetFore(SCE_HJ_KEYWORD, LightPlus2(Scope::Keyword));
|
||||
StyleSetFore(WINUI_SCE_HJ_KEYWORD2, LightPlus2(Scope::KeywordControl));
|
||||
StyleSetFore(SCE_HJ_DOUBLESTRING, LightPlus2(Scope::String));
|
||||
StyleSetFore(SCE_HJ_SINGLESTRING, LightPlus2(Scope::String));
|
||||
StyleSetFore(SCE_HJ_SYMBOLS, LightPlus2(Scope::KeywordOperator));
|
||||
StyleSetFore(SCE_HJ_STRINGEOL, LightPlus2(Scope::String));
|
||||
StyleSetFore(SCE_HJ_REGEX, LightPlus2(Scope::StringRegexp));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
StyleClearCustom();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,557 +0,0 @@
|
|||
#include "CodeEditorHandler.h"
|
||||
#include <cmath>
|
||||
#include "ScintillaMessages.h"
|
||||
|
||||
using namespace Scintilla;
|
||||
|
||||
namespace WinUIEditor
|
||||
{
|
||||
void CodeEditorHandler::SetScintilla(std::shared_ptr<ScintillaCall> call)
|
||||
{
|
||||
_call = call;
|
||||
}
|
||||
|
||||
void CodeEditorHandler::SetLexilla(Lexilla::CreateLexerFn createLexer)
|
||||
{
|
||||
_createLexer = createLexer;
|
||||
}
|
||||
|
||||
void CodeEditorHandler::Initialize()
|
||||
{
|
||||
AddKeyboardShortcuts();
|
||||
ChangeDefaults();
|
||||
ChangeDocumentDefaults();
|
||||
}
|
||||
|
||||
void CodeEditorHandler::ChangeDocumentDefaults()
|
||||
{
|
||||
_call->SetUseTabs(false);
|
||||
_call->SetTabWidth(4);
|
||||
_call->SetIndent(4); // Brace matching and autoindent relies on this
|
||||
}
|
||||
|
||||
void CodeEditorHandler::UpdateColors(CodeEditorTheme theme)
|
||||
{
|
||||
// Todo: Support high contrast mode
|
||||
|
||||
constexpr auto folderForeDark{ IntRGBA(0, 0, 0, 0) };
|
||||
constexpr auto folderBackDark{ IntRGBA(0xFF, 0xFF, 0xFF, 148) };
|
||||
constexpr auto folderBackHighlightDark{ folderBackDark };
|
||||
constexpr auto folderForeLight{ IntRGBA(0xFF, 0xFF, 0xFF, 0) };
|
||||
constexpr auto folderBackLight{ IntRGBA(0, 0, 0, 108) };
|
||||
constexpr auto folderBackHighlightLight{ folderBackLight };
|
||||
|
||||
if (_theme != theme)
|
||||
{
|
||||
_theme = theme;
|
||||
|
||||
switch (theme)
|
||||
{
|
||||
case CodeEditorTheme::Dark:
|
||||
_call->SetElementColour(Element::Caret, IntRGBA(0xAE, 0xAF, 0xAD));
|
||||
_call->SetElementColour(Element::SelectionBack, IntRGBA(0x26, 0x4F, 0x78));
|
||||
_call->SetElementColour(Element::SelectionAdditionalBack, IntRGBA(0x26, 0x4F, 0x78));
|
||||
_call->SetElementColour(Element::SelectionInactiveBack, IntRGBA(0x3A, 0x3D, 0x41));
|
||||
_call->SetElementColour(Element::HiddenLine, IntRGBA(0xFF, 0xFF, 0xFF, 48));
|
||||
|
||||
MarkerSetColors(Scintilla::MarkerOutline::FolderOpen, folderForeDark, folderBackDark, folderBackHighlightDark);
|
||||
MarkerSetColors(Scintilla::MarkerOutline::Folder, folderForeDark, folderBackDark, folderBackHighlightDark);
|
||||
MarkerSetColors(Scintilla::MarkerOutline::FolderSub, folderForeDark, folderBackDark, folderBackHighlightDark);
|
||||
MarkerSetColors(Scintilla::MarkerOutline::FolderTail, folderForeDark, folderBackDark, folderBackHighlightDark);
|
||||
MarkerSetColors(Scintilla::MarkerOutline::FolderEnd, folderForeDark, folderBackDark, folderBackHighlightDark);
|
||||
MarkerSetColors(Scintilla::MarkerOutline::FolderOpenMid, folderForeDark, folderBackDark, folderBackHighlightDark);
|
||||
MarkerSetColors(Scintilla::MarkerOutline::FolderMidTail, folderForeDark, folderBackDark, folderBackHighlightDark);
|
||||
|
||||
_call->MarkerSetForeTranslucent(static_cast<int>(Scintilla::MarkerOutline::HistoryRevertedToOrigin), IntRGBA(0x35, 0x95, 0xDE));
|
||||
_call->MarkerSetBackTranslucent(static_cast<int>(Scintilla::MarkerOutline::HistoryRevertedToOrigin), IntRGBA(0x35, 0x95, 0xDE, 0x00));
|
||||
_call->MarkerSetForeTranslucent(static_cast<int>(Scintilla::MarkerOutline::HistorySaved), IntRGBA(0x55, 0xB1, 0x55));
|
||||
_call->MarkerSetBackTranslucent(static_cast<int>(Scintilla::MarkerOutline::HistorySaved), IntRGBA(0x55, 0xB1, 0x55));
|
||||
_call->MarkerSetForeTranslucent(static_cast<int>(Scintilla::MarkerOutline::HistoryModified), IntRGBA(0xD0, 0xB1, 0x32));
|
||||
_call->MarkerSetBackTranslucent(static_cast<int>(Scintilla::MarkerOutline::HistoryModified), IntRGBA(0x27, 0x27, 0x27, 0x00));
|
||||
_call->MarkerSetForeTranslucent(static_cast<int>(Scintilla::MarkerOutline::HistoryRevertedToModified), IntRGBA(0x93, 0xB1, 0x44));
|
||||
_call->MarkerSetBackTranslucent(static_cast<int>(Scintilla::MarkerOutline::HistoryRevertedToModified), IntRGBA(0x93, 0xB1, 0x44, 0x00));
|
||||
break;
|
||||
|
||||
case CodeEditorTheme::Light:
|
||||
_call->SetElementColour(Element::Caret, IntRGBA(0x00, 0x00, 0x00));
|
||||
_call->SetElementColour(Element::SelectionBack, IntRGBA(0xAD, 0xD6, 0xFF));
|
||||
_call->SetElementColour(Element::SelectionAdditionalBack, IntRGBA(0xAD, 0xD6, 0xFF));
|
||||
_call->SetElementColour(Element::SelectionInactiveBack, IntRGBA(0xE5, 0xEB, 0xF1));
|
||||
_call->SetElementColour(Element::HiddenLine, IntRGBA(0x00, 0x00, 0x00, 64));
|
||||
|
||||
MarkerSetColors(Scintilla::MarkerOutline::FolderOpen, folderForeLight, folderBackLight, folderBackHighlightLight);
|
||||
MarkerSetColors(Scintilla::MarkerOutline::Folder, folderForeLight, folderBackLight, folderBackHighlightLight);
|
||||
MarkerSetColors(Scintilla::MarkerOutline::FolderSub, folderForeLight, folderBackLight, folderBackHighlightLight);
|
||||
MarkerSetColors(Scintilla::MarkerOutline::FolderTail, folderForeLight, folderBackLight, folderBackHighlightLight);
|
||||
MarkerSetColors(Scintilla::MarkerOutline::FolderEnd, folderForeLight, folderBackLight, folderBackHighlightLight);
|
||||
MarkerSetColors(Scintilla::MarkerOutline::FolderOpenMid, folderForeLight, folderBackLight, folderBackHighlightLight);
|
||||
MarkerSetColors(Scintilla::MarkerOutline::FolderMidTail, folderForeLight, folderBackLight, folderBackHighlightLight);
|
||||
|
||||
_call->MarkerSetForeTranslucent(static_cast<int>(Scintilla::MarkerOutline::HistoryRevertedToOrigin), IntRGBA(0x00, 0x78, 0xD4));
|
||||
_call->MarkerSetBackTranslucent(static_cast<int>(Scintilla::MarkerOutline::HistoryRevertedToOrigin), IntRGBA(0x00, 0x78, 0xD4, 0x00));
|
||||
_call->MarkerSetForeTranslucent(static_cast<int>(Scintilla::MarkerOutline::HistorySaved), IntRGBA(0x10, 0x7C, 0x10));
|
||||
_call->MarkerSetBackTranslucent(static_cast<int>(Scintilla::MarkerOutline::HistorySaved), IntRGBA(0x10, 0x7C, 0x10));
|
||||
_call->MarkerSetForeTranslucent(static_cast<int>(Scintilla::MarkerOutline::HistoryModified), IntRGBA(0xAE, 0x8C, 0x00));
|
||||
_call->MarkerSetBackTranslucent(static_cast<int>(Scintilla::MarkerOutline::HistoryModified), IntRGBA(0xF5, 0xF5, 0xF5, 0x00));
|
||||
_call->MarkerSetForeTranslucent(static_cast<int>(Scintilla::MarkerOutline::HistoryRevertedToModified), IntRGBA(0x5F, 0x84, 0x08));
|
||||
_call->MarkerSetBackTranslucent(static_cast<int>(Scintilla::MarkerOutline::HistoryRevertedToModified), IntRGBA(0x5F, 0x84, 0x08, 0x00));
|
||||
break;
|
||||
}
|
||||
|
||||
UpdateCaretLineBackColors(true);
|
||||
|
||||
UpdateStyles();
|
||||
}
|
||||
}
|
||||
|
||||
// Duplicated from Helpers.cpp to make portable
|
||||
// Derived from https://github.com/microsoft/Windows-universal-samples/blob/main/Samples/ComplexInk/cpp/Common/DeviceResources.h
|
||||
static constexpr int ConvertFromDipToPixelUnit(float val, float dpiAdjustmentRatio, bool rounded = true)
|
||||
{
|
||||
float pixelVal = val * dpiAdjustmentRatio;
|
||||
return static_cast<int>(rounded ? floorf(pixelVal + 0.5f) : pixelVal); // Todo: Test if this is ever necessary
|
||||
}
|
||||
|
||||
void CodeEditorHandler::UpdateDpi(double value)
|
||||
{
|
||||
_dpiScale = value;
|
||||
_call->SetXCaretPolicy(CaretPolicy::Slop | CaretPolicy::Strict | CaretPolicy::Even, ConvertFromDipToPixelUnit(24, value));
|
||||
UpdateZoom();
|
||||
}
|
||||
|
||||
void CodeEditorHandler::StyleSetFore(int style, ColourAlpha color)
|
||||
{
|
||||
// Overridable to allow users to internally set transparent color
|
||||
_call->StyleSetFore(style, color);
|
||||
}
|
||||
|
||||
void CodeEditorHandler::StyleSetBack(int style, ColourAlpha color)
|
||||
{
|
||||
// Overridable to allow users to internally set transparent color
|
||||
_call->StyleSetBack(style, color);
|
||||
}
|
||||
|
||||
void CodeEditorHandler::InvalidateStyleRedraw()
|
||||
{
|
||||
// Overridable to allow users to invalidate after setting all colors
|
||||
// Not needed if using default StyleSetFore/Back
|
||||
}
|
||||
|
||||
void CodeEditorHandler::StyleClearCustom()
|
||||
{
|
||||
// Less performant way to copy styles
|
||||
// Overridable when there is access to Scintilla internals
|
||||
for (size_t i = 0; i < 256; i++)
|
||||
{
|
||||
if (i < static_cast<int>(StylesCommon::Default) || i > static_cast<int>(StylesCommon::LastPredefined))
|
||||
{
|
||||
_call->StyleSetFont(i, _call->StyleGetFont(static_cast<int>(StylesCommon::Default)).c_str());
|
||||
_call->StyleSetSizeFractional(i, _call->StyleGetSizeFractional(static_cast<int>(StylesCommon::Default)));
|
||||
_call->StyleSetBold(i, _call->StyleGetBold(static_cast<int>(StylesCommon::Default)));
|
||||
_call->StyleSetWeight(i, _call->StyleGetWeight(static_cast<int>(StylesCommon::Default)));
|
||||
_call->StyleSetItalic(i, _call->StyleGetItalic(static_cast<int>(StylesCommon::Default)));
|
||||
_call->StyleSetUnderline(i, _call->StyleGetUnderline(static_cast<int>(StylesCommon::Default)));
|
||||
_call->StyleSetFore(i, _call->StyleGetFore(static_cast<int>(StylesCommon::Default)));
|
||||
_call->StyleSetBack(i, _call->StyleGetBack(static_cast<int>(StylesCommon::Default)));
|
||||
_call->StyleSetEOLFilled(i, _call->StyleGetEOLFilled(static_cast<int>(StylesCommon::Default)));
|
||||
_call->StyleSetCharacterSet(i, _call->StyleGetCharacterSet(static_cast<int>(StylesCommon::Default)));
|
||||
_call->StyleSetCase(i, _call->StyleGetCase(static_cast<int>(StylesCommon::Default)));
|
||||
_call->StyleSetVisible(i, _call->StyleGetVisible(static_cast<int>(StylesCommon::Default)));
|
||||
_call->StyleSetChangeable(i, _call->StyleGetChangeable(static_cast<int>(StylesCommon::Default)));
|
||||
_call->StyleSetHotSpot(i, _call->StyleGetHotSpot(static_cast<int>(StylesCommon::Default)));
|
||||
_call->StyleSetCheckMonospaced(i, _call->StyleGetCheckMonospaced(static_cast<int>(StylesCommon::Default)));
|
||||
_call->StyleSetInvisibleRepresentation(i, _call->StyleGetInvisibleRepresentation(static_cast<int>(StylesCommon::Default)).c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CodeEditorHandler::SetFoldMarginColor(bool useSetting, ColourAlpha back)
|
||||
{
|
||||
// Implement for transparent folding margin. Not implemented so default is preserved
|
||||
}
|
||||
|
||||
void CodeEditorHandler::SetFoldMarginHiColor(bool useSetting, ColourAlpha fore)
|
||||
{
|
||||
// Implement for transparent folding margin. Not implemented so default is preserved
|
||||
}
|
||||
|
||||
void CodeEditorHandler::DefaultColorsChanged(CodeEditorTheme theme)
|
||||
{
|
||||
// Default event handler
|
||||
}
|
||||
|
||||
void CodeEditorHandler::SyntaxHighlightingApplied(CodeEditorTheme theme)
|
||||
{
|
||||
// Default event handler
|
||||
}
|
||||
|
||||
void CodeEditorHandler::UpdateStyles()
|
||||
{
|
||||
constexpr auto bgDark{ IntRGBA(0x27, 0x27, 0x27, 0x00) };
|
||||
constexpr auto bgLight{ IntRGBA(0xF5, 0xF5, 0xF5, 0x00) };
|
||||
|
||||
switch (_theme)
|
||||
{
|
||||
case CodeEditorTheme::Dark:
|
||||
StyleSetFore(static_cast<int>(StylesCommon::LineNumber), IntRGBA(0x85, 0x85, 0x85));
|
||||
StyleSetBack(static_cast<int>(StylesCommon::LineNumber), bgDark);
|
||||
|
||||
StyleSetFore(static_cast<int>(StylesCommon::Default), IntRGBA(0xFF, 0xFF, 0xFF));
|
||||
StyleSetBack(static_cast<int>(StylesCommon::Default), bgDark);
|
||||
|
||||
StyleSetFore(static_cast<int>(StylesCommon::BraceLight), IntRGBA(0xFF, 0xFF, 0xFF));
|
||||
StyleSetBack(static_cast<int>(StylesCommon::BraceLight), IntRGBA(0x11, 0x3D, 0x6F));
|
||||
StyleSetFore(static_cast<int>(StylesCommon::BraceBad), IntRGBA(0xcd, 0x31, 0x31));
|
||||
StyleSetBack(static_cast<int>(StylesCommon::BraceBad), bgDark);
|
||||
|
||||
StyleSetFore(static_cast<int>(StylesCommon::IndentGuide), IntRGBA(0xFF, 0xFF, 0xFF, 48));
|
||||
StyleSetBack(static_cast<int>(StylesCommon::IndentGuide), bgDark);
|
||||
|
||||
StyleSetFore(static_cast<int>(StylesCommon::ControlChar), IntRGBA(0xFF, 0xFF, 0xFF));
|
||||
StyleSetBack(static_cast<int>(StylesCommon::ControlChar), IntRGBA(0x96, 0x00, 0x00));
|
||||
|
||||
StyleSetFore(static_cast<int>(StylesCommon::FoldDisplayText), IntRGBA(0xB8, 0xC2, 0xCC));
|
||||
StyleSetBack(static_cast<int>(StylesCommon::FoldDisplayText), IntRGBA(0x26, 0x33, 0x3F));
|
||||
break;
|
||||
|
||||
case CodeEditorTheme::Light:
|
||||
StyleSetFore(static_cast<int>(StylesCommon::LineNumber), IntRGBA(0x23, 0x78, 0x93));
|
||||
StyleSetBack(static_cast<int>(StylesCommon::LineNumber), bgLight);
|
||||
|
||||
StyleSetFore(static_cast<int>(StylesCommon::Default), IntRGBA(0x00, 0x00, 0x00));
|
||||
StyleSetBack(static_cast<int>(StylesCommon::Default), bgLight);
|
||||
|
||||
StyleSetFore(static_cast<int>(StylesCommon::BraceLight), IntRGBA(0x00, 0x00, 0x00));
|
||||
StyleSetBack(static_cast<int>(StylesCommon::BraceLight), IntRGBA(0xE2, 0xE6, 0xD6));
|
||||
StyleSetFore(static_cast<int>(StylesCommon::BraceBad), IntRGBA(0xcd, 0x31, 0x31));
|
||||
StyleSetBack(static_cast<int>(StylesCommon::BraceBad), bgLight);
|
||||
|
||||
StyleSetFore(static_cast<int>(StylesCommon::IndentGuide), IntRGBA(0x00, 0x00, 0x00, 64));
|
||||
StyleSetBack(static_cast<int>(StylesCommon::IndentGuide), bgLight);
|
||||
|
||||
StyleSetFore(static_cast<int>(StylesCommon::ControlChar), IntRGBA(0xFF, 0xFF, 0xFF));
|
||||
StyleSetBack(static_cast<int>(StylesCommon::ControlChar), IntRGBA(0x96, 0x00, 0x00));
|
||||
|
||||
StyleSetFore(static_cast<int>(StylesCommon::FoldDisplayText), IntRGBA(0x73, 0x79, 0x80));
|
||||
StyleSetBack(static_cast<int>(StylesCommon::FoldDisplayText), IntRGBA(0xDC, 0xEA, 0xF5));
|
||||
break;
|
||||
}
|
||||
|
||||
DefaultColorsChanged(_theme);
|
||||
|
||||
UpdateLanguageStyles();
|
||||
|
||||
SyntaxHighlightingApplied(_theme);
|
||||
|
||||
InvalidateStyleRedraw();
|
||||
}
|
||||
|
||||
void CodeEditorHandler::MarkerSetColors(Scintilla::MarkerOutline marker, Scintilla::ColourAlpha fore, Scintilla::ColourAlpha back, Scintilla::ColourAlpha backHighlight)
|
||||
{
|
||||
const auto markerNumber{ static_cast<int>(marker) };
|
||||
_call->MarkerSetForeTranslucent(markerNumber, fore);
|
||||
_call->MarkerSetBackTranslucent(markerNumber, back);
|
||||
_call->MarkerSetBackSelectedTranslucent(markerNumber, backHighlight);
|
||||
}
|
||||
|
||||
void CodeEditorHandler::UpdateCaretLineBackColors(bool colorsUpdated)
|
||||
{
|
||||
const auto hasEmptySelection = _call->SelectionEmpty();
|
||||
|
||||
if ((_hasEmptySelection != hasEmptySelection) || (hasEmptySelection && colorsUpdated))
|
||||
{
|
||||
_hasEmptySelection = hasEmptySelection;
|
||||
|
||||
if (hasEmptySelection)
|
||||
{
|
||||
switch (_theme)
|
||||
{
|
||||
case CodeEditorTheme::Dark:
|
||||
_call->SetElementColour(Element::CaretLineBack, IntRGBA(0xFF, 0xFF, 0xFF, 16));
|
||||
break;
|
||||
|
||||
case CodeEditorTheme::Light:
|
||||
_call->SetElementColour(Element::CaretLineBack, IntRGBA(0x00, 0x00, 0x00, 12));
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_call->ResetElementColour(Element::CaretLineBack);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CodeEditorHandler::UpdateBraceMatch()
|
||||
{
|
||||
SciBraceMatch();
|
||||
}
|
||||
|
||||
void CodeEditorHandler::AutoIndent(char ch)
|
||||
{
|
||||
SciAutomaticIndentation(ch);
|
||||
}
|
||||
|
||||
void CodeEditorHandler::SetLanguageIndentMode(
|
||||
int indentKeywordStyle, const std::set<std::string> &indentKeywords,
|
||||
int lineEndStyle, const std::set<std::string> &lineEndWords,
|
||||
int blockStartStyle, const std::set<std::string> &blockStartWords,
|
||||
int blockEndStyle, const std::set<std::string> &blockEndWords)
|
||||
{
|
||||
_sciStatementIndent = { indentKeywordStyle, { indentKeywords, } }; // Todo: customize. also note using WORD2 for these
|
||||
_sciStatementEnd = { lineEndStyle, { lineEndWords, } };
|
||||
_sciBlockStart = { blockStartStyle, { blockStartWords, } };
|
||||
_sciBlockEnd = { blockEndStyle, { blockEndWords, } };
|
||||
}
|
||||
|
||||
void CodeEditorHandler::UpdateZoom()
|
||||
{
|
||||
const auto size{ _call->StyleGetSizeFractional(static_cast<int>(StylesCommon::Default)) };
|
||||
const auto zoom{ static_cast<int>(_call->Zoom()) };
|
||||
const auto factor{ static_cast<float>((size + zoom * 100)) / size };
|
||||
// Todo: Width 11 hard coded for a digit. Use below for real value:
|
||||
// _call->TextWidth, static_cast<uptr_t>(StylesCommon::LineNumber), reinterpret_cast<sptr_t>("9"))
|
||||
const auto line{ _call->LineCount() };
|
||||
const auto width{ 12 + 11 * std::max(3, static_cast<int>(std::floor(std::log10(line) + 1))) };
|
||||
_call->SetMarginWidthN(0, ConvertFromDipToPixelUnit(std::floorf(factor * width + 0.5f), _dpiScale));
|
||||
_call->SetMarginWidthN(1, ConvertFromDipToPixelUnit(std::floorf(factor * 12 + 0.5f), _dpiScale));
|
||||
_call->SetMarginWidthN(2, ConvertFromDipToPixelUnit(std::floorf(factor * 10 + 0.5f), _dpiScale));
|
||||
const auto foldMarkerStroke{ ConvertFromDipToPixelUnit(factor * 100.0f, _dpiScale, false) };
|
||||
_call->MarkerSetStrokeWidth(static_cast<int>(Scintilla::MarkerOutline::FolderOpen), foldMarkerStroke);
|
||||
_call->MarkerSetStrokeWidth(static_cast<int>(Scintilla::MarkerOutline::Folder), foldMarkerStroke);
|
||||
_call->MarkerSetStrokeWidth(static_cast<int>(Scintilla::MarkerOutline::FolderSub), foldMarkerStroke);
|
||||
_call->MarkerSetStrokeWidth(static_cast<int>(Scintilla::MarkerOutline::FolderTail), foldMarkerStroke);
|
||||
_call->MarkerSetStrokeWidth(static_cast<int>(Scintilla::MarkerOutline::FolderEnd), foldMarkerStroke);
|
||||
_call->MarkerSetStrokeWidth(static_cast<int>(Scintilla::MarkerOutline::FolderOpenMid), foldMarkerStroke);
|
||||
_call->MarkerSetStrokeWidth(static_cast<int>(Scintilla::MarkerOutline::FolderMidTail), foldMarkerStroke);
|
||||
const auto historyMarkerStroke{ foldMarkerStroke };
|
||||
_call->MarkerSetStrokeWidth(static_cast<int>(Scintilla::MarkerOutline::HistoryRevertedToOrigin), historyMarkerStroke);
|
||||
// HistorySaved is left at default width (1) because rendering artifacts occur with the solid color + box outline
|
||||
//_call->MarkerSetStrokeWidth(static_cast<int>(Scintilla::MarkerOutline::HistorySaved), historyMarkerStroke);
|
||||
_call->MarkerSetStrokeWidth(static_cast<int>(Scintilla::MarkerOutline::HistoryModified), historyMarkerStroke);
|
||||
_call->MarkerSetStrokeWidth(static_cast<int>(Scintilla::MarkerOutline::HistoryRevertedToModified), historyMarkerStroke);
|
||||
_call->SetMarginLeft(ConvertFromDipToPixelUnit(std::floorf(factor * 1 + 0.5f), _dpiScale));
|
||||
// Todo: Set caret width to be at least the UISettings system caret width
|
||||
const auto caretWidth{ std::max(1.0f, std::floorf(factor * 2 * _dpiScale)) };
|
||||
_call->SetCaretWidth(caretWidth); // Todo: Needs to stop blinking after timeout and respect blink rate
|
||||
_call->SetCaretLineFrame(caretWidth);
|
||||
_call->SetExtraDescent(std::floorf(factor * 1.8 * _dpiScale));
|
||||
}
|
||||
|
||||
void CodeEditorHandler::AddKeyboardShortcuts()
|
||||
{
|
||||
_call->AssignCmdKey(187 + (static_cast<int>(KeyMod::Ctrl) << 16), static_cast<int>(Message::ZoomIn)); // Ctrl+Plus
|
||||
_call->AssignCmdKey(189 + (static_cast<int>(KeyMod::Ctrl) << 16), static_cast<int>(Message::ZoomOut)); // Ctrl+Minus
|
||||
_call->AssignCmdKey(48 + (static_cast<int>(KeyMod::Ctrl) << 16), static_cast<int>(Message::SetZoom)); // Ctrl+0
|
||||
}
|
||||
|
||||
void CodeEditorHandler::ChangeDefaults()
|
||||
{
|
||||
_call->SetMultipleSelection(true);
|
||||
_call->SetScrollWidth(2000);
|
||||
_call->SetScrollWidthTracking(true);
|
||||
_call->SetYCaretPolicy(CaretPolicy::Slop | CaretPolicy::Strict | CaretPolicy::Even, 1);
|
||||
_call->SetVisiblePolicy(VisiblePolicy::Slop, 0);
|
||||
_call->SetHScrollBar(true);
|
||||
_call->SetEndAtLastLine(false);
|
||||
_call->StyleSetFont(static_cast<int>(StylesCommon::Default), "Cascadia Code"); // Todo: Use font available on Windows 10
|
||||
_call->StyleSetSizeFractional(static_cast<int>(StylesCommon::Default), 11 * FontSizeMultiplier);
|
||||
_call->SetAdditionalSelectionTyping(true);
|
||||
_call->SetMultiPaste(MultiPaste::Each);
|
||||
_call->SetLayoutThreads(16); // Todo: Determine performance impact
|
||||
_call->SetCaretLineVisibleAlways(true);
|
||||
_call->SetCaretLineLayer(Layer::UnderText);
|
||||
_call->SetCaretLineHighlightSubLine(true);
|
||||
_call->SetIndentationGuides(IndentView::LookBoth);
|
||||
_call->SetMarginMaskN(2, Scintilla::MaskFolders);
|
||||
_call->SetMarginSensitiveN(2, true);
|
||||
SetFoldMarginColor(true, IntRGBA(0, 0, 0, 0));
|
||||
SetFoldMarginHiColor(true, IntRGBA(0, 0, 0, 0));
|
||||
|
||||
constexpr auto useCustomChevron{ true }; // Todo: make overridable
|
||||
constexpr auto chevronMinus{ static_cast<MarkerSymbol>(1989) };
|
||||
constexpr auto chevronPlus{ static_cast<MarkerSymbol>(1990) };
|
||||
_call->MarkerDefine(static_cast<int>(MarkerOutline::FolderOpen), useCustomChevron ? chevronMinus : MarkerSymbol::BoxMinus);
|
||||
_call->MarkerDefine(static_cast<int>(MarkerOutline::Folder), useCustomChevron ? chevronPlus : MarkerSymbol::BoxPlus);
|
||||
_call->MarkerDefine(static_cast<int>(MarkerOutline::FolderSub), MarkerSymbol::VLine);
|
||||
_call->MarkerDefine(static_cast<int>(MarkerOutline::FolderTail), MarkerSymbol::LCorner);
|
||||
_call->MarkerDefine(static_cast<int>(MarkerOutline::FolderEnd), useCustomChevron ? chevronPlus : MarkerSymbol::BoxPlusConnected);
|
||||
_call->MarkerDefine(static_cast<int>(MarkerOutline::FolderOpenMid), useCustomChevron ? chevronMinus : MarkerSymbol::BoxMinusConnected);
|
||||
_call->MarkerDefine(static_cast<int>(MarkerOutline::FolderMidTail), MarkerSymbol::TCorner);
|
||||
_call->MarkerEnableHighlight(false);
|
||||
|
||||
_call->SetDefaultFoldDisplayText(u8"\u00a0\u22ef\u00a0"); // ... nbsp + centered vertically + nbsp
|
||||
_call->FoldDisplayTextSetStyle(Scintilla::FoldDisplayTextStyle::Standard);
|
||||
|
||||
_call->SetAutomaticFold(static_cast<Scintilla::AutomaticFold>(static_cast<int>(Scintilla::AutomaticFold::Show) | static_cast<int>(Scintilla::AutomaticFold::Click) | static_cast<int>(Scintilla::AutomaticFold::Change)));
|
||||
}
|
||||
|
||||
// Todo: This code needs to integrate with find and replace
|
||||
// Todo: This code seems to struggle with rectangular selections and/or multiple carets already existing and/or multiple selections already existing
|
||||
void CodeEditorHandler::ChangeAllOccurrences()
|
||||
{
|
||||
sptr_t start;
|
||||
sptr_t end;
|
||||
const auto s{ GetMainSelectedText(true, start, end) };
|
||||
if (s.length() == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
const auto length{ end - start };
|
||||
|
||||
// Drop additional selections and ensure caret is at end of selection
|
||||
_call->SetSelection(end, start);
|
||||
|
||||
_call->TargetWholeDocument();
|
||||
_call->SetSearchFlags(FindOption::MatchCase);
|
||||
|
||||
const auto mainSelection{ _call->MainSelection() };
|
||||
const auto bodyLength{ _call->Length() };
|
||||
|
||||
while (true)
|
||||
{
|
||||
const auto match{ _call->SearchInTarget(length, &s[0]) };
|
||||
|
||||
if (match == -1)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
const auto targetEnd{ _call->TargetEnd() };
|
||||
|
||||
if (match != start)
|
||||
{
|
||||
// Todo: Add maximum number of carets and notify user if exceeded (VS Code allows 10,000)
|
||||
// Todo: This method calls a lot of redraws in a loop. You might need to use the lower level API to avoid that
|
||||
_call->AddSelection(match + length, match);
|
||||
}
|
||||
|
||||
_call->SetTargetStart(targetEnd);
|
||||
_call->SetTargetEnd(bodyLength);
|
||||
}
|
||||
|
||||
_call->SetMainSelection(mainSelection);
|
||||
}
|
||||
|
||||
std::wstring_view CodeEditorHandler::HighlightingLanguage()
|
||||
{
|
||||
return _highlightingLanguage;
|
||||
}
|
||||
|
||||
void CodeEditorHandler::HighlightingLanguage(std::wstring_view value)
|
||||
{
|
||||
if (_highlightingLanguage == value)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_highlightingLanguage = value;
|
||||
|
||||
_call->ClearDocumentStyle();
|
||||
|
||||
SetLexer();
|
||||
|
||||
UpdateStyles();
|
||||
|
||||
_call->ColouriseAll();
|
||||
}
|
||||
|
||||
void CodeEditorHandler::ProcessNotification(NotificationData *data)
|
||||
{
|
||||
if (data->nmhdr.code == Notification::Zoom
|
||||
|| (data->nmhdr.code == Notification::Modified && data->linesAdded))
|
||||
{
|
||||
UpdateZoom();
|
||||
}
|
||||
|
||||
if (data->nmhdr.code == Notification::UpdateUI && FlagSet(data->updated, Update::Content | Update::Selection))
|
||||
{
|
||||
UpdateCaretLineBackColors();
|
||||
if (_call->Focus())
|
||||
{
|
||||
UpdateBraceMatch();
|
||||
}
|
||||
}
|
||||
|
||||
if (data->nmhdr.code == Notification::FocusOut)
|
||||
{
|
||||
_call->BraceBadLight(-1);
|
||||
}
|
||||
else if (data->nmhdr.code == Notification::FocusIn)
|
||||
{
|
||||
UpdateBraceMatch();
|
||||
}
|
||||
|
||||
if (data->nmhdr.code == Notification::CharAdded && data->ch <= 0xFF)
|
||||
{
|
||||
const auto sel{ _call->SelectionSpan() };
|
||||
|
||||
if (sel.start == sel.end && sel.start > 0
|
||||
&& !_call->CallTipActive()
|
||||
&& !_call->AutoCActive())
|
||||
{
|
||||
AutoIndent(data->ch);
|
||||
}
|
||||
}
|
||||
|
||||
if (data->nmhdr.code == Notification::DoubleClick && _call->FoldDisplayTextGetStyle() != FoldDisplayTextStyle::Hidden)
|
||||
{
|
||||
const auto lineEndPosition{ _call->LineEndPosition(data->line) };
|
||||
if ((data->position == lineEndPosition || data->position == InvalidPosition)
|
||||
&& !_call->FoldExpanded(data->line))
|
||||
{
|
||||
const auto ctrl{ FlagSet(data->modifiers, KeyMod::Ctrl) };
|
||||
const auto shift{ FlagSet(data->modifiers, KeyMod::Shift) };
|
||||
const auto levelClick{ _call->FoldLevel(data->line) };
|
||||
if (LevelIsHeader(levelClick))
|
||||
{
|
||||
if (shift)
|
||||
{
|
||||
// Ensure all children visible
|
||||
_call->ExpandChildren(data->line, levelClick);
|
||||
}
|
||||
else if (ctrl)
|
||||
{
|
||||
_call->FoldChildren(data->line, FoldAction::Toggle);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Toggle this line
|
||||
_call->FoldLine(data->line, FoldAction::Toggle);
|
||||
}
|
||||
|
||||
// Remove selection from double click
|
||||
_call->SetEmptySelection(lineEndPosition);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::string CodeEditorHandler::GetMainSelectedText(bool expandCaretToWord, sptr_t &start, sptr_t &end)
|
||||
{
|
||||
// Todo: This code may be problematic for rectangular selections
|
||||
start = _call->SelectionStart();
|
||||
end = _call->SelectionEnd();
|
||||
if (expandCaretToWord && start == end)
|
||||
{
|
||||
start = _call->WordStartPosition(start, true);
|
||||
end = _call->WordEndPosition(start, true);
|
||||
|
||||
if (start == end)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
const auto length{ end - start };
|
||||
std::string s(length, '\0');
|
||||
TextRangeFull range
|
||||
{
|
||||
{ start, end, },
|
||||
&s[0],
|
||||
};
|
||||
_call->GetTextRangeFull(&range);
|
||||
|
||||
return s;
|
||||
}
|
||||
}
|
|
@ -1,102 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include <set>
|
||||
#include <vector>
|
||||
#include "ScintillaTypes.h"
|
||||
#include "ScintillaStructures.h"
|
||||
#include "ScintillaCall.h"
|
||||
#include "ILexer.h"
|
||||
#include "Lexilla.h"
|
||||
#include "CodeEditorHandler.SciEdit.h"
|
||||
|
||||
namespace WinUIEditor
|
||||
{
|
||||
constexpr int IntRGBA(unsigned int red, unsigned int green, unsigned int blue, unsigned int alpha = 0xff) noexcept
|
||||
{
|
||||
return red | (green << 8) | (blue << 16) | (alpha << 24);
|
||||
}
|
||||
|
||||
enum class CodeEditorTheme
|
||||
{
|
||||
Unset,
|
||||
Light,
|
||||
Dark,
|
||||
};
|
||||
|
||||
struct CodeEditorHandler
|
||||
{
|
||||
void SetScintilla(std::shared_ptr<Scintilla::ScintillaCall> call);
|
||||
void SetLexilla(Lexilla::CreateLexerFn createLexer);
|
||||
void Initialize();
|
||||
void ChangeDocumentDefaults();
|
||||
void UpdateColors(CodeEditorTheme theme);
|
||||
void UpdateDpi(double value);
|
||||
void UpdateZoom();
|
||||
void ChangeAllOccurrences();
|
||||
std::wstring_view HighlightingLanguage();
|
||||
void HighlightingLanguage(std::wstring_view language);
|
||||
void ProcessNotification(Scintilla::NotificationData *data);
|
||||
void SetLexer();
|
||||
|
||||
protected:
|
||||
virtual void StyleSetFore(int style, Scintilla::ColourAlpha color);
|
||||
virtual void StyleSetBack(int style, Scintilla::ColourAlpha color);
|
||||
virtual void InvalidateStyleRedraw();
|
||||
virtual void StyleClearCustom();
|
||||
virtual void SetFoldMarginColor(bool useSetting, Scintilla::ColourAlpha back);
|
||||
virtual void SetFoldMarginHiColor(bool useSetting, Scintilla::ColourAlpha fore);
|
||||
|
||||
virtual void DefaultColorsChanged(CodeEditorTheme theme);
|
||||
virtual void SyntaxHighlightingApplied(CodeEditorTheme theme);
|
||||
|
||||
private:
|
||||
std::shared_ptr<Scintilla::ScintillaCall> _call{ nullptr };
|
||||
Lexilla::CreateLexerFn _createLexer{ nullptr };
|
||||
CodeEditorTheme _theme{ CodeEditorTheme::Unset };
|
||||
double _dpiScale;
|
||||
int8_t _hasEmptySelection{ -1 };
|
||||
std::wstring _highlightingLanguage;
|
||||
|
||||
void UpdateStyles();
|
||||
void UpdateCaretLineBackColors(bool colorsUpdated = false);
|
||||
void UpdateBraceMatch();
|
||||
void AutoIndent(char ch);
|
||||
void AddKeyboardShortcuts();
|
||||
void ChangeDefaults();
|
||||
std::string GetMainSelectedText(bool expandCaretToWord, Scintilla::sptr_t &start, Scintilla::sptr_t &end);
|
||||
void SetLanguageIndentMode(
|
||||
int indentKeywordStyle, const std::set<std::string> &indentKeywords,
|
||||
int lineEndStyle, const std::set<std::string> &lineEndWords,
|
||||
int blockStartStyle, const std::set<std::string> &blockStartWords,
|
||||
int blockEndStyle, const std::set<std::string> &blockEndWords
|
||||
);
|
||||
|
||||
void SetJavaScriptDefaults(int wordList1, int wordList2, int indentKeywordStyle, int symbolStyle);
|
||||
void UpdateLanguageStyles();
|
||||
|
||||
void MarkerSetColors(Scintilla::MarkerOutline marker, Scintilla::ColourAlpha fore, Scintilla::ColourAlpha back, Scintilla::ColourAlpha backHighlight);
|
||||
|
||||
static constexpr bool _sciIndentOpening{ false };
|
||||
static constexpr bool _sciIndentClosing{ false };
|
||||
static constexpr int _sciStatementLookback{ 20 };
|
||||
Internal::StyleAndWords _sciStatementIndent;
|
||||
Internal::StyleAndWords _sciStatementEnd;
|
||||
Internal::StyleAndWords _sciBlockStart;
|
||||
Internal::StyleAndWords _sciBlockEnd;
|
||||
bool SciFindMatchingBracePosition(Scintilla::Position &braceAtCaret, Scintilla::Position &braceOpposite, bool sloppy);
|
||||
void SciBraceMatch();
|
||||
Scintilla::Line SciGetCurrentLineNumber();
|
||||
int SciIndentOfBlock(Scintilla::Line line);
|
||||
int SciGetLineIndentation(Scintilla::Line line);
|
||||
Scintilla::Position SciGetLineIndentPosition(Scintilla::Line line);
|
||||
void SciSetLineIndentation(Scintilla::Line line, int indent);
|
||||
Scintilla::Span SciGetSelection();
|
||||
std::vector<std::string> SciGetLinePartsInStyle(Scintilla::Line line, const Internal::StyleAndWords &saw);
|
||||
void SciSetSelection(Scintilla::Position anchor, Scintilla::Position currentPos);
|
||||
bool SciRangeIsAllWhitespace(Scintilla::Position start, Scintilla::Position end);
|
||||
Internal::IndentationStatus SciGetIndentState(Scintilla::Line line);
|
||||
void SciAutomaticIndentation(char ch);
|
||||
};
|
||||
}
|
|
@ -1,4 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include "EditorBaseControl.h"
|
||||
#include "CodeEditorControl.h"
|
|
@ -1,213 +0,0 @@
|
|||
// Ported from
|
||||
// https://github.com/microsoft/vscode/blob/main/extensions/theme-defaults/themes/dark_plus.json
|
||||
// https://github.com/microsoft/vscode/blob/main/extensions/theme-defaults/themes/dark_vs.json
|
||||
// under the following license
|
||||
|
||||
/*
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2015 - present Microsoft Corporation
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace WinUIEditor
|
||||
{
|
||||
constexpr int DarkPlusEditorForeground{ IntRGBA(0xD4, 0xD4, 0xD4) };
|
||||
|
||||
constexpr int DarkPlus(Scope scope)
|
||||
{
|
||||
switch (scope)
|
||||
{
|
||||
case Scope::MetaEmbedded: return IntRGBA(0xD4, 0xD4, 0xD4);
|
||||
case Scope::SourceGroovyEmbedded: return IntRGBA(0xD4, 0xD4, 0xD4);
|
||||
case Scope::String__MetaImageInlineMarkdown: return IntRGBA(0xD4, 0xD4, 0xD4);
|
||||
case Scope::VariableLegacyBuiltinPython: return IntRGBA(0xD4, 0xD4, 0xD4);
|
||||
case Scope::Header: return IntRGBA(0x00, 0x00, 0x80);
|
||||
case Scope::Comment: return IntRGBA(0x6A, 0x99, 0x55);
|
||||
case Scope::ConstantLanguage: return IntRGBA(0x56, 0x9C, 0xD6);
|
||||
case Scope::ConstantNumeric: return IntRGBA(0xB5, 0xCE, 0xA8);
|
||||
case Scope::VariableOtherEnummember: return IntRGBA(0x4F, 0xC1, 0xFF);
|
||||
case Scope::KeywordOperatorPlusExponent: return IntRGBA(0xB5, 0xCE, 0xA8);
|
||||
case Scope::KeywordOperatorMinusExponent: return IntRGBA(0xB5, 0xCE, 0xA8);
|
||||
case Scope::ConstantRegexp: return IntRGBA(0x64, 0x66, 0x95);
|
||||
case Scope::EntityNameTag: return IntRGBA(0x56, 0x9C, 0xD6);
|
||||
case Scope::EntityNameTagCss: return IntRGBA(0xD7, 0xBA, 0x7D);
|
||||
case Scope::EntityOtherAttribute_Name: return IntRGBA(0x9C, 0xDC, 0xFE);
|
||||
case Scope::EntityOtherAttribute_NameClassCss: return IntRGBA(0xD7, 0xBA, 0x7D);
|
||||
case Scope::EntityOtherAttribute_NameClassMixinCss: return IntRGBA(0xD7, 0xBA, 0x7D);
|
||||
case Scope::EntityOtherAttribute_NameIdCss: return IntRGBA(0xD7, 0xBA, 0x7D);
|
||||
case Scope::EntityOtherAttribute_NameParent_SelectorCss: return IntRGBA(0xD7, 0xBA, 0x7D);
|
||||
case Scope::EntityOtherAttribute_NamePseudo_ClassCss: return IntRGBA(0xD7, 0xBA, 0x7D);
|
||||
case Scope::EntityOtherAttribute_NamePseudo_ElementCss: return IntRGBA(0xD7, 0xBA, 0x7D);
|
||||
case Scope::SourceCssLess__EntityOtherAttribute_NameId: return IntRGBA(0xD7, 0xBA, 0x7D);
|
||||
case Scope::EntityOtherAttribute_NameScss: return IntRGBA(0xD7, 0xBA, 0x7D);
|
||||
case Scope::Invalid: return IntRGBA(0xF4, 0x47, 0x47);
|
||||
case Scope::MarkupBold: return IntRGBA(0x56, 0x9C, 0xD6);
|
||||
case Scope::MarkupHeading: return IntRGBA(0x56, 0x9C, 0xD6);
|
||||
case Scope::MarkupInserted: return IntRGBA(0xB5, 0xCE, 0xA8);
|
||||
case Scope::MarkupDeleted: return IntRGBA(0xCE, 0x91, 0x78);
|
||||
case Scope::MarkupChanged: return IntRGBA(0x56, 0x9C, 0xD6);
|
||||
case Scope::PunctuationDefinitionQuoteBeginMarkdown: return IntRGBA(0x6A, 0x99, 0x55);
|
||||
case Scope::PunctuationDefinitionListBeginMarkdown: return IntRGBA(0x67, 0x96, 0xE6);
|
||||
case Scope::MarkupInlineRaw: return IntRGBA(0xCE, 0x91, 0x78);
|
||||
case Scope::PunctuationDefinitionTag: return IntRGBA(0x80, 0x80, 0x80);
|
||||
case Scope::MetaPreprocessor: return IntRGBA(0x56, 0x9C, 0xD6);
|
||||
case Scope::EntityNameFunctionPreprocessor: return IntRGBA(0x56, 0x9C, 0xD6);
|
||||
case Scope::MetaPreprocessorString: return IntRGBA(0xCE, 0x91, 0x78);
|
||||
case Scope::MetaPreprocessorNumeric: return IntRGBA(0xB5, 0xCE, 0xA8);
|
||||
case Scope::MetaStructureDictionaryKeyPython: return IntRGBA(0x9C, 0xDC, 0xFE);
|
||||
case Scope::MetaDiffHeader: return IntRGBA(0x56, 0x9C, 0xD6);
|
||||
case Scope::Storage: return IntRGBA(0x56, 0x9C, 0xD6);
|
||||
case Scope::StorageType: return IntRGBA(0x56, 0x9C, 0xD6);
|
||||
case Scope::StorageModifier: return IntRGBA(0x56, 0x9C, 0xD6);
|
||||
case Scope::KeywordOperatorNoexcept: return IntRGBA(0x56, 0x9C, 0xD6);
|
||||
case Scope::String: return IntRGBA(0xCE, 0x91, 0x78);
|
||||
case Scope::MetaEmbeddedAssembly: return IntRGBA(0xCE, 0x91, 0x78);
|
||||
case Scope::StringTag: return IntRGBA(0xCE, 0x91, 0x78);
|
||||
case Scope::StringValue: return IntRGBA(0xCE, 0x91, 0x78);
|
||||
case Scope::StringRegexp: return IntRGBA(0xD1, 0x69, 0x69);
|
||||
case Scope::PunctuationDefinitionTemplate_ExpressionBegin: return IntRGBA(0x56, 0x9C, 0xD6);
|
||||
case Scope::PunctuationDefinitionTemplate_ExpressionEnd: return IntRGBA(0x56, 0x9C, 0xD6);
|
||||
case Scope::PunctuationSectionEmbedded: return IntRGBA(0x56, 0x9C, 0xD6);
|
||||
case Scope::MetaTemplateExpression: return IntRGBA(0xD4, 0xD4, 0xD4);
|
||||
case Scope::SupportTypeVendoredProperty_Name: return IntRGBA(0x9C, 0xDC, 0xFE);
|
||||
case Scope::SupportTypeProperty_Name: return IntRGBA(0x9C, 0xDC, 0xFE);
|
||||
case Scope::VariableCss: return IntRGBA(0x9C, 0xDC, 0xFE);
|
||||
case Scope::VariableScss: return IntRGBA(0x9C, 0xDC, 0xFE);
|
||||
case Scope::VariableOtherLess: return IntRGBA(0x9C, 0xDC, 0xFE);
|
||||
case Scope::SourceCoffeeEmbedded: return IntRGBA(0x9C, 0xDC, 0xFE);
|
||||
case Scope::Keyword: return IntRGBA(0x56, 0x9C, 0xD6);
|
||||
case Scope::KeywordControl: return IntRGBA(0xC5, 0x86, 0xC0);
|
||||
case Scope::KeywordOperator: return IntRGBA(0xD4, 0xD4, 0xD4);
|
||||
case Scope::KeywordOperatorNew: return IntRGBA(0x56, 0x9C, 0xD6);
|
||||
case Scope::KeywordOperatorExpression: return IntRGBA(0x56, 0x9C, 0xD6);
|
||||
case Scope::KeywordOperatorCast: return IntRGBA(0x56, 0x9C, 0xD6);
|
||||
case Scope::KeywordOperatorSizeof: return IntRGBA(0x56, 0x9C, 0xD6);
|
||||
case Scope::KeywordOperatorAlignof: return IntRGBA(0x56, 0x9C, 0xD6);
|
||||
case Scope::KeywordOperatorTypeid: return IntRGBA(0x56, 0x9C, 0xD6);
|
||||
case Scope::KeywordOperatorAlignas: return IntRGBA(0x56, 0x9C, 0xD6);
|
||||
case Scope::KeywordOperatorInstanceof: return IntRGBA(0x56, 0x9C, 0xD6);
|
||||
case Scope::KeywordOperatorLogicalPython: return IntRGBA(0x56, 0x9C, 0xD6);
|
||||
case Scope::KeywordOperatorWordlike: return IntRGBA(0x56, 0x9C, 0xD6);
|
||||
case Scope::KeywordOtherUnit: return IntRGBA(0xB5, 0xCE, 0xA8);
|
||||
case Scope::PunctuationSectionEmbeddedBeginPhp: return IntRGBA(0x56, 0x9C, 0xD6);
|
||||
case Scope::PunctuationSectionEmbeddedEndPhp: return IntRGBA(0x56, 0x9C, 0xD6);
|
||||
case Scope::SupportFunctionGit_Rebase: return IntRGBA(0x9C, 0xDC, 0xFE);
|
||||
case Scope::ConstantShaGit_Rebase: return IntRGBA(0xB5, 0xCE, 0xA8);
|
||||
case Scope::StorageModifierImportJava: return IntRGBA(0xD4, 0xD4, 0xD4);
|
||||
case Scope::VariableLanguageWildcardJava: return IntRGBA(0xD4, 0xD4, 0xD4);
|
||||
case Scope::StorageModifierPackageJava: return IntRGBA(0xD4, 0xD4, 0xD4);
|
||||
case Scope::VariableLanguage: return IntRGBA(0x56, 0x9C, 0xD6);
|
||||
case Scope::EntityNameFunction: return IntRGBA(0xDC, 0xDC, 0xAA);
|
||||
case Scope::SupportFunction: return IntRGBA(0xDC, 0xDC, 0xAA);
|
||||
case Scope::SupportConstantHandlebars: return IntRGBA(0xDC, 0xDC, 0xAA);
|
||||
case Scope::SourcePowershell__VariableOtherMember: return IntRGBA(0xDC, 0xDC, 0xAA);
|
||||
case Scope::EntityNameOperatorCustom_Literal: return IntRGBA(0xDC, 0xDC, 0xAA);
|
||||
case Scope::SupportClass: return IntRGBA(0x4E, 0xC9, 0xB0);
|
||||
case Scope::SupportType: return IntRGBA(0x4E, 0xC9, 0xB0);
|
||||
case Scope::EntityNameType: return IntRGBA(0x4E, 0xC9, 0xB0);
|
||||
case Scope::EntityNameNamespace: return IntRGBA(0x4E, 0xC9, 0xB0);
|
||||
case Scope::EntityOtherAttribute: return IntRGBA(0x4E, 0xC9, 0xB0);
|
||||
case Scope::EntityNameScope_Resolution: return IntRGBA(0x4E, 0xC9, 0xB0);
|
||||
case Scope::EntityNameClass: return IntRGBA(0x4E, 0xC9, 0xB0);
|
||||
case Scope::StorageTypeNumericGo: return IntRGBA(0x4E, 0xC9, 0xB0);
|
||||
case Scope::StorageTypeByteGo: return IntRGBA(0x4E, 0xC9, 0xB0);
|
||||
case Scope::StorageTypeBooleanGo: return IntRGBA(0x4E, 0xC9, 0xB0);
|
||||
case Scope::StorageTypeStringGo: return IntRGBA(0x4E, 0xC9, 0xB0);
|
||||
case Scope::StorageTypeUintptrGo: return IntRGBA(0x4E, 0xC9, 0xB0);
|
||||
case Scope::StorageTypeErrorGo: return IntRGBA(0x4E, 0xC9, 0xB0);
|
||||
case Scope::StorageTypeRuneGo: return IntRGBA(0x4E, 0xC9, 0xB0);
|
||||
case Scope::StorageTypeCs: return IntRGBA(0x4E, 0xC9, 0xB0);
|
||||
case Scope::StorageTypeGenericCs: return IntRGBA(0x4E, 0xC9, 0xB0);
|
||||
case Scope::StorageTypeModifierCs: return IntRGBA(0x4E, 0xC9, 0xB0);
|
||||
case Scope::StorageTypeVariableCs: return IntRGBA(0x4E, 0xC9, 0xB0);
|
||||
case Scope::StorageTypeAnnotationJava: return IntRGBA(0x4E, 0xC9, 0xB0);
|
||||
case Scope::StorageTypeGenericJava: return IntRGBA(0x4E, 0xC9, 0xB0);
|
||||
case Scope::StorageTypeJava: return IntRGBA(0x4E, 0xC9, 0xB0);
|
||||
case Scope::StorageTypeObjectArrayJava: return IntRGBA(0x4E, 0xC9, 0xB0);
|
||||
case Scope::StorageTypePrimitiveArrayJava: return IntRGBA(0x4E, 0xC9, 0xB0);
|
||||
case Scope::StorageTypePrimitiveJava: return IntRGBA(0x4E, 0xC9, 0xB0);
|
||||
case Scope::StorageTypeTokenJava: return IntRGBA(0x4E, 0xC9, 0xB0);
|
||||
case Scope::StorageTypeGroovy: return IntRGBA(0x4E, 0xC9, 0xB0);
|
||||
case Scope::StorageTypeAnnotationGroovy: return IntRGBA(0x4E, 0xC9, 0xB0);
|
||||
case Scope::StorageTypeParametersGroovy: return IntRGBA(0x4E, 0xC9, 0xB0);
|
||||
case Scope::StorageTypeGenericGroovy: return IntRGBA(0x4E, 0xC9, 0xB0);
|
||||
case Scope::StorageTypeObjectArrayGroovy: return IntRGBA(0x4E, 0xC9, 0xB0);
|
||||
case Scope::StorageTypePrimitiveArrayGroovy: return IntRGBA(0x4E, 0xC9, 0xB0);
|
||||
case Scope::StorageTypePrimitiveGroovy: return IntRGBA(0x4E, 0xC9, 0xB0);
|
||||
case Scope::MetaTypeCastExpr: return IntRGBA(0x4E, 0xC9, 0xB0);
|
||||
case Scope::MetaTypeNewExpr: return IntRGBA(0x4E, 0xC9, 0xB0);
|
||||
case Scope::SupportConstantMath: return IntRGBA(0x4E, 0xC9, 0xB0);
|
||||
case Scope::SupportConstantDom: return IntRGBA(0x4E, 0xC9, 0xB0);
|
||||
case Scope::SupportConstantJson: return IntRGBA(0x4E, 0xC9, 0xB0);
|
||||
case Scope::EntityOtherInherited_Class: return IntRGBA(0x4E, 0xC9, 0xB0);
|
||||
case Scope::SourceCpp__KeywordOperatorNew: return IntRGBA(0xC5, 0x86, 0xC0);
|
||||
case Scope::KeywordOperatorDelete: return IntRGBA(0xC5, 0x86, 0xC0);
|
||||
case Scope::KeywordOtherUsing: return IntRGBA(0xC5, 0x86, 0xC0);
|
||||
case Scope::KeywordOtherDirectiveUsing: return IntRGBA(0xC5, 0x86, 0xC0);
|
||||
case Scope::KeywordOtherOperator: return IntRGBA(0xC5, 0x86, 0xC0);
|
||||
case Scope::EntityNameOperator: return IntRGBA(0xC5, 0x86, 0xC0);
|
||||
case Scope::Variable: return IntRGBA(0x9C, 0xDC, 0xFE);
|
||||
case Scope::MetaDefinitionVariableName: return IntRGBA(0x9C, 0xDC, 0xFE);
|
||||
case Scope::SupportVariable: return IntRGBA(0x9C, 0xDC, 0xFE);
|
||||
case Scope::EntityNameVariable: return IntRGBA(0x9C, 0xDC, 0xFE);
|
||||
case Scope::ConstantOtherPlaceholder: return IntRGBA(0x9C, 0xDC, 0xFE);
|
||||
case Scope::VariableOtherConstant: return IntRGBA(0x4F, 0xC1, 0xFF);
|
||||
case Scope::MetaObject_LiteralKey: return IntRGBA(0x9C, 0xDC, 0xFE);
|
||||
case Scope::SupportConstantProperty_Value: return IntRGBA(0xCE, 0x91, 0x78);
|
||||
case Scope::SupportConstantFont_Name: return IntRGBA(0xCE, 0x91, 0x78);
|
||||
case Scope::SupportConstantMedia_Type: return IntRGBA(0xCE, 0x91, 0x78);
|
||||
case Scope::SupportConstantMedia: return IntRGBA(0xCE, 0x91, 0x78);
|
||||
case Scope::ConstantOtherColorRgb_Value: return IntRGBA(0xCE, 0x91, 0x78);
|
||||
case Scope::ConstantOtherRgb_Value: return IntRGBA(0xCE, 0x91, 0x78);
|
||||
case Scope::SupportConstantColor: return IntRGBA(0xCE, 0x91, 0x78);
|
||||
case Scope::PunctuationDefinitionGroupRegexp: return IntRGBA(0xCE, 0x91, 0x78);
|
||||
case Scope::PunctuationDefinitionGroupAssertionRegexp: return IntRGBA(0xCE, 0x91, 0x78);
|
||||
case Scope::PunctuationDefinitionCharacter_ClassRegexp: return IntRGBA(0xCE, 0x91, 0x78);
|
||||
case Scope::PunctuationCharacterSetBeginRegexp: return IntRGBA(0xCE, 0x91, 0x78);
|
||||
case Scope::PunctuationCharacterSetEndRegexp: return IntRGBA(0xCE, 0x91, 0x78);
|
||||
case Scope::KeywordOperatorNegationRegexp: return IntRGBA(0xCE, 0x91, 0x78);
|
||||
case Scope::SupportOtherParenthesisRegexp: return IntRGBA(0xCE, 0x91, 0x78);
|
||||
case Scope::ConstantCharacterCharacter_ClassRegexp: return IntRGBA(0xD1, 0x69, 0x69);
|
||||
case Scope::ConstantOtherCharacter_ClassSetRegexp: return IntRGBA(0xD1, 0x69, 0x69);
|
||||
case Scope::ConstantOtherCharacter_ClassRegexp: return IntRGBA(0xD1, 0x69, 0x69);
|
||||
case Scope::ConstantCharacterSetRegexp: return IntRGBA(0xD1, 0x69, 0x69);
|
||||
case Scope::KeywordOperatorOrRegexp: return IntRGBA(0xDC, 0xDC, 0xAA);
|
||||
case Scope::KeywordControlAnchorRegexp: return IntRGBA(0xDC, 0xDC, 0xAA);
|
||||
case Scope::KeywordOperatorQuantifierRegexp: return IntRGBA(0xD7, 0xBA, 0x7D);
|
||||
case Scope::ConstantCharacter: return IntRGBA(0x56, 0x9C, 0xD6);
|
||||
case Scope::ConstantOtherOption: return IntRGBA(0x56, 0x9C, 0xD6);
|
||||
case Scope::ConstantCharacterEscape: return IntRGBA(0xD7, 0xBA, 0x7D);
|
||||
case Scope::EntityNameLabel: return IntRGBA(0xC8, 0xC8, 0xC8);
|
||||
}
|
||||
}
|
||||
|
||||
constexpr int DarkPlus2(Scope scope)
|
||||
{
|
||||
switch (scope)
|
||||
{
|
||||
case Scope::MetaPreprocessor: return IntRGBA(0x9B, 0x9B, 0x9B);
|
||||
case Scope::SupportTypeProperty_NameJson: return DarkPlus(Scope::SupportTypeProperty_Name);
|
||||
default: return DarkPlus(scope);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,5 +0,0 @@
|
|||
#ifdef WINUI3
|
||||
#define DUX Microsoft.UI.Xaml
|
||||
#else
|
||||
#define DUX Windows.UI.Xaml
|
||||
#endif
|
|
@ -1,13 +0,0 @@
|
|||
#include "pch.h"
|
||||
#include "DummyPage.h"
|
||||
#if __has_include("DummyPage.g.cpp")
|
||||
#include "DummyPage.g.cpp"
|
||||
#endif
|
||||
|
||||
// Workaround for https://github.com/microsoft/xlang/issues/431
|
||||
// Improves compile time when working on headers by including
|
||||
// them in the DummyPage header instead of pch.h
|
||||
// because the XAML compiler is not including them itself
|
||||
|
||||
// Not used in Release mode
|
||||
// Do not include in metadata
|
|
@ -1,19 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include "DummyPage.g.h"
|
||||
|
||||
#include "ControlIncludes.h"
|
||||
|
||||
namespace winrt::WinUIEditor::implementation
|
||||
{
|
||||
struct DummyPage : DummyPageT<DummyPage>
|
||||
{
|
||||
};
|
||||
}
|
||||
|
||||
namespace winrt::WinUIEditor::factory_implementation
|
||||
{
|
||||
struct DummyPage : DummyPageT<DummyPage, implementation::DummyPage>
|
||||
{
|
||||
};
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
#include "Defines.idl"
|
||||
|
||||
namespace WinUIEditor
|
||||
{
|
||||
[default_interface]
|
||||
[webhosthidden]
|
||||
runtimeclass DummyPage : DUX.Controls.Page
|
||||
{
|
||||
DummyPage();
|
||||
}
|
||||
}
|
|
@ -1,8 +0,0 @@
|
|||
<Page
|
||||
x:Class="WinUIEditor.DummyPage"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="using:WinUIEditor"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d" />
|
|
@ -1,665 +0,0 @@
|
|||
#include "pch.h"
|
||||
#include "EditorBaseControl.h"
|
||||
#if __has_include("EditorBaseControl.g.cpp")
|
||||
#include "EditorBaseControl.g.cpp"
|
||||
#endif
|
||||
#include "EditorWrapper.h"
|
||||
#include "Helpers.h"
|
||||
#include "EditorBaseControlAutomationPeer.h"
|
||||
|
||||
using namespace ::WinUIEditor;
|
||||
using namespace winrt;
|
||||
using namespace DUX;
|
||||
using namespace DUX::Automation::Peers;
|
||||
using namespace DUX::Controls;
|
||||
using namespace DUX::Controls::Primitives;
|
||||
using namespace DUX::Input;
|
||||
using namespace DUX::Media;
|
||||
using namespace DUX::Media::Imaging;
|
||||
using namespace Windows::Foundation;
|
||||
using namespace Windows::Foundation::Collections;
|
||||
using namespace Windows::System;
|
||||
using namespace Windows::Graphics::Display;
|
||||
using namespace Windows::ApplicationModel;
|
||||
using namespace Windows::ApplicationModel::DataTransfer;
|
||||
|
||||
namespace winrt::WinUIEditor::implementation
|
||||
{
|
||||
// Todo: Something about this control is keeping the WinUI 3 versions from closing.
|
||||
// Note that making this into a blank control fixes the issue, so it is definitely something here.
|
||||
EditorBaseControl::EditorBaseControl()
|
||||
{
|
||||
DefaultStyleKey(winrt::box_value(L"WinUIEditor.EditorBaseControl"));
|
||||
|
||||
_wrapper = std::make_shared<Wrapper>();
|
||||
|
||||
Loaded({ this, &EditorBaseControl::OnLoaded });
|
||||
Unloaded({ this, &EditorBaseControl::OnUnloaded });
|
||||
|
||||
#ifndef WINUI3
|
||||
if (!_hasXamlRoot)
|
||||
{
|
||||
_displayInformation = DisplayInformation::GetForCurrentView();
|
||||
}
|
||||
#endif
|
||||
|
||||
_scintilla = make_self<Scintilla::Internal::ScintillaWinUI>(_wrapper);
|
||||
_call = std::make_shared<Scintilla::ScintillaCall>();
|
||||
_call->SetFnPtr(reinterpret_cast<SciFnDirectStatus>(_scintilla->WndProc(Scintilla::Message::GetDirectStatusFunction, 0, 0)), _scintilla->WndProc(Scintilla::Message::GetDirectPointer, 0, 0));
|
||||
|
||||
_editorWrapper = make<implementation::Editor>(get_strong());
|
||||
|
||||
_scintilla->SetWndProcTag(*this);
|
||||
_scintilla->SetWndProc(&EditorBaseControl::WndProc);
|
||||
|
||||
#ifndef WINUI3
|
||||
if (_hasFcu)
|
||||
{
|
||||
#endif
|
||||
// Registering the CharacterReceived event causes undesirable behavior with TSF in CoreWindow (normal UWP)
|
||||
// but is required to get text in classic windows (XAML Islands and WinUI 3)
|
||||
// Todo: Find more ideal way to do this
|
||||
// Tried using _tfThreadManager->GetActiveFlags but TF_TMF_IMMERSIVEMODE flag was not accurate
|
||||
if (IsClassicWindow())
|
||||
{
|
||||
CharacterReceived({ this, &EditorBaseControl::EditorBaseControl_CharacterReceived });
|
||||
}
|
||||
#ifndef WINUI3
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
EditorBaseControl::~EditorBaseControl()
|
||||
{
|
||||
_scintilla->Finalize();
|
||||
}
|
||||
|
||||
WinUIEditor::Editor EditorBaseControl::Editor()
|
||||
{
|
||||
return _editorWrapper;
|
||||
}
|
||||
|
||||
void EditorBaseControl::OnLoaded(IInspectable const &sender, DUX::RoutedEventArgs const &args)
|
||||
{
|
||||
// Following pattern from https://github.com/microsoft/microsoft-ui-xaml/blob/a7183df20367bc0e2b8c825430597a5c1e6871b6/dev/WebView2/WebView2.cpp#L1556
|
||||
|
||||
#ifndef WINUI3
|
||||
_isLoaded = true;
|
||||
#endif
|
||||
|
||||
if (!IsLoadedCompat())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
#ifndef WINUI3
|
||||
if (_hasXamlRoot)
|
||||
{
|
||||
#endif
|
||||
UpdateDpi(XamlRoot().RasterizationScale());
|
||||
_xamlRootChangedRevoker = XamlRoot().Changed(auto_revoke, { this, &EditorBaseControl::XamlRoot_Changed });
|
||||
#ifndef WINUI3
|
||||
}
|
||||
else
|
||||
{
|
||||
UpdateDpi(_displayInformation.RawPixelsPerViewPixel());
|
||||
_dpiChangedRevoker = _displayInformation.DpiChanged(auto_revoke, { this, &EditorBaseControl::DisplayInformation_DpiChanged });
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void EditorBaseControl::OnUnloaded(IInspectable const &sender, DUX::RoutedEventArgs const &args)
|
||||
{
|
||||
#ifndef WINUI3
|
||||
_isLoaded = false;
|
||||
#endif
|
||||
|
||||
if (IsLoadedCompat())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
#ifndef WINUI3
|
||||
if (_hasXamlRoot)
|
||||
{
|
||||
#endif
|
||||
_xamlRootChangedRevoker.revoke();
|
||||
#ifndef WINUI3
|
||||
}
|
||||
else
|
||||
{
|
||||
_dpiChangedRevoker.revoke();
|
||||
}
|
||||
#endif
|
||||
|
||||
_scintilla->StopTimers();
|
||||
}
|
||||
|
||||
bool EditorBaseControl::IsLoadedCompat()
|
||||
{
|
||||
#ifndef WINUI3
|
||||
if (_hasIsLoaded)
|
||||
{
|
||||
#endif
|
||||
return IsLoaded();
|
||||
#ifndef WINUI3
|
||||
}
|
||||
else
|
||||
{
|
||||
return _isLoaded;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef WINUI3
|
||||
void EditorBaseControl::DisplayInformation_DpiChanged(DisplayInformation const &sender, IInspectable const &args)
|
||||
{
|
||||
UpdateDpi(sender.RawPixelsPerViewPixel());
|
||||
}
|
||||
#endif
|
||||
|
||||
void EditorBaseControl::XamlRoot_Changed(DUX::XamlRoot const &sender, XamlRootChangedEventArgs const &args)
|
||||
{
|
||||
UpdateDpi(sender.RasterizationScale());
|
||||
}
|
||||
|
||||
void EditorBaseControl::UpdateDpi(float dpiScale)
|
||||
{
|
||||
if (_dpiScale != dpiScale)
|
||||
{
|
||||
_wrapper->LogicalDpi(dpiScale * 96);
|
||||
_dpiScale = dpiScale;
|
||||
_scintilla->DpiChanged();
|
||||
_dpiChangedEvent(*this, dpiScale);
|
||||
}
|
||||
}
|
||||
|
||||
void EditorBaseControl::AddContextMenuItems(MenuFlyout const &menu)
|
||||
{
|
||||
const auto writable{ !static_cast<bool>(_scintilla->WndProc(Scintilla::Message::GetReadOnly, 0, 0)) };
|
||||
const auto selection{ !static_cast<bool>(_scintilla->WndProc(Scintilla::Message::GetSelectionEmpty, 0, 0)) };
|
||||
|
||||
const MenuFlyoutItem undoItem{};
|
||||
undoItem.Text(L"Undo"); // Todo: Localize
|
||||
undoItem.Icon(SymbolIcon{ Symbol::Undo });
|
||||
undoItem.Tag(box_value(ScintillaMessage::Undo));
|
||||
undoItem.IsEnabled(_scintilla->WndProc(Scintilla::Message::CanUndo, 0, 0));
|
||||
undoItem.Click({ this, &EditorBaseControl::ContextMenuItem_Click }); // Todo: Revoke event handler?
|
||||
menu.Items().Append(undoItem);
|
||||
|
||||
const MenuFlyoutItem redoItem{};
|
||||
redoItem.Text(L"Redo");
|
||||
redoItem.Icon(SymbolIcon{ Symbol::Redo });
|
||||
redoItem.Tag(box_value(ScintillaMessage::Redo));
|
||||
redoItem.IsEnabled(_scintilla->WndProc(Scintilla::Message::CanRedo, 0, 0));
|
||||
redoItem.Click({ this, &EditorBaseControl::ContextMenuItem_Click });
|
||||
menu.Items().Append(redoItem);
|
||||
|
||||
menu.Items().Append(MenuFlyoutSeparator{});
|
||||
|
||||
const MenuFlyoutItem cutItem{};
|
||||
cutItem.Text(L"Cut");
|
||||
cutItem.Icon(SymbolIcon{ Symbol::Cut });
|
||||
cutItem.Tag(box_value(ScintillaMessage::Cut));
|
||||
cutItem.IsEnabled(writable && selection);
|
||||
cutItem.Click({ this, &EditorBaseControl::ContextMenuItem_Click });
|
||||
menu.Items().Append(cutItem);
|
||||
|
||||
const MenuFlyoutItem copyItem{};
|
||||
copyItem.Text(L"Copy");
|
||||
copyItem.Icon(SymbolIcon{ Symbol::Copy });
|
||||
copyItem.Tag(box_value(ScintillaMessage::Copy));
|
||||
copyItem.IsEnabled(selection);
|
||||
copyItem.Click({ this, &EditorBaseControl::ContextMenuItem_Click });
|
||||
menu.Items().Append(copyItem);
|
||||
|
||||
const MenuFlyoutItem pasteItem{};
|
||||
pasteItem.Text(L"Paste");
|
||||
pasteItem.Icon(SymbolIcon{ Symbol::Paste });
|
||||
pasteItem.Tag(box_value(ScintillaMessage::Paste));
|
||||
pasteItem.IsEnabled(_scintilla->WndProc(Scintilla::Message::CanPaste, 0, 0));
|
||||
pasteItem.Click({ this, &EditorBaseControl::ContextMenuItem_Click });
|
||||
menu.Items().Append(pasteItem);
|
||||
|
||||
const MenuFlyoutItem deleteItem{};
|
||||
deleteItem.Text(L"Delete");
|
||||
deleteItem.Icon(SymbolIcon{ Symbol::Delete });
|
||||
deleteItem.Tag(box_value(ScintillaMessage::Clear));
|
||||
deleteItem.IsEnabled(writable && selection);
|
||||
deleteItem.Click({ this, &EditorBaseControl::ContextMenuItem_Click });
|
||||
menu.Items().Append(deleteItem);
|
||||
|
||||
menu.Items().Append(MenuFlyoutSeparator{});
|
||||
|
||||
const MenuFlyoutItem selectAllItem{};
|
||||
selectAllItem.Text(L"Select all");
|
||||
selectAllItem.Icon(SymbolIcon{ Symbol::SelectAll });
|
||||
selectAllItem.Tag(box_value(ScintillaMessage::SelectAll));
|
||||
selectAllItem.Click({ this, &EditorBaseControl::ContextMenuItem_Click });
|
||||
menu.Items().Append(selectAllItem);
|
||||
}
|
||||
|
||||
bool EditorBaseControl::ShowContextMenu(UIElement const &targetElement, Point const &point)
|
||||
{
|
||||
if (_scintilla->ShouldShowContextMenu(Point{ point.X * _dpiScale, point.Y * _dpiScale }))
|
||||
{
|
||||
const MenuFlyout menu{};
|
||||
AddContextMenuItems(menu);
|
||||
menu.ShowAt(targetElement, point);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool EditorBaseControl::ShowContextMenuAtCurrentPosition()
|
||||
{
|
||||
if (auto imageTarget{ GetTemplateChild(L"ImageTarget").try_as<UIElement>() }) // Todo: Store this
|
||||
{
|
||||
const auto pos{ _scintilla->WndProc(Scintilla::Message::GetCurrentPos, 0, 0) };
|
||||
return ShowContextMenu(imageTarget, Point{
|
||||
_scintilla->WndProc(Scintilla::Message::PointXFromPosition, 0, pos) / _dpiScale,
|
||||
(_scintilla->WndProc(Scintilla::Message::PointYFromPosition, 0, pos) + _scintilla->WndProc(Scintilla::Message::TextHeight, 0, 0)) / _dpiScale
|
||||
});
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
Scintilla::sptr_t EditorBaseControl::PublicWndProc(Scintilla::Message iMessage, Scintilla::uptr_t wParam, Scintilla::sptr_t lParam)
|
||||
{
|
||||
return _scintilla->WndProc(iMessage, wParam, lParam);
|
||||
}
|
||||
|
||||
int64_t EditorBaseControl::SendMessage(ScintillaMessage const &message, uint64_t wParam, int64_t lParam)
|
||||
{
|
||||
return PublicWndProc(static_cast<Scintilla::Message>(message), wParam, lParam);
|
||||
}
|
||||
|
||||
void EditorBaseControl::StyleSetForeTransparent(int style, Scintilla::Internal::ColourRGBA color)
|
||||
{
|
||||
_scintilla->StyleSetForeTransparent(style, color);
|
||||
}
|
||||
|
||||
void EditorBaseControl::StyleSetBackTransparent(int style, Scintilla::Internal::ColourRGBA color)
|
||||
{
|
||||
_scintilla->StyleSetBackTransparent(style, color);
|
||||
}
|
||||
|
||||
void EditorBaseControl::InvalidateStyleRedraw()
|
||||
{
|
||||
_scintilla->PublicInvalidateStyleRedraw();
|
||||
}
|
||||
|
||||
void EditorBaseControl::StyleClearCustom()
|
||||
{
|
||||
_scintilla->StyleClearCustom();
|
||||
}
|
||||
|
||||
void EditorBaseControl::SetFoldMarginColorTransparent(bool useSetting, Scintilla::Internal::ColourRGBA back)
|
||||
{
|
||||
_scintilla->SetFoldMarginColorTransparent(useSetting, back);
|
||||
}
|
||||
|
||||
void EditorBaseControl::SetFoldMarginHiColorTransparent(bool useSetting, Scintilla::Internal::ColourRGBA fore)
|
||||
{
|
||||
_scintilla->SetFoldMarginHiColorTransparent(useSetting, fore);
|
||||
}
|
||||
|
||||
void EditorBaseControl::OnApplyTemplate()
|
||||
{
|
||||
__super::OnApplyTemplate();
|
||||
|
||||
#ifndef WINUI3
|
||||
if (_hasXamlRoot)
|
||||
{
|
||||
#endif
|
||||
UpdateDpi(XamlRoot().RasterizationScale());
|
||||
#ifndef WINUI3
|
||||
}
|
||||
else
|
||||
{
|
||||
UpdateDpi(_displayInformation.RawPixelsPerViewPixel());
|
||||
}
|
||||
#endif
|
||||
|
||||
const VirtualSurfaceImageSource virtualSurfaceImageSource{ 0, 0 };
|
||||
|
||||
_vsisNative = virtualSurfaceImageSource.as<::IVirtualSurfaceImageSourceNative>();
|
||||
|
||||
_wrapper->VsisNative(_vsisNative);
|
||||
_wrapper->CreateGraphicsDevices();
|
||||
_vsisNative->RegisterForUpdatesNeeded(_scintilla.as<::IVirtualSurfaceUpdatesCallbackNative>().get());
|
||||
|
||||
// The SurfaceImageSource object's underlying
|
||||
// ISurfaceImageSourceNativeWithD2D object will contain the completed bitmap.
|
||||
|
||||
const auto horizontalScrollBar{ GetTemplateChild(L"HorizontalScrollBar").try_as<ScrollBar>() };
|
||||
const auto verticalScrollBar{ GetTemplateChild(L"VerticalScrollBar").try_as<ScrollBar>() };
|
||||
if (horizontalScrollBar)
|
||||
{
|
||||
_horizontalScrollBarScrollRevoker = horizontalScrollBar.Scroll(auto_revoke, { this, &EditorBaseControl::HorizontalScrollBar_Scroll });
|
||||
}
|
||||
if (verticalScrollBar)
|
||||
{
|
||||
_verticalScrollBarScrollRevoker = verticalScrollBar.Scroll(auto_revoke, { this, &EditorBaseControl::VerticalScrollBar_Scroll });
|
||||
}
|
||||
_wrapper->SetScrollBars(horizontalScrollBar, verticalScrollBar);
|
||||
|
||||
if (const auto imageTarget{ GetTemplateChild(L"ImageTarget").try_as<Border>() })
|
||||
{
|
||||
_imageTargetSizeChangedRevoker = imageTarget.SizeChanged(auto_revoke, { this, &EditorBaseControl::ImageTarget_SizeChanged });
|
||||
_imageTargetPointerMovedRevoker = imageTarget.PointerMoved(auto_revoke, { this, &EditorBaseControl::ImageTarget_PointerMoved });
|
||||
#ifndef WINUI3
|
||||
_imageTargetPointerCaptureLostRevoker = imageTarget.PointerCaptureLost(auto_revoke, { this, &EditorBaseControl::ImageTarget_PointerCaptureLost });
|
||||
_imageTargetPointerEnteredRevoker = imageTarget.PointerEntered(auto_revoke, { this, &EditorBaseControl::ImageTarget_PointerEntered });
|
||||
#endif
|
||||
_imageTargetPointerExitedRevoker = imageTarget.PointerExited(auto_revoke, { this, &EditorBaseControl::ImageTarget_PointerExited });
|
||||
_imageTargetPointerWheelChangedRevoker = imageTarget.PointerWheelChanged(auto_revoke, { this, &EditorBaseControl::ImageTarget_PointerWheelChanged });
|
||||
_imageTargetDragEnterRevoker = imageTarget.DragEnter(auto_revoke, { this, &EditorBaseControl::ImageTarget_DragEnter });
|
||||
_imageTargetDragOverRevoker = imageTarget.DragOver(auto_revoke, { this, &EditorBaseControl::ImageTarget_DragOver });
|
||||
_imageTargetDragLeaveRevoker = imageTarget.DragLeave(auto_revoke, { this, &EditorBaseControl::ImageTarget_DragLeave });
|
||||
_imageTargetDropRevoker = imageTarget.Drop(auto_revoke, { this, &EditorBaseControl::ImageTarget_Drop });
|
||||
|
||||
_wrapper->SetMouseCaptureElement(imageTarget);
|
||||
_imageTargetDragStartingRevoker = imageTarget.DragStarting(auto_revoke, { this, &EditorBaseControl::ImageTarget_DragStarting });
|
||||
|
||||
_imageTargetContextRequestedRevoker = imageTarget.ContextRequested(auto_revoke, { this, &EditorBaseControl::ImageTarget_ContextRequested });
|
||||
|
||||
const ImageBrush brush{};
|
||||
brush.ImageSource(virtualSurfaceImageSource);
|
||||
imageTarget.Background(brush);
|
||||
}
|
||||
|
||||
#ifndef WINUI3
|
||||
// Todo: Evaluate if this is an appropriate place to add this event (and other code in this method)
|
||||
_suspendingRevoker = Application::Current().Suspending(auto_revoke, { this, &EditorBaseControl::Application_Suspending });
|
||||
#endif
|
||||
}
|
||||
|
||||
// Todo: Focus bug: deactive window, click on control, press ctrl+a quickly. result: selection disappears
|
||||
|
||||
void EditorBaseControl::OnGotFocus(RoutedEventArgs const &e)
|
||||
{
|
||||
__super::OnGotFocus(e);
|
||||
|
||||
_isFocused = true;
|
||||
|
||||
_scintilla->FocusChanged(true);
|
||||
}
|
||||
|
||||
void EditorBaseControl::OnLostFocus(RoutedEventArgs const &e)
|
||||
{
|
||||
__super::OnLostFocus(e);
|
||||
|
||||
_isFocused = false;
|
||||
|
||||
_scintilla->FocusChanged(false);
|
||||
}
|
||||
|
||||
void EditorBaseControl::OnPointerPressed(DUX::Input::PointerRoutedEventArgs const &e)
|
||||
{
|
||||
__super::OnPointerPressed(e);
|
||||
|
||||
Focus(FocusState::Pointer);
|
||||
|
||||
// The focus state seems to get confused if the following code is placed in ImageTarget_PointerPressed.
|
||||
// OnPointerReleased is the same for symmetry. ImageTarget_PointerMoved is there to show correct cursor
|
||||
// when moving the cursor over the scrollbar (UWP).
|
||||
|
||||
if (auto imageTarget{ GetTemplateChild(L"ImageTarget").try_as<UIElement>() }) // Todo: Store this
|
||||
{
|
||||
auto point{ e.GetCurrentPoint(imageTarget) };
|
||||
auto scaled{ point.Position() };
|
||||
switch (point.Properties().PointerUpdateKind())
|
||||
{
|
||||
case DUI::PointerUpdateKind::LeftButtonPressed:
|
||||
_scintilla->PointerPressed(Point{ scaled.X * _dpiScale, scaled.Y * _dpiScale }, point.Timestamp() / 1000ul, e.KeyModifiers());
|
||||
break;
|
||||
case DUI::PointerUpdateKind::RightButtonPressed:
|
||||
_scintilla->RightPointerPressed(Point{ scaled.X * _dpiScale, scaled.Y * _dpiScale }, point.Timestamp() / 1000ul, e.KeyModifiers());
|
||||
break;
|
||||
}
|
||||
// Todo: make sure the loss of precision is not going to realistically cause a problem
|
||||
}
|
||||
}
|
||||
|
||||
void EditorBaseControl::OnPointerReleased(DUX::Input::PointerRoutedEventArgs const &e)
|
||||
{
|
||||
__super::OnPointerReleased(e);
|
||||
|
||||
if (auto imageTarget{ GetTemplateChild(L"ImageTarget").try_as<UIElement>() }) // Todo: Store this
|
||||
{
|
||||
auto point{ e.GetCurrentPoint(imageTarget) };
|
||||
auto scaled{ point.Position() };
|
||||
switch (point.Properties().PointerUpdateKind())
|
||||
{
|
||||
case DUI::PointerUpdateKind::LeftButtonReleased:
|
||||
_scintilla->PointerReleased(Point{ scaled.X * _dpiScale, scaled.Y * _dpiScale }, point.Timestamp() / 1000ul, e.KeyModifiers());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
e.Handled(true); // Prevents control from losing focus on pointer released
|
||||
// See https://stackoverflow.com/questions/59392044/uwp-control-to-keep-focus-after-mouse-click
|
||||
// Alternate approach: call Focus in OnFocusLost
|
||||
}
|
||||
|
||||
AutomationPeer EditorBaseControl::OnCreateAutomationPeer()
|
||||
{
|
||||
return make<EditorBaseControlAutomationPeer>(*this);
|
||||
}
|
||||
|
||||
void EditorBaseControl::ImageTarget_PointerMoved(IInspectable const &sender, PointerRoutedEventArgs const &e)
|
||||
{
|
||||
if (auto imageTarget{ GetTemplateChild(L"ImageTarget").try_as<UIElement>() }) // Todo: Store this
|
||||
{
|
||||
auto point{ e.GetCurrentPoint(imageTarget) };
|
||||
auto scaled{ point.Position() };
|
||||
auto x{ scaled.X * _dpiScale };
|
||||
auto y{ scaled.Y * _dpiScale };
|
||||
|
||||
_scintilla->PointerMoved(Point{ x, y }, point.Timestamp() / 1000ul, e.KeyModifiers(), point);
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef WINUI3
|
||||
void EditorBaseControl::ImageTarget_PointerCaptureLost(IInspectable const &sender, PointerRoutedEventArgs const &e)
|
||||
{
|
||||
if (!_isPointerOver)
|
||||
{
|
||||
// Todo: if you, e.g. hover over a HyperlinkButton when this is called, you will get an arrow instead of the hand you want
|
||||
winrt::Windows::UI::Core::CoreWindow::GetForCurrentThread().PointerCursor(Windows::UI::Core::CoreCursor{ Windows::UI::Core::CoreCursorType::Arrow, 0 });
|
||||
}
|
||||
}
|
||||
|
||||
void EditorBaseControl::ImageTarget_PointerEntered(IInspectable const &sender, PointerRoutedEventArgs const &e)
|
||||
{
|
||||
_isPointerOver = true;
|
||||
}
|
||||
#endif
|
||||
|
||||
void EditorBaseControl::ImageTarget_PointerExited(IInspectable const &sender, PointerRoutedEventArgs const &e)
|
||||
{
|
||||
#ifndef WINUI3
|
||||
_isPointerOver = false;
|
||||
if (!_wrapper->HaveMouseCapture())
|
||||
{
|
||||
winrt::Windows::UI::Core::CoreWindow::GetForCurrentThread().PointerCursor(Windows::UI::Core::CoreCursor{ Windows::UI::Core::CoreCursorType::Arrow, 0 });
|
||||
}
|
||||
#endif
|
||||
_scintilla->PointerExited();
|
||||
}
|
||||
|
||||
void EditorBaseControl::OnKeyDown(KeyRoutedEventArgs const &e)
|
||||
{
|
||||
__super::OnKeyDown(e);
|
||||
|
||||
const auto modifiers{ GetKeyModifiersForCurrentThread() };
|
||||
|
||||
auto handled = true;
|
||||
_scintilla->KeyDown(e.Key(), modifiers, e.KeyStatus().IsExtendedKey, &handled); // Todo: Or use VirtualKey?
|
||||
|
||||
if (!handled
|
||||
&& e.Key() == VirtualKey::F10 && (modifiers & VirtualKeyModifiers::Shift) == VirtualKeyModifiers::Shift
|
||||
&& ShowContextMenuAtCurrentPosition())
|
||||
{
|
||||
handled = true;
|
||||
}
|
||||
|
||||
e.Handled(handled);
|
||||
}
|
||||
|
||||
void EditorBaseControl::OnKeyUp(KeyRoutedEventArgs const &e)
|
||||
{
|
||||
if (e.Key() == VirtualKey::Application)
|
||||
{
|
||||
e.Handled(ShowContextMenuAtCurrentPosition());
|
||||
}
|
||||
}
|
||||
|
||||
void EditorBaseControl::EditorBaseControl_CharacterReceived(DUX::UIElement const &sender, CharacterReceivedRoutedEventArgs const &e)
|
||||
{
|
||||
if (_isFocused)
|
||||
{
|
||||
_scintilla->CharacterReceived(e.Character());
|
||||
e.Handled(true);
|
||||
}
|
||||
}
|
||||
|
||||
void EditorBaseControl::ImageTarget_SizeChanged(IInspectable const &sender, SizeChangedEventArgs const &args)
|
||||
{
|
||||
if (_vsisNative)
|
||||
{
|
||||
auto width{ ConvertFromDipToPixelUnit(args.NewSize().Width, _dpiScale) };
|
||||
auto height{ ConvertFromDipToPixelUnit(args.NewSize().Height, _dpiScale) };
|
||||
_wrapper->Width(width);
|
||||
_wrapper->Height(height);
|
||||
_vsisNative->Resize(width, height);
|
||||
_scintilla->SizeChanged();
|
||||
}
|
||||
}
|
||||
|
||||
void EditorBaseControl::ImageTarget_PointerWheelChanged(IInspectable const &sender, PointerRoutedEventArgs const &e)
|
||||
{
|
||||
auto properties{ e.GetCurrentPoint(sender.as<UIElement>()).Properties() };
|
||||
_scintilla->PointerWheelChanged(properties.MouseWheelDelta(), properties.IsHorizontalMouseWheel(), e.KeyModifiers());
|
||||
}
|
||||
|
||||
void EditorBaseControl::ImageTarget_DragEnter(IInspectable const &sender, DragEventArgs const &e)
|
||||
{
|
||||
DataPackageOperation op;
|
||||
_scintilla->DragEnter(e.DataView(), e.AllowedOperations(), e.Modifiers(), op);
|
||||
e.AcceptedOperation(op);
|
||||
e.DragUIOverride().IsContentVisible(false);
|
||||
e.DragUIOverride().IsCaptionVisible(false);
|
||||
}
|
||||
|
||||
void EditorBaseControl::ImageTarget_DragOver(IInspectable const &sender, DragEventArgs const &e)
|
||||
{
|
||||
auto point{ e.GetPosition(sender.as<UIElement>()) };
|
||||
point.X *= _dpiScale;
|
||||
point.Y *= _dpiScale;
|
||||
DataPackageOperation op;
|
||||
_scintilla->DragOver(point, e.AllowedOperations(), e.Modifiers(), op);
|
||||
e.AcceptedOperation(op);
|
||||
}
|
||||
|
||||
void EditorBaseControl::ImageTarget_DragLeave(IInspectable const &sender, DragEventArgs const &e)
|
||||
{
|
||||
_scintilla->DragLeave();
|
||||
}
|
||||
|
||||
void EditorBaseControl::ImageTarget_Drop(IInspectable const &sender, DragEventArgs const &e)
|
||||
{
|
||||
auto point{ e.GetPosition(sender.as<UIElement>()) };
|
||||
point.X *= _dpiScale;
|
||||
point.Y *= _dpiScale;
|
||||
DataPackageOperation op;
|
||||
_scintilla->Drop(point, e.DataView(), e.AllowedOperations(), e.Modifiers(), op);
|
||||
e.AcceptedOperation(op);
|
||||
}
|
||||
|
||||
void EditorBaseControl::ImageTarget_DragStarting(UIElement const &sender, DragStartingEventArgs const &e)
|
||||
{
|
||||
e.AllowedOperations(DataPackageOperation::Copy | DataPackageOperation::Move);
|
||||
e.Data().SetText(winrt::to_hstring(_scintilla->GetDragData()));
|
||||
e.DragUI().SetContentFromDataPackage();
|
||||
}
|
||||
|
||||
void EditorBaseControl::ImageTarget_ContextRequested(UIElement const &sender, ContextRequestedEventArgs const &e)
|
||||
{
|
||||
Point point;
|
||||
if (e.TryGetPosition(sender, point))
|
||||
{
|
||||
e.Handled(ShowContextMenu(sender, point));
|
||||
}
|
||||
else if (const auto frameworkElement{ sender.try_as<FrameworkElement>() })
|
||||
{
|
||||
e.Handled(ShowContextMenuAtCurrentPosition());
|
||||
}
|
||||
}
|
||||
|
||||
void EditorBaseControl::ContextMenuItem_Click(Windows::Foundation::IInspectable const &sender, DUX::RoutedEventArgs const &e)
|
||||
{
|
||||
_scintilla->WndProc(static_cast<Scintilla::Message>(unbox_value<ScintillaMessage>(sender.as<FrameworkElement>().Tag())), 0, 0);
|
||||
}
|
||||
|
||||
void EditorBaseControl::HorizontalScrollBar_Scroll(IInspectable const &sender, ScrollEventArgs const &e)
|
||||
{
|
||||
_scintilla->HorizontalScroll(static_cast<Scintilla::Internal::ScrollEventType>(e.ScrollEventType()), static_cast<int>(e.NewValue()));
|
||||
}
|
||||
|
||||
void EditorBaseControl::VerticalScrollBar_Scroll(IInspectable const &sender, ScrollEventArgs const &e)
|
||||
{
|
||||
_scintilla->Scroll(static_cast<Scintilla::Internal::ScrollEventType>(e.ScrollEventType()), static_cast<int>(e.NewValue()));
|
||||
}
|
||||
|
||||
LRESULT EditorBaseControl::WndProc(IInspectable const &tag, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
if (msg == WM_NOTIFY)
|
||||
{
|
||||
const auto data{ reinterpret_cast<Scintilla::NotificationData *>(lParam) };
|
||||
const auto sender{ tag.as<EditorBaseControl>() };
|
||||
sender->InternalNotifyMessageReceived(*sender, lParam); // CodeEditorControl should receive the notification before user subscriptions
|
||||
sender->_notifyMessageReceived(*sender, lParam);
|
||||
sender->_editorWrapper.as<implementation::Editor>()->ProcessEvent(data);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
event_token EditorBaseControl::DpiChanged(EventHandler<double> const &handler)
|
||||
{
|
||||
return _dpiChangedEvent.add(handler);
|
||||
}
|
||||
|
||||
void EditorBaseControl::DpiChanged(event_token const &token) noexcept
|
||||
{
|
||||
_dpiChangedEvent.remove(token);
|
||||
}
|
||||
|
||||
event_token EditorBaseControl::NotifyMessageReceived(EventHandler<int64_t> const &handler)
|
||||
{
|
||||
return _notifyMessageReceived.add(handler);
|
||||
}
|
||||
|
||||
void EditorBaseControl::NotifyMessageReceived(event_token const &token) noexcept
|
||||
{
|
||||
_notifyMessageReceived.remove(token);
|
||||
}
|
||||
|
||||
float EditorBaseControl::DpiScale()
|
||||
{
|
||||
return _dpiScale;
|
||||
}
|
||||
|
||||
#ifndef WINUI3
|
||||
void EditorBaseControl::Application_Suspending(IInspectable const &sender, SuspendingEventArgs const &args)
|
||||
{
|
||||
// Required or crashes on resume
|
||||
// https://learn.microsoft.com/en-us/windows/uwp/gaming/directx-and-xaml-interop
|
||||
// https://learn.microsoft.com/en-us/windows/win32/api/dxgi1_3/nf-dxgi1_3-idxgidevice3-trim
|
||||
// Todo: Should ClearResources get called too? https://github.com/microsoft/Win2D/blob/master/winrt/lib/drawing/CanvasDevice.cpp#L1040
|
||||
_wrapper->TrimDxgiDevice();
|
||||
}
|
||||
#endif
|
||||
}
|
|
@ -1,121 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include "EditorBaseControl.g.h"
|
||||
|
||||
#include "ScintillaWin.h"
|
||||
#include "ScintillaCall.h"
|
||||
#include "Wrapper.h"
|
||||
|
||||
namespace winrt::WinUIEditor::implementation
|
||||
{
|
||||
struct EditorBaseControl : EditorBaseControlT<EditorBaseControl>
|
||||
{
|
||||
EditorBaseControl();
|
||||
~EditorBaseControl();
|
||||
|
||||
WinUIEditor::Editor Editor();
|
||||
std::shared_ptr<Scintilla::ScintillaCall> Call() noexcept { return _call; }
|
||||
|
||||
void OnApplyTemplate();
|
||||
void OnGotFocus(DUX::RoutedEventArgs const &e);
|
||||
void OnLostFocus(DUX::RoutedEventArgs const &e);
|
||||
void OnKeyDown(DUX::Input::KeyRoutedEventArgs const &e);
|
||||
void OnKeyUp(DUX::Input::KeyRoutedEventArgs const &e);
|
||||
void OnPointerPressed(DUX::Input::PointerRoutedEventArgs const &e);
|
||||
void OnPointerReleased(DUX::Input::PointerRoutedEventArgs const &e);
|
||||
DUX::Automation::Peers::AutomationPeer OnCreateAutomationPeer();
|
||||
|
||||
Scintilla::sptr_t PublicWndProc(Scintilla::Message iMessage, Scintilla::uptr_t wParam, Scintilla::sptr_t lParam);
|
||||
int64_t SendMessage(ScintillaMessage const &message, uint64_t wParam, int64_t lParam);
|
||||
|
||||
void StyleSetForeTransparent(int style, Scintilla::Internal::ColourRGBA color);
|
||||
void StyleSetBackTransparent(int style, Scintilla::Internal::ColourRGBA color);
|
||||
void InvalidateStyleRedraw();
|
||||
void StyleClearCustom();
|
||||
void SetFoldMarginColorTransparent(bool useSetting, Scintilla::Internal::ColourRGBA back);
|
||||
void SetFoldMarginHiColorTransparent(bool useSetting, Scintilla::Internal::ColourRGBA fore);
|
||||
|
||||
event_token DpiChanged(Windows::Foundation::EventHandler<double> const &handler);
|
||||
void DpiChanged(event_token const &token) noexcept;
|
||||
|
||||
event_token NotifyMessageReceived(Windows::Foundation::EventHandler<int64_t> const &handler);
|
||||
void NotifyMessageReceived(event_token const &token) noexcept;
|
||||
float DpiScale();
|
||||
|
||||
event<Windows::Foundation::EventHandler<int64_t>> InternalNotifyMessageReceived;
|
||||
|
||||
private:
|
||||
#ifndef WINUI3
|
||||
bool _hasFcu{ Windows::Foundation::Metadata::ApiInformation::IsApiContractPresent(L"Windows.Foundation.UniversalApiContract", 5) }; // Todo: Make static
|
||||
bool _hasXamlRoot{ Windows::Foundation::Metadata::ApiInformation::IsTypePresent(L"Windows.UI.Xaml.XamlRoot") }; // Todo: Make static
|
||||
bool _hasIsLoaded{ Windows::Foundation::Metadata::ApiInformation::IsPropertyPresent(L"Windows.UI.Xaml.FrameworkElement", L"IsLoaded") }; // Todo: Make static
|
||||
bool _isPointerOver{ false };
|
||||
Windows::Graphics::Display::DisplayInformation _displayInformation{ nullptr };
|
||||
bool _isLoaded{ false };
|
||||
#endif
|
||||
bool _isFocused{ false };
|
||||
WinUIEditor::Editor _editorWrapper{ nullptr };
|
||||
std::shared_ptr<Scintilla::ScintillaCall> _call{ nullptr };
|
||||
com_ptr<::Scintilla::Internal::ScintillaWinUI> _scintilla{ nullptr };
|
||||
float _dpiScale{ 0 };
|
||||
event<Windows::Foundation::EventHandler<double>> _dpiChangedEvent;
|
||||
event<Windows::Foundation::EventHandler<int64_t>> _notifyMessageReceived;
|
||||
DUX::FrameworkElement::SizeChanged_revoker _imageTargetSizeChangedRevoker{};
|
||||
void ImageTarget_SizeChanged(Windows::Foundation::IInspectable const &sender, DUX::SizeChangedEventArgs const &args);
|
||||
DUX::UIElement::PointerMoved_revoker _imageTargetPointerMovedRevoker{};
|
||||
void ImageTarget_PointerMoved(Windows::Foundation::IInspectable const &sender, DUX::Input::PointerRoutedEventArgs const &e);
|
||||
#ifndef WINUI3
|
||||
DUX::UIElement::PointerCaptureLost_revoker _imageTargetPointerCaptureLostRevoker{};
|
||||
void ImageTarget_PointerCaptureLost(Windows::Foundation::IInspectable const &sender, DUX::Input::PointerRoutedEventArgs const &e);
|
||||
DUX::UIElement::PointerEntered_revoker _imageTargetPointerEnteredRevoker{};
|
||||
void ImageTarget_PointerEntered(Windows::Foundation::IInspectable const &sender, DUX::Input::PointerRoutedEventArgs const &e);
|
||||
#endif
|
||||
DUX::UIElement::PointerExited_revoker _imageTargetPointerExitedRevoker{};
|
||||
void ImageTarget_PointerExited(Windows::Foundation::IInspectable const &sender, DUX::Input::PointerRoutedEventArgs const &e);
|
||||
DUX::UIElement::PointerWheelChanged_revoker _imageTargetPointerWheelChangedRevoker{};
|
||||
void ImageTarget_PointerWheelChanged(Windows::Foundation::IInspectable const &sender, DUX::Input::PointerRoutedEventArgs const &e);
|
||||
DUX::UIElement::DragEnter_revoker _imageTargetDragEnterRevoker{};
|
||||
void ImageTarget_DragEnter(Windows::Foundation::IInspectable const &sender, DUX::DragEventArgs const &e);
|
||||
DUX::UIElement::DragOver_revoker _imageTargetDragOverRevoker{};
|
||||
void ImageTarget_DragOver(Windows::Foundation::IInspectable const &sender, DUX::DragEventArgs const &e);
|
||||
DUX::UIElement::DragLeave_revoker _imageTargetDragLeaveRevoker{};
|
||||
void ImageTarget_DragLeave(Windows::Foundation::IInspectable const &sender, DUX::DragEventArgs const &e);
|
||||
DUX::UIElement::Drop_revoker _imageTargetDropRevoker{};
|
||||
void ImageTarget_Drop(Windows::Foundation::IInspectable const &sender, DUX::DragEventArgs const &e);
|
||||
DUX::UIElement::DragStarting_revoker _imageTargetDragStartingRevoker{};
|
||||
void ImageTarget_DragStarting(DUX::UIElement const &sender, DUX::DragStartingEventArgs const &e);
|
||||
DUX::UIElement::ContextRequested_revoker _imageTargetContextRequestedRevoker{};
|
||||
void ImageTarget_ContextRequested(DUX::UIElement const &sender, DUX::Input::ContextRequestedEventArgs const &e);
|
||||
void ContextMenuItem_Click(Windows::Foundation::IInspectable const &sender, DUX::RoutedEventArgs const &e);
|
||||
DUXC::Primitives::ScrollBar::Scroll_revoker _horizontalScrollBarScrollRevoker{};
|
||||
void HorizontalScrollBar_Scroll(Windows::Foundation::IInspectable const &sender, DUX::Controls::Primitives::ScrollEventArgs const &e);
|
||||
DUXC::Primitives::ScrollBar::Scroll_revoker _verticalScrollBarScrollRevoker{};
|
||||
void VerticalScrollBar_Scroll(Windows::Foundation::IInspectable const &sender, DUX::Controls::Primitives::ScrollEventArgs const &e);
|
||||
void EditorBaseControl_CharacterReceived(DUX::UIElement const &sender, DUX::Input::CharacterReceivedRoutedEventArgs const &args);
|
||||
void OnLoaded(Windows::Foundation::IInspectable const &sender, DUX::RoutedEventArgs const &args);
|
||||
void OnUnloaded(Windows::Foundation::IInspectable const &sender, DUX::RoutedEventArgs const &args);
|
||||
bool IsLoadedCompat();
|
||||
DUX::XamlRoot::Changed_revoker _xamlRootChangedRevoker{};
|
||||
void XamlRoot_Changed(DUX::XamlRoot const &sender, DUX::XamlRootChangedEventArgs const &args);
|
||||
void UpdateDpi(float dpiScale);
|
||||
void AddContextMenuItems(DUX::Controls::MenuFlyout const &menu);
|
||||
bool ShowContextMenu(DUX::UIElement const &targetElement, Windows::Foundation::Point const &point);
|
||||
bool ShowContextMenuAtCurrentPosition();
|
||||
winrt::com_ptr<::IVirtualSurfaceImageSourceNative> _vsisNative;
|
||||
std::shared_ptr<::WinUIEditor::Wrapper> _wrapper{ nullptr };
|
||||
static LRESULT WndProc(Windows::Foundation::IInspectable const &, UINT msg, WPARAM wParam, LPARAM lParam);
|
||||
#ifndef WINUI3
|
||||
Windows::Graphics::Display::DisplayInformation::DpiChanged_revoker _dpiChangedRevoker{};
|
||||
void DisplayInformation_DpiChanged(Windows::Graphics::Display::DisplayInformation const &sender, Windows::Foundation::IInspectable const &args);
|
||||
Windows::UI::Xaml::Application::Suspending_revoker _suspendingRevoker{};
|
||||
void Application_Suspending(Windows::Foundation::IInspectable const &sender, Windows::ApplicationModel::SuspendingEventArgs const &args);
|
||||
#endif
|
||||
};
|
||||
}
|
||||
|
||||
namespace winrt::WinUIEditor::factory_implementation
|
||||
{
|
||||
struct EditorBaseControl : EditorBaseControlT<EditorBaseControl, implementation::EditorBaseControl>
|
||||
{
|
||||
};
|
||||
}
|
|
@ -1,15 +0,0 @@
|
|||
#include "Defines.idl"
|
||||
import "EditorWrapper.idl";
|
||||
import "IEditorAccess.idl";
|
||||
|
||||
namespace WinUIEditor
|
||||
{
|
||||
[default_interface]
|
||||
[webhosthidden]
|
||||
runtimeclass EditorBaseControl : DUX.Controls.Control, IEditorAccess
|
||||
{
|
||||
EditorBaseControl();
|
||||
Editor Editor { get; };
|
||||
event Windows.Foundation.EventHandler<Double> DpiChanged;
|
||||
}
|
||||
}
|
|
@ -1,190 +0,0 @@
|
|||
#include "pch.h"
|
||||
#include "EditorBaseControlAutomationPeer.h"
|
||||
#include "EditorBaseControlAutomationPeer.g.cpp"
|
||||
#include "TextRangeProvider.h"
|
||||
#include "Helpers.h"
|
||||
#include "EditorBaseControl.h"
|
||||
|
||||
using namespace ::WinUIEditor;
|
||||
using namespace winrt;
|
||||
using namespace Windows::Foundation;
|
||||
using namespace DUX::Automation;
|
||||
using namespace DUX::Automation::Peers;
|
||||
using namespace DUX::Automation::Provider;
|
||||
using namespace DUX::Automation::Text;
|
||||
|
||||
namespace winrt::WinUIEditor::implementation
|
||||
{
|
||||
EditorBaseControlAutomationPeer::EditorBaseControlAutomationPeer(WinUIEditor::EditorBaseControl const &owner) : base_type(owner)
|
||||
{
|
||||
_updateUIRevoker = owner.Editor().UpdateUI(auto_revoke, { this, &EditorBaseControlAutomationPeer::Editor_UpdateUI });
|
||||
}
|
||||
|
||||
void EditorBaseControlAutomationPeer::Editor_UpdateUI(Editor const &sender, UpdateUIEventArgs const &args)
|
||||
{
|
||||
// https://github.com/microsoft/terminal/blob/main/src/cascadia/TerminalControl/TermControlAutomationPeer.cpp#L133
|
||||
// Todo: Maybe we should raise selection changed on Update::Content also
|
||||
if (static_cast<int>(static_cast<Update>(args.Updated()) & Update::Selection))
|
||||
{
|
||||
this->RaiseAutomationEvent(AutomationEvents::TextPatternOnTextSelectionChanged);
|
||||
}
|
||||
}
|
||||
|
||||
hstring EditorBaseControlAutomationPeer::GetLocalizedControlTypeCore()
|
||||
{
|
||||
// Todo: Localize
|
||||
// Todo: Make sure this is a good name
|
||||
return L"code editor";
|
||||
}
|
||||
|
||||
IInspectable EditorBaseControlAutomationPeer::GetPatternCore(PatternInterface const &patternInterface)
|
||||
{
|
||||
// Todo: Should we forward scroll elements? https://learn.microsoft.com/en-us/windows/apps/design/accessibility/custom-automation-peers#forwarding-patterns-from-sub-elements
|
||||
switch (patternInterface)
|
||||
{
|
||||
case PatternInterface::TextEdit:
|
||||
case PatternInterface::Text:
|
||||
case PatternInterface::Text2:
|
||||
case PatternInterface::Value:
|
||||
return *this;
|
||||
default:
|
||||
return __super::GetPatternCore(patternInterface);
|
||||
}
|
||||
}
|
||||
|
||||
hstring EditorBaseControlAutomationPeer::GetClassNameCore()
|
||||
{
|
||||
return hstring{ name_of<WinUIEditor::EditorBaseControl>() };
|
||||
}
|
||||
|
||||
AutomationControlType EditorBaseControlAutomationPeer::GetAutomationControlTypeCore()
|
||||
{
|
||||
return AutomationControlType::Edit;
|
||||
}
|
||||
|
||||
ITextRangeProvider EditorBaseControlAutomationPeer::DocumentRange()
|
||||
{
|
||||
// Todo: Look at how WinUI 2 handles GetImpl in automation peers
|
||||
const auto editor{ Owner().as<WinUIEditor::EditorBaseControl>().Editor() };
|
||||
return make<TextRangeProvider>(ProviderFromPeer(*this), editor, 0, editor.Length(), GetBoundingRectangle());
|
||||
}
|
||||
|
||||
SupportedTextSelection EditorBaseControlAutomationPeer::SupportedTextSelection()
|
||||
{
|
||||
const auto editor{ Owner().as<WinUIEditor::EditorBaseControl>().Editor() };
|
||||
return editor.MultipleSelection() ? SupportedTextSelection::Multiple : SupportedTextSelection::Single;
|
||||
}
|
||||
|
||||
com_array<ITextRangeProvider> EditorBaseControlAutomationPeer::GetSelection()
|
||||
{
|
||||
const auto editor{ Owner().as<WinUIEditor::EditorBaseControl>().Editor() };
|
||||
const auto n{ static_cast<uint32_t>(editor.Selections()) };
|
||||
com_array<ITextRangeProvider> arr(n, nullptr);
|
||||
const auto topLeft{ GetBoundingRectangle() };
|
||||
for (uint32_t i{ 0 }; i < n; i++)
|
||||
{
|
||||
const auto start{ editor.GetSelectionNStart(i) };
|
||||
const auto end{ editor.GetSelectionNEnd(i) };
|
||||
arr[i] = make<TextRangeProvider>(ProviderFromPeer(*this), editor, start, end, topLeft);
|
||||
}
|
||||
return arr; // Todo: Trying to retrieve the value of a selection n >= 1 crashes Accessibility Insights
|
||||
}
|
||||
|
||||
com_array<ITextRangeProvider> EditorBaseControlAutomationPeer::GetVisibleRanges()
|
||||
{
|
||||
// Visual Studio implements this line by line
|
||||
// Todo: Consider folding and line visible messages
|
||||
// Todo: Not sure if this is the best method for top line
|
||||
const auto editor{ Owner().as<WinUIEditor::EditorBaseControl>().Editor() };
|
||||
|
||||
const auto firstVisibleLine{ editor.FirstVisibleLine() };
|
||||
const auto maxLine{ editor.LineCount() - 1 };
|
||||
// Todo: LinesOnScreen has no concept of wrapping, so you could end up with many more lines than truly visibly
|
||||
const auto lastVisibleLine{ std::min(maxLine, firstVisibleLine + editor.LinesOnScreen()) };
|
||||
|
||||
const auto count{ lastVisibleLine - firstVisibleLine + 1 };
|
||||
|
||||
com_array<ITextRangeProvider> arr(count, nullptr);
|
||||
const auto topLeft{ GetBoundingRectangle() };
|
||||
for (int64_t i{ 0 }; i < count; i++)
|
||||
{
|
||||
const auto line{ firstVisibleLine + i };
|
||||
const auto start{ editor.PositionFromLine(line) };
|
||||
const auto end{ editor.GetLineEndPosition(line) };
|
||||
arr[i] = make<TextRangeProvider>(ProviderFromPeer(*this), editor, start, end, topLeft);
|
||||
}
|
||||
return arr;
|
||||
}
|
||||
|
||||
ITextRangeProvider EditorBaseControlAutomationPeer::RangeFromChild(IRawElementProviderSimple const &childElement)
|
||||
{
|
||||
// Todo: Does this need to be implemented?
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ITextRangeProvider EditorBaseControlAutomationPeer::RangeFromPoint(Point const &screenLocation)
|
||||
{
|
||||
const auto rect{ GetBoundingRectangle() };
|
||||
const Point point{
|
||||
screenLocation.X - rect.X,
|
||||
screenLocation.Y - rect.Y };
|
||||
|
||||
const auto editor{ Owner().as<WinUIEditor::EditorBaseControl>().Editor() };
|
||||
const auto pos{ editor.PositionFromPoint(point.X, point.Y) };
|
||||
const auto line{ editor.LineFromPosition(pos) };
|
||||
const auto start{ editor.PositionFromLine(line) };
|
||||
const auto end{ editor.GetLineEndPosition(line) };
|
||||
|
||||
return make<TextRangeProvider>(ProviderFromPeer(*this), editor, start, end, rect);
|
||||
}
|
||||
|
||||
ITextRangeProvider EditorBaseControlAutomationPeer::GetActiveComposition()
|
||||
{
|
||||
// Todo: implement
|
||||
throw hresult_not_implemented{};
|
||||
}
|
||||
|
||||
ITextRangeProvider EditorBaseControlAutomationPeer::GetConversionTarget()
|
||||
{
|
||||
// Todo: implement
|
||||
throw hresult_not_implemented{};
|
||||
}
|
||||
|
||||
ITextRangeProvider EditorBaseControlAutomationPeer::RangeFromAnnotation(IRawElementProviderSimple const &annotationElement)
|
||||
{
|
||||
// Todo: implement
|
||||
throw hresult_not_implemented{};
|
||||
}
|
||||
|
||||
ITextRangeProvider EditorBaseControlAutomationPeer::GetCaretRange(bool &isActive)
|
||||
{
|
||||
const auto editor{ Owner().as<WinUIEditor::EditorBaseControl>().Editor() };
|
||||
|
||||
isActive = editor.Focus();
|
||||
|
||||
const auto pos{ editor.GetSelectionNCaret(editor.MainSelection()) };
|
||||
|
||||
return make<TextRangeProvider>(ProviderFromPeer(*this), editor, pos, pos, GetBoundingRectangle());
|
||||
}
|
||||
|
||||
bool EditorBaseControlAutomationPeer::IsReadOnly()
|
||||
{
|
||||
const auto editor{ Owner().as<WinUIEditor::EditorBaseControl>().Editor() };
|
||||
|
||||
return editor.ReadOnly();
|
||||
}
|
||||
|
||||
hstring EditorBaseControlAutomationPeer::Value()
|
||||
{
|
||||
const auto editor{ Owner().as<WinUIEditor::EditorBaseControl>().Editor() };
|
||||
|
||||
return editor.GetText(editor.Length()); // Todo: this could potentially be gigabytes of data, so provide a maximum safeguard
|
||||
}
|
||||
|
||||
void EditorBaseControlAutomationPeer::SetValue(hstring const &value)
|
||||
{
|
||||
const auto editor{ Owner().as<WinUIEditor::EditorBaseControl>().Editor() };
|
||||
|
||||
editor.SetText(value);
|
||||
}
|
||||
}
|
|
@ -1,43 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include "EditorBaseControlAutomationPeer.g.h"
|
||||
|
||||
namespace winrt::WinUIEditor::implementation
|
||||
{
|
||||
struct EditorBaseControlAutomationPeer : EditorBaseControlAutomationPeerT<EditorBaseControlAutomationPeer>
|
||||
{
|
||||
EditorBaseControlAutomationPeer(WinUIEditor::EditorBaseControl const &owner);
|
||||
|
||||
hstring GetLocalizedControlTypeCore();
|
||||
Windows::Foundation::IInspectable GetPatternCore(DUX::Automation::Peers::PatternInterface const &patternInterface);
|
||||
hstring GetClassNameCore();
|
||||
DUX::Automation::Peers::AutomationControlType GetAutomationControlTypeCore();
|
||||
|
||||
DUX::Automation::Provider::ITextRangeProvider DocumentRange();
|
||||
DUX::Automation::SupportedTextSelection SupportedTextSelection();
|
||||
com_array<DUX::Automation::Provider::ITextRangeProvider> GetSelection();
|
||||
com_array<DUX::Automation::Provider::ITextRangeProvider> GetVisibleRanges();
|
||||
DUX::Automation::Provider::ITextRangeProvider RangeFromChild(DUX::Automation::Provider::IRawElementProviderSimple const &childElement);
|
||||
DUX::Automation::Provider::ITextRangeProvider RangeFromPoint(Windows::Foundation::Point const &screenLocation);
|
||||
DUX::Automation::Provider::ITextRangeProvider GetActiveComposition();
|
||||
DUX::Automation::Provider::ITextRangeProvider GetConversionTarget();
|
||||
|
||||
DUX::Automation::Provider::ITextRangeProvider RangeFromAnnotation(DUX::Automation::Provider::IRawElementProviderSimple const &annotationElement);
|
||||
DUX::Automation::Provider::ITextRangeProvider GetCaretRange(bool &isActive);
|
||||
|
||||
bool IsReadOnly();
|
||||
hstring Value();
|
||||
void SetValue(hstring const &value);
|
||||
|
||||
private:
|
||||
WinUIEditor::Editor::UpdateUI_revoker _updateUIRevoker{};
|
||||
void Editor_UpdateUI(WinUIEditor::Editor const &sender, WinUIEditor::UpdateUIEventArgs const &args);
|
||||
};
|
||||
}
|
||||
|
||||
namespace winrt::WinUIEditor::factory_implementation
|
||||
{
|
||||
struct EditorBaseControlAutomationPeer : EditorBaseControlAutomationPeerT<EditorBaseControlAutomationPeer, implementation::EditorBaseControlAutomationPeer>
|
||||
{
|
||||
};
|
||||
}
|
|
@ -1,15 +0,0 @@
|
|||
#include "Defines.idl"
|
||||
import "EditorBaseControl.idl";
|
||||
|
||||
namespace WinUIEditor
|
||||
{
|
||||
[default_interface]
|
||||
[webhosthidden]
|
||||
runtimeclass EditorBaseControlAutomationPeer : DUX.Automation.Peers.FrameworkElementAutomationPeer,
|
||||
DUX.Automation.Provider.ITextEditProvider,
|
||||
DUX.Automation.Provider.ITextProvider2,
|
||||
DUX.Automation.Provider.IValueProvider
|
||||
{
|
||||
EditorBaseControlAutomationPeer(EditorBaseControl owner);
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -1,81 +0,0 @@
|
|||
#include "pch.h"
|
||||
#include "Helpers.h"
|
||||
|
||||
namespace WinUIEditor
|
||||
{
|
||||
// Derived from https://github.com/microsoft/Windows-universal-samples/blob/main/Samples/ComplexInk/cpp/Common/DeviceResources.h
|
||||
int ConvertFromDipToPixelUnit(float val, float dpiAdjustmentRatio, bool rounded)
|
||||
{
|
||||
float pixelVal = val * dpiAdjustmentRatio;
|
||||
return static_cast<int>(rounded ? floorf(pixelVal + 0.5f) : pixelVal); // Todo: Test if this is ever necessary
|
||||
}
|
||||
|
||||
typedef LONG(WINAPI *AppPolicyGetWindowingModelPtr)(HANDLE processToken, AppPolicyWindowingModel *policy);
|
||||
static AppPolicyGetWindowingModelPtr s_appPolicyGetWindowingModel;
|
||||
|
||||
bool IsClassicWindow()
|
||||
{
|
||||
// To avoid issues with AppPolicyGetWindowingModel and Store certification, this method cannot be called normally
|
||||
// See https://github.com/microsoft/react-native-windows/pull/5369 (though OneCoreUAP_apiset.lib did not pass either)
|
||||
|
||||
if (!s_appPolicyGetWindowingModel)
|
||||
{
|
||||
s_appPolicyGetWindowingModel =
|
||||
reinterpret_cast<AppPolicyGetWindowingModelPtr>(GetProcAddress(GetModuleHandleW(L"Api-ms-win-appmodel-runtime-l1-1-2.dll"), "AppPolicyGetWindowingModel"));
|
||||
}
|
||||
AppPolicyWindowingModel model;
|
||||
return !(s_appPolicyGetWindowingModel && SUCCEEDED(s_appPolicyGetWindowingModel(GetCurrentThreadEffectiveToken(), &model)))
|
||||
|| model != AppPolicyWindowingModel_Universal;
|
||||
}
|
||||
|
||||
winrt::Windows::System::VirtualKeyModifiers GetKeyModifiersForCurrentThread()
|
||||
{
|
||||
auto modifiers{ winrt::Windows::System::VirtualKeyModifiers::None };
|
||||
|
||||
#ifdef WINUI3
|
||||
// Todo: Do we need to check Locked?
|
||||
// Todo: Left vs right keys?
|
||||
// does not help us
|
||||
if ((winrt::Microsoft::UI::Input::InputKeyboardSource::GetKeyStateForCurrentThread(winrt::Windows::System::VirtualKey::Shift) & winrt::Windows::UI::Core::CoreVirtualKeyStates::Down) == winrt::Windows::UI::Core::CoreVirtualKeyStates::Down)
|
||||
{
|
||||
modifiers |= winrt::Windows::System::VirtualKeyModifiers::Shift;
|
||||
}
|
||||
if ((winrt::Microsoft::UI::Input::InputKeyboardSource::GetKeyStateForCurrentThread(winrt::Windows::System::VirtualKey::Control) & winrt::Windows::UI::Core::CoreVirtualKeyStates::Down) == winrt::Windows::UI::Core::CoreVirtualKeyStates::Down)
|
||||
{
|
||||
modifiers |= winrt::Windows::System::VirtualKeyModifiers::Control;
|
||||
}
|
||||
if ((winrt::Microsoft::UI::Input::InputKeyboardSource::GetKeyStateForCurrentThread(winrt::Windows::System::VirtualKey::Menu) & winrt::Windows::UI::Core::CoreVirtualKeyStates::Down) == winrt::Windows::UI::Core::CoreVirtualKeyStates::Down)
|
||||
{
|
||||
modifiers |= winrt::Windows::System::VirtualKeyModifiers::Menu; // Todo: KeyStatus.IsMenuKeyDown?
|
||||
}
|
||||
if ((winrt::Microsoft::UI::Input::InputKeyboardSource::GetKeyStateForCurrentThread(winrt::Windows::System::VirtualKey::LeftWindows) & winrt::Windows::UI::Core::CoreVirtualKeyStates::Down) == winrt::Windows::UI::Core::CoreVirtualKeyStates::Down
|
||||
|| (winrt::Microsoft::UI::Input::InputKeyboardSource::GetKeyStateForCurrentThread(winrt::Windows::System::VirtualKey::RightWindows) & winrt::Windows::UI::Core::CoreVirtualKeyStates::Down) == winrt::Windows::UI::Core::CoreVirtualKeyStates::Down)
|
||||
{
|
||||
modifiers |= winrt::Windows::System::VirtualKeyModifiers::Windows;
|
||||
}
|
||||
#else
|
||||
const auto window{ winrt::Windows::UI::Core::CoreWindow::GetForCurrentThread() }; // Todo: is it worth it to store this?
|
||||
// Todo: Do we need to check Locked?
|
||||
// Todo: Left vs right keys?
|
||||
if ((window.GetKeyState(winrt::Windows::System::VirtualKey::Shift) & winrt::Windows::UI::Core::CoreVirtualKeyStates::Down) == winrt::Windows::UI::Core::CoreVirtualKeyStates::Down)
|
||||
{
|
||||
modifiers |= winrt::Windows::System::VirtualKeyModifiers::Shift;
|
||||
}
|
||||
if ((window.GetKeyState(winrt::Windows::System::VirtualKey::Control) & winrt::Windows::UI::Core::CoreVirtualKeyStates::Down) == winrt::Windows::UI::Core::CoreVirtualKeyStates::Down)
|
||||
{
|
||||
modifiers |= winrt::Windows::System::VirtualKeyModifiers::Control;
|
||||
}
|
||||
if ((window.GetKeyState(winrt::Windows::System::VirtualKey::Menu) & winrt::Windows::UI::Core::CoreVirtualKeyStates::Down) == winrt::Windows::UI::Core::CoreVirtualKeyStates::Down)
|
||||
{
|
||||
modifiers |= winrt::Windows::System::VirtualKeyModifiers::Menu; // Todo: KeyStatus.IsMenuKeyDown?
|
||||
}
|
||||
if ((window.GetKeyState(winrt::Windows::System::VirtualKey::LeftWindows) & winrt::Windows::UI::Core::CoreVirtualKeyStates::Down) == winrt::Windows::UI::Core::CoreVirtualKeyStates::Down
|
||||
|| (window.GetKeyState(winrt::Windows::System::VirtualKey::RightWindows) & winrt::Windows::UI::Core::CoreVirtualKeyStates::Down) == winrt::Windows::UI::Core::CoreVirtualKeyStates::Down)
|
||||
{
|
||||
modifiers |= winrt::Windows::System::VirtualKeyModifiers::Windows;
|
||||
}
|
||||
#endif
|
||||
|
||||
return modifiers;
|
||||
}
|
||||
}
|
|
@ -1,8 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
namespace WinUIEditor
|
||||
{
|
||||
int ConvertFromDipToPixelUnit(float val, float dpiAdjustmentRatio, bool rounded = true);
|
||||
bool IsClassicWindow();
|
||||
winrt::Windows::System::VirtualKeyModifiers GetKeyModifiersForCurrentThread();
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
import "EditorWrapper.idl";
|
||||
|
||||
namespace WinUIEditor
|
||||
{
|
||||
interface IEditorAccess
|
||||
{
|
||||
Int64 SendMessage(ScintillaMessage message, UInt64 wParam, Int64 lParam);
|
||||
event Windows.Foundation.EventHandler<Int64> NotifyMessageReceived;
|
||||
}
|
||||
}
|
|
@ -1,225 +0,0 @@
|
|||
// Ported from
|
||||
// https://github.com/microsoft/vscode/blob/main/extensions/theme-defaults/themes/light_plus.json
|
||||
// https://github.com/microsoft/vscode/blob/main/extensions/theme-defaults/themes/light_vs.json
|
||||
// under the following license
|
||||
|
||||
/*
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2015 - present Microsoft Corporation
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace WinUIEditor
|
||||
{
|
||||
constexpr int LightPlusEditorForeground{ IntRGBA(0x00, 0x00, 0x00) };
|
||||
|
||||
constexpr int LightPlus(Scope scope)
|
||||
{
|
||||
switch (scope)
|
||||
{
|
||||
case Scope::MetaEmbedded: return IntRGBA(0x00, 0x00, 0x00);
|
||||
case Scope::SourceGroovyEmbedded: return IntRGBA(0x00, 0x00, 0x00);
|
||||
case Scope::String__MetaImageInlineMarkdown: return IntRGBA(0x00, 0x00, 0x00);
|
||||
case Scope::VariableLegacyBuiltinPython: return IntRGBA(0x00, 0x00, 0x00);
|
||||
case Scope::MetaDiffHeader: return IntRGBA(0x00, 0x00, 0x80);
|
||||
case Scope::Comment: return IntRGBA(0x00, 0x80, 0x00);
|
||||
case Scope::ConstantLanguage: return IntRGBA(0x00, 0x00, 0xFF);
|
||||
case Scope::ConstantNumeric: return IntRGBA(0x09, 0x86, 0x58);
|
||||
case Scope::VariableOtherEnummember: return IntRGBA(0x00, 0x70, 0xC1);
|
||||
case Scope::KeywordOperatorPlusExponent: return IntRGBA(0x09, 0x86, 0x58);
|
||||
case Scope::KeywordOperatorMinusExponent: return IntRGBA(0x09, 0x86, 0x58);
|
||||
case Scope::ConstantRegexp: return IntRGBA(0x81, 0x1F, 0x3F);
|
||||
case Scope::EntityNameTag: return IntRGBA(0x80, 0x00, 0x00);
|
||||
case Scope::EntityNameSelector: return IntRGBA(0x80, 0x00, 0x00);
|
||||
case Scope::EntityOtherAttribute_Name: return IntRGBA(0xE5, 0x00, 0x00);
|
||||
case Scope::EntityOtherAttribute_NameClassCss: return IntRGBA(0x80, 0x00, 0x00);
|
||||
case Scope::EntityOtherAttribute_NameClassMixinCss: return IntRGBA(0x80, 0x00, 0x00);
|
||||
case Scope::EntityOtherAttribute_NameIdCss: return IntRGBA(0x80, 0x00, 0x00);
|
||||
case Scope::EntityOtherAttribute_NameParent_SelectorCss: return IntRGBA(0x80, 0x00, 0x00);
|
||||
case Scope::EntityOtherAttribute_NamePseudo_ClassCss: return IntRGBA(0x80, 0x00, 0x00);
|
||||
case Scope::EntityOtherAttribute_NamePseudo_ElementCss: return IntRGBA(0x80, 0x00, 0x00);
|
||||
case Scope::SourceCssLess__EntityOtherAttribute_NameId: return IntRGBA(0x80, 0x00, 0x00);
|
||||
case Scope::EntityOtherAttribute_NameScss: return IntRGBA(0x80, 0x00, 0x00);
|
||||
case Scope::Invalid: return IntRGBA(0xCD, 0x31, 0x31);
|
||||
case Scope::MarkupBold: return IntRGBA(0x00, 0x00, 0x80);
|
||||
case Scope::MarkupHeading: return IntRGBA(0x80, 0x00, 0x00);
|
||||
case Scope::MarkupInserted: return IntRGBA(0x09, 0x86, 0x58);
|
||||
case Scope::MarkupDeleted: return IntRGBA(0xA3, 0x15, 0x15);
|
||||
case Scope::MarkupChanged: return IntRGBA(0x04, 0x51, 0xA5);
|
||||
case Scope::PunctuationDefinitionQuoteBeginMarkdown: return IntRGBA(0x04, 0x51, 0xA5);
|
||||
case Scope::PunctuationDefinitionListBeginMarkdown: return IntRGBA(0x04, 0x51, 0xA5);
|
||||
case Scope::MarkupInlineRaw: return IntRGBA(0x80, 0x00, 0x00);
|
||||
case Scope::PunctuationDefinitionTag: return IntRGBA(0x80, 0x00, 0x00);
|
||||
case Scope::MetaPreprocessor: return IntRGBA(0x00, 0x00, 0xFF);
|
||||
case Scope::EntityNameFunctionPreprocessor: return IntRGBA(0x00, 0x00, 0xFF);
|
||||
case Scope::MetaPreprocessorString: return IntRGBA(0xA3, 0x15, 0x15);
|
||||
case Scope::MetaPreprocessorNumeric: return IntRGBA(0x09, 0x86, 0x58);
|
||||
case Scope::MetaStructureDictionaryKeyPython: return IntRGBA(0x04, 0x51, 0xA5);
|
||||
case Scope::Storage: return IntRGBA(0x00, 0x00, 0xFF);
|
||||
case Scope::StorageType: return IntRGBA(0x00, 0x00, 0xFF);
|
||||
case Scope::StorageModifier: return IntRGBA(0x00, 0x00, 0xFF);
|
||||
case Scope::KeywordOperatorNoexcept: return IntRGBA(0x00, 0x00, 0xFF);
|
||||
case Scope::String: return IntRGBA(0xA3, 0x15, 0x15);
|
||||
case Scope::MetaEmbeddedAssembly: return IntRGBA(0xA3, 0x15, 0x15);
|
||||
case Scope::StringCommentBufferedBlockPug: return IntRGBA(0x00, 0x00, 0xFF);
|
||||
case Scope::StringQuotedPug: return IntRGBA(0x00, 0x00, 0xFF);
|
||||
case Scope::StringInterpolatedPug: return IntRGBA(0x00, 0x00, 0xFF);
|
||||
case Scope::StringUnquotedPlainInYaml: return IntRGBA(0x00, 0x00, 0xFF);
|
||||
case Scope::StringUnquotedPlainOutYaml: return IntRGBA(0x00, 0x00, 0xFF);
|
||||
case Scope::StringUnquotedBlockYaml: return IntRGBA(0x00, 0x00, 0xFF);
|
||||
case Scope::StringQuotedSingleYaml: return IntRGBA(0x00, 0x00, 0xFF);
|
||||
case Scope::StringQuotedDoubleXml: return IntRGBA(0x00, 0x00, 0xFF);
|
||||
case Scope::StringQuotedSingleXml: return IntRGBA(0x00, 0x00, 0xFF);
|
||||
case Scope::StringUnquotedCdataXml: return IntRGBA(0x00, 0x00, 0xFF);
|
||||
case Scope::StringQuotedDoubleHtml: return IntRGBA(0x00, 0x00, 0xFF);
|
||||
case Scope::StringQuotedSingleHtml: return IntRGBA(0x00, 0x00, 0xFF);
|
||||
case Scope::StringUnquotedHtml: return IntRGBA(0x00, 0x00, 0xFF);
|
||||
case Scope::StringQuotedSingleHandlebars: return IntRGBA(0x00, 0x00, 0xFF);
|
||||
case Scope::StringQuotedDoubleHandlebars: return IntRGBA(0x00, 0x00, 0xFF);
|
||||
case Scope::StringRegexp: return IntRGBA(0x81, 0x1F, 0x3F);
|
||||
case Scope::PunctuationDefinitionTemplate_ExpressionBegin: return IntRGBA(0x00, 0x00, 0xFF);
|
||||
case Scope::PunctuationDefinitionTemplate_ExpressionEnd: return IntRGBA(0x00, 0x00, 0xFF);
|
||||
case Scope::PunctuationSectionEmbedded: return IntRGBA(0x00, 0x00, 0xFF);
|
||||
case Scope::MetaTemplateExpression: return IntRGBA(0x00, 0x00, 0x00);
|
||||
case Scope::SupportConstantProperty_Value: return IntRGBA(0x04, 0x51, 0xA5);
|
||||
case Scope::SupportConstantFont_Name: return IntRGBA(0x04, 0x51, 0xA5);
|
||||
case Scope::SupportConstantMedia_Type: return IntRGBA(0x04, 0x51, 0xA5);
|
||||
case Scope::SupportConstantMedia: return IntRGBA(0x04, 0x51, 0xA5);
|
||||
case Scope::ConstantOtherColorRgb_Value: return IntRGBA(0x04, 0x51, 0xA5);
|
||||
case Scope::ConstantOtherRgb_Value: return IntRGBA(0x04, 0x51, 0xA5);
|
||||
case Scope::SupportConstantColor: return IntRGBA(0x04, 0x51, 0xA5);
|
||||
case Scope::SupportTypeVendoredProperty_Name: return IntRGBA(0xE5, 0x00, 0x00);
|
||||
case Scope::SupportTypeProperty_Name: return IntRGBA(0xE5, 0x00, 0x00);
|
||||
case Scope::VariableCss: return IntRGBA(0xE5, 0x00, 0x00);
|
||||
case Scope::VariableScss: return IntRGBA(0xE5, 0x00, 0x00);
|
||||
case Scope::VariableOtherLess: return IntRGBA(0xE5, 0x00, 0x00);
|
||||
case Scope::SourceCoffeeEmbedded: return IntRGBA(0xE5, 0x00, 0x00);
|
||||
case Scope::SupportTypeProperty_NameJson: return IntRGBA(0x04, 0x51, 0xA5);
|
||||
case Scope::Keyword: return IntRGBA(0x00, 0x00, 0xFF);
|
||||
case Scope::KeywordControl: return IntRGBA(0xAF, 0x00, 0xDB);
|
||||
case Scope::KeywordOperator: return IntRGBA(0x00, 0x00, 0x00);
|
||||
case Scope::KeywordOperatorNew: return IntRGBA(0x00, 0x00, 0xFF);
|
||||
case Scope::KeywordOperatorExpression: return IntRGBA(0x00, 0x00, 0xFF);
|
||||
case Scope::KeywordOperatorCast: return IntRGBA(0x00, 0x00, 0xFF);
|
||||
case Scope::KeywordOperatorSizeof: return IntRGBA(0x00, 0x00, 0xFF);
|
||||
case Scope::KeywordOperatorAlignof: return IntRGBA(0x00, 0x00, 0xFF);
|
||||
case Scope::KeywordOperatorTypeid: return IntRGBA(0x00, 0x00, 0xFF);
|
||||
case Scope::KeywordOperatorAlignas: return IntRGBA(0x00, 0x00, 0xFF);
|
||||
case Scope::KeywordOperatorInstanceof: return IntRGBA(0x00, 0x00, 0xFF);
|
||||
case Scope::KeywordOperatorLogicalPython: return IntRGBA(0x00, 0x00, 0xFF);
|
||||
case Scope::KeywordOperatorWordlike: return IntRGBA(0x00, 0x00, 0xFF);
|
||||
case Scope::KeywordOtherUnit: return IntRGBA(0x09, 0x86, 0x58);
|
||||
case Scope::PunctuationSectionEmbeddedBeginPhp: return IntRGBA(0x80, 0x00, 0x00);
|
||||
case Scope::PunctuationSectionEmbeddedEndPhp: return IntRGBA(0x80, 0x00, 0x00);
|
||||
case Scope::SupportFunctionGit_Rebase: return IntRGBA(0x04, 0x51, 0xA5);
|
||||
case Scope::ConstantShaGit_Rebase: return IntRGBA(0x09, 0x86, 0x58);
|
||||
case Scope::StorageModifierImportJava: return IntRGBA(0x00, 0x00, 0x00);
|
||||
case Scope::VariableLanguageWildcardJava: return IntRGBA(0x00, 0x00, 0x00);
|
||||
case Scope::StorageModifierPackageJava: return IntRGBA(0x00, 0x00, 0x00);
|
||||
case Scope::VariableLanguage: return IntRGBA(0x00, 0x00, 0xFF);
|
||||
case Scope::EntityNameFunction: return IntRGBA(0x79, 0x5E, 0x26);
|
||||
case Scope::SupportFunction: return IntRGBA(0x79, 0x5E, 0x26);
|
||||
case Scope::SupportConstantHandlebars: return IntRGBA(0x79, 0x5E, 0x26);
|
||||
case Scope::SourcePowershell__VariableOtherMember: return IntRGBA(0x79, 0x5E, 0x26);
|
||||
case Scope::EntityNameOperatorCustom_Literal: return IntRGBA(0x79, 0x5E, 0x26);
|
||||
case Scope::SupportClass: return IntRGBA(0x26, 0x7F, 0x99);
|
||||
case Scope::SupportType: return IntRGBA(0x26, 0x7F, 0x99);
|
||||
case Scope::EntityNameType: return IntRGBA(0x26, 0x7F, 0x99);
|
||||
case Scope::EntityNameNamespace: return IntRGBA(0x26, 0x7F, 0x99);
|
||||
case Scope::EntityOtherAttribute: return IntRGBA(0x26, 0x7F, 0x99);
|
||||
case Scope::EntityNameScope_Resolution: return IntRGBA(0x26, 0x7F, 0x99);
|
||||
case Scope::EntityNameClass: return IntRGBA(0x26, 0x7F, 0x99);
|
||||
case Scope::StorageTypeNumericGo: return IntRGBA(0x26, 0x7F, 0x99);
|
||||
case Scope::StorageTypeByteGo: return IntRGBA(0x26, 0x7F, 0x99);
|
||||
case Scope::StorageTypeBooleanGo: return IntRGBA(0x26, 0x7F, 0x99);
|
||||
case Scope::StorageTypeStringGo: return IntRGBA(0x26, 0x7F, 0x99);
|
||||
case Scope::StorageTypeUintptrGo: return IntRGBA(0x26, 0x7F, 0x99);
|
||||
case Scope::StorageTypeErrorGo: return IntRGBA(0x26, 0x7F, 0x99);
|
||||
case Scope::StorageTypeRuneGo: return IntRGBA(0x26, 0x7F, 0x99);
|
||||
case Scope::StorageTypeCs: return IntRGBA(0x26, 0x7F, 0x99);
|
||||
case Scope::StorageTypeGenericCs: return IntRGBA(0x26, 0x7F, 0x99);
|
||||
case Scope::StorageTypeModifierCs: return IntRGBA(0x26, 0x7F, 0x99);
|
||||
case Scope::StorageTypeVariableCs: return IntRGBA(0x26, 0x7F, 0x99);
|
||||
case Scope::StorageTypeAnnotationJava: return IntRGBA(0x26, 0x7F, 0x99);
|
||||
case Scope::StorageTypeGenericJava: return IntRGBA(0x26, 0x7F, 0x99);
|
||||
case Scope::StorageTypeJava: return IntRGBA(0x26, 0x7F, 0x99);
|
||||
case Scope::StorageTypeObjectArrayJava: return IntRGBA(0x26, 0x7F, 0x99);
|
||||
case Scope::StorageTypePrimitiveArrayJava: return IntRGBA(0x26, 0x7F, 0x99);
|
||||
case Scope::StorageTypePrimitiveJava: return IntRGBA(0x26, 0x7F, 0x99);
|
||||
case Scope::StorageTypeTokenJava: return IntRGBA(0x26, 0x7F, 0x99);
|
||||
case Scope::StorageTypeGroovy: return IntRGBA(0x26, 0x7F, 0x99);
|
||||
case Scope::StorageTypeAnnotationGroovy: return IntRGBA(0x26, 0x7F, 0x99);
|
||||
case Scope::StorageTypeParametersGroovy: return IntRGBA(0x26, 0x7F, 0x99);
|
||||
case Scope::StorageTypeGenericGroovy: return IntRGBA(0x26, 0x7F, 0x99);
|
||||
case Scope::StorageTypeObjectArrayGroovy: return IntRGBA(0x26, 0x7F, 0x99);
|
||||
case Scope::StorageTypePrimitiveArrayGroovy: return IntRGBA(0x26, 0x7F, 0x99);
|
||||
case Scope::StorageTypePrimitiveGroovy: return IntRGBA(0x26, 0x7F, 0x99);
|
||||
case Scope::MetaTypeCastExpr: return IntRGBA(0x26, 0x7F, 0x99);
|
||||
case Scope::MetaTypeNewExpr: return IntRGBA(0x26, 0x7F, 0x99);
|
||||
case Scope::SupportConstantMath: return IntRGBA(0x26, 0x7F, 0x99);
|
||||
case Scope::SupportConstantDom: return IntRGBA(0x26, 0x7F, 0x99);
|
||||
case Scope::SupportConstantJson: return IntRGBA(0x26, 0x7F, 0x99);
|
||||
case Scope::EntityOtherInherited_Class: return IntRGBA(0x26, 0x7F, 0x99);
|
||||
case Scope::SourceCpp__KeywordOperatorNew: return IntRGBA(0xAF, 0x00, 0xDB);
|
||||
case Scope::SourceCpp__KeywordOperatorDelete: return IntRGBA(0xAF, 0x00, 0xDB);
|
||||
case Scope::KeywordOtherUsing: return IntRGBA(0xAF, 0x00, 0xDB);
|
||||
case Scope::KeywordOtherDirectiveUsing: return IntRGBA(0xAF, 0x00, 0xDB);
|
||||
case Scope::KeywordOtherOperator: return IntRGBA(0xAF, 0x00, 0xDB);
|
||||
case Scope::EntityNameOperator: return IntRGBA(0xAF, 0x00, 0xDB);
|
||||
case Scope::Variable: return IntRGBA(0x00, 0x10, 0x80);
|
||||
case Scope::MetaDefinitionVariableName: return IntRGBA(0x00, 0x10, 0x80);
|
||||
case Scope::SupportVariable: return IntRGBA(0x00, 0x10, 0x80);
|
||||
case Scope::EntityNameVariable: return IntRGBA(0x00, 0x10, 0x80);
|
||||
case Scope::ConstantOtherPlaceholder: return IntRGBA(0x00, 0x10, 0x80);
|
||||
case Scope::VariableOtherConstant: return IntRGBA(0x00, 0x70, 0xC1);
|
||||
case Scope::MetaObject_LiteralKey: return IntRGBA(0x00, 0x10, 0x80);
|
||||
case Scope::PunctuationDefinitionGroupRegexp: return IntRGBA(0xD1, 0x69, 0x69);
|
||||
case Scope::PunctuationDefinitionGroupAssertionRegexp: return IntRGBA(0xD1, 0x69, 0x69);
|
||||
case Scope::PunctuationDefinitionCharacter_ClassRegexp: return IntRGBA(0xD1, 0x69, 0x69);
|
||||
case Scope::PunctuationCharacterSetBeginRegexp: return IntRGBA(0xD1, 0x69, 0x69);
|
||||
case Scope::PunctuationCharacterSetEndRegexp: return IntRGBA(0xD1, 0x69, 0x69);
|
||||
case Scope::KeywordOperatorNegationRegexp: return IntRGBA(0xD1, 0x69, 0x69);
|
||||
case Scope::SupportOtherParenthesisRegexp: return IntRGBA(0xD1, 0x69, 0x69);
|
||||
case Scope::ConstantCharacterCharacter_ClassRegexp: return IntRGBA(0x81, 0x1F, 0x3F);
|
||||
case Scope::ConstantOtherCharacter_ClassSetRegexp: return IntRGBA(0x81, 0x1F, 0x3F);
|
||||
case Scope::ConstantOtherCharacter_ClassRegexp: return IntRGBA(0x81, 0x1F, 0x3F);
|
||||
case Scope::ConstantCharacterSetRegexp: return IntRGBA(0x81, 0x1F, 0x3F);
|
||||
case Scope::KeywordOperatorQuantifierRegexp: return IntRGBA(0x00, 0x00, 0x00);
|
||||
case Scope::KeywordOperatorOrRegexp: return IntRGBA(0xEE, 0x00, 0x00);
|
||||
case Scope::KeywordControlAnchorRegexp: return IntRGBA(0xEE, 0x00, 0x00);
|
||||
case Scope::ConstantCharacter: return IntRGBA(0x00, 0x00, 0xFF);
|
||||
case Scope::ConstantOtherOption: return IntRGBA(0x00, 0x00, 0xFF);
|
||||
case Scope::ConstantCharacterEscape: return IntRGBA(0xEE, 0x00, 0x00);
|
||||
case Scope::EntityNameLabel: return IntRGBA(0x00, 0x00, 0x00);
|
||||
}
|
||||
}
|
||||
|
||||
constexpr int LightPlus2(Scope scope)
|
||||
{
|
||||
switch (scope)
|
||||
{
|
||||
case Scope::MetaPreprocessor: return IntRGBA(0x80, 0x80, 0x80);
|
||||
default: return LightPlus(scope);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,215 +0,0 @@
|
|||
// Ported from
|
||||
// https://github.com/microsoft/vscode/blob/main/extensions/theme-defaults/themes/light_plus.json
|
||||
// https://github.com/microsoft/vscode/blob/main/extensions/theme-defaults/themes/light_vs.json
|
||||
// https://github.com/microsoft/vscode/blob/main/extensions/theme-defaults/themes/dark_plus.json
|
||||
// https://github.com/microsoft/vscode/blob/main/extensions/theme-defaults/themes/dark_vs.json
|
||||
// under the following license
|
||||
|
||||
/*
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2015 - present Microsoft Corporation
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
enum class Scope
|
||||
{
|
||||
MetaEmbedded, // meta.embedded
|
||||
SourceGroovyEmbedded, // source.groovy.embedded
|
||||
String__MetaImageInlineMarkdown, // string meta.image.inline.markdown
|
||||
VariableLegacyBuiltinPython, // variable.legacy.builtin.python
|
||||
MetaDiffHeader, // meta.diff.header
|
||||
Comment, // comment
|
||||
ConstantLanguage, // constant.language
|
||||
ConstantNumeric, // constant.numeric
|
||||
VariableOtherEnummember, // variable.other.enummember
|
||||
KeywordOperatorPlusExponent, // keyword.operator.plus.exponent
|
||||
KeywordOperatorMinusExponent, // keyword.operator.minus.exponent
|
||||
ConstantRegexp, // constant.regexp
|
||||
EntityNameTag, // entity.name.tag
|
||||
EntityNameSelector, // entity.name.selector
|
||||
EntityOtherAttribute_Name, // entity.other.attribute-name
|
||||
EntityOtherAttribute_NameClassCss, // entity.other.attribute-name.class.css
|
||||
EntityOtherAttribute_NameClassMixinCss, // entity.other.attribute-name.class.mixin.css
|
||||
EntityOtherAttribute_NameIdCss, // entity.other.attribute-name.id.css
|
||||
EntityOtherAttribute_NameParent_SelectorCss, // entity.other.attribute-name.parent-selector.css
|
||||
EntityOtherAttribute_NamePseudo_ClassCss, // entity.other.attribute-name.pseudo-class.css
|
||||
EntityOtherAttribute_NamePseudo_ElementCss, // entity.other.attribute-name.pseudo-element.css
|
||||
SourceCssLess__EntityOtherAttribute_NameId, // source.css.less entity.other.attribute-name.id
|
||||
EntityOtherAttribute_NameScss, // entity.other.attribute-name.scss
|
||||
Invalid, // invalid
|
||||
MarkupBold, // markup.bold
|
||||
MarkupHeading, // markup.heading
|
||||
MarkupInserted, // markup.inserted
|
||||
MarkupDeleted, // markup.deleted
|
||||
MarkupChanged, // markup.changed
|
||||
PunctuationDefinitionQuoteBeginMarkdown, // punctuation.definition.quote.begin.markdown
|
||||
PunctuationDefinitionListBeginMarkdown, // punctuation.definition.list.begin.markdown
|
||||
MarkupInlineRaw, // markup.inline.raw
|
||||
PunctuationDefinitionTag, // punctuation.definition.tag
|
||||
MetaPreprocessor, // meta.preprocessor
|
||||
EntityNameFunctionPreprocessor, // entity.name.function.preprocessor
|
||||
MetaPreprocessorString, // meta.preprocessor.string
|
||||
MetaPreprocessorNumeric, // meta.preprocessor.numeric
|
||||
MetaStructureDictionaryKeyPython, // meta.structure.dictionary.key.python
|
||||
Storage, // storage
|
||||
StorageType, // storage.type
|
||||
StorageModifier, // storage.modifier
|
||||
KeywordOperatorNoexcept, // keyword.operator.noexcept
|
||||
String, // string
|
||||
MetaEmbeddedAssembly, // meta.embedded.assembly
|
||||
StringCommentBufferedBlockPug, // string.comment.buffered.block.pug
|
||||
StringQuotedPug, // string.quoted.pug
|
||||
StringInterpolatedPug, // string.interpolated.pug
|
||||
StringUnquotedPlainInYaml, // string.unquoted.plain.in.yaml
|
||||
StringUnquotedPlainOutYaml, // string.unquoted.plain.out.yaml
|
||||
StringUnquotedBlockYaml, // string.unquoted.block.yaml
|
||||
StringQuotedSingleYaml, // string.quoted.single.yaml
|
||||
StringQuotedDoubleXml, // string.quoted.double.xml
|
||||
StringQuotedSingleXml, // string.quoted.single.xml
|
||||
StringUnquotedCdataXml, // string.unquoted.cdata.xml
|
||||
StringQuotedDoubleHtml, // string.quoted.double.html
|
||||
StringQuotedSingleHtml, // string.quoted.single.html
|
||||
StringUnquotedHtml, // string.unquoted.html
|
||||
StringQuotedSingleHandlebars, // string.quoted.single.handlebars
|
||||
StringQuotedDoubleHandlebars, // string.quoted.double.handlebars
|
||||
StringRegexp, // string.regexp
|
||||
PunctuationDefinitionTemplate_ExpressionBegin, // punctuation.definition.template-expression.begin
|
||||
PunctuationDefinitionTemplate_ExpressionEnd, // punctuation.definition.template-expression.end
|
||||
PunctuationSectionEmbedded, // punctuation.section.embedded
|
||||
MetaTemplateExpression, // meta.template.expression
|
||||
SupportConstantProperty_Value, // support.constant.property-value
|
||||
SupportConstantFont_Name, // support.constant.font-name
|
||||
SupportConstantMedia_Type, // support.constant.media-type
|
||||
SupportConstantMedia, // support.constant.media
|
||||
ConstantOtherColorRgb_Value, // constant.other.color.rgb-value
|
||||
ConstantOtherRgb_Value, // constant.other.rgb-value
|
||||
SupportConstantColor, // support.constant.color
|
||||
SupportTypeVendoredProperty_Name, // support.type.vendored.property-name
|
||||
SupportTypeProperty_Name, // support.type.property-name
|
||||
VariableCss, // variable.css
|
||||
VariableScss, // variable.scss
|
||||
VariableOtherLess, // variable.other.less
|
||||
SourceCoffeeEmbedded, // source.coffee.embedded
|
||||
SupportTypeProperty_NameJson, // support.type.property-name.json
|
||||
Keyword, // keyword
|
||||
KeywordControl, // keyword.control
|
||||
KeywordOperator, // keyword.operator
|
||||
KeywordOperatorNew, // keyword.operator.new
|
||||
KeywordOperatorExpression, // keyword.operator.expression
|
||||
KeywordOperatorCast, // keyword.operator.cast
|
||||
KeywordOperatorSizeof, // keyword.operator.sizeof
|
||||
KeywordOperatorAlignof, // keyword.operator.alignof
|
||||
KeywordOperatorTypeid, // keyword.operator.typeid
|
||||
KeywordOperatorAlignas, // keyword.operator.alignas
|
||||
KeywordOperatorInstanceof, // keyword.operator.instanceof
|
||||
KeywordOperatorLogicalPython, // keyword.operator.logical.python
|
||||
KeywordOperatorWordlike, // keyword.operator.wordlike
|
||||
KeywordOtherUnit, // keyword.other.unit
|
||||
PunctuationSectionEmbeddedBeginPhp, // punctuation.section.embedded.begin.php
|
||||
PunctuationSectionEmbeddedEndPhp, // punctuation.section.embedded.end.php
|
||||
SupportFunctionGit_Rebase, // support.function.git-rebase
|
||||
ConstantShaGit_Rebase, // constant.sha.git-rebase
|
||||
StorageModifierImportJava, // storage.modifier.import.java
|
||||
VariableLanguageWildcardJava, // variable.language.wildcard.java
|
||||
StorageModifierPackageJava, // storage.modifier.package.java
|
||||
VariableLanguage, // variable.language
|
||||
EntityNameFunction, // entity.name.function
|
||||
SupportFunction, // support.function
|
||||
SupportConstantHandlebars, // support.constant.handlebars
|
||||
SourcePowershell__VariableOtherMember, // source.powershell variable.other.member
|
||||
EntityNameOperatorCustom_Literal, // entity.name.operator.custom-literal
|
||||
SupportClass, // support.class
|
||||
SupportType, // support.type
|
||||
EntityNameType, // entity.name.type
|
||||
EntityNameNamespace, // entity.name.namespace
|
||||
EntityOtherAttribute, // entity.other.attribute
|
||||
EntityNameScope_Resolution, // entity.name.scope-resolution
|
||||
EntityNameClass, // entity.name.class
|
||||
StorageTypeNumericGo, // storage.type.numeric.go
|
||||
StorageTypeByteGo, // storage.type.byte.go
|
||||
StorageTypeBooleanGo, // storage.type.boolean.go
|
||||
StorageTypeStringGo, // storage.type.string.go
|
||||
StorageTypeUintptrGo, // storage.type.uintptr.go
|
||||
StorageTypeErrorGo, // storage.type.error.go
|
||||
StorageTypeRuneGo, // storage.type.rune.go
|
||||
StorageTypeCs, // storage.type.cs
|
||||
StorageTypeGenericCs, // storage.type.generic.cs
|
||||
StorageTypeModifierCs, // storage.type.modifier.cs
|
||||
StorageTypeVariableCs, // storage.type.variable.cs
|
||||
StorageTypeAnnotationJava, // storage.type.annotation.java
|
||||
StorageTypeGenericJava, // storage.type.generic.java
|
||||
StorageTypeJava, // storage.type.java
|
||||
StorageTypeObjectArrayJava, // storage.type.object.array.java
|
||||
StorageTypePrimitiveArrayJava, // storage.type.primitive.array.java
|
||||
StorageTypePrimitiveJava, // storage.type.primitive.java
|
||||
StorageTypeTokenJava, // storage.type.token.java
|
||||
StorageTypeGroovy, // storage.type.groovy
|
||||
StorageTypeAnnotationGroovy, // storage.type.annotation.groovy
|
||||
StorageTypeParametersGroovy, // storage.type.parameters.groovy
|
||||
StorageTypeGenericGroovy, // storage.type.generic.groovy
|
||||
StorageTypeObjectArrayGroovy, // storage.type.object.array.groovy
|
||||
StorageTypePrimitiveArrayGroovy, // storage.type.primitive.array.groovy
|
||||
StorageTypePrimitiveGroovy, // storage.type.primitive.groovy
|
||||
MetaTypeCastExpr, // meta.type.cast.expr
|
||||
MetaTypeNewExpr, // meta.type.new.expr
|
||||
SupportConstantMath, // support.constant.math
|
||||
SupportConstantDom, // support.constant.dom
|
||||
SupportConstantJson, // support.constant.json
|
||||
EntityOtherInherited_Class, // entity.other.inherited-class
|
||||
SourceCpp__KeywordOperatorNew, // source.cpp keyword.operator.new
|
||||
SourceCpp__KeywordOperatorDelete, // source.cpp keyword.operator.delete
|
||||
KeywordOtherUsing, // keyword.other.using
|
||||
KeywordOtherDirectiveUsing, // keyword.other.directive.using
|
||||
KeywordOtherOperator, // keyword.other.operator
|
||||
EntityNameOperator, // entity.name.operator
|
||||
Variable, // variable
|
||||
MetaDefinitionVariableName, // meta.definition.variable.name
|
||||
SupportVariable, // support.variable
|
||||
EntityNameVariable, // entity.name.variable
|
||||
ConstantOtherPlaceholder, // constant.other.placeholder
|
||||
VariableOtherConstant, // variable.other.constant
|
||||
MetaObject_LiteralKey, // meta.object-literal.key
|
||||
PunctuationDefinitionGroupRegexp, // punctuation.definition.group.regexp
|
||||
PunctuationDefinitionGroupAssertionRegexp, // punctuation.definition.group.assertion.regexp
|
||||
PunctuationDefinitionCharacter_ClassRegexp, // punctuation.definition.character-class.regexp
|
||||
PunctuationCharacterSetBeginRegexp, // punctuation.character.set.begin.regexp
|
||||
PunctuationCharacterSetEndRegexp, // punctuation.character.set.end.regexp
|
||||
KeywordOperatorNegationRegexp, // keyword.operator.negation.regexp
|
||||
SupportOtherParenthesisRegexp, // support.other.parenthesis.regexp
|
||||
ConstantCharacterCharacter_ClassRegexp, // constant.character.character-class.regexp
|
||||
ConstantOtherCharacter_ClassSetRegexp, // constant.other.character-class.set.regexp
|
||||
ConstantOtherCharacter_ClassRegexp, // constant.other.character-class.regexp
|
||||
ConstantCharacterSetRegexp, // constant.character.set.regexp
|
||||
KeywordOperatorQuantifierRegexp, // keyword.operator.quantifier.regexp
|
||||
KeywordOperatorOrRegexp, // keyword.operator.or.regexp
|
||||
KeywordControlAnchorRegexp, // keyword.control.anchor.regexp
|
||||
ConstantCharacter, // constant.character
|
||||
ConstantOtherOption, // constant.other.option
|
||||
ConstantCharacterEscape, // constant.character.escape
|
||||
EntityNameLabel, // entity.name.label
|
||||
Header, // header
|
||||
EntityNameTagCss, // entity.name.tag.css
|
||||
StringTag, // string.tag
|
||||
StringValue, // string.value
|
||||
KeywordOperatorDelete, // keyword.operator.delete
|
||||
};
|
|
@ -1,334 +0,0 @@
|
|||
#include "pch.h"
|
||||
#include "TextRangeProvider.h"
|
||||
|
||||
using namespace winrt;
|
||||
using namespace Windows::Foundation;
|
||||
using namespace DUX;
|
||||
using namespace DUX::Automation;
|
||||
using namespace DUX::Automation::Peers;
|
||||
using namespace DUX::Automation::Provider;
|
||||
using namespace DUX::Automation::Text;
|
||||
|
||||
constexpr hresult XAML_E_NOT_SUPPORTED{ static_cast<int32_t>(0x80131515) };
|
||||
|
||||
namespace winrt::WinUIEditor::implementation
|
||||
{
|
||||
TextRangeProvider::TextRangeProvider(IRawElementProviderSimple const &peer, Editor const &editor, int64_t rangeStart, int64_t rangeEnd, Rect const &bounds)
|
||||
: _peer{ peer }, _editor{ editor }, _rangeStart{ rangeStart }, _rangeEnd{ rangeEnd }, _bounds{ bounds }
|
||||
{
|
||||
}
|
||||
|
||||
ITextRangeProvider TextRangeProvider::Clone()
|
||||
{
|
||||
return make<TextRangeProvider>(_peer, _editor.get(), _rangeStart, _rangeEnd, _bounds);
|
||||
}
|
||||
|
||||
bool TextRangeProvider::Compare(ITextRangeProvider const &textRangeProvider)
|
||||
{
|
||||
const auto target{ textRangeProvider.as<TextRangeProvider>() };
|
||||
return _rangeStart == target->_rangeStart && _rangeEnd == target->_rangeEnd;
|
||||
}
|
||||
|
||||
int32_t TextRangeProvider::CompareEndpoints(TextPatternRangeEndpoint const &endpoint, ITextRangeProvider const &textRangeProvider, TextPatternRangeEndpoint const &targetEndpoint)
|
||||
{
|
||||
const auto target{ textRangeProvider.as<TextRangeProvider>() };
|
||||
const auto thisEnd{ endpoint == TextPatternRangeEndpoint::Start ? _rangeStart : _rangeEnd };
|
||||
const auto targetEnd{ targetEndpoint == TextPatternRangeEndpoint::Start ? target->_rangeStart : target->_rangeEnd };
|
||||
return thisEnd - targetEnd;
|
||||
}
|
||||
|
||||
void TextRangeProvider::ExpandToEnclosingUnit(TextUnit const &unit)
|
||||
{
|
||||
const auto editor{ _editor.get() };
|
||||
if (!editor)
|
||||
{
|
||||
throw hresult_error{ E_POINTER };
|
||||
}
|
||||
|
||||
if (unit == TextUnit::Document)
|
||||
{
|
||||
_rangeStart = 0;
|
||||
_rangeEnd = editor.Length();
|
||||
}
|
||||
else if (unit == TextUnit::Line || unit == TextUnit::Paragraph)
|
||||
{
|
||||
const auto line{ editor.LineFromPosition(_rangeStart) };
|
||||
_rangeStart = editor.PositionFromLine(line);
|
||||
_rangeEnd = editor.GetLineEndPosition(line);
|
||||
}
|
||||
else if (unit == TextUnit::Page)
|
||||
{
|
||||
const auto firstVisibleLine{ editor.FirstVisibleLine() };
|
||||
const auto maxLine{ editor.LineCount() - 1 };
|
||||
const auto lastVisibleLine{ std::min(maxLine, firstVisibleLine + editor.LinesOnScreen()) };
|
||||
|
||||
_rangeStart = editor.PositionFromLine(firstVisibleLine);
|
||||
_rangeEnd = editor.GetLineEndPosition(lastVisibleLine);
|
||||
}
|
||||
else if (unit == TextUnit::Word)
|
||||
{
|
||||
_rangeStart = editor.WordStartPosition(_rangeStart, false);
|
||||
_rangeEnd = editor.WordEndPosition(_rangeStart, false);
|
||||
}
|
||||
else if (unit == TextUnit::Character)
|
||||
{
|
||||
_rangeEnd = std::min(_rangeStart + 1, editor.Length()); // Todo: Multibyte chars
|
||||
}
|
||||
}
|
||||
|
||||
ITextRangeProvider TextRangeProvider::FindAttribute(int32_t attributeId, IInspectable const &value, bool backward)
|
||||
{
|
||||
throw hresult_not_implemented{};
|
||||
}
|
||||
|
||||
ITextRangeProvider TextRangeProvider::FindText(hstring const &text, bool backward, bool ignoreCase)
|
||||
{
|
||||
throw hresult_not_implemented{};
|
||||
}
|
||||
|
||||
IInspectable TextRangeProvider::GetAttributeValue(int32_t attributeId)
|
||||
{
|
||||
const auto editor{ _editor.get() };
|
||||
if (!editor)
|
||||
{
|
||||
throw hresult_error{ E_POINTER };
|
||||
}
|
||||
|
||||
switch (static_cast<AutomationTextAttributesEnum>(attributeId))
|
||||
{
|
||||
case AutomationTextAttributesEnum::IsReadOnlyAttribute:
|
||||
return box_value(editor.ReadOnly());
|
||||
case AutomationTextAttributesEnum::CaretPositionAttribute:
|
||||
{
|
||||
const auto sel{ editor.MainSelection() };
|
||||
const auto caret{ editor.GetSelectionNCaret(sel) };
|
||||
if (caret < _rangeStart || caret > _rangeEnd)
|
||||
{
|
||||
// Unknown if caret is outside this text range
|
||||
// Todo: Not sure if this is the correct behavior
|
||||
return box_value(AutomationCaretPosition::Unknown);
|
||||
}
|
||||
const auto line{ editor.LineFromPosition(caret) };
|
||||
if (caret == editor.PositionFromLine(line))
|
||||
{
|
||||
return box_value(AutomationCaretPosition::BeginningOfLine);
|
||||
}
|
||||
else if (caret == editor.GetLineEndPosition(line))
|
||||
{
|
||||
return box_value(AutomationCaretPosition::EndOfLine);
|
||||
}
|
||||
else
|
||||
{
|
||||
return box_value(AutomationCaretPosition::Unknown);
|
||||
}
|
||||
}
|
||||
default:
|
||||
// Must throw instead of returning nullptr
|
||||
// https://github.com/microsoft/terminal/blob/main/src/cascadia/TerminalControl/XamlUiaTextRange.cpp#L141
|
||||
throw_hresult(XAML_E_NOT_SUPPORTED);
|
||||
}
|
||||
}
|
||||
|
||||
void TextRangeProvider::GetBoundingRectangles(com_array<double> &returnValue)
|
||||
{
|
||||
// Structure: https://github.com/microsoft/terminal/blob/main/src/types/UiaTextRangeBase.cpp#L836
|
||||
|
||||
const auto editor{ _editor.get() };
|
||||
if (!editor)
|
||||
{
|
||||
throw hresult_error{ E_POINTER };
|
||||
}
|
||||
|
||||
// Todo: see EditorBaseControlAutomationPeer::GetVisibleRanges for caveats
|
||||
// Todo: Does not account for horizontal scrolling
|
||||
// Todo: Does not account for ranges that do not start and end at line starts/ends
|
||||
|
||||
const auto firstVisibleLine{ editor.FirstVisibleLine() };
|
||||
const auto maxLine{ editor.LineCount() - 1 };
|
||||
const auto lastVisibleLine{ std::min(maxLine, firstVisibleLine + editor.LinesOnScreen()) };
|
||||
|
||||
const auto startLine{ editor.LineFromPosition(_rangeStart) };
|
||||
const auto endLine{ editor.LineFromPosition(_rangeEnd) };
|
||||
|
||||
const auto top{ std::max(startLine, firstVisibleLine) };
|
||||
const auto end{ std::min(endLine, lastVisibleLine) };
|
||||
const auto count{ end - top + 1 };
|
||||
|
||||
if (count < 1)
|
||||
{
|
||||
returnValue = {};
|
||||
return;
|
||||
}
|
||||
|
||||
auto margins{ editor.MarginLeft() };
|
||||
const auto nMargins{ editor.Margins() };
|
||||
for (auto i{ 0 }; i < nMargins; i++)
|
||||
{
|
||||
margins += editor.GetMarginWidthN(i);
|
||||
}
|
||||
const auto maxTextWidth{ static_cast<int>(_bounds.Width) - editor.MarginRight() };
|
||||
|
||||
returnValue = com_array<double>(count * 4);
|
||||
// Todo: This code pretends that TextHeight gets the correct height including sublines (wrapping). It does not
|
||||
for (int64_t i = 0, j = 0; i < count; i++, j += 4)
|
||||
{
|
||||
const auto line{ top + i };
|
||||
const auto pos{ editor.PositionFromLine(line) };
|
||||
const auto xStart{ editor.PointXFromPosition(line == startLine ? _rangeStart : pos) };
|
||||
const auto xEnd{ editor.PointXFromPosition((line == endLine ? _rangeEnd : editor.GetLineEndPosition(line))) };
|
||||
const auto textStart{ std::max(margins, xStart) };
|
||||
returnValue[j + 0] = _bounds.X + textStart; // Left
|
||||
returnValue[j + 1] = _bounds.Y + editor.PointYFromPosition(pos); // Top
|
||||
returnValue[j + 2] = std::min(maxTextWidth, xEnd) - textStart; // Width
|
||||
returnValue[j + 3] = editor.TextHeight(line); // Height
|
||||
|
||||
// Todo: Reconsider how off screen text is handled
|
||||
if (xEnd < margins)
|
||||
{
|
||||
returnValue[j + 0] = _bounds.X + margins;
|
||||
returnValue[j + 2] = 0;
|
||||
}
|
||||
if (xStart > maxTextWidth)
|
||||
{
|
||||
returnValue[j + 0] = _bounds.X + maxTextWidth;
|
||||
returnValue[j + 2] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
IRawElementProviderSimple TextRangeProvider::GetEnclosingElement()
|
||||
{
|
||||
return _peer;
|
||||
}
|
||||
|
||||
hstring TextRangeProvider::GetText(int32_t maxLength)
|
||||
{
|
||||
const auto editor{ _editor.get() };
|
||||
if (!editor)
|
||||
{
|
||||
throw hresult_error{ E_POINTER };
|
||||
}
|
||||
|
||||
const auto length{ std::min(editor.Length() - _rangeStart, maxLength == -1 ? _rangeEnd - _rangeStart : std::min(_rangeEnd - _rangeStart, static_cast<int64_t>(maxLength))) };
|
||||
std::string s(length, '\0');
|
||||
Scintilla::TextRangeFull range
|
||||
{
|
||||
{ _rangeStart, _rangeStart + length, },
|
||||
&s[0],
|
||||
};
|
||||
editor.GetTextRangeFull(reinterpret_cast<uint64_t>(&range));
|
||||
return to_hstring(s);
|
||||
}
|
||||
|
||||
int32_t TextRangeProvider::Move(TextUnit const &unit, int32_t count)
|
||||
{
|
||||
// Todo: Bounds checking and other units etc. and make sure handling this right
|
||||
if (unit == TextUnit::Character)
|
||||
{
|
||||
_rangeStart += count;
|
||||
_rangeEnd += count;
|
||||
return count;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t TextRangeProvider::MoveEndpointByUnit(TextPatternRangeEndpoint const &endpoint, TextUnit const &unit, int32_t count)
|
||||
{
|
||||
// Todo: Bounds checking and other units etc.
|
||||
if (endpoint == TextPatternRangeEndpoint::Start && unit == TextUnit::Character)
|
||||
{
|
||||
_rangeStart += count;
|
||||
return count;
|
||||
}
|
||||
else if (endpoint == TextPatternRangeEndpoint::End && unit == TextUnit::Character)
|
||||
{
|
||||
_rangeEnd += count;
|
||||
return count;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void TextRangeProvider::MoveEndpointByRange(TextPatternRangeEndpoint const &endpoint, ITextRangeProvider const &textRangeProvider, TextPatternRangeEndpoint const &targetEndpoint)
|
||||
{
|
||||
const auto target{ textRangeProvider.as<TextRangeProvider>() };
|
||||
const auto src{ targetEndpoint == TextPatternRangeEndpoint::Start ? target->_rangeStart : target->_rangeEnd };
|
||||
if (endpoint == TextPatternRangeEndpoint::Start)
|
||||
{
|
||||
_rangeStart = src;
|
||||
if (_rangeStart > _rangeEnd)
|
||||
{
|
||||
_rangeEnd = _rangeStart;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_rangeEnd = src;
|
||||
if (_rangeStart > _rangeEnd)
|
||||
{
|
||||
_rangeStart = _rangeEnd;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TextRangeProvider::Select()
|
||||
{
|
||||
const auto editor{ _editor.get() };
|
||||
if (!editor)
|
||||
{
|
||||
throw hresult_error{ E_POINTER };
|
||||
}
|
||||
|
||||
editor.SetSelection(_rangeEnd, _rangeStart);
|
||||
}
|
||||
|
||||
void TextRangeProvider::AddToSelection()
|
||||
{
|
||||
const auto editor{ _editor.get() };
|
||||
if (!editor)
|
||||
{
|
||||
throw hresult_error{ E_POINTER };
|
||||
}
|
||||
|
||||
editor.AddSelection(_rangeEnd, _rangeStart);
|
||||
}
|
||||
|
||||
void TextRangeProvider::RemoveFromSelection()
|
||||
{
|
||||
const auto editor{ _editor.get() };
|
||||
if (!editor)
|
||||
{
|
||||
throw hresult_error{ E_POINTER };
|
||||
}
|
||||
|
||||
const auto count{ editor.Selections() };
|
||||
for (auto i{ 0 }; i < count; i++)
|
||||
{
|
||||
if (_rangeStart == editor.GetSelectionNStart(i)
|
||||
&& _rangeEnd == editor.GetSelectionNEnd(i))
|
||||
{
|
||||
editor.DropSelectionN(i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TextRangeProvider::ScrollIntoView(bool alignToTop)
|
||||
{
|
||||
const auto editor{ _editor.get() };
|
||||
if (!editor)
|
||||
{
|
||||
throw hresult_error{ E_POINTER };
|
||||
}
|
||||
|
||||
// Todo: You would want primary to be the caret and secondary to be anchor rather than start and end
|
||||
// Todo: see if we can honor alignToTop
|
||||
editor.ScrollRange(_rangeEnd, _rangeStart);
|
||||
}
|
||||
|
||||
com_array<IRawElementProviderSimple> TextRangeProvider::GetChildren()
|
||||
{
|
||||
return {};
|
||||
}
|
||||
}
|
|
@ -1,38 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include <winrt/WinUIEditor.h>
|
||||
|
||||
namespace winrt::WinUIEditor::implementation
|
||||
{
|
||||
struct TextRangeProvider : implements<TextRangeProvider, DUX::Automation::Provider::ITextRangeProvider>
|
||||
{
|
||||
TextRangeProvider(DUX::Automation::Provider::IRawElementProviderSimple const &peer, WinUIEditor::Editor const &editor, int64_t rangeStart, int64_t rangeEnd, Windows::Foundation::Rect const &bounds);
|
||||
|
||||
DUX::Automation::Provider::ITextRangeProvider Clone();
|
||||
bool Compare(DUX::Automation::Provider::ITextRangeProvider const &textRangeProvider);
|
||||
int32_t CompareEndpoints(DUX::Automation::Text::TextPatternRangeEndpoint const &endpoint, DUX::Automation::Provider::ITextRangeProvider const &textRangeProvider, DUX::Automation::Text::TextPatternRangeEndpoint const &targetEndpoint);
|
||||
void ExpandToEnclosingUnit(DUX::Automation::Text::TextUnit const &unit);
|
||||
DUX::Automation::Provider::ITextRangeProvider FindAttribute(int32_t attributeId, Windows::Foundation::IInspectable const &value, bool backward);
|
||||
DUX::Automation::Provider::ITextRangeProvider FindText(hstring const &text, bool backward, bool ignoreCase);
|
||||
Windows::Foundation::IInspectable GetAttributeValue(int32_t attributeId);
|
||||
void GetBoundingRectangles(com_array<double> &returnValue);
|
||||
DUX::Automation::Provider::IRawElementProviderSimple GetEnclosingElement();
|
||||
hstring GetText(int32_t maxLength);
|
||||
int32_t Move(DUX::Automation::Text::TextUnit const &unit, int32_t count);
|
||||
int32_t MoveEndpointByUnit(DUX::Automation::Text::TextPatternRangeEndpoint const &endpoint, DUX::Automation::Text::TextUnit const &unit, int32_t count);
|
||||
void MoveEndpointByRange(DUX::Automation::Text::TextPatternRangeEndpoint const &endpoint, DUX::Automation::Provider::ITextRangeProvider const &textRangeProvider, DUX::Automation::Text::TextPatternRangeEndpoint const &targetEndpoint);
|
||||
void Select();
|
||||
void AddToSelection();
|
||||
void RemoveFromSelection();
|
||||
void ScrollIntoView(bool alignToTop);
|
||||
com_array<DUX::Automation::Provider::IRawElementProviderSimple> GetChildren();
|
||||
|
||||
|
||||
private:
|
||||
DUX::Automation::Provider::IRawElementProviderSimple _peer{ nullptr };
|
||||
weak_ref<WinUIEditor::Editor> _editor{ nullptr };
|
||||
int64_t _rangeStart;
|
||||
int64_t _rangeEnd;
|
||||
Windows::Foundation::Rect _bounds;
|
||||
};
|
||||
}
|
|
@ -1,67 +0,0 @@
|
|||
<ResourceDictionary
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="using:WinUIEditor">
|
||||
|
||||
<!-- Todo: Apply corner radius to this. Remember conditional Setters do not work, so make a different style for each version. What happens with WinUI 3? -->
|
||||
<Style TargetType="local:EditorBaseControl">
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="local:EditorBaseControl">
|
||||
<Grid
|
||||
Padding="{TemplateBinding Padding}"
|
||||
Background="{TemplateBinding Background}"
|
||||
BorderBrush="{TemplateBinding BorderBrush}"
|
||||
BorderThickness="{TemplateBinding BorderThickness}"
|
||||
CornerRadius="{TemplateBinding CornerRadius}">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="*" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Border
|
||||
x:Name="ImageTarget"
|
||||
Grid.Row="0"
|
||||
Grid.RowSpan="2"
|
||||
Grid.Column="0"
|
||||
Grid.ColumnSpan="2"
|
||||
AllowDrop="True" />
|
||||
<ScrollBar
|
||||
x:Name="VerticalScrollBar"
|
||||
Grid.Row="0"
|
||||
Grid.Column="1"
|
||||
IndicatorMode="MouseIndicator"
|
||||
IsTabStop="False"
|
||||
Orientation="Vertical" />
|
||||
<ScrollBar
|
||||
x:Name="HorizontalScrollBar"
|
||||
Grid.Row="1"
|
||||
Grid.Column="0"
|
||||
IndicatorMode="MouseIndicator"
|
||||
IsTabStop="False"
|
||||
Orientation="Horizontal" />
|
||||
</Grid>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<Style TargetType="local:CodeEditorControl">
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="local:CodeEditorControl">
|
||||
<ContentPresenter
|
||||
x:Name="EditorContainer"
|
||||
Padding="{TemplateBinding Padding}"
|
||||
Background="{TemplateBinding Background}"
|
||||
BorderBrush="{TemplateBinding BorderBrush}"
|
||||
BorderThickness="{TemplateBinding BorderThickness}"
|
||||
CornerRadius="{TemplateBinding CornerRadius}" />
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
</ResourceDictionary>
|
|
@ -1,3 +0,0 @@
|
|||
EXPORTS
|
||||
DllCanUnloadNow = WINRT_CanUnloadNow PRIVATE
|
||||
DllGetActivationFactory = WINRT_GetActivationFactory PRIVATE
|
|
@ -1,847 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="..\ChangeBuild.props" />
|
||||
<Import Project="..\packages\Microsoft.WindowsAppSDK.1.5.240227000\build\native\Microsoft.WindowsAppSDK.props" Condition="$(WinUIEditorUseWinUI3) And Exists('..\packages\Microsoft.WindowsAppSDK.1.5.240227000\build\native\Microsoft.WindowsAppSDK.props')" />
|
||||
<Import Project="..\packages\Microsoft.Windows.SDK.BuildTools.10.0.22621.3233\build\Microsoft.Windows.SDK.BuildTools.props" Condition="Exists('..\packages\Microsoft.Windows.SDK.BuildTools.10.0.22621.3233\build\Microsoft.Windows.SDK.BuildTools.props')" />
|
||||
<Import Project="..\packages\Microsoft.Windows.CppWinRT.2.0.240111.5\build\native\Microsoft.Windows.CppWinRT.props" Condition="Exists('..\packages\Microsoft.Windows.CppWinRT.2.0.240111.5\build\native\Microsoft.Windows.CppWinRT.props')" />
|
||||
<PropertyGroup Label="Globals">
|
||||
<CppWinRTOptimized>true</CppWinRTOptimized>
|
||||
<CppWinRTRootNamespaceAutoMerge>true</CppWinRTRootNamespaceAutoMerge>
|
||||
<MinimalCoreWin>true</MinimalCoreWin>
|
||||
<ProjectGuid>{290647e3-d8cb-46b5-87ce-409f721e441a}</ProjectGuid>
|
||||
<ProjectName>WinUIEditor</ProjectName>
|
||||
<RootNamespace>WinUIEditor</RootNamespace>
|
||||
<DefaultLanguage>en-US</DefaultLanguage>
|
||||
<MinimumVisualStudioVersion>16.0</MinimumVisualStudioVersion>
|
||||
<AppContainerApplication>true</AppContainerApplication>
|
||||
<ApplicationType>Windows Store</ApplicationType>
|
||||
<ApplicationTypeRevision>10.0</ApplicationTypeRevision>
|
||||
<WindowsTargetPlatformVersion Condition="'$(WindowsTargetPlatformVersion)' == ''">10.0.22621.0</WindowsTargetPlatformVersion>
|
||||
<WindowsTargetPlatformMinVersion Condition="$(WinUIEditorUseWinUI3)">10.0.17763.0</WindowsTargetPlatformMinVersion>
|
||||
<WindowsTargetPlatformMinVersion Condition="!$(WinUIEditorUseWinUI3)">10.0.15063.0</WindowsTargetPlatformMinVersion>
|
||||
<DesktopCompatible Condition="$(WinUIEditorUseWinUI3)">true</DesktopCompatible>
|
||||
<UseWinUI Condition="$(WinUIEditorUseWinUI3)">true</UseWinUI>
|
||||
<_NoWinAPIFamilyApp Condition="$(WinUIEditorUseWinUI3)">true</_NoWinAPIFamilyApp>
|
||||
<_VC_Target_Library_Platform Condition="$(WinUIEditorUseWinUI3)">Desktop</_VC_Target_Library_Platform>
|
||||
<UseCrtSDKReference Condition="$(WinUIEditorUseWinUI3)">false</UseCrtSDKReference>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<Import Project="..\DualBuild.props" />
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|ARM">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>ARM</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|arm64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>arm64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|ARM">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>ARM</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|arm64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>arm64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<GenerateManifest>false</GenerateManifest>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)' == 'Debug'" Label="Configuration">
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<UseDummyPage>true</UseDummyPage>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)' == 'Release'" Label="Configuration">
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup />
|
||||
<ItemDefinitionGroup>
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
<PrecompiledHeaderOutputFile>$(IntDir)pch.pch</PrecompiledHeaderOutputFile>
|
||||
<AdditionalIncludeDirectories>..\scintilla\winui;..\scintilla\include;..\scintilla\src;..\lexilla\include\;..\lexilla\lexlib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<WarningLevel>Level4</WarningLevel>
|
||||
<AdditionalOptions>%(AdditionalOptions) /bigobj</AdditionalOptions>
|
||||
<PreprocessorDefinitions>SCI_EMPTYCATALOGUE;_CRT_SECURE_NO_DEPRECATE;_SCL_SECURE_NO_WARNINGS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>NOMINMAX;_WINRT_DLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions Condition="$(WinUIEditorUseWinUI3)">WINUI3;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalUsingDirectories>$(WindowsSDK_WindowsMetadata);$(AdditionalUsingDirectories)</AdditionalUsingDirectories>
|
||||
</ClCompile>
|
||||
<Midl>
|
||||
<PreprocessorDefinitions Condition="$(WinUIEditorUseWinUI3)">WINUI3;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</Midl>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateWindowsMetadata>true</GenerateWindowsMetadata>
|
||||
<ModuleDefinitionFile>WinUIEditor.def</ModuleDefinitionFile>
|
||||
<AdditionalDependencies Condition="$(WinUIEditorUseWinUI3)">user32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)' == 'Debug'">
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>USE_DUMMY_PAGE;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary Condition="$(WinUIEditorUseWinUI3)">MultiThreadedDebug</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<IgnoreSpecificDefaultLibraries Condition="$(WinUIEditorUseWinUI3)">%(IgnoreSpecificDefaultLibraries);libucrtd.lib</IgnoreSpecificDefaultLibraries>
|
||||
<AdditionalOptions Condition="$(WinUIEditorUseWinUI3)">%(AdditionalOptions) /defaultlib:ucrtd.lib</AdditionalOptions>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)' == 'Release'">
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ControlFlowGuard>Guard</ControlFlowGuard>
|
||||
<RuntimeLibrary Condition="$(WinUIEditorUseWinUI3)">MultiThreaded</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<IgnoreSpecificDefaultLibraries Condition="$(WinUIEditorUseWinUI3)">%(IgnoreSpecificDefaultLibraries);libucrt.lib</IgnoreSpecificDefaultLibraries>
|
||||
<AdditionalOptions Condition="$(WinUIEditorUseWinUI3)">%(AdditionalOptions) /defaultlib:ucrt.lib</AdditionalOptions>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="CodeEditorHandler.SciEdit.h" />
|
||||
<ClInclude Include="CodeEditorHandler.h" />
|
||||
<ClInclude Include="ControlIncludes.h" />
|
||||
<ClInclude Include="DarkPlus.h" />
|
||||
<ClInclude Include="DummyPage.h" Condition="'$(UseDummyPage)' == 'true'">
|
||||
<DependentUpon>DummyPage.xaml</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Helpers.h" />
|
||||
<ClInclude Include="EditorWrapper.h">
|
||||
<DependentUpon>EditorWrapper.cpp</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
</ClInclude>
|
||||
<ClInclude Include="LightPlus.h" />
|
||||
<ClInclude Include="EditorBaseControl.h">
|
||||
<DependentUpon>EditorBaseControl.cpp</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
</ClInclude>
|
||||
<ClInclude Include="CodeEditorControl.h">
|
||||
<DependentUpon>CodeEditorControl.cpp</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
</ClInclude>
|
||||
<ClInclude Include="EditorBaseControlAutomationPeer.h">
|
||||
<DependentUpon>EditorBaseControlAutomationPeer.cpp</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
</ClInclude>
|
||||
<ClInclude Include="pch.h" />
|
||||
<ClInclude Include="..\scintilla\winui\PlatWin.h" />
|
||||
<ClInclude Include="..\scintilla\winui\ScintillaWin.h" />
|
||||
<ClInclude Include="..\scintilla\winui\WinTypes.h" />
|
||||
<ClInclude Include="TextMateScope.h" />
|
||||
<ClInclude Include="TextRangeProvider.h" />
|
||||
<ClInclude Include="Wrapper.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="CodeEditorHandler.SciEdit.cpp">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="CodeEditorHandler.cpp">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="DummyPage.cpp" Condition="'$(UseDummyPage)' == 'true'">
|
||||
<DependentUpon>DummyPage.xaml</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Helpers.cpp" />
|
||||
<ClCompile Include="EditorWrapper.cpp">
|
||||
<SubType>Code</SubType>
|
||||
</ClCompile>
|
||||
<ClCompile Include="EditorBaseControl.cpp">
|
||||
<SubType>Code</SubType>
|
||||
</ClCompile>
|
||||
<ClCompile Include="CodeEditorControl.cpp">
|
||||
<SubType>Code</SubType>
|
||||
</ClCompile>
|
||||
<ClCompile Include="CodeEditorHandler.SyntaxHighlighting.cpp">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="EditorBaseControlAutomationPeer.cpp">
|
||||
<SubType>Code</SubType>
|
||||
</ClCompile>
|
||||
<ClCompile Include="pch.cpp">
|
||||
<PrecompiledHeader>Create</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(GeneratedFilesDir)module.g.cpp" />
|
||||
<ClCompile Include="..\lexilla\src\Lexilla.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\scintilla\winui\PlatWin.cxx" />
|
||||
<ClCompile Include="..\scintilla\winui\ScintillaWin.cxx" />
|
||||
<ClCompile Include="TextRangeProvider.cpp" />
|
||||
<ClCompile Include="Wrapper.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="WinUIEditor.def" />
|
||||
<None Include="packages.config" />
|
||||
<None Include="Defines.idl" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Midl Include="DummyPage.idl" Condition="'$(UseDummyPage)' == 'true'">
|
||||
<DependentUpon>DummyPage.xaml</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
</Midl>
|
||||
<Midl Include="EditorWrapper.idl">
|
||||
<DependentUpon>EditorWrapper.cpp</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
</Midl>
|
||||
<Midl Include="EditorBaseControl.idl">
|
||||
<DependentUpon>EditorBaseControl.cpp</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
</Midl>
|
||||
<Midl Include="CodeEditorControl.idl">
|
||||
<DependentUpon>CodeEditorControl.cpp</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
</Midl>
|
||||
<Midl Include="EditorBaseControlAutomationPeer.idl">
|
||||
<DependentUpon>EditorBaseControlAutomationPeer.cpp</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
</Midl>
|
||||
<Midl Include="IEditorAccess.idl" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Page Include="DummyPage.xaml" Condition="'$(UseDummyPage)' == 'true'">
|
||||
<SubType>Designer</SubType>
|
||||
</Page>
|
||||
<Page Include="Themes\Generic.xaml" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
<Import Project="..\packages\Microsoft.Windows.CppWinRT.2.0.240111.5\build\native\Microsoft.Windows.CppWinRT.targets" Condition="Exists('..\packages\Microsoft.Windows.CppWinRT.2.0.240111.5\build\native\Microsoft.Windows.CppWinRT.targets')" />
|
||||
<Import Project="..\packages\Microsoft.Windows.SDK.BuildTools.10.0.22621.3233\build\Microsoft.Windows.SDK.BuildTools.targets" Condition="Exists('..\packages\Microsoft.Windows.SDK.BuildTools.10.0.22621.3233\build\Microsoft.Windows.SDK.BuildTools.targets')" />
|
||||
<Import Project="..\packages\Microsoft.WindowsAppSDK.1.5.240227000\build\native\Microsoft.WindowsAppSDK.targets" Condition="$(WinUIEditorUseWinUI3) And Exists('..\packages\Microsoft.WindowsAppSDK.1.5.240227000\build\native\Microsoft.WindowsAppSDK.targets')" />
|
||||
<Import Project="..\packages\Microsoft.Windows.ImplementationLibrary.1.0.240122.1\build\native\Microsoft.Windows.ImplementationLibrary.targets" Condition="Exists('..\packages\Microsoft.Windows.ImplementationLibrary.1.0.240122.1\build\native\Microsoft.Windows.ImplementationLibrary.targets')" />
|
||||
</ImportGroup>
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('..\packages\Microsoft.Windows.CppWinRT.2.0.240111.5\build\native\Microsoft.Windows.CppWinRT.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Windows.CppWinRT.2.0.240111.5\build\native\Microsoft.Windows.CppWinRT.props'))" />
|
||||
<Error Condition="!Exists('..\packages\Microsoft.Windows.CppWinRT.2.0.240111.5\build\native\Microsoft.Windows.CppWinRT.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Windows.CppWinRT.2.0.240111.5\build\native\Microsoft.Windows.CppWinRT.targets'))" />
|
||||
<Error Condition="!Exists('..\packages\Microsoft.Windows.SDK.BuildTools.10.0.22621.3233\build\Microsoft.Windows.SDK.BuildTools.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Windows.SDK.BuildTools.10.0.22621.3233\build\Microsoft.Windows.SDK.BuildTools.props'))" />
|
||||
<Error Condition="!Exists('..\packages\Microsoft.Windows.SDK.BuildTools.10.0.22621.3233\build\Microsoft.Windows.SDK.BuildTools.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Windows.SDK.BuildTools.10.0.22621.3233\build\Microsoft.Windows.SDK.BuildTools.targets'))" />
|
||||
<Error Condition="$(WinUIEditorUseWinUI3) And !Exists('..\packages\Microsoft.WindowsAppSDK.1.5.240227000\build\native\Microsoft.WindowsAppSDK.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.WindowsAppSDK.1.5.240227000\build\native\Microsoft.WindowsAppSDK.props'))" />
|
||||
<Error Condition="$(WinUIEditorUseWinUI3) And !Exists('..\packages\Microsoft.WindowsAppSDK.1.5.240227000\build\native\Microsoft.WindowsAppSDK.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.WindowsAppSDK.1.5.240227000\build\native\Microsoft.WindowsAppSDK.targets'))" />
|
||||
<Error Condition="!Exists('..\packages\Microsoft.Windows.ImplementationLibrary.1.0.240122.1\build\native\Microsoft.Windows.ImplementationLibrary.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Windows.ImplementationLibrary.1.0.240122.1\build\native\Microsoft.Windows.ImplementationLibrary.targets'))" />
|
||||
</Target>
|
||||
<ItemGroup>
|
||||
<!--<WildcardClInclude Include="..\scintilla\include\*.h">-->
|
||||
<ClInclude Include="..\scintilla\include\ILexer.h" />
|
||||
<ClInclude Include="..\scintilla\include\ILoader.h" />
|
||||
<ClInclude Include="..\scintilla\include\Sci_Position.h" />
|
||||
<ClInclude Include="..\scintilla\include\Scintilla.h" />
|
||||
<ClInclude Include="..\scintilla\include\ScintillaCall.h" />
|
||||
<ClInclude Include="..\scintilla\include\ScintillaMessages.h" />
|
||||
<ClInclude Include="..\scintilla\include\ScintillaStructures.h" />
|
||||
<ClInclude Include="..\scintilla\include\ScintillaTypes.h" />
|
||||
<ClInclude Include="..\scintilla\include\ScintillaWidget.h" />
|
||||
<!--</WildcardClInclude>-->
|
||||
<!--<WildcardClInclude Include="..\scintilla\src\*.h">-->
|
||||
<ClInclude Include="..\scintilla\src\AutoComplete.h" />
|
||||
<ClInclude Include="..\scintilla\src\CallTip.h" />
|
||||
<ClInclude Include="..\scintilla\src\CaseConvert.h" />
|
||||
<ClInclude Include="..\scintilla\src\CaseFolder.h" />
|
||||
<ClInclude Include="..\scintilla\src\CellBuffer.h" />
|
||||
<ClInclude Include="..\scintilla\src\ChangeHistory.h" />
|
||||
<ClInclude Include="..\scintilla\src\CharacterCategoryMap.h" />
|
||||
<ClInclude Include="..\scintilla\src\CharacterType.h" />
|
||||
<ClInclude Include="..\scintilla\src\CharClassify.h" />
|
||||
<ClInclude Include="..\scintilla\src\ContractionState.h" />
|
||||
<ClInclude Include="..\scintilla\src\DBCS.h" />
|
||||
<ClInclude Include="..\scintilla\src\Debugging.h" />
|
||||
<ClInclude Include="..\scintilla\src\Decoration.h" />
|
||||
<ClInclude Include="..\scintilla\src\Document.h" />
|
||||
<ClInclude Include="..\scintilla\src\EditModel.h" />
|
||||
<ClInclude Include="..\scintilla\src\Editor.h" />
|
||||
<ClInclude Include="..\scintilla\src\EditView.h" />
|
||||
<ClInclude Include="..\scintilla\src\ElapsedPeriod.h" />
|
||||
<ClInclude Include="..\scintilla\src\Geometry.h" />
|
||||
<ClInclude Include="..\scintilla\src\Indicator.h" />
|
||||
<ClInclude Include="..\scintilla\src\KeyMap.h" />
|
||||
<ClInclude Include="..\scintilla\src\LineMarker.h" />
|
||||
<ClInclude Include="..\scintilla\src\MarginView.h" />
|
||||
<ClInclude Include="..\scintilla\src\Partitioning.h" />
|
||||
<ClInclude Include="..\scintilla\src\PerLine.h" />
|
||||
<ClInclude Include="..\scintilla\src\Platform.h" />
|
||||
<ClInclude Include="..\scintilla\src\Position.h" />
|
||||
<ClInclude Include="..\scintilla\src\PositionCache.h" />
|
||||
<ClInclude Include="..\scintilla\src\RESearch.h" />
|
||||
<ClInclude Include="..\scintilla\src\RunStyles.h" />
|
||||
<ClInclude Include="..\scintilla\src\ScintillaBase.h" />
|
||||
<ClInclude Include="..\scintilla\src\Selection.h" />
|
||||
<ClInclude Include="..\scintilla\src\SparseVector.h" />
|
||||
<ClInclude Include="..\scintilla\src\SplitVector.h" />
|
||||
<ClInclude Include="..\scintilla\src\Style.h" />
|
||||
<ClInclude Include="..\scintilla\src\UndoHistory.h" />
|
||||
<ClInclude Include="..\scintilla\src\UniConversion.h" />
|
||||
<ClInclude Include="..\scintilla\src\UniqueString.h" />
|
||||
<ClInclude Include="..\scintilla\src\ViewStyle.h" />
|
||||
<ClInclude Include="..\scintilla\src\XPM.h" />
|
||||
<!--</WildcardClInclude>-->
|
||||
<!--<WildcardClInclude Include="..\lexilla\include\*.h">-->
|
||||
<ClInclude Include="..\lexilla\include\Lexilla.h" />
|
||||
<ClInclude Include="..\lexilla\include\SciLexer.h" />
|
||||
<!--</WildcardClInclude>-->
|
||||
<!--<WildcardClInclude Include="..\lexilla\lexlib\*.h">-->
|
||||
<ClInclude Include="..\lexilla\lexlib\Accessor.h" />
|
||||
<ClInclude Include="..\lexilla\lexlib\CatalogueModules.h" />
|
||||
<ClInclude Include="..\lexilla\lexlib\CharacterCategory.h" />
|
||||
<ClInclude Include="..\lexilla\lexlib\CharacterSet.h" />
|
||||
<ClInclude Include="..\lexilla\lexlib\DefaultLexer.h" />
|
||||
<ClInclude Include="..\lexilla\lexlib\InList.h" />
|
||||
<ClInclude Include="..\lexilla\lexlib\LexAccessor.h" />
|
||||
<ClInclude Include="..\lexilla\lexlib\LexerBase.h" />
|
||||
<ClInclude Include="..\lexilla\lexlib\LexerModule.h" />
|
||||
<ClInclude Include="..\lexilla\lexlib\LexerNoExceptions.h" />
|
||||
<ClInclude Include="..\lexilla\lexlib\LexerSimple.h" />
|
||||
<ClInclude Include="..\lexilla\lexlib\OptionSet.h" />
|
||||
<ClInclude Include="..\lexilla\lexlib\PropSetSimple.h" />
|
||||
<ClInclude Include="..\lexilla\lexlib\SparseState.h" />
|
||||
<ClInclude Include="..\lexilla\lexlib\StringCopy.h" />
|
||||
<ClInclude Include="..\lexilla\lexlib\StyleContext.h" />
|
||||
<ClInclude Include="..\lexilla\lexlib\SubStyles.h" />
|
||||
<ClInclude Include="..\lexilla\lexlib\WordList.h" />
|
||||
<!--</WildcardClInclude>-->
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<!--<WildcardClCompile Include="..\scintilla\src\*.cxx" PrecompiledHeader="NotUsing">-->
|
||||
<ClCompile Include="..\scintilla\src\AutoComplete.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\scintilla\src\CallTip.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\scintilla\src\CaseConvert.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\scintilla\src\CaseFolder.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\scintilla\src\CellBuffer.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\scintilla\src\ChangeHistory.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\scintilla\src\CharacterCategoryMap.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\scintilla\src\CharacterType.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\scintilla\src\CharClassify.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\scintilla\src\ContractionState.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\scintilla\src\DBCS.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\scintilla\src\Decoration.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\scintilla\src\Document.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\scintilla\src\EditModel.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\scintilla\src\Editor.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\scintilla\src\EditView.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\scintilla\src\Geometry.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\scintilla\src\Indicator.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\scintilla\src\KeyMap.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\scintilla\src\LineMarker.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\scintilla\src\MarginView.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\scintilla\src\PerLine.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\scintilla\src\PositionCache.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\scintilla\src\RESearch.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\scintilla\src\RunStyles.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\scintilla\src\ScintillaBase.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\scintilla\src\Selection.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\scintilla\src\Style.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\scintilla\src\UndoHistory.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\scintilla\src\UniConversion.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\scintilla\src\UniqueString.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\scintilla\src\ViewStyle.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\scintilla\src\XPM.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<!--</WildcardClInclude>-->
|
||||
<!--<WildcardClCompile Include="..\scintilla\call\*.cxx" PrecompiledHeader="NotUsing">-->
|
||||
<ClCompile Include="..\scintilla\call\ScintillaCall.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<!--</WildcardClInclude>-->
|
||||
<!--<WildcardClCompile Include="..\lexilla\lexers\*.cxx" PrecompiledHeader="NotUsing">-->
|
||||
<ClCompile Include="..\lexilla\lexers\LexA68k.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexAbaqus.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexAda.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexAPDL.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexAsciidoc.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexAsm.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexAsn1.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexASY.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexAU3.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexAVE.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexAVS.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexBaan.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexBash.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexBasic.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexBatch.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexBibTeX.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexBullant.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexCaml.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexCIL.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexCLW.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexCmake.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexCOBOL.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexCoffeeScript.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexConf.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexCPP.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexCrontab.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexCsound.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexCSS.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexD.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexDataflex.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexDiff.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexDMAP.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexDMIS.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexECL.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexEDIFACT.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexEiffel.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexErlang.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexErrorList.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexEScript.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexFlagship.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexForth.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexFortran.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexFSharp.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexGAP.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexGDScript.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexGui4Cli.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexHaskell.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexHex.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexHollywood.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexHTML.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexIndent.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexInno.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexJSON.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexJulia.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexKix.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexKVIrc.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexLaTeX.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexLisp.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexLout.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexLua.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexMagik.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexMake.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexMarkdown.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexMatlab.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexMaxima.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexMetapost.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexMMIXAL.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexModula.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexMPT.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexMSSQL.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexMySQL.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexNim.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexNimrod.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexNsis.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexNull.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexOpal.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexOScript.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexPascal.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexPB.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexPerl.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexPLM.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexPO.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexPOV.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexPowerPro.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexPowerShell.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexProgress.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexProps.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexPS.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexPython.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexR.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexRaku.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexRebol.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexRegistry.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexRuby.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexRust.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexSAS.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexScriptol.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexSmalltalk.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexSML.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexSorcus.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexSpecman.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexSpice.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexSQL.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexStata.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexSTTXT.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexTACL.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexTADS3.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexTAL.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexTCL.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexTCMD.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexTeX.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexTxt2tags.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexVB.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexVerilog.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexVHDL.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexVisualProlog.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexX12.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexYAML.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<!--</WildcardClInclude>-->
|
||||
<!--<WildcardClCompile Include="..\lexilla\lexlib\*.cxx" PrecompiledHeader="NotUsing">-->
|
||||
<ClCompile Include="..\lexilla\lexlib\Accessor.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexlib\CharacterCategory.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexlib\CharacterSet.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexlib\DefaultLexer.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexlib\InList.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexlib\LexAccessor.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexlib\LexerBase.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexlib\LexerModule.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexlib\LexerNoExceptions.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexlib\LexerSimple.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexlib\PropSetSimple.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexlib\StyleContext.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexlib\WordList.cxx">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<!--</WildcardClInclude>-->
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -1,785 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="15.0">
|
||||
<ItemGroup>
|
||||
<Filter Include="Resources">
|
||||
<UniqueIdentifier>accd3aa8-1ba0-4223-9bbe-0c431709210b</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tga;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Generated Files">
|
||||
<UniqueIdentifier>{926ab91d-31b4-48c3-b9a4-e681349f27f0}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Scintilla">
|
||||
<UniqueIdentifier>{d2af1cc1-e66c-4161-aa1f-2dce16d662a7}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Lexilla">
|
||||
<UniqueIdentifier>{dcec4768-41d4-43a2-9eaa-ebecc2ebbcca}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Lexers">
|
||||
<UniqueIdentifier>{d97ff389-708f-4fce-a1ad-4f6ad3a99854}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="$(GeneratedFilesDir)module.g.cpp">
|
||||
<Filter>Generated Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="CodeEditorControl.cpp" />
|
||||
<ClCompile Include="CodeEditorHandler.cpp" />
|
||||
<ClCompile Include="CodeEditorHandler.SciEdit.cpp" />
|
||||
<ClCompile Include="CodeEditorHandler.SyntaxHighlighting.cpp" />
|
||||
<ClCompile Include="DummyPage.cpp" />
|
||||
<ClCompile Include="EditorBaseControl.cpp" />
|
||||
<ClCompile Include="EditorBaseControlAutomationPeer.cpp" />
|
||||
<ClCompile Include="EditorWrapper.cpp" />
|
||||
<ClCompile Include="Helpers.cpp" />
|
||||
<ClCompile Include="pch.cpp" />
|
||||
<ClCompile Include="TextRangeProvider.cpp" />
|
||||
<ClCompile Include="Wrapper.cpp" />
|
||||
<ClCompile Include="..\scintilla\winui\PlatWin.cxx" />
|
||||
<ClCompile Include="..\scintilla\winui\ScintillaWin.cxx" />
|
||||
<ClCompile Include="..\scintilla\src\AutoComplete.cxx">
|
||||
<Filter>Scintilla</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\scintilla\src\CallTip.cxx">
|
||||
<Filter>Scintilla</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\scintilla\src\CaseConvert.cxx">
|
||||
<Filter>Scintilla</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\scintilla\src\CaseFolder.cxx">
|
||||
<Filter>Scintilla</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\scintilla\src\CellBuffer.cxx">
|
||||
<Filter>Scintilla</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\scintilla\src\ChangeHistory.cxx">
|
||||
<Filter>Scintilla</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\scintilla\src\CharacterCategoryMap.cxx">
|
||||
<Filter>Scintilla</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\scintilla\src\CharacterType.cxx">
|
||||
<Filter>Scintilla</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\scintilla\src\CharClassify.cxx">
|
||||
<Filter>Scintilla</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\scintilla\src\ContractionState.cxx">
|
||||
<Filter>Scintilla</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\scintilla\src\DBCS.cxx">
|
||||
<Filter>Scintilla</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\scintilla\src\Decoration.cxx">
|
||||
<Filter>Scintilla</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\scintilla\src\Document.cxx">
|
||||
<Filter>Scintilla</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\scintilla\src\EditModel.cxx">
|
||||
<Filter>Scintilla</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\scintilla\src\Editor.cxx">
|
||||
<Filter>Scintilla</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\scintilla\src\EditView.cxx">
|
||||
<Filter>Scintilla</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\scintilla\src\Geometry.cxx">
|
||||
<Filter>Scintilla</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\scintilla\src\Indicator.cxx">
|
||||
<Filter>Scintilla</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\scintilla\src\KeyMap.cxx">
|
||||
<Filter>Scintilla</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\scintilla\src\LineMarker.cxx">
|
||||
<Filter>Scintilla</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\scintilla\src\MarginView.cxx">
|
||||
<Filter>Scintilla</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\scintilla\src\PerLine.cxx">
|
||||
<Filter>Scintilla</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\scintilla\src\PositionCache.cxx">
|
||||
<Filter>Scintilla</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\scintilla\src\RESearch.cxx">
|
||||
<Filter>Scintilla</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\scintilla\src\RunStyles.cxx">
|
||||
<Filter>Scintilla</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\scintilla\src\ScintillaBase.cxx">
|
||||
<Filter>Scintilla</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\scintilla\src\Selection.cxx">
|
||||
<Filter>Scintilla</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\scintilla\src\Style.cxx">
|
||||
<Filter>Scintilla</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\scintilla\src\UndoHistory.cxx">
|
||||
<Filter>Scintilla</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\scintilla\src\UniConversion.cxx">
|
||||
<Filter>Scintilla</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\scintilla\src\UniqueString.cxx">
|
||||
<Filter>Scintilla</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\scintilla\src\ViewStyle.cxx">
|
||||
<Filter>Scintilla</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\scintilla\src\XPM.cxx">
|
||||
<Filter>Scintilla</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\scintilla\call\ScintillaCall.cxx">
|
||||
<Filter>Scintilla</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexA68k.cxx">
|
||||
<Filter>Lexers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexAbaqus.cxx">
|
||||
<Filter>Lexers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexAda.cxx">
|
||||
<Filter>Lexers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexAPDL.cxx">
|
||||
<Filter>Lexers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexAsciidoc.cxx">
|
||||
<Filter>Lexers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexAsm.cxx">
|
||||
<Filter>Lexers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexAsn1.cxx">
|
||||
<Filter>Lexers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexASY.cxx">
|
||||
<Filter>Lexers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexAU3.cxx">
|
||||
<Filter>Lexers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexAVE.cxx">
|
||||
<Filter>Lexers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexAVS.cxx">
|
||||
<Filter>Lexers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexBaan.cxx">
|
||||
<Filter>Lexers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexBash.cxx">
|
||||
<Filter>Lexers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexBasic.cxx">
|
||||
<Filter>Lexers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexBatch.cxx">
|
||||
<Filter>Lexers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexBibTeX.cxx">
|
||||
<Filter>Lexers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexBullant.cxx">
|
||||
<Filter>Lexers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexCaml.cxx">
|
||||
<Filter>Lexers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexCIL.cxx">
|
||||
<Filter>Lexers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexCLW.cxx">
|
||||
<Filter>Lexers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexCmake.cxx">
|
||||
<Filter>Lexers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexCOBOL.cxx">
|
||||
<Filter>Lexers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexCoffeeScript.cxx">
|
||||
<Filter>Lexers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexConf.cxx">
|
||||
<Filter>Lexers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexCPP.cxx">
|
||||
<Filter>Lexers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexCrontab.cxx">
|
||||
<Filter>Lexers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexCsound.cxx">
|
||||
<Filter>Lexers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexCSS.cxx">
|
||||
<Filter>Lexers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexD.cxx">
|
||||
<Filter>Lexers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexDataflex.cxx">
|
||||
<Filter>Lexers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexDiff.cxx">
|
||||
<Filter>Lexers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexDMAP.cxx">
|
||||
<Filter>Lexers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexDMIS.cxx">
|
||||
<Filter>Lexers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexECL.cxx">
|
||||
<Filter>Lexers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexEDIFACT.cxx">
|
||||
<Filter>Lexers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexEiffel.cxx">
|
||||
<Filter>Lexers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexErlang.cxx">
|
||||
<Filter>Lexers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexErrorList.cxx">
|
||||
<Filter>Lexers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexEScript.cxx">
|
||||
<Filter>Lexers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexFlagship.cxx">
|
||||
<Filter>Lexers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexForth.cxx">
|
||||
<Filter>Lexers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexFortran.cxx">
|
||||
<Filter>Lexers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexFSharp.cxx">
|
||||
<Filter>Lexers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexGAP.cxx">
|
||||
<Filter>Lexers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexGDScript.cxx">
|
||||
<Filter>Lexers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexGui4Cli.cxx">
|
||||
<Filter>Lexers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexHaskell.cxx">
|
||||
<Filter>Lexers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexHex.cxx">
|
||||
<Filter>Lexers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexHollywood.cxx">
|
||||
<Filter>Lexers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexHTML.cxx">
|
||||
<Filter>Lexers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexIndent.cxx">
|
||||
<Filter>Lexers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexInno.cxx">
|
||||
<Filter>Lexers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexJSON.cxx">
|
||||
<Filter>Lexers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexJulia.cxx">
|
||||
<Filter>Lexers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexKix.cxx">
|
||||
<Filter>Lexers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexKVIrc.cxx">
|
||||
<Filter>Lexers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexLaTeX.cxx">
|
||||
<Filter>Lexers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexLisp.cxx">
|
||||
<Filter>Lexers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexLout.cxx">
|
||||
<Filter>Lexers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexLua.cxx">
|
||||
<Filter>Lexers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexMagik.cxx">
|
||||
<Filter>Lexers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexMake.cxx">
|
||||
<Filter>Lexers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexMarkdown.cxx">
|
||||
<Filter>Lexers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexMatlab.cxx">
|
||||
<Filter>Lexers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexMaxima.cxx">
|
||||
<Filter>Lexers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexMetapost.cxx">
|
||||
<Filter>Lexers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexMMIXAL.cxx">
|
||||
<Filter>Lexers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexModula.cxx">
|
||||
<Filter>Lexers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexMPT.cxx">
|
||||
<Filter>Lexers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexMSSQL.cxx">
|
||||
<Filter>Lexers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexMySQL.cxx">
|
||||
<Filter>Lexers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexNim.cxx">
|
||||
<Filter>Lexers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexNimrod.cxx">
|
||||
<Filter>Lexers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexNsis.cxx">
|
||||
<Filter>Lexers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexNull.cxx">
|
||||
<Filter>Lexers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexOpal.cxx">
|
||||
<Filter>Lexers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexOScript.cxx">
|
||||
<Filter>Lexers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexPascal.cxx">
|
||||
<Filter>Lexers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexPB.cxx">
|
||||
<Filter>Lexers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexPerl.cxx">
|
||||
<Filter>Lexers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexPLM.cxx">
|
||||
<Filter>Lexers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexPO.cxx">
|
||||
<Filter>Lexers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexPOV.cxx">
|
||||
<Filter>Lexers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexPowerPro.cxx">
|
||||
<Filter>Lexers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexPowerShell.cxx">
|
||||
<Filter>Lexers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexProgress.cxx">
|
||||
<Filter>Lexers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexProps.cxx">
|
||||
<Filter>Lexers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexPS.cxx">
|
||||
<Filter>Lexers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexPython.cxx">
|
||||
<Filter>Lexers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexR.cxx">
|
||||
<Filter>Lexers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexRaku.cxx">
|
||||
<Filter>Lexers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexRebol.cxx">
|
||||
<Filter>Lexers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexRegistry.cxx">
|
||||
<Filter>Lexers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexRuby.cxx">
|
||||
<Filter>Lexers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexRust.cxx">
|
||||
<Filter>Lexers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexSAS.cxx">
|
||||
<Filter>Lexers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexScriptol.cxx">
|
||||
<Filter>Lexers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexSmalltalk.cxx">
|
||||
<Filter>Lexers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexSML.cxx">
|
||||
<Filter>Lexers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexSorcus.cxx">
|
||||
<Filter>Lexers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexSpecman.cxx">
|
||||
<Filter>Lexers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexSpice.cxx">
|
||||
<Filter>Lexers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexSQL.cxx">
|
||||
<Filter>Lexers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexStata.cxx">
|
||||
<Filter>Lexers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexSTTXT.cxx">
|
||||
<Filter>Lexers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexTACL.cxx">
|
||||
<Filter>Lexers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexTADS3.cxx">
|
||||
<Filter>Lexers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexTAL.cxx">
|
||||
<Filter>Lexers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexTCL.cxx">
|
||||
<Filter>Lexers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexTCMD.cxx">
|
||||
<Filter>Lexers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexTeX.cxx">
|
||||
<Filter>Lexers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexTxt2tags.cxx">
|
||||
<Filter>Lexers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexVB.cxx">
|
||||
<Filter>Lexers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexVerilog.cxx">
|
||||
<Filter>Lexers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexVHDL.cxx">
|
||||
<Filter>Lexers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexVisualProlog.cxx">
|
||||
<Filter>Lexers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexX12.cxx">
|
||||
<Filter>Lexers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexers\LexYAML.cxx">
|
||||
<Filter>Lexers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexlib\Accessor.cxx">
|
||||
<Filter>Lexilla</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexlib\CharacterCategory.cxx">
|
||||
<Filter>Lexilla</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexlib\CharacterSet.cxx">
|
||||
<Filter>Lexilla</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexlib\DefaultLexer.cxx">
|
||||
<Filter>Lexilla</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexlib\InList.cxx">
|
||||
<Filter>Lexilla</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexlib\LexAccessor.cxx">
|
||||
<Filter>Lexilla</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexlib\LexerBase.cxx">
|
||||
<Filter>Lexilla</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexlib\LexerModule.cxx">
|
||||
<Filter>Lexilla</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexlib\LexerNoExceptions.cxx">
|
||||
<Filter>Lexilla</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexlib\LexerSimple.cxx">
|
||||
<Filter>Lexilla</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexlib\PropSetSimple.cxx">
|
||||
<Filter>Lexilla</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexlib\StyleContext.cxx">
|
||||
<Filter>Lexilla</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\lexlib\WordList.cxx">
|
||||
<Filter>Lexilla</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lexilla\src\Lexilla.cxx">
|
||||
<Filter>Lexilla</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="CodeEditorControl.h" />
|
||||
<ClInclude Include="CodeEditorHandler.h" />
|
||||
<ClInclude Include="CodeEditorHandler.SciEdit.h" />
|
||||
<ClInclude Include="ControlIncludes.h" />
|
||||
<ClInclude Include="DarkPlus.h" />
|
||||
<ClInclude Include="DummyPage.h" />
|
||||
<ClInclude Include="EditorBaseControl.h" />
|
||||
<ClInclude Include="EditorBaseControlAutomationPeer.h" />
|
||||
<ClInclude Include="EditorWrapper.h" />
|
||||
<ClInclude Include="Helpers.h" />
|
||||
<ClInclude Include="LightPlus.h" />
|
||||
<ClInclude Include="pch.h" />
|
||||
<ClInclude Include="TextMateScope.h" />
|
||||
<ClInclude Include="TextRangeProvider.h" />
|
||||
<ClInclude Include="Wrapper.h" />
|
||||
<ClInclude Include="..\scintilla\winui\PlatWin.h" />
|
||||
<ClInclude Include="..\scintilla\winui\ScintillaWin.h" />
|
||||
<ClInclude Include="..\scintilla\winui\WinTypes.h" />
|
||||
<ClInclude Include="..\scintilla\include\ILexer.h">
|
||||
<Filter>Scintilla</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\scintilla\include\ILoader.h">
|
||||
<Filter>Scintilla</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\scintilla\include\Sci_Position.h">
|
||||
<Filter>Scintilla</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\scintilla\include\Scintilla.h">
|
||||
<Filter>Scintilla</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\scintilla\include\ScintillaCall.h">
|
||||
<Filter>Scintilla</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\scintilla\include\ScintillaMessages.h">
|
||||
<Filter>Scintilla</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\scintilla\include\ScintillaStructures.h">
|
||||
<Filter>Scintilla</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\scintilla\include\ScintillaTypes.h">
|
||||
<Filter>Scintilla</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\scintilla\include\ScintillaWidget.h">
|
||||
<Filter>Scintilla</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\scintilla\src\AutoComplete.h">
|
||||
<Filter>Scintilla</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\scintilla\src\CallTip.h">
|
||||
<Filter>Scintilla</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\scintilla\src\CaseConvert.h">
|
||||
<Filter>Scintilla</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\scintilla\src\CaseFolder.h">
|
||||
<Filter>Scintilla</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\scintilla\src\CellBuffer.h">
|
||||
<Filter>Scintilla</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\scintilla\src\ChangeHistory.h">
|
||||
<Filter>Scintilla</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\scintilla\src\CharacterCategoryMap.h">
|
||||
<Filter>Scintilla</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\scintilla\src\CharacterType.h">
|
||||
<Filter>Scintilla</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\scintilla\src\CharClassify.h">
|
||||
<Filter>Scintilla</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\scintilla\src\ContractionState.h">
|
||||
<Filter>Scintilla</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\scintilla\src\DBCS.h">
|
||||
<Filter>Scintilla</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\scintilla\src\Debugging.h">
|
||||
<Filter>Scintilla</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\scintilla\src\Decoration.h">
|
||||
<Filter>Scintilla</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\scintilla\src\Document.h">
|
||||
<Filter>Scintilla</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\scintilla\src\EditModel.h">
|
||||
<Filter>Scintilla</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\scintilla\src\Editor.h">
|
||||
<Filter>Scintilla</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\scintilla\src\EditView.h">
|
||||
<Filter>Scintilla</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\scintilla\src\ElapsedPeriod.h">
|
||||
<Filter>Scintilla</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\scintilla\src\Geometry.h">
|
||||
<Filter>Scintilla</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\scintilla\src\Indicator.h">
|
||||
<Filter>Scintilla</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\scintilla\src\KeyMap.h">
|
||||
<Filter>Scintilla</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\scintilla\src\LineMarker.h">
|
||||
<Filter>Scintilla</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\scintilla\src\MarginView.h">
|
||||
<Filter>Scintilla</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\scintilla\src\Partitioning.h">
|
||||
<Filter>Scintilla</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\scintilla\src\PerLine.h">
|
||||
<Filter>Scintilla</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\scintilla\src\Platform.h">
|
||||
<Filter>Scintilla</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\scintilla\src\Position.h">
|
||||
<Filter>Scintilla</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\scintilla\src\PositionCache.h">
|
||||
<Filter>Scintilla</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\scintilla\src\RESearch.h">
|
||||
<Filter>Scintilla</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\scintilla\src\RunStyles.h">
|
||||
<Filter>Scintilla</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\scintilla\src\ScintillaBase.h">
|
||||
<Filter>Scintilla</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\scintilla\src\Selection.h">
|
||||
<Filter>Scintilla</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\scintilla\src\SparseVector.h">
|
||||
<Filter>Scintilla</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\scintilla\src\SplitVector.h">
|
||||
<Filter>Scintilla</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\scintilla\src\Style.h">
|
||||
<Filter>Scintilla</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\scintilla\src\UndoHistory.h">
|
||||
<Filter>Scintilla</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\scintilla\src\UniConversion.h">
|
||||
<Filter>Scintilla</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\scintilla\src\UniqueString.h">
|
||||
<Filter>Scintilla</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\scintilla\src\ViewStyle.h">
|
||||
<Filter>Scintilla</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\scintilla\src\XPM.h">
|
||||
<Filter>Scintilla</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\lexilla\lexlib\Accessor.h">
|
||||
<Filter>Lexilla</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\lexilla\lexlib\CatalogueModules.h">
|
||||
<Filter>Lexilla</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\lexilla\lexlib\CharacterCategory.h">
|
||||
<Filter>Lexilla</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\lexilla\lexlib\CharacterSet.h">
|
||||
<Filter>Lexilla</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\lexilla\lexlib\DefaultLexer.h">
|
||||
<Filter>Lexilla</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\lexilla\lexlib\InList.h">
|
||||
<Filter>Lexilla</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\lexilla\lexlib\LexAccessor.h">
|
||||
<Filter>Lexilla</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\lexilla\lexlib\LexerBase.h">
|
||||
<Filter>Lexilla</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\lexilla\lexlib\LexerModule.h">
|
||||
<Filter>Lexilla</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\lexilla\lexlib\LexerNoExceptions.h">
|
||||
<Filter>Lexilla</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\lexilla\lexlib\LexerSimple.h">
|
||||
<Filter>Lexilla</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\lexilla\lexlib\OptionSet.h">
|
||||
<Filter>Lexilla</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\lexilla\lexlib\PropSetSimple.h">
|
||||
<Filter>Lexilla</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\lexilla\lexlib\SparseState.h">
|
||||
<Filter>Lexilla</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\lexilla\lexlib\StringCopy.h">
|
||||
<Filter>Lexilla</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\lexilla\lexlib\StyleContext.h">
|
||||
<Filter>Lexilla</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\lexilla\lexlib\SubStyles.h">
|
||||
<Filter>Lexilla</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\lexilla\lexlib\WordList.h">
|
||||
<Filter>Lexilla</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\lexilla\include\Lexilla.h">
|
||||
<Filter>Lexilla</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\lexilla\include\SciLexer.h">
|
||||
<Filter>Lexilla</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="WinUIEditor.def" />
|
||||
<None Include="packages.config" />
|
||||
<None Include="Defines.idl" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Page Include="Themes\Generic.xaml" />
|
||||
<Page Include="DummyPage.xaml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Natvis Include="$(MSBuildThisFileDirectory)..\..\natvis\wil.natvis" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Midl Include="CodeEditorControl.idl" />
|
||||
<Midl Include="DummyPage.idl" />
|
||||
<Midl Include="EditorBaseControl.idl" />
|
||||
<Midl Include="EditorBaseControlAutomationPeer.idl" />
|
||||
<Midl Include="EditorWrapper.idl" />
|
||||
<Midl Include="IEditorAccess.idl" />
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -1,261 +0,0 @@
|
|||
#include "pch.h"
|
||||
#include "Wrapper.h"
|
||||
|
||||
namespace WinUIEditor
|
||||
{
|
||||
winrt::com_ptr<::IVirtualSurfaceImageSourceNative> Wrapper::VsisNative()
|
||||
{
|
||||
return _vsisNative;
|
||||
}
|
||||
|
||||
void Wrapper::VsisNative(winrt::com_ptr<::IVirtualSurfaceImageSourceNative> const &value)
|
||||
{
|
||||
_vsisNative = value;
|
||||
_sisNativeWithD2D = _vsisNative.as<::ISurfaceImageSourceNativeWithD2D>();
|
||||
}
|
||||
|
||||
winrt::com_ptr<::ISurfaceImageSourceNativeWithD2D> Wrapper::SisNativeWithD2D()
|
||||
{
|
||||
return _sisNativeWithD2D;
|
||||
}
|
||||
|
||||
winrt::com_ptr<::ID2D1DeviceContext> Wrapper::D2dDeviceContext()
|
||||
{
|
||||
return _d2dDeviceContext;
|
||||
}
|
||||
|
||||
void Wrapper::TrimDxgiDevice()
|
||||
{
|
||||
if (_dxgiDevice)
|
||||
{
|
||||
_dxgiDevice->Trim();
|
||||
}
|
||||
}
|
||||
|
||||
float Wrapper::LogicalDpi()
|
||||
{
|
||||
return _logicalDpi;
|
||||
}
|
||||
|
||||
void Wrapper::LogicalDpi(float value)
|
||||
{
|
||||
_logicalDpi = value;
|
||||
}
|
||||
|
||||
int Wrapper::Width()
|
||||
{
|
||||
return _width;
|
||||
}
|
||||
|
||||
void Wrapper::Width(int value)
|
||||
{
|
||||
_width = value;
|
||||
}
|
||||
|
||||
int Wrapper::Height()
|
||||
{
|
||||
return _height;
|
||||
}
|
||||
|
||||
void Wrapper::Height(int value)
|
||||
{
|
||||
_height = value;
|
||||
}
|
||||
|
||||
void Wrapper::SetMouseCapture(bool on)
|
||||
{
|
||||
if (!_mouseCaptureElement)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (on)
|
||||
{
|
||||
if (_lastPointer) // Todo: Check if works
|
||||
{
|
||||
_captured = _mouseCaptureElement.CapturePointer(_lastPointer);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_mouseCaptureElement.ReleasePointerCaptures(); // Todo: Or just one?
|
||||
_captured = false;
|
||||
}
|
||||
}
|
||||
|
||||
bool Wrapper::HaveMouseCapture()
|
||||
{
|
||||
return _captured;
|
||||
}
|
||||
|
||||
void Wrapper::SetMouseCaptureElement(winrt::DUX::UIElement const &element)
|
||||
{
|
||||
_mouseCaptureElement = element;
|
||||
// Todo: Do we need to revoke?
|
||||
// Todo: Do we need a strong/weak reference?
|
||||
_mouseCaptureElement.PointerPressed([&](winrt::Windows::Foundation::IInspectable const &sender, winrt::DUX::Input::PointerRoutedEventArgs const &args)
|
||||
{
|
||||
_lastPointer = args.Pointer();
|
||||
});
|
||||
_mouseCaptureElement.PointerCaptureLost([&](winrt::Windows::Foundation::IInspectable const &sender, winrt::DUX::Input::PointerRoutedEventArgs const &args)
|
||||
{
|
||||
_captured = false;
|
||||
});
|
||||
}
|
||||
|
||||
void Wrapper::SetCursor(winrt::DCUR cursor)
|
||||
{
|
||||
#ifdef WINUI3
|
||||
if (_mouseCaptureElement)
|
||||
{
|
||||
_mouseCaptureElement.try_as<winrt::Microsoft::UI::Xaml::IUIElementProtected>().ProtectedCursor(winrt::Microsoft::UI::Input::InputSystemCursor::Create(cursor));
|
||||
}
|
||||
#else
|
||||
winrt::Windows::UI::Core::CoreWindow::GetForCurrentThread().PointerCursor(winrt::Windows::UI::Core::CoreCursor{ cursor, 0 });
|
||||
#endif
|
||||
}
|
||||
|
||||
void Wrapper::SetScrollBars(winrt::DUX::Controls::Primitives::ScrollBar const &horizontalScrollBar, winrt::DUX::Controls::Primitives::ScrollBar const &verticalScrollBar)
|
||||
{
|
||||
_horizontalScrollBar = horizontalScrollBar;
|
||||
_verticalScrollBar = verticalScrollBar;
|
||||
}
|
||||
|
||||
bool Wrapper::HasScrollBars()
|
||||
{
|
||||
return _horizontalScrollBar && _verticalScrollBar;
|
||||
}
|
||||
|
||||
void Wrapper::HorizontalScrollBarValue(double value)
|
||||
{
|
||||
_horizontalScrollBar.Value(value);
|
||||
}
|
||||
|
||||
void Wrapper::VerticalScrollBarValue(double value)
|
||||
{
|
||||
_verticalScrollBar.Value(value);
|
||||
}
|
||||
|
||||
void Wrapper::HorizontalScrollBarMinimum(double value)
|
||||
{
|
||||
_horizontalScrollBar.Minimum(value);
|
||||
}
|
||||
|
||||
void Wrapper::VerticalScrollBarMinimum(double value)
|
||||
{
|
||||
_verticalScrollBar.Minimum(value);
|
||||
}
|
||||
|
||||
void Wrapper::HorizontalScrollBarMaximum(double value)
|
||||
{
|
||||
_horizontalScrollBar.Maximum(value);
|
||||
}
|
||||
|
||||
void Wrapper::VerticalScrollBarMaximum(double value)
|
||||
{
|
||||
_verticalScrollBar.Maximum(value);
|
||||
}
|
||||
|
||||
void Wrapper::HorizontalScrollBarViewportSize(double value)
|
||||
{
|
||||
_horizontalScrollBar.ViewportSize(value);
|
||||
}
|
||||
|
||||
void Wrapper::VerticalScrollBarViewportSize(double value)
|
||||
{
|
||||
_verticalScrollBar.ViewportSize(value);
|
||||
}
|
||||
|
||||
double Wrapper::HorizontalScrollBarValue()
|
||||
{
|
||||
return _horizontalScrollBar.Value();
|
||||
}
|
||||
|
||||
double Wrapper::VerticalScrollBarValue()
|
||||
{
|
||||
return _verticalScrollBar.Value();
|
||||
}
|
||||
|
||||
double Wrapper::HorizontalScrollBarMinimum()
|
||||
{
|
||||
return _horizontalScrollBar.Minimum();
|
||||
}
|
||||
|
||||
double Wrapper::VerticalScrollBarMinimum()
|
||||
{
|
||||
return _verticalScrollBar.Minimum();
|
||||
}
|
||||
|
||||
double Wrapper::HorizontalScrollBarMaximum()
|
||||
{
|
||||
return _horizontalScrollBar.Maximum();
|
||||
}
|
||||
|
||||
double Wrapper::VerticalScrollBarMaximum()
|
||||
{
|
||||
return _verticalScrollBar.Maximum();
|
||||
}
|
||||
|
||||
double Wrapper::HorizontalScrollBarViewportSize()
|
||||
{
|
||||
return _horizontalScrollBar.ViewportSize();
|
||||
}
|
||||
|
||||
double Wrapper::VerticalScrollBarViewportSize()
|
||||
{
|
||||
return _verticalScrollBar.ViewportSize();
|
||||
}
|
||||
|
||||
winrt::Windows::Foundation::IAsyncOperation<winrt::Windows::ApplicationModel::DataTransfer::DataPackageOperation> Wrapper::StartDragAsync(winrt::DUI::PointerPoint const &pointerPoint)
|
||||
{
|
||||
return _mouseCaptureElement.StartDragAsync(pointerPoint);
|
||||
}
|
||||
|
||||
void Wrapper::CreateGraphicsDevices()
|
||||
{
|
||||
// Todo: Is there any cleanup that needs to be done when the control is deleted or if the device gets re-created?
|
||||
|
||||
uint32_t creationFlags = D3D11_CREATE_DEVICE_BGRA_SUPPORT;
|
||||
|
||||
D3D_FEATURE_LEVEL featureLevels[] =
|
||||
{
|
||||
D3D_FEATURE_LEVEL_11_1,
|
||||
D3D_FEATURE_LEVEL_11_0,
|
||||
D3D_FEATURE_LEVEL_10_1,
|
||||
D3D_FEATURE_LEVEL_10_0,
|
||||
D3D_FEATURE_LEVEL_9_3,
|
||||
D3D_FEATURE_LEVEL_9_2,
|
||||
D3D_FEATURE_LEVEL_9_1,
|
||||
};
|
||||
|
||||
// Create the Direct3D device
|
||||
winrt::com_ptr<ID3D11Device> d3dDevice;
|
||||
D3D_FEATURE_LEVEL supportedFeatureLevel;
|
||||
winrt::check_hresult(D3D11CreateDevice(
|
||||
nullptr,
|
||||
D3D_DRIVER_TYPE_HARDWARE,
|
||||
0,
|
||||
creationFlags,
|
||||
featureLevels,
|
||||
ARRAYSIZE(featureLevels),
|
||||
D3D11_SDK_VERSION,
|
||||
d3dDevice.put(),
|
||||
&supportedFeatureLevel,
|
||||
nullptr));
|
||||
|
||||
// Get the Direct3D device.
|
||||
_dxgiDevice = d3dDevice.as<IDXGIDevice3>();
|
||||
|
||||
// Create the Direct2D device and a corresponding context
|
||||
winrt::com_ptr<ID2D1Device> d2dDevice;
|
||||
D2D1CreateDevice(_dxgiDevice.get(), nullptr, d2dDevice.put());
|
||||
|
||||
winrt::check_hresult(
|
||||
d2dDevice->CreateDeviceContext(
|
||||
D2D1_DEVICE_CONTEXT_OPTIONS_NONE,
|
||||
_d2dDeviceContext.put()));
|
||||
|
||||
// Associate the Direct2D device with the SurfaceImageSource
|
||||
SisNativeWithD2D()->SetDevice(d2dDevice.get());
|
||||
}
|
||||
}
|
|
@ -1,70 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
namespace WinUIEditor
|
||||
{
|
||||
class Wrapper
|
||||
{
|
||||
public:
|
||||
winrt::com_ptr<::IVirtualSurfaceImageSourceNative> VsisNative();
|
||||
void VsisNative(winrt::com_ptr<::IVirtualSurfaceImageSourceNative> const &value);
|
||||
winrt::com_ptr<::ISurfaceImageSourceNativeWithD2D> SisNativeWithD2D();
|
||||
winrt::com_ptr<::ID2D1DeviceContext> D2dDeviceContext();
|
||||
void TrimDxgiDevice();
|
||||
float LogicalDpi();
|
||||
void LogicalDpi(float value);
|
||||
int Width();
|
||||
void Width(int value);
|
||||
int Height();
|
||||
void Height(int value);
|
||||
|
||||
// Todo: Make abstract
|
||||
void SetMouseCapture(bool on);
|
||||
bool HaveMouseCapture();
|
||||
|
||||
// Todo: Move to separate XAML class
|
||||
void SetMouseCaptureElement(winrt::DUX::UIElement const &element);
|
||||
void SetCursor(winrt::DCUR cursor);
|
||||
|
||||
void SetScrollBars(winrt::DUX::Controls::Primitives::ScrollBar const &horizontalScrollBar, winrt::DUX::Controls::Primitives::ScrollBar const &verticalScrollBar);
|
||||
bool HasScrollBars();
|
||||
void HorizontalScrollBarValue(double value);
|
||||
void VerticalScrollBarValue(double value);
|
||||
void HorizontalScrollBarMinimum(double value);
|
||||
void VerticalScrollBarMinimum(double value);
|
||||
void HorizontalScrollBarMaximum(double value);
|
||||
void VerticalScrollBarMaximum(double value);
|
||||
void HorizontalScrollBarViewportSize(double value);
|
||||
void VerticalScrollBarViewportSize(double value);
|
||||
double HorizontalScrollBarValue();
|
||||
double VerticalScrollBarValue();
|
||||
double HorizontalScrollBarMinimum();
|
||||
double VerticalScrollBarMinimum();
|
||||
double HorizontalScrollBarMaximum();
|
||||
double VerticalScrollBarMaximum();
|
||||
double HorizontalScrollBarViewportSize();
|
||||
double VerticalScrollBarViewportSize();
|
||||
|
||||
winrt::Windows::Foundation::IAsyncOperation<winrt::Windows::ApplicationModel::DataTransfer::DataPackageOperation> StartDragAsync(winrt::DUI::PointerPoint const &pointerPoint);
|
||||
|
||||
void CreateGraphicsDevices();
|
||||
|
||||
// Font used for arrows in folding column markers. Stored here to allow retrieval from SurfaceD2D
|
||||
// Do not access outside of GetChevronFontFromSurface
|
||||
std::shared_ptr<Scintilla::Internal::Font> chevronFont{ nullptr };
|
||||
Scintilla::Internal::XYPOSITION chevronFontSize{ -1.0 };
|
||||
|
||||
private:
|
||||
winrt::DUX::Input::Pointer _lastPointer{ nullptr };
|
||||
winrt::DUX::UIElement _mouseCaptureElement{ nullptr };
|
||||
winrt::DUX::Controls::Primitives::ScrollBar _horizontalScrollBar{ nullptr };
|
||||
winrt::DUX::Controls::Primitives::ScrollBar _verticalScrollBar{ nullptr };
|
||||
bool _captured;
|
||||
winrt::com_ptr<IVirtualSurfaceImageSourceNative> _vsisNative{ nullptr };
|
||||
winrt::com_ptr<::ISurfaceImageSourceNativeWithD2D> _sisNativeWithD2D{ nullptr };
|
||||
winrt::com_ptr<::ID2D1DeviceContext> _d2dDeviceContext{ nullptr };
|
||||
winrt::com_ptr<::IDXGIDevice3> _dxgiDevice{ nullptr };
|
||||
float _logicalDpi;
|
||||
int _width;
|
||||
int _height;
|
||||
};
|
||||
}
|
|
@ -1,7 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Microsoft.Windows.CppWinRT" version="2.0.240111.5" targetFramework="native" />
|
||||
<package id="Microsoft.Windows.ImplementationLibrary" version="1.0.240122.1" targetFramework="native" />
|
||||
<package id="Microsoft.Windows.SDK.BuildTools" version="10.0.22621.3233" targetFramework="native" />
|
||||
<package id="Microsoft.WindowsAppSDK" version="1.5.240227000" targetFramework="native" />
|
||||
</packages>
|
|
@ -1 +0,0 @@
|
|||
#include "pch.h"
|
|
@ -1,144 +0,0 @@
|
|||
#pragma once
|
||||
#include <unknwn.h>
|
||||
#include <winrt/Windows.Foundation.h>
|
||||
#include <winrt/Windows.Foundation.Collections.h>
|
||||
#include <winrt/Windows.Foundation.Metadata.h>
|
||||
#include <winrt/Windows.Graphics.Display.h>
|
||||
#include <winrt/Windows.System.h>
|
||||
#include <winrt/Windows.Storage.Streams.h>
|
||||
#include <winrt/Windows.UI.Text.Core.h>
|
||||
#include <winrt/Windows.UI.Core.h>
|
||||
#include <winrt/Windows.ApplicationModel.DataTransfer.h>
|
||||
#include <winrt/Windows.UI.Xaml.Interop.h>
|
||||
#include <winrt/Windows.UI.Popups.h>
|
||||
#include <winrt/Windows.UI.ViewManagement.h>
|
||||
#ifdef WINUI3
|
||||
#include <winrt/Microsoft.UI.Input.h>
|
||||
#include <winrt/Microsoft.UI.Composition.h>
|
||||
#include <winrt/Microsoft.UI.Xaml.h>
|
||||
#include <winrt/Microsoft.UI.Xaml.Automation.Peers.h>
|
||||
#include <winrt/Microsoft.UI.Xaml.Automation.Provider.h>
|
||||
#include <winrt/Microsoft.UI.Xaml.Automation.Text.h>
|
||||
#include <winrt/Microsoft.UI.Xaml.Controls.h>
|
||||
#include <winrt/Microsoft.UI.Xaml.Input.h>
|
||||
#include <winrt/Microsoft.UI.Xaml.Controls.Primitives.h>
|
||||
#include <winrt/Microsoft.UI.Xaml.Data.h>
|
||||
#include <winrt/Microsoft.UI.Xaml.Markup.h>
|
||||
#include <winrt/Microsoft.UI.Xaml.Navigation.h>
|
||||
#include <winrt/Microsoft.UI.Dispatching.h>
|
||||
#include <winrt/Microsoft.UI.Xaml.Media.Imaging.h>
|
||||
|
||||
#include <microsoft.ui.xaml.media.dxinterop.h>
|
||||
#include <microsoft.ui.xaml.window.h>
|
||||
|
||||
#include <wil/cppwinrt_helpers.h>
|
||||
|
||||
#define DUX Microsoft::UI::Xaml
|
||||
#define DUXC Microsoft::UI::Xaml::Controls
|
||||
#define DUI Microsoft::UI::Input
|
||||
#define DCUR Microsoft::UI::Input::InputSystemCursorShape
|
||||
#define DUD Microsoft::UI::Dispatching
|
||||
#else
|
||||
#include <winrt/Windows.UI.Input.h>
|
||||
#include <winrt/Windows.UI.Composition.h>
|
||||
#include <winrt/Windows.UI.Xaml.h>
|
||||
#include <winrt/Windows.UI.Xaml.Automation.Peers.h>
|
||||
#include <winrt/Windows.UI.Xaml.Automation.Provider.h>
|
||||
#include <winrt/Windows.UI.Xaml.Automation.Text.h>
|
||||
#include <winrt/Windows.UI.Xaml.Controls.h>
|
||||
#include <winrt/Windows.UI.Xaml.Input.h>
|
||||
#include <winrt/Windows.UI.Xaml.Controls.Primitives.h>
|
||||
#include <winrt/Windows.UI.Xaml.Data.h>
|
||||
#include <winrt/Windows.UI.Xaml.Markup.h>
|
||||
#include <winrt/Windows.UI.Xaml.Navigation.h>
|
||||
#include <winrt/Windows.UI.Xaml.Media.Imaging.h>
|
||||
#include <windows.ui.xaml.media.dxinterop.h>
|
||||
|
||||
#define DUX Windows::UI::Xaml
|
||||
#define DUXC Windows::UI::Xaml::Controls
|
||||
#define DUI Windows::UI::Input
|
||||
#define DCUR Windows::UI::Core::CoreCursorType
|
||||
#define DUD Windows::System
|
||||
#endif
|
||||
|
||||
#include <d3d11_4.h>
|
||||
#include <d2d1_1.h>
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdlib>
|
||||
#include <cstdint>
|
||||
#include <cassert>
|
||||
#include <cstring>
|
||||
#include <cstdio>
|
||||
#include <cmath>
|
||||
#include <climits>
|
||||
|
||||
#include <stdexcept>
|
||||
#include <new>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <queue>
|
||||
#include <optional>
|
||||
#include <algorithm>
|
||||
#include <memory>
|
||||
#include <chrono>
|
||||
#include <mutex>
|
||||
#include <functional>
|
||||
|
||||
#include <olectl.h>
|
||||
#include <msctf.h>
|
||||
#include <appmodel.h>
|
||||
|
||||
#include "ScintillaTypes.h"
|
||||
#include "ScintillaMessages.h"
|
||||
#include "ScintillaStructures.h"
|
||||
#include "ILoader.h"
|
||||
#include "ILexer.h"
|
||||
|
||||
#include "Debugging.h"
|
||||
#include "Geometry.h"
|
||||
#include "Platform.h"
|
||||
|
||||
#include "CharacterCategoryMap.h"
|
||||
#include "Position.h"
|
||||
#include "UniqueString.h"
|
||||
#include "SplitVector.h"
|
||||
#include "Partitioning.h"
|
||||
#include "RunStyles.h"
|
||||
#include "ContractionState.h"
|
||||
#include "CellBuffer.h"
|
||||
#include "CallTip.h"
|
||||
#include "KeyMap.h"
|
||||
#include "Indicator.h"
|
||||
#include "LineMarker.h"
|
||||
#include "Style.h"
|
||||
#include "ViewStyle.h"
|
||||
#include "CharClassify.h"
|
||||
#include "Decoration.h"
|
||||
#include "CaseFolder.h"
|
||||
#include "Document.h"
|
||||
#include "CaseConvert.h"
|
||||
#include "UniConversion.h"
|
||||
#include "Selection.h"
|
||||
#include "PositionCache.h"
|
||||
#include "EditModel.h"
|
||||
#include "MarginView.h"
|
||||
#include "EditView.h"
|
||||
#include "Editor.h"
|
||||
#include "ElapsedPeriod.h"
|
||||
|
||||
#include "AutoComplete.h"
|
||||
#include "ScintillaBase.h"
|
||||
|
||||
#include "Scintilla.h"
|
||||
|
||||
#include "Lexilla.h"
|
||||
#include "SciLexer.h"
|
||||
|
||||
#ifndef USE_DUMMY_PAGE
|
||||
#include "ControlIncludes.h"
|
||||
#endif
|
|
@ -1,49 +0,0 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Import Project="..\ChangeBuild.props" />
|
||||
<Import Project="..\DualBuild.props" />
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0-windows10.0.17763.0</TargetFramework>
|
||||
<Platform>AnyCPU</Platform>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<CsWinRTIncludes Condition="$(WinUIEditorUseWinUI3)">WinUIEditor</CsWinRTIncludes>
|
||||
<CsWinRTGeneratedFilesDir>$(OutDir)</CsWinRTGeneratedFilesDir>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<GeneratedNugetDir>.\nuget\</GeneratedNugetDir>
|
||||
<NuspecFile Condition="$(WinUIEditorUseWinUI3)">$(GeneratedNugetDir)WinUIEditorWinUI3.nuspec</NuspecFile>
|
||||
<NuspecFile Condition="!$(WinUIEditorUseWinUI3)">$(GeneratedNugetDir)WinUIEditorUWP.nuspec</NuspecFile>
|
||||
<OutputPath>$(GeneratedNugetDir)</OutputPath>
|
||||
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Include="nuget\WinUIEditor.targets" />
|
||||
<None Include="nuget\WinUIEditorWinUI3.nuspec" />
|
||||
<None Include="nuget\WinUIEditorUWP.nuspec" />
|
||||
<None Include="nuget\WinUIEditor.xml" />
|
||||
<None Include="nuget\WinUIEditorCsWinRT.xml" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Windows.CsWinRT" Version="2.0.7" />
|
||||
<PackageReference Condition="$(WinUIEditorUseWinUI3)" Include="Microsoft.WindowsAppSDK" Version="1.5.240227000" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<CsWinRTInputs Condition="$(WinUIEditorUseWinUI3)" Include="..\_buildWinUI3\x64\Release\WinUIEditor\bin\WinUIEditor\WinUIEditor.winmd" />
|
||||
<CsWinRTInputs Condition="!$(WinUIEditorUseWinUI3)" Include="..\_buildUwp\x64\Release\WinUIEditor\bin\WinUIEditor\WinUIEditor.winmd" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\WinUIEditor\WinUIEditor.vcxproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<!-- Workaround for MSB3271 error on processor architecture mismatch -->
|
||||
<ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch>None</ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch>
|
||||
</PropertyGroup>
|
||||
</Project>
|
Loading…
Reference in New Issue
Block a user