Starting from scratch
This commit is contained in:
Родитель
be1420a601
Коммит
17776dd15f
|
@ -1,17 +1,63 @@
|
|||
# Auto detect text files and perform LF normalization
|
||||
###############################################################################
|
||||
# Set default behavior to automatically normalize line endings.
|
||||
###############################################################################
|
||||
* text=auto
|
||||
|
||||
# Custom for Visual Studio
|
||||
*.cs diff=csharp
|
||||
###############################################################################
|
||||
# Set default behavior for command prompt diff.
|
||||
#
|
||||
# This is need for earlier builds of msysgit that does not have it on by
|
||||
# default for csharp files.
|
||||
# Note: This is only used by command line
|
||||
###############################################################################
|
||||
#*.cs diff=csharp
|
||||
|
||||
# Standard to msysgit
|
||||
*.doc diff=astextplain
|
||||
*.DOC diff=astextplain
|
||||
*.docx diff=astextplain
|
||||
*.DOCX diff=astextplain
|
||||
*.dot diff=astextplain
|
||||
*.DOT diff=astextplain
|
||||
*.pdf diff=astextplain
|
||||
*.PDF diff=astextplain
|
||||
*.rtf diff=astextplain
|
||||
*.RTF diff=astextplain
|
||||
###############################################################################
|
||||
# Set the merge driver for project and solution files
|
||||
#
|
||||
# Merging from the command prompt will add diff markers to the files if there
|
||||
# are conflicts (Merging from VS is not affected by the settings below, in VS
|
||||
# the diff markers are never inserted). Diff markers may cause the following
|
||||
# file extensions to fail to load in VS. An alternative would be to treat
|
||||
# these files as binary and thus will always conflict and require user
|
||||
# intervention with every merge. To do so, just uncomment the entries below
|
||||
###############################################################################
|
||||
#*.sln merge=binary
|
||||
#*.csproj merge=binary
|
||||
#*.vbproj merge=binary
|
||||
#*.vcxproj merge=binary
|
||||
#*.vcproj merge=binary
|
||||
#*.dbproj merge=binary
|
||||
#*.fsproj merge=binary
|
||||
#*.lsproj merge=binary
|
||||
#*.wixproj merge=binary
|
||||
#*.modelproj merge=binary
|
||||
#*.sqlproj merge=binary
|
||||
#*.wwaproj merge=binary
|
||||
|
||||
###############################################################################
|
||||
# behavior for image files
|
||||
#
|
||||
# image files are treated as binary by default.
|
||||
###############################################################################
|
||||
#*.jpg binary
|
||||
#*.png binary
|
||||
#*.gif binary
|
||||
|
||||
###############################################################################
|
||||
# diff behavior for common document formats
|
||||
#
|
||||
# Convert binary document formats to text before diffing them. This feature
|
||||
# is only available from the command line. Turn it on by uncommenting the
|
||||
# entries below.
|
||||
###############################################################################
|
||||
#*.doc diff=astextplain
|
||||
#*.DOC diff=astextplain
|
||||
#*.docx diff=astextplain
|
||||
#*.DOCX diff=astextplain
|
||||
#*.dot diff=astextplain
|
||||
#*.DOT diff=astextplain
|
||||
#*.pdf diff=astextplain
|
||||
#*.PDF diff=astextplain
|
||||
#*.rtf diff=astextplain
|
||||
#*.RTF diff=astextplain
|
||||
|
|
|
@ -1,35 +1,53 @@
|
|||
.vs/
|
||||
OutputRoot/
|
||||
/packages/
|
||||
PrecompiledWeb/
|
||||
.tools/
|
||||
project.lock.json
|
||||
#################
|
||||
## Visual Studio
|
||||
#################
|
||||
|
||||
## Ignore Visual Studio temporary files, build results, and
|
||||
## files generated by popular Visual Studio add-ons.
|
||||
|
||||
# User-specific files
|
||||
*.suo
|
||||
*.user
|
||||
*.userosscache
|
||||
*.sln.docstates
|
||||
|
||||
# Build results
|
||||
# User-specific files (MonoDevelop/Xamarin Studio)
|
||||
*.userprefs
|
||||
|
||||
# Build results
|
||||
[Dd]ebug/
|
||||
[Dd]ebugPublic/
|
||||
[Rr]elease/
|
||||
[Rr]eleases/
|
||||
x64/
|
||||
x86/
|
||||
bld/
|
||||
[Bb]in/
|
||||
[Oo]bj/
|
||||
[Ll]og/
|
||||
|
||||
# Visual Studio 2015 cache/options directory
|
||||
.vs/
|
||||
# Uncomment if you have tasks that create the project's static files in wwwroot
|
||||
#wwwroot/
|
||||
|
||||
# MSTest test Results
|
||||
[Tt]est[Rr]esult*/
|
||||
[Bb]uild[Ll]og.*
|
||||
|
||||
# NUNIT
|
||||
*.VisualState.xml
|
||||
TestResult.xml
|
||||
|
||||
# Build Results of an ATL Project
|
||||
[Dd]ebugPS/
|
||||
[Rr]eleasePS/
|
||||
dlldata.c
|
||||
|
||||
# DNX
|
||||
project.lock.json
|
||||
project.fragment.lock.json
|
||||
artifacts/
|
||||
|
||||
*_i.c
|
||||
*_p.c
|
||||
*_i.h
|
||||
*.ilk
|
||||
*.meta
|
||||
*.obj
|
||||
|
@ -49,21 +67,31 @@ x64/
|
|||
*.vssscc
|
||||
.builds
|
||||
*.pidb
|
||||
*.log
|
||||
*.svclog
|
||||
*.scc
|
||||
*.publishproj
|
||||
|
||||
# Chutzpah Test files
|
||||
_Chutzpah*
|
||||
|
||||
# Visual C++ cache files
|
||||
ipch/
|
||||
*.aps
|
||||
*.ncb
|
||||
*.opendb
|
||||
*.opensdf
|
||||
*.sdf
|
||||
*.cachefile
|
||||
*.VC.db
|
||||
*.VC.VC.opendb
|
||||
|
||||
# Visual Studio profiler
|
||||
*.psess
|
||||
*.vsp
|
||||
*.vspx
|
||||
*.sap
|
||||
|
||||
# TFS 2012 Local Workspace
|
||||
$tf/
|
||||
|
||||
# Guidance Automation Toolkit
|
||||
*.gpState
|
||||
|
@ -71,6 +99,10 @@ ipch/
|
|||
# ReSharper is a .NET coding add-in
|
||||
_ReSharper*/
|
||||
*.[Rr]e[Ss]harper
|
||||
*.DotSettings.user
|
||||
|
||||
# JustCode is a .NET coding add-in
|
||||
.JustCode
|
||||
|
||||
# TeamCity is a build add-in
|
||||
_TeamCity*
|
||||
|
@ -79,8 +111,16 @@ _TeamCity*
|
|||
*.dotCover
|
||||
|
||||
# NCrunch
|
||||
*.ncrunch*
|
||||
_NCrunch_*
|
||||
.*crunch*.local.xml
|
||||
nCrunchTemp_*
|
||||
|
||||
# MightyMoose
|
||||
*.mm.*
|
||||
AutoTest.Net/
|
||||
|
||||
# Web workbench (sass)
|
||||
.sass-cache/
|
||||
|
||||
# Installshield output folder
|
||||
[Ee]xpress/
|
||||
|
@ -99,60 +139,123 @@ DocProject/Help/html
|
|||
publish/
|
||||
|
||||
# Publish Web Output
|
||||
*.Publish.xml
|
||||
*.pubxml
|
||||
*.[Pp]ublish.xml
|
||||
*.azurePubxml
|
||||
# TODO: Comment the next line if you want to checkin your web deploy settings
|
||||
# but database connection strings (with potential passwords) will be unencrypted
|
||||
#*.pubxml
|
||||
*.publishproj
|
||||
|
||||
# NuGet Packages Directory
|
||||
## TODO: If you have NuGet Package Restore enabled, uncomment the next line
|
||||
#packages/
|
||||
!src/PerspexVS/packages
|
||||
# Windows Azure Build Output
|
||||
csx
|
||||
# Microsoft Azure Web App publish settings. Comment the next line if you want to
|
||||
# checkin your Azure Web App publish settings, but sensitive information contained
|
||||
# in these scripts will be unencrypted
|
||||
PublishScripts/
|
||||
|
||||
# NuGet Packages
|
||||
*.nupkg
|
||||
# The packages folder can be ignored because of Package Restore
|
||||
**/packages/*
|
||||
# except build/, which is used as an MSBuild target.
|
||||
!**/packages/build/
|
||||
# Uncomment if necessary however generally it will be regenerated when needed
|
||||
#!**/packages/repositories.config
|
||||
# NuGet v3's project.json files produces more ignoreable files
|
||||
*.nuget.props
|
||||
*.nuget.targets
|
||||
|
||||
# Microsoft Azure Build Output
|
||||
csx/
|
||||
*.build.csdef
|
||||
|
||||
# Windows Store app package directory
|
||||
# Microsoft Azure Emulator
|
||||
ecf/
|
||||
rcf/
|
||||
|
||||
# Windows Store app package directories and files
|
||||
AppPackages/
|
||||
BundleArtifacts/
|
||||
Package.StoreAssociation.xml
|
||||
_pkginfo.txt
|
||||
|
||||
# Visual Studio cache files
|
||||
# files ending in .cache can be ignored
|
||||
*.[Cc]ache
|
||||
# but keep track of directories ending in .cache
|
||||
!*.[Cc]ache/
|
||||
|
||||
# Others
|
||||
sql/
|
||||
*.Cache
|
||||
ClientBin/
|
||||
[Ss]tyle[Cc]op.*
|
||||
~$*
|
||||
*~
|
||||
*.dbmdl
|
||||
*.[Pp]ublish.xml
|
||||
*.dbproj.schemaview
|
||||
*.jfm
|
||||
*.pfx
|
||||
*.publishsettings
|
||||
node_modules/
|
||||
orleans.codegen.cs
|
||||
|
||||
# Since there are multiple workflows, uncomment next line to ignore bower_components
|
||||
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
|
||||
#bower_components/
|
||||
|
||||
# RIA/Silverlight projects
|
||||
Generated_Code/
|
||||
|
||||
# Backup & report files from converting an old project file to a newer
|
||||
# Visual Studio version. Backup files are not needed, because we have git ;-)
|
||||
# Backup & report files from converting an old project file
|
||||
# to a newer Visual Studio version. Backup files are not needed,
|
||||
# because we have git ;-)
|
||||
_UpgradeReport_Files/
|
||||
Backup*/
|
||||
UpgradeLog*.XML
|
||||
UpgradeLog*.htm
|
||||
|
||||
# SQL Server files
|
||||
App_Data/*.mdf
|
||||
App_Data/*.ldf
|
||||
*.mdf
|
||||
*.ldf
|
||||
|
||||
#############
|
||||
## Windows detritus
|
||||
#############
|
||||
# Business Intelligence projects
|
||||
*.rdl.data
|
||||
*.bim.layout
|
||||
*.bim_*.settings
|
||||
|
||||
# Windows image file caches
|
||||
Thumbs.db
|
||||
ehthumbs.db
|
||||
# Microsoft Fakes
|
||||
FakesAssemblies/
|
||||
|
||||
# Folder config file
|
||||
Desktop.ini
|
||||
# GhostDoc plugin setting file
|
||||
*.GhostDoc.xml
|
||||
|
||||
# Recycle Bin used on file shares
|
||||
$RECYCLE.BIN/
|
||||
# Node.js Tools for Visual Studio
|
||||
.ntvs_analysis.dat
|
||||
|
||||
# Mac crap
|
||||
.DS_Store
|
||||
# Visual Studio 6 build log
|
||||
*.plg
|
||||
|
||||
# Visual Studio 6 workspace options file
|
||||
*.opt
|
||||
|
||||
# Visual Studio LightSwitch build output
|
||||
**/*.HTMLClient/GeneratedArtifacts
|
||||
**/*.DesktopClient/GeneratedArtifacts
|
||||
**/*.DesktopClient/ModelManifest.xml
|
||||
**/*.Server/GeneratedArtifacts
|
||||
**/*.Server/ModelManifest.xml
|
||||
_Pvt_Extensions
|
||||
|
||||
# Paket dependency manager
|
||||
.paket/paket.exe
|
||||
paket-files/
|
||||
|
||||
# FAKE - F# Make
|
||||
.fake/
|
||||
|
||||
# JetBrains Rider
|
||||
.idea/
|
||||
*.sln.iml
|
||||
|
||||
# CodeRush
|
||||
.cr/
|
||||
|
||||
# Python Tools for Visual Studio (PTVS)
|
||||
__pycache__/
|
||||
*.pyc
|
|
@ -1,3 +0,0 @@
|
|||
[submodule "src/external/Avalonia.Ide"]
|
||||
path = src/external/Avalonia.Ide
|
||||
url = https://github.com/donandren/Avalonia.Ide
|
|
@ -1,69 +0,0 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 15
|
||||
VisualStudioVersion = 15.0.27130.2020
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Templates", "Templates", "{82C1C97B-56A1-4287-B8C2-42A127A07821}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AvaloniaVS", "src\AvaloniaVS\AvaloniaVS.csproj", "{378D99A6-57BF-432D-A5A2-82CC4153736A}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AvaloniaApplicationTemplate", "src\Templates\AvaloniaApplicationTemplate\AvaloniaApplicationTemplate.csproj", "{75104AA0-3B1B-47D4-9C4D-501A8185ACFC}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AvaloniaWindowTemplate", "src\Templates\AvaloniaWindowTemplate\AvaloniaWindowTemplate.csproj", "{C8B3FF98-50A3-4C04-8F8C-ED853EC0760C}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AvaloniaVS.Controls", "src\AvaloniaVS.Controls\AvaloniaVS.Controls.csproj", "{BDDC602F-89C4-439C-B728-582700B689B4}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AvaloniaUserControlTemplate", "src\Templates\AvaloniaUserControlTemplate\AvaloniaUserControlTemplate.csproj", "{3BFD12BB-E6D8-46D7-9D5F-119A9896941E}"
|
||||
EndProject
|
||||
Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "Avalonia.Ide.CompletionEngine", "src\external\Avalonia.Ide.build\Avalonia.Ide.CompletionEngine\Avalonia.Ide.CompletionEngine.shproj", "{C704041D-EB66-4C37-B0D5-90B4F58FFD02}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AvaloniaMvvmApplicationTemplate", "src\Templates\AvaloniaMvvmApplicationTemplate\AvaloniaMvvmApplicationTemplate.csproj", "{D458691F-3B40-4E54-8BC2-782D017CFD2B}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SharedMSBuildProjectFiles) = preSolution
|
||||
src\external\Avalonia.Ide.build\Avalonia.Ide.CompletionEngine\Avalonia.Ide.CompletionEngine.projitems*{378d99a6-57bf-432d-a5a2-82cc4153736a}*SharedItemsImports = 4
|
||||
src\external\Avalonia.Ide.build\Avalonia.Ide.CompletionEngine\Avalonia.Ide.CompletionEngine.projitems*{c704041d-eb66-4c37-b0d5-90b4f58ffd02}*SharedItemsImports = 13
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{378D99A6-57BF-432D-A5A2-82CC4153736A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{378D99A6-57BF-432D-A5A2-82CC4153736A}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{378D99A6-57BF-432D-A5A2-82CC4153736A}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{378D99A6-57BF-432D-A5A2-82CC4153736A}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{75104AA0-3B1B-47D4-9C4D-501A8185ACFC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{75104AA0-3B1B-47D4-9C4D-501A8185ACFC}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{75104AA0-3B1B-47D4-9C4D-501A8185ACFC}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{75104AA0-3B1B-47D4-9C4D-501A8185ACFC}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{C8B3FF98-50A3-4C04-8F8C-ED853EC0760C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{C8B3FF98-50A3-4C04-8F8C-ED853EC0760C}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{C8B3FF98-50A3-4C04-8F8C-ED853EC0760C}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{C8B3FF98-50A3-4C04-8F8C-ED853EC0760C}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{BDDC602F-89C4-439C-B728-582700B689B4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{BDDC602F-89C4-439C-B728-582700B689B4}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{BDDC602F-89C4-439C-B728-582700B689B4}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{BDDC602F-89C4-439C-B728-582700B689B4}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{3BFD12BB-E6D8-46D7-9D5F-119A9896941E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{3BFD12BB-E6D8-46D7-9D5F-119A9896941E}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{3BFD12BB-E6D8-46D7-9D5F-119A9896941E}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{3BFD12BB-E6D8-46D7-9D5F-119A9896941E}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{D458691F-3B40-4E54-8BC2-782D017CFD2B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{D458691F-3B40-4E54-8BC2-782D017CFD2B}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{D458691F-3B40-4E54-8BC2-782D017CFD2B}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{D458691F-3B40-4E54-8BC2-782D017CFD2B}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(NestedProjects) = preSolution
|
||||
{75104AA0-3B1B-47D4-9C4D-501A8185ACFC} = {82C1C97B-56A1-4287-B8C2-42A127A07821}
|
||||
{C8B3FF98-50A3-4C04-8F8C-ED853EC0760C} = {82C1C97B-56A1-4287-B8C2-42A127A07821}
|
||||
{3BFD12BB-E6D8-46D7-9D5F-119A9896941E} = {82C1C97B-56A1-4287-B8C2-42A127A07821}
|
||||
{D458691F-3B40-4E54-8BC2-782D017CFD2B} = {82C1C97B-56A1-4287-B8C2-42A127A07821}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {62C774A2-5642-4106-8A78-25BF85BB788F}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
|
@ -1,120 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{BDDC602F-89C4-439C-B728-582700B689B4}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>AvaloniaVS.Controls</RootNamespace>
|
||||
<AssemblyName>AvaloniaVS.Controls</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
|
||||
<TargetFrameworkProfile />
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<StartupObject />
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<SignAssembly>true</SignAssembly>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<AssemblyOriginatorKeyFile>Key.snk</AssemblyOriginatorKeyFile>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.ComponentModel.Composition" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Xml" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="System.Net.Http" />
|
||||
<Reference Include="System.Xaml">
|
||||
<RequiredTargetFramework>4.0</RequiredTargetFramework>
|
||||
</Reference>
|
||||
<Reference Include="WindowsBase" />
|
||||
<Reference Include="PresentationCore" />
|
||||
<Reference Include="PresentationFramework" />
|
||||
<PackageReference Include="Microsoft.VisualStudio.Shell.Framework">
|
||||
<Version>15.0.26201</Version>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="FocusableContentPresenter.cs" />
|
||||
<Compile Include="Internals\DoubleUtilties.cs" />
|
||||
<Compile Include="Internals\LineEquation.cs" />
|
||||
<Compile Include="Internals\AvaloniaDesignerBrushes.cs" />
|
||||
<Compile Include="Primitives\TabItemDock.cs" />
|
||||
<Compile Include="SplitterCommands.cs" />
|
||||
<Compile Include="SplitterContainer.cs" />
|
||||
<Compile Include="SplitterGrip.cs" />
|
||||
<Compile Include="Primitives\TabItemBorder.cs" />
|
||||
<Compile Include="Internals\BooleanBoxes.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Properties\Resources.Designer.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DesignTime>True</DesignTime>
|
||||
<DependentUpon>Resources.resx</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Properties\Settings.Designer.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>Settings.settings</DependentUpon>
|
||||
<DesignTimeSharedInput>True</DesignTimeSharedInput>
|
||||
</Compile>
|
||||
<EmbeddedResource Include="Properties\Resources.resx">
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
|
||||
</EmbeddedResource>
|
||||
<None Include="Key.snk" />
|
||||
<None Include="Properties\Settings.settings">
|
||||
<Generator>SettingsSingleFileGenerator</Generator>
|
||||
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
|
||||
</None>
|
||||
<AppDesigner Include="Properties\" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Page Include="Themes\Generic.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
<SubType>Designer</SubType>
|
||||
</Page>
|
||||
<Page Include="Themes\SplitterGrip.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
<SubType>Designer</SubType>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
|
@ -1,33 +0,0 @@
|
|||
// Copyright (c) The Avalonia Project. All rights reserved.
|
||||
// Licensed under the MIT license. See license.md file in the project root for full license information.
|
||||
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Input;
|
||||
using AvaloniaVS.Controls.Internals;
|
||||
|
||||
namespace AvaloniaVS.Controls
|
||||
{
|
||||
public class FocusableContentPresenter : ContentPresenter
|
||||
{
|
||||
static FocusableContentPresenter()
|
||||
{
|
||||
FocusableProperty.OverrideMetadata(typeof (FocusableContentPresenter), new FrameworkPropertyMetadata(BooleanBoxes.True));
|
||||
FocusVisualStyleProperty.OverrideMetadata(typeof(FocusableContentPresenter), new FrameworkPropertyMetadata(null));
|
||||
}
|
||||
|
||||
protected override void OnGotKeyboardFocus(KeyboardFocusChangedEventArgs e)
|
||||
{
|
||||
base.OnGotKeyboardFocus(e);
|
||||
|
||||
if (e.NewFocus == this)
|
||||
{
|
||||
var content = this.Content as IInputElement;
|
||||
if (content != null)
|
||||
{
|
||||
Keyboard.Focus(content);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,253 +0,0 @@
|
|||
// Copyright (c) The Avalonia Project. All rights reserved.
|
||||
// Licensed under the MIT license. See license.md file in the project root for full license information.
|
||||
|
||||
using System;
|
||||
using Microsoft.VisualStudio.Shell;
|
||||
|
||||
namespace AvaloniaVS.Controls.Internals
|
||||
{
|
||||
internal static class AvaloniaDesignerBrushes
|
||||
{
|
||||
#region Autogenerated resource keys
|
||||
|
||||
// These resource keys are generated by Visual Studio Extension Color Editor, and should be replaced when new colors are added to this category.
|
||||
public static readonly Guid Category = new Guid("1fb2e5ba-ede6-4dff-9dd6-59602a4414f9");
|
||||
|
||||
private static ThemeResourceKey _ButtonBackgroundColorKey;
|
||||
private static ThemeResourceKey _ButtonBackgroundBrushKey;
|
||||
|
||||
public static ThemeResourceKey ButtonBackgroundColorKey
|
||||
{
|
||||
get
|
||||
{
|
||||
return _ButtonBackgroundColorKey ??
|
||||
(_ButtonBackgroundColorKey = new ThemeResourceKey(Category, "ButtonBackground", ThemeResourceKeyType.BackgroundColor));
|
||||
}
|
||||
}
|
||||
|
||||
public static ThemeResourceKey ButtonBackgroundBrushKey
|
||||
{
|
||||
get
|
||||
{
|
||||
return _ButtonBackgroundBrushKey ??
|
||||
(_ButtonBackgroundBrushKey = new ThemeResourceKey(Category, "ButtonBackground", ThemeResourceKeyType.BackgroundBrush));
|
||||
}
|
||||
}
|
||||
|
||||
private static ThemeResourceKey _ButtonForegroundColorKey;
|
||||
private static ThemeResourceKey _ButtonForegroundBrushKey;
|
||||
|
||||
public static ThemeResourceKey ButtonForegroundColorKey
|
||||
{
|
||||
get
|
||||
{
|
||||
return _ButtonForegroundColorKey ??
|
||||
(_ButtonForegroundColorKey = new ThemeResourceKey(Category, "ButtonForeground", ThemeResourceKeyType.BackgroundColor));
|
||||
}
|
||||
}
|
||||
|
||||
public static ThemeResourceKey ButtonForegroundBrushKey
|
||||
{
|
||||
get
|
||||
{
|
||||
return _ButtonForegroundBrushKey ??
|
||||
(_ButtonForegroundBrushKey = new ThemeResourceKey(Category, "ButtonForeground", ThemeResourceKeyType.BackgroundBrush));
|
||||
}
|
||||
}
|
||||
|
||||
private static ThemeResourceKey _ButtonMouseOverBackgroundColorKey;
|
||||
private static ThemeResourceKey _ButtonMouseOverBackgroundBrushKey;
|
||||
|
||||
public static ThemeResourceKey ButtonMouseOverBackgroundColorKey
|
||||
{
|
||||
get
|
||||
{
|
||||
return _ButtonMouseOverBackgroundColorKey ??
|
||||
(_ButtonMouseOverBackgroundColorKey =
|
||||
new ThemeResourceKey(Category, "ButtonMouseOverBackground", ThemeResourceKeyType.BackgroundColor));
|
||||
}
|
||||
}
|
||||
|
||||
public static ThemeResourceKey ButtonMouseOverBackgroundBrushKey
|
||||
{
|
||||
get
|
||||
{
|
||||
return _ButtonMouseOverBackgroundBrushKey ??
|
||||
(_ButtonMouseOverBackgroundBrushKey =
|
||||
new ThemeResourceKey(Category, "ButtonMouseOverBackground", ThemeResourceKeyType.BackgroundBrush));
|
||||
}
|
||||
}
|
||||
|
||||
private static ThemeResourceKey _ButtonMouseOverForegroundColorKey;
|
||||
private static ThemeResourceKey _ButtonMouseOverForegroundBrushKey;
|
||||
|
||||
public static ThemeResourceKey ButtonMouseOverForegroundColorKey
|
||||
{
|
||||
get
|
||||
{
|
||||
return _ButtonMouseOverForegroundColorKey ??
|
||||
(_ButtonMouseOverForegroundColorKey =
|
||||
new ThemeResourceKey(Category, "ButtonMouseOverForeground", ThemeResourceKeyType.BackgroundColor));
|
||||
}
|
||||
}
|
||||
|
||||
public static ThemeResourceKey ButtonMouseOverForegroundBrushKey
|
||||
{
|
||||
get
|
||||
{
|
||||
return _ButtonMouseOverForegroundBrushKey ??
|
||||
(_ButtonMouseOverForegroundBrushKey =
|
||||
new ThemeResourceKey(Category, "ButtonMouseOverForeground", ThemeResourceKeyType.BackgroundBrush));
|
||||
}
|
||||
}
|
||||
|
||||
private static ThemeResourceKey _ButtonPressedBackgroundColorKey;
|
||||
private static ThemeResourceKey _ButtonPressedBackgroundBrushKey;
|
||||
|
||||
public static ThemeResourceKey ButtonPressedBackgroundColorKey
|
||||
{
|
||||
get
|
||||
{
|
||||
return _ButtonPressedBackgroundColorKey ??
|
||||
(_ButtonPressedBackgroundColorKey = new ThemeResourceKey(Category, "ButtonPressedBackground", ThemeResourceKeyType.BackgroundColor));
|
||||
}
|
||||
}
|
||||
|
||||
public static ThemeResourceKey ButtonPressedBackgroundBrushKey
|
||||
{
|
||||
get
|
||||
{
|
||||
return _ButtonPressedBackgroundBrushKey ??
|
||||
(_ButtonPressedBackgroundBrushKey = new ThemeResourceKey(Category, "ButtonPressedBackground", ThemeResourceKeyType.BackgroundBrush));
|
||||
}
|
||||
}
|
||||
|
||||
private static ThemeResourceKey _ButtonPressedForegroundColorKey;
|
||||
private static ThemeResourceKey _ButtonPressedForegroundBrushKey;
|
||||
|
||||
public static ThemeResourceKey ButtonPressedForegroundColorKey
|
||||
{
|
||||
get
|
||||
{
|
||||
return _ButtonPressedForegroundColorKey ??
|
||||
(_ButtonPressedForegroundColorKey = new ThemeResourceKey(Category, "ButtonPressedForeground", ThemeResourceKeyType.BackgroundColor));
|
||||
}
|
||||
}
|
||||
|
||||
public static ThemeResourceKey ButtonPressedForegroundBrushKey
|
||||
{
|
||||
get
|
||||
{
|
||||
return _ButtonPressedForegroundBrushKey ??
|
||||
(_ButtonPressedForegroundBrushKey = new ThemeResourceKey(Category, "ButtonPressedForeground", ThemeResourceKeyType.BackgroundBrush));
|
||||
}
|
||||
}
|
||||
|
||||
private static ThemeResourceKey _HeaderActiveColorKey;
|
||||
private static ThemeResourceKey _HeaderActiveBrushKey;
|
||||
|
||||
public static ThemeResourceKey HeaderActiveColorKey
|
||||
{
|
||||
get
|
||||
{
|
||||
return _HeaderActiveColorKey ??
|
||||
(_HeaderActiveColorKey = new ThemeResourceKey(Category, "HeaderActive", ThemeResourceKeyType.BackgroundColor));
|
||||
}
|
||||
}
|
||||
|
||||
public static ThemeResourceKey HeaderActiveBrushKey
|
||||
{
|
||||
get
|
||||
{
|
||||
return _HeaderActiveBrushKey ??
|
||||
(_HeaderActiveBrushKey = new ThemeResourceKey(Category, "HeaderActive", ThemeResourceKeyType.BackgroundBrush));
|
||||
}
|
||||
}
|
||||
|
||||
private static ThemeResourceKey _HeaderActiveTextColorKey;
|
||||
private static ThemeResourceKey _HeaderActiveTextBrushKey;
|
||||
|
||||
public static ThemeResourceKey HeaderActiveTextColorKey
|
||||
{
|
||||
get
|
||||
{
|
||||
return _HeaderActiveTextColorKey ??
|
||||
(_HeaderActiveTextColorKey = new ThemeResourceKey(Category, "HeaderActiveText", ThemeResourceKeyType.BackgroundColor));
|
||||
}
|
||||
}
|
||||
|
||||
public static ThemeResourceKey HeaderActiveTextBrushKey
|
||||
{
|
||||
get
|
||||
{
|
||||
return _HeaderActiveTextBrushKey ??
|
||||
(_HeaderActiveTextBrushKey = new ThemeResourceKey(Category, "HeaderActiveText", ThemeResourceKeyType.BackgroundBrush));
|
||||
}
|
||||
}
|
||||
|
||||
private static ThemeResourceKey _HeaderInactiveColorKey;
|
||||
private static ThemeResourceKey _HeaderInactiveBrushKey;
|
||||
|
||||
public static ThemeResourceKey HeaderInactiveColorKey
|
||||
{
|
||||
get
|
||||
{
|
||||
return _HeaderInactiveColorKey ??
|
||||
(_HeaderInactiveColorKey = new ThemeResourceKey(Category, "HeaderInactive", ThemeResourceKeyType.BackgroundColor));
|
||||
}
|
||||
}
|
||||
|
||||
public static ThemeResourceKey HeaderInactiveBrushKey
|
||||
{
|
||||
get
|
||||
{
|
||||
return _HeaderInactiveBrushKey ??
|
||||
(_HeaderInactiveBrushKey = new ThemeResourceKey(Category, "HeaderInactive", ThemeResourceKeyType.BackgroundBrush));
|
||||
}
|
||||
}
|
||||
|
||||
private static ThemeResourceKey _HeaderInactiveTextColorKey;
|
||||
private static ThemeResourceKey _HeaderInactiveTextBrushKey;
|
||||
|
||||
public static ThemeResourceKey HeaderInactiveTextColorKey
|
||||
{
|
||||
get
|
||||
{
|
||||
return _HeaderInactiveTextColorKey ??
|
||||
(_HeaderInactiveTextColorKey = new ThemeResourceKey(Category, "HeaderInactiveText", ThemeResourceKeyType.BackgroundColor));
|
||||
}
|
||||
}
|
||||
|
||||
public static ThemeResourceKey HeaderInactiveTextBrushKey
|
||||
{
|
||||
get
|
||||
{
|
||||
return _HeaderInactiveTextBrushKey ??
|
||||
(_HeaderInactiveTextBrushKey = new ThemeResourceKey(Category, "HeaderInactiveText", ThemeResourceKeyType.BackgroundBrush));
|
||||
}
|
||||
}
|
||||
|
||||
private static ThemeResourceKey _SplitterBackgroundColorKey;
|
||||
private static ThemeResourceKey _SplitterBackgroundBrushKey;
|
||||
|
||||
public static ThemeResourceKey SplitterBackgroundColorKey
|
||||
{
|
||||
get
|
||||
{
|
||||
return _SplitterBackgroundColorKey ??
|
||||
(_SplitterBackgroundColorKey = new ThemeResourceKey(Category, "SplitterBackground", ThemeResourceKeyType.BackgroundColor));
|
||||
}
|
||||
}
|
||||
|
||||
public static ThemeResourceKey SplitterBackgroundBrushKey
|
||||
{
|
||||
get
|
||||
{
|
||||
return _SplitterBackgroundBrushKey ??
|
||||
(_SplitterBackgroundBrushKey = new ThemeResourceKey(Category, "SplitterBackground", ThemeResourceKeyType.BackgroundBrush));
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
// Copyright (c) The Avalonia Project. All rights reserved.
|
||||
// Licensed under the MIT license. See license.md file in the project root for full license information.
|
||||
|
||||
namespace AvaloniaVS.Controls.Internals
|
||||
{
|
||||
internal class BooleanBoxes
|
||||
{
|
||||
public static object True = true;
|
||||
public static object False = false;
|
||||
|
||||
public static object Box(bool value)
|
||||
{
|
||||
return value ? True : False;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,17 +0,0 @@
|
|||
// Copyright (c) The Avalonia Project. All rights reserved.
|
||||
// Licensed under the MIT license. See license.md file in the project root for full license information.
|
||||
|
||||
using System;
|
||||
|
||||
namespace AvaloniaVS.Controls.Internals
|
||||
{
|
||||
internal static class DoubleUtilties
|
||||
{
|
||||
internal const double MAX_DIFF = 0.1;
|
||||
|
||||
public static bool AreClose(double value2, double value1)
|
||||
{
|
||||
return Math.Abs(value1 - value2) < MAX_DIFF;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,52 +0,0 @@
|
|||
// Copyright (c) The Avalonia Project. All rights reserved.
|
||||
// Licensed under the MIT license. See license.md file in the project root for full license information.
|
||||
|
||||
using System.Windows;
|
||||
|
||||
namespace AvaloniaVS.Controls.Internals
|
||||
{
|
||||
/// <summary>
|
||||
/// Encapsulates a line equation
|
||||
/// </summary>
|
||||
internal struct LineEquation
|
||||
{
|
||||
// line equation y=mx+b
|
||||
|
||||
private readonly double _m;
|
||||
private readonly double _b;
|
||||
|
||||
private static double CalculateB(double m, double x, double y)
|
||||
{
|
||||
var b = y - (m * x);
|
||||
return b;
|
||||
}
|
||||
|
||||
public Point IntersectWithHorizontalLine(double providedX, double y)
|
||||
{
|
||||
if (double.IsInfinity(_m))
|
||||
{
|
||||
return new Point(providedX, y);
|
||||
}
|
||||
|
||||
var x = (y - _b) / _m;
|
||||
return new Point(x, y);
|
||||
}
|
||||
|
||||
public LineEquation(Point p1, Point p2)
|
||||
{
|
||||
_m = (p2.Y - p1.Y) / (p2.X - p1.X);
|
||||
_b = CalculateB(_m, p1.X, p1.Y);
|
||||
}
|
||||
|
||||
public Point IntersectWithVerticalLine(double providedY, double x)
|
||||
{
|
||||
if (double.IsInfinity(_m))
|
||||
{
|
||||
return new Point(x, providedY);
|
||||
}
|
||||
|
||||
var y = _m * x + _b;
|
||||
return new Point(x, y);
|
||||
}
|
||||
}
|
||||
}
|
Двоичные данные
src/AvaloniaVS.Controls/Key.snk
Двоичные данные
src/AvaloniaVS.Controls/Key.snk
Двоичный файл не отображается.
|
@ -1,740 +0,0 @@
|
|||
// Copyright (c) The Avalonia Project. All rights reserved.
|
||||
// Licensed under the MIT license. See license.md file in the project root for full license information.
|
||||
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Media;
|
||||
using AvaloniaVS.Controls.Internals;
|
||||
|
||||
namespace AvaloniaVS.Controls.Primitives
|
||||
{
|
||||
public class TabItemBorder : Decorator
|
||||
{
|
||||
private Pen _cachedBoderPen;
|
||||
private Geometry _cachedBackgroundGeometry;
|
||||
private Geometry _cachedBorderGeometry;
|
||||
|
||||
/// <summary>
|
||||
/// Identifies the <see cref="Dock"/> dependency property.
|
||||
/// </summary>
|
||||
public static readonly DependencyProperty DockProperty = DependencyProperty.Register(
|
||||
"Dock",
|
||||
typeof (TabItemDock),
|
||||
typeof (TabItemBorder),
|
||||
new FrameworkPropertyMetadata(TabItemDock.None,
|
||||
FrameworkPropertyMetadataOptions.AffectsMeasure | FrameworkPropertyMetadataOptions.AffectsRender));
|
||||
|
||||
/// <summary>
|
||||
/// Identifies the <see cref="CornerRadius"/> dependency property.
|
||||
/// </summary>
|
||||
public static readonly DependencyProperty CornerRadiusProperty = DependencyProperty.Register(
|
||||
"CornerRadius",
|
||||
typeof (double),
|
||||
typeof (TabItemBorder),
|
||||
new FrameworkPropertyMetadata(
|
||||
0.0,
|
||||
FrameworkPropertyMetadataOptions.AffectsMeasure | FrameworkPropertyMetadataOptions.AffectsRender,
|
||||
(o, args) =>
|
||||
{
|
||||
var border = (TabItemBorder) o;
|
||||
border.InvalidateGeometries();
|
||||
}));
|
||||
|
||||
/// <summary>
|
||||
/// Identifies the <see cref="BorderBrush"/> dependency property.
|
||||
/// </summary>
|
||||
public static readonly DependencyProperty BorderBrushProperty = DependencyProperty.Register(
|
||||
"BorderBrush",
|
||||
typeof (Brush),
|
||||
typeof (TabItemBorder),
|
||||
new FrameworkPropertyMetadata(
|
||||
null,
|
||||
FrameworkPropertyMetadataOptions.AffectsRender,
|
||||
(o, args) =>
|
||||
{
|
||||
var border = (TabItemBorder) o;
|
||||
border._cachedBoderPen = null;
|
||||
}));
|
||||
|
||||
/// <summary>
|
||||
/// Identifies the <see cref="BorderThickness"/> dependency property.
|
||||
/// </summary>
|
||||
public static readonly DependencyProperty BorderThicknessProperty = DependencyProperty.Register(
|
||||
"BorderThickness",
|
||||
typeof (double),
|
||||
typeof (TabItemBorder),
|
||||
new FrameworkPropertyMetadata(
|
||||
0.0,
|
||||
FrameworkPropertyMetadataOptions.AffectsMeasure | FrameworkPropertyMetadataOptions.AffectsRender,
|
||||
(o, args) =>
|
||||
{
|
||||
var border = (TabItemBorder) o;
|
||||
border._cachedBoderPen = null;
|
||||
border.InvalidateGeometries();
|
||||
}),
|
||||
value =>
|
||||
{
|
||||
// you can't have a thickness lest than 0
|
||||
// we don't coerce we validate.
|
||||
var thickness = (double) value;
|
||||
return thickness >= 0;
|
||||
});
|
||||
|
||||
/// <summary>
|
||||
/// Identifies the <see cref="Padding"/> dependency property.
|
||||
/// </summary>
|
||||
public static readonly DependencyProperty PaddingProperty = DependencyProperty.Register(
|
||||
"Padding",
|
||||
typeof (Thickness),
|
||||
typeof (TabItemBorder),
|
||||
new FrameworkPropertyMetadata(
|
||||
new Thickness(),
|
||||
FrameworkPropertyMetadataOptions.AffectsMeasure | FrameworkPropertyMetadataOptions.AffectsRender));
|
||||
|
||||
/// <summary>
|
||||
/// Identifies the <see cref="Background"/> dependency property.
|
||||
/// </summary>
|
||||
public static readonly DependencyProperty BackgroundProperty = DependencyProperty.Register(
|
||||
"Background",
|
||||
typeof (Brush),
|
||||
typeof (TabItemBorder),
|
||||
new FrameworkPropertyMetadata(
|
||||
null,
|
||||
FrameworkPropertyMetadataOptions.AffectsRender));
|
||||
|
||||
/// <summary>
|
||||
/// Identifies the <see cref="LeftSlopeOffset"/> dependency property.
|
||||
/// </summary>
|
||||
public static readonly DependencyProperty LeftSlopeOffsetProperty = DependencyProperty.Register(
|
||||
"LeftSlopeOffset",
|
||||
typeof (double),
|
||||
typeof (TabItemBorder),
|
||||
new FrameworkPropertyMetadata(0.0,
|
||||
FrameworkPropertyMetadataOptions.AffectsMeasure | FrameworkPropertyMetadataOptions.AffectsRender,
|
||||
OnSlopeOffsetValueChanged,
|
||||
OnCoerceSlopeOffsetValue));
|
||||
|
||||
/// <summary>
|
||||
/// Identifies the <see cref="RightSlopeOffset"/> dependency property.
|
||||
/// </summary>
|
||||
public static readonly DependencyProperty RightSlopeOffsetProperty = DependencyProperty.Register(
|
||||
"RightSlopeOffset",
|
||||
typeof (double),
|
||||
typeof (TabItemBorder),
|
||||
new FrameworkPropertyMetadata(0.0,
|
||||
FrameworkPropertyMetadataOptions.AffectsMeasure | FrameworkPropertyMetadataOptions.AffectsRender,
|
||||
OnSlopeOffsetValueChanged,
|
||||
OnCoerceSlopeOffsetValue));
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value that indicates the location of the border open side.
|
||||
/// </summary>
|
||||
[Bindable(true)]
|
||||
public TabItemDock Dock
|
||||
{
|
||||
get { return (TabItemDock) GetValue(DockProperty); }
|
||||
set { SetValue(DockProperty, value); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the corner radius, our border is open on one side indicates by the <see cref="Dock"/> value.
|
||||
/// so even the start and the end of the border are curved using this value.
|
||||
/// </summary>
|
||||
[Bindable(true)]
|
||||
public double CornerRadius
|
||||
{
|
||||
get { return (double) GetValue(CornerRadiusProperty); }
|
||||
set { SetValue(CornerRadiusProperty, value); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the brush used to render the border.
|
||||
/// </summary>
|
||||
[Bindable(true)]
|
||||
public Brush BorderBrush
|
||||
{
|
||||
get { return (Brush) GetValue(BorderBrushProperty); }
|
||||
set { SetValue(BorderBrushProperty, value); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the thickness of the border.
|
||||
/// </summary>
|
||||
[Bindable(true)]
|
||||
public double BorderThickness
|
||||
{
|
||||
get { return (double) GetValue(BorderThicknessProperty); }
|
||||
set { SetValue(BorderThicknessProperty, value); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the padding of the border child.
|
||||
/// </summary>
|
||||
[Bindable(true)]
|
||||
public Thickness Padding
|
||||
{
|
||||
get { return (Thickness) GetValue(PaddingProperty); }
|
||||
set { SetValue(PaddingProperty, value); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the background brush.
|
||||
/// </summary>
|
||||
public Brush Background
|
||||
{
|
||||
get { return (Brush) GetValue(BackgroundProperty); }
|
||||
set { SetValue(BackgroundProperty, value); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value that indicates the distance of the left border from the edge in pixels.
|
||||
/// </summary>
|
||||
[Bindable(true)]
|
||||
public double LeftSlopeOffset
|
||||
{
|
||||
get { return (double) GetValue(LeftSlopeOffsetProperty); }
|
||||
set { SetValue(LeftSlopeOffsetProperty, value); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value that indicates the distance of the right border from the edge in pixels.
|
||||
/// </summary>
|
||||
[Bindable(true)]
|
||||
public double RightSlopeOffset
|
||||
{
|
||||
get { return (double) GetValue(RightSlopeOffsetProperty); }
|
||||
set { SetValue(RightSlopeOffsetProperty, value); }
|
||||
}
|
||||
|
||||
private static object OnCoerceSlopeOffsetValue(DependencyObject o, object value)
|
||||
{
|
||||
var baseValue = (double) value;
|
||||
if (baseValue < 0.0)
|
||||
{
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
private static void OnSlopeOffsetValueChanged(DependencyObject o, DependencyPropertyChangedEventArgs args)
|
||||
{
|
||||
var border = (TabItemBorder) o;
|
||||
border.InvalidateGeometries();
|
||||
}
|
||||
|
||||
protected override Size MeasureOverride(Size constraint)
|
||||
{
|
||||
var child = Child;
|
||||
var borderThickness = BorderThickness;
|
||||
var padding = Padding;
|
||||
var cornerRadius = CornerRadius;
|
||||
var dock = Dock;
|
||||
var isHorizontal = (dock & TabItemDock.Bottom) == TabItemDock.Bottom || (dock & TabItemDock.Top) == TabItemDock.Top;
|
||||
|
||||
var reservedWidth = isHorizontal
|
||||
? (padding.Left + padding.Right) + (borderThickness * 2) + (cornerRadius * 2) + LeftSlopeOffset + RightSlopeOffset
|
||||
: (padding.Left + padding.Right) + (borderThickness);
|
||||
|
||||
var reservedHeight = isHorizontal
|
||||
? (padding.Top + padding.Bottom) + (borderThickness)
|
||||
: (padding.Top + padding.Bottom) + (borderThickness * 2) + (cornerRadius * 2) + LeftSlopeOffset + RightSlopeOffset;
|
||||
|
||||
if (child == null)
|
||||
{
|
||||
return new Size(reservedWidth, reservedHeight);
|
||||
}
|
||||
|
||||
var availableWidth = Math.Max(0.0, constraint.Width - reservedWidth);
|
||||
var availableHeight = Math.Max(0.0, constraint.Height - reservedHeight);
|
||||
|
||||
child.Measure(new Size(availableWidth, availableHeight));
|
||||
var desiredSize = child.DesiredSize;
|
||||
return new Size(desiredSize.Width + reservedWidth, desiredSize.Height + reservedHeight);
|
||||
}
|
||||
|
||||
protected override Size ArrangeOverride(Size arrangeSize)
|
||||
{
|
||||
var child = Child;
|
||||
|
||||
if (child != null)
|
||||
{
|
||||
var childRect = new Rect(arrangeSize);
|
||||
var borderThickness = BorderThickness;
|
||||
var padding = Padding;
|
||||
var cornerRadius = CornerRadius;
|
||||
var dock = Dock;
|
||||
var isHorizontal = (dock & TabItemDock.Bottom) == TabItemDock.Bottom || (dock & TabItemDock.Top) == TabItemDock.Top;
|
||||
|
||||
var reservedWidth = isHorizontal
|
||||
? (padding.Left + padding.Right) + (borderThickness * 2) + (cornerRadius * 2) + LeftSlopeOffset + RightSlopeOffset
|
||||
: (padding.Left + padding.Right) + (borderThickness);
|
||||
|
||||
var reservedHeight = isHorizontal
|
||||
? (padding.Top + padding.Bottom) + (borderThickness)
|
||||
: (padding.Top + padding.Top) + (borderThickness * 2) + (cornerRadius * 2) + LeftSlopeOffset + RightSlopeOffset;
|
||||
|
||||
childRect.Width = Math.Max(0.0, arrangeSize.Width - reservedWidth);
|
||||
childRect.Height = Math.Max(0.0, arrangeSize.Height - reservedHeight);
|
||||
|
||||
|
||||
childRect.X = isHorizontal
|
||||
? padding.Left + borderThickness + cornerRadius + LeftSlopeOffset
|
||||
: padding.Left + borderThickness;
|
||||
|
||||
childRect.Y = isHorizontal
|
||||
? padding.Top + borderThickness
|
||||
: padding.Top + borderThickness + cornerRadius + LeftSlopeOffset;
|
||||
|
||||
child.Arrange(childRect);
|
||||
}
|
||||
|
||||
InvalidateGeometries();
|
||||
|
||||
return arrangeSize;
|
||||
}
|
||||
|
||||
private void InvalidateGeometries()
|
||||
{
|
||||
InvalidateCache();
|
||||
}
|
||||
|
||||
protected override void OnRender(DrawingContext dc)
|
||||
{
|
||||
EnsureBorderPen();
|
||||
Render(dc);
|
||||
}
|
||||
|
||||
private void EnsureBorderPen()
|
||||
{
|
||||
if (_cachedBoderPen != null) return;
|
||||
_cachedBoderPen = new Pen(BorderBrush, BorderThickness);
|
||||
}
|
||||
|
||||
|
||||
public void InvalidateCache()
|
||||
{
|
||||
// they will be re-generated on the render pass
|
||||
_cachedBackgroundGeometry = null;
|
||||
_cachedBorderGeometry = null;
|
||||
}
|
||||
|
||||
public void Render(DrawingContext dc)
|
||||
{
|
||||
var brush = Background;
|
||||
if (brush != null)
|
||||
{
|
||||
EnsureBackgroundGeometry(dc);
|
||||
dc.DrawGeometry(brush, null, _cachedBackgroundGeometry);
|
||||
}
|
||||
|
||||
if (BorderBrush != null)
|
||||
{
|
||||
EnsureBorderGeometry(dc);
|
||||
dc.DrawGeometry(null, _cachedBoderPen, _cachedBorderGeometry);
|
||||
}
|
||||
}
|
||||
|
||||
private void EnsureBackgroundGeometry(DrawingContext dc)
|
||||
{
|
||||
if (_cachedBackgroundGeometry == null)
|
||||
{
|
||||
_cachedBackgroundGeometry = GenerateGeometry(RenderSize, CornerRadius, true, dc);
|
||||
}
|
||||
}
|
||||
|
||||
private void EnsureBorderGeometry(DrawingContext dc)
|
||||
{
|
||||
if (_cachedBorderGeometry == null)
|
||||
{
|
||||
_cachedBorderGeometry = GenerateGeometry(RenderSize, CornerRadius, false, dc);
|
||||
}
|
||||
}
|
||||
|
||||
// will return the origin point for the various cases.
|
||||
private Point GetP0(Rect rect, bool isBackground)
|
||||
{
|
||||
var dock = Dock;
|
||||
var hasCornerRadius = CornerRadius > 0;
|
||||
var hbt = BorderThickness * 0.5;
|
||||
|
||||
var isBottom = (dock & TabItemDock.Bottom) == TabItemDock.Bottom;
|
||||
if (isBottom)
|
||||
{
|
||||
return new Point(rect.Left - (hasCornerRadius ? hbt : 0), rect.Bottom + (isBackground || hasCornerRadius ? 0 : hbt));
|
||||
}
|
||||
|
||||
var isTop = (dock & TabItemDock.Top) == TabItemDock.Top;
|
||||
if (isTop)
|
||||
{
|
||||
return new Point(rect.Left - (hasCornerRadius ? hbt : 0), rect.Top - (isBackground || hasCornerRadius ? 0 : hbt));
|
||||
}
|
||||
|
||||
var isLeft = (dock & TabItemDock.Left) == TabItemDock.Left;
|
||||
if (isLeft)
|
||||
{
|
||||
return new Point(rect.Left + (isBackground || hasCornerRadius ? 0 : hbt), rect.Top - (hasCornerRadius ? hbt : 0.0));
|
||||
}
|
||||
|
||||
var isRight = (dock & TabItemDock.Right) == TabItemDock.Right;
|
||||
Debug.Assert(isRight);
|
||||
return new Point(rect.Right + (isBackground || hasCornerRadius ? 0 : hbt), rect.Top - (hasCornerRadius ? hbt : 0.0));
|
||||
}
|
||||
|
||||
private Point GetP1(Rect rect, double cr)
|
||||
{
|
||||
var dock = Dock;
|
||||
var isBottom = (dock & TabItemDock.Bottom) == TabItemDock.Bottom;
|
||||
if (isBottom)
|
||||
{
|
||||
return new Point(rect.Left + cr, rect.Bottom - cr);
|
||||
}
|
||||
|
||||
var isTop = (dock & TabItemDock.Top) == TabItemDock.Top;
|
||||
if (isTop)
|
||||
{
|
||||
return new Point(rect.Left + cr, rect.Top + cr);
|
||||
}
|
||||
|
||||
var isLeft = (dock & TabItemDock.Left) == TabItemDock.Left;
|
||||
if (isLeft)
|
||||
{
|
||||
return new Point(rect.Left + cr, rect.Top + cr);
|
||||
}
|
||||
|
||||
return new Point(rect.Right - cr, rect.Top + cr);
|
||||
}
|
||||
|
||||
private Point GetP2(Rect rect, double cr, double leftSlopeOffset)
|
||||
{
|
||||
var dock = Dock;
|
||||
var isBottom = (dock & TabItemDock.Bottom) == TabItemDock.Bottom;
|
||||
if (isBottom)
|
||||
{
|
||||
return new Point(rect.Left + cr + leftSlopeOffset, rect.Top + cr);
|
||||
}
|
||||
|
||||
var isTop = (dock & TabItemDock.Top) == TabItemDock.Top;
|
||||
if (isTop)
|
||||
{
|
||||
return new Point(rect.Left + cr + leftSlopeOffset, rect.Bottom - cr);
|
||||
}
|
||||
|
||||
var isLeft = (dock & TabItemDock.Left) == TabItemDock.Left;
|
||||
if (isLeft)
|
||||
{
|
||||
return new Point(rect.Right - cr, rect.Top + leftSlopeOffset + cr);
|
||||
}
|
||||
|
||||
return new Point(rect.Left + cr, rect.Top + leftSlopeOffset + cr);
|
||||
}
|
||||
|
||||
private Point GetP3(Rect rect, double cr, double leftSlopeOffset)
|
||||
{
|
||||
var dock = Dock;
|
||||
var isBottom = (dock & TabItemDock.Bottom) == TabItemDock.Bottom;
|
||||
if (isBottom)
|
||||
{
|
||||
return new Point(rect.Left + leftSlopeOffset + cr * 2, rect.Top);
|
||||
}
|
||||
|
||||
var isTop = (dock & TabItemDock.Top) == TabItemDock.Top;
|
||||
if (isTop)
|
||||
{
|
||||
return new Point(rect.Left + leftSlopeOffset + cr * 2, rect.Bottom);
|
||||
}
|
||||
|
||||
var isLeft = (dock & TabItemDock.Left) == TabItemDock.Left;
|
||||
if (isLeft)
|
||||
{
|
||||
return new Point(rect.Right, rect.Top + leftSlopeOffset + cr * 2);
|
||||
}
|
||||
|
||||
return new Point(rect.Left, rect.Top + leftSlopeOffset + cr * 2);
|
||||
}
|
||||
|
||||
private Point GetP4(Rect rect, double cr, double rightSlopeOffset)
|
||||
{
|
||||
var dock = Dock;
|
||||
var isBottom = (dock & TabItemDock.Bottom) == TabItemDock.Bottom;
|
||||
if (isBottom)
|
||||
{
|
||||
return new Point(rect.Right - rightSlopeOffset - (cr * 2), rect.Top);
|
||||
}
|
||||
|
||||
var isTop = (dock & TabItemDock.Top) == TabItemDock.Top;
|
||||
if (isTop)
|
||||
{
|
||||
return new Point(rect.Right - rightSlopeOffset - (cr * 2), rect.Bottom);
|
||||
}
|
||||
|
||||
var isLeft = (dock & TabItemDock.Left) == TabItemDock.Left;
|
||||
if (isLeft)
|
||||
{
|
||||
return new Point(rect.Right, rect.Bottom - rightSlopeOffset - (cr * 2));
|
||||
}
|
||||
|
||||
return new Point(rect.Left, rect.Bottom - rightSlopeOffset - (cr * 2));
|
||||
}
|
||||
|
||||
private Point GetP5(Rect rect, double cr, double rightSlopeOffset)
|
||||
{
|
||||
var dock = Dock;
|
||||
var isBottom = (dock & TabItemDock.Bottom) == TabItemDock.Bottom;
|
||||
if (isBottom)
|
||||
{
|
||||
return new Point(rect.Right - rightSlopeOffset - cr, rect.Top + cr);
|
||||
}
|
||||
|
||||
var isTop = (dock & TabItemDock.Top) == TabItemDock.Top;
|
||||
if (isTop)
|
||||
{
|
||||
return new Point(rect.Right - rightSlopeOffset - cr, rect.Bottom - cr);
|
||||
}
|
||||
|
||||
var isLeft = (dock & TabItemDock.Left) == TabItemDock.Left;
|
||||
if (isLeft)
|
||||
{
|
||||
return new Point(rect.Right - cr, rect.Bottom - rightSlopeOffset - cr);
|
||||
}
|
||||
|
||||
return new Point(rect.Left + cr, rect.Bottom - rightSlopeOffset - cr);
|
||||
}
|
||||
|
||||
private Point GetP6(Rect rect, double cr, bool isBackground, bool hasCornerRadius, double hbt)
|
||||
{
|
||||
var dock = Dock;
|
||||
var isBottom = (dock & TabItemDock.Bottom) == TabItemDock.Bottom;
|
||||
if (isBottom)
|
||||
{
|
||||
return new Point(rect.Right - cr, rect.Bottom - cr + (isBackground || hasCornerRadius ? 0 : hbt));
|
||||
}
|
||||
|
||||
var isTop = (dock & TabItemDock.Top) == TabItemDock.Top;
|
||||
if (isTop)
|
||||
{
|
||||
return new Point(rect.Right - cr, rect.Top + cr + (isBackground || hasCornerRadius ? 0 : hbt));
|
||||
}
|
||||
|
||||
var isLeft = (dock & TabItemDock.Left) == TabItemDock.Left;
|
||||
if (isLeft)
|
||||
{
|
||||
return new Point(rect.Left + cr + (isBackground || hasCornerRadius ? 0 : hbt), rect.Bottom - cr);
|
||||
}
|
||||
|
||||
return new Point(rect.Right - cr - (isBackground || hasCornerRadius ? 0 : hbt), rect.Bottom - cr);
|
||||
}
|
||||
|
||||
private Point GetP7(Rect rect, double hbt)
|
||||
{
|
||||
var dock = Dock;
|
||||
var isBottom = (dock & TabItemDock.Bottom) == TabItemDock.Bottom;
|
||||
if (isBottom)
|
||||
{
|
||||
return new Point(rect.Right + hbt, rect.Bottom);
|
||||
}
|
||||
|
||||
var isTop = (dock & TabItemDock.Top) == TabItemDock.Top;
|
||||
if (isTop)
|
||||
{
|
||||
return new Point(rect.Right + hbt, rect.Top);
|
||||
}
|
||||
|
||||
var isLeft = (dock & TabItemDock.Left) == TabItemDock.Left;
|
||||
if (isLeft)
|
||||
{
|
||||
return new Point(rect.Left, rect.Bottom + hbt);
|
||||
}
|
||||
|
||||
return new Point(rect.Right, rect.Bottom + hbt);
|
||||
}
|
||||
|
||||
private Point GetCp1(Rect rect, Point p1, Point p2)
|
||||
{
|
||||
var leftLineEquation = new LineEquation(p1, p2);
|
||||
var dock = Dock;
|
||||
|
||||
var isBottom = (dock & TabItemDock.Bottom) == TabItemDock.Bottom;
|
||||
if (isBottom)
|
||||
{
|
||||
// the 1st control point is the intersection between the slope line and the base line.
|
||||
return leftLineEquation.IntersectWithHorizontalLine(p1.X, rect.Bottom);
|
||||
}
|
||||
|
||||
var isTop = (dock & TabItemDock.Top) == TabItemDock.Top;
|
||||
if (isTop)
|
||||
{
|
||||
return leftLineEquation.IntersectWithHorizontalLine(p1.X, rect.Top);
|
||||
}
|
||||
|
||||
var isLeft = (dock & TabItemDock.Left) == TabItemDock.Left;
|
||||
if (isLeft)
|
||||
{
|
||||
return leftLineEquation.IntersectWithVerticalLine(p1.Y, rect.Left);
|
||||
}
|
||||
|
||||
return leftLineEquation.IntersectWithVerticalLine(p1.Y, rect.Right);
|
||||
}
|
||||
|
||||
private Point GetCp2(Rect rect, Point p1, Point p2)
|
||||
{
|
||||
var leftLineEquation = new LineEquation(p1, p2);
|
||||
var dock = Dock;
|
||||
|
||||
var isBottom = (dock & TabItemDock.Bottom) == TabItemDock.Bottom;
|
||||
if (isBottom)
|
||||
{
|
||||
// the 1st control point is the intersection between the slope line and the base line.
|
||||
return leftLineEquation.IntersectWithHorizontalLine(p2.X, rect.Top);
|
||||
}
|
||||
|
||||
var isTop = (dock & TabItemDock.Top) == TabItemDock.Top;
|
||||
if (isTop)
|
||||
{
|
||||
return leftLineEquation.IntersectWithHorizontalLine(p2.X, rect.Bottom);
|
||||
}
|
||||
|
||||
var isLeft = (dock & TabItemDock.Left) == TabItemDock.Left;
|
||||
if (isLeft)
|
||||
{
|
||||
return leftLineEquation.IntersectWithVerticalLine(p2.Y, rect.Right);
|
||||
}
|
||||
|
||||
return leftLineEquation.IntersectWithVerticalLine(p2.Y, rect.Left);
|
||||
}
|
||||
|
||||
private Point GetCp3(Rect rect, Point p1, Point p2)
|
||||
{
|
||||
var rightLineEquation = new LineEquation(p1, p2);
|
||||
var dock = Dock;
|
||||
|
||||
var isBottom = (dock & TabItemDock.Bottom) == TabItemDock.Bottom;
|
||||
if (isBottom)
|
||||
{
|
||||
return rightLineEquation.IntersectWithHorizontalLine(p1.X, rect.Top);
|
||||
}
|
||||
|
||||
var isTop = (dock & TabItemDock.Top) == TabItemDock.Top;
|
||||
if (isTop)
|
||||
{
|
||||
return rightLineEquation.IntersectWithHorizontalLine(p1.X, rect.Bottom);
|
||||
}
|
||||
|
||||
var isLeft = (dock & TabItemDock.Left) == TabItemDock.Left;
|
||||
if (isLeft)
|
||||
{
|
||||
return rightLineEquation.IntersectWithVerticalLine(p1.Y, rect.Right);
|
||||
}
|
||||
|
||||
return rightLineEquation.IntersectWithVerticalLine(p1.Y, rect.Left);
|
||||
}
|
||||
|
||||
private Point GetCp4(Rect rect, Point p1, Point p2)
|
||||
{
|
||||
var rightLineEquation = new LineEquation(p1, p2);
|
||||
var dock = Dock;
|
||||
|
||||
var isBottom = (dock & TabItemDock.Bottom) == TabItemDock.Bottom;
|
||||
if (isBottom)
|
||||
{
|
||||
return rightLineEquation.IntersectWithHorizontalLine(p2.X, rect.Bottom);
|
||||
}
|
||||
|
||||
var isTop = (dock & TabItemDock.Top) == TabItemDock.Top;
|
||||
if (isTop)
|
||||
{
|
||||
return rightLineEquation.IntersectWithHorizontalLine(p2.X, rect.Top);
|
||||
}
|
||||
|
||||
var isLeft = (dock & TabItemDock.Left) == TabItemDock.Left;
|
||||
if (isLeft)
|
||||
{
|
||||
return rightLineEquation.IntersectWithVerticalLine(p2.Y, rect.Left);
|
||||
}
|
||||
|
||||
return rightLineEquation.IntersectWithVerticalLine(p2.Y, rect.Right);
|
||||
}
|
||||
|
||||
private Geometry GenerateGeometry(Size renderSize, double cr, bool isBackground, DrawingContext dc)
|
||||
{
|
||||
var bt = BorderThickness;
|
||||
var hbt = bt * 0.5;
|
||||
var rect = new Rect(hbt, hbt, renderSize.Width - bt, renderSize.Height - bt);
|
||||
var geometry = new StreamGeometry();
|
||||
const bool isStroked = true;
|
||||
var hasCornerRadius = cr > 0;
|
||||
var leftSlopeOffset = LeftSlopeOffset;
|
||||
var rightSlopeOffset = RightSlopeOffset;
|
||||
|
||||
using (var ctx = geometry.Open())
|
||||
{
|
||||
var p0 = GetP0(rect, isBackground);
|
||||
ctx.BeginFigure(p0, true /* is filled */, false);
|
||||
|
||||
var p1 = GetP1(rect, cr);
|
||||
var p2 = GetP2(rect, cr, leftSlopeOffset);
|
||||
|
||||
// the 1st control point is the intersection between the slope line and the base line.
|
||||
var cp1 = GetCp1(rect, p1, p2);
|
||||
|
||||
ctx.QuadraticBezierTo(cp1, p1, isStroked, false);
|
||||
|
||||
ctx.LineTo(p2, isStroked, false);
|
||||
|
||||
var cp2 = GetCp2(rect, p1, p2);
|
||||
|
||||
var p3 = GetP3(rect, cr, leftSlopeOffset);
|
||||
ctx.QuadraticBezierTo(cp2, p3, isStroked, false);
|
||||
|
||||
var p4 = GetP4(rect, cr, rightSlopeOffset);
|
||||
ctx.LineTo(p4, isStroked, false);
|
||||
|
||||
var p5 = GetP5(rect, cr, rightSlopeOffset);
|
||||
var p6 = GetP6(rect, cr, isBackground, hasCornerRadius, hbt);
|
||||
|
||||
var cp3 = GetCp3(rect, p5, p6);
|
||||
ctx.QuadraticBezierTo(cp3, p5, isStroked, false);
|
||||
|
||||
ctx.LineTo(p6, isStroked, false);
|
||||
|
||||
var p7 = GetP7(rect, hbt);
|
||||
var cp4 = GetCp4(rect, p5, p6);
|
||||
ctx.QuadraticBezierTo(cp4, p7, isStroked, false);
|
||||
}
|
||||
|
||||
geometry.Freeze();
|
||||
|
||||
// I found it very hard to construct a background geometry
|
||||
// that doesn't overlap the border geometry, the issue was
|
||||
// always the bottom left/right corner radius.
|
||||
// so what I am doing is constructing the background geometry based
|
||||
// on the border geometry and stretching to fill the remaining
|
||||
// bottom space.
|
||||
return isBackground ? ApplyTransform(geometry, bt, renderSize) : geometry;
|
||||
}
|
||||
|
||||
private void DrawPoint(DrawingContext dc, params Point[] pts)
|
||||
{
|
||||
foreach (var pt in pts)
|
||||
{
|
||||
dc.DrawEllipse(Brushes.Brown, null, new Point(pt.X - 0.5, pt.Y - 0.5), 1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
private static Geometry ApplyTransform(Geometry geometry, double bt, Size renderSize)
|
||||
{
|
||||
var pathGeometry = new PathGeometry();
|
||||
pathGeometry.AddGeometry(geometry);
|
||||
|
||||
var hbt = bt * 0.5;
|
||||
//var scaleY = ((hbt * 100) / renderSize.Height) / 100;
|
||||
var scaleY = hbt / renderSize.Height;
|
||||
pathGeometry.Transform = new ScaleTransform(1, scaleY + 1, renderSize.Width * 0.5, 0);
|
||||
pathGeometry.Freeze();
|
||||
return pathGeometry;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,17 +0,0 @@
|
|||
// Copyright (c) The Avalonia Project. All rights reserved.
|
||||
// Licensed under the MIT license. See license.md file in the project root for full license information.
|
||||
|
||||
using System;
|
||||
|
||||
namespace AvaloniaVS.Controls.Primitives
|
||||
{
|
||||
[Flags]
|
||||
public enum TabItemDock
|
||||
{
|
||||
None = 0,
|
||||
Bottom = 1,
|
||||
Top = Bottom << 1,
|
||||
Left = Top << 1,
|
||||
Right = Left << 1
|
||||
}
|
||||
}
|
|
@ -1,55 +0,0 @@
|
|||
using System.Reflection;
|
||||
using System.Resources;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Windows;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("AvaloniaVS.Controls")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("AvaloniaVS.Controls")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2016")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
//In order to begin building localizable applications, set
|
||||
//<UICulture>CultureYouAreCodingWith</UICulture> in your .csproj file
|
||||
//inside a <PropertyGroup>. For example, if you are using US english
|
||||
//in your source files, set the <UICulture> to en-US. Then uncomment
|
||||
//the NeutralResourceLanguage attribute below. Update the "en-US" in
|
||||
//the line below to match the UICulture setting in the project file.
|
||||
|
||||
//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)]
|
||||
|
||||
|
||||
[assembly: ThemeInfo(
|
||||
ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
|
||||
//(used if a resource is not found in the page,
|
||||
// or application resource dictionaries)
|
||||
ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
|
||||
//(used if a resource is not found in the page,
|
||||
// app, or any theme specific resource dictionaries)
|
||||
)]
|
||||
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
|
@ -1,71 +0,0 @@
|
|||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version:4.0.30319.42000
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace AvaloniaVS.Controls.Properties
|
||||
{
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// A strongly-typed resource class, for looking up localized strings, etc.
|
||||
/// </summary>
|
||||
// This class was auto-generated by the StronglyTypedResourceBuilder
|
||||
// class via a tool like ResGen or Visual Studio.
|
||||
// To add or remove a member, edit your .ResX file then rerun ResGen
|
||||
// with the /str option, or rebuild your VS project.
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
internal class Resources
|
||||
{
|
||||
|
||||
private static global::System.Resources.ResourceManager resourceMan;
|
||||
|
||||
private static global::System.Globalization.CultureInfo resourceCulture;
|
||||
|
||||
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
|
||||
internal Resources()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the cached ResourceManager instance used by this class.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Resources.ResourceManager ResourceManager
|
||||
{
|
||||
get
|
||||
{
|
||||
if ((resourceMan == null))
|
||||
{
|
||||
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("AvaloniaVS.Controls.Properties.Resources", typeof(Resources).Assembly);
|
||||
resourceMan = temp;
|
||||
}
|
||||
return resourceMan;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Overrides the current thread's CurrentUICulture property for all
|
||||
/// resource lookups using this strongly typed resource class.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Globalization.CultureInfo Culture
|
||||
{
|
||||
get
|
||||
{
|
||||
return resourceCulture;
|
||||
}
|
||||
set
|
||||
{
|
||||
resourceCulture = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,117 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
</root>
|
|
@ -1,30 +0,0 @@
|
|||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version:4.0.30319.42000
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace AvaloniaVS.Controls.Properties
|
||||
{
|
||||
|
||||
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")]
|
||||
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase
|
||||
{
|
||||
|
||||
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
|
||||
|
||||
public static Settings Default
|
||||
{
|
||||
get
|
||||
{
|
||||
return defaultInstance;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,7 +0,0 @@
|
|||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<SettingsFile xmlns="uri:settings" CurrentProfile="(Default)">
|
||||
<Profiles>
|
||||
<Profile Name="(Default)" />
|
||||
</Profiles>
|
||||
<Settings />
|
||||
</SettingsFile>
|
|
@ -1,77 +0,0 @@
|
|||
// Copyright (c) The Avalonia Project. All rights reserved.
|
||||
// Licensed under the MIT license. See license.md file in the project root for full license information.
|
||||
|
||||
using System.Windows.Input;
|
||||
|
||||
namespace AvaloniaVS.Controls
|
||||
{
|
||||
public static class SplitterCommands
|
||||
{
|
||||
private static RoutedUICommand _expandCollapsePaneCommand;
|
||||
private static RoutedUICommand _splitVerticalCommand;
|
||||
private static RoutedUICommand _splitHorizontalCommand;
|
||||
private static RoutedUICommand _swapPanesCommand;
|
||||
private static RoutedUICommand _activateViewCommand;
|
||||
|
||||
public static RoutedUICommand ActivateViewCommand
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_activateViewCommand == null)
|
||||
{
|
||||
_activateViewCommand = new RoutedUICommand("Activate View", "ActivateView", typeof(SplitterCommands));
|
||||
}
|
||||
|
||||
return _activateViewCommand;
|
||||
}
|
||||
}
|
||||
|
||||
public static RoutedUICommand ExpandCollapsePaneCommand
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_expandCollapsePaneCommand == null)
|
||||
{
|
||||
_expandCollapsePaneCommand = new RoutedUICommand("Expand/Collapse Pane", "ExpandCollapsePaneCommand", typeof(SplitterCommands));
|
||||
}
|
||||
return _expandCollapsePaneCommand;
|
||||
}
|
||||
}
|
||||
|
||||
public static RoutedUICommand SplitVerticalCommand
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_splitVerticalCommand == null)
|
||||
{
|
||||
_splitVerticalCommand = new RoutedUICommand("Split Vertical", "SplitVerticalCommand", typeof(SplitterCommands));
|
||||
}
|
||||
return _splitVerticalCommand;
|
||||
}
|
||||
}
|
||||
|
||||
public static RoutedUICommand SplitHorizontalCommand
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_splitHorizontalCommand == null)
|
||||
{
|
||||
_splitHorizontalCommand = new RoutedUICommand("Split Horizontal", "SplitHorizontalCommand", typeof(SplitterCommands));
|
||||
}
|
||||
return _splitHorizontalCommand;
|
||||
}
|
||||
}
|
||||
|
||||
public static RoutedUICommand SwapPanesCommand
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_swapPanesCommand == null)
|
||||
{
|
||||
_swapPanesCommand = new RoutedUICommand("Swap Panes", "SwapPanesCommand", typeof(SplitterCommands));
|
||||
}
|
||||
return _swapPanesCommand;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,830 +0,0 @@
|
|||
// Copyright (c) The Avalonia Project. All rights reserved.
|
||||
// Licensed under the MIT license. See license.md file in the project root for full license information.
|
||||
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Controls.Primitives;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using AvaloniaVS.Controls.Internals;
|
||||
|
||||
namespace AvaloniaVS.Controls
|
||||
{
|
||||
/// <summary>
|
||||
/// An enum that represents the views supported by the <see cref="SplitterContainer"/>.
|
||||
/// </summary>
|
||||
public enum SplitterViews
|
||||
{
|
||||
Design,
|
||||
Editor
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public sealed class SplitterContainer : FrameworkElement
|
||||
{
|
||||
private static Rect s_EmptyRect = new Rect();
|
||||
|
||||
/// <summary>
|
||||
/// Identifies the <see cref="Orientation"/> dependency property.
|
||||
/// </summary>
|
||||
public static readonly DependencyProperty OrientationProperty = DependencyProperty.Register(
|
||||
"Orientation",
|
||||
typeof(Orientation),
|
||||
typeof(SplitterContainer),
|
||||
new FrameworkPropertyMetadata(Orientation.Horizontal,
|
||||
FrameworkPropertyMetadataOptions.AffectsArrange,
|
||||
(o, e) =>
|
||||
{
|
||||
var splitContainer = o as SplitterContainer;
|
||||
if (splitContainer == null || splitContainer._grip == null)
|
||||
return;
|
||||
|
||||
splitContainer._grip.Orientation = (Orientation)e.NewValue;
|
||||
splitContainer.InvalidateOrientationProperties();
|
||||
}),
|
||||
IsValidOrientation);
|
||||
|
||||
/// <summary>
|
||||
/// Identifies the <see cref="IsReversed"/> dependency property.
|
||||
/// </summary>
|
||||
public static readonly DependencyProperty IsReversedProperty = DependencyProperty.Register(
|
||||
"IsReversed",
|
||||
typeof(bool),
|
||||
typeof(SplitterContainer),
|
||||
new FrameworkPropertyMetadata(BooleanBoxes.False,
|
||||
FrameworkPropertyMetadataOptions.AffectsArrange,
|
||||
(o, args) =>
|
||||
{
|
||||
var container = (SplitterContainer)o;
|
||||
container.InvalidateActiveView(false);
|
||||
}));
|
||||
|
||||
private static readonly DependencyPropertyKey IsDesignerActivePropertyKey = DependencyProperty.RegisterReadOnly(
|
||||
"IsDesignerActive",
|
||||
typeof (bool),
|
||||
typeof (SplitterContainer),
|
||||
new FrameworkPropertyMetadata(BooleanBoxes.False));
|
||||
|
||||
/// <summary>
|
||||
/// Identifies the <see cref="IsDesignerActive"/> read-only dependency property.
|
||||
/// </summary>
|
||||
public static readonly DependencyProperty IsDesignerActiveProperty = IsDesignerActivePropertyKey.DependencyProperty;
|
||||
|
||||
private static readonly DependencyPropertyKey IsEditorActivePropertyKey = DependencyProperty.RegisterReadOnly(
|
||||
"IsEditorActive",
|
||||
typeof(bool),
|
||||
typeof(SplitterContainer),
|
||||
new FrameworkPropertyMetadata(BooleanBoxes.False));
|
||||
|
||||
/// <summary>
|
||||
/// Identifies the <see cref="IsEditorActive"/> read-only dependency property.
|
||||
/// </summary>
|
||||
public static readonly DependencyProperty IsEditorActiveProperty = IsEditorActivePropertyKey.DependencyProperty;
|
||||
|
||||
private static readonly DependencyPropertyKey IsCollapsedPropertyKey = DependencyProperty.RegisterReadOnly(
|
||||
"IsCollapsed",
|
||||
typeof(bool),
|
||||
typeof(SplitterContainer),
|
||||
new FrameworkPropertyMetadata(
|
||||
BooleanBoxes.False,
|
||||
(o, args) =>
|
||||
{
|
||||
var splitContainer = o as SplitterContainer;
|
||||
if (splitContainer?._grip == null)
|
||||
return;
|
||||
|
||||
splitContainer.OnIsCollapsedChanged();
|
||||
}));
|
||||
|
||||
/// <summary>
|
||||
/// Identifies the <see cref="IsCollapsed"/> read-only property.
|
||||
/// </summary>
|
||||
public static readonly DependencyProperty IsCollapsedProperty = IsCollapsedPropertyKey.DependencyProperty;
|
||||
|
||||
/// <summary>
|
||||
/// Identifies the <see cref="DesignerHeader"/> dependency property.
|
||||
/// </summary>
|
||||
public static readonly DependencyProperty DesignerHeaderProperty = DependencyProperty.Register(
|
||||
"DesignerHeader",
|
||||
typeof(object),
|
||||
typeof(SplitterContainer),
|
||||
new FrameworkPropertyMetadata(null));
|
||||
|
||||
/// <summary>
|
||||
/// Identifies the <see cref="ExtraPanel"/> dependency property.
|
||||
/// </summary>
|
||||
public static readonly DependencyProperty ExtraPanelProperty = DependencyProperty.Register(
|
||||
"ExtraPanel",
|
||||
typeof(object),
|
||||
typeof(SplitterContainer),
|
||||
new FrameworkPropertyMetadata(null));
|
||||
|
||||
/// <summary>
|
||||
/// Identifies the <see cref="EditorHeader"/> dependency property.
|
||||
/// </summary>
|
||||
public static readonly DependencyProperty EditorHeaderProperty = DependencyProperty.Register(
|
||||
"EditorHeader",
|
||||
typeof(object),
|
||||
typeof(SplitterContainer),
|
||||
new FrameworkPropertyMetadata(null));
|
||||
|
||||
/// <summary>
|
||||
/// IsHorizontal Read-Only Dependency Property
|
||||
/// </summary>
|
||||
private static readonly DependencyPropertyKey IsHorizontalPropertyKey = DependencyProperty.RegisterReadOnly(
|
||||
"IsHorizontal",
|
||||
typeof(bool),
|
||||
typeof(SplitterContainer),
|
||||
new FrameworkPropertyMetadata(BooleanBoxes.False));
|
||||
|
||||
public static readonly DependencyProperty IsHorizontalProperty
|
||||
= IsHorizontalPropertyKey.DependencyProperty;
|
||||
|
||||
/// <summary>
|
||||
/// IsVertical Read-Only Dependency Property
|
||||
/// </summary>
|
||||
private static readonly DependencyPropertyKey IsVerticalPropertyKey = DependencyProperty.RegisterReadOnly(
|
||||
"IsVertical",
|
||||
typeof(bool),
|
||||
typeof(SplitterContainer),
|
||||
new FrameworkPropertyMetadata(BooleanBoxes.False));
|
||||
|
||||
public static readonly DependencyProperty IsVerticalProperty
|
||||
= IsVerticalPropertyKey.DependencyProperty;
|
||||
|
||||
/// <summary>
|
||||
/// Identifies the <see cref="ActiveViewChanged"/> routed event.
|
||||
/// </summary>
|
||||
public static readonly RoutedEvent ActiveViewChangedEvent = EventManager.RegisterRoutedEvent(
|
||||
"ActiveViewChanged",
|
||||
RoutingStrategy.Bubble,
|
||||
typeof(RoutedEventHandler),
|
||||
typeof(SplitterContainer));
|
||||
|
||||
private FrameworkElement _designerContainer;
|
||||
private FrameworkElement _editorContainer;
|
||||
private SplitterGrip _grip;
|
||||
private readonly UIElementCollection _visualChildren;
|
||||
private double _gripOffset = double.NaN; // in percent
|
||||
private double _previousGripOffset;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes static members of the <see cref="SplitterContainer"/> class.
|
||||
/// </summary>
|
||||
static SplitterContainer()
|
||||
{
|
||||
ClipToBoundsProperty.OverrideMetadata(typeof(SplitterContainer), new FrameworkPropertyMetadata(BooleanBoxes.True));
|
||||
InitCommands();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes instance members of the <see cref="SplitterContainer"/> class.
|
||||
/// </summary>
|
||||
public SplitterContainer()
|
||||
{
|
||||
InitSplitterHandle();
|
||||
|
||||
_visualChildren = new UIElementCollection(this, this)
|
||||
{
|
||||
_grip
|
||||
};
|
||||
InvalidateOrientationProperties();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the <see cref="System.Windows.Controls.Orientation"/> of the control.
|
||||
/// </summary>
|
||||
/// <value>The default value is <see cref="System.Windows.Controls.Orientation.Horizontal"/></value>
|
||||
[Bindable(true)]
|
||||
public Orientation Orientation
|
||||
{
|
||||
get { return (Orientation)GetValue(OrientationProperty); }
|
||||
set { SetValue(OrientationProperty, value); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value that indicates whether <see cref="Designer"/> and <see cref="Editor"/> are arranged in reverse.
|
||||
/// The default order is <see cref="Designer"/> at the top/left and the <see cref="Editor"/> is bottom/right.
|
||||
/// </summary>
|
||||
[Bindable(true)]
|
||||
public bool IsReversed
|
||||
{
|
||||
get { return (bool)GetValue(IsReversedProperty); }
|
||||
set { SetValue(IsReversedProperty, BooleanBoxes.Box(value)); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value that indicates whether the <see cref="Designer"/> is the currently active view.
|
||||
/// </summary>
|
||||
public bool IsDesignerActive
|
||||
{
|
||||
get { return (bool)GetValue(IsDesignerActiveProperty); }
|
||||
private set { SetValue(IsDesignerActivePropertyKey, BooleanBoxes.Box(value)); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value that indicates whether the <see cref="Editor"/> is the currently active view.
|
||||
/// </summary>
|
||||
public bool IsEditorActive
|
||||
{
|
||||
get { return (bool)GetValue(IsEditorActiveProperty); }
|
||||
private set { SetValue(IsEditorActivePropertyKey, BooleanBoxes.Box(value)); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value that indicates whether the <see cref="SplitterContainer"/> is collapsed
|
||||
/// and only a single view is displayed at once.
|
||||
/// </summary>
|
||||
public bool IsCollapsed
|
||||
{
|
||||
get { return (bool)GetValue(IsCollapsedProperty); }
|
||||
internal set { SetValue(IsCollapsedPropertyKey, BooleanBoxes.Box(value)); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the content of the <see cref="Designer"/> tab-item header.
|
||||
/// </summary>
|
||||
[Bindable(true)]
|
||||
public object DesignerHeader
|
||||
{
|
||||
get { return (object)GetValue(DesignerHeaderProperty); }
|
||||
set { SetValue(DesignerHeaderProperty, value); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the content of the extra panel
|
||||
/// </summary>
|
||||
[Bindable(true)]
|
||||
public object ExtraPanel
|
||||
{
|
||||
get { return (object)GetValue(ExtraPanelProperty); }
|
||||
set { SetValue(ExtraPanelProperty, value); }
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the content of the <see cref="Editor"/> tab-item header.
|
||||
/// </summary>
|
||||
[Bindable(true)]
|
||||
public object EditorHeader
|
||||
{
|
||||
get { return (object)GetValue(EditorHeaderProperty); }
|
||||
set { SetValue(EditorHeaderProperty, value); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value that indicates whether the <see cref="SplitterContainer"/> views are arranged horizontally.
|
||||
/// </summary>
|
||||
public bool IsHorizontal
|
||||
{
|
||||
get { return (bool)GetValue(IsHorizontalProperty); }
|
||||
private set { SetValue(IsHorizontalPropertyKey, BooleanBoxes.Box(value)); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value that indicates whether the <see cref="SplitterContainer"/> views are arranged vertically.
|
||||
/// </summary>
|
||||
public bool IsVertical
|
||||
{
|
||||
get { return (bool)GetValue(IsVerticalProperty); }
|
||||
private set { SetValue(IsVerticalPropertyKey, BooleanBoxes.Box(value)); }
|
||||
}
|
||||
|
||||
public FrameworkElement Designer
|
||||
{
|
||||
get { return _designerContainer; }
|
||||
set
|
||||
{
|
||||
if (_designerContainer == value)
|
||||
throw new NotSupportedException("");
|
||||
|
||||
UpdateView(_designerContainer, value);
|
||||
_designerContainer = value;
|
||||
}
|
||||
}
|
||||
|
||||
public FrameworkElement Editor
|
||||
{
|
||||
get { return _editorContainer; }
|
||||
set
|
||||
{
|
||||
if (_editorContainer == value)
|
||||
throw new NotSupportedException("");
|
||||
|
||||
UpdateView(_editorContainer, value);
|
||||
_editorContainer = value;
|
||||
}
|
||||
}
|
||||
|
||||
private FrameworkElement InternalView1
|
||||
{
|
||||
get { return IsReversed ? Editor : Designer; }
|
||||
}
|
||||
|
||||
private FrameworkElement InternalView2
|
||||
{
|
||||
get { return IsReversed ? Designer : Editor; }
|
||||
}
|
||||
|
||||
private double Density { get; set; }
|
||||
|
||||
private double InternalOffset
|
||||
{
|
||||
get
|
||||
{
|
||||
return double.IsNaN(_gripOffset) ? 50 : _gripOffset;
|
||||
}
|
||||
}
|
||||
|
||||
protected override int VisualChildrenCount
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_visualChildren == null)
|
||||
return 0;
|
||||
|
||||
return _visualChildren.Count;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when the active view changes, the active view is the one that has keybaord focus.
|
||||
/// </summary>
|
||||
public event RoutedEventHandler ActiveViewChanged
|
||||
{
|
||||
add { AddHandler(ActiveViewChangedEvent, value); }
|
||||
remove { RemoveHandler(ActiveViewChangedEvent, value); }
|
||||
}
|
||||
|
||||
private static bool IsValidOrientation(object value)
|
||||
{
|
||||
var orientation = (Orientation)value;
|
||||
return orientation == Orientation.Horizontal || orientation == Orientation.Vertical;
|
||||
}
|
||||
|
||||
private void OnIsCollapsedChanged()
|
||||
{
|
||||
_grip.IsCollapsed = IsCollapsed;
|
||||
|
||||
if (IsCollapsed)
|
||||
{
|
||||
ActivateView(_activeViewType);
|
||||
}
|
||||
|
||||
InvalidateFocus();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A static helper method to raise the <see cref="ActiveViewChanged"/>
|
||||
/// event on a target <see cref="SplitterContainer"/>.
|
||||
/// </summary>
|
||||
private static void RaiseActiveViewChangedEvent(SplitterContainer target)
|
||||
{
|
||||
if (target == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var rags = new RoutedEventArgs { RoutedEvent = ActiveViewChangedEvent };
|
||||
target.RaiseEvent(rags);
|
||||
}
|
||||
|
||||
private static void InitCommands()
|
||||
{
|
||||
CommandManager.RegisterClassCommandBinding(typeof(SplitterContainer),
|
||||
new CommandBinding(SplitterCommands.ExpandCollapsePaneCommand, OnExpandCollapseExecuted));
|
||||
|
||||
CommandManager.RegisterClassCommandBinding(typeof(SplitterContainer),
|
||||
new CommandBinding(SplitterCommands.SplitHorizontalCommand, OnSplitHorizontalExecuted));
|
||||
|
||||
CommandManager.RegisterClassCommandBinding(typeof(SplitterContainer),
|
||||
new CommandBinding(SplitterCommands.SplitVerticalCommand, OnSplitVerticalExecuted));
|
||||
|
||||
CommandManager.RegisterClassCommandBinding(typeof(SplitterContainer),
|
||||
new CommandBinding(SplitterCommands.SwapPanesCommand, OnSwapPanesExecuted, OnSwapPanesCanExecute));
|
||||
|
||||
CommandManager.RegisterClassCommandBinding(typeof(SplitterContainer), new CommandBinding(SplitterCommands.ActivateViewCommand, OnActivateView));
|
||||
}
|
||||
|
||||
private static void OnActivateView(object sender, ExecutedRoutedEventArgs e)
|
||||
{
|
||||
if (!(e.Parameter is SplitterViews))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var container = (SplitterContainer)sender;
|
||||
container.ActivateView((SplitterViews)e.Parameter);
|
||||
}
|
||||
|
||||
SplitterViews _activeViewType = SplitterViews.Editor;
|
||||
|
||||
private void ActivateView(SplitterViews views)
|
||||
{
|
||||
_activeViewType = views;
|
||||
|
||||
MoveFocusTo(views == SplitterViews.Design ? InternalView1 : InternalView2);
|
||||
InvalidateActiveView();
|
||||
|
||||
// in case we're collapsed, we need to invalidate the arrange to make
|
||||
// the currently activated view visible.
|
||||
if (IsCollapsed)
|
||||
{
|
||||
InvalidateArrange();
|
||||
}
|
||||
}
|
||||
|
||||
private static void OnSwapPanesCanExecute(object sender, CanExecuteRoutedEventArgs e)
|
||||
{
|
||||
var splitContainer = sender as SplitterContainer;
|
||||
if (splitContainer == null)
|
||||
return;
|
||||
|
||||
e.CanExecute = !splitContainer.IsCollapsed;
|
||||
}
|
||||
|
||||
private static void OnSplitHorizontalExecuted(object sender, ExecutedRoutedEventArgs e)
|
||||
{
|
||||
var splitContainer = sender as SplitterContainer;
|
||||
splitContainer?.SwitchOrientation(Orientation.Horizontal);
|
||||
}
|
||||
|
||||
private static void OnSplitVerticalExecuted(object sender, ExecutedRoutedEventArgs e)
|
||||
{
|
||||
var splitContainer = sender as SplitterContainer;
|
||||
splitContainer?.SwitchOrientation(Orientation.Vertical);
|
||||
}
|
||||
|
||||
private void SwitchOrientation(Orientation orientation)
|
||||
{
|
||||
if (IsCollapsed)
|
||||
{
|
||||
_gripOffset = 50;
|
||||
IsCollapsed = false;
|
||||
}
|
||||
|
||||
Orientation = orientation;
|
||||
}
|
||||
|
||||
private static void OnSwapPanesExecuted(object sender, ExecutedRoutedEventArgs e)
|
||||
{
|
||||
var splitContainer = sender as SplitterContainer;
|
||||
splitContainer?.OnSwapPanes();
|
||||
}
|
||||
|
||||
private static void OnExpandCollapseExecuted(object sender, ExecutedRoutedEventArgs e)
|
||||
{
|
||||
var splitContainer = sender as SplitterContainer;
|
||||
splitContainer?.OnExpandCollapse();
|
||||
}
|
||||
|
||||
private void OnExpandCollapse()
|
||||
{
|
||||
if (!IsCollapsed)
|
||||
{
|
||||
_previousGripOffset = double.IsNaN(_gripOffset) ? 50 : _gripOffset;
|
||||
_gripOffset = 100;
|
||||
IsCollapsed = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (DoubleUtilties.AreClose(_previousGripOffset, 0.0))
|
||||
{
|
||||
_previousGripOffset = 50;
|
||||
}
|
||||
|
||||
_gripOffset = _previousGripOffset;
|
||||
IsCollapsed = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnSwapPanes()
|
||||
{
|
||||
IsReversed = !IsReversed;
|
||||
}
|
||||
|
||||
public void SwapActiveView()
|
||||
{
|
||||
ActivateView(_activeViewType == SplitterViews.Design ? SplitterViews.Editor : SplitterViews.Design);
|
||||
}
|
||||
|
||||
private void InvalidateOrientationProperties()
|
||||
{
|
||||
IsHorizontal = Orientation == Orientation.Horizontal;
|
||||
IsVertical = Orientation == Orientation.Vertical;
|
||||
}
|
||||
|
||||
private void InitSplitterHandle()
|
||||
{
|
||||
_grip = new SplitterGrip
|
||||
{
|
||||
Orientation = Orientation,
|
||||
IsCollapsed = IsCollapsed
|
||||
};
|
||||
_grip.DragDelta += OnGripDragDelta;
|
||||
_grip.DragCompleted += OnDragCompleted;
|
||||
}
|
||||
|
||||
private void OnGripDragDelta(object sender, DragDeltaEventArgs e)
|
||||
{
|
||||
var isHorizontal = Orientation == Orientation.Horizontal;
|
||||
var change = isHorizontal ? e.VerticalChange : e.HorizontalChange;
|
||||
|
||||
if (_grip.Popup != null)
|
||||
{
|
||||
InitializePopup(_grip.Popup);
|
||||
InvalidatePopupPlacement(_grip.Popup, change);
|
||||
}
|
||||
|
||||
e.Handled = true;
|
||||
}
|
||||
|
||||
private void InvalidatePopupPlacement(Popup popup, double change)
|
||||
{
|
||||
var rect = LayoutInformation.GetLayoutSlot(_grip);
|
||||
var isHorizontal = Orientation == Orientation.Horizontal;
|
||||
var offset = (isHorizontal ? rect.Top : rect.Left) + change;
|
||||
var maxOffset = isHorizontal ? (this.ActualHeight - 5) : (this.ActualWidth - 5);
|
||||
|
||||
offset = offset + 5;
|
||||
offset = Math.Max(0, offset);
|
||||
offset = Math.Min(offset, maxOffset);
|
||||
|
||||
if (isHorizontal)
|
||||
popup.VerticalOffset = offset;
|
||||
else
|
||||
popup.HorizontalOffset = offset;
|
||||
}
|
||||
|
||||
private void InitializePopup(Popup popup)
|
||||
{
|
||||
if (popup == null || popup.IsOpen)
|
||||
return;
|
||||
|
||||
popup.Placement = PlacementMode.Relative;
|
||||
popup.PlacementTarget = this;
|
||||
popup.IsOpen = true;
|
||||
}
|
||||
|
||||
private void ComputeOffset(double change)
|
||||
{
|
||||
var offset = InternalOffset;
|
||||
offset += Density * change;
|
||||
|
||||
CoerceOffset(ref offset);
|
||||
|
||||
_gripOffset = offset;
|
||||
InvalidateMeasure();
|
||||
InvalidateArrange();
|
||||
}
|
||||
|
||||
private void CoerceOffset(ref double offset)
|
||||
{
|
||||
var isCollapsed = false;
|
||||
|
||||
if (offset < 0.0)
|
||||
{
|
||||
offset = 100;
|
||||
isCollapsed = true;
|
||||
}
|
||||
else if (offset > 100)
|
||||
{
|
||||
offset = 100;
|
||||
isCollapsed = true;
|
||||
}
|
||||
|
||||
IsCollapsed = isCollapsed;
|
||||
}
|
||||
|
||||
private void OnDragCompleted(object sender, DragCompletedEventArgs e)
|
||||
{
|
||||
var change = Orientation == Orientation.Horizontal ? e.VerticalChange : e.HorizontalChange;
|
||||
ComputeOffset(change);
|
||||
_grip.Popup.IsOpen = false;
|
||||
}
|
||||
|
||||
private void UpdateView(FrameworkElement oldView, FrameworkElement newView)
|
||||
{
|
||||
if (oldView == newView)
|
||||
return;
|
||||
|
||||
if (oldView != null)
|
||||
_visualChildren.Remove(oldView);
|
||||
|
||||
if (newView != null)
|
||||
_visualChildren.Add(newView);
|
||||
|
||||
InvalidateMeasure();
|
||||
InvalidateArrange();
|
||||
}
|
||||
|
||||
protected override Visual GetVisualChild(int index)
|
||||
{
|
||||
if (_visualChildren == null || (index < 0 || index > (_visualChildren.Count - 1)))
|
||||
throw new ArgumentOutOfRangeException(nameof(index));
|
||||
|
||||
return _visualChildren[index];
|
||||
}
|
||||
|
||||
protected override Size MeasureOverride(Size availableSize)
|
||||
{
|
||||
var isHorizontal = Orientation == Orientation.Horizontal;
|
||||
|
||||
if (isHorizontal && (double.IsPositiveInfinity(availableSize.Height) || double.IsInfinity(availableSize.Height)))
|
||||
return base.MeasureOverride(availableSize);
|
||||
|
||||
if (!isHorizontal && (double.IsPositiveInfinity(availableSize.Width) || double.IsInfinity(availableSize.Width)))
|
||||
return base.MeasureOverride(availableSize);
|
||||
|
||||
double startPos, handleSize, designerSize, editorSize;
|
||||
ComputePartsSizes(availableSize, isHorizontal, out designerSize, out editorSize, out handleSize, out startPos);
|
||||
|
||||
var designer = InternalView1;
|
||||
designer?.Measure(isHorizontal
|
||||
? new Size(availableSize.Width, designerSize)
|
||||
: new Size(designerSize, availableSize.Height));
|
||||
|
||||
var editor = InternalView2;
|
||||
editor?.Measure(isHorizontal
|
||||
? new Size(availableSize.Width, editorSize)
|
||||
: new Size(editorSize, availableSize.Height));
|
||||
|
||||
_grip.Measure(availableSize);
|
||||
return _grip.DesiredSize;
|
||||
}
|
||||
|
||||
protected override Size ArrangeOverride(Size finalSize)
|
||||
{
|
||||
// initialization
|
||||
var isHorizontal = Orientation == Orientation.Horizontal;
|
||||
var designer = InternalView1;
|
||||
var editor = InternalView2;
|
||||
|
||||
double designerSize, editorSize, gripSize, startPos;
|
||||
ComputePartsSizes(finalSize, isHorizontal, out designerSize, out editorSize, out gripSize, out startPos);
|
||||
|
||||
|
||||
var finalRect = isHorizontal
|
||||
? new Rect
|
||||
{
|
||||
Location = new Point(0, startPos),
|
||||
Width = finalSize.Width
|
||||
}
|
||||
: new Rect
|
||||
{
|
||||
Location = new Point(startPos, 0),
|
||||
Height = finalSize.Height
|
||||
};
|
||||
|
||||
|
||||
if (IsCollapsed)
|
||||
{
|
||||
// in case we're collapsed, the view arranged is the one active.
|
||||
|
||||
// Designer
|
||||
if (isHorizontal)
|
||||
finalRect.Height = designerSize;
|
||||
else
|
||||
finalRect.Width = designerSize;
|
||||
designer?.Arrange(IsDesignerActive ? finalRect : s_EmptyRect);
|
||||
|
||||
// Editor
|
||||
editor?.Arrange(IsEditorActive ? finalRect : s_EmptyRect);
|
||||
|
||||
// Grip
|
||||
if (isHorizontal)
|
||||
{
|
||||
finalRect.Y += designerSize;
|
||||
finalRect.Height = gripSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
finalRect.X += designerSize;
|
||||
finalRect.Width = gripSize;
|
||||
}
|
||||
_grip.Arrange(finalRect);
|
||||
}
|
||||
else
|
||||
{
|
||||
// designer
|
||||
if (isHorizontal)
|
||||
finalRect.Height = designerSize;
|
||||
else
|
||||
finalRect.Width = designerSize;
|
||||
designer?.Arrange(finalRect);
|
||||
|
||||
// grip
|
||||
if (isHorizontal)
|
||||
{
|
||||
finalRect.Y += designerSize;
|
||||
finalRect.Height = gripSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
finalRect.X += designerSize;
|
||||
finalRect.Width = gripSize;
|
||||
}
|
||||
_grip.Arrange(finalRect);
|
||||
|
||||
// editor
|
||||
if (isHorizontal)
|
||||
{
|
||||
finalRect.Y += gripSize;
|
||||
finalRect.Height = editorSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
finalRect.X += gripSize;
|
||||
finalRect.Width = editorSize;
|
||||
}
|
||||
editor?.Arrange(finalRect);
|
||||
}
|
||||
|
||||
return finalSize;
|
||||
}
|
||||
|
||||
private void ComputePartsSizes(Size arrangeSize,
|
||||
bool isHorizontal,
|
||||
out double designerSize,
|
||||
out double editorSize,
|
||||
out double handleSize,
|
||||
out double startPos)
|
||||
{
|
||||
var offset = InternalOffset;
|
||||
startPos = 0;
|
||||
|
||||
double length;
|
||||
if (isHorizontal)
|
||||
{
|
||||
length = arrangeSize.Height;
|
||||
handleSize = _grip.DesiredSize.Height;
|
||||
}
|
||||
else
|
||||
{
|
||||
length = arrangeSize.Width;
|
||||
handleSize = _grip.DesiredSize.Width;
|
||||
}
|
||||
|
||||
var remainingLength = length - handleSize;
|
||||
if (IsCollapsed) // if either view is collapsed
|
||||
{
|
||||
designerSize = editorSize = remainingLength;
|
||||
}
|
||||
else
|
||||
{
|
||||
designerSize = remainingLength * (offset / 100);
|
||||
editorSize = remainingLength - designerSize;
|
||||
}
|
||||
|
||||
Density = 100 / remainingLength;
|
||||
}
|
||||
|
||||
private void InvalidateFocus()
|
||||
{
|
||||
if (!IsCollapsed)
|
||||
return;
|
||||
|
||||
var activeView = _activeViewType == SplitterViews.Editor ? Editor : Designer;
|
||||
if (activeView?.IsKeyboardFocusWithin ?? false)
|
||||
MoveFocusTo(activeView);
|
||||
}
|
||||
|
||||
public bool IsDesignerVisible => IsCollapsed == false ? true : (!IsReversed ? IsDesignerActive : IsEditorActive);
|
||||
|
||||
private void InvalidateActiveView(bool raiseEvent = true)
|
||||
{
|
||||
IsDesignerActive = _activeViewType == SplitterViews.Design;
|
||||
IsEditorActive = _activeViewType == SplitterViews.Editor;
|
||||
|
||||
if (raiseEvent)
|
||||
{
|
||||
RaiseActiveViewChangedEvent(this);
|
||||
}
|
||||
}
|
||||
|
||||
private static void MoveFocusTo(FrameworkElement element)
|
||||
{
|
||||
if (element != null)
|
||||
Keyboard.Focus(element);
|
||||
}
|
||||
|
||||
public void Collapse(SplitterViews activeView)
|
||||
{
|
||||
OnExpandCollapse();
|
||||
|
||||
_activeViewType = activeView;
|
||||
Loaded += OnContainerLoaded;
|
||||
}
|
||||
|
||||
private void OnContainerLoaded(object sender, RoutedEventArgs routedEventArgs)
|
||||
{
|
||||
ActivateView(_activeViewType);
|
||||
Loaded -= OnContainerLoaded;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,56 +0,0 @@
|
|||
// Copyright (c) The Avalonia Project. All rights reserved.
|
||||
// Licensed under the MIT license. See license.md file in the project root for full license information.
|
||||
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Controls.Primitives;
|
||||
using AvaloniaVS.Controls.Internals;
|
||||
|
||||
namespace AvaloniaVS.Controls
|
||||
{
|
||||
public class SplitterGrip : Thumb
|
||||
{
|
||||
private static readonly DependencyPropertyKey OrientationPropertyKey = DependencyProperty.RegisterReadOnly(
|
||||
"Orientation",
|
||||
typeof(Orientation),
|
||||
typeof(SplitterGrip),
|
||||
new FrameworkPropertyMetadata(Orientation.Horizontal));
|
||||
public static readonly DependencyProperty OrientationProperty = OrientationPropertyKey.DependencyProperty;
|
||||
|
||||
private static readonly DependencyPropertyKey IsCollapsedPropertyKey = DependencyProperty.RegisterReadOnly(
|
||||
"IsCollapsed",
|
||||
typeof(bool),
|
||||
typeof(SplitterGrip),
|
||||
new FrameworkPropertyMetadata(BooleanBoxes.False));
|
||||
|
||||
public static readonly DependencyProperty IsCollapsedProperty = IsCollapsedPropertyKey.DependencyProperty;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes static members of the <see cref="SplitterGrip"/> class.
|
||||
/// </summary>
|
||||
static SplitterGrip()
|
||||
{
|
||||
DefaultStyleKeyProperty.OverrideMetadata(typeof(SplitterGrip), new FrameworkPropertyMetadata(typeof(SplitterGrip)));
|
||||
}
|
||||
|
||||
public Orientation Orientation
|
||||
{
|
||||
get { return (Orientation)GetValue(OrientationProperty); }
|
||||
internal set { SetValue(OrientationPropertyKey, value); }
|
||||
}
|
||||
|
||||
public bool IsCollapsed
|
||||
{
|
||||
get { return (bool)GetValue(IsCollapsedProperty); }
|
||||
internal set { SetValue(IsCollapsedPropertyKey, BooleanBoxes.Box(value)); }
|
||||
}
|
||||
|
||||
internal Popup Popup { get; set; }
|
||||
|
||||
public override void OnApplyTemplate()
|
||||
{
|
||||
base.OnApplyTemplate();
|
||||
Popup = GetTemplateChild("PART_Popup") as Popup;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,534 +0,0 @@
|
|||
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:lc="clr-namespace:AvaloniaVS.Controls"
|
||||
xmlns:pr="clr-namespace:AvaloniaVS.Controls.Primitives"
|
||||
xmlns:internals="clr-namespace:AvaloniaVS.Controls.Internals">
|
||||
|
||||
<Geometry x:Key="HorizontalExpandShape">
|
||||
M 0,0 L0,11 L11,11 L11,0 Z
|
||||
M 1,1 L1,10 L10,10 L10,1 Z
|
||||
M 3,2 L3,4 L4,4 L4,5 L5,5 L5,6 L6,6 L6,5 L7,5 L7,4 L8,4 L8,3 L8,2 L7,2 L7,3 L6,3 L6,4 L5,4 L5,3 L4,3 L4,2 Z
|
||||
M 3,5 L3,7 L4,7 L4,8 L5,8 L5,9 L6,9 L6,8 L7,8 L7,7 L8,7 L8,6 L8,5 L7,5 L7,6 L6,6 L6,7 L5,7 L5,6 L4,6 L4,5 Z
|
||||
</Geometry>
|
||||
<Geometry x:Key="HorizontalCollapseShape">
|
||||
M 0,0 L0,11 L11,11 L11,0 Z
|
||||
M 1,1 L1,10 L10,10 L10,1 Z
|
||||
M 3,9 L3,7 L4,7 L4,6 L5,6 L5,5 L6,5 L6,6 L7,6 L7,7 L8,7 L8,8 L8,9 L7,9 L7,8 L6,8 L6,7 L5,7 L5,8 L4,8 L4,9 Z
|
||||
M 3,6 L3,4 L4,4 L4,3 L5,3 L5,2 L6,2 L6,3 L7,3 L7,4 L8,4 L8,5 L8,6 L7,6 L7,5 L6,5 L6,4 L5,4 L5,5 L4,5 L4,6 Z
|
||||
</Geometry>
|
||||
<Geometry x:Key="VerticalExpandShape">
|
||||
M 0,0 L0,11 L11,11 L11,0 Z
|
||||
M 1,1 L1,10 L10,10 L10,1 Z
|
||||
M 9,3 L7,3 L7,4 L6,4 L6,5 L5,5 L5,6 L6,6 L6,7 L7,7 L7,8 L8,8 L9,8 L9,7 L8,7 L8,6 L7,6 L7,5 L8,5 L8,4 L9,4 Z
|
||||
M 6,3 L4,3 L4,4 L3,4 L3,5 L2,5 L2,6 L3,6 L3,7 L4,7 L4,8 L5,8 L6,8 L6,7 L5,7 L5,6 L4,6 L4,5 L5,5 L5,4 L6,4 Z
|
||||
</Geometry>
|
||||
<Geometry x:Key="VerticalCollapseShape">
|
||||
M 0,0 L0,11 L11,11 L11,0 Z
|
||||
M 1,1 L1,10 L10,10 L10,1 Z
|
||||
M 2,3 L4,3 L4,4 L5,4 L5,5 L6,5 L6,6 L5,6 L5,7 L4,7 L4,8 L3,8 L2,8 L2,7 L3,7 L3,6 L4,6 L4,5 L3,5 L3,4 L2,4 Z
|
||||
M 5,3 L7,3 L7,4 L8,4 L8,5 L9,5 L9,6 L8,6 L8,7 L7,7 L7,8 L6,8 L5,8 L5,7 L6,7 L6,6 L7,6 L7,5 L6,5 L6,4 L5,4 Z
|
||||
</Geometry>
|
||||
|
||||
<Geometry x:Key="HorizontalSwapPanesShape">
|
||||
M 2,11 L3,11 L3,4 L5,4 L5,3 L4,3 L4,2 L3,2 L3,1 L2,1 L2,2 L1,2 L1,3 L0,3 L0,4 L2,4 Z
|
||||
M 8,0 L9,0 L9,7 L11,7 L11,8 L10,8 L10,9 L9,9 L9,10 L8,10 L8,9 L7,9 L7,8 L6,8 L6,7 L8,7 Z
|
||||
</Geometry>
|
||||
|
||||
<Geometry x:Key="VerticalSwapPanesShape">
|
||||
M 11,2 L11,3 L4,3 L4,5 L3,5 L3,4 L2,4 L2,3 L1,3 L1,2 L2,2 L2,1 L3,1 L3,0 L4,0 L4,2 Z
|
||||
M 0,8 L0,9 L7,9 L7,11 L8,11 L8,10 L9,10 L9,9 L10,9 L10,8 L9,8 L9,7 L8,7 L8,6 L7,6 L7,8 Z
|
||||
</Geometry>
|
||||
|
||||
<Style x:Key="SplitterHandleButton" TargetType="Button">
|
||||
<Setter Property="OverridesDefaultStyle" Value="True" />
|
||||
<Setter Property="Focusable" Value="False" />
|
||||
<Setter Property="VerticalAlignment" Value="Center" />
|
||||
<Setter Property="Padding" Value="2" />
|
||||
<Setter Property="Foreground" Value="{DynamicResource {x:Static internals:AvaloniaDesignerBrushes.HeaderActiveTextBrushKey}}" />
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="Button">
|
||||
<Border x:Name="bg"
|
||||
Padding="{TemplateBinding Padding}"
|
||||
Background="Transparent">
|
||||
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
|
||||
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
|
||||
</Border>
|
||||
<ControlTemplate.Triggers>
|
||||
<Trigger Property="IsMouseOver" Value="True">
|
||||
<Setter TargetName="bg" Property="Background" Value="{DynamicResource {x:Static internals:AvaloniaDesignerBrushes.ButtonMouseOverBackgroundBrushKey}}" />
|
||||
<Setter Property="Foreground" Value="{DynamicResource {x:Static internals:AvaloniaDesignerBrushes.ButtonMouseOverForegroundBrushKey}}" />
|
||||
</Trigger>
|
||||
<Trigger Property="IsPressed" Value="True">
|
||||
<Setter TargetName="bg" Property="Background" Value="{DynamicResource {x:Static internals:AvaloniaDesignerBrushes.ButtonPressedBackgroundBrushKey}}" />
|
||||
<Setter Property="Foreground" Value="{DynamicResource {x:Static internals:AvaloniaDesignerBrushes.ButtonPressedForegroundBrushKey}}" />
|
||||
</Trigger>
|
||||
</ControlTemplate.Triggers>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="ExpandCollapseButtonStyle" TargetType="Button">
|
||||
<Setter Property="OverridesDefaultStyle" Value="True" />
|
||||
<Setter Property="Focusable" Value="False" />
|
||||
<Setter Property="VerticalAlignment" Value="Center" />
|
||||
<Setter Property="Padding" Value="2" />
|
||||
<Setter Property="Foreground" Value="{DynamicResource {x:Static internals:AvaloniaDesignerBrushes.HeaderActiveTextBrushKey}}" />
|
||||
<Setter Property="ToolTip" Value="Collapse Pane" />
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="Button">
|
||||
<Border x:Name="bg"
|
||||
Padding="{TemplateBinding Padding}"
|
||||
Background="Transparent">
|
||||
<Path HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
|
||||
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
|
||||
x:Name="image"
|
||||
Fill="{TemplateBinding Foreground}"
|
||||
Data="{StaticResource HorizontalExpandShape}"
|
||||
Width="11"
|
||||
Height="11"
|
||||
SnapsToDevicePixels="True"/>
|
||||
</Border>
|
||||
<ControlTemplate.Triggers>
|
||||
<Trigger Property="IsMouseOver" Value="True">
|
||||
<Setter TargetName="bg" Property="Background" Value="{DynamicResource {x:Static internals:AvaloniaDesignerBrushes.ButtonMouseOverBackgroundBrushKey}}" />
|
||||
<Setter Property="Foreground" Value="{DynamicResource {x:Static internals:AvaloniaDesignerBrushes.ButtonMouseOverForegroundBrushKey}}" />
|
||||
</Trigger>
|
||||
<Trigger Property="IsPressed" Value="True">
|
||||
<Setter TargetName="bg" Property="Background" Value="{DynamicResource {x:Static internals:AvaloniaDesignerBrushes.ButtonPressedBackgroundBrushKey}}" />
|
||||
<Setter Property="Foreground" Value="{DynamicResource {x:Static internals:AvaloniaDesignerBrushes.ButtonPressedForegroundBrushKey}}" />
|
||||
</Trigger>
|
||||
|
||||
<DataTrigger Binding="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=lc:SplitterGrip}, Path=IsCollapsed}" Value="True">
|
||||
<Setter Property="ToolTip" Value="Expand Pane" />
|
||||
<Setter TargetName="image"
|
||||
Property="Data"
|
||||
Value="{StaticResource HorizontalCollapseShape}" />
|
||||
</DataTrigger>
|
||||
|
||||
<DataTrigger Binding="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=lc:SplitterGrip}, Path=Orientation}" Value="Vertical">
|
||||
<Setter TargetName="image" Property="Data" Value="{StaticResource VerticalCollapseShape}" />
|
||||
</DataTrigger>
|
||||
|
||||
<MultiDataTrigger>
|
||||
<MultiDataTrigger.Conditions>
|
||||
<Condition Binding="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=lc:SplitterGrip}, Path=IsCollapsed}" Value="True" />
|
||||
<Condition Binding="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=lc:SplitterGrip}, Path=Orientation}" Value="Vertical" />
|
||||
</MultiDataTrigger.Conditions>
|
||||
<Setter TargetName="image" Property="Data" Value="{StaticResource VerticalExpandShape}" />
|
||||
</MultiDataTrigger>
|
||||
|
||||
</ControlTemplate.Triggers>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="SplitterHandleToggleButton" TargetType="ToggleButton">
|
||||
<Setter Property="OverridesDefaultStyle" Value="True" />
|
||||
<Setter Property="Focusable" Value="False" />
|
||||
<Setter Property="Padding" Value="1" />
|
||||
<Setter Property="VerticalAlignment" Value="Center" />
|
||||
<Setter Property="Foreground" Value="{DynamicResource {x:Static internals:AvaloniaDesignerBrushes.HeaderActiveTextBrushKey}}" />
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="ToggleButton">
|
||||
<Border x:Name="bg"
|
||||
BorderBrush="Transparent"
|
||||
BorderThickness="1"
|
||||
Padding="1"
|
||||
Background="Transparent"
|
||||
SnapsToDevicePixels="True">
|
||||
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
|
||||
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
|
||||
</Border>
|
||||
|
||||
<ControlTemplate.Triggers>
|
||||
<Trigger Property="IsMouseOver" Value="True">
|
||||
<Setter TargetName="bg" Property="Background" Value="{DynamicResource {x:Static internals:AvaloniaDesignerBrushes.ButtonMouseOverBackgroundBrushKey}}" />
|
||||
<Setter TargetName="bg" Property="BorderBrush" Value="{DynamicResource {x:Static internals:AvaloniaDesignerBrushes.ButtonMouseOverBackgroundBrushKey}}" />
|
||||
<Setter Property="Foreground" Value="{DynamicResource {x:Static internals:AvaloniaDesignerBrushes.ButtonMouseOverForegroundBrushKey}}" />
|
||||
</Trigger>
|
||||
<Trigger Property="IsPressed" Value="True">
|
||||
<Setter TargetName="bg" Property="Background" Value="{DynamicResource {x:Static internals:AvaloniaDesignerBrushes.ButtonPressedBackgroundBrushKey}}" />
|
||||
<Setter TargetName="bg" Property="BorderBrush" Value="{DynamicResource {x:Static internals:AvaloniaDesignerBrushes.ButtonPressedBackgroundBrushKey}}" />
|
||||
<Setter Property="Foreground" Value="{DynamicResource {x:Static internals:AvaloniaDesignerBrushes.ButtonPressedForegroundBrushKey}}" />
|
||||
</Trigger>
|
||||
<Trigger Property="IsChecked" Value="True">
|
||||
<Setter TargetName="bg" Property="BorderBrush" Value="{DynamicResource {x:Static internals:AvaloniaDesignerBrushes.ButtonPressedBackgroundBrushKey}}" />
|
||||
</Trigger>
|
||||
</ControlTemplate.Triggers>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="TabItemBaseStyle" TargetType="RadioButton">
|
||||
<Setter Property="OverridesDefaultStyle" Value="True" />
|
||||
<Setter Property="Focusable" Value="False" />
|
||||
<Setter Property="FocusVisualStyle" Value="{x:Null}" />
|
||||
<Setter Property="HorizontalContentAlignment" Value="Center" />
|
||||
<Setter Property="VerticalContentAlignment" Value="Center" />
|
||||
<Setter Property="FontSize" Value="11" />
|
||||
<Setter Property="Padding" Value="8,1" />
|
||||
<Style.Triggers>
|
||||
<Trigger Property="IsChecked" Value="True">
|
||||
<Setter Property="Background" Value="{DynamicResource {x:Static internals:AvaloniaDesignerBrushes.HeaderActiveBrushKey}}" />
|
||||
<Setter Property="Foreground" Value="{DynamicResource {x:Static internals:AvaloniaDesignerBrushes.HeaderActiveTextBrushKey}}" />
|
||||
<Setter Property="Panel.ZIndex" Value="10" />
|
||||
</Trigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="DesignerTabItemStyle" TargetType="RadioButton" BasedOn="{StaticResource TabItemBaseStyle}">
|
||||
<Setter Property="Background" Value="{DynamicResource {x:Static internals:AvaloniaDesignerBrushes.HeaderInactiveBrushKey}}" />
|
||||
<Setter Property="Foreground" Value="{DynamicResource {x:Static internals:AvaloniaDesignerBrushes.HeaderInactiveTextBrushKey}}" />
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="RadioButton">
|
||||
<pr:TabItemBorder x:Name="bg"
|
||||
RightSlopeOffset="8"
|
||||
Dock="Top"
|
||||
SnapsToDevicePixels="True"
|
||||
CornerRadius="3"
|
||||
Padding="{TemplateBinding Padding}"
|
||||
Background="{TemplateBinding Background}">
|
||||
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
|
||||
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
|
||||
</pr:TabItemBorder>
|
||||
|
||||
<ControlTemplate.Triggers>
|
||||
<DataTrigger Binding="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=lc:SplitterGrip}, Path=Orientation}" Value="Vertical">
|
||||
<Setter TargetName="bg" Property="Dock" Value="Left" />
|
||||
<Setter TargetName="bg" Property="RightSlopeOffset" Value="5" />
|
||||
<Setter TargetName="bg" Property="Padding" Value="3,4" />
|
||||
</DataTrigger>
|
||||
|
||||
<MultiDataTrigger>
|
||||
<MultiDataTrigger.Conditions>
|
||||
<Condition Binding="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=lc:SplitterGrip}, Path=IsCollapsed}" Value="True" />
|
||||
<Condition Binding="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=lc:SplitterGrip}, Path=Orientation}" Value="Horizontal" />
|
||||
</MultiDataTrigger.Conditions>
|
||||
|
||||
<Setter TargetName="bg" Property="Dock" Value="None,Top" />
|
||||
<Setter TargetName="bg" Property="Margin" Value="0,0,0,3" />
|
||||
</MultiDataTrigger>
|
||||
|
||||
<MultiDataTrigger>
|
||||
<MultiDataTrigger.Conditions>
|
||||
<Condition Binding="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=lc:SplitterGrip}, Path=IsCollapsed}" Value="True" />
|
||||
<Condition Binding="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=lc:SplitterGrip}, Path=Orientation}" Value="Vertical" />
|
||||
</MultiDataTrigger.Conditions>
|
||||
<Setter TargetName="bg" Property="Dock" Value="None,Left" />
|
||||
</MultiDataTrigger>
|
||||
|
||||
</ControlTemplate.Triggers>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="EditorTabItemStyle" TargetType="RadioButton" BasedOn="{StaticResource TabItemBaseStyle}">
|
||||
<Setter Property="Background" Value="{DynamicResource {x:Static internals:AvaloniaDesignerBrushes.HeaderInactiveBrushKey}}" />
|
||||
<Setter Property="Foreground" Value="{DynamicResource {x:Static internals:AvaloniaDesignerBrushes.HeaderInactiveTextBrushKey}}" />
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="RadioButton">
|
||||
<pr:TabItemBorder x:Name="bg"
|
||||
LeftSlopeOffset="8"
|
||||
Dock="Bottom"
|
||||
SnapsToDevicePixels="True"
|
||||
CornerRadius="3"
|
||||
Padding="{TemplateBinding Padding}"
|
||||
Background="{TemplateBinding Background}">
|
||||
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
|
||||
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
|
||||
</pr:TabItemBorder>
|
||||
|
||||
<ControlTemplate.Triggers>
|
||||
<DataTrigger Binding="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=lc:SplitterGrip}, Path=Orientation}" Value="Vertical">
|
||||
<Setter TargetName="bg" Property="Dock" Value="Right" />
|
||||
<Setter TargetName="bg" Property="LeftSlopeOffset" Value="5" />
|
||||
<Setter Property="Padding" Value="3,4" />
|
||||
</DataTrigger>
|
||||
|
||||
<MultiDataTrigger>
|
||||
<MultiDataTrigger.Conditions>
|
||||
<Condition Binding="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=lc:SplitterGrip}, Path=IsCollapsed}" Value="True" />
|
||||
<Condition Binding="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=lc:SplitterGrip}, Path=Orientation}" Value="Horizontal" />
|
||||
</MultiDataTrigger.Conditions>
|
||||
|
||||
<Setter TargetName="bg" Property="Dock" Value="None,Top" />
|
||||
<Setter TargetName="bg" Property="LeftSlopeOffset" Value="0" />
|
||||
<Setter TargetName="bg" Property="RightSlopeOffset" Value="8" />
|
||||
<Setter TargetName="bg" Property="Margin" Value="0,0,0,3" />
|
||||
</MultiDataTrigger>
|
||||
|
||||
<MultiDataTrigger>
|
||||
<MultiDataTrigger.Conditions>
|
||||
<Condition Binding="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=lc:SplitterGrip}, Path=IsCollapsed}" Value="True" />
|
||||
<Condition Binding="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=lc:SplitterGrip}, Path=Orientation}" Value="Vertical" />
|
||||
</MultiDataTrigger.Conditions>
|
||||
<Setter TargetName="bg" Property="Dock" Value="None,Left" />
|
||||
<Setter TargetName="bg" Property="LeftSlopeOffset" Value="0" />
|
||||
<Setter TargetName="bg" Property="RightSlopeOffset" Value="8" />
|
||||
<Setter TargetName="bg" Property="Margin" Value="0,0,3,0" />
|
||||
</MultiDataTrigger>
|
||||
</ControlTemplate.Triggers>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<ControlTemplate x:Key="VerticalSpliterGrip" TargetType="lc:SplitterGrip">
|
||||
<Grid>
|
||||
<Border IsHitTestVisible="False"
|
||||
Background="{TemplateBinding Background}" />
|
||||
<Popup x:Name="PART_Popup"
|
||||
AllowsTransparency="True"
|
||||
Focusable="False"
|
||||
IsOpen="False">
|
||||
<Border Background="#808080" Width="5" Height="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=ActualHeight}" />
|
||||
</Popup>
|
||||
<DockPanel LastChildFill="True">
|
||||
<Button x:Name="ExpandCollapseButton"
|
||||
DockPanel.Dock="Bottom"
|
||||
HorizontalAlignment="Center"
|
||||
Style="{StaticResource ExpandCollapseButtonStyle}"
|
||||
Command="{x:Static lc:SplitterCommands.ExpandCollapsePaneCommand}">
|
||||
</Button>
|
||||
<ToggleButton x:Name="SplitHorizontalButton"
|
||||
DockPanel.Dock="Bottom"
|
||||
Style="{StaticResource ResourceKey=SplitterHandleToggleButton}"
|
||||
ToolTip="Horizontal Split"
|
||||
HorizontalAlignment="Center"
|
||||
IsChecked="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=lc:SplitterContainer}, Path=IsHorizontal, Mode=OneWay}"
|
||||
Command="{x:Static lc:SplitterCommands.SplitHorizontalCommand}">
|
||||
<Path x:Name="HorizontalPath"
|
||||
Fill="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=ToggleButton}, Path=Foreground}"
|
||||
Data="M 0,0 L0,11 L11,11 L11,0 Z
|
||||
M 1,1 L1,10 L10,10 L10,1 Z
|
||||
M 2,5 L9,5 L9,6 L2,6 Z"
|
||||
Width="11"
|
||||
Height="11"
|
||||
Visibility="Visible"
|
||||
SnapsToDevicePixels="True" />
|
||||
</ToggleButton>
|
||||
<ToggleButton x:Name="SplitVerticalButton"
|
||||
DockPanel.Dock="Bottom"
|
||||
HorizontalAlignment="Center"
|
||||
Style="{StaticResource ResourceKey=SplitterHandleToggleButton}"
|
||||
ToolTip="Vertical Split"
|
||||
IsChecked="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=lc:SplitterContainer}, Path=IsVertical, Mode=OneWay}"
|
||||
Command="{x:Static lc:SplitterCommands.SplitVerticalCommand}">
|
||||
<Path x:Name="VerticalPath"
|
||||
Fill="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=ToggleButton}, Path=Foreground}"
|
||||
Data="M 0,0 L0,11 L11,11 L11,0 Z
|
||||
M 1,1 L1,10 L10,10 L10,1 Z
|
||||
M 5,2 L5,9 L6,9 L6,2 Z"
|
||||
Width="11"
|
||||
Height="11"
|
||||
Visibility="Visible"
|
||||
SnapsToDevicePixels="True" />
|
||||
</ToggleButton>
|
||||
|
||||
<RadioButton x:Name="DesignerButton"
|
||||
DockPanel.Dock="Top"
|
||||
Content="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=lc:SplitterContainer}, Path=DesignerHeader}"
|
||||
IsChecked="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=lc:SplitterContainer}, Path=IsDesignerActive, Mode=OneWay}"
|
||||
Command="{x:Static lc:SplitterCommands.ActivateViewCommand}"
|
||||
CommandParameter="{x:Static lc:SplitterViews.Design}"
|
||||
Style="{StaticResource DesignerTabItemStyle}"
|
||||
HorizontalAlignment="Left"
|
||||
Margin="0,9,3,0" />
|
||||
<Button x:Name="SwapPanesButton"
|
||||
Command="{x:Static lc:SplitterCommands.SwapPanesCommand}"
|
||||
HorizontalAlignment="Center"
|
||||
DockPanel.Dock="Top"
|
||||
Margin="0,3"
|
||||
ToolTip="Swap Panes">
|
||||
<Button.Style>
|
||||
<Style TargetType="Button" BasedOn="{StaticResource SplitterHandleButton}">
|
||||
<Setter Property="Content">
|
||||
<Setter.Value>
|
||||
<Path x:Name="SwapPath"
|
||||
Fill="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=Button}, Path=Foreground}"
|
||||
Data="{StaticResource HorizontalSwapPanesShape}"
|
||||
Width="11"
|
||||
Height="12"
|
||||
SnapsToDevicePixels="True" />
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=lc:SplitterGrip}, Path=Orientation}" Value="Vertical">
|
||||
<Setter Property="Content">
|
||||
<Setter.Value>
|
||||
<Path Fill="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=Button}, Path=Foreground}"
|
||||
Data="{StaticResource VerticalSwapPanesShape}"
|
||||
Width="12"
|
||||
Height="11"
|
||||
SnapsToDevicePixels="True" />
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</Button.Style>
|
||||
</Button>
|
||||
<RadioButton x:Name="EditorButton"
|
||||
DockPanel.Dock="Top"
|
||||
Content="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=lc:SplitterContainer}, Path=EditorHeader}"
|
||||
IsChecked="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=lc:SplitterContainer}, Path=IsEditorActive, Mode=OneWay}"
|
||||
Command="{x:Static lc:SplitterCommands.ActivateViewCommand}"
|
||||
CommandParameter="{x:Static lc:SplitterViews.Editor}"
|
||||
Style="{StaticResource EditorTabItemStyle}"
|
||||
HorizontalAlignment="Right"
|
||||
Margin="3,0,0,0" />
|
||||
|
||||
<Rectangle Fill="Transparent" Cursor="SizeWE" />
|
||||
</DockPanel>
|
||||
</Grid>
|
||||
|
||||
<ControlTemplate.Triggers>
|
||||
<Trigger Property="IsCollapsed" Value="True">
|
||||
<Setter TargetName="SwapPanesButton" Property="Visibility" Value="Collapsed" />
|
||||
<Setter TargetName="DesignerButton" Property="Margin" Value="0,9,0,0" />
|
||||
<Setter TargetName="EditorButton" Property="Margin" Value="0,-8,0,0" />
|
||||
</Trigger>
|
||||
|
||||
<DataTrigger Binding="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=lc:SplitterContainer}, Path=IsReversed}" Value="True">
|
||||
<Setter TargetName="DesignerButton"
|
||||
Property="Content"
|
||||
Value="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=lc:SplitterContainer}, Path=EditorHeader}" />
|
||||
<Setter TargetName="EditorButton"
|
||||
Property="Content"
|
||||
Value="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=lc:SplitterContainer}, Path=DesignerHeader}" />
|
||||
</DataTrigger>
|
||||
</ControlTemplate.Triggers>
|
||||
</ControlTemplate>
|
||||
|
||||
<ControlTemplate x:Key="HorizontalSplitterGrip" TargetType="lc:SplitterGrip">
|
||||
<Grid>
|
||||
<Border IsHitTestVisible="False"
|
||||
Background="{TemplateBinding Background}" />
|
||||
<Popup x:Name="PART_Popup"
|
||||
AllowsTransparency="True"
|
||||
Focusable="False"
|
||||
Height="6"
|
||||
IsOpen="False">
|
||||
<Border Background="#808080"
|
||||
Height="5"
|
||||
Width="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=ActualWidth}" />
|
||||
</Popup>
|
||||
<DockPanel LastChildFill="True">
|
||||
<Button x:Name="ExpandCollapseButton"
|
||||
DockPanel.Dock="Right"
|
||||
Style="{StaticResource ExpandCollapseButtonStyle}"
|
||||
Command="{x:Static lc:SplitterCommands.ExpandCollapsePaneCommand}">
|
||||
</Button>
|
||||
<ToggleButton x:Name="SplitHorizontalButton"
|
||||
DockPanel.Dock="Right"
|
||||
Style="{StaticResource SplitterHandleToggleButton}"
|
||||
ToolTip="Horizontal Split"
|
||||
IsChecked="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=lc:SplitterContainer}, Path=IsHorizontal, Mode=OneWay}"
|
||||
Command="{x:Static lc:SplitterCommands.SplitHorizontalCommand}">
|
||||
<Path x:Name="HorizontalPath"
|
||||
Fill="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=ToggleButton}, Path=Foreground}"
|
||||
Data="M 0,0 L0,11 L11,11 L11,0 Z
|
||||
M 1,1 L1,10 L10,10 L10,1 Z
|
||||
M 2,5 L9,5 L9,6 L2,6 Z"
|
||||
Width="11"
|
||||
Height="11"
|
||||
Visibility="Visible"
|
||||
SnapsToDevicePixels="True" />
|
||||
</ToggleButton>
|
||||
<ToggleButton x:Name="SplitVerticalButton"
|
||||
DockPanel.Dock="Right"
|
||||
Style="{StaticResource SplitterHandleToggleButton}"
|
||||
ToolTip="Vertical Split"
|
||||
IsChecked="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=lc:SplitterContainer}, Path=IsVertical, Mode=OneWay}"
|
||||
Command="{x:Static lc:SplitterCommands.SplitVerticalCommand}">
|
||||
<Path x:Name="VerticalPath"
|
||||
Fill="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=ToggleButton}, Path=Foreground}"
|
||||
Data="M 0,0 L0,11 L11,11 L11,0 Z
|
||||
M 1,1 L1,10 L10,10 L10,1 Z
|
||||
M 5,2 L5,9 L6,9 L6,2 Z"
|
||||
Width="11"
|
||||
Height="11"
|
||||
Visibility="Visible"
|
||||
SnapsToDevicePixels="True" />
|
||||
</ToggleButton>
|
||||
<ContentPresenter Content="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=lc:SplitterContainer}, Path=ExtraPanel}" DockPanel.Dock="Right"/>
|
||||
<RadioButton DockPanel.Dock="Left"
|
||||
x:Name="DesignerButton"
|
||||
Content="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=lc:SplitterContainer}, Path=DesignerHeader}"
|
||||
IsChecked="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=lc:SplitterContainer}, Path=IsDesignerActive, Mode=OneWay}"
|
||||
Command="{x:Static lc:SplitterCommands.ActivateViewCommand}"
|
||||
CommandParameter="{x:Static lc:SplitterViews.Design}"
|
||||
Style="{StaticResource DesignerTabItemStyle}"
|
||||
VerticalAlignment="Top"
|
||||
Margin="9,0,0,3" />
|
||||
<Button x:Name="SwapPanesButton"
|
||||
Command="{x:Static lc:SplitterCommands.SwapPanesCommand}"
|
||||
Margin="3,0"
|
||||
ToolTip="Swap Panes"
|
||||
Style="{StaticResource SplitterHandleButton}">
|
||||
<Button.Content>
|
||||
<Path x:Name="SwapPath"
|
||||
Fill="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=Button}, Path=Foreground}"
|
||||
Data="{StaticResource HorizontalSwapPanesShape}"
|
||||
Width="11"
|
||||
Height="12"
|
||||
SnapsToDevicePixels="True" />
|
||||
</Button.Content>
|
||||
</Button>
|
||||
<RadioButton DockPanel.Dock="Left"
|
||||
x:Name="EditorButton"
|
||||
Content="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=lc:SplitterContainer}, Path=EditorHeader}"
|
||||
IsChecked="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=lc:SplitterContainer}, Path=IsEditorActive, Mode=OneWay}"
|
||||
Command="{x:Static lc:SplitterCommands.ActivateViewCommand}"
|
||||
CommandParameter="{x:Static lc:SplitterViews.Editor}"
|
||||
Style="{StaticResource EditorTabItemStyle}"
|
||||
VerticalAlignment="Bottom"
|
||||
Margin="0,3,0,0" />
|
||||
|
||||
<Rectangle Fill="Transparent" Cursor="SizeNS" />
|
||||
</DockPanel>
|
||||
</Grid>
|
||||
|
||||
<ControlTemplate.Triggers>
|
||||
<Trigger Property="IsCollapsed" Value="True">
|
||||
<Setter TargetName="SwapPanesButton" Property="Visibility" Value="Collapsed" />
|
||||
<Setter TargetName="DesignerButton" Property="Margin" Value="9,0,0,0" />
|
||||
<Setter TargetName="EditorButton" Property="Margin" Value="-8,0,0,0" />
|
||||
</Trigger>
|
||||
|
||||
<DataTrigger Binding="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=lc:SplitterContainer}, Path=IsReversed}" Value="True">
|
||||
<Setter TargetName="DesignerButton"
|
||||
Property="Content"
|
||||
Value="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=lc:SplitterContainer}, Path=EditorHeader}" />
|
||||
|
||||
<Setter TargetName="EditorButton"
|
||||
Property="Content"
|
||||
Value="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=lc:SplitterContainer}, Path=DesignerHeader}" />
|
||||
</DataTrigger>
|
||||
</ControlTemplate.Triggers>
|
||||
</ControlTemplate>
|
||||
|
||||
<Style TargetType="lc:SplitterGrip">
|
||||
<Setter Property="HorizontalAlignment" Value="Stretch" />
|
||||
<Setter Property="VerticalAlignment" Value="Stretch" />
|
||||
<Setter Property="Background" Value="{DynamicResource {x:Static internals:AvaloniaDesignerBrushes.SplitterBackgroundBrushKey}}" />
|
||||
<Style.Triggers>
|
||||
<Trigger Property="Orientation" Value="Vertical">
|
||||
<Setter Property="Template" Value="{StaticResource VerticalSpliterGrip}" />
|
||||
</Trigger>
|
||||
<Trigger Property="Orientation" Value="Horizontal">
|
||||
<Setter Property="Template" Value="{StaticResource HorizontalSplitterGrip}" />
|
||||
</Trigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
|
||||
</ResourceDictionary>
|
|
@ -1,4 +0,0 @@
|
|||
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
|
||||
|
||||
</ResourceDictionary>
|
|
@ -1,8 +0,0 @@
|
|||
[$RootKey$\Themes\{de3dbbcd-f642-433c-8353-8f1df4370aba}\PamlDesigner]
|
||||
"Data"=hex:5c,01,00,00,0b,00,00,00,01,00,00,00,ba,e5,b2,1f,e6,ed,ff,4d,9d,d6,59,60,2a,44,14,f9,0b,00,00,00,12,00,00,00,53,70,6c,69,74,74,65,72,42,61,63,6b,67,72,6f,75,6e,64,01,ef,ef,f2,ff,00,10,00,00,00,42,75,74,74,6f,6e,42,61,63,6b,67,72,6f,75,6e,64,01,ff,ff,ff,00,00,10,00,00,00,42,75,74,74,6f,6e,46,6f,72,65,67,72,6f,75,6e,64,01,1e,1e,1e,ff,00,19,00,00,00,42,75,74,74,6f,6e,4d,6f,75,73,65,4f,76,65,72,42,61,63,6b,67,72,6f,75,6e,64,01,c9,de,f5,ff,00,19,00,00,00,42,75,74,74,6f,6e,4d,6f,75,73,65,4f,76,65,72,46,6f,72,65,67,72,6f,75,6e,64,01,1e,1e,1e,ff,00,17,00,00,00,42,75,74,74,6f,6e,50,72,65,73,73,65,64,42,61,63,6b,67,72,6f,75,6e,64,01,00,7a,cc,ff,00,17,00,00,00,42,75,74,74,6f,6e,50,72,65,73,73,65,64,46,6f,72,65,67,72,6f,75,6e,64,01,ff,ff,ff,ff,00,0c,00,00,00,48,65,61,64,65,72,41,63,74,69,76,65,01,ff,ff,ff,ff,00,10,00,00,00,48,65,61,64,65,72,41,63,74,69,76,65,54,65,78,74,01,1e,1e,1e,ff,00,0e,00,00,00,48,65,61,64,65,72,49,6e,61,63,74,69,76,65,01,f6,f6,f6,ff,00,12,00,00,00,48,65,61,64,65,72,49,6e,61,63,74,69,76,65,54,65,78,74,01,42,42,42,ff,00
|
||||
|
||||
[$RootKey$\Themes\{a4d6a176-b948-4b29-8c66-53c97a1ed7d0}\PamlDesigner]
|
||||
"Data"=hex:5c,01,00,00,0b,00,00,00,01,00,00,00,ba,e5,b2,1f,e6,ed,ff,4d,9d,d6,59,60,2a,44,14,f9,0b,00,00,00,12,00,00,00,53,70,6c,69,74,74,65,72,42,61,63,6b,67,72,6f,75,6e,64,01,ef,ef,f2,ff,00,10,00,00,00,42,75,74,74,6f,6e,42,61,63,6b,67,72,6f,75,6e,64,01,ff,ff,ff,00,00,10,00,00,00,42,75,74,74,6f,6e,46,6f,72,65,67,72,6f,75,6e,64,01,1e,1e,1e,ff,00,19,00,00,00,42,75,74,74,6f,6e,4d,6f,75,73,65,4f,76,65,72,42,61,63,6b,67,72,6f,75,6e,64,01,fd,f4,bf,ff,00,19,00,00,00,42,75,74,74,6f,6e,4d,6f,75,73,65,4f,76,65,72,46,6f,72,65,67,72,6f,75,6e,64,01,1e,1e,1e,ff,00,17,00,00,00,42,75,74,74,6f,6e,50,72,65,73,73,65,64,42,61,63,6b,67,72,6f,75,6e,64,01,00,7a,cc,ff,00,17,00,00,00,42,75,74,74,6f,6e,50,72,65,73,73,65,64,46,6f,72,65,67,72,6f,75,6e,64,01,ff,ff,ff,ff,00,0c,00,00,00,48,65,61,64,65,72,41,63,74,69,76,65,01,ff,ff,ff,ff,00,10,00,00,00,48,65,61,64,65,72,41,63,74,69,76,65,54,65,78,74,01,1e,1e,1e,ff,00,0e,00,00,00,48,65,61,64,65,72,49,6e,61,63,74,69,76,65,01,f6,f6,f6,ff,00,12,00,00,00,48,65,61,64,65,72,49,6e,61,63,74,69,76,65,54,65,78,74,01,42,42,42,ff,00
|
||||
|
||||
[$RootKey$\Themes\{1ded0138-47ce-435e-84ef-9ec1f439b749}\PamlDesigner]
|
||||
"Data"=hex:5c,01,00,00,0b,00,00,00,01,00,00,00,ba,e5,b2,1f,e6,ed,ff,4d,9d,d6,59,60,2a,44,14,f9,0b,00,00,00,12,00,00,00,53,70,6c,69,74,74,65,72,42,61,63,6b,67,72,6f,75,6e,64,01,2d,2d,30,ff,00,10,00,00,00,42,75,74,74,6f,6e,42,61,63,6b,67,72,6f,75,6e,64,01,ff,ff,ff,00,00,10,00,00,00,42,75,74,74,6f,6e,46,6f,72,65,67,72,6f,75,6e,64,01,f1,f1,f1,ff,00,19,00,00,00,42,75,74,74,6f,6e,4d,6f,75,73,65,4f,76,65,72,42,61,63,6b,67,72,6f,75,6e,64,01,3e,3e,40,ff,00,19,00,00,00,42,75,74,74,6f,6e,4d,6f,75,73,65,4f,76,65,72,46,6f,72,65,67,72,6f,75,6e,64,01,f1,f1,f1,ff,00,17,00,00,00,42,75,74,74,6f,6e,50,72,65,73,73,65,64,42,61,63,6b,67,72,6f,75,6e,64,01,00,7a,cc,ff,00,17,00,00,00,42,75,74,74,6f,6e,50,72,65,73,73,65,64,46,6f,72,65,67,72,6f,75,6e,64,01,ff,ff,ff,ff,00,0c,00,00,00,48,65,61,64,65,72,41,63,74,69,76,65,01,43,43,46,ff,00,10,00,00,00,48,65,61,64,65,72,41,63,74,69,76,65,54,65,78,74,01,f1,f1,f1,ff,00,0e,00,00,00,48,65,61,64,65,72,49,6e,61,63,74,69,76,65,01,33,33,37,ff,00,12,00,00,00,48,65,61,64,65,72,49,6e,61,63,74,69,76,65,54,65,78,74,01,f0,ef,f1,ff,00
|
|
@ -1,317 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<MinimumVisualStudioVersion>15.0</MinimumVisualStudioVersion>
|
||||
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
|
||||
<NuGetPackageImportStamp>
|
||||
</NuGetPackageImportStamp>
|
||||
<UseCodebase>true</UseCodebase>
|
||||
<FileUpgradeFlags>
|
||||
</FileUpgradeFlags>
|
||||
<PublishUrl>publish\</PublishUrl>
|
||||
<Install>true</Install>
|
||||
<InstallFrom>Disk</InstallFrom>
|
||||
<UpdateEnabled>false</UpdateEnabled>
|
||||
<UpdateMode>Foreground</UpdateMode>
|
||||
<UpdateInterval>7</UpdateInterval>
|
||||
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
|
||||
<UpdatePeriodically>false</UpdatePeriodically>
|
||||
<UpdateRequired>false</UpdateRequired>
|
||||
<MapFileExtensions>true</MapFileExtensions>
|
||||
<ApplicationRevision>0</ApplicationRevision>
|
||||
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
|
||||
<IsWebBootstrapper>false</IsWebBootstrapper>
|
||||
<UseApplicationTrust>false</UseApplicationTrust>
|
||||
<BootstrapperEnabled>true</BootstrapperEnabled>
|
||||
<TargetFrameworkProfile />
|
||||
<StartAction>Program</StartAction>
|
||||
<StartProgram>$(DevEnvDir)\devenv.exe</StartProgram>
|
||||
<StartArguments>/rootsuffix Exp</StartArguments>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<SignAssembly>true</SignAssembly>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<AssemblyOriginatorKeyFile>Infrastructure\Key.snk</AssemblyOriginatorKeyFile>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProjectTypeGuids>{82b43b9b-a64c-4715-b499-d71e9ca2bd60};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||
<ProjectGuid>{378D99A6-57BF-432D-A5A2-82CC4153736A}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>AvaloniaVS</RootNamespace>
|
||||
<AssemblyName>AvaloniaVS</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
|
||||
<GeneratePkgDefFile>true</GeneratePkgDefFile>
|
||||
<IncludeAssemblyInVSIXContainer>true</IncludeAssemblyInVSIXContainer>
|
||||
<IncludeDebugSymbolsInVSIXContainer>true</IncludeDebugSymbolsInVSIXContainer>
|
||||
<IncludeDebugSymbolsInLocalVSIXDeployment>true</IncludeDebugSymbolsInLocalVSIXDeployment>
|
||||
<CopyBuildOutputToOutputDirectory>true</CopyBuildOutputToOutputDirectory>
|
||||
<CopyOutputSymbolsToOutputDirectory>false</CopyOutputSymbolsToOutputDirectory>
|
||||
<DeployExtension>True</DeployExtension>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>TRACE;DEBUG;DESKTOP</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<CreateVsixContainer>True</CreateVsixContainer>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE;DESKTOP</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Converters\EnumDescriptionConverter.cs" />
|
||||
<Compile Include="Helpers\AvaloniaDesignerGeneralPageViewModelDesign.cs" />
|
||||
<Compile Include="Helpers\Extensions.cs" />
|
||||
<Compile Include="Infrastructure\DesignerKiller.cs" />
|
||||
<Compile Include="Infrastructure\AvaloniaDesignerPane.IOleCommandTarget.cs">
|
||||
<DependentUpon>AvaloniaDesignerPane.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Infrastructure\AvaloniaDesignerPane.IVsFindTarget.cs">
|
||||
<DependentUpon>AvaloniaDesignerPane.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Infrastructure\ProjectInfoService.cs" />
|
||||
<Compile Include="Infrastructure\PropertyChangedBase.cs" />
|
||||
<Compile Include="Infrastructure\RelayCommand.cs" />
|
||||
<Compile Include="Infrastructure\TriggerMenuOnLeftClickBehavior.cs" />
|
||||
<Compile Include="Internals\VisualStudioServices.cs" />
|
||||
<Compile Include="Internals\Guids.cs" />
|
||||
<Compile Include="Infrastructure\MarkupExtensionParser.cs" />
|
||||
<Compile Include="Infrastructure\AvaloniaDesignerPane.cs" />
|
||||
<Compile Include="Infrastructure\AvaloniaEditorFactory.cs" />
|
||||
<Compile Include="IntelliSense\CompletionCommandHandler.cs" />
|
||||
<Compile Include="IntelliSense\CompletionSource.cs" />
|
||||
<Compile Include="Internals\VsComInterfaces.cs" />
|
||||
<Compile Include="ViewModels\AvaloniaDesignerHostViewModel.cs" />
|
||||
<Compile Include="ViewModels\IAvaloniaDesignerHostViewModel.cs" />
|
||||
<Compile Include="ViewModels\ProjectDescriptor.cs" />
|
||||
<Compile Include="ViewModels\ViewModelBase.cs" />
|
||||
<Compile Include="Infrastructure\DocumentView.cs" />
|
||||
<Compile Include="ViewModels\IAvaloniaDesignerGeneralPageViewModel.cs" />
|
||||
<Compile Include="Infrastructure\IAvaloniaDesignerSettings.cs" />
|
||||
<Compile Include="Options\AvaloniaDesignerGeneralPage.cs">
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
<Compile Include="ViewModels\AvaloniaDesignerGeneralPageViewModel.cs" />
|
||||
<Compile Include="Infrastructure\AvaloniaDesignerSettings.cs" />
|
||||
<Compile Include="Infrastructure\SplitOrientation.cs" />
|
||||
<Compile Include="Utils.cs" />
|
||||
<Compile Include="Infrastructure\GuidList.cs" />
|
||||
<Compile Include="Infrastructure\AvaloniaBuildEvents.cs" />
|
||||
<Compile Include="Infrastructure\AvaloniaPackage.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Views\AvaloniaDesignerGeneralPageView.xaml.cs">
|
||||
<DependentUpon>AvaloniaDesignerGeneralPageView.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Views\AvaloniaDesignerHostView.xaml.cs">
|
||||
<DependentUpon>AvaloniaDesignerHostView.xaml</DependentUpon>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="app.config" />
|
||||
<None Include="Infrastructure\Key.snk" />
|
||||
<Content Include="FodyWeavers.xml" />
|
||||
<None Include="source.extension.vsixmanifest">
|
||||
<SubType>Designer</SubType>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
<Import Project="..\external\Avalonia.Ide.build\Avalonia.Ide.CompletionEngine\Avalonia.Ide.CompletionEngine.projitems" Label="Shared" />
|
||||
<ItemGroup>
|
||||
<Reference Include="Avalonia.Designer">
|
||||
<HintPath>lib\Avalonia.Designer.exe</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="Microsoft.VisualStudio.CommandBars, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<EmbedInteropTypes>True</EmbedInteropTypes>
|
||||
</Reference>
|
||||
<Reference Include="PresentationCore" />
|
||||
<Reference Include="PresentationFramework" />
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.ComponentModel.Composition" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="System.Design" />
|
||||
<Reference Include="System.Drawing" />
|
||||
<Reference Include="System.Management" />
|
||||
<Reference Include="System.Windows.Forms" />
|
||||
<Reference Include="System.Xaml" />
|
||||
<Reference Include="System.Xml" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="WindowsBase" />
|
||||
<Reference Include="WindowsFormsIntegration" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="AvaloniaDesignerTheme.pkgdef">
|
||||
<IncludeInVSIX>true</IncludeInVSIX>
|
||||
</Content>
|
||||
<Content Include="lib\Avalonia.Designer.HostApp.dll">
|
||||
<IncludeInVSIX>true</IncludeInVSIX>
|
||||
</Content>
|
||||
<Content Include="lib\Avalonia.Designer.HostApp.exe">
|
||||
<IncludeInVSIX>true</IncludeInVSIX>
|
||||
</Content>
|
||||
<Content Include="Resources\AvaloniaPackage.ico" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="Infrastructure\VSPackage.resx">
|
||||
<MergeWithCTO>true</MergeWithCTO>
|
||||
<ManifestResourceName>VSPackage</ManifestResourceName>
|
||||
<SubType>Designer</SubType>
|
||||
</EmbeddedResource>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Page Include="Views\AvaloniaDesignerGeneralPageView.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Include="Views\AvaloniaDesignerHostView.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\AvaloniaVS.Controls\AvaloniaVS.Controls.csproj">
|
||||
<Project>{bddc602f-89c4-439c-b728-582700b689b4}</Project>
|
||||
<Name>AvaloniaVS.Controls</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\Templates\AvaloniaApplicationTemplate\AvaloniaApplicationTemplate.csproj">
|
||||
<Project>{75104AA0-3B1B-47D4-9C4D-501A8185ACFC}</Project>
|
||||
<Name>AvaloniaApplicationTemplate</Name>
|
||||
<VSIXSubPath>ProjectTemplates</VSIXSubPath>
|
||||
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
|
||||
<IncludeOutputGroupsInVSIX>TemplateProjectOutputGroup%3b</IncludeOutputGroupsInVSIX>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\Templates\AvaloniaMvvmApplicationTemplate\AvaloniaMvvmApplicationTemplate.csproj">
|
||||
<Project>{d458691f-3b40-4e54-8bc2-782d017cfd2b}</Project>
|
||||
<Name>AvaloniaMvvmApplicationTemplate</Name>
|
||||
<VSIXSubPath>ProjectTemplates</VSIXSubPath>
|
||||
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
|
||||
<IncludeOutputGroupsInVSIX>TemplateProjectOutputGroup%3b</IncludeOutputGroupsInVSIX>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\Templates\AvaloniaUserControlTemplate\AvaloniaUserControlTemplate.csproj">
|
||||
<Project>{3BFD12BB-E6D8-46D7-9D5F-119A9896941E}</Project>
|
||||
<Name>AvaloniaUserControlTemplate</Name>
|
||||
<VSIXSubPath>ItemTemplates</VSIXSubPath>
|
||||
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
|
||||
<IncludeOutputGroupsInVSIX>TemplateProjectOutputGroup%3b</IncludeOutputGroupsInVSIX>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\Templates\AvaloniaWindowTemplate\AvaloniaWindowTemplate.csproj">
|
||||
<Project>{C8B3FF98-50A3-4C04-8F8C-ED853EC0760C}</Project>
|
||||
<Name>AvaloniaWindowTemplate</Name>
|
||||
<VSIXSubPath>ItemTemplates</VSIXSubPath>
|
||||
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
|
||||
<IncludeOutputGroupsInVSIX>TemplateProjectOutputGroup%3b</IncludeOutputGroupsInVSIX>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<BootstrapperPackage Include=".NETFramework,Version=v4.5.2">
|
||||
<Visible>False</Visible>
|
||||
<ProductName>Microsoft .NET Framework 4.5.2 %28x86 and x64%29</ProductName>
|
||||
<Install>true</Install>
|
||||
</BootstrapperPackage>
|
||||
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
|
||||
<Visible>False</Visible>
|
||||
<ProductName>.NET Framework 3.5 SP1</ProductName>
|
||||
<Install>false</Install>
|
||||
</BootstrapperPackage>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="EnvDTE100">
|
||||
<Version>10.0.3</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.Build">
|
||||
<Version>15.1.548</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.VisualStudio.ComponentModelHost">
|
||||
<Version>15.0.26201</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.VisualStudio.Editor">
|
||||
<Version>15.0.26201</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.VisualStudio.ImageCatalog">
|
||||
<Version>15.0.26201</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.VisualStudio.Imaging.Interop.14.0.DesignTime">
|
||||
<Version>14.3.26930</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.VisualStudio.Language.Intellisense">
|
||||
<Version>15.0.26201</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.VisualStudio.Package.LanguageService.15.0">
|
||||
<Version>15.0.26201</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.VisualStudio.ProjectSystem.Sdk">
|
||||
<Version>15.0.737</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.VisualStudio.SDK.VsixSuppression">
|
||||
<Version>14.1.37</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.VisualStudio.Shell.Immutable.14.0">
|
||||
<Version>15.0.25405</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.VisualStudio.Shell.Interop.15.0.DesignTime">
|
||||
<Version>15.0.26932</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.VisualStudio.Text.Data">
|
||||
<Version>15.0.26201</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.VisualStudio.Text.UI.Wpf">
|
||||
<Version>15.0.26201</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.VisualStudio.TextManager.Interop.12.0">
|
||||
<Version>12.0.30112</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.VisualStudio.Threading.Analyzers">
|
||||
<Version>15.0.240</Version>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.VSSDK.BuildTools">
|
||||
<Version>15.0.26201</Version>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Newtonsoft.Json">
|
||||
<Version>9.0.1</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="PropertyChanged.Fody">
|
||||
<Version>2.5.13</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="System.Reflection.Metadata">
|
||||
<Version>1.4.2</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="VSLangProj">
|
||||
<Version>7.0.3301</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Avalonia.dnlib" Version="2018.11.26-git-67c321d7a4219415492a910d22c95f5efb0c30b8" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<Import Project="$(VSToolsPath)\VSSDK\Microsoft.VsSDK.targets" Condition="'$(VSToolsPath)' != ''" />
|
||||
<Target Name="IncludePackageReferenceDependencies" AfterTargets="GetVsixSourceItems">
|
||||
<ItemGroup>
|
||||
<VSIXSourceItem Include="@(ReferenceCopyLocalPaths)" Condition="'%(ReferenceCopyLocalPaths.NuGetPackageId)' == 'Avalonia.dnlib'" />
|
||||
</ItemGroup>
|
||||
</Target>
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
|
@ -1,43 +0,0 @@
|
|||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Markup;
|
||||
|
||||
namespace AvaloniaVS.Converters
|
||||
{
|
||||
public class EnumDescriptionConverter : MarkupExtension, IValueConverter
|
||||
{
|
||||
public Type EnumType { get; set; }
|
||||
|
||||
public override object ProvideValue(IServiceProvider serviceProvider)
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
if (EnumType == null || value == null)
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
var fieldInfo = EnumType.GetField(System.Convert.ToString(value));
|
||||
var descriptionAttribute = fieldInfo.GetCustomAttributes<DescriptionAttribute>().FirstOrDefault();
|
||||
if (descriptionAttribute == null)
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
return descriptionAttribute.Description;
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
// there should be no convert back, make sure the binding is just one-way.
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,4 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Weavers>
|
||||
<PropertyChanged />
|
||||
</Weavers>
|
|
@ -1,14 +0,0 @@
|
|||
using AvaloniaVS.Infrastructure;
|
||||
using AvaloniaVS.Options;
|
||||
using AvaloniaVS.ViewModels;
|
||||
|
||||
namespace AvaloniaVS.Helpers
|
||||
{
|
||||
internal class AvaloniaDesignerGeneralPageViewModelDesign : IAvaloniaDesignerGeneralPageViewModel
|
||||
{
|
||||
public bool IsDesignerEnabled { get; set; }
|
||||
public bool IsReversed { get; set; }
|
||||
public DocumentView DocumentView { get; set; }
|
||||
public SplitOrientation SplitOrientation { get; set; }
|
||||
}
|
||||
}
|
|
@ -1,36 +0,0 @@
|
|||
using System.Runtime.InteropServices;
|
||||
using Microsoft.VisualStudio.Settings;
|
||||
using Microsoft.VisualStudio.Shell;
|
||||
using Microsoft.VisualStudio.Shell.Settings;
|
||||
using Microsoft.VisualStudio.Text;
|
||||
using Microsoft.VisualStudio.TextManager.Interop;
|
||||
using AvaloniaVS.Internals;
|
||||
|
||||
namespace AvaloniaVS.Helpers
|
||||
{
|
||||
internal static class Extensions
|
||||
{
|
||||
internal static WritableSettingsStore GetWritableSettingsStore(this SVsServiceProvider vsServiceProvider, SettingsScope scope)
|
||||
{
|
||||
var shellSettingsManager = new ShellSettingsManager(vsServiceProvider);
|
||||
return shellSettingsManager.GetWritableSettingsStore(scope);
|
||||
}
|
||||
|
||||
internal static ITextBuffer GetTextBuffer(this IVsTextLines vsTextBuffer)
|
||||
{
|
||||
return VisualStudioServices.VsEditorAdaptersFactoryService.GetDataBuffer(vsTextBuffer);
|
||||
}
|
||||
|
||||
internal static T GetObjectSafe<T>(this EnvDTE.Project project) where T:class
|
||||
{
|
||||
try
|
||||
{
|
||||
return project as T ?? project?.Object as T;
|
||||
}
|
||||
catch (COMException e)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,108 +0,0 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using EnvDTE;
|
||||
using Microsoft.VisualStudio.Shell;
|
||||
using Microsoft.Win32;
|
||||
|
||||
namespace AvaloniaVS.Infrastructure
|
||||
{
|
||||
internal sealed class AvaloniaBuildEvents
|
||||
{
|
||||
private DTEEvents _dteEvents;
|
||||
private BuildEvents _buildEvents;
|
||||
|
||||
public static AvaloniaBuildEvents Instance { get; } = new AvaloniaBuildEvents();
|
||||
/// <summary>
|
||||
/// Raised when a build operation is started
|
||||
/// </summary>
|
||||
public event Action BuildBegin;
|
||||
|
||||
/// <summary>
|
||||
/// Reised when a build operation has ended
|
||||
/// </summary>
|
||||
public event Action BuildEnd;
|
||||
|
||||
public event Action ModeChanged;
|
||||
|
||||
public static bool IsBuilding { get; private set; }
|
||||
|
||||
private AvaloniaBuildEvents()
|
||||
{
|
||||
if (Equals(Registry.GetValue(@"HKEY_CURRENT_USER\Software\AvaloniaUI\Designer", "AllocConsole", 0), 1))
|
||||
CreateConsole();
|
||||
var dte = (DTE) Package.GetGlobalService(typeof (DTE));
|
||||
_buildEvents = dte.Events.BuildEvents;
|
||||
_buildEvents.OnBuildBegin += PdbeBuildBegin;
|
||||
_buildEvents.OnBuildDone += NotifyBuildEnd;
|
||||
_dteEvents = dte.Events.DTEEvents;
|
||||
_dteEvents.ModeChanged += NotifyModeChanged;
|
||||
}
|
||||
|
||||
public static void CreateConsole()
|
||||
{
|
||||
AllocConsole();
|
||||
// reopen stdout
|
||||
TextWriter writer = new StreamWriter(Console.OpenStandardOutput())
|
||||
{ AutoFlush = true };
|
||||
Console.SetOut(writer);
|
||||
}
|
||||
|
||||
// P/Invoke required:
|
||||
private const UInt32 StdOutputHandle = 0xFFFFFFF5;
|
||||
[DllImport("kernel32.dll")]
|
||||
private static extern IntPtr GetStdHandle(UInt32 nStdHandle);
|
||||
[DllImport("kernel32.dll")]
|
||||
private static extern void SetStdHandle(UInt32 nStdHandle, IntPtr handle);
|
||||
[DllImport("kernel32")]
|
||||
static extern bool AllocConsole();
|
||||
|
||||
private void NotifyModeChanged(vsIDEMode lastmode)
|
||||
{
|
||||
Console.WriteLine("Mode: " + ((DTE) Package.GetGlobalService(typeof (DTE))).Mode);
|
||||
DesignerKiller.KillAllDesigners();
|
||||
ModeChanged?.Invoke();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Global Build Done Callback
|
||||
/// </summary>
|
||||
/// <param name="scope"></param>
|
||||
/// <param name="action"></param>
|
||||
private void NotifyBuildEnd(vsBuildScope scope, vsBuildAction action)
|
||||
{
|
||||
IsBuilding = false;
|
||||
Console.WriteLine("BuildEnd: " + scope + "/" + action);
|
||||
if (action < vsBuildAction.vsBuildActionBuild || action > vsBuildAction.vsBuildActionRebuildAll)
|
||||
{
|
||||
//Not an actual build event, we are here if user hits Start and there is nothing to build
|
||||
DesignerKiller.KillAllDesigners();
|
||||
return;
|
||||
}
|
||||
BuildEnd?.Invoke();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Global Build Start Callback
|
||||
/// </summary>
|
||||
/// <param name="scope"></param>
|
||||
/// <param name="action"></param>
|
||||
private void PdbeBuildBegin(vsBuildScope scope, vsBuildAction action)
|
||||
{
|
||||
IsBuilding = true;
|
||||
BuildBegin?.Invoke();
|
||||
DesignerKiller.KillAllDesigners();
|
||||
}
|
||||
}
|
||||
|
||||
public static class EventHandlerExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Raises event with thread and null-ref safety.
|
||||
/// </summary>
|
||||
public static void Raise(this Action handler)
|
||||
{
|
||||
handler?.Invoke();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,212 +0,0 @@
|
|||
using System;
|
||||
using System.ComponentModel.Design;
|
||||
using System.IO;
|
||||
using System.Windows;
|
||||
using Microsoft.VisualStudio;
|
||||
using Microsoft.VisualStudio.OLE.Interop;
|
||||
using Microsoft.VisualStudio.Shell;
|
||||
using Microsoft.VisualStudio.Shell.Interop;
|
||||
using Microsoft.VisualStudio.Text.Editor;
|
||||
using Microsoft.VisualStudio.TextManager.Interop;
|
||||
using AvaloniaVS.Internals;
|
||||
using Constants = Microsoft.VisualStudio.OLE.Interop.Constants;
|
||||
|
||||
namespace AvaloniaVS.Infrastructure
|
||||
{
|
||||
public partial class AvaloniaDesignerPane : IOleCommandTarget
|
||||
{
|
||||
private IOleCommandTarget _editorCommandTarget;
|
||||
|
||||
private IOleCommandTarget OleCommandTarget
|
||||
{
|
||||
get
|
||||
{
|
||||
return _editorCommandTarget ?? (_editorCommandTarget = (IOleCommandTarget)_vsCodeWindow);
|
||||
}
|
||||
}
|
||||
|
||||
public int Exec(ref Guid pguidCmdGroup, uint nCmdID, uint nCmdexecopt, IntPtr pvaIn, IntPtr pvaOut)
|
||||
{
|
||||
if (pguidCmdGroup == VSConstants.GUID_VSStandardCommandSet97)
|
||||
{
|
||||
if (nCmdID == (int)VSConstants.VSStd97CmdID.NewWindow ||
|
||||
nCmdID == (int)VSConstants.VSStd97CmdID.ViewCode ||
|
||||
nCmdID == (int)VSConstants.VSStd97CmdID.ViewForm)
|
||||
{
|
||||
var oleCommandTarget = GetService(typeof(IOleCommandTarget)) as IOleCommandTarget;
|
||||
if (oleCommandTarget != null)
|
||||
{
|
||||
return oleCommandTarget.Exec(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var hr = (int)Constants.OLECMDERR_E_NOTSUPPORTED;
|
||||
if (OleCommandTarget != null)
|
||||
{
|
||||
hr = OleCommandTarget.Exec(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut);
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
|
||||
public int QueryStatus(ref Guid pguidCmdGroup, uint cCmds, OLECMD[] prgCmds, IntPtr pCmdText)
|
||||
{
|
||||
var hr = (int)Constants.OLECMDERR_E_NOTSUPPORTED;
|
||||
|
||||
// we want the VSConstants.VSStd97CmdID.NewWindow and the VSConstants.VSStd97CmdID.ViewCode to be handled by the
|
||||
// WindowPane rather than the text editor host.
|
||||
if (pguidCmdGroup == VSConstants.GUID_VSStandardCommandSet97)
|
||||
{
|
||||
if (cCmds == 1 && (prgCmds[0].cmdID == (int)VSConstants.VSStd97CmdID.NewWindow ||
|
||||
prgCmds[0].cmdID == (int)VSConstants.VSStd97CmdID.ViewCode ||
|
||||
prgCmds[0].cmdID == (int)VSConstants.VSStd97CmdID.ViewForm))
|
||||
{
|
||||
var oleCommandTarget = GetService(typeof(IOleCommandTarget)) as IOleCommandTarget;
|
||||
if (oleCommandTarget != null)
|
||||
{
|
||||
return oleCommandTarget.QueryStatus(pguidCmdGroup, cCmds, prgCmds, pCmdText);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (OleCommandTarget != null)
|
||||
{
|
||||
hr = OleCommandTarget.QueryStatus(ref pguidCmdGroup, cCmds, prgCmds, pCmdText);
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
|
||||
protected override bool PreProcessMessage(ref System.Windows.Forms.Message m)
|
||||
{
|
||||
//Only try and pre-process keyboard input messages, all others are not interesting to us.
|
||||
if (m.Msg >= WM_KEYFIRST && m.Msg <= WM_KEYLAST)
|
||||
{
|
||||
//Only attempt to do the input -> command mapping if focus is inside our hosted editor.
|
||||
if ((_designerHost.EditView as FrameworkElement)?.IsKeyboardFocusWithin == true)
|
||||
{
|
||||
IVsFilterKeys2 filterKeys = (IVsFilterKeys2)GetService(typeof(SVsFilterKeys));
|
||||
MSG oleMSG = new MSG() { hwnd = m.HWnd, lParam = m.LParam, wParam = m.WParam, message = (uint)m.Msg };
|
||||
|
||||
//Ask the shell to do the command mapping for us and fire off the command if it succeeds with that mapping. We pass no 'custom' scopes
|
||||
//(third and fourth argument) because we pass VSTAEXF_UseTextEditorKBScope to indicate we want the shell to apply the text editor
|
||||
//command scope to this call.
|
||||
Guid cmdGuid;
|
||||
uint cmdId;
|
||||
int fTranslated;
|
||||
int fStartsMultiKeyChord;
|
||||
int res = filterKeys.TranslateAcceleratorEx(new MSG[] { oleMSG },
|
||||
(uint)(__VSTRANSACCELEXFLAGS.VSTAEXF_UseTextEditorKBScope),
|
||||
0 /*scope count*/,
|
||||
new Guid[0] /*scopes*/,
|
||||
out cmdGuid,
|
||||
out cmdId,
|
||||
out fTranslated,
|
||||
out fStartsMultiKeyChord);
|
||||
|
||||
if (fStartsMultiKeyChord == 0)
|
||||
{
|
||||
//HACK: Work around a bug in TranslateAcceleratorEx that will report it DIDN'T do the command mapping
|
||||
//when in fact it did :( Problem has been fixed (since I found it while writing this code), but in the
|
||||
//mean time we need to successfully eat keystrokes that have been mapped to commands and dispatched,
|
||||
//we DON'T want them to continue on to Translate/Dispatch. "Luckily" asking TranslateAcceleratorEx to
|
||||
//do the mapping WITHOUT firing the command will give us the right result code to indicate if the command
|
||||
//mapped or not, unfortunately we can't always do this as it would break key-chords as it causes the shell
|
||||
//to not remember the first input match of a multi-part chord, hence the reason we ONLY hit this block if
|
||||
//it didn't tell us the input IS part of key-chord.
|
||||
res = filterKeys.TranslateAcceleratorEx(new MSG[] { oleMSG },
|
||||
(uint)(__VSTRANSACCELEXFLAGS.VSTAEXF_NoFireCommand | __VSTRANSACCELEXFLAGS.VSTAEXF_UseTextEditorKBScope),
|
||||
0,
|
||||
new Guid[0],
|
||||
out cmdGuid,
|
||||
out cmdId,
|
||||
out fTranslated,
|
||||
out fStartsMultiKeyChord);
|
||||
|
||||
return res == VSConstants.S_OK;
|
||||
}
|
||||
|
||||
//We return true (that we handled the input message) if we managed to map it to a command OR it was the
|
||||
//beginning of a multi-key chord, anything else should continue on with normal processing.
|
||||
return (res == VSConstants.S_OK) || (fStartsMultiKeyChord != 0);
|
||||
}
|
||||
}
|
||||
|
||||
return base.PreProcessMessage(ref m);
|
||||
}
|
||||
|
||||
private void RegisterMenuCommands()
|
||||
{
|
||||
var menuService = GetService(typeof(IMenuCommandService)) as OleMenuCommandService;
|
||||
if (menuService != null)
|
||||
{
|
||||
// Window->New Window Command
|
||||
AddCommand(menuService, VSConstants.GUID_VSStandardCommandSet97, (int)VSConstants.VSStd97CmdID.NewWindow, OnNewWindow, OnNewWindowBeforeQueryStatus);
|
||||
AddCommand(menuService, VSConstants.GUID_VSStandardCommandSet97, (int)VSConstants.VSStd97CmdID.ViewCode, OnViewCode, OnViewCodeQueryStatus);
|
||||
AddCommand(menuService, VSConstants.GUID_VSStandardCommandSet97, (int)VSConstants.VSStd97CmdID.ViewForm, OnViewForm, OnViewFormQueryStatus);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnViewFormQueryStatus(object sender, EventArgs e)
|
||||
{
|
||||
var command = (OleMenuCommand)sender;
|
||||
command.Enabled = true;
|
||||
}
|
||||
|
||||
private void OnViewForm(object sender, EventArgs e)
|
||||
{
|
||||
_designerHostView.Container.SwapActiveView();
|
||||
if (_designerHostView.Container.IsEditorActive)
|
||||
{
|
||||
IVsTextView lastActiveView;
|
||||
GetLastActiveView(out lastActiveView);
|
||||
|
||||
var wpfEditorView = lastActiveView as IWpfTextView;
|
||||
if (wpfEditorView != null)
|
||||
{
|
||||
wpfEditorView.VisualElement.Focus();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void OnViewCodeQueryStatus(object sender, EventArgs e)
|
||||
{
|
||||
var command = (OleMenuCommand)sender;
|
||||
command.Enabled = true;
|
||||
}
|
||||
|
||||
private void OnViewCode(object sender, EventArgs e)
|
||||
{
|
||||
var codeBehindFile = $"{_fileName}.cs";
|
||||
if (!File.Exists(codeBehindFile))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
VsShellUtilities.OpenDocument(this, codeBehindFile);
|
||||
}
|
||||
|
||||
private void OnNewWindowBeforeQueryStatus(object sender, EventArgs eventArgs)
|
||||
{
|
||||
var newWindowCommand = sender as OleMenuCommand;
|
||||
if (newWindowCommand != null)
|
||||
{
|
||||
newWindowCommand.Visible = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnNewWindow(object sender, EventArgs eventArgs) { }
|
||||
|
||||
private static void AddCommand(IMenuCommandService mcs, Guid menuGroup, int cmdId, EventHandler invokeHandler, EventHandler beforeQueryStatus)
|
||||
{
|
||||
var id = new CommandID(menuGroup, cmdId);
|
||||
var command = new OleMenuCommand(invokeHandler, id) { Visible = true };
|
||||
|
||||
if (beforeQueryStatus != null)
|
||||
{
|
||||
command.BeforeQueryStatus += beforeQueryStatus;
|
||||
}
|
||||
|
||||
mcs.AddCommand(command);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,371 +0,0 @@
|
|||
using System;
|
||||
using EnvDTE;
|
||||
using Microsoft.VisualStudio;
|
||||
using Microsoft.VisualStudio.OLE.Interop;
|
||||
using Microsoft.VisualStudio.Shell.Interop;
|
||||
using Microsoft.VisualStudio.TextManager.Interop;
|
||||
|
||||
namespace AvaloniaVS.Infrastructure
|
||||
{
|
||||
public partial class AvaloniaDesignerPane : IVsFindTarget,
|
||||
IVsFindTarget2,
|
||||
IVsDropdownBarManager,
|
||||
IVsUserData,
|
||||
IVsHasRelatedSaveItems,
|
||||
IVsToolboxUser,
|
||||
IVsStatusbarUser,
|
||||
IVsCodeWindow,
|
||||
IVsCodeWindowEx,
|
||||
IVsCodeWindow2,
|
||||
IConnectionPointContainer,
|
||||
IVsWindowFrameNotify2,
|
||||
IExtensibleObject,
|
||||
IObjectWithSite,
|
||||
Microsoft.VisualStudio.OLE.Interop.IServiceProvider,
|
||||
IVsBackForwardNavigation,
|
||||
IVsBackForwardNavigation2,
|
||||
IVsDocOutlineProvider,
|
||||
IVsTextEditorPropertyContainer
|
||||
{
|
||||
public int GetCapabilities(bool[] pfImage, uint[] pgrfOptions)
|
||||
{
|
||||
var findTarget = (IVsFindTarget)_vsCodeWindow;
|
||||
return findTarget.GetCapabilities(pfImage, pgrfOptions);
|
||||
}
|
||||
|
||||
public int GetProperty(uint propid, out object pvar)
|
||||
{
|
||||
var findTarget = (IVsFindTarget)_vsCodeWindow;
|
||||
return findTarget.GetProperty(propid, out pvar);
|
||||
}
|
||||
|
||||
public int GetSearchImage(uint grfOptions, IVsTextSpanSet[] ppSpans, out IVsTextImage ppTextImage)
|
||||
{
|
||||
var findTarget = (IVsFindTarget)_vsCodeWindow;
|
||||
return findTarget.GetSearchImage(grfOptions, ppSpans, out ppTextImage);
|
||||
}
|
||||
|
||||
public int Find(string pszSearch, uint grfOptions, int fResetStartPoint, IVsFindHelper pHelper, out uint pResult)
|
||||
{
|
||||
var findTarget = (IVsFindTarget)_vsCodeWindow;
|
||||
return findTarget.Find(pszSearch, grfOptions, fResetStartPoint, pHelper, out pResult);
|
||||
}
|
||||
|
||||
public int Replace(string pszSearch, string pszReplace, uint grfOptions, int fResetStartPoint, IVsFindHelper pHelper, out int pfReplaced)
|
||||
{
|
||||
var findTarget = (IVsFindTarget)_vsCodeWindow;
|
||||
return findTarget.Replace(pszSearch, pszReplace, grfOptions, fResetStartPoint, pHelper, out pfReplaced);
|
||||
}
|
||||
|
||||
public int GetMatchRect(RECT[] prc)
|
||||
{
|
||||
var findTarget = (IVsFindTarget)_vsCodeWindow;
|
||||
return findTarget.GetMatchRect(prc);
|
||||
}
|
||||
|
||||
public int NavigateTo(TextSpan[] pts)
|
||||
{
|
||||
var findTarget = (IVsFindTarget)_vsCodeWindow;
|
||||
return findTarget.NavigateTo(pts);
|
||||
}
|
||||
|
||||
public int GetCurrentSpan(TextSpan[] pts)
|
||||
{
|
||||
var findTarget = (IVsFindTarget)_vsCodeWindow;
|
||||
return findTarget.GetCurrentSpan(pts);
|
||||
}
|
||||
|
||||
public int SetFindState(object pUnk)
|
||||
{
|
||||
var findTarget = (IVsFindTarget)_vsCodeWindow;
|
||||
return findTarget.SetFindState(pUnk);
|
||||
}
|
||||
|
||||
public int GetFindState(out object ppunk)
|
||||
{
|
||||
var findTarget = (IVsFindTarget)_vsCodeWindow;
|
||||
return findTarget.GetFindState(out ppunk);
|
||||
}
|
||||
|
||||
public int NotifyFindTarget(uint notification)
|
||||
{
|
||||
var findTarget = (IVsFindTarget)_vsCodeWindow;
|
||||
return findTarget.NotifyFindTarget(notification);
|
||||
}
|
||||
|
||||
public int MarkSpan(TextSpan[] pts)
|
||||
{
|
||||
var findTarget = (IVsFindTarget)_vsCodeWindow;
|
||||
return findTarget.MarkSpan(pts);
|
||||
}
|
||||
|
||||
public int NavigateTo2(IVsTextSpanSet pSpans, TextSelMode iSelMode)
|
||||
{
|
||||
var findTarget = (IVsFindTarget2)_vsCodeWindow;
|
||||
return findTarget.NavigateTo2(pSpans, iSelMode);
|
||||
}
|
||||
|
||||
public IVsDropdownBarManager DropdownBarManager
|
||||
{
|
||||
get { return (IVsDropdownBarManager) _vsCodeWindow; }
|
||||
}
|
||||
|
||||
public int AddDropdownBar(int cCombos, IVsDropdownBarClient pClient)
|
||||
{
|
||||
return DropdownBarManager.AddDropdownBar(cCombos, pClient);
|
||||
}
|
||||
|
||||
public int GetDropdownBar(out IVsDropdownBar ppDropdownBar)
|
||||
{
|
||||
return DropdownBarManager.GetDropdownBar(out ppDropdownBar);
|
||||
}
|
||||
|
||||
public int RemoveDropdownBar()
|
||||
{
|
||||
return DropdownBarManager.RemoveDropdownBar();
|
||||
}
|
||||
|
||||
public IVsUserData VsUserData
|
||||
{
|
||||
get { return (IVsUserData) _vsCodeWindow; }
|
||||
}
|
||||
|
||||
public int GetData(ref Guid riidKey, out object pvtData)
|
||||
{
|
||||
return VsUserData.GetData(ref riidKey, out pvtData);
|
||||
}
|
||||
|
||||
public int SetData(ref Guid riidKey, object vtData)
|
||||
{
|
||||
return VsUserData.GetData(ref riidKey, out vtData);
|
||||
}
|
||||
|
||||
public int GetRelatedSaveTreeItems(VSSAVETREEITEM saveItem, uint celt, VSSAVETREEITEM[] rgSaveTreeItems, out uint pcActual)
|
||||
{
|
||||
var codeWindow = (IVsHasRelatedSaveItems) _vsCodeWindow;
|
||||
return codeWindow.GetRelatedSaveTreeItems(saveItem, celt, rgSaveTreeItems, out pcActual);
|
||||
}
|
||||
|
||||
public int IsSupported(IDataObject pDO)
|
||||
{
|
||||
var toolboxUser = (IVsToolboxUser) _vsCodeWindow;
|
||||
return toolboxUser.IsSupported(pDO);
|
||||
}
|
||||
|
||||
public int ItemPicked(IDataObject pDO)
|
||||
{
|
||||
var toolboxUser = (IVsToolboxUser)_vsCodeWindow;
|
||||
return toolboxUser.IsSupported(pDO);
|
||||
}
|
||||
|
||||
public int SetInfo()
|
||||
{
|
||||
var codeWindow = (IVsStatusbarUser) _vsCodeWindow;
|
||||
return codeWindow.SetInfo();
|
||||
}
|
||||
|
||||
public int SetBuffer(IVsTextLines pBuffer)
|
||||
{
|
||||
return _vsCodeWindow.SetBuffer(pBuffer);
|
||||
}
|
||||
|
||||
public int GetBuffer(out IVsTextLines ppBuffer)
|
||||
{
|
||||
return _vsCodeWindow.GetBuffer(out ppBuffer);
|
||||
}
|
||||
|
||||
public int GetPrimaryView(out IVsTextView ppView)
|
||||
{
|
||||
return _vsCodeWindow.GetPrimaryView(out ppView);
|
||||
}
|
||||
|
||||
public int GetSecondaryView(out IVsTextView ppView)
|
||||
{
|
||||
return _vsCodeWindow.GetSecondaryView(out ppView);
|
||||
}
|
||||
|
||||
public int SetViewClassID(ref Guid clsidView)
|
||||
{
|
||||
return _vsCodeWindow.SetViewClassID(ref clsidView);
|
||||
}
|
||||
|
||||
public int GetViewClassID(out Guid pclsidView)
|
||||
{
|
||||
return _vsCodeWindow.GetViewClassID(out pclsidView);
|
||||
}
|
||||
|
||||
public int SetBaseEditorCaption(string[] pszBaseEditorCaption)
|
||||
{
|
||||
return _vsCodeWindow.SetBaseEditorCaption(pszBaseEditorCaption);
|
||||
}
|
||||
|
||||
public int GetEditorCaption(READONLYSTATUS dwReadOnly, out string pbstrEditorCaption)
|
||||
{
|
||||
return _vsCodeWindow.GetEditorCaption(dwReadOnly, out pbstrEditorCaption);
|
||||
}
|
||||
|
||||
public int Close()
|
||||
{
|
||||
return _vsCodeWindow.Close();
|
||||
}
|
||||
|
||||
public int GetLastActiveView(out IVsTextView ppView)
|
||||
{
|
||||
return _vsCodeWindow.GetLastActiveView(out ppView);
|
||||
}
|
||||
|
||||
public int Initialize(uint grfCodeWindowBehaviorFlags,
|
||||
VSUSERCONTEXTATTRIBUTEUSAGE usageAuxUserContext,
|
||||
string szNameAuxUserContext,
|
||||
string szValueAuxUserContext,
|
||||
uint initViewFlags,
|
||||
INITVIEW[] pInitView)
|
||||
{
|
||||
var vsCodeWindow = (IVsCodeWindowEx) _vsCodeWindow;
|
||||
return vsCodeWindow.Initialize(grfCodeWindowBehaviorFlags, usageAuxUserContext, szNameAuxUserContext, szValueAuxUserContext, initViewFlags, pInitView);
|
||||
}
|
||||
|
||||
public int IsReadOnly()
|
||||
{
|
||||
var vsCodeWindow = (IVsCodeWindowEx) _vsCodeWindow;
|
||||
return vsCodeWindow.IsReadOnly();
|
||||
}
|
||||
|
||||
public int GetProperty(VSEDITPROPID idProp, out object pvar)
|
||||
{
|
||||
var codeWindow = (IVsTextEditorPropertyContainer) _vsCodeWindow;
|
||||
return codeWindow.GetProperty(idProp, out pvar);
|
||||
}
|
||||
|
||||
public int SetProperty(VSEDITPROPID idProp, object var)
|
||||
{
|
||||
var codeWindow = (IVsTextEditorPropertyContainer)_vsCodeWindow;
|
||||
return codeWindow.SetProperty(idProp, var);
|
||||
}
|
||||
|
||||
public int RemoveProperty(VSEDITPROPID idProp)
|
||||
{
|
||||
var codeWindow = (IVsTextEditorPropertyContainer)_vsCodeWindow;
|
||||
return codeWindow.RemoveProperty(idProp);
|
||||
}
|
||||
|
||||
public void EnumConnectionPoints(out IEnumConnectionPoints ppEnum)
|
||||
{
|
||||
var codeWindow = (IConnectionPointContainer) _vsCodeWindow;
|
||||
codeWindow.EnumConnectionPoints(out ppEnum);
|
||||
}
|
||||
|
||||
public void FindConnectionPoint(ref Guid riid, out IConnectionPoint ppCP)
|
||||
{
|
||||
var codeWindow = (IConnectionPointContainer) _vsCodeWindow;
|
||||
codeWindow.FindConnectionPoint(ref riid, out ppCP);
|
||||
}
|
||||
|
||||
private IVsTextManager _textManager;
|
||||
internal IVsTextManager TextManager
|
||||
{
|
||||
get
|
||||
{
|
||||
if (this._textManager == null)
|
||||
this._textManager = (IVsTextManager)this.GetService(typeof(SVsTextManager));
|
||||
return this._textManager;
|
||||
}
|
||||
}
|
||||
|
||||
public int OnClose(ref uint pgrfSaveOptions)
|
||||
{
|
||||
// currently if we route the call to the _vsCodeWindow instance
|
||||
// we will get an 'System.NullReferenceException' in Microsoft.VisualStudio.Editor.Implementation.dll
|
||||
// for now we skip the call and return an OK
|
||||
|
||||
return VSConstants.S_OK;
|
||||
|
||||
//var codeWindow = (IVsWindowFrameNotify2)_vsCodeWindow;
|
||||
//return codeWindow.OnClose(ref pgrfSaveOptions);
|
||||
}
|
||||
|
||||
public void GetAutomationObject(string Name, IExtensibleObjectSite pParent, out object ppDisp)
|
||||
{
|
||||
var extensibleObject = (IExtensibleObject) _vsCodeWindow;
|
||||
extensibleObject.GetAutomationObject(Name, pParent, out ppDisp);
|
||||
}
|
||||
|
||||
public void SetSite(object pUnkSite)
|
||||
{
|
||||
var objectWithSite = (IObjectWithSite) _vsCodeWindow;
|
||||
objectWithSite.SetSite(pUnkSite);
|
||||
}
|
||||
|
||||
public void GetSite(ref Guid riid, out IntPtr ppvSite)
|
||||
{
|
||||
var objectWithSite = (IObjectWithSite)_vsCodeWindow;
|
||||
objectWithSite.GetSite(ref riid, out ppvSite);
|
||||
}
|
||||
|
||||
public int QueryService(ref Guid guidService, ref Guid riid, out IntPtr ppvObject)
|
||||
{
|
||||
var codeWindow = (Microsoft.VisualStudio.OLE.Interop.IServiceProvider) _vsCodeWindow;
|
||||
return codeWindow.QueryService(ref guidService, ref riid, out ppvObject);
|
||||
}
|
||||
|
||||
public int NavigateTo(IVsWindowFrame pFrame, string bstrData, object punk)
|
||||
{
|
||||
var codeWindow = (IVsBackForwardNavigation) _vsCodeWindow;
|
||||
return codeWindow.NavigateTo(pFrame, bstrData, punk);
|
||||
}
|
||||
|
||||
public int IsEqual(IVsWindowFrame pFrame, string bstrData, object punk, out int fReplaceSelf)
|
||||
{
|
||||
var codeWindow = (IVsBackForwardNavigation) _vsCodeWindow;
|
||||
return codeWindow.IsEqual(pFrame, bstrData, punk, out fReplaceSelf);
|
||||
}
|
||||
|
||||
public bool RequestAddNavigationItem(IVsWindowFrame frame)
|
||||
{
|
||||
var codeWindow = (IVsBackForwardNavigation2)_vsCodeWindow;
|
||||
return codeWindow.RequestAddNavigationItem(frame);
|
||||
}
|
||||
|
||||
public int GetOutlineCaption(VSOUTLINECAPTION nCaptionType, out string pbstrCaption)
|
||||
{
|
||||
var outlineProvider = (IVsDocOutlineProvider) _vsCodeWindow;
|
||||
return outlineProvider.GetOutlineCaption(nCaptionType, out pbstrCaption);
|
||||
}
|
||||
|
||||
public int GetOutline(out IntPtr phwnd, out IOleCommandTarget ppCmdTarget)
|
||||
{
|
||||
var outlineProvider = (IVsDocOutlineProvider)_vsCodeWindow;
|
||||
return outlineProvider.GetOutline(out phwnd, out ppCmdTarget);
|
||||
}
|
||||
|
||||
public int ReleaseOutline(IntPtr hwnd, IOleCommandTarget pCmdTarget)
|
||||
{
|
||||
var outlineProvider = (IVsDocOutlineProvider)_vsCodeWindow;
|
||||
return outlineProvider.ReleaseOutline(hwnd, pCmdTarget);
|
||||
}
|
||||
|
||||
public int OnOutlineStateChange(uint dwMask, uint dwState)
|
||||
{
|
||||
var outlineProvider = (IVsDocOutlineProvider)_vsCodeWindow;
|
||||
return outlineProvider.OnOutlineStateChange(dwMask, dwState);
|
||||
}
|
||||
|
||||
public int GetEmbeddedCodeWindowCount(out int piCount)
|
||||
{
|
||||
var vsCodeWindow = (IVsCodeWindow2) _vsCodeWindow;
|
||||
return vsCodeWindow.GetEmbeddedCodeWindowCount(out piCount);
|
||||
}
|
||||
|
||||
public int GetEmbeddedCodeWindow(int iIndex, out IVsCodeWindow ppCodeWindow)
|
||||
{
|
||||
var vsCodeWindow = (IVsCodeWindow2)_vsCodeWindow;
|
||||
return vsCodeWindow.GetEmbeddedCodeWindow(iIndex, out ppCodeWindow);
|
||||
}
|
||||
|
||||
public int GetContainingCodeWindow(out IVsCodeWindow ppCodeWindow)
|
||||
{
|
||||
var vsCodeWindow = (IVsCodeWindow2)_vsCodeWindow;
|
||||
return vsCodeWindow.GetContainingCodeWindow(out ppCodeWindow);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,258 +0,0 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using Avalonia.Designer;
|
||||
using Avalonia.Ide.CompletionEngine;
|
||||
using Avalonia.Ide.CompletionEngine.AssemblyMetadata;
|
||||
using Avalonia.Ide.CompletionEngine.DnlibMetadataProvider;
|
||||
using AvaloniaVS.Helpers;
|
||||
using AvaloniaVS.ViewModels;
|
||||
using AvaloniaVS.Views;
|
||||
using EnvDTE;
|
||||
using Microsoft.VisualStudio.Shell;
|
||||
using Microsoft.VisualStudio.Text;
|
||||
using Microsoft.VisualStudio.TextManager.Interop;
|
||||
using HorizontalAlignment = System.Windows.HorizontalAlignment;
|
||||
|
||||
namespace AvaloniaVS.Infrastructure
|
||||
{
|
||||
[ComVisible(true), Guid("75b0ba12-1e01-4f80-a035-32239896bcab")]
|
||||
public partial class AvaloniaDesignerPane : WindowPane
|
||||
{
|
||||
private const int WM_KEYFIRST = 0x0100;
|
||||
private const int WM_KEYLAST = 0x0109;
|
||||
|
||||
private AvaloniaDesignerHostView _designerHostView;
|
||||
private AvaloniaDesignerHostViewModel _designerHost;
|
||||
private readonly string _fileName;
|
||||
private readonly IAvaloniaDesignerSettings _designerSettings;
|
||||
private AvaloniaDesigner _designer;
|
||||
private string _targetExe;
|
||||
private long _lastRestartToken;
|
||||
private IVsCodeWindow _vsCodeWindow;
|
||||
private readonly ITextBuffer _textBuffer;
|
||||
|
||||
public AvaloniaDesignerPane(IVsCodeWindow vsCodeWindow, IVsTextLines textBuffer, string fileName, IAvaloniaDesignerSettings designerSettings)
|
||||
{
|
||||
_vsCodeWindow = vsCodeWindow;
|
||||
_textBuffer = textBuffer.GetTextBuffer();
|
||||
_fileName = fileName;
|
||||
_designerSettings = designerSettings;
|
||||
}
|
||||
|
||||
protected override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
InitializePane();
|
||||
RegisterMenuCommands();
|
||||
}
|
||||
|
||||
object GetContent(object adapter)
|
||||
{
|
||||
return adapter.GetType().GetProperties(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance)
|
||||
.FirstOrDefault(p => p.Name == "Content").GetMethod.Invoke(adapter, null);
|
||||
}
|
||||
|
||||
private void InitializePane()
|
||||
{
|
||||
|
||||
// initialize the designer host view.
|
||||
_designerHost = new AvaloniaDesignerHostViewModel(_fileName)
|
||||
{
|
||||
EditView = GetContent(_vsCodeWindow),
|
||||
Orientation = _designerSettings.SplitOrientation == SplitOrientation.Default ||
|
||||
_designerSettings.SplitOrientation == SplitOrientation.Horizontal
|
||||
? Orientation.Horizontal
|
||||
: Orientation.Vertical,
|
||||
IsReversed = _designerSettings.IsReversed
|
||||
};
|
||||
_designerHostView = new AvaloniaDesignerHostView {DataContext = _designerHost};
|
||||
_designerHostView.Init(_designerSettings);
|
||||
|
||||
InitializeDesigner();
|
||||
_designerHost.TargetExeChanged += UpdateTargetExe;
|
||||
}
|
||||
|
||||
void UpdateTargetExe(string exe)
|
||||
{
|
||||
_targetExe = exe;
|
||||
_designer.TargetExe = exe;
|
||||
_designerHost.DesignView = _targetExe == null
|
||||
? (object) new TextBlock
|
||||
{
|
||||
VerticalAlignment = VerticalAlignment.Center,
|
||||
HorizontalAlignment = HorizontalAlignment.Center,
|
||||
TextWrapping = TextWrapping.Wrap,
|
||||
Text = $"{Path.GetFileName(_fileName)} cannot be edited in the Design view. Make sure that it's referenced from at least one desktop exe project and rebuild solution. FixMe button below might also help."
|
||||
}
|
||||
: _designer;
|
||||
ReloadMetadata();
|
||||
SetDesignerXaml();
|
||||
}
|
||||
|
||||
private void InitializeDesigner()
|
||||
{
|
||||
var basePath =
|
||||
Path.GetDirectoryName(typeof(AvaloniaDesignerPane).Assembly.GetModules()[0].FullyQualifiedName);
|
||||
basePath = Path.Combine(basePath, "lib");
|
||||
_designer = new AvaloniaDesigner(new DesignerConfiguration
|
||||
{
|
||||
NetFxAppHostPath = Path.Combine(basePath, "Avalonia.Designer.HostApp.exe"),
|
||||
NetCoreAppHostPath = Path.Combine(basePath, "Avalonia.Designer.HostApp.dll")
|
||||
})
|
||||
{
|
||||
SourceAssembly = Utils.GetContainerProject(_fileName)?.GetAssemblyPath()
|
||||
};
|
||||
_designer.SpawnedProcess += DesignerKiller.Register;
|
||||
_designerHost.SourceAssemblyChanged += sa =>
|
||||
{
|
||||
if (_designer != null)
|
||||
_designer.SourceAssembly = sa;
|
||||
};
|
||||
UpdateTargetExe(_designerHost.TargetExe);
|
||||
_designerHost.RestartDesigner = new RelayCommand(() =>
|
||||
{
|
||||
Restart();
|
||||
});
|
||||
SetDesignerXaml(_textBuffer.CurrentSnapshot.GetText());
|
||||
AvaloniaBuildEvents.Instance.BuildEnd += Restart;
|
||||
AvaloniaBuildEvents.Instance.ModeChanged += OnModeChanged;
|
||||
_textBuffer.PostChanged += OnTextBufferPostChanged;
|
||||
|
||||
_designerHostView.IsDesingerVisibleChanged = () => SetDesignerXaml();
|
||||
}
|
||||
|
||||
private void OnTextBufferPostChanged(object sender, EventArgs e)
|
||||
{
|
||||
var buffer = (ITextBuffer)sender;
|
||||
|
||||
SetDesignerXaml(buffer.CurrentSnapshot.GetText());
|
||||
}
|
||||
|
||||
private bool IsDesignerVisible()
|
||||
{
|
||||
return _designerHostView?.IsDesingerVisible ?? false;
|
||||
}
|
||||
|
||||
private string _lastXaml;
|
||||
|
||||
private bool _lastIsDesignerVisible = false;
|
||||
|
||||
private void SetDesignerXaml(string xaml = null)
|
||||
{
|
||||
if (xaml == null) xaml = _lastXaml;
|
||||
|
||||
//we don't need preview in source only view
|
||||
if (!IsDesignerVisible())
|
||||
{
|
||||
_designer.Xaml = "";
|
||||
_designer.Visibility = Visibility.Collapsed;
|
||||
_designer?.KillProcess();
|
||||
}
|
||||
else
|
||||
{
|
||||
_designer.Visibility = Visibility.Visible;
|
||||
_designer.Xaml = xaml;
|
||||
if (!_lastIsDesignerVisible) Restart();
|
||||
}
|
||||
_lastIsDesignerVisible = IsDesignerVisible();
|
||||
_lastXaml = xaml;
|
||||
}
|
||||
|
||||
protected override void OnClose()
|
||||
{
|
||||
_vsCodeWindow.Close();
|
||||
base.OnClose();
|
||||
}
|
||||
|
||||
private void ReloadMetadata()
|
||||
{
|
||||
try
|
||||
{
|
||||
_textBuffer.Properties["AssemblyName"] = Utils.GetContainerProject(_fileName)?.GetAssemblyName();
|
||||
}
|
||||
catch { }
|
||||
|
||||
string metadataAssembly = string.IsNullOrEmpty(_targetExe) || !File.Exists(_targetExe) ?
|
||||
Utils.GetContainerProject(_fileName).GetAssemblyPath() : _targetExe;
|
||||
|
||||
if (string.IsNullOrEmpty(metadataAssembly) || !File.Exists(metadataAssembly))
|
||||
return;
|
||||
|
||||
try
|
||||
{
|
||||
_textBuffer.Properties[typeof(Metadata)] = new MetadataReader(new DnlibMetadataProvider())
|
||||
.GetForTargetAssembly(metadataAssembly);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
//TODO: Log
|
||||
}
|
||||
}
|
||||
|
||||
public override object Content => _designerHostView;
|
||||
|
||||
private void EventsOnBuildBegin()
|
||||
{
|
||||
_designer?.KillProcess();
|
||||
}
|
||||
|
||||
private void OnModeChanged()
|
||||
{
|
||||
var dte = (DTE)Package.GetGlobalService(typeof(DTE));
|
||||
if (dte.Mode == vsIDEMode.vsIDEModeDesign)
|
||||
Restart();
|
||||
}
|
||||
|
||||
private async void Restart()
|
||||
{
|
||||
long token = ++_lastRestartToken;
|
||||
Console.WriteLine("Designer restart requested, waiting");
|
||||
await System.Threading.Tasks.Task.Delay(1000);
|
||||
if (token != _lastRestartToken)
|
||||
return;
|
||||
var dte = (DTE)Microsoft.VisualStudio.Shell.Package.GetGlobalService(typeof(DTE));
|
||||
if (dte.Mode != vsIDEMode.vsIDEModeDesign || AvaloniaBuildEvents.IsBuilding)
|
||||
return;
|
||||
try
|
||||
{
|
||||
if (!IsDesignerVisible())
|
||||
{
|
||||
Console.WriteLine("Designer suspended in SourceView");
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("Restarting designer");
|
||||
_designer?.RestartProcess();
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
//TODO: Log
|
||||
}
|
||||
ReloadMetadata();
|
||||
|
||||
}
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
PaneDispose(disposing);
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
private void PaneDispose(bool disposing)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
AvaloniaBuildEvents.Instance.BuildEnd -= Restart;
|
||||
AvaloniaBuildEvents.Instance.ModeChanged -= OnModeChanged;
|
||||
_designer?.KillProcess();
|
||||
_textBuffer.PostChanged -= OnTextBufferPostChanged;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,60 +0,0 @@
|
|||
using System.ComponentModel.Composition;
|
||||
using Microsoft.VisualStudio.Settings;
|
||||
using Microsoft.VisualStudio.Shell;
|
||||
using AvaloniaVS.Helpers;
|
||||
|
||||
namespace AvaloniaVS.Infrastructure
|
||||
{
|
||||
[Export(typeof(IAvaloniaDesignerSettings)), PartCreationPolicy(CreationPolicy.Shared)]
|
||||
public class AvaloniaDesignerSettings : IAvaloniaDesignerSettings
|
||||
{
|
||||
private const string COLLECTION_PATH = "AvaloniaDesigner";
|
||||
private const string DOCUMENT_VIEW_PROPERTY = "DocumentView";
|
||||
private const string SPLIT_ORIENTATION_PROPERTY = "SplitOrientation";
|
||||
private const string IS_DESIGNER_ENABLED_PROPERTY = "IsDesignerEnabled";
|
||||
private const string IS_REVERSED_PROPERTY = "IsReversed";
|
||||
|
||||
private readonly WritableSettingsStore _store;
|
||||
|
||||
[ImportingConstructor]
|
||||
public AvaloniaDesignerSettings(SVsServiceProvider vsServiceProvider)
|
||||
{
|
||||
_store = vsServiceProvider.GetWritableSettingsStore(SettingsScope.UserSettings);
|
||||
LoadSettings();
|
||||
}
|
||||
|
||||
public bool IsDesignerEnabled { get; set; }
|
||||
public SplitOrientation SplitOrientation { get; set; }
|
||||
public DocumentView DocumentView { get; set; }
|
||||
public bool IsReversed { get; set; }
|
||||
|
||||
private void LoadSettings()
|
||||
{
|
||||
// IsDesignerEnabled, either read from the store or initialize to true.
|
||||
IsDesignerEnabled = !_store.PropertyExists(COLLECTION_PATH, IS_DESIGNER_ENABLED_PROPERTY) || _store.GetBoolean(COLLECTION_PATH, IS_DESIGNER_ENABLED_PROPERTY);
|
||||
|
||||
SplitOrientation = _store.PropertyExists(COLLECTION_PATH, SPLIT_ORIENTATION_PROPERTY)
|
||||
? (SplitOrientation)_store.GetInt32(COLLECTION_PATH, SPLIT_ORIENTATION_PROPERTY)
|
||||
: SplitOrientation.Default;
|
||||
|
||||
DocumentView = _store.PropertyExists(COLLECTION_PATH, DOCUMENT_VIEW_PROPERTY)
|
||||
? (DocumentView)_store.GetInt32(COLLECTION_PATH, DOCUMENT_VIEW_PROPERTY)
|
||||
: DocumentView.SplitView;
|
||||
|
||||
IsReversed = _store.PropertyExists(COLLECTION_PATH, IS_REVERSED_PROPERTY) && _store.GetBoolean(COLLECTION_PATH, IS_REVERSED_PROPERTY);
|
||||
}
|
||||
|
||||
public void Save()
|
||||
{
|
||||
if (!_store.CollectionExists(COLLECTION_PATH))
|
||||
{
|
||||
_store.CreateCollection(COLLECTION_PATH);
|
||||
}
|
||||
|
||||
_store.SetBoolean(COLLECTION_PATH, IS_DESIGNER_ENABLED_PROPERTY, IsDesignerEnabled);
|
||||
_store.SetBoolean(COLLECTION_PATH, IS_REVERSED_PROPERTY, IsReversed);
|
||||
_store.SetInt32(COLLECTION_PATH, SPLIT_ORIENTATION_PROPERTY, (int)SplitOrientation);
|
||||
_store.SetInt32(COLLECTION_PATH, DOCUMENT_VIEW_PROPERTY, (int)DocumentView);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,200 +0,0 @@
|
|||
using System;
|
||||
using System.ComponentModel.Composition;
|
||||
using System.IO;
|
||||
using Microsoft.VisualStudio.Shell.Interop;
|
||||
using IServiceProvider = Microsoft.VisualStudio.OLE.Interop.IServiceProvider;
|
||||
using System.Runtime.InteropServices;
|
||||
using Microsoft.VisualStudio;
|
||||
using Microsoft.VisualStudio.OLE.Interop;
|
||||
using Microsoft.VisualStudio.Shell;
|
||||
using Microsoft.VisualStudio.TextManager.Interop;
|
||||
using AvaloniaVS.Internals;
|
||||
using IOleServiceProvider = Microsoft.VisualStudio.OLE.Interop.IServiceProvider;
|
||||
|
||||
namespace AvaloniaVS.Infrastructure
|
||||
{
|
||||
[Guid(Guids.AvaloniaEditorFactoryString), Export]
|
||||
public class AvaloniaEditorFactory : IVsEditorFactory, IDisposable
|
||||
{
|
||||
private readonly AvaloniaPackage _package;
|
||||
private readonly IAvaloniaDesignerSettings _designerSettings;
|
||||
private ServiceProvider _serviceProvider;
|
||||
private IOleServiceProvider _oleServiceProvider;
|
||||
|
||||
[ImportingConstructor]
|
||||
public AvaloniaEditorFactory(AvaloniaPackage package, IAvaloniaDesignerSettings designerSettings)
|
||||
{
|
||||
_package = package;
|
||||
_designerSettings = designerSettings;
|
||||
}
|
||||
|
||||
public object GetService(Type serviceType)
|
||||
{
|
||||
return _serviceProvider.GetService(serviceType);
|
||||
}
|
||||
|
||||
public int CreateEditorInstance(uint grfCreateDoc,
|
||||
string pszMkDocument,
|
||||
string pszPhysicalView,
|
||||
IVsHierarchy pvHier,
|
||||
uint itemid,
|
||||
IntPtr punkDocDataExisting,
|
||||
out IntPtr ppunkDocView,
|
||||
out IntPtr ppunkDocData,
|
||||
out string pbstrEditorCaption,
|
||||
out Guid pguidCmdUI,
|
||||
out int pgrfCDW)
|
||||
{
|
||||
ppunkDocView = IntPtr.Zero;
|
||||
ppunkDocData = IntPtr.Zero;
|
||||
pguidCmdUI = Guids.AvaloniaDesignerGeneralPageGuid;
|
||||
pgrfCDW = 0;
|
||||
pbstrEditorCaption = null;
|
||||
|
||||
// Validate inputs
|
||||
if ((grfCreateDoc & (VSConstants.CEF_OPENFILE | VSConstants.CEF_SILENT)) == 0)
|
||||
{
|
||||
return VSConstants.E_INVALIDARG;
|
||||
}
|
||||
|
||||
if (pszMkDocument.ToLowerInvariant().EndsWith(".xaml"))
|
||||
{
|
||||
//Special handling for xaml documents
|
||||
if (!Utils.CheckAvaloniaRoot(File.ReadAllText(pszMkDocument)))
|
||||
return VSConstants.VS_E_UNSUPPORTEDFORMAT;
|
||||
}
|
||||
|
||||
IVsTextLines documentBuffer = null;
|
||||
|
||||
if (punkDocDataExisting == IntPtr.Zero)
|
||||
{
|
||||
// create an invisible editor
|
||||
var invisibleEditorManager = (IVsInvisibleEditorManager)_serviceProvider.GetService(typeof(IVsInvisibleEditorManager));
|
||||
IVsInvisibleEditor invisibleEditor;
|
||||
ErrorHandler.ThrowOnFailure(invisibleEditorManager.RegisterInvisibleEditor(pszMkDocument,
|
||||
null,
|
||||
(uint) _EDITORREGFLAGS.RIEF_ENABLECACHING,
|
||||
null,
|
||||
out invisibleEditor));
|
||||
|
||||
var docDataPointer = IntPtr.Zero;
|
||||
var guidIVSTextLines = typeof(IVsTextLines).GUID;
|
||||
ErrorHandler.ThrowOnFailure(invisibleEditor.GetDocData(1, ref guidIVSTextLines, out docDataPointer));
|
||||
documentBuffer = (IVsTextLines)Marshal.GetObjectForIUnknown(docDataPointer);
|
||||
|
||||
//It is important to site the TextBuffer object
|
||||
var objWSite = documentBuffer as IObjectWithSite;
|
||||
if (objWSite != null)
|
||||
{
|
||||
var oleServiceProvider = (IOleServiceProvider)GetService(typeof(IOleServiceProvider));
|
||||
objWSite.SetSite(oleServiceProvider);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
documentBuffer = Marshal.GetObjectForIUnknown(punkDocDataExisting) as IVsTextLines;
|
||||
if (documentBuffer == null)
|
||||
{
|
||||
return VSConstants.VS_E_INCOMPATIBLEDOCDATA;
|
||||
}
|
||||
}
|
||||
|
||||
if (documentBuffer == null)
|
||||
{
|
||||
return VSConstants.S_FALSE;
|
||||
}
|
||||
|
||||
// set xml as the language service id
|
||||
ErrorHandler.ThrowOnFailure(documentBuffer.SetLanguageServiceID(ref Guids.XmlLanguageServiceGuid));
|
||||
|
||||
var editorPane = GetDocumentView(documentBuffer, pszMkDocument);
|
||||
ppunkDocView = Marshal.GetIUnknownForObject(editorPane);
|
||||
ppunkDocData = Marshal.GetIUnknownForObject(documentBuffer);
|
||||
pbstrEditorCaption = "";
|
||||
return VSConstants.S_OK;
|
||||
}
|
||||
|
||||
internal object GetDocumentView(IVsTextLines documentBuffer, string filePath)
|
||||
{
|
||||
var codeWindow = CreateVsCodeWindow(documentBuffer);
|
||||
|
||||
// in case the designer is not supported, we return the current VsCodeWindow that we just created.
|
||||
if (!_designerSettings.IsDesignerEnabled)
|
||||
{
|
||||
return codeWindow;
|
||||
}
|
||||
|
||||
var AvaloniaDesignerPane = new AvaloniaDesignerPane(codeWindow, documentBuffer, filePath, _designerSettings);
|
||||
SiteObject(AvaloniaDesignerPane);
|
||||
return AvaloniaDesignerPane;
|
||||
}
|
||||
|
||||
private void SiteObject(IObjectWithSite objectWithSite)
|
||||
{
|
||||
if (objectWithSite == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var oleServiceProvider = (IOleServiceProvider)GetService(typeof(IOleServiceProvider));
|
||||
objectWithSite.SetSite(oleServiceProvider);
|
||||
}
|
||||
|
||||
private IVsCodeWindow CreateVsCodeWindow(IVsTextLines documentBuffer)
|
||||
{
|
||||
// Create a code window adapter.
|
||||
var codeWindow = VisualStudioServices.VsEditorAdaptersFactoryService.CreateVsCodeWindowAdapter(_oleServiceProvider);
|
||||
|
||||
// Disable the splitter control on the editor as leaving it enabled causes a crash if the user
|
||||
// tries to use it here :(
|
||||
var codeWindowEx = (IVsCodeWindowEx)codeWindow;
|
||||
var initView = new INITVIEW[1];
|
||||
codeWindowEx.Initialize((uint)_codewindowbehaviorflags.CWB_DEFAULT, VSUSERCONTEXTATTRIBUTEUSAGE.VSUC_Usage_Filter, "", "", 0, initView);
|
||||
|
||||
//Associate our IVsTextLines with our new code window.
|
||||
ErrorHandler.ThrowOnFailure(codeWindow.SetBuffer(documentBuffer));
|
||||
return codeWindow;
|
||||
}
|
||||
|
||||
public int SetSite(IServiceProvider psp)
|
||||
{
|
||||
_oleServiceProvider = psp;
|
||||
_serviceProvider =new ServiceProvider(psp);
|
||||
return VSConstants.S_OK;
|
||||
}
|
||||
|
||||
public int Close()
|
||||
{
|
||||
return VSConstants.S_OK;
|
||||
}
|
||||
|
||||
public int MapLogicalView(ref Guid rguidLogicalView, out string pbstrPhysicalView)
|
||||
{
|
||||
pbstrPhysicalView = null;
|
||||
|
||||
// primary view.
|
||||
if (rguidLogicalView == VSConstants.LOGVIEWID_Primary ||
|
||||
rguidLogicalView == VSConstants.LOGVIEWID_Code ||
|
||||
rguidLogicalView == VSConstants.LOGVIEWID_Debugging ||
|
||||
rguidLogicalView == VSConstants.LOGVIEWID_TextView ||
|
||||
rguidLogicalView == VSConstants.LOGVIEWID_Designer)
|
||||
{
|
||||
return VSConstants.S_OK;
|
||||
}
|
||||
|
||||
return VSConstants.E_NOTIMPL;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
lock (this)
|
||||
{
|
||||
if (_serviceProvider != null)
|
||||
{
|
||||
_serviceProvider.Dispose();
|
||||
_serviceProvider = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,96 +0,0 @@
|
|||
//------------------------------------------------------------------------------
|
||||
// <copyright file="AvaloniaPackage.cs" company="Company">
|
||||
// Copyright (c) Company. All rights reserved.
|
||||
// </copyright>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
using System.ComponentModel.Composition;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Runtime.InteropServices;
|
||||
using Microsoft.VisualStudio.ComponentModelHost;
|
||||
using Microsoft.VisualStudio.Editor;
|
||||
using Microsoft.VisualStudio.Shell;
|
||||
using Microsoft.VisualStudio.Shell.Interop;
|
||||
using AvaloniaVS.Internals;
|
||||
using AvaloniaVS.Options;
|
||||
using System;
|
||||
using System.Threading;
|
||||
using Task = System.Threading.Tasks.Task;
|
||||
|
||||
namespace AvaloniaVS.Infrastructure
|
||||
{
|
||||
// this attribute will allow visual studio to look for assemblies in the extension
|
||||
// folder
|
||||
[ProvideBindingPath]
|
||||
|
||||
[PackageRegistration(UseManagedResourcesOnly = true, AllowsBackgroundLoading =true)]
|
||||
[InstalledProductRegistration("#110", "#112", "1.0", IconResourceID = 400)] // Info on this package for Help/About
|
||||
|
||||
[ProvideXmlEditorChooserDesignerView("Avalonia",
|
||||
"xaml",
|
||||
LogicalViewID.Designer,
|
||||
10000,
|
||||
Namespace = "https://github.com/avaloniaui",
|
||||
MatchExtensionAndNamespace = true,
|
||||
CodeLogicalViewEditor = typeof(AvaloniaEditorFactory),
|
||||
DesignerLogicalViewEditor = typeof(AvaloniaEditorFactory),
|
||||
DebuggingLogicalViewEditor = typeof(AvaloniaEditorFactory),
|
||||
TextLogicalViewEditor = typeof(AvaloniaEditorFactory))]
|
||||
|
||||
[ProvideXmlEditorChooserDesignerView("Avalonia_Enforced",
|
||||
"xaml",
|
||||
LogicalViewID.Designer,
|
||||
10001,
|
||||
CodeLogicalViewEditor = typeof(AvaloniaEditorFactory),
|
||||
DesignerLogicalViewEditor = typeof(AvaloniaEditorFactory),
|
||||
DebuggingLogicalViewEditor = typeof(AvaloniaEditorFactory),
|
||||
TextLogicalViewEditor = typeof(AvaloniaEditorFactory))]
|
||||
|
||||
[ProvideEditorExtension(typeof(AvaloniaEditorFactory), ".paml", 100, NameResourceID = 113, DefaultName = "Avalonia Xaml Editor")]
|
||||
[ProvideEditorLogicalView(typeof(AvaloniaEditorFactory), LogicalViewID.TextView)]
|
||||
[ProvideEditorLogicalView(typeof(AvaloniaEditorFactory), LogicalViewID.Code)]
|
||||
[ProvideEditorLogicalView(typeof(AvaloniaEditorFactory), LogicalViewID.Designer)]
|
||||
[ProvideEditorLogicalView(typeof(AvaloniaEditorFactory), LogicalViewID.Debugging)]
|
||||
|
||||
[ProvideEditorFactory(typeof(AvaloniaEditorFactory),
|
||||
113,
|
||||
TrustLevel = __VSEDITORTRUSTLEVEL.ETL_AlwaysTrusted)]
|
||||
|
||||
// Options pages
|
||||
[ProvideProfile(typeof(AvaloniaDesignerGeneralPage), "Avalonia designer", "Avalonia Designer Options", 114, 114, true, DescriptionResourceID = 114)]
|
||||
[ProvideOptionPage(typeof(AvaloniaDesignerGeneralPage),
|
||||
"Avalonia Designer",
|
||||
"General",
|
||||
114,
|
||||
115,
|
||||
true,
|
||||
new[] { "xaml", "designer" })]
|
||||
|
||||
// we let the shell know that the package exposes some menus
|
||||
[ProvideMenuResource("Menus.ctmenu", 1)]
|
||||
|
||||
[SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1650:ElementDocumentationMustBeSpelledCorrectly", Justification = "pkgdef, VS and vsixmanifest are valid VS terms")]
|
||||
[ProvideAutoLoad("F1536EF8-92EC-443C-9ED7-FDADF150DA82")]
|
||||
[ProvideAutoLoad("ADFC4E64-0397-11D1-9F4E-00A0C911004F")]
|
||||
[Guid(PackageGuidString)]
|
||||
[ComVisible(true)]
|
||||
[Export]
|
||||
public sealed class AvaloniaPackage : AsyncPackage
|
||||
{
|
||||
public const string PackageGuidString = "865ba8d5-1180-4bf8-8821-345f72a4cb79";
|
||||
|
||||
protected override async Task InitializeAsync(CancellationToken cancellationToken, IProgress<ServiceProgressData> progress)
|
||||
{
|
||||
await base.InitializeAsync(cancellationToken, progress);
|
||||
|
||||
await JoinableTaskFactory.SwitchToMainThreadAsync();
|
||||
|
||||
var componentModel = (IComponentModel)await GetServiceAsync(typeof(SComponentModel));
|
||||
VisualStudioServices.ComponentModel = componentModel;
|
||||
VisualStudioServices.VsEditorAdaptersFactoryService = componentModel.GetService<IVsEditorAdaptersFactoryService>();
|
||||
|
||||
var editorFactory = componentModel.GetService<AvaloniaEditorFactory>();
|
||||
RegisterEditorFactory(editorFactory);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,41 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Management;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace AvaloniaVS.Infrastructure
|
||||
{
|
||||
internal class DesignerKiller
|
||||
{
|
||||
static List<Process> s_designers = new List<Process>();
|
||||
|
||||
|
||||
public static void KillAllDesigners()
|
||||
{
|
||||
lock (s_designers)
|
||||
{
|
||||
foreach (var p in s_designers.ToList())
|
||||
{
|
||||
try
|
||||
{
|
||||
p.Kill();
|
||||
}
|
||||
catch
|
||||
{
|
||||
// Ignore
|
||||
}
|
||||
}
|
||||
s_designers.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
public static void Register(Process proc)
|
||||
{
|
||||
lock (s_designers)
|
||||
s_designers.Add(proc);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
using System.ComponentModel;
|
||||
|
||||
namespace AvaloniaVS.Infrastructure
|
||||
{
|
||||
public enum DocumentView
|
||||
{
|
||||
[Description("Split View")]
|
||||
SplitView,
|
||||
|
||||
[Description("Source View")]
|
||||
SourceView,
|
||||
|
||||
[Description("Design View")]
|
||||
DesignView
|
||||
}
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
using System;
|
||||
|
||||
namespace AvaloniaVS.Infrastructure
|
||||
{
|
||||
static class GuidList
|
||||
{
|
||||
public static readonly Guid EditorFactoryGuid = new Guid("31C92F7E-F95D-40AD-9D30-0DD0D28D96A6");
|
||||
public const string EditorFactoryGuidString = "31C92F7E-F95D-40AD-9D30-0DD0D28D96A6";
|
||||
public const string XmlChooserEditorFactory = @"{32CC8DFA-2D70-49b2-94CD-22D57349B778}";
|
||||
}
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
namespace AvaloniaVS.Infrastructure
|
||||
{
|
||||
public interface IAvaloniaDesignerSettings
|
||||
{
|
||||
void Save();
|
||||
bool IsDesignerEnabled { get; set; }
|
||||
SplitOrientation SplitOrientation { get; set; }
|
||||
DocumentView DocumentView { get; set; }
|
||||
bool IsReversed { get; set; }
|
||||
}
|
||||
}
|
Двоичные данные
src/AvaloniaVS/Infrastructure/Key.snk
Двоичные данные
src/AvaloniaVS/Infrastructure/Key.snk
Двоичный файл не отображается.
|
@ -1,189 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace AvaloniaVS.Infrastructure
|
||||
{
|
||||
public class MarkupExtensionParser
|
||||
{
|
||||
struct ParserState
|
||||
{
|
||||
public ParserStateType State { get; set; }
|
||||
public int ElementNameStart;
|
||||
public int? ElementNameEnd;
|
||||
public int? AttributeNameStart;
|
||||
public int? AttributeNameEnd;
|
||||
public int? AttributeValueStart;
|
||||
|
||||
public void Reset(ParserStateType state)
|
||||
{
|
||||
State = state;
|
||||
ElementNameStart = 0;
|
||||
ElementNameEnd = AttributeNameStart = AttributeNameEnd = AttributeValueStart = null;
|
||||
}
|
||||
}
|
||||
|
||||
public enum ParserStateType
|
||||
{
|
||||
None,
|
||||
StartElement,
|
||||
InsideElement,
|
||||
StartAttribute,
|
||||
AfterAttribute,
|
||||
BeforeAttributeValue,
|
||||
AttributeValue
|
||||
}
|
||||
|
||||
public int CurrentValueStart
|
||||
{
|
||||
get
|
||||
{
|
||||
if (State == ParserStateType.StartElement)
|
||||
return _state.ElementNameStart;
|
||||
if (State == ParserStateType.StartAttribute)
|
||||
return _state.AttributeNameStart.Value;
|
||||
if (State == ParserStateType.AttributeValue)
|
||||
return _state.AttributeValueStart.Value;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public ParserStateType State => _state.State;
|
||||
|
||||
public string ElementName
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_data.Length == 0)
|
||||
return null;
|
||||
if (_state.State < ParserStateType.StartElement)
|
||||
return null;
|
||||
var endElement = _state.ElementNameEnd ?? (_data.Length - 1);
|
||||
if (endElement < _state.ElementNameStart)
|
||||
endElement = _state.ElementNameStart;
|
||||
if (endElement >= _data.Length)
|
||||
return "";
|
||||
return _data.Substring(_state.ElementNameStart, endElement - _state.ElementNameStart + 1);
|
||||
}
|
||||
}
|
||||
|
||||
public string AttributeName
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_state.State < ParserStateType.StartAttribute || _data.Length == 0)
|
||||
return null;
|
||||
if (_state.AttributeNameStart == null || _state.AttributeNameEnd == null)
|
||||
return null;
|
||||
if (_state.AttributeNameEnd.Value < _state.AttributeNameStart.Value)
|
||||
return null;
|
||||
return _data.Substring(_state.AttributeNameStart.Value,
|
||||
_state.AttributeNameEnd.Value - _state.AttributeNameStart.Value + 1);
|
||||
}
|
||||
}
|
||||
|
||||
public string AttributeValue
|
||||
{
|
||||
get
|
||||
{
|
||||
if (State < ParserStateType.AttributeValue || _data.Length == 0 || _state.AttributeValueStart == null)
|
||||
return null;
|
||||
return _data.Substring(_state.AttributeValueStart.Value);
|
||||
}
|
||||
}
|
||||
|
||||
ParserState _state;
|
||||
Stack<ParserState> _stack = new Stack<ParserState>();
|
||||
|
||||
private readonly string _data;
|
||||
|
||||
private MarkupExtensionParser(string data)
|
||||
{
|
||||
_data = data;
|
||||
}
|
||||
|
||||
private void Parse()
|
||||
{
|
||||
for (int c = 0; c < _data.Length; c++)
|
||||
{
|
||||
var st = _state.State;
|
||||
var ch = _data[c];
|
||||
|
||||
//Special symbols that we can handle ignoring current state (assuming that expression syntax is correct)
|
||||
if (ch == ',')
|
||||
{
|
||||
_state.State = ParserStateType.InsideElement;
|
||||
}
|
||||
else if (ch == '{')
|
||||
{
|
||||
if(st != ParserStateType.None)
|
||||
_stack.Push(_state);
|
||||
_state.Reset(ParserStateType.StartElement);
|
||||
_state.ElementNameStart = c + 1;
|
||||
}
|
||||
else if (ch == '}')
|
||||
{
|
||||
if (_stack.Count != 0)
|
||||
{
|
||||
_state = _stack.Pop();
|
||||
_state.State = ParserStateType.InsideElement;
|
||||
}
|
||||
}
|
||||
//Regular state handling
|
||||
else if (st == ParserStateType.StartElement)
|
||||
{
|
||||
if (_state.ElementNameStart == c && char.IsWhiteSpace(ch))
|
||||
_state.ElementNameStart++;
|
||||
else if (char.IsWhiteSpace(ch))
|
||||
{
|
||||
_state.ElementNameEnd = c;
|
||||
_state.State = ParserStateType.InsideElement;
|
||||
}
|
||||
}
|
||||
else if (st == ParserStateType.InsideElement)
|
||||
{
|
||||
if (!char.IsWhiteSpace(ch))
|
||||
{
|
||||
_state.State = ParserStateType.StartAttribute;
|
||||
_state.AttributeNameStart = c;
|
||||
}
|
||||
}
|
||||
else if (st == ParserStateType.StartAttribute)
|
||||
{
|
||||
_state.AttributeNameEnd = c - 1;
|
||||
if (ch == '=')
|
||||
_state.State = ParserStateType.BeforeAttributeValue;
|
||||
else if (char.IsWhiteSpace(ch))
|
||||
_state.State = ParserStateType.AfterAttribute;
|
||||
}
|
||||
else if (st == ParserStateType.AfterAttribute)
|
||||
{
|
||||
if (ch == '=')
|
||||
_state.State = ParserStateType.BeforeAttributeValue;
|
||||
}
|
||||
else if (st == ParserStateType.BeforeAttributeValue)
|
||||
{
|
||||
if (!char.IsWhiteSpace(ch))
|
||||
{
|
||||
_state.AttributeValueStart = c;
|
||||
_state.State = ParserStateType.AttributeValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static MarkupExtensionParser Parse(string data)
|
||||
{
|
||||
var rv = new MarkupExtensionParser(data);
|
||||
rv.Parse();
|
||||
return rv;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"State: {State}, ElementName: {ElementName}, AttributeName: {AttributeName}, AttributeValue: {AttributeValue}";
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,229 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Threading;
|
||||
using AvaloniaVS.Helpers;
|
||||
using AvaloniaVS.ViewModels;
|
||||
using EnvDTE;
|
||||
using EnvDTE100;
|
||||
using EnvDTE80;
|
||||
using Microsoft.VisualStudio.Shell.Interop;
|
||||
using VSLangProj;
|
||||
|
||||
namespace AvaloniaVS.Infrastructure
|
||||
{
|
||||
public sealed class ProjectInfoService
|
||||
{
|
||||
static readonly ProjectInfoService Instance = new ProjectInfoService();
|
||||
private readonly DTE2 _dte;
|
||||
public static IEnumerable<ProjectDescriptor> Projects => Instance._cached;
|
||||
|
||||
private bool _solutionRescanQueued = true;
|
||||
private bool _targetPathRescanQueued = true;
|
||||
private bool _treeRebuildQueued = true;
|
||||
private ProjectItemsEvents _solutionItemEvents;
|
||||
private SolutionEvents _solutionEvents;
|
||||
|
||||
|
||||
class ProjectEntry
|
||||
{
|
||||
private readonly ProjectInfoService _service;
|
||||
private ReferencesEvents _events;
|
||||
public Project Project { get; }
|
||||
public HashSet<Project> References = new HashSet<Project>();
|
||||
public ProjectDescriptor Descriptor { get; }
|
||||
public bool RescanQueued { get; private set; }
|
||||
public bool TargetPathUpdateQueued { get; private set; }
|
||||
|
||||
public void CheckForLoadedStateChanges()
|
||||
{
|
||||
var project = Project.GetObjectSafe<VSProject>();
|
||||
if (project != null && _events == null)
|
||||
{
|
||||
SetupEvents(project);
|
||||
Rescan();
|
||||
}
|
||||
if (project == null && _events != null)
|
||||
{
|
||||
_events = null;
|
||||
References.Clear();
|
||||
_service._treeRebuildQueued = true;
|
||||
TargetPathUpdateQueued = true;
|
||||
}
|
||||
}
|
||||
|
||||
void SetupEvents(VSProject vsProject)
|
||||
{
|
||||
_events = vsProject.Events.ReferencesEvents;
|
||||
_events.ReferenceAdded += r =>
|
||||
{
|
||||
var p = r.SourceProject;
|
||||
if (p != null)
|
||||
References.Add(p);
|
||||
_service._treeRebuildQueued = true;
|
||||
};
|
||||
_events.ReferenceRemoved += r =>
|
||||
{
|
||||
var p = r.SourceProject;
|
||||
if (p != null)
|
||||
References.Remove(p);
|
||||
_service._treeRebuildQueued = true;
|
||||
};
|
||||
_events.ReferenceChanged += delegate
|
||||
{
|
||||
RescanQueued = true;
|
||||
};
|
||||
}
|
||||
|
||||
public ProjectEntry(ProjectInfoService service, Project project)
|
||||
{
|
||||
_service = service;
|
||||
Project = project;
|
||||
Descriptor = new ProjectDescriptor(project);
|
||||
var vsProject = project.GetObjectSafe<VSProject>();
|
||||
if (vsProject != null)
|
||||
SetupEvents(vsProject);
|
||||
RescanQueued = TargetPathUpdateQueued = true;
|
||||
}
|
||||
|
||||
public void Rescan()
|
||||
{
|
||||
References.Clear();
|
||||
var vsProject = Project.GetObjectSafe<VSProject>();
|
||||
if (vsProject != null)
|
||||
foreach (Reference r in vsProject.References)
|
||||
{
|
||||
var p = r.SourceProject;
|
||||
if (p != null)
|
||||
References.Add(p);
|
||||
}
|
||||
RescanQueued = false;
|
||||
_service._treeRebuildQueued = true;
|
||||
}
|
||||
|
||||
public bool UpdateTargetPath()
|
||||
{
|
||||
var n = Project.GetAssemblyPath();
|
||||
TargetPathUpdateQueued = false;
|
||||
if (n != Descriptor.TargetAssembly)
|
||||
{
|
||||
Descriptor.TargetAssembly = n;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private Dictionary<Project, ProjectEntry> _projects = new Dictionary<Project, ProjectEntry>();
|
||||
private List<ProjectDescriptor> _cached = new List<ProjectDescriptor>();
|
||||
|
||||
private ProjectInfoService()
|
||||
{
|
||||
_dte = (DTE2)Microsoft.VisualStudio.Shell.Package.GetGlobalService(typeof(SDTE));
|
||||
_solutionItemEvents = _dte.Events.SolutionItemsEvents;
|
||||
_solutionItemEvents.ItemAdded += delegate { _solutionRescanQueued = true; };
|
||||
_solutionItemEvents.ItemRenamed += delegate { _solutionRescanQueued = true; };
|
||||
_solutionItemEvents.ItemRemoved += delegate { _solutionRescanQueued = true; };
|
||||
_solutionEvents = _dte.Events.SolutionEvents;
|
||||
_solutionEvents.Opened += delegate { _solutionRescanQueued = true; };
|
||||
|
||||
new DispatcherTimer() { Interval = new TimeSpan(0, 0, 0, 1), IsEnabled = true }.Tick += OnTick;
|
||||
OnTick(null, null);
|
||||
AvaloniaBuildEvents.Instance.BuildEnd += delegate
|
||||
{
|
||||
_targetPathRescanQueued = true;
|
||||
};
|
||||
}
|
||||
|
||||
IEnumerable<Project> Collect(ProjectEntry desc)
|
||||
{
|
||||
foreach (var r in desc.References)
|
||||
{
|
||||
yield return r;
|
||||
if(_projects.TryGetValue(r, out var found))
|
||||
foreach (var ch in Collect(found))
|
||||
yield return ch;
|
||||
}
|
||||
}
|
||||
|
||||
public static ICommand ReloadAll => new RelayCommand(() =>
|
||||
{
|
||||
Instance._projects = new Dictionary<Project, ProjectEntry>();
|
||||
Instance._solutionRescanQueued = Instance._treeRebuildQueued = Instance._targetPathRescanQueued = true;
|
||||
Instance.OnTick(null, null);
|
||||
});
|
||||
|
||||
|
||||
private void OnTick(object sender, EventArgs e)
|
||||
{
|
||||
|
||||
var dic = new Dictionary<Project, ProjectEntry>();
|
||||
|
||||
foreach(var p in GetProjects(_dte.Solution.Projects.OfType<Project>()))
|
||||
{
|
||||
if (_projects.TryGetValue(p, out var existing))
|
||||
dic[p] = existing;
|
||||
else
|
||||
{
|
||||
dic[p] = new ProjectEntry(this, p);
|
||||
_treeRebuildQueued = true;
|
||||
}
|
||||
}
|
||||
if (dic.Count != _projects.Count)
|
||||
_treeRebuildQueued = true;
|
||||
_projects = dic;
|
||||
|
||||
|
||||
bool targetPathsChanged = false;
|
||||
foreach (var p in _projects.Values)
|
||||
{
|
||||
p.CheckForLoadedStateChanges();
|
||||
if (p.RescanQueued)
|
||||
p.Rescan();
|
||||
if (_targetPathRescanQueued || p.TargetPathUpdateQueued)
|
||||
targetPathsChanged |= p.UpdateTargetPath();
|
||||
|
||||
}
|
||||
_targetPathRescanQueued = false;
|
||||
if (_treeRebuildQueued)
|
||||
{
|
||||
foreach (var p in _projects.Values)
|
||||
{
|
||||
p.Descriptor.References = Collect(p).Distinct().ToList();
|
||||
}
|
||||
_cached = _projects.Values.Select(d => d.Descriptor).ToList();
|
||||
|
||||
}
|
||||
if (targetPathsChanged || _treeRebuildQueued)
|
||||
Changed?.Invoke(this, new EventArgs());
|
||||
_treeRebuildQueued = false;
|
||||
}
|
||||
|
||||
|
||||
public static void AddChangedHandler(EventHandler<EventArgs> handler)
|
||||
{
|
||||
WeakEventManager<ProjectInfoService, EventArgs>.AddHandler(Instance, nameof(Changed), handler);
|
||||
}
|
||||
|
||||
public event EventHandler<EventArgs> Changed;
|
||||
|
||||
|
||||
static IEnumerable<Project> GetProjects(IEnumerable<Project> en)
|
||||
{
|
||||
foreach (var p in en)
|
||||
{
|
||||
if (p.GetObjectSafe<VSProject>() != null)
|
||||
yield return p;
|
||||
|
||||
if (p.GetObjectSafe<SolutionFolder>() != null)
|
||||
foreach (var item in GetProjects(p.ProjectItems.OfType<ProjectItem>().Select(i => i.SubProject)))
|
||||
yield return item;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,15 +0,0 @@
|
|||
using System.ComponentModel;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace AvaloniaVS.Infrastructure
|
||||
{
|
||||
public class PropertyChangedBase : INotifyPropertyChanged
|
||||
{
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
|
||||
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
|
||||
{
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,30 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Input;
|
||||
|
||||
namespace AvaloniaVS.Infrastructure
|
||||
{
|
||||
class RelayCommand : ICommand
|
||||
{
|
||||
private readonly Action _cb;
|
||||
|
||||
public RelayCommand(Action cb)
|
||||
{
|
||||
_cb = cb;
|
||||
}
|
||||
public bool CanExecute(object parameter)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public void Execute(object parameter)
|
||||
{
|
||||
_cb();
|
||||
}
|
||||
|
||||
public event EventHandler CanExecuteChanged;
|
||||
}
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
using System.ComponentModel;
|
||||
|
||||
namespace AvaloniaVS.Infrastructure
|
||||
{
|
||||
public enum SplitOrientation
|
||||
{
|
||||
[Description("Default")]
|
||||
Default,
|
||||
|
||||
[Description("Horizontal")]
|
||||
Horizontal,
|
||||
|
||||
[Description("Vertical")]
|
||||
Vertical
|
||||
}
|
||||
}
|
|
@ -1,58 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Controls.Primitives;
|
||||
|
||||
namespace AvaloniaVS.Infrastructure
|
||||
{
|
||||
public class TriggerMenuOnLeftClickBehavior
|
||||
{
|
||||
private static readonly DependencyProperty EnabledProperty =
|
||||
DependencyProperty.RegisterAttached(
|
||||
"Enabled", typeof(bool), typeof(TriggerMenuOnLeftClickBehavior),
|
||||
new PropertyMetadata(new PropertyChangedCallback(HandlePropertyChanged))
|
||||
);
|
||||
|
||||
public static bool GetEnabled(DependencyObject obj)
|
||||
{
|
||||
return (bool)obj.GetValue(EnabledProperty);
|
||||
}
|
||||
|
||||
public static void SetEnabled(DependencyObject obj, bool value)
|
||||
{
|
||||
obj.SetValue(EnabledProperty, value);
|
||||
}
|
||||
|
||||
private static void HandlePropertyChanged(
|
||||
DependencyObject obj, DependencyPropertyChangedEventArgs args)
|
||||
{
|
||||
if (obj is ButtonBase el)
|
||||
{
|
||||
if (args.NewValue as bool? == true)
|
||||
el.Click += OnClick;
|
||||
else
|
||||
el.Click -= OnClick;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
private static void OnClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (sender is ButtonBase btn)
|
||||
{
|
||||
var menu = btn.ContextMenu;
|
||||
if (menu != null)
|
||||
{
|
||||
menu.PlacementTarget = btn;
|
||||
menu.DataContext = btn.DataContext;
|
||||
menu.IsOpen = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,139 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="110" xml:space="preserve">
|
||||
<value>AvaloniaPackage Extension</value>
|
||||
</data>
|
||||
<data name="112" xml:space="preserve">
|
||||
<value>AvaloniaPackage Visual Studio Extension Detailed Info</value>
|
||||
</data>
|
||||
<data name="113" xml:space="preserve">
|
||||
<value>Avalonia Xaml Editor</value>
|
||||
</data>
|
||||
<data name="114" xml:space="preserve">
|
||||
<value>Avalonia Designer</value>
|
||||
</data>
|
||||
<data name="115" xml:space="preserve">
|
||||
<value>General</value>
|
||||
</data>
|
||||
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||
<data name="400" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\AvaloniaPackage.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
</root>
|
|
@ -1,231 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.Composition;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Input;
|
||||
using Microsoft.VisualStudio;
|
||||
using Microsoft.VisualStudio.Editor;
|
||||
using Microsoft.VisualStudio.Language.Intellisense;
|
||||
using Microsoft.VisualStudio.OLE.Interop;
|
||||
using Microsoft.VisualStudio.Shell;
|
||||
using Microsoft.VisualStudio.Text;
|
||||
using Microsoft.VisualStudio.Text.Editor;
|
||||
using Microsoft.VisualStudio.TextManager.Interop;
|
||||
using Microsoft.VisualStudio.Utilities;
|
||||
|
||||
namespace AvaloniaVS.IntelliSense
|
||||
{
|
||||
[Export(typeof (IVsTextViewCreationListener))]
|
||||
[Name("Avalonia Completion Handler")]
|
||||
[ContentType("xml")]
|
||||
[TextViewRole(PredefinedTextViewRoles.Editable)]
|
||||
internal class CompletionHandlerProvider : IVsTextViewCreationListener
|
||||
{
|
||||
[Import] internal IVsEditorAdaptersFactoryService AdapterService = null;
|
||||
|
||||
[Import]
|
||||
internal ICompletionBroker CompletionBroker { get; set; }
|
||||
|
||||
[Import]
|
||||
internal SVsServiceProvider ServiceProvider { get; set; }
|
||||
|
||||
public void VsTextViewCreated(IVsTextView textViewAdapter)
|
||||
{
|
||||
ITextView textView = AdapterService.GetWpfTextView(textViewAdapter);
|
||||
if (textView == null || !Utils.IsAvaloniaMarkup(textView))
|
||||
return;
|
||||
|
||||
Func<CompletionCommandHandler> createCommandHandler =
|
||||
() => new CompletionCommandHandler(textViewAdapter, textView, this);
|
||||
textView.Properties.GetOrCreateSingletonProperty(createCommandHandler);
|
||||
}
|
||||
}
|
||||
|
||||
internal class CompletionCommandHandler : IOleCommandTarget
|
||||
{
|
||||
private readonly IOleCommandTarget _nextCommandHandler;
|
||||
private readonly IOleCommandTarget _realCommandHandler;
|
||||
private readonly ITextView _textView;
|
||||
private readonly CompletionHandlerProvider _provider;
|
||||
private ICompletionSession _session;
|
||||
|
||||
|
||||
internal CompletionCommandHandler(IVsTextView textViewAdapter, ITextView textView,
|
||||
CompletionHandlerProvider provider)
|
||||
{
|
||||
this._textView = textView;
|
||||
this._provider = provider;
|
||||
|
||||
//add the command to the command chain
|
||||
textViewAdapter.AddCommandFilter(this, out _nextCommandHandler);
|
||||
var nextProp = _nextCommandHandler.GetType().GetProperty("Next");
|
||||
var filterObjectProp = _nextCommandHandler.GetType().GetProperty("FilterObject");
|
||||
|
||||
_realCommandHandler =
|
||||
(IOleCommandTarget)
|
||||
filterObjectProp.GetValue(nextProp.GetValue(nextProp.GetValue(_nextCommandHandler)));
|
||||
textView.Properties[typeof (CompletionCommandHandler)] = this;
|
||||
}
|
||||
|
||||
public int QueryStatus(ref Guid pguidCmdGroup, uint cCmds, OLECMD[] prgCmds, IntPtr pCmdText)
|
||||
{
|
||||
return _nextCommandHandler.QueryStatus(ref pguidCmdGroup, cCmds, prgCmds, pCmdText);
|
||||
}
|
||||
|
||||
public int Exec(ref Guid pguidCmdGroup, uint nCmdID, uint nCmdexecopt, IntPtr pvaIn, IntPtr pvaOut)
|
||||
{
|
||||
if (VsShellUtilities.IsInAutomationFunction(_provider.ServiceProvider))
|
||||
{
|
||||
return _nextCommandHandler.Exec(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut);
|
||||
}
|
||||
|
||||
|
||||
//make a copy of this so we can look at it after forwarding some commands
|
||||
uint commandID = nCmdID;
|
||||
char typedChar = char.MinValue;
|
||||
//make sure the input is a char before getting it
|
||||
if (pguidCmdGroup == VSConstants.VSStd2K && nCmdID == (uint) VSConstants.VSStd2KCmdID.TYPECHAR)
|
||||
{
|
||||
typedChar = (char) (ushort) Marshal.GetObjectForNativeVariant(pvaIn);
|
||||
}
|
||||
|
||||
if (typedChar == '.')
|
||||
{
|
||||
Console.WriteLine();
|
||||
}
|
||||
|
||||
//check for a commit character
|
||||
if (nCmdID == (uint) VSConstants.VSStd2KCmdID.RETURN
|
||||
|| nCmdID == (uint) VSConstants.VSStd2KCmdID.TAB
|
||||
|| (char.IsWhiteSpace(typedChar) || char.IsPunctuation(typedChar)))
|
||||
{
|
||||
//check for a a selection
|
||||
if (_session != null && !_session.IsDismissed)
|
||||
{
|
||||
//if the selection is fully selected, commit the current session
|
||||
if (_session.SelectedCompletionSet.SelectionStatus.IsSelected)
|
||||
{
|
||||
var completion = _session.SelectedCompletionSet.SelectionStatus.Completion;
|
||||
if (completion.InsertionText != null &&
|
||||
typedChar != ':' &&
|
||||
(typedChar != '.' || !completion.InsertionText.Contains('.')))
|
||||
{
|
||||
_session.Commit();
|
||||
|
||||
if (completion.Properties.ContainsProperty("RecommendedCursorOffset"))
|
||||
{
|
||||
int offset = (int)completion.Properties["RecommendedCursorOffset"];
|
||||
|
||||
var currp = _textView.Caret.Position.BufferPosition;
|
||||
var newp = currp - (completion.InsertionText.Length - offset);
|
||||
|
||||
_textView.Caret.MoveTo(newp);
|
||||
}
|
||||
|
||||
//also, don't add the character to the buffer
|
||||
return VSConstants.S_OK;
|
||||
}
|
||||
else nCmdID = (uint) VSConstants.VSStd2KCmdID.COMPLETEWORD;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
//if there is no selection, dismiss the session
|
||||
_session.Dismiss();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//pass along the command so the char is added to the buffer
|
||||
int retVal = VSConstants.S_OK;
|
||||
bool handled = false;
|
||||
if (nCmdID == (uint) VSConstants.VSStd2KCmdID.COMPLETEWORD ||
|
||||
(!typedChar.Equals(char.MinValue) &&
|
||||
(char.IsLetterOrDigit(typedChar) || typedChar == '<' || typedChar == ' ' || typedChar == '.' || typedChar == ':')))
|
||||
{
|
||||
if (typedChar != '\0')
|
||||
{
|
||||
if (typedChar == '.' || typedChar == ':' || typedChar == '<')
|
||||
{
|
||||
if (!_textView.Selection.IsEmpty)
|
||||
{
|
||||
foreach (var span in _textView.Selection.SelectedSpans.OrderByDescending(x => x.Start))
|
||||
_textView.TextBuffer.Replace(span, "");
|
||||
}
|
||||
_textView.TextBuffer.Insert(_textView.Caret.Position.BufferPosition.Position,
|
||||
typedChar.ToString());
|
||||
}
|
||||
else
|
||||
retVal = _realCommandHandler.Exec(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut);
|
||||
}
|
||||
if (_session == null || _session.IsDismissed)
|
||||
// If there is no active session, bring up completion
|
||||
{
|
||||
|
||||
TriggerCompletion();
|
||||
if (typedChar != '<' && typedChar != 0 && _session != null)
|
||||
_session.Filter();
|
||||
}
|
||||
else
|
||||
{
|
||||
_session.Filter();
|
||||
}
|
||||
handled = true;
|
||||
}
|
||||
else if (commandID == (uint) VSConstants.VSStd2KCmdID.BACKSPACE //redo the filter if there is a deletion
|
||||
|| commandID == (uint) VSConstants.VSStd2KCmdID.DELETE)
|
||||
{
|
||||
if (_session != null && !_session.IsDismissed)
|
||||
_session.Filter();
|
||||
retVal = _nextCommandHandler.Exec(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut);
|
||||
handled = true;
|
||||
}
|
||||
|
||||
else
|
||||
retVal = _nextCommandHandler.Exec(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut);
|
||||
if (handled) return VSConstants.S_OK;
|
||||
return retVal;
|
||||
}
|
||||
|
||||
public void TriggerNew()
|
||||
{
|
||||
if (_session != null)
|
||||
OnSessionDismissed(null, null);
|
||||
TriggerCompletion();
|
||||
}
|
||||
|
||||
public bool TriggerCompletion()
|
||||
{
|
||||
//the caret must be in a non-projection location
|
||||
SnapshotPoint? caretPoint =
|
||||
_textView.Caret.Position.Point.GetPoint(
|
||||
textBuffer => (!textBuffer.ContentType.IsOfType("projection")), PositionAffinity.Predecessor);
|
||||
if (!caretPoint.HasValue)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
_session = _provider.CompletionBroker.CreateCompletionSession
|
||||
(_textView,
|
||||
caretPoint.Value.Snapshot.CreateTrackingPoint(caretPoint.Value.Position,
|
||||
PointTrackingMode.Positive),
|
||||
true);
|
||||
|
||||
//subscribe to the Dismissed event on the session
|
||||
_session.Dismissed += this.OnSessionDismissed;
|
||||
_session.Start();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void OnSessionDismissed(object sender, EventArgs e)
|
||||
{
|
||||
_session.Dismissed -= this.OnSessionDismissed;
|
||||
_session = null;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,100 +0,0 @@
|
|||
using System.Collections.Generic;
|
||||
using System.ComponentModel.Composition;
|
||||
using System.Linq;
|
||||
using Avalonia.Ide.CompletionEngine;
|
||||
using Microsoft.VisualStudio.Imaging;
|
||||
using Microsoft.VisualStudio.Imaging.Interop;
|
||||
using Microsoft.VisualStudio.Language.Intellisense;
|
||||
using Microsoft.VisualStudio.Text;
|
||||
using Microsoft.VisualStudio.Text.Operations;
|
||||
using Microsoft.VisualStudio.Utilities;
|
||||
using CompletionSet = Microsoft.VisualStudio.Language.Intellisense.CompletionSet;
|
||||
using VsCompletion = Microsoft.VisualStudio.Language.Intellisense.Completion3;
|
||||
|
||||
namespace AvaloniaVS.IntelliSense
|
||||
{
|
||||
class CompletionSource : ICompletionSource
|
||||
{
|
||||
private readonly ITextBuffer _textBuffer;
|
||||
private readonly CompletionSourceProvider _provider;
|
||||
private readonly CompletionEngine _engine = new CompletionEngine();
|
||||
|
||||
public CompletionSource(ITextBuffer textBuffer, CompletionSourceProvider provider)
|
||||
{
|
||||
_textBuffer = textBuffer;
|
||||
_provider = provider;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
}
|
||||
|
||||
public void AugmentCompletionSession(ICompletionSession session, IList<CompletionSet> completionSets)
|
||||
{
|
||||
Metadata metadata;
|
||||
string currentAssemblyName;
|
||||
_textBuffer.Properties.TryGetProperty(typeof(Metadata), out metadata);
|
||||
if (metadata == null)
|
||||
return;
|
||||
|
||||
_textBuffer.Properties.TryGetProperty("AssemblyName", out currentAssemblyName);
|
||||
var pos = session.TextView.Caret.Position.BufferPosition;
|
||||
var text = pos.Snapshot.GetText(0, pos.Position);
|
||||
var completions = _engine.GetCompletions(metadata, text, pos, currentAssemblyName);
|
||||
|
||||
if (completions != null && completions.Completions.Count != 0)
|
||||
{
|
||||
var curStart = completions.StartPosition;
|
||||
var span = new SnapshotSpan(pos.Snapshot, curStart, pos.Position - curStart);
|
||||
completionSets.Insert(0, new CompletionSet("Avalonia", "Avalonia",
|
||||
pos.Snapshot.CreateTrackingSpan(span, SpanTrackingMode.EdgeInclusive), completions.Completions
|
||||
.Select(c => ToVsCompletion(c)), null));
|
||||
}
|
||||
}
|
||||
|
||||
private static VsCompletion ToVsCompletion(Avalonia.Ide.CompletionEngine.Completion c)
|
||||
{
|
||||
var result = new VsCompletion(c.DisplayText, c.InsertText, c.Description, ToImageMoniker(c.Kind), null);
|
||||
|
||||
if (c.RecommendedCursorOffset != null)
|
||||
{
|
||||
result.Properties["RecommendedCursorOffset"] = c.RecommendedCursorOffset.Value;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static ImageMoniker ToImageMoniker(CompletionKind kind)
|
||||
{
|
||||
switch (kind)
|
||||
{
|
||||
case CompletionKind.Class: return KnownMonikers.Namespace;
|
||||
case CompletionKind.Property: return KnownMonikers.PropertyPublic;
|
||||
case CompletionKind.AttachedProperty: return KnownMonikers.ExtendedProperty;
|
||||
case CompletionKind.StaticProperty: return KnownMonikers.EnumerationItemPublic;
|
||||
case CompletionKind.Enum: return KnownMonikers.Enumeration;
|
||||
case CompletionKind.Namespace: return KnownMonikers.EnumerationItemPublic;
|
||||
case CompletionKind.MarkupExtension: return KnownMonikers.AddNamespace;
|
||||
case CompletionKind.None: return KnownMonikers.None;
|
||||
default: return KnownMonikers.UnknownMember;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Export(typeof(ICompletionSourceProvider))]
|
||||
[ContentType("xml")]
|
||||
//problem in vs 15.8 token completition is already used in some internal stuff
|
||||
//https://developercommunity.visualstudio.com/content/problem/319949/icompletionsourceprovider-not-getting-called-anymo.html
|
||||
//[Name("token completion")]
|
||||
[Name("avalonia token completion")]
|
||||
internal class CompletionSourceProvider : ICompletionSourceProvider
|
||||
{
|
||||
[Import]
|
||||
internal ITextStructureNavigatorSelectorService NavigatorService { get; set; }
|
||||
|
||||
public ICompletionSource TryCreateCompletionSource(ITextBuffer textBuffer)
|
||||
{
|
||||
return new CompletionSource(textBuffer, this);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
using System;
|
||||
|
||||
namespace AvaloniaVS.Internals
|
||||
{
|
||||
internal static class Guids
|
||||
{
|
||||
// PamlEditorFactory guid
|
||||
public const string AvaloniaEditorFactoryString = "bd983d0e-8554-4053-a787-6f4872cf1d80";
|
||||
public static Guid AvaloniaEditorFactoryGuid = new Guid(AvaloniaEditorFactoryString);
|
||||
|
||||
// xml language service id
|
||||
public const string XmlLanguageServiceString = @"{f6819a78-a205-47b5-be1c-675b3c7f0b8e}";
|
||||
public static Guid XmlLanguageServiceGuid = new Guid(XmlLanguageServiceString);
|
||||
|
||||
// Avalonia designer general page guid
|
||||
public const string AvaloniaDesignerGeneralPageString = "b7e0e2c8-4fae-4387-8933-0560bee874c5";
|
||||
public static Guid AvaloniaDesignerGeneralPageGuid = new Guid(AvaloniaDesignerGeneralPageString);
|
||||
}
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
using Microsoft.VisualStudio.ComponentModelHost;
|
||||
using Microsoft.VisualStudio.Editor;
|
||||
|
||||
namespace AvaloniaVS.Internals
|
||||
{
|
||||
internal static class VisualStudioServices
|
||||
{
|
||||
public static IComponentModel ComponentModel { get; set; }
|
||||
|
||||
public static IVsEditorAdaptersFactoryService VsEditorAdaptersFactoryService { get; set; }
|
||||
}
|
||||
}
|
|
@ -1,35 +0,0 @@
|
|||
using System.Runtime.InteropServices;
|
||||
using Microsoft.VisualStudio.TextManager.Interop;
|
||||
|
||||
namespace AvaloniaVS.Internals
|
||||
{
|
||||
// TODO: those are some of the interface that should be implemented by the AvaloniaDesignerPane, to be fully compatible with the
|
||||
// internal implementation of VsCodeWindowAdapter
|
||||
|
||||
[Guid("47AB8522-6BB1-4C85-BA88-E4B4513F8BE1")]
|
||||
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
|
||||
[ComImport]
|
||||
public interface IVsFindTarget4
|
||||
{
|
||||
int get_IsAutonomous();
|
||||
int get_IsIncrementalSearchSupported();
|
||||
}
|
||||
|
||||
[Guid("A2F0D62B-D0DD-4C59-AAB8-79CD20785451")]
|
||||
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
|
||||
[ComImport]
|
||||
public interface IVsFindTarget3
|
||||
{
|
||||
int get_IsNewUISupported();
|
||||
int NotifyShowingNewUI();
|
||||
}
|
||||
|
||||
[Guid("F657BA30-A2E2-4381-9AC8-F51C73962284")]
|
||||
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
|
||||
[ComImport]
|
||||
public interface IVsEmbeddedCodeWindowHost
|
||||
{
|
||||
void OnNewEmbeddedCodeWindow(IVsCodeWindow codeWindow, bool isReadOnly);
|
||||
void OnCloseEmbeddedCodeWindow(IVsCodeWindow codeWindow);
|
||||
}
|
||||
}
|
|
@ -1,44 +0,0 @@
|
|||
using System.Diagnostics;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Windows;
|
||||
using Microsoft.VisualStudio.Shell;
|
||||
using AvaloniaVS.Internals;
|
||||
using AvaloniaVS.ViewModels;
|
||||
using AvaloniaVS.Views;
|
||||
|
||||
namespace AvaloniaVS.Options
|
||||
{
|
||||
[ClassInterface(ClassInterfaceType.AutoDual)]
|
||||
[Guid(Guids.AvaloniaDesignerGeneralPageString)]
|
||||
public class AvaloniaDesignerGeneralPage : UIElementDialogPage
|
||||
{
|
||||
private AvaloniaDesignerGeneralPageView _view;
|
||||
|
||||
protected override UIElement Child
|
||||
{
|
||||
get
|
||||
{
|
||||
LoadView();
|
||||
return _view;
|
||||
}
|
||||
}
|
||||
|
||||
private void LoadView()
|
||||
{
|
||||
_view = VisualStudioServices.ComponentModel.DefaultExportProvider.GetExportedValue<AvaloniaDesignerGeneralPageView>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles Apply messages from the Visual Studio environment.
|
||||
/// </summary>
|
||||
/// <param name="e">[in] Arguments to event handler.</param>
|
||||
protected override void OnApply(PageApplyEventArgs e)
|
||||
{
|
||||
Debug.Assert(_view != null);
|
||||
var viewModel = _view.DataContext as AvaloniaDesignerGeneralPageViewModel;
|
||||
Debug.Assert(viewModel != null);
|
||||
viewModel.ApplyChanges();
|
||||
base.OnApply(e);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,33 +0,0 @@
|
|||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("AvaloniaVS")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("AvaloniaVS")]
|
||||
[assembly: AssemblyCopyright("")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
Двоичные данные
src/AvaloniaVS/Resources/AvaloniaPackage.ico
Двоичные данные
src/AvaloniaVS/Resources/AvaloniaPackage.ico
Двоичный файл не отображается.
До Ширина: | Высота: | Размер: 418 KiB |
Двоичные данные
src/AvaloniaVS/Resources/File.ico
Двоичные данные
src/AvaloniaVS/Resources/File.ico
Двоичный файл не отображается.
До Ширина: | Высота: | Размер: 1.1 KiB |
|
@ -1,263 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
using System.Xml;
|
||||
using AvaloniaVS.Helpers;
|
||||
using EnvDTE;
|
||||
using EnvDTE80;
|
||||
using Microsoft.VisualStudio;
|
||||
using Microsoft.VisualStudio.ProjectSystem;
|
||||
using Microsoft.VisualStudio.ProjectSystem.Properties;
|
||||
using Microsoft.VisualStudio.Shell;
|
||||
using Microsoft.VisualStudio.Shell.Interop;
|
||||
using Microsoft.VisualStudio.Text;
|
||||
using Microsoft.VisualStudio.Text.Editor;
|
||||
|
||||
namespace AvaloniaVS
|
||||
{
|
||||
static class Utils
|
||||
{
|
||||
public static string GetFilePath(this ITextView textView)
|
||||
{
|
||||
ITextDocument document;
|
||||
return !textView.TextBuffer.Properties.TryGetProperty(typeof (ITextDocument), out document)
|
||||
? null
|
||||
: document.FilePath;
|
||||
}
|
||||
|
||||
public static bool IsAvaloniaMarkup(ITextView textView)
|
||||
{
|
||||
var file = textView.GetFilePath()?.ToLower();
|
||||
bool edit = file?.EndsWith(".paml") == true;
|
||||
if (!edit && file?.EndsWith(".xaml") == true)
|
||||
{
|
||||
edit = Utils.CheckAvaloniaRoot(File.ReadAllText(file));
|
||||
}
|
||||
return edit;
|
||||
}
|
||||
|
||||
public static bool CheckAvaloniaRoot(string content)
|
||||
=> CheckAvaloniaRoot(new XmlTextReader(new StringReader(content)));
|
||||
|
||||
public static bool CheckAvaloniaRoot(XmlReader reader)
|
||||
{
|
||||
try
|
||||
{
|
||||
while (!reader.IsStartElement())
|
||||
{
|
||||
reader.Read();
|
||||
}
|
||||
if (!reader.MoveToFirstAttribute())
|
||||
return false;
|
||||
do
|
||||
{
|
||||
if (reader.Name == "xmlns")
|
||||
{
|
||||
reader.ReadAttributeValue();
|
||||
return reader.Value.ToLower() == AvaloniaNamespace;
|
||||
}
|
||||
|
||||
} while (reader.MoveToNextAttribute());
|
||||
return false;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public const string AvaloniaNamespace = "https://github.com/avaloniaui";
|
||||
|
||||
public static Project GetContainingProject(this IWpfTextView textView)
|
||||
{
|
||||
var fileName = textView.GetFilePath();
|
||||
if (string.IsNullOrWhiteSpace(fileName)) return null;
|
||||
var dte2 = (DTE2)Package.GetGlobalService(typeof(SDTE));
|
||||
var projItem = dte2?.Solution.FindProjectItem(fileName);
|
||||
return projItem?.ContainingProject;
|
||||
}
|
||||
|
||||
static string TryGetProperty(Properties props, string name)
|
||||
{
|
||||
try
|
||||
{
|
||||
return props.Item(name).Value.ToString();
|
||||
}
|
||||
catch
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static Regex DesktopFrameworkRegex = new Regex("^net[0-9]+$");
|
||||
|
||||
/// <summary>
|
||||
/// Gets the full path of the <see cref="Project"/> configuration
|
||||
/// </summary>
|
||||
/// <param name="vsProject"></param>
|
||||
/// <returns>Target Exe path</returns>
|
||||
public static string GetAssemblyPath(this Project vsProject) =>
|
||||
GetProjectOutputInfo(vsProject)?.FirstOrDefault()?.TargetAssembly;
|
||||
|
||||
public static string GetAssemblyName(this Project vsProject) =>
|
||||
vsProject?.Properties.Item("AssemblyName")?.Value?.ToString();
|
||||
|
||||
public static List<ProjectOutputInfo> GetProjectOutputInfo(this Project vsProject)
|
||||
{
|
||||
try
|
||||
{
|
||||
return GetProjectOutputInfoInternal(vsProject);
|
||||
}
|
||||
catch (COMException e) when ((uint)e.HResult == 0x80004005)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public class ProjectOutputInfo
|
||||
{
|
||||
public string TargetAssembly { get; set; }
|
||||
public bool OutputTypeIsExecutable { get; set; }
|
||||
public string TargetFramework { get; set; }
|
||||
public bool IsFullDotNet { get; set; }
|
||||
public bool IsNetCore { get; set; }
|
||||
}
|
||||
|
||||
static List<ProjectOutputInfo> GetProjectOutputInfoInternal(this Project vsProject)
|
||||
{
|
||||
var alternatives = new Dictionary<string, string>();
|
||||
var ucproject = GetUnconfiguredProject(vsProject);
|
||||
if (ucproject != null)
|
||||
foreach (var loaded in ucproject.LoadedConfiguredProjects)
|
||||
{
|
||||
var task = loaded.GetType()
|
||||
.GetProperty("MSBuildProject",
|
||||
BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance)
|
||||
.GetMethod.Invoke(loaded, null) as Task<Microsoft.Build.Evaluation.Project>;
|
||||
if (task?.IsCompleted != true)
|
||||
continue;
|
||||
|
||||
var targetPath = task.Result.AllEvaluatedProperties.FirstOrDefault(p => p.Name == "TargetPath")?.EvaluatedValue;
|
||||
if (!string.IsNullOrWhiteSpace(targetPath))
|
||||
{
|
||||
if (!loaded.ProjectConfiguration.Dimensions.TryGetValue("TargetFramework", out var targetFw))
|
||||
targetFw = task.Result.AllEvaluatedProperties.FirstOrDefault(p => p.Name == "TargetFramework")
|
||||
?.EvaluatedValue ?? "unknown";
|
||||
alternatives[targetFw] = targetPath;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
string fullPath = TryGetProperty(vsProject?.Properties,"FullPath");
|
||||
|
||||
string outputPath = vsProject?.ConfigurationManager?.ActiveConfiguration?.Properties?.Item("OutputPath")?.Value?.ToString();
|
||||
if (fullPath != null && outputPath != null)
|
||||
{
|
||||
string outputDir = Path.Combine(fullPath, outputPath);
|
||||
/*
|
||||
var dic = new Dictionary<string, string>();
|
||||
foreach(Property prop in vsProject.Properties)
|
||||
{
|
||||
try
|
||||
{
|
||||
dic[prop.Name] = prop.Value?.ToString();
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
||||
}
|
||||
}*/
|
||||
string outputFileName = vsProject.Properties.Item("OutputFileName").Value.ToString();
|
||||
if (!string.IsNullOrWhiteSpace(outputFileName))
|
||||
{
|
||||
var fw = "net40";
|
||||
var tfm = TryGetProperty(vsProject.Properties, "TargetFrameworkMoniker");
|
||||
const string tfmPrefix = ".netframework,version=v";
|
||||
if (tfm != null && tfm.ToLowerInvariant().StartsWith(tfmPrefix))
|
||||
fw = "net" + tfm.Substring(tfmPrefix.Length).Replace(".", "");
|
||||
|
||||
string assemblyPath = Path.Combine(outputDir, outputFileName);
|
||||
alternatives[fw] = assemblyPath;
|
||||
}
|
||||
}
|
||||
var outputType = TryGetProperty(vsProject?.Properties, "OutputType") ??
|
||||
TryGetProperty(vsProject?.ConfigurationManager?.ActiveConfiguration?.Properties,
|
||||
"OutputType");
|
||||
var outputTypeIsExecutable = outputType == "0" || outputType == "1"
|
||||
|| outputType?.ToLowerInvariant() == "exe" ||
|
||||
outputType?.ToLowerInvariant() == "winexe";
|
||||
|
||||
|
||||
var lst = new List<ProjectOutputInfo>();
|
||||
foreach (var alternative in alternatives.OrderByDescending(x => x.Key == "classic"
|
||||
? 10
|
||||
: DesktopFrameworkRegex.IsMatch(x.Key)
|
||||
? 9
|
||||
: x.Key.StartsWith("netcoreapp")
|
||||
? 8
|
||||
: x.Key.StartsWith("netstandard")
|
||||
? 7
|
||||
: 0))
|
||||
{
|
||||
var nfo = new ProjectOutputInfo
|
||||
{
|
||||
TargetAssembly = alternative.Value,
|
||||
OutputTypeIsExecutable = outputTypeIsExecutable,
|
||||
TargetFramework = alternative.Key == "classic" ? "net40" : alternative.Key
|
||||
};
|
||||
nfo.IsNetCore = nfo.TargetFramework.StartsWith("netcoreapp");
|
||||
nfo.IsFullDotNet = DesktopFrameworkRegex.IsMatch(nfo.TargetFramework);
|
||||
lst.Add(nfo);
|
||||
}
|
||||
return lst;
|
||||
}
|
||||
|
||||
static UnconfiguredProject GetUnconfiguredProject(EnvDTE.Project project)
|
||||
{
|
||||
return project.GetObjectSafe<IVsBrowseObjectContext>()?.UnconfiguredProject;
|
||||
}
|
||||
|
||||
public static Project GetContainerProject(string fileName)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(fileName) || !File.Exists(fileName))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var dte2 = (DTE2)Microsoft.VisualStudio.Shell.Package.GetGlobalService(typeof(SDTE));
|
||||
var projItem = dte2?.Solution.FindProjectItem(fileName);
|
||||
return projItem?.ContainingProject;
|
||||
}
|
||||
|
||||
public static TValue GetOrCreate<TKey, TValue>(this Dictionary<TKey, TValue> dic, TKey key,
|
||||
Func<TKey, TValue> getter)
|
||||
{
|
||||
TValue rv;
|
||||
if (!dic.TryGetValue(key, out rv))
|
||||
dic[key] = rv = getter(key);
|
||||
return rv;
|
||||
}
|
||||
|
||||
public static TValue GetOrCreate<TKey, TValue>(this Dictionary<TKey, TValue> dic, TKey key) where TValue :new()
|
||||
{
|
||||
TValue rv;
|
||||
if (!dic.TryGetValue(key, out rv))
|
||||
dic[key] = rv = new TValue();
|
||||
return rv;
|
||||
}
|
||||
|
||||
public static TValue GetValueOrDefault<TKey, TValue>(this Dictionary<TKey, TValue> dic, TKey key)
|
||||
{
|
||||
TValue rv;
|
||||
if (!dic.TryGetValue(key, out rv))
|
||||
return default(TValue);
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,95 +0,0 @@
|
|||
using System.ComponentModel.Composition;
|
||||
using AvaloniaVS.Infrastructure;
|
||||
|
||||
namespace AvaloniaVS.ViewModels
|
||||
{
|
||||
[Export, PartCreationPolicy(CreationPolicy.NonShared)]
|
||||
public class AvaloniaDesignerGeneralPageViewModel : ViewModelBase, IAvaloniaDesignerGeneralPageViewModel
|
||||
{
|
||||
private readonly IAvaloniaDesignerSettings _settings;
|
||||
private bool _isDesignerEnabled;
|
||||
private DocumentView _documentView;
|
||||
private SplitOrientation _splitOrientation;
|
||||
private bool _isReversed;
|
||||
|
||||
[ImportingConstructor]
|
||||
public AvaloniaDesignerGeneralPageViewModel(IAvaloniaDesignerSettings settings)
|
||||
{
|
||||
_settings = settings;
|
||||
LoadSettings();
|
||||
}
|
||||
|
||||
public bool IsDesignerEnabled
|
||||
{
|
||||
get { return _isDesignerEnabled; }
|
||||
set
|
||||
{
|
||||
if (_isDesignerEnabled == value)
|
||||
{
|
||||
return;
|
||||
}
|
||||
_isDesignerEnabled = value;
|
||||
RaisePropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsReversed
|
||||
{
|
||||
get { return _isReversed; }
|
||||
set
|
||||
{
|
||||
if (_isReversed == value)
|
||||
{
|
||||
return;
|
||||
}
|
||||
_isReversed = value;
|
||||
RaisePropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public DocumentView DocumentView
|
||||
{
|
||||
get { return _documentView; }
|
||||
set
|
||||
{
|
||||
if (_documentView == value)
|
||||
{
|
||||
return;
|
||||
}
|
||||
_documentView = value;
|
||||
RaisePropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public SplitOrientation SplitOrientation
|
||||
{
|
||||
get { return _splitOrientation; }
|
||||
set
|
||||
{
|
||||
if (_splitOrientation == value)
|
||||
{
|
||||
return;
|
||||
}
|
||||
_splitOrientation = value;
|
||||
RaisePropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
private void LoadSettings()
|
||||
{
|
||||
IsDesignerEnabled = _settings.IsDesignerEnabled;
|
||||
DocumentView = _settings.DocumentView;
|
||||
SplitOrientation = _settings.SplitOrientation;
|
||||
IsReversed = _settings.IsReversed;
|
||||
}
|
||||
|
||||
public void ApplyChanges()
|
||||
{
|
||||
_settings.IsDesignerEnabled = IsDesignerEnabled;
|
||||
_settings.DocumentView = DocumentView;
|
||||
_settings.SplitOrientation = SplitOrientation;
|
||||
_settings.IsReversed = IsReversed;
|
||||
_settings.Save();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,104 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.ComponentModel;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Input;
|
||||
using AvaloniaVS.Infrastructure;
|
||||
using EnvDTE;
|
||||
using EnvDTE80;
|
||||
using Microsoft.VisualStudio.Shell.Interop;
|
||||
using PropertyChanged;
|
||||
|
||||
namespace AvaloniaVS.ViewModels
|
||||
{
|
||||
public class PreviewerRunTarget
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public string TargetAssembly { get; set; }
|
||||
public override string ToString() => Name;
|
||||
}
|
||||
|
||||
public class AvaloniaDesignerHostViewModel : PropertyChangedBase, IAvaloniaDesignerHostViewModel
|
||||
{
|
||||
private readonly string _fileName;
|
||||
private PreviewerRunTarget _selectedTarget;
|
||||
private string _sourceAssembly;
|
||||
|
||||
public object EditView { get; set; }
|
||||
public object DesignView { get; set; }
|
||||
public bool ShowTargetSelector { get; set; }
|
||||
public Orientation Orientation { get; set; }
|
||||
public bool IsReversed { get; set; }
|
||||
public List<PreviewerRunTarget> AvailableTargets { get; set; }
|
||||
public ICommand RestartDesigner { get; set; }
|
||||
public event Action<string> TargetExeChanged;
|
||||
public event Action<string> SourceAssemblyChanged;
|
||||
|
||||
public PreviewerRunTarget SelectedTarget
|
||||
{
|
||||
get { return _selectedTarget; }
|
||||
set
|
||||
{
|
||||
_selectedTarget = value;
|
||||
OnPropertyChanged();
|
||||
TargetExe = _selectedTarget?.TargetAssembly;
|
||||
TargetExeChanged?.Invoke(TargetExe);
|
||||
}
|
||||
}
|
||||
|
||||
public string TargetExe { get; set; }
|
||||
|
||||
public string SourceAssembly
|
||||
{
|
||||
get { return _sourceAssembly; }
|
||||
set
|
||||
{
|
||||
_sourceAssembly = value;
|
||||
OnPropertyChanged();
|
||||
SourceAssemblyChanged?.Invoke(value);
|
||||
}
|
||||
}
|
||||
|
||||
public AvaloniaDesignerHostViewModel(string fileName)
|
||||
{
|
||||
_fileName = fileName;
|
||||
PopulateTargetList();
|
||||
ProjectInfoService.AddChangedHandler(OnProjectInfoChanged);
|
||||
}
|
||||
|
||||
private void OnProjectInfoChanged(object sender, EventArgs e)
|
||||
{
|
||||
PopulateTargetList();
|
||||
SourceAssembly = Utils.GetContainerProject(_fileName).GetAssemblyPath();
|
||||
}
|
||||
|
||||
|
||||
void PopulateTargetList()
|
||||
{
|
||||
var containing = Utils.GetContainerProject(_fileName);
|
||||
AvailableTargets = new List<PreviewerRunTarget>(
|
||||
ProjectInfoService.Projects.Where(p => p.Project == containing || p.References.Contains(containing))
|
||||
.OrderBy(p => p.Project == containing)
|
||||
.SelectMany(p => p.RunnableOutputs.Select(o => new PreviewerRunTarget
|
||||
{
|
||||
Name = $"{p.Name} [{o.Key}]",
|
||||
TargetAssembly = o.Value
|
||||
})));
|
||||
|
||||
SelectedTarget = (SelectedTarget == null
|
||||
? null
|
||||
: AvailableTargets.FirstOrDefault(a => a.TargetAssembly == SelectedTarget.TargetAssembly)) ??
|
||||
AvailableTargets.FirstOrDefault();
|
||||
ShowTargetSelector = AvailableTargets.Count > 1;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
using AvaloniaVS.Infrastructure;
|
||||
|
||||
namespace AvaloniaVS.ViewModels
|
||||
{
|
||||
public interface IAvaloniaDesignerGeneralPageViewModel
|
||||
{
|
||||
bool IsDesignerEnabled { get; set; }
|
||||
bool IsReversed { get; set; }
|
||||
DocumentView DocumentView { get; set; }
|
||||
SplitOrientation SplitOrientation { get; set; }
|
||||
}
|
||||
}
|
|
@ -1,38 +0,0 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Input;
|
||||
|
||||
namespace AvaloniaVS.ViewModels
|
||||
{
|
||||
public interface IAvaloniaDesignerHostViewModel
|
||||
{
|
||||
List<PreviewerRunTarget> AvailableTargets { get; set; }
|
||||
object DesignView { get; set; }
|
||||
object EditView { get; set; }
|
||||
bool IsReversed { get; set; }
|
||||
bool ShowTargetSelector { get; }
|
||||
Orientation Orientation { get; set; }
|
||||
PreviewerRunTarget SelectedTarget { get; set; }
|
||||
ICommand RestartDesigner { get; set; }
|
||||
}
|
||||
|
||||
public class AvaloniaDesignerHostViewModelMock : IAvaloniaDesignerHostViewModel
|
||||
{
|
||||
public List<PreviewerRunTarget> AvailableTargets { get; set; }
|
||||
public object DesignView { get; set; }
|
||||
public object EditView { get; set; }
|
||||
public bool IsReversed { get; set; }
|
||||
public bool ShowTargetSelector => true;
|
||||
public Orientation Orientation { get; set; }
|
||||
public ICommand RestartDesigner { get; set; }
|
||||
|
||||
public PreviewerRunTarget SelectedTarget { get; set; } =
|
||||
new PreviewerRunTarget {Name = "DUMMY", TargetAssembly = "DUMMY"};
|
||||
|
||||
public AvaloniaDesignerHostViewModelMock()
|
||||
{
|
||||
AvailableTargets = new List<PreviewerRunTarget> {SelectedTarget};
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,51 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using AvaloniaVS.Infrastructure;
|
||||
using EnvDTE;
|
||||
using VSLangProj;
|
||||
|
||||
namespace AvaloniaVS.ViewModels
|
||||
{
|
||||
public class ProjectDescriptor : PropertyChangedBase
|
||||
{
|
||||
public Project Project { get; }
|
||||
public string Name { get; }
|
||||
public string TargetAssembly;
|
||||
public Dictionary<string, string> RunnableOutputs = new Dictionary<string, string>();
|
||||
|
||||
public List<Project> References { get; set; } = new List<Project>();
|
||||
|
||||
public ProjectDescriptor(Project project)
|
||||
{
|
||||
Project = project;
|
||||
Name = project.Name;
|
||||
var nfo = Project.GetProjectOutputInfo();
|
||||
if(nfo!=null)
|
||||
foreach (var o in nfo)
|
||||
{
|
||||
if (TargetAssembly == null)
|
||||
TargetAssembly = o.TargetAssembly;
|
||||
|
||||
if (o.IsFullDotNet || o.IsNetCore)
|
||||
{
|
||||
if (o.TargetAssembly.ToLowerInvariant().EndsWith(".exe") ||
|
||||
o.OutputTypeIsExecutable)
|
||||
RunnableOutputs[o.TargetFramework] = o.TargetAssembly;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public ProjectDescriptor(string dummyName)
|
||||
{
|
||||
Name = dummyName;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return Name;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,15 +0,0 @@
|
|||
using System.ComponentModel;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace AvaloniaVS.ViewModels
|
||||
{
|
||||
public abstract class ViewModelBase : INotifyPropertyChanged
|
||||
{
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
|
||||
protected virtual void RaisePropertyChanged([CallerMemberName] string propertyName = null)
|
||||
{
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,91 +0,0 @@
|
|||
<UserControl x:Class="AvaloniaVS.Views.AvaloniaDesignerGeneralPageView"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:converters="clr-namespace:AvaloniaVS.Converters"
|
||||
xmlns:options="clr-namespace:AvaloniaVS.Options"
|
||||
xmlns:sys="clr-namespace:System;assembly=mscorlib"
|
||||
xmlns:helpers="clr-namespace:AvaloniaVS.Helpers"
|
||||
xmlns:infrastructure="clr-namespace:AvaloniaVS.Infrastructure"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="300" d:DesignWidth="300">
|
||||
<d:UserControl.DataContext>
|
||||
<helpers:AvaloniaDesignerGeneralPageViewModelDesign />
|
||||
</d:UserControl.DataContext>
|
||||
|
||||
<UserControl.Resources>
|
||||
<ObjectDataProvider x:Key="DocumentViewSource" ObjectType="{x:Type sys:Enum}" MethodName="GetValues">
|
||||
<ObjectDataProvider.MethodParameters>
|
||||
<x:Type TypeName="infrastructure:DocumentView" />
|
||||
</ObjectDataProvider.MethodParameters>
|
||||
</ObjectDataProvider>
|
||||
|
||||
<ObjectDataProvider x:Key="SplitOrientationSource" ObjectType="{x:Type sys:Enum}" MethodName="GetValues">
|
||||
<ObjectDataProvider.MethodParameters>
|
||||
<x:Type TypeName="infrastructure:SplitOrientation" />
|
||||
</ObjectDataProvider.MethodParameters>
|
||||
</ObjectDataProvider>
|
||||
</UserControl.Resources>
|
||||
|
||||
<DockPanel LastChildFill="False">
|
||||
<CheckBox Content="Enable Avalonia Designer (Requires re-opening current XAML documents)"
|
||||
IsChecked="{Binding Path=IsDesignerEnabled, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
|
||||
Margin="0,4,0,0"
|
||||
DockPanel.Dock="Top"/>
|
||||
|
||||
<Grid Margin="15,10,0,0" VerticalAlignment="Top" MinWidth="300" HorizontalAlignment="Left" DockPanel.Dock="Top">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition />
|
||||
<RowDefinition Height="5" />
|
||||
<RowDefinition />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="20" />
|
||||
<ColumnDefinition Width="*" MinWidth="184" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<!-- default document view -->
|
||||
<Label Content="Default document view:"
|
||||
IsEnabled="{Binding Path=IsDesignerEnabled}" />
|
||||
<ComboBox Grid.Column="2"
|
||||
Grid.Row="0"
|
||||
IsEnabled="{Binding Path=IsDesignerEnabled, Mode=OneWay}"
|
||||
ItemsSource="{Binding Source={StaticResource DocumentViewSource}}"
|
||||
SelectedValue="{Binding Path=DocumentView, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
|
||||
VerticalAlignment="Center">
|
||||
<ComboBox.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<TextBlock Text="{Binding Converter={converters:EnumDescriptionConverter EnumType=infrastructure:DocumentView}}" />
|
||||
</DataTemplate>
|
||||
</ComboBox.ItemTemplate>
|
||||
</ComboBox>
|
||||
|
||||
<!-- split orientation -->
|
||||
<Label Grid.Row="2"
|
||||
Grid.Column="0"
|
||||
IsEnabled="{Binding Path=IsDesignerEnabled, Mode=OneWay}"
|
||||
Content="Split Orientation:" />
|
||||
|
||||
<ComboBox Grid.Column="2"
|
||||
Grid.Row="2"
|
||||
IsEnabled="{Binding Path=IsDesignerEnabled, Mode=OneWay}"
|
||||
ItemsSource="{Binding Source={StaticResource SplitOrientationSource}}"
|
||||
SelectedValue="{Binding Path=SplitOrientation, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
|
||||
VerticalAlignment="Center">
|
||||
<ComboBox.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<TextBlock Text="{Binding Converter={converters:EnumDescriptionConverter EnumType=infrastructure:SplitOrientation}}" />
|
||||
</DataTemplate>
|
||||
</ComboBox.ItemTemplate>
|
||||
</ComboBox>
|
||||
</Grid>
|
||||
<CheckBox IsEnabled="{Binding Path=IsDesignerEnabled, Mode=OneWay}"
|
||||
IsChecked="{Binding Path=IsReversed, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
|
||||
DockPanel.Dock="Top"
|
||||
Margin="0,10,0,0"
|
||||
Content="Reverse designer and editor initial locations" />
|
||||
|
||||
</DockPanel>
|
||||
</UserControl>
|
|
@ -1,21 +0,0 @@
|
|||
using System.ComponentModel.Composition;
|
||||
using AvaloniaVS.ViewModels;
|
||||
|
||||
namespace AvaloniaVS.Views
|
||||
{
|
||||
[Export]
|
||||
public partial class AvaloniaDesignerGeneralPageView
|
||||
{
|
||||
public AvaloniaDesignerGeneralPageView()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
[Import(typeof(AvaloniaDesignerGeneralPageViewModel))]
|
||||
public new object DataContext
|
||||
{
|
||||
get { return base.DataContext; }
|
||||
set { base.DataContext = value; }
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,97 +0,0 @@
|
|||
<UserControl x:Class="AvaloniaVS.Views.AvaloniaDesignerHostView"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:lc="clr-namespace:AvaloniaVS.Controls;assembly=AvaloniaVS.Controls"
|
||||
xmlns:viewModels="clr-namespace:AvaloniaVS.ViewModels"
|
||||
xmlns:infrastructure="clr-namespace:AvaloniaVS.Infrastructure"
|
||||
Background="White"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="300"
|
||||
d:DesignWidth="300"
|
||||
d:DataContext="{d:DesignInstance viewModels:AvaloniaDesignerHostViewModelMock}">
|
||||
|
||||
<UserControl.Resources>
|
||||
<Geometry x:Key="MarkupIconShape">
|
||||
M 0,0 L0,9 L9,9 L9,0 Z
|
||||
M 1,1 L1,8 L8,8 L8,1 Z
|
||||
M 3,3 L4,3 L4,4 L3,4 Z
|
||||
M 3,4 L3,5 L2,5 L2,4 Z
|
||||
M 3,5 L4,5 L4,6 L3,6 Z
|
||||
M 5,3 L6,3 L6,4 L5,4 Z
|
||||
M 7,4 L7,5 L6,5 L6,4 Z
|
||||
M 5,5 L6,5 L6,6 L5,6 Z
|
||||
</Geometry>
|
||||
|
||||
<Geometry x:Key="DesignIconShape">
|
||||
M 0,0 L9,0 L9,5 L8,5 L8,1 L1,1 L1,8 L5,8 L5,9 L0,9 Z
|
||||
M 7,6 L9,6 L9,7 L10,7 L10,9 L9,9 L9,10 L7,10 L7,9 L6,9 L6,7 L7,7 Z
|
||||
</Geometry>
|
||||
|
||||
<BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />
|
||||
</UserControl.Resources>
|
||||
<Border x:Name="Root">
|
||||
<lc:SplitterContainer x:Name="Container" Orientation="{Binding Orientation, Mode=TwoWay}" IsReversed="{Binding IsReversed, Mode=TwoWay}">
|
||||
<lc:SplitterContainer.DesignerHeader>
|
||||
<DockPanel>
|
||||
<Path Fill="{Binding RelativeSource={x:Static RelativeSource.Self}, Path=(TextElement.Foreground), Mode=OneWay}"
|
||||
Width="10"
|
||||
DockPanel.Dock="Left"
|
||||
Height="10"
|
||||
Data="{StaticResource DesignIconShape}"
|
||||
SnapsToDevicePixels="True" />
|
||||
<TextBlock Text="Design"
|
||||
Margin="2,0,0,0"
|
||||
Visibility="{Binding ElementName=Container, Path=IsHorizontal, Converter={StaticResource BooleanToVisibilityConverter}}"/>
|
||||
</DockPanel>
|
||||
</lc:SplitterContainer.DesignerHeader>
|
||||
<lc:SplitterContainer.EditorHeader>
|
||||
<DockPanel>
|
||||
<Path Fill="{Binding RelativeSource={x:Static RelativeSource.Self}, Path=(TextElement.Foreground), Mode=OneWay}"
|
||||
Width="10"
|
||||
Height="10"
|
||||
DockPanel.Dock="Left"
|
||||
Data="{StaticResource MarkupIconShape}"
|
||||
SnapsToDevicePixels="True" />
|
||||
<TextBlock Text="XAML"
|
||||
Margin="2,0,0,0"
|
||||
Visibility="{Binding ElementName=Container, Path=IsHorizontal, Converter={StaticResource BooleanToVisibilityConverter}}"/>
|
||||
</DockPanel>
|
||||
</lc:SplitterContainer.EditorHeader>
|
||||
<lc:SplitterContainer.Designer>
|
||||
<DockPanel DataContext="{Binding DataContext, ElementName=Root}">
|
||||
<DockPanel Dock="Top" Visibility="{Binding ShowTargetSelector, Converter={StaticResource BooleanToVisibilityConverter}}">
|
||||
<TextBlock VerticalAlignment="Center">Target project</TextBlock>
|
||||
<ComboBox Margin="5,0,0,0" ItemsSource="{Binding AvailableTargets}" SelectedItem="{Binding SelectedTarget}"/>
|
||||
</DockPanel>
|
||||
<Rectangle DockPanel.Dock="Top" Stroke="DimGray" Height="0.6"></Rectangle>
|
||||
<lc:FocusableContentPresenter Content="{Binding DesignView}" />
|
||||
</DockPanel>
|
||||
</lc:SplitterContainer.Designer>
|
||||
<lc:SplitterContainer.Editor>
|
||||
<lc:FocusableContentPresenter TextOptions.TextFormattingMode="{Binding (TextOptions.TextFormattingMode), RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type FrameworkElement}}}"
|
||||
DataContext="{Binding DataContext, ElementName=Root}"
|
||||
Content="{Binding EditView}" />
|
||||
</lc:SplitterContainer.Editor>
|
||||
<lc:SplitterContainer.ExtraPanel>
|
||||
<StackPanel Orientation="Horizontal" DataContext="{Binding ElementName=Root, Path=DataContext}">
|
||||
<TextBlock FontSize="10" VerticalAlignment="Center" Margin="0,0,10,0">
|
||||
<Hyperlink Focusable="False" NavigateUri="https://github.com/AvaloniaUI/Avalonia/wiki/Visual-Studio-Extension-Previewer"
|
||||
RequestNavigate="Hyperlink_OnRequestNavigate">Help</Hyperlink>
|
||||
</TextBlock>
|
||||
<Button x:Name="FixMe" Background="Transparent" BorderThickness="0" FontSize="10" Padding="0"
|
||||
infrastructure:TriggerMenuOnLeftClickBehavior.Enabled="True" Focusable="False">
|
||||
Fix Me ▼
|
||||
<Button.ContextMenu>
|
||||
<ContextMenu>
|
||||
<MenuItem Command="{Binding RestartDesigner}" Header="Restart"/>
|
||||
<MenuItem Command="{x:Static infrastructure:ProjectInfoService.ReloadAll}" Header="Reload solution info"/>
|
||||
</ContextMenu>
|
||||
</Button.ContextMenu>
|
||||
</Button>
|
||||
</StackPanel>
|
||||
</lc:SplitterContainer.ExtraPanel>
|
||||
</lc:SplitterContainer>
|
||||
</Border>
|
||||
</UserControl>
|
|
@ -1,45 +0,0 @@
|
|||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Windows.Navigation;
|
||||
using AvaloniaVS.Controls;
|
||||
using AvaloniaVS.Infrastructure;
|
||||
|
||||
namespace AvaloniaVS.Views
|
||||
{
|
||||
public partial class AvaloniaDesignerHostView
|
||||
{
|
||||
public AvaloniaDesignerHostView()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
public void Init(IAvaloniaDesignerSettings designerSettings)
|
||||
{
|
||||
if (designerSettings.DocumentView != DocumentView.SplitView)
|
||||
{
|
||||
Container.Collapse(designerSettings.DocumentView == DocumentView.DesignView
|
||||
? SplitterViews.Design
|
||||
: SplitterViews.Editor);
|
||||
}
|
||||
|
||||
Container.ActiveViewChanged += (s, e) => IsDesingerVisibleChanged?.Invoke();
|
||||
}
|
||||
|
||||
internal Action IsDesingerVisibleChanged;
|
||||
|
||||
internal bool IsDesingerVisible
|
||||
=> Container?.IsDesignerVisible ?? false;
|
||||
|
||||
private void Hyperlink_OnRequestNavigate(object sender, RequestNavigateEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
Process.Start(e.Uri.ToString());
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,14 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<runtime>
|
||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-9.0.0.0" newVersion="9.0.0.0" />
|
||||
</dependentAssembly>
|
||||
</assemblyBinding>
|
||||
</runtime>
|
||||
<startup>
|
||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
|
||||
</startup>
|
||||
</configuration>
|
Двоичные данные
src/AvaloniaVS/lib/Avalonia.Designer.HostApp.dll
Двоичные данные
src/AvaloniaVS/lib/Avalonia.Designer.HostApp.dll
Двоичный файл не отображается.
Двоичные данные
src/AvaloniaVS/lib/Avalonia.Designer.HostApp.exe
Двоичные данные
src/AvaloniaVS/lib/Avalonia.Designer.HostApp.exe
Двоичный файл не отображается.
Двоичные данные
src/AvaloniaVS/lib/Avalonia.Designer.exe
Двоичные данные
src/AvaloniaVS/lib/Avalonia.Designer.exe
Двоичный файл не отображается.
|
@ -1,6 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<startup>
|
||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5"/>
|
||||
</startup>
|
||||
</configuration>
|
Двоичные данные
src/AvaloniaVS/lib/dnlib.dll
Двоичные данные
src/AvaloniaVS/lib/dnlib.dll
Двоичный файл не отображается.
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -1,27 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<PackageManifest Version="2.0.0" xmlns="http://schemas.microsoft.com/developer/vsx-schema/2011" xmlns:d="http://schemas.microsoft.com/developer/vsx-schema-design/2011">
|
||||
<Metadata>
|
||||
<Identity Id="AvaloniaForVisualStudio" Version="0.7.0.1" Language="en-US" Publisher="avalonia"/>
|
||||
<DisplayName>Avalonia for Visual Studio</DisplayName>
|
||||
<Description xml:space="preserve">Avalonia Extensions for Visual Studio</Description>
|
||||
</Metadata>
|
||||
<Installation>
|
||||
<InstallationTarget Id="Microsoft.VisualStudio.Community" Version="[15.0]" />
|
||||
</Installation>
|
||||
<Dependencies>
|
||||
<Dependency Id="Microsoft.Framework.NDP" DisplayName="Microsoft .NET Framework" d:Source="Manual" Version="[4.6,)" />
|
||||
<Dependency Id="Microsoft.VisualStudio.MPF.15.0" DisplayName="Visual Studio MPF 15.0" d:Source="Installed" Version="[15.0,16.0)" />
|
||||
</Dependencies>
|
||||
<Assets>
|
||||
<Asset Type="Microsoft.VisualStudio.MefComponent" d:Source="Project" d:ProjectName="%CurrentProject%" Path="|%CurrentProject%|" />
|
||||
<Asset Type="Microsoft.VisualStudio.VsPackage" d:Source="Project" d:ProjectName="%CurrentProject%" Path="|%CurrentProject%;PkgdefProjectOutputGroup|" />
|
||||
<Asset Type="Microsoft.VisualStudio.ProjectTemplate" d:Source="Project" d:TargetPath="|AvaloniaApplicationTemplate;TemplateProjectOutputGroup|" Path="ProjectTemplates" d:VsixSubPath="ProjectTemplates" d:ProjectName="AvaloniaApplicationTemplate" />
|
||||
<Asset Type="Microsoft.VisualStudio.ProjectTemplate" d:Source="Project" d:TargetPath="|AvaloniaMvvmApplicationTemplate;TemplateProjectOutputGroup|" Path="ProjectTemplates" d:VsixSubPath="ProjectTemplates" d:ProjectName="AvaloniaMvvmApplicationTemplate" />
|
||||
<Asset Type="Microsoft.VisualStudio.ItemTemplate" d:Source="Project" d:ProjectName="AvaloniaWindowTemplate" d:TargetPath="|AvaloniaWindowTemplate;TemplateProjectOutputGroup|" Path="ItemTemplates" d:VsixSubPath="ItemTemplates" />
|
||||
</Assets>
|
||||
<Prerequisites>
|
||||
<Prerequisite Id="Microsoft.NetCore.ComponentGroup.Web" Version="[15.0.26208.0,16.0)" DisplayName=".NET Core 1.0 - 1.1 development tools" />
|
||||
<Prerequisite Id="Microsoft.VisualStudio.Component.ManagedDesktop.Prerequisites" Version="[15.0.26208.0,16.0)" DisplayName=".NET desktop development tools" />
|
||||
<Prerequisite Id="Microsoft.VisualStudio.Component.Roslyn.LanguageServices" Version="[15.0.26208.0,16.0)" DisplayName="C# and Visual Basic" />
|
||||
</Prerequisites>
|
||||
</PackageManifest>
|
|
@ -1,7 +0,0 @@
|
|||
<Application xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
|
||||
<Application.Styles>
|
||||
<StyleInclude Source="resm:Avalonia.Themes.Default.DefaultTheme.xaml?assembly=Avalonia.Themes.Default"/>
|
||||
<StyleInclude Source="resm:Avalonia.Themes.Default.Accents.BaseLight.xaml?assembly=Avalonia.Themes.Default"/>
|
||||
</Application.Styles>
|
||||
</Application>
|
|
@ -1,13 +0,0 @@
|
|||
using Avalonia;
|
||||
using Avalonia.Markup.Xaml;
|
||||
|
||||
namespace $safeprojectname$
|
||||
{
|
||||
public class App : Application
|
||||
{
|
||||
public override void Initialize()
|
||||
{
|
||||
AvaloniaXamlLoader.Load(this);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,126 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<MinimumVisualStudioVersion>15.0</MinimumVisualStudioVersion>
|
||||
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
|
||||
<FileUpgradeFlags>
|
||||
</FileUpgradeFlags>
|
||||
<OldToolsVersion>14.0</OldToolsVersion>
|
||||
<UpgradeBackupLocation>
|
||||
</UpgradeBackupLocation>
|
||||
<PublishUrl>publish\</PublishUrl>
|
||||
<Install>true</Install>
|
||||
<InstallFrom>Disk</InstallFrom>
|
||||
<UpdateEnabled>false</UpdateEnabled>
|
||||
<UpdateMode>Foreground</UpdateMode>
|
||||
<UpdateInterval>7</UpdateInterval>
|
||||
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
|
||||
<UpdatePeriodically>false</UpdatePeriodically>
|
||||
<UpdateRequired>false</UpdateRequired>
|
||||
<MapFileExtensions>true</MapFileExtensions>
|
||||
<ApplicationRevision>0</ApplicationRevision>
|
||||
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
|
||||
<IsWebBootstrapper>false</IsWebBootstrapper>
|
||||
<UseApplicationTrust>false</UseApplicationTrust>
|
||||
<BootstrapperEnabled>true</BootstrapperEnabled>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectTypeGuids>{82b43b9b-a64c-4715-b499-d71e9ca2bd60};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||
<ProjectGuid>{75104AA0-3B1B-47D4-9C4D-501A8185ACFC}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>AvaloniaApplicationTemplate</RootNamespace>
|
||||
<AssemblyName>AvaloniaApplicationTemplate</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.6</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<GeneratePkgDefFile>false</GeneratePkgDefFile>
|
||||
<IncludeAssemblyInVSIXContainer>false</IncludeAssemblyInVSIXContainer>
|
||||
<IncludeDebugSymbolsInVSIXContainer>false</IncludeDebugSymbolsInVSIXContainer>
|
||||
<IncludeDebugSymbolsInLocalVSIXDeployment>false</IncludeDebugSymbolsInLocalVSIXDeployment>
|
||||
<CreateVsixContainer>false</CreateVsixContainer>
|
||||
<DeployExtension>false</DeployExtension>
|
||||
<DeployVSTemplates>false</DeployVSTemplates>
|
||||
<CopyVsixManifestToOutput>false</CopyVsixManifestToOutput>
|
||||
<CopyBuildOutputToOutputDirectory>false</CopyBuildOutputToOutputDirectory>
|
||||
<CopyOutputSymbolsToOutputDirectory>false</CopyOutputSymbolsToOutputDirectory>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Microsoft.VisualStudio.CoreUtility">
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="App.xaml.cs" />
|
||||
<None Include="App.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</None>
|
||||
<None Include="MainWindow.xaml.cs" />
|
||||
<None Include="Program.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="MainWindow.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</None>
|
||||
<None Include="nuget.config" />
|
||||
<None Include="ProjectTemplate.csproj">
|
||||
<SubType>Designer</SubType>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<VSTemplate Include="AvaloniaApplicationTemplate.vstemplate">
|
||||
<SubType>Designer</SubType>
|
||||
<OutputSubPath>Avalonia</OutputSubPath>
|
||||
</VSTemplate>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<BootstrapperPackage Include=".NETFramework,Version=v4.6">
|
||||
<Visible>False</Visible>
|
||||
<ProductName>Microsoft .NET Framework 4.6 %28x86 and x64%29</ProductName>
|
||||
<Install>true</Install>
|
||||
</BootstrapperPackage>
|
||||
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
|
||||
<Visible>False</Visible>
|
||||
<ProductName>.NET Framework 3.5 SP1</ProductName>
|
||||
<Install>false</Install>
|
||||
</BootstrapperPackage>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="AvaloniaApplicationTemplate.ico" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<Import Project="$(VSToolsPath)\VSSDK\Microsoft.VsSDK.targets" Condition="'$(VSToolsPath)' != ''" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
Двоичный файл не отображается.
До Ширина: | Высота: | Размер: 172 KiB |
|
@ -1,27 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<VSTemplate Version="3.0.0" Type="Project" xmlns="http://schemas.microsoft.com/developer/vstemplate/2005" xmlns:sdk="http://schemas.microsoft.com/developer/vstemplate-sdkextension/2010">
|
||||
<TemplateData>
|
||||
<Name>Avalonia Application</Name>
|
||||
<Description>Avalonia client application</Description>
|
||||
<Icon>AvaloniaApplicationTemplate.ico</Icon>
|
||||
<ProjectType>CSharp</ProjectType>
|
||||
<RequiredFrameworkVersion>4.5</RequiredFrameworkVersion>
|
||||
<SortOrder>1000</SortOrder>
|
||||
<TemplateID>191cf8ae-cce5-4162-8932-d4f34eec1938</TemplateID>
|
||||
<CreateNewFolder>true</CreateNewFolder>
|
||||
<DefaultName>AvaloniaApplication</DefaultName>
|
||||
<ProvideDefaultName>true</ProvideDefaultName>
|
||||
<CreateInPlace>true</CreateInPlace>
|
||||
<PromptForSaveOnCreation>true</PromptForSaveOnCreation>
|
||||
</TemplateData>
|
||||
<TemplateContent>
|
||||
<Project File="ProjectTemplate.csproj" ReplaceParameters="true">
|
||||
<ProjectItem ReplaceParameters="true" TargetFileName="App.xaml">App.xaml</ProjectItem>
|
||||
<ProjectItem ReplaceParameters="true" TargetFileName="App.xaml.cs" >App.xaml.cs</ProjectItem>
|
||||
<ProjectItem ReplaceParameters="true" OpenInEditor="true" TargetFileName="MainWindow.xaml">MainWindow.xaml</ProjectItem>
|
||||
<ProjectItem ReplaceParameters="true" TargetFileName="MainWindow.xaml.cs" >MainWindow.xaml.cs</ProjectItem>
|
||||
<ProjectItem ReplaceParameters="false" TargetFileName="nuget.config" >nuget.config</ProjectItem>
|
||||
<ProjectItem ReplaceParameters="true" TargetFileName="Program.cs" >Program.cs</ProjectItem>
|
||||
</Project>
|
||||
</TemplateContent>
|
||||
</VSTemplate>
|
|
@ -1,5 +0,0 @@
|
|||
<Window xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
Title="$safeprojectname$">
|
||||
Hello World!
|
||||
</Window>
|
|
@ -1,22 +0,0 @@
|
|||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Markup.Xaml;
|
||||
|
||||
namespace $safeprojectname$
|
||||
{
|
||||
public class MainWindow : Window
|
||||
{
|
||||
public MainWindow()
|
||||
{
|
||||
InitializeComponent();
|
||||
#if DEBUG
|
||||
this.AttachDevTools();
|
||||
#endif
|
||||
}
|
||||
|
||||
private void InitializeComponent()
|
||||
{
|
||||
AvaloniaXamlLoader.Load(this);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
using System;
|
||||
using Avalonia;
|
||||
using Avalonia.Logging.Serilog;
|
||||
|
||||
namespace $safeprojectname$
|
||||
{
|
||||
class Program
|
||||
{
|
||||
static void Main(string[] args)
|
||||
{
|
||||
BuildAvaloniaApp().Start<MainWindow>();
|
||||
}
|
||||
|
||||
public static AppBuilder BuildAvaloniaApp()
|
||||
=> AppBuilder.Configure<App>()
|
||||
.UsePlatformDetect()
|
||||
.LogToDebug();
|
||||
}
|
||||
}
|
|
@ -1,18 +0,0 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFrameworks>netcoreapp2.0;net461</TargetFrameworks>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Compile Update="**\*.xaml.cs">
|
||||
<DependentUpon>%(Filename)</DependentUpon>
|
||||
</Compile>
|
||||
<EmbeddedResource Include="**\*.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
</EmbeddedResource>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Avalonia" Version="0.7.0" />
|
||||
<PackageReference Include="Avalonia.Desktop" Version="0.7.0" />
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -1,36 +0,0 @@
|
|||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("AvaloniaApplicationTemplate")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("Nikita Tsukanov")]
|
||||
[assembly: AssemblyProduct("AvaloniaApplicationTemplate")]
|
||||
[assembly: AssemblyCopyright("Copyright © Nikita Tsukanov 2015")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("75104aa0-3b1b-47d4-9c4d-501a8185acfc")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
|
@ -1,6 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<packageSources>
|
||||
<add key="AvaloniaCI" value="https://www.myget.org/F/avalonia-ci/api/v2" />
|
||||
</packageSources>
|
||||
</configuration>
|
|
@ -1,12 +0,0 @@
|
|||
<Application xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="clr-namespace:$safeprojectname$">
|
||||
<Application.DataTemplates>
|
||||
<local:ViewLocator/>
|
||||
</Application.DataTemplates>
|
||||
|
||||
<Application.Styles>
|
||||
<StyleInclude Source="resm:Avalonia.Themes.Default.DefaultTheme.xaml?assembly=Avalonia.Themes.Default"/>
|
||||
<StyleInclude Source="resm:Avalonia.Themes.Default.Accents.BaseLight.xaml?assembly=Avalonia.Themes.Default"/>
|
||||
</Application.Styles>
|
||||
</Application>
|
|
@ -1,13 +0,0 @@
|
|||
using Avalonia;
|
||||
using Avalonia.Markup.Xaml;
|
||||
|
||||
namespace $safeprojectname$
|
||||
{
|
||||
public class App : Application
|
||||
{
|
||||
public override void Initialize()
|
||||
{
|
||||
AvaloniaXamlLoader.Load(this);
|
||||
}
|
||||
}
|
||||
}
|
Двоичный файл не отображается.
До Ширина: | Высота: | Размер: 172 KiB |
|
@ -1,133 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<MinimumVisualStudioVersion>15.0</MinimumVisualStudioVersion>
|
||||
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
|
||||
<FileUpgradeFlags>
|
||||
</FileUpgradeFlags>
|
||||
<OldToolsVersion>14.0</OldToolsVersion>
|
||||
<UpgradeBackupLocation>
|
||||
</UpgradeBackupLocation>
|
||||
<PublishUrl>publish\</PublishUrl>
|
||||
<Install>true</Install>
|
||||
<InstallFrom>Disk</InstallFrom>
|
||||
<UpdateEnabled>false</UpdateEnabled>
|
||||
<UpdateMode>Foreground</UpdateMode>
|
||||
<UpdateInterval>7</UpdateInterval>
|
||||
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
|
||||
<UpdatePeriodically>false</UpdatePeriodically>
|
||||
<UpdateRequired>false</UpdateRequired>
|
||||
<MapFileExtensions>true</MapFileExtensions>
|
||||
<ApplicationRevision>0</ApplicationRevision>
|
||||
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
|
||||
<IsWebBootstrapper>false</IsWebBootstrapper>
|
||||
<UseApplicationTrust>false</UseApplicationTrust>
|
||||
<BootstrapperEnabled>true</BootstrapperEnabled>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectTypeGuids>{82b43b9b-a64c-4715-b499-d71e9ca2bd60};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||
<ProjectGuid>{D458691F-3B40-4E54-8BC2-782D017CFD2B}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>AvaloniaMvvmApplicationTemplate</RootNamespace>
|
||||
<AssemblyName>AvaloniaMvvmApplicationTemplate</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.6</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<GeneratePkgDefFile>false</GeneratePkgDefFile>
|
||||
<IncludeAssemblyInVSIXContainer>false</IncludeAssemblyInVSIXContainer>
|
||||
<IncludeDebugSymbolsInVSIXContainer>false</IncludeDebugSymbolsInVSIXContainer>
|
||||
<IncludeDebugSymbolsInLocalVSIXDeployment>false</IncludeDebugSymbolsInLocalVSIXDeployment>
|
||||
<CreateVsixContainer>false</CreateVsixContainer>
|
||||
<DeployExtension>false</DeployExtension>
|
||||
<DeployVSTemplates>false</DeployVSTemplates>
|
||||
<CopyVsixManifestToOutput>false</CopyVsixManifestToOutput>
|
||||
<CopyBuildOutputToOutputDirectory>false</CopyBuildOutputToOutputDirectory>
|
||||
<CopyOutputSymbolsToOutputDirectory>false</CopyOutputSymbolsToOutputDirectory>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Microsoft.VisualStudio.CoreUtility">
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="ViewLocator.cs" />
|
||||
<None Include="ViewModels\MainWindowViewModel.cs" />
|
||||
<None Include="ViewModels\ViewModelBase.cs" />
|
||||
<None Include="App.xaml.cs" />
|
||||
<None Include="App.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</None>
|
||||
<None Include="Views\MainWindow.xaml.cs" />
|
||||
<None Include="Program.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="Views\MainWindow.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</None>
|
||||
<None Include="nuget.config" />
|
||||
<None Include="ProjectTemplate.csproj">
|
||||
<SubType>Designer</SubType>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<BootstrapperPackage Include=".NETFramework,Version=v4.6">
|
||||
<Visible>False</Visible>
|
||||
<ProductName>Microsoft .NET Framework 4.6 %28x86 and x64%29</ProductName>
|
||||
<Install>true</Install>
|
||||
</BootstrapperPackage>
|
||||
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
|
||||
<Visible>False</Visible>
|
||||
<ProductName>.NET Framework 3.5 SP1</ProductName>
|
||||
<Install>false</Install>
|
||||
</BootstrapperPackage>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="Assets\avalonia-logo.ico" />
|
||||
<Content Include="AvaloniaMvvmApplicationTemplate.ico" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Folder Include="Models\" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<VSTemplate Include="AvaloniaMvvmApplicationTemplate.vstemplate">
|
||||
<SubType>Designer</SubType>
|
||||
<OutputSubPath>Avalonia</OutputSubPath>
|
||||
</VSTemplate>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<Import Project="$(VSToolsPath)\VSSDK\Microsoft.VsSDK.targets" Condition="'$(VSToolsPath)' != ''" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
Двоичный файл не отображается.
До Ширина: | Высота: | Размер: 172 KiB |
|
@ -1,32 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<VSTemplate Version="3.0.0" Type="Project" xmlns="http://schemas.microsoft.com/developer/vstemplate/2005" xmlns:sdk="http://schemas.microsoft.com/developer/vstemplate-sdkextension/2010">
|
||||
<TemplateData>
|
||||
<Name>Avalonia MVVM Application</Name>
|
||||
<Description>Avalonia MVVM application</Description>
|
||||
<Icon>AvaloniaMvvmApplicationTemplate.ico</Icon>
|
||||
<ProjectType>CSharp</ProjectType>
|
||||
<RequiredFrameworkVersion>4.5</RequiredFrameworkVersion>
|
||||
<SortOrder>1000</SortOrder>
|
||||
<TemplateID>191cf8ae-cce5-4162-8932-d4f34eec1938</TemplateID>
|
||||
<CreateNewFolder>true</CreateNewFolder>
|
||||
<DefaultName>AvaloniaApplication</DefaultName>
|
||||
<ProvideDefaultName>true</ProvideDefaultName>
|
||||
<CreateInPlace>true</CreateInPlace>
|
||||
<PromptForSaveOnCreation>true</PromptForSaveOnCreation>
|
||||
</TemplateData>
|
||||
<TemplateContent>
|
||||
<Project File="ProjectTemplate.csproj" ReplaceParameters="true">
|
||||
<Folder Name="Models" TargetFolderName="Models"/>
|
||||
<ProjectItem>Assets\avalonia-logo.ico</ProjectItem>
|
||||
<ProjectItem ReplaceParameters="true">ViewModels\MainWindowViewModel.cs</ProjectItem>
|
||||
<ProjectItem ReplaceParameters="true">ViewModels\ViewModelBase.cs</ProjectItem>
|
||||
<ProjectItem ReplaceParameters="true" OpenInEditor="true">Views\MainWindow.xaml</ProjectItem>
|
||||
<ProjectItem ReplaceParameters="true">Views\MainWindow.xaml.cs</ProjectItem>
|
||||
<ProjectItem ReplaceParameters="true">App.xaml</ProjectItem>
|
||||
<ProjectItem ReplaceParameters="true">App.xaml.cs</ProjectItem>
|
||||
<ProjectItem>nuget.config</ProjectItem>
|
||||
<ProjectItem ReplaceParameters="true">Program.cs</ProjectItem>
|
||||
<ProjectItem ReplaceParameters="true">ViewLocator.cs</ProjectItem>
|
||||
</Project>
|
||||
</TemplateContent>
|
||||
</VSTemplate>
|
|
@ -1,22 +0,0 @@
|
|||
using System;
|
||||
using Avalonia;
|
||||
using Avalonia.Logging.Serilog;
|
||||
using $safeprojectname$.ViewModels;
|
||||
using $safeprojectname$.Views;
|
||||
|
||||
namespace $safeprojectname$
|
||||
{
|
||||
class Program
|
||||
{
|
||||
static void Main(string[] args)
|
||||
{
|
||||
BuildAvaloniaApp().Start<MainWindow>(() => new MainWindowViewModel());
|
||||
}
|
||||
|
||||
public static AppBuilder BuildAvaloniaApp()
|
||||
=> AppBuilder.Configure<App>()
|
||||
.UsePlatformDetect()
|
||||
.UseReactiveUI()
|
||||
.LogToDebug();
|
||||
}
|
||||
}
|
|
@ -1,21 +0,0 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFrameworks>netcoreapp2.0;net461</TargetFrameworks>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Folder Include="Models\" />
|
||||
<Compile Update="**\*.xaml.cs">
|
||||
<DependentUpon>%(Filename)</DependentUpon>
|
||||
</Compile>
|
||||
<EmbeddedResource Include="**\*.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Assets\*"/>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Avalonia" Version="0.7.0" />
|
||||
<PackageReference Include="Avalonia.Desktop" Version="0.7.0" />
|
||||
<PackageReference Include="Avalonia.ReactiveUI" Version="0.7.0" />
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -1,36 +0,0 @@
|
|||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("AvaloniaMvvmApplicationTemplate")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("Nikita Tsukanov")]
|
||||
[assembly: AssemblyProduct("AvaloniaMvvmApplicationTemplate")]
|
||||
[assembly: AssemblyCopyright("Copyright © Nikita Tsukanov 2015")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("75104aa0-3b1b-47d4-9c4d-501a8185acfc")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
|
@ -1,32 +0,0 @@
|
|||
using System;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Controls.Templates;
|
||||
using $safeprojectname$.ViewModels;
|
||||
|
||||
namespace $safeprojectname$
|
||||
{
|
||||
public class ViewLocator : IDataTemplate
|
||||
{
|
||||
public bool SupportsRecycling => false;
|
||||
|
||||
public IControl Build(object data)
|
||||
{
|
||||
var name = data.GetType().FullName.Replace("ViewModel", "View");
|
||||
var type = Type.GetType(name);
|
||||
|
||||
if (type != null)
|
||||
{
|
||||
return (Control)Activator.CreateInstance(type);
|
||||
}
|
||||
else
|
||||
{
|
||||
return new TextBlock { Text = "Not Found: " + name };
|
||||
}
|
||||
}
|
||||
|
||||
public bool Match(object data)
|
||||
{
|
||||
return data is ViewModelBase;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace $safeprojectname$.ViewModels
|
||||
{
|
||||
public class MainWindowViewModel : ViewModelBase
|
||||
{
|
||||
public string Greeting => "Hello World!";
|
||||
}
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using ReactiveUI;
|
||||
|
||||
namespace $safeprojectname$.ViewModels
|
||||
{
|
||||
public class ViewModelBase : ReactiveObject
|
||||
{
|
||||
}
|
||||
}
|
|
@ -1,13 +0,0 @@
|
|||
<Window xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:vm="clr-namespace:$safeprojectname$.ViewModels;assembly=$safeprojectname$"
|
||||
Icon="resm:$safeprojectname$.Assets.avalonia-logo.ico"
|
||||
Title="$safeprojectname$">
|
||||
|
||||
<Design.DataContext>
|
||||
<vm:MainWindowViewModel/>
|
||||
</Design.DataContext>
|
||||
|
||||
<TextBlock Text="{Binding Greeting}" HorizontalAlignment="Center" VerticalAlignment="Center"/>
|
||||
|
||||
</Window>
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче