引入一个外部editor试一试
This commit is contained in:
parent
0ddd8fdbc7
commit
5a48d4041d
3
.filenesting.json
Normal file
3
.filenesting.json
Normal file
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"help":"https://go.microsoft.com/fwlink/?linkid=866610"
|
||||
}
|
|
@ -5,6 +5,8 @@ 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}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
|
|
|
@ -153,9 +153,9 @@ public partial class App : Microsoft.UI.Xaml.Application
|
|||
{
|
||||
//MainWindow.Activate();
|
||||
//MainWindow = new MainWindow();
|
||||
var editor=new Editor.EditorWin();
|
||||
editor.Activate();
|
||||
//await App.GetService<IActivationService>().ActivateAsync(args);
|
||||
//new Editor.EditorWin().Activate();
|
||||
MainWindow = new MainWindow();
|
||||
await App.GetService<IActivationService>().ActivateAsync(args);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
14
RustTools/Assets/image/folder_20.svg
Normal file
14
RustTools/Assets/image/folder_20.svg
Normal file
|
@ -0,0 +1,14 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 26.5.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [
|
||||
<!ENTITY st0 "fill:#5AC8FA;">
|
||||
]>
|
||||
<svg version="1.1" id="图层_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 50 50" style="enable-background:new 0 0 50 50;" xml:space="preserve">
|
||||
<path style="&st0;" d="M22.8,22.5h10c1.2,0,2.2,1.1,2.2,2.5v7.5c0,1.4-1,2.5-2.2,2.5h-10c-1.2,0-2.2-1.1-2.2-2.5V25
|
||||
C20.6,23.6,21.6,22.5,22.8,22.5z"/>
|
||||
<path d="M17.2,16.3c-0.7,0-1.1,0.6-1.1,1.2v15c0,0.8,0.4,1.2,1.1,1.2h15.6c0.7,0,1.1-0.5,1.1-1.2V20c0-0.8-0.6-1.3-1.1-1.3h-7.3
|
||||
c-0.6,0-1.1-0.2-1.6-0.8l-1.2-1.4c-0.2-0.3-0.6-0.4-0.8-0.4H17.2z M17.2,15h4.7c0.6,0,1.1,0.2,1.6,0.8l1.2,1.4
|
||||
c0.2,0.3,0.4,0.4,0.8,0.4h7.3c1.2,0,2.2,1.1,2.2,2.5v12.5c0,1.4-1,2.5-2.2,2.5H17.2C16,35,15,33.9,15,32.5v-15
|
||||
C15,16.1,16,15,17.2,15z"/>
|
||||
</svg>
|
After Width: | Height: | Size: 1005 B |
183
RustTools/Editor/EditorLoad.cs
Normal file
183
RustTools/Editor/EditorLoad.cs
Normal file
|
@ -0,0 +1,183 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Windows.ApplicationModel.Payments;
|
||||
|
||||
namespace RustTools.Editor;
|
||||
public class EditorLoad
|
||||
{
|
||||
/// <summary>
|
||||
/// 加载所有的文件 Debug 用
|
||||
/// </summary>
|
||||
/// <param name="directoryInfo"></param>
|
||||
/// <param name="parentItem"></param>
|
||||
private void LoadDirectory(DirectoryInfo directoryInfo, ExplorerItem parentItem)
|
||||
{
|
||||
// 获取当前目录中的所有子目录
|
||||
var directories = directoryInfo.GetDirectories();
|
||||
foreach (var directory in directories)
|
||||
{
|
||||
// 创建新的 ExplorerItem 代表当前子目录
|
||||
var folderItem = new ExplorerItem
|
||||
{
|
||||
Name = directory.Name,
|
||||
Type = ExplorerItem.ExplorerItemType.Folder
|
||||
};
|
||||
|
||||
// 将这个目录项添加到父级的 Children 集合中
|
||||
parentItem.Children.Add(folderItem);
|
||||
|
||||
// 递归调用,继续加载子目录中的内容
|
||||
LoadDirectory(directory, folderItem);
|
||||
}
|
||||
|
||||
// 获取当前目录中的所有文件
|
||||
var files = directoryInfo.GetFiles();
|
||||
foreach (var file in files)
|
||||
{
|
||||
// 创建新的 ExplorerItem 代表当前文件
|
||||
var fileItem = new ExplorerItem
|
||||
{
|
||||
Name = file.Name,
|
||||
Type = ExplorerItem.ExplorerItemType.File
|
||||
};
|
||||
|
||||
// 将这个文件项添加到父级的 Children 集合中
|
||||
parentItem.Children.Add(fileItem);
|
||||
}
|
||||
}
|
||||
|
||||
public ObservableCollection<ExplorerItem> GetData(string dir)
|
||||
{
|
||||
var list = new ObservableCollection<ExplorerItem>();
|
||||
|
||||
var directoryInfos = new DirectoryInfo(dir);
|
||||
|
||||
// 创建根节点 ExplorerItem 根节点不显示防止用户删除
|
||||
//var rootItem = new ExplorerItem
|
||||
//{
|
||||
// Name = directoryInfos.Name,
|
||||
// Dir = directoryInfos.FullName,
|
||||
// Type = ExplorerItem.ExplorerItemType.Folder,
|
||||
//};
|
||||
//LoadDirectory(directoryInfos,rootItem);
|
||||
foreach (var file in directoryInfos.GetDirectories()) {
|
||||
var explorerItem = new ExplorerItem()
|
||||
{
|
||||
Name = file.Name,
|
||||
Dir = file.FullName,
|
||||
Type = ExplorerItem.ExplorerItemType.Folder
|
||||
};
|
||||
list.Add(explorerItem);
|
||||
foreach (var a in file.GetDirectories())
|
||||
{
|
||||
explorerItem.Children.Add(new ExplorerItem()
|
||||
{
|
||||
Name = a.Name,
|
||||
Dir = a.FullName,
|
||||
Type = ExplorerItem.ExplorerItemType.Folder
|
||||
});
|
||||
}
|
||||
foreach (var a in file.GetFiles())
|
||||
{
|
||||
explorerItem.Children.Add(new ExplorerItem()
|
||||
{
|
||||
Name = a.Name,
|
||||
Dir = a.FullName,
|
||||
Type = ExplorerItem.ExplorerItemType.File
|
||||
});
|
||||
}
|
||||
}
|
||||
foreach (var file in directoryInfos.GetFiles())
|
||||
{
|
||||
list.Add(new ExplorerItem()
|
||||
{
|
||||
Name = file.Name,
|
||||
Dir = file.FullName,
|
||||
Type = ExplorerItem.ExplorerItemType.File
|
||||
});
|
||||
}
|
||||
return list;
|
||||
ExplorerItem folder1 = new ExplorerItem()
|
||||
{
|
||||
Name = "Work Documents",
|
||||
Type = ExplorerItem.ExplorerItemType.Folder,
|
||||
Children =
|
||||
{
|
||||
new ExplorerItem()
|
||||
{
|
||||
Name = "Functional Specifications",
|
||||
Type = ExplorerItem.ExplorerItemType.Folder,
|
||||
Children =
|
||||
{
|
||||
new ExplorerItem()
|
||||
{
|
||||
Name = "TreeView spec",
|
||||
Type = ExplorerItem.ExplorerItemType.File,
|
||||
}
|
||||
}
|
||||
},
|
||||
new ExplorerItem()
|
||||
{
|
||||
Name = "Feature Schedule",
|
||||
Type = ExplorerItem.ExplorerItemType.File,
|
||||
},
|
||||
new ExplorerItem()
|
||||
{
|
||||
Name = "Overall Project Plan",
|
||||
Type = ExplorerItem.ExplorerItemType.File,
|
||||
},
|
||||
new ExplorerItem()
|
||||
{
|
||||
Name = "Feature Resources Allocation",
|
||||
Type = ExplorerItem.ExplorerItemType.File,
|
||||
}
|
||||
}
|
||||
};
|
||||
ExplorerItem folder2 = new ExplorerItem()
|
||||
{
|
||||
Name = "Personal Folder",
|
||||
Type = ExplorerItem.ExplorerItemType.Folder,
|
||||
Children =
|
||||
{
|
||||
new ExplorerItem()
|
||||
{
|
||||
Name = "Home Remodel Folder",
|
||||
Type = ExplorerItem.ExplorerItemType.Folder,
|
||||
Children =
|
||||
{
|
||||
new ExplorerItem()
|
||||
{
|
||||
Name = "Contractor Contact Info",
|
||||
Type = ExplorerItem.ExplorerItemType.File,
|
||||
},
|
||||
new ExplorerItem()
|
||||
{
|
||||
Name = "Paint Color Scheme",
|
||||
Type = ExplorerItem.ExplorerItemType.File,
|
||||
},
|
||||
new ExplorerItem()
|
||||
{
|
||||
Name = "Flooring Woodgrain type",
|
||||
Type = ExplorerItem.ExplorerItemType.File,
|
||||
},
|
||||
new ExplorerItem()
|
||||
{
|
||||
Name = "Kitchen Cabinet Style",
|
||||
Type = ExplorerItem.ExplorerItemType.File,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
list.Add(folder1);
|
||||
list.Add(folder2);
|
||||
return list;
|
||||
}
|
||||
}
|
|
@ -3,6 +3,7 @@
|
|||
x:Class="RustTools.Editor.EditorWin"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:controlpages="using:RustTools.Editor"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="using:RustTools"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
|
@ -11,14 +12,91 @@
|
|||
MinHeight="500"
|
||||
mc:Ignorable="d">
|
||||
|
||||
<Grid Name="grid">
|
||||
<Grid Padding="9" Visibility="Visible">
|
||||
<Page Name="page">
|
||||
<Page.Resources>
|
||||
<DataTemplate x:Key="FolderTemplate">
|
||||
<TreeViewItem
|
||||
AutomationProperties.Name="{Binding Name}"
|
||||
IsExpanded="False"
|
||||
ItemsSource="{Binding Children}">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<FontIcon Glyph="" />
|
||||
<TextBlock Margin="0,0,10,0" />
|
||||
<TextBlock Text="{Binding Name}" />
|
||||
</StackPanel>
|
||||
</TreeViewItem>
|
||||
</DataTemplate>
|
||||
|
||||
<DataTemplate x:Key="FileTemplate">
|
||||
<TreeViewItem AutomationProperties.Name="{Binding Name}">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<FontIcon Glyph="" />
|
||||
<TextBlock Margin="0,0,10,0" />
|
||||
<TextBlock Text="{Binding Name}" />
|
||||
</StackPanel>
|
||||
</TreeViewItem>
|
||||
</DataTemplate>
|
||||
<controlpages:ExplorerItemTemplateSelector
|
||||
x:Key="ExplorerItemTemplateSelector"
|
||||
FileTemplate="{StaticResource FileTemplate}"
|
||||
FolderTemplate="{StaticResource FolderTemplate}" />
|
||||
|
||||
<TabViewItem x:Key="FileTab">
|
||||
<TextBox
|
||||
x:Name="MyTextBox"
|
||||
Height="200"
|
||||
AcceptsReturn="True"
|
||||
TextWrapping="Wrap" />
|
||||
</TabViewItem>
|
||||
</Page.Resources>
|
||||
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Grid.Column="0" Text="这是模组名称" />
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid
|
||||
Grid.Row="0"
|
||||
Padding="9"
|
||||
Visibility="Visible">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock
|
||||
Name="TitleText"
|
||||
Grid.Column="0"
|
||||
Margin="16,0,0,0" />
|
||||
</Grid>
|
||||
<ScrollViewer
|
||||
Grid.Row="2"
|
||||
Grid.Column="0"
|
||||
Width="300"
|
||||
Margin="0,9,0,6"
|
||||
Padding="0,0,16,0"
|
||||
HorizontalScrollBarVisibility="Visible"
|
||||
HorizontalScrollMode="Auto"
|
||||
IsHorizontalRailEnabled="True"
|
||||
IsHorizontalScrollChainingEnabled="True">
|
||||
|
||||
<TreeView
|
||||
Name="treeView"
|
||||
Grid.Row="2"
|
||||
Grid.Column="0"
|
||||
ItemInvoked="TreeView_ItemInvoked"
|
||||
ItemTemplateSelector="{StaticResource ExplorerItemTemplateSelector}"
|
||||
ItemsSource="{x:Bind DataSource}"
|
||||
KeyDown="treeView_KeyDown"
|
||||
KeyUp="treeView_KeyUp"
|
||||
SelectionMode="Single" />
|
||||
</ScrollViewer>
|
||||
|
||||
<Grid Grid.Row="1" Grid.Column="1" />
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Page>
|
||||
</windowex:WindowEx>
|
||||
|
|
|
@ -1,12 +1,26 @@
|
|||
using System.Collections.ObjectModel;
|
||||
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;
|
||||
|
@ -17,7 +31,8 @@ namespace RustTools.Editor;
|
|||
/// </summary>
|
||||
public sealed partial class EditorWin : WindowEx
|
||||
{
|
||||
|
||||
//目录列表
|
||||
public ObservableCollection<ExplorerItem> DataSource=new ();
|
||||
private Microsoft.UI.Windowing.AppWindow? app;
|
||||
public EditorWin()
|
||||
{
|
||||
|
@ -28,27 +43,25 @@ public sealed partial class EditorWin : WindowEx
|
|||
if (frame != null)
|
||||
{
|
||||
gj.UpdateTitleBar(this, frame.ActualTheme);
|
||||
grid.RequestedTheme = frame.ActualTheme;
|
||||
page.RequestedTheme = frame.ActualTheme;
|
||||
}
|
||||
|
||||
//WindowManager.Get(this).IsMinimizable = false;
|
||||
//WindowManager.Get(this).IsMaximizable = false;
|
||||
//WindowManager.Get(this).IsResizable = false;
|
||||
//WindowManager.Get(this).IsAlwaysOnTop = false;
|
||||
//WindowManager.Get(this).IsTitleBarVisible = false;
|
||||
|
||||
|
||||
//app = GetAppWindowForCurrentWindow();
|
||||
//app.Closing += OnClosing;
|
||||
//Closed += EditorWin_Closed;
|
||||
|
||||
var directoryInfo = new DirectoryInfo("D:\\steam\\steamapps\\common\\Rusted Warfare\\mods\\units\\赤道·联合进攻0.9补丁版0.2");
|
||||
DataSource = new EditorLoad().GetData(directoryInfo.FullName);
|
||||
Title=directoryInfo.Name;
|
||||
TitleText.Text = directoryInfo.Name;
|
||||
Closed += EditorWin_Closed;
|
||||
}
|
||||
|
||||
private async Task SaveDataAsync()
|
||||
{
|
||||
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.
|
||||
|
||||
}
|
||||
|
||||
//用户有没有保存
|
||||
private bool IsSave = false;
|
||||
private ContentDialog? ClosedDialog;
|
||||
|
@ -65,7 +78,7 @@ public sealed partial class EditorWin : WindowEx
|
|||
// 显示一个对话框,告知用户窗口不能关闭
|
||||
ClosedDialog = new ContentDialog
|
||||
{
|
||||
XamlRoot = grid.XamlRoot,
|
||||
XamlRoot = page.XamlRoot,
|
||||
Title = "警告",
|
||||
Content = "你还有未保存的文件在编译器中。",
|
||||
PrimaryButtonText = "保存关闭",
|
||||
|
@ -96,4 +109,107 @@ public sealed partial class EditorWin : WindowEx
|
|||
var myWndId = Win32Interop.GetWindowIdFromWindow(hWnd);
|
||||
return Microsoft.UI.Windowing.AppWindow.GetFromWindowId(myWndId);
|
||||
}
|
||||
private void TreeView_ItemInvoked(TreeView sender, TreeViewItemInvokedEventArgs args)
|
||||
{
|
||||
// 获取当前选中的项
|
||||
// 获取被点击的项
|
||||
var invokedItem = args.InvokedItem;
|
||||
// 检查是否重复选择
|
||||
if (sender.SelectedItem is ExplorerItem selectedItem && invokedItem != null && selectedItem == invokedItem)
|
||||
{
|
||||
// 如果是同一个项,直接返回,不进行进一步处理
|
||||
return;
|
||||
}
|
||||
if (invokedItem is not ExplorerItem explorerItem)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (explorerItem.Type == ExplorerItem.ExplorerItemType.Folder)
|
||||
{
|
||||
var directoryInfo = new DirectoryInfo(explorerItem.Dir);
|
||||
}
|
||||
}
|
||||
|
||||
private void TreeView_DragItemsStarting(TreeView sender, TreeViewDragItemsStartingEventArgs args)
|
||||
{
|
||||
args.Cancel = true;
|
||||
// 设置拖动的数据
|
||||
var items = args.Items.Cast<ExplorerItem>();
|
||||
var v = items.ToList()[0];
|
||||
args.Data.SetData("TreeViewItems", v.Dir);
|
||||
args.Data.RequestedOperation = DataPackageOperation.Move;
|
||||
}
|
||||
//在拖动项目悬停在 TreeView 上时,为放置操作提供视觉反馈。
|
||||
private void TreeView_DragOver(object sender, DragEventArgs e)
|
||||
{
|
||||
// 检查是否存在 "TreeViewItems" 数据
|
||||
gj.sc("aaaaaa");
|
||||
if (e.DataView.Contains("TreeViewItems"))
|
||||
{
|
||||
e.AcceptedOperation = DataPackageOperation.Move; // 允许将文件夹拖放
|
||||
}
|
||||
else
|
||||
{
|
||||
gj.sc("No");
|
||||
e.AcceptedOperation = DataPackageOperation.None; // 不接受拖放操作
|
||||
}
|
||||
}
|
||||
//处理项目放置的逻辑,将文件或文件夹移动到新的位置。
|
||||
private async void TreeView_Drop(object sender, DragEventArgs e)
|
||||
{
|
||||
gj.sc(e);
|
||||
// 获取拖动的数据
|
||||
if (e.DataView.Contains("TreeViewItems"))
|
||||
{
|
||||
// 确保数据不为空
|
||||
if (await e.DataView.GetDataAsync("TreeViewItems") is string Dir)
|
||||
{
|
||||
gj.sc(Dir);
|
||||
// 获取放置位置的 TreeViewItem
|
||||
var treeView = sender as TreeView;
|
||||
ExplorerItem v = treeView.DataContext is ExplorerItem;
|
||||
//var dropPosition = e.GetPosition(treeView);
|
||||
//data.Name
|
||||
gj.sc(v.Name);
|
||||
}
|
||||
}
|
||||
}
|
||||
private IList<object> initialSelectedItems;
|
||||
/// <summary>
|
||||
/// 如果是shift则开启多选状态
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="e"></param>
|
||||
private void treeView_KeyDown(object sender, KeyRoutedEventArgs e)
|
||||
{
|
||||
// 检查是否按下了Shift键
|
||||
if (e.Key == Windows.System.VirtualKey.Shift)
|
||||
{
|
||||
gj.sc(e.Key);
|
||||
// 启用多选模式
|
||||
treeView.SelectionMode = TreeViewSelectionMode.Multiple;
|
||||
}
|
||||
}
|
||||
private void treeView_KeyUp(object sender, KeyRoutedEventArgs e)
|
||||
{
|
||||
// 检查是否松开了Shift键
|
||||
if (e.Key == Windows.System.VirtualKey.Shift)
|
||||
{ // 清除当前多选模式下选中的项目
|
||||
var selectedItems = treeView.SelectedItems.ToList();
|
||||
foreach (var item in selectedItems)
|
||||
{
|
||||
treeView.SelectedItems.Remove(item);
|
||||
}
|
||||
gj.sc("取消");
|
||||
// 取消多选模式
|
||||
treeView.SelectionMode = TreeViewSelectionMode.Single;
|
||||
//treeView.SelectedItems.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
private void tabView_TabCloseRequested(TabView sender, TabViewTabCloseRequestedEventArgs args)
|
||||
{
|
||||
sender.TabItems.Remove(args.Tab);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
88
RustTools/Editor/ExplorerItemTemplateSelector.cs
Normal file
88
RustTools/Editor/ExplorerItemTemplateSelector.cs
Normal file
|
@ -0,0 +1,88 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.UI.Xaml.Controls;
|
||||
using Microsoft.UI.Xaml;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.ComponentModel;
|
||||
|
||||
namespace RustTools.Editor;
|
||||
public class ExplorerItemTemplateSelector : DataTemplateSelector
|
||||
{
|
||||
public DataTemplate FolderTemplate
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
public DataTemplate FileTemplate
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
|
||||
protected override DataTemplate SelectTemplateCore(object item)
|
||||
{
|
||||
var explorerItem = (ExplorerItem)item;
|
||||
return explorerItem.Type == ExplorerItem.ExplorerItemType.Folder ? FolderTemplate : FileTemplate;
|
||||
}
|
||||
}
|
||||
public class ExplorerItem : INotifyPropertyChanged
|
||||
{
|
||||
public enum ExplorerItemType { Folder, File };
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
public string Name
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
public ExplorerItemType Type
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
public string Dir
|
||||
{
|
||||
get;set;
|
||||
}
|
||||
private ObservableCollection<ExplorerItem> m_children;
|
||||
public ObservableCollection<ExplorerItem> Children
|
||||
{
|
||||
get
|
||||
{
|
||||
if (m_children == null)
|
||||
{
|
||||
m_children = new ObservableCollection<ExplorerItem>();
|
||||
}
|
||||
return m_children;
|
||||
}
|
||||
set
|
||||
{
|
||||
m_children = value;
|
||||
}
|
||||
}
|
||||
|
||||
private bool m_isExpanded;
|
||||
public bool IsExpanded
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_isExpanded;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (m_isExpanded != value)
|
||||
{
|
||||
m_isExpanded = value;
|
||||
NotifyPropertyChanged("IsExpanded");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void NotifyPropertyChanged(string propertyName)
|
||||
{
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
||||
}
|
||||
|
||||
public static implicit operator ExplorerItem(bool v)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
|
@ -19,7 +19,6 @@
|
|||
<PackageReadmeFile>README.md</PackageReadmeFile>
|
||||
<DefaultLanguage>zh-cn</DefaultLanguage>
|
||||
|
||||
|
||||
<GenerateAppInstallerFile>False</GenerateAppInstallerFile>
|
||||
<AppxPackageSigningEnabled>True</AppxPackageSigningEnabled>
|
||||
<PackageCertificateThumbprint>3386EC79D3BB9691D0A8DA634167500B242E109D</PackageCertificateThumbprint>
|
||||
|
@ -28,7 +27,6 @@
|
|||
<AppxSymbolPackageEnabled>False</AppxSymbolPackageEnabled>
|
||||
<GenerateTestArtifacts>True</GenerateTestArtifacts>
|
||||
<AppxBundle>Never</AppxBundle>
|
||||
<AppInstallerUri>C:\\RustTools</AppInstallerUri>
|
||||
<AppxPackageDir>D:\RustTools</AppxPackageDir>
|
||||
</PropertyGroup>
|
||||
|
||||
|
@ -46,46 +44,19 @@
|
|||
<PackageReference Include="RestSharp" Version="111.4.0" />
|
||||
<PackageReference Include="System.Management" Version="8.0.0" />
|
||||
<PackageReference Include="WinUIEx" Version="2.3.2" />
|
||||
|
||||
<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" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="Assets\**">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Page Update="Views\ModulePage.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Update="Styles\TitleSubtitleControlStyle.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Update="Styles\ItemView.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Update="WindowUI\ImportModule.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Update="Views\ConcernPage.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Update="Views\UserPage.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Update="Views\RankingPage.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Update="Views\HomePage.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
<ItemGroup Condition="'$(DisableMsixProjectCapabilityAddedByProject)'!='true' and '$(EnableMsixTooling)'=='true'">
|
||||
<ProjectCapability Include="Msix" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
<PropertyGroup Condition="'$(DisableHasPackageAndPublishMenuAddedByProject)'!='true' and '$(EnableMsixTooling)'=='true'">
|
||||
<HasPackageAndPublishMenu>true</HasPackageAndPublishMenu>
|
||||
</PropertyGroup>
|
||||
|
||||
|
||||
</Project>
|
|
@ -37,6 +37,7 @@ public class DataObject
|
|||
get; set;
|
||||
}
|
||||
|
||||
#pragma warning disable CS8765 // 参数类型的为 Null 性与重写成员不匹配(可能是由于为 Null 性特性)。
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (obj is DataObject other)
|
||||
|
@ -111,7 +112,8 @@ public sealed partial class ModulePage : Page
|
|||
}
|
||||
private void Button_Delete(object sender, RoutedEventArgs e)
|
||||
{
|
||||
var menuItem = sender as ButtonBase;
|
||||
var menuItem = sender as Control;
|
||||
gj.sc(menuItem);
|
||||
if (menuItem != null)
|
||||
{
|
||||
if (menuItem.DataContext is DataObject folderItem)
|
||||
|
|
1
UseWinUI3.txt
Normal file
1
UseWinUI3.txt
Normal file
|
@ -0,0 +1 @@
|
|||
true
|
336
WinUIEditor/CodeEditorControl.cpp
Normal file
336
WinUIEditor/CodeEditorControl.cpp
Normal file
|
@ -0,0 +1,336 @@
|
|||
#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);
|
||||
}
|
||||
}
|
75
WinUIEditor/CodeEditorControl.h
Normal file
75
WinUIEditor/CodeEditorControl.h
Normal file
|
@ -0,0 +1,75 @@
|
|||
#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>
|
||||
{
|
||||
};
|
||||
}
|
19
WinUIEditor/CodeEditorControl.idl
Normal file
19
WinUIEditor/CodeEditorControl.idl
Normal file
|
@ -0,0 +1,19 @@
|
|||
#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();
|
||||
}
|
||||
}
|
669
WinUIEditor/CodeEditorHandler.SciEdit.cpp
Normal file
669
WinUIEditor/CodeEditorHandler.SciEdit.cpp
Normal file
|
@ -0,0 +1,669 @@
|
|||
// 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);
|
||||
}
|
||||
}
|
||||
}
|
91
WinUIEditor/CodeEditorHandler.SciEdit.h
Normal file
91
WinUIEditor/CodeEditorHandler.SciEdit.h
Normal file
|
@ -0,0 +1,91 @@
|
|||
// 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);
|
||||
};
|
||||
}
|
395
WinUIEditor/CodeEditorHandler.SyntaxHighlighting.cpp
Normal file
395
WinUIEditor/CodeEditorHandler.SyntaxHighlighting.cpp
Normal file
|
@ -0,0 +1,395 @@
|
|||
#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();
|
||||
}
|
||||
}
|
||||
}
|
557
WinUIEditor/CodeEditorHandler.cpp
Normal file
557
WinUIEditor/CodeEditorHandler.cpp
Normal file
|
@ -0,0 +1,557 @@
|
|||
#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;
|
||||
}
|
||||
}
|
102
WinUIEditor/CodeEditorHandler.h
Normal file
102
WinUIEditor/CodeEditorHandler.h
Normal file
|
@ -0,0 +1,102 @@
|
|||
#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);
|
||||
};
|
||||
}
|
4
WinUIEditor/ControlIncludes.h
Normal file
4
WinUIEditor/ControlIncludes.h
Normal file
|
@ -0,0 +1,4 @@
|
|||
#pragma once
|
||||
|
||||
#include "EditorBaseControl.h"
|
||||
#include "CodeEditorControl.h"
|
213
WinUIEditor/DarkPlus.h
Normal file
213
WinUIEditor/DarkPlus.h
Normal file
|
@ -0,0 +1,213 @@
|
|||
// 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);
|
||||
}
|
||||
}
|
||||
}
|
5
WinUIEditor/Defines.idl
Normal file
5
WinUIEditor/Defines.idl
Normal file
|
@ -0,0 +1,5 @@
|
|||
#ifdef WINUI3
|
||||
#define DUX Microsoft.UI.Xaml
|
||||
#else
|
||||
#define DUX Windows.UI.Xaml
|
||||
#endif
|
13
WinUIEditor/DummyPage.cpp
Normal file
13
WinUIEditor/DummyPage.cpp
Normal file
|
@ -0,0 +1,13 @@
|
|||
#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
|
19
WinUIEditor/DummyPage.h
Normal file
19
WinUIEditor/DummyPage.h
Normal file
|
@ -0,0 +1,19 @@
|
|||
#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>
|
||||
{
|
||||
};
|
||||
}
|
11
WinUIEditor/DummyPage.idl
Normal file
11
WinUIEditor/DummyPage.idl
Normal file
|
@ -0,0 +1,11 @@
|
|||
#include "Defines.idl"
|
||||
|
||||
namespace WinUIEditor
|
||||
{
|
||||
[default_interface]
|
||||
[webhosthidden]
|
||||
runtimeclass DummyPage : DUX.Controls.Page
|
||||
{
|
||||
DummyPage();
|
||||
}
|
||||
}
|
8
WinUIEditor/DummyPage.xaml
Normal file
8
WinUIEditor/DummyPage.xaml
Normal file
|
@ -0,0 +1,8 @@
|
|||
<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" />
|
665
WinUIEditor/EditorBaseControl.cpp
Normal file
665
WinUIEditor/EditorBaseControl.cpp
Normal file
|
@ -0,0 +1,665 @@
|
|||
#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
|
||||
}
|
121
WinUIEditor/EditorBaseControl.h
Normal file
121
WinUIEditor/EditorBaseControl.h
Normal file
|
@ -0,0 +1,121 @@
|
|||
#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>
|
||||
{
|
||||
};
|
||||
}
|
15
WinUIEditor/EditorBaseControl.idl
Normal file
15
WinUIEditor/EditorBaseControl.idl
Normal file
|
@ -0,0 +1,15 @@
|
|||
#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;
|
||||
}
|
||||
}
|
190
WinUIEditor/EditorBaseControlAutomationPeer.cpp
Normal file
190
WinUIEditor/EditorBaseControlAutomationPeer.cpp
Normal file
|
@ -0,0 +1,190 @@
|
|||
#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);
|
||||
}
|
||||
}
|
43
WinUIEditor/EditorBaseControlAutomationPeer.h
Normal file
43
WinUIEditor/EditorBaseControlAutomationPeer.h
Normal file
|
@ -0,0 +1,43 @@
|
|||
#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>
|
||||
{
|
||||
};
|
||||
}
|
15
WinUIEditor/EditorBaseControlAutomationPeer.idl
Normal file
15
WinUIEditor/EditorBaseControlAutomationPeer.idl
Normal file
|
@ -0,0 +1,15 @@
|
|||
#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);
|
||||
}
|
||||
}
|
8461
WinUIEditor/EditorWrapper.cpp
Normal file
8461
WinUIEditor/EditorWrapper.cpp
Normal file
File diff suppressed because it is too large
Load Diff
4756
WinUIEditor/EditorWrapper.h
Normal file
4756
WinUIEditor/EditorWrapper.h
Normal file
File diff suppressed because it is too large
Load Diff
8489
WinUIEditor/EditorWrapper.idl
Normal file
8489
WinUIEditor/EditorWrapper.idl
Normal file
File diff suppressed because it is too large
Load Diff
81
WinUIEditor/Helpers.cpp
Normal file
81
WinUIEditor/Helpers.cpp
Normal file
|
@ -0,0 +1,81 @@
|
|||
#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;
|
||||
}
|
||||
}
|
8
WinUIEditor/Helpers.h
Normal file
8
WinUIEditor/Helpers.h
Normal file
|
@ -0,0 +1,8 @@
|
|||
#pragma once
|
||||
|
||||
namespace WinUIEditor
|
||||
{
|
||||
int ConvertFromDipToPixelUnit(float val, float dpiAdjustmentRatio, bool rounded = true);
|
||||
bool IsClassicWindow();
|
||||
winrt::Windows::System::VirtualKeyModifiers GetKeyModifiersForCurrentThread();
|
||||
}
|
10
WinUIEditor/IEditorAccess.idl
Normal file
10
WinUIEditor/IEditorAccess.idl
Normal file
|
@ -0,0 +1,10 @@
|
|||
import "EditorWrapper.idl";
|
||||
|
||||
namespace WinUIEditor
|
||||
{
|
||||
interface IEditorAccess
|
||||
{
|
||||
Int64 SendMessage(ScintillaMessage message, UInt64 wParam, Int64 lParam);
|
||||
event Windows.Foundation.EventHandler<Int64> NotifyMessageReceived;
|
||||
}
|
||||
}
|
225
WinUIEditor/LightPlus.h
Normal file
225
WinUIEditor/LightPlus.h
Normal file
|
@ -0,0 +1,225 @@
|
|||
// 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);
|
||||
}
|
||||
}
|
||||
}
|
215
WinUIEditor/TextMateScope.h
Normal file
215
WinUIEditor/TextMateScope.h
Normal file
|
@ -0,0 +1,215 @@
|
|||
// 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
|
||||
};
|
334
WinUIEditor/TextRangeProvider.cpp
Normal file
334
WinUIEditor/TextRangeProvider.cpp
Normal file
|
@ -0,0 +1,334 @@
|
|||
#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 {};
|
||||
}
|
||||
}
|
38
WinUIEditor/TextRangeProvider.h
Normal file
38
WinUIEditor/TextRangeProvider.h
Normal file
|
@ -0,0 +1,38 @@
|
|||
#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;
|
||||
};
|
||||
}
|
67
WinUIEditor/Themes/Generic.xaml
Normal file
67
WinUIEditor/Themes/Generic.xaml
Normal file
|
@ -0,0 +1,67 @@
|
|||
<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>
|
3
WinUIEditor/WinUIEditor.def
Normal file
3
WinUIEditor/WinUIEditor.def
Normal file
|
@ -0,0 +1,3 @@
|
|||
EXPORTS
|
||||
DllCanUnloadNow = WINRT_CanUnloadNow PRIVATE
|
||||
DllGetActivationFactory = WINRT_GetActivationFactory PRIVATE
|
847
WinUIEditor/WinUIEditor.vcxproj
Normal file
847
WinUIEditor/WinUIEditor.vcxproj
Normal file
|
@ -0,0 +1,847 @@
|
|||
<?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>
|
785
WinUIEditor/WinUIEditor.vcxproj.filters
Normal file
785
WinUIEditor/WinUIEditor.vcxproj.filters
Normal file
|
@ -0,0 +1,785 @@
|
|||
<?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>
|
261
WinUIEditor/Wrapper.cpp
Normal file
261
WinUIEditor/Wrapper.cpp
Normal file
|
@ -0,0 +1,261 @@
|
|||
#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());
|
||||
}
|
||||
}
|
70
WinUIEditor/Wrapper.h
Normal file
70
WinUIEditor/Wrapper.h
Normal file
|
@ -0,0 +1,70 @@
|
|||
#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;
|
||||
};
|
||||
}
|
7
WinUIEditor/packages.config
Normal file
7
WinUIEditor/packages.config
Normal file
|
@ -0,0 +1,7 @@
|
|||
<?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
WinUIEditor/pch.cpp
Normal file
1
WinUIEditor/pch.cpp
Normal file
|
@ -0,0 +1 @@
|
|||
#include "pch.h"
|
144
WinUIEditor/pch.h
Normal file
144
WinUIEditor/pch.h
Normal file
|
@ -0,0 +1,144 @@
|
|||
#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
|
49
WinUIEditorCsWinRT/WinUIEditorCsWinRT.csproj
Normal file
49
WinUIEditorCsWinRT/WinUIEditorCsWinRT.csproj
Normal file
|
@ -0,0 +1,49 @@
|
|||
<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