894 changed files with 20702 additions and 16659 deletions
@ -0,0 +1,11 @@ |
|||
; This file is for unifying the coding style for different editors and IDEs. |
|||
; More information at http://EditorConfig.org |
|||
|
|||
root = true |
|||
|
|||
[*] |
|||
end_of_line = CRLF |
|||
|
|||
[*.cs] |
|||
indent_style = space |
|||
indent_size = 4 |
|||
@ -1,3 +1,10 @@ |
|||
[submodule "src/Perspex.ReactiveUI/src"] |
|||
path = src/Perspex.ReactiveUI/src |
|||
url = https://github.com/reactiveui/ReactiveUI.git |
|||
[submodule "src/Perspex.HtmlRenderer/external"] |
|||
path = src/Perspex.HtmlRenderer/external |
|||
url = https://github.com/Perspex/HTML-Renderer.git |
|||
branch = perspex-pcl |
|||
[submodule "src/Markup/Perspex.Markup.Xaml/OmniXAML"] |
|||
path = src/Markup/Perspex.Markup.Xaml/OmniXAML |
|||
url = https://github.com/SuperJMN/OmniXAML.git |
|||
|
|||
@ -0,0 +1,17 @@ |
|||
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation"> |
|||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=6417B24E_002D49C2_002D4985_002D8DB2_002D3AB9D898EC91/@EntryIndexedValue">ExplicitlyExcluded</s:String> |
|||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=E3A1060B_002D50D0_002D44E8_002D88B6_002DF44EF2E5BD72_002Ff_003Ahtml_002Ehtm/@EntryIndexedValue">ExplicitlyExcluded</s:String> |
|||
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=RedundantUsingDirective/@EntryIndexedValue">HINT</s:String> |
|||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=Constants/@EntryIndexedValue"><Policy Inspect="False" Prefix="" Suffix="" Style="AaBb" /></s:String> |
|||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=EnumMember/@EntryIndexedValue"><Policy Inspect="False" Prefix="" Suffix="" Style="AaBb" /></s:String> |
|||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=Interfaces/@EntryIndexedValue"><Policy Inspect="False" Prefix="I" Suffix="" Style="AaBb" /></s:String> |
|||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=Locals/@EntryIndexedValue"><Policy Inspect="False" Prefix="" Suffix="" Style="aaBb" /></s:String> |
|||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=MethodPropertyEvent/@EntryIndexedValue"><Policy Inspect="False" Prefix="" Suffix="" Style="AaBb" /></s:String> |
|||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=Other/@EntryIndexedValue"><Policy Inspect="False" Prefix="" Suffix="" Style="AaBb" /></s:String> |
|||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=Parameters/@EntryIndexedValue"><Policy Inspect="False" Prefix="" Suffix="" Style="aaBb" /></s:String> |
|||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=PrivateConstants/@EntryIndexedValue"><Policy Inspect="False" Prefix="" Suffix="" Style="AaBb" /></s:String> |
|||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=PrivateStaticFields/@EntryIndexedValue"><Policy Inspect="True" Prefix="s_" Suffix="" Style="aaBb" /></s:String> |
|||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=PrivateStaticReadonly/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="AaBb"><ExtraRule Prefix="s_" Suffix="" Style="aaBb" /></Policy></s:String> |
|||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=StaticReadonly/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /></s:String> |
|||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=TypeParameters/@EntryIndexedValue"><Policy Inspect="False" Prefix="T" Suffix="" Style="AaBb" /></s:String> |
|||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=TypesAndNamespaces/@EntryIndexedValue"><Policy Inspect="False" Prefix="" Suffix="" Style="AaBb" /></s:String></wpf:ResourceDictionary> |
|||
Binary file not shown.
@ -0,0 +1,44 @@ |
|||
namespace Perspex.Controls.UnitTests.DockPanelTests |
|||
{ |
|||
using Xunit; |
|||
|
|||
|
|||
public class AlignerTests |
|||
{ |
|||
[Fact] |
|||
public void ToStartTest() |
|||
{ |
|||
Segment container = new Segment(2, 5); |
|||
|
|||
var aligned = container.AlignToStart(2); |
|||
Assert.Equal(new Segment(2, 4), aligned); |
|||
} |
|||
|
|||
[Fact] |
|||
public void ToEndTest() |
|||
{ |
|||
Segment container = new Segment(2, 5); |
|||
|
|||
var aligned = container.AlignToEnd(2); |
|||
Assert.Equal(new Segment(3, 5), aligned); |
|||
} |
|||
|
|||
[Fact] |
|||
public void ToMiddleTest() |
|||
{ |
|||
Segment container = new Segment(2, 5); |
|||
|
|||
var aligned = container.AlignToMiddle(2); |
|||
Assert.Equal(new Segment(2.5, 4.5), aligned); |
|||
} |
|||
|
|||
[Fact] |
|||
public void ToMiddleTest2() |
|||
{ |
|||
Segment container = new Segment(0, 500); |
|||
|
|||
var aligned = container.AlignToMiddle(200); |
|||
Assert.Equal(new Segment(150, 350), aligned); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,38 @@ |
|||
namespace Perspex.Controls.UnitTests.DockPanelTests |
|||
{ |
|||
using System.Collections.Generic; |
|||
using Layout; |
|||
using Moq; |
|||
using Xunit; |
|||
|
|||
public class LeftDockerTests |
|||
{ |
|||
private readonly ILayoutable _layoutable; |
|||
|
|||
public LeftDockerTests() |
|||
{ |
|||
var layoutableMock = new Mock<ILayoutable>(); |
|||
layoutableMock.Setup(l => l.DesiredSize).Returns(new Size(40, 30)); |
|||
_layoutable = layoutableMock.Object; |
|||
} |
|||
|
|||
[Theory] |
|||
[MemberData("Source")] |
|||
public void Dock(Margins margins, Rect expectedRect) |
|||
{ |
|||
var sut = new LeftDocker(new Size(100, 50)); |
|||
var actualRect = sut.GetDockingRect(_layoutable.DesiredSize, margins, new Alignments(Alignment.Middle, Alignment.Stretch)); |
|||
|
|||
Assert.Equal(expectedRect, actualRect); |
|||
} |
|||
|
|||
// ReSharper disable once UnusedMember.Global
|
|||
public static IEnumerable<object[]> Source => new[] |
|||
{ |
|||
new object[] { new Margins(), new Rect(0, 0, 40, 50)}, |
|||
new object[] { new Margins { VerticalMargin = new Segment(15, 0) }, new Rect(0, 15, 40, 35)}, |
|||
new object[] { new Margins { VerticalMargin = new Segment(0, 15) }, new Rect(0, 0, 40, 35)}, |
|||
new object[] { new Margins { VerticalMargin = new Segment(20, 15) }, new Rect(0, 20, 40, 15)}, |
|||
}; |
|||
} |
|||
} |
|||
@ -0,0 +1,40 @@ |
|||
namespace Perspex.Controls.UnitTests.DockPanelTests |
|||
{ |
|||
using Layout; |
|||
using Xunit; |
|||
|
|||
public class RectAlignerTests |
|||
{ |
|||
private readonly Rect _container = new Rect(0, 0, 40, 40); |
|||
private readonly Size _child = new Size(20, 20); |
|||
|
|||
[Theory] |
|||
[MemberData("TestData")] |
|||
public void LefTopTest(Alignment horz, Alignment vert, Rect expectedRect) |
|||
{ |
|||
var actualRect = _container.AlignChild(_child, horz, vert); |
|||
Assert.Equal(expectedRect, actualRect); |
|||
} |
|||
|
|||
// ReSharper disable once UnusedMember.Global
|
|||
public static object[] TestData => new object[] |
|||
{ |
|||
new object[] {Alignment.Start, Alignment.Start, new Rect(0, 0, 20, 20)}, |
|||
new object[] {Alignment.Middle, Alignment.Start, new Rect(10, 0, 20, 20)}, |
|||
new object[] {Alignment.End, Alignment.Start, new Rect(20, 0, 20, 20)}, |
|||
new object[] {Alignment.Stretch, Alignment.Start, new Rect(0, 0, 40, 20)}, |
|||
|
|||
new object[] {Alignment.Start, Alignment.Middle, new Rect(0, 10, 20, 20)}, |
|||
new object[] {Alignment.Middle, Alignment.Middle, new Rect(10, 10, 20, 20)}, |
|||
new object[] {Alignment.End, Alignment.Middle, new Rect(20, 10, 20, 20)}, |
|||
new object[] {Alignment.Stretch, Alignment.Middle, new Rect(0, 10, 40, 20)}, |
|||
|
|||
new object[] {Alignment.Start, VerticalAlignment.Bottom, new Rect(0, 20, 20, 20)}, |
|||
new object[] {Alignment.Middle, VerticalAlignment.Bottom, new Rect(10, 20, 20, 20)}, |
|||
new object[] {Alignment.End, VerticalAlignment.Bottom, new Rect(20, 20, 20, 20)}, |
|||
new object[] {Alignment.Stretch, VerticalAlignment.Bottom, new Rect(0, 20, 40, 20)}, |
|||
|
|||
new object[] {Alignment.Stretch, VerticalAlignment.Stretch, new Rect(0, 0, 40, 40)}, |
|||
}; |
|||
} |
|||
} |
|||
@ -0,0 +1,38 @@ |
|||
namespace Perspex.Controls.UnitTests.DockPanelTests |
|||
{ |
|||
using System.Collections.Generic; |
|||
using Layout; |
|||
using Moq; |
|||
using Xunit; |
|||
|
|||
public class RightDockerTests |
|||
{ |
|||
private readonly ILayoutable _layoutable; |
|||
|
|||
public RightDockerTests() |
|||
{ |
|||
var layoutableMock = new Mock<ILayoutable>(); |
|||
layoutableMock.Setup(l => l.DesiredSize).Returns(new Size(40, 30)); |
|||
_layoutable = layoutableMock.Object; |
|||
} |
|||
|
|||
[Theory] |
|||
[MemberData("Source")] |
|||
public void Dock(Margins margins, Rect expectedRect) |
|||
{ |
|||
var sut = new RightDocker(new Size(100, 50)); |
|||
var actualRect = sut.GetDockingRect(_layoutable.DesiredSize, margins, new Alignments(Alignment.Middle, Alignment.Stretch)); |
|||
|
|||
Assert.Equal(expectedRect, actualRect); |
|||
} |
|||
|
|||
// ReSharper disable once UnusedMember.Global
|
|||
public static IEnumerable<object[]> Source => new[] |
|||
{ |
|||
new object[] { new Margins(), new Rect(60, 0, 40, 50)}, |
|||
new object[] { new Margins { VerticalMargin = new Segment(0, 15) }, new Rect(60, 0, 40, 35)}, |
|||
new object[] { new Margins { VerticalMargin = new Segment(15, 0) }, new Rect(60, 15, 40, 35)}, |
|||
new object[] { new Margins { VerticalMargin = new Segment(20, 15) }, new Rect(60, 20, 40, 15)}, |
|||
}; |
|||
} |
|||
} |
|||
|
After Width: | Height: | Size: 20 KiB |
|
After Width: | Height: | Size: 233 KiB |
@ -0,0 +1,15 @@ |
|||
# Getting Started |
|||
|
|||
## Windows |
|||
|
|||
 |
|||
|
|||
The easiest way to try out Perspex is to install the Visual Studio Extension. |
|||
|
|||
This will add a Perspex project template and a Window template to the standard Visual Studo “Add” dialog (yes, icons still to come :) ): |
|||
|
|||
## OSX / Linux |
|||
|
|||
It is a little more manual on non-Windows platforms, but using Xamarin Studio you can install the Perspex NuGet package. |
|||
|
|||
 |
|||
|
After Width: | Height: | Size: 133 KiB |
|
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 104 KiB |
@ -0,0 +1,93 @@ |
|||
# Styling in Perspex |
|||
|
|||
The main difference between Perspex and existing XAML toolkits such as WPF and |
|||
UWP is in styling. Styling in Perspex uses a CSS-like system that aims to be |
|||
more powerful and flexible than existing XAML styling systems. For convenience |
|||
for the rest of this document we'll refer to existing XAML toolkit's styling as |
|||
"WPF styling" as that's where it originated. |
|||
|
|||
## Basics |
|||
|
|||
- Styles are defined on the `Control.Styles` collection (as opposed to in |
|||
`ResourceDictionaries` in WPF). |
|||
- Styles have a `Selector` and a collection of `Setter`s |
|||
- Selector works like a CSS selector. |
|||
- Setters function like WPF's setters. |
|||
- Styles are applied to a control and all its descendants, depending on whether |
|||
the selector matches. |
|||
|
|||
## Simple example |
|||
|
|||
Make all `Button`s in a `StackPanel` have a blue `Background`: |
|||
|
|||
<StackPanel> |
|||
<StackPanel.Styles> |
|||
<Style Selector="Button"> |
|||
<Setter Property="Button.Background" Value="Blue"/> |
|||
</Style> |
|||
</StackPanel.Styles> |
|||
<Button>I will have a blue background.</Button> |
|||
</StackPanel> |
|||
|
|||
This is very similar to WPF, except `TargetType` is replaced by `Selector`. |
|||
|
|||
*Note that currently (as of Alpha 2) you **always** need to specify the fully |
|||
qualified property name (i.e. `Button.Background` instead of simply |
|||
`Background`). This restriction will be lifted in future.* |
|||
|
|||
## Style Classes |
|||
|
|||
As in CSS, controls can be given *style classes* which can be used in selectors: |
|||
|
|||
<StackPanel> |
|||
<StackPanel.Styles> |
|||
<Style Selector="Button.blue"> |
|||
<Setter Property="Button.Background" Value="Blue"/> |
|||
</Style> |
|||
</StackPanel.Styles> |
|||
<Button Classes="blue">I will have a blue background.</Button> |
|||
<Button>I will not.</Button> |
|||
</StackPanel> |
|||
|
|||
## Pseudoclasses |
|||
|
|||
Also as in CSS, controls can have pseudoclasses; these are classes that are |
|||
defined by the control itself rather than by the user. Pseudoclasses start |
|||
with a `:` character. |
|||
|
|||
One example of a pseudoclass is the `:pointerover` |
|||
pseudoclass (`:hover` in CSS - we may change to that in future). |
|||
|
|||
Pseudoclasses provide the functionality of `Triggers` in WPF and |
|||
`VisualStateManager` in UWP: |
|||
|
|||
<StackPanel> |
|||
<StackPanel.Styles> |
|||
<Style Selector="Button:pointerover"> |
|||
<Setter Property="Button.Foreground" Value="Red"/> |
|||
</Style> |
|||
</StackPanel.Styles> |
|||
<Button>I will have red text when hovered.</Button> |
|||
</StackPanel> |
|||
|
|||
Other pseudoclasses include `:focus`, `:disabled`, `:pressed` for buttons, |
|||
`:checked` for checkboxes etc. |
|||
|
|||
## Named Controls |
|||
|
|||
Named controls can be selected using `#` as in CSS, e.g. `Button#Name`. |
|||
|
|||
## Children |
|||
|
|||
As with CSS, you can select children and descendants: |
|||
|
|||
- `StackPanel > Button#Foo` selects a `Button` named `"Foo"` that is the child |
|||
of a `StackPanel`. |
|||
- `StackPanel Button.foo` selects all `Button`s with the `foo` class that are |
|||
descendants of a `StackPanel`. |
|||
|
|||
## Templates |
|||
|
|||
You can select controls in the template of a lookless control by using the |
|||
`/template/` selector, so `Button /template/ Border#outline` selects `Border` |
|||
controls named `"outline"` in the template of a `Button`. |
|||
@ -0,0 +1,2 @@ |
|||
// Copyright (c) The Perspex Project. All rights reserved. |
|||
// Licensed under the MIT license. See licence.md file in the project root for full license information. |
|||
@ -1,7 +1,2 @@ |
|||
- build/ |
|||
|
|||
**/lib/**/*.dll |
|||
**/lib/**/*.xml |
|||
**/build/**/*.dll |
|||
**/build/**/*.xml |
|||
Perspex |
|||
*.nupkg |
|||
@ -0,0 +1,33 @@ |
|||
$scriptpath = $MyInvocation.MyCommand.Path |
|||
$dir = Split-Path $scriptpath |
|||
Push-Location $dir |
|||
|
|||
|
|||
sv version $env:APPVEYOR_BUILD_NUMBER |
|||
#sv version "1-debug" |
|||
|
|||
sv version 9999.0.$version-nightly |
|||
sv key $env:myget_key |
|||
|
|||
sv file Perspex.$version.nupkg |
|||
|
|||
.\build-version.ps1 $version |
|||
|
|||
|
|||
sv reponame $env:APPVEYOR_REPO_NAME |
|||
sv repobranch $env:APPVEYOR_REPO_BRANCH |
|||
sv pullreq $env:APPVEYOR_PULL_REQUEST_NUMBER |
|||
|
|||
echo "Checking for publishing" |
|||
echo $reponame $repobranch $pullreq |
|||
if ($reponame -eq "Perspex/Perspex") |
|||
{ |
|||
echo Repo name matched |
|||
if($repobranch -eq "master") |
|||
{ |
|||
echo Repo branch matched |
|||
nuget.exe push $file $key -Source https://www.myget.org/F/perspex-nightly/api/v2/package |
|||
} |
|||
} |
|||
|
|||
|
|||
@ -0,0 +1,47 @@ |
|||
rm -Force -Recurse .\Perspex -ErrorAction SilentlyContinue |
|||
rm -Force -Recurse *.nupkg -ErrorAction SilentlyContinue |
|||
Copy-Item template Perspex -Recurse |
|||
sv lib "Perspex\lib\portable-windows8+net45" |
|||
sv build "Perspex\build\net45" |
|||
mkdir $lib -ErrorAction SilentlyContinue |
|||
mkdir $build -ErrorAction SilentlyContinue |
|||
|
|||
Copy-Item ..\src\Perspex.Animation\bin\Release\Perspex.Animation.dll $lib |
|||
Copy-Item ..\src\Perspex.Animation\bin\Release\Perspex.Animation.xml $lib |
|||
Copy-Item ..\src\Perspex.Application\bin\Release\Perspex.Application.dll $lib |
|||
Copy-Item ..\src\Perspex.Application\bin\Release\Perspex.Application.xml $lib |
|||
Copy-Item ..\src\Perspex.Base\bin\Release\Perspex.Base.dll $lib |
|||
Copy-Item ..\src\Perspex.Base\bin\Release\Perspex.Base.xml $lib |
|||
Copy-Item ..\src\Perspex.Controls\bin\Release\Perspex.Controls.dll $lib |
|||
Copy-Item ..\src\Perspex.Controls\bin\Release\Perspex.Controls.xml $lib |
|||
Copy-Item ..\src\Perspex.Diagnostics\bin\Release\\Perspex.Diagnostics.dll $lib |
|||
Copy-Item ..\src\Perspex.Diagnostics\bin\Release\\Perspex.Diagnostics.xml $lib |
|||
Copy-Item ..\src\Perspex.Input\bin\Release\Perspex.Input.dll $lib |
|||
Copy-Item ..\src\Perspex.Input\bin\Release\Perspex.Input.xml $lib |
|||
Copy-Item ..\src\Perspex.Interactivity\bin\Release\Perspex.Interactivity.dll $lib |
|||
Copy-Item ..\src\Perspex.Interactivity\bin\Release\Perspex.Interactivity.xml $lib |
|||
Copy-Item ..\src\Perspex.Layout\bin\Release\Perspex.Layout.dll $lib |
|||
Copy-Item ..\src\Perspex.Layout\bin\Release\Perspex.Layout.xml $lib |
|||
Copy-Item ..\src\Perspex.SceneGraph\bin\Release\Perspex.SceneGraph.dll $lib |
|||
Copy-Item ..\src\Perspex.SceneGraph\bin\Release\Perspex.SceneGraph.xml $lib |
|||
Copy-Item ..\src\Perspex.Styling\bin\Release\Perspex.Styling.dll $lib |
|||
Copy-Item ..\src\Perspex.Styling\bin\Release\Perspex.Styling.xml $lib |
|||
Copy-Item ..\src\Perspex.Themes.Default\bin\Release\Perspex.Themes.Default.dll $lib |
|||
Copy-Item ..\src\Perspex.Themes.Default\bin\Release\Perspex.Themes.Default.xml $lib |
|||
Copy-Item ..\src\Markup\Perspex.Markup.Xaml\bin\Release\Perspex.Markup.Xaml.dll $lib |
|||
Copy-Item ..\src\Markup\Perspex.Markup.Xaml\bin\Release\Perspex.Markup.Xaml.xml $lib |
|||
Copy-Item ..\src\Perspex.HtmlRenderer\bin\Release\Perspex.HtmlRenderer.dll $lib |
|||
Copy-Item ..\src\Perspex.ReactiveUI\bin\Release\Perspex.ReactiveUI.dll $lib |
|||
|
|||
Copy-Item ..\src\Windows\Perspex.Direct2D1\bin\Release\Perspex.Direct2D1.dll $build |
|||
Copy-Item ..\src\Windows\Perspex.Direct2D1\bin\Release\SharpDX.dll $build |
|||
Copy-Item ..\src\Windows\Perspex.Direct2D1\bin\Release\SharpDX.Direct2D1.dll $build |
|||
Copy-Item ..\src\Windows\Perspex.Direct2D1\bin\Release\SharpDX.DXGI.dll $build |
|||
Copy-Item ..\src\Windows\Perspex.Win32\bin\Release\Perspex.Win32.dll $build |
|||
Copy-Item ..\src\Gtk\Perspex.Gtk\bin\Release\Perspex.Gtk.dll $build |
|||
Copy-Item ..\src\Gtk\Perspex.Cairo\bin\Release\Perspex.Cairo.dll $build |
|||
|
|||
(gc Perspex\Perspex.nuspec).replace('#VERSION#', $args[0]) | sc Perspex\Perspex.nuspec |
|||
|
|||
nuget.exe pack Perspex\Perspex.nuspec |
|||
rm -Force -Recurse .\Perspex |
|||
@ -1,39 +0,0 @@ |
|||
SET lib="Perspex\lib\portable-windows8+net45" |
|||
SET build="Perspex\build\net45" |
|||
|
|||
mkdir %lib% |
|||
mkdir %build% |
|||
|
|||
copy ..\src\Perspex.Animation\bin\Release\Perspex.Animation.dll %lib% |
|||
copy ..\src\Perspex.Animation\bin\Release\Perspex.Animation.xml %lib% |
|||
copy ..\src\Perspex.Application\bin\Release\Perspex.Application.dll %lib% |
|||
copy ..\src\Perspex.Application\bin\Release\Perspex.Application.xml %lib% |
|||
copy ..\src\Perspex.Base\bin\Release\Perspex.Base.dll %lib% |
|||
copy ..\src\Perspex.Base\bin\Release\Perspex.Base.xml %lib% |
|||
copy ..\src\Perspex.Controls\bin\Release\Perspex.Controls.dll %lib% |
|||
copy ..\src\Perspex.Controls\bin\Release\Perspex.Controls.xml %lib% |
|||
copy ..\src\Perspex.Diagnostics\bin\Release\\Perspex.Diagnostics.dll %lib% |
|||
copy ..\src\Perspex.Diagnostics\bin\Release\\Perspex.Diagnostics.xml %lib% |
|||
copy ..\src\Perspex.Input\bin\Release\Perspex.Input.dll %lib% |
|||
copy ..\src\Perspex.Input\bin\Release\Perspex.Input.xml %lib% |
|||
copy ..\src\Perspex.Interactivity\bin\Release\Perspex.Interactivity.dll %lib% |
|||
copy ..\src\Perspex.Interactivity\bin\Release\Perspex.Interactivity.xml %lib% |
|||
copy ..\src\Perspex.Layout\bin\Release\Perspex.Layout.dll %lib% |
|||
copy ..\src\Perspex.Layout\bin\Release\Perspex.Layout.xml %lib% |
|||
copy ..\src\Perspex.SceneGraph\bin\Release\Perspex.SceneGraph.dll %lib% |
|||
copy ..\src\Perspex.SceneGraph\bin\Release\Perspex.SceneGraph.xml %lib% |
|||
copy ..\src\Perspex.Styling\bin\Release\Perspex.Styling.dll %lib% |
|||
copy ..\src\Perspex.Styling\bin\Release\Perspex.Styling.xml %lib% |
|||
copy ..\src\Perspex.Themes.Default\bin\Release\Perspex.Themes.Default.dll %lib% |
|||
copy ..\src\Perspex.Themes.Default\bin\Release\Perspex.Themes.Default.xml %lib% |
|||
copy ..\src\Markup\Perspex.Markup.Xaml\bin\Release\Perspex.Markup.Xaml.dll %lib% |
|||
copy ..\src\Markup\Perspex.Markup.Xaml\bin\Release\Perspex.Markup.Xaml.xml %lib% |
|||
copy ..\src\NGenerics\bin\Release\NGenerics.dll %lib% |
|||
|
|||
copy ..\src\Windows\Perspex.Direct2D1\bin\Release\Perspex.Direct2D1.dll %build% |
|||
copy ..\src\Windows\Perspex.Direct2D1\bin\Release\SharpDX.dll %build% |
|||
copy ..\src\Windows\Perspex.Direct2D1\bin\Release\SharpDX.Direct2D1.dll %build% |
|||
copy ..\src\Windows\Perspex.Direct2D1\bin\Release\SharpDX.DXGI.dll %build% |
|||
copy ..\src\Windows\Perspex.Win32\bin\Release\Perspex.Win32.dll %build% |
|||
|
|||
nuget.exe pack Perspex\Perspex.nuspec |
|||
@ -0,0 +1 @@ |
|||
.\build-version.ps1 0.1.1-alpha2 |
|||
@ -1,16 +1,20 @@ |
|||
namespace TestApplication |
|||
{ |
|||
using System; |
|||
using Perspex; |
|||
using Perspex.Themes.Default; |
|||
// Copyright (c) The Perspex Project. All rights reserved.
|
|||
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
|||
|
|||
using System; |
|||
using Perspex; |
|||
using Perspex.Themes.Default; |
|||
|
|||
namespace TestApplication |
|||
{ |
|||
public class App : Application |
|||
{ |
|||
public App() |
|||
{ |
|||
this.RegisterServices(); |
|||
this.InitializeSubsystems((int)Environment.OSVersion.Platform); |
|||
this.Styles = new DefaultTheme(); |
|||
RegisterServices(); |
|||
InitializeSubsystems((int)Environment.OSVersion.Platform); |
|||
Styles = new DefaultTheme(); |
|||
Styles.Add(new SampleTabStyle()); |
|||
} |
|||
} |
|||
} |
|||
|
|||
@ -0,0 +1,123 @@ |
|||
using Perspex; |
|||
using Perspex.Controls; |
|||
using Perspex.Controls.Presenters; |
|||
using Perspex.Controls.Primitives; |
|||
using Perspex.Controls.Templates; |
|||
using Perspex.Media; |
|||
using Perspex.Styling; |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Text; |
|||
using System.Threading.Tasks; |
|||
|
|||
namespace TestApplication |
|||
{ |
|||
internal class SampleTabStyle : Styles |
|||
{ |
|||
public SampleTabStyle() |
|||
{ |
|||
this.AddRange(new[] |
|||
{ |
|||
new Style (s => s.Class(":container").OfType<TabControl> ()) |
|||
{ |
|||
Setters = new[] |
|||
{ |
|||
new Setter (TemplatedControl.TemplateProperty, new ControlTemplate<TabControl> (TabControlTemplate)) |
|||
} |
|||
}, |
|||
|
|||
new Style(s => s.Class(":container").OfType<TabControl>().Child().Child().Child().Child().Child().OfType<TabItem>()) |
|||
{ |
|||
Setters = new[] |
|||
{ |
|||
new Setter (TemplatedControl.TemplateProperty, new ControlTemplate<TabItem> (TabItemTemplate)), |
|||
} |
|||
}, |
|||
|
|||
new Style(s => s.Name("internalStrip").OfType<TabStrip>().Child().OfType<TabItem>()) |
|||
{ |
|||
Setters = new[] |
|||
{ |
|||
new Setter(TemplatedControl.FontSizeProperty, 14.0), |
|||
new Setter(TemplatedControl.ForegroundProperty, Brushes.White) |
|||
} |
|||
}, |
|||
|
|||
new Style(s => s.Name("internalStrip").OfType<TabStrip>().Child().OfType<TabItem>().Class("selected")) |
|||
{ |
|||
Setters = new[] |
|||
{ |
|||
new Setter(TemplatedControl.ForegroundProperty, Brushes.White), |
|||
new Setter(TemplatedControl.BackgroundProperty, new SolidColorBrush(Colors.White) { Opacity = 0.1 }), |
|||
}, |
|||
}, |
|||
}); |
|||
} |
|||
|
|||
public static Control TabItemTemplate(TabItem control) |
|||
{ |
|||
return new ContentPresenter |
|||
{ |
|||
DataTemplates = new DataTemplates |
|||
{ |
|||
new DataTemplate<string>(x => new Border |
|||
{ |
|||
[~Border.BackgroundProperty] = control[~TemplatedControl.BackgroundProperty], |
|||
Padding = new Thickness(10), |
|||
Child = new TextBlock |
|||
{ |
|||
VerticalAlignment = Perspex.Layout.VerticalAlignment.Center, |
|||
Text = x |
|||
} |
|||
}) |
|||
}, |
|||
Name = "headerPresenter", |
|||
[~ContentPresenter.ContentProperty] = control[~HeaderedContentControl.HeaderProperty], |
|||
}; |
|||
} |
|||
|
|||
public static Control TabControlTemplate(TabControl control) |
|||
{ |
|||
return new Grid |
|||
{ |
|||
ColumnDefinitions = new ColumnDefinitions |
|||
{ |
|||
new ColumnDefinition(GridLength.Auto), |
|||
new ColumnDefinition(new GridLength(1, GridUnitType.Star)), |
|||
}, |
|||
Children = new Controls |
|||
{ |
|||
new Border |
|||
{ |
|||
Width = 190, |
|||
Background = SolidColorBrush.Parse("#1976D2"), |
|||
Child = new ScrollViewer |
|||
{ |
|||
Content = new TabStrip |
|||
{ |
|||
ItemsPanel = new FuncTemplate<IPanel>(() => new StackPanel { Orientation = Orientation.Vertical, Gap = 4 }), |
|||
Margin = new Thickness(0, 10, 0, 0), |
|||
Name = "internalStrip", |
|||
[!ItemsControl.ItemsProperty] = control[!ItemsControl.ItemsProperty], |
|||
[!!SelectingItemsControl.SelectedItemProperty] = control[!!SelectingItemsControl.SelectedItemProperty], |
|||
} |
|||
} |
|||
}, |
|||
new Deck |
|||
{ |
|||
Name = "deck", |
|||
DataTemplates = new DataTemplates |
|||
{ |
|||
new DataTemplate<TabItem>(x => (Control)control.MaterializeDataTemplate(x.Content)), |
|||
}, |
|||
[~Deck.TransitionProperty] = control[~TabControl.TransitionProperty], |
|||
[!ItemsControl.ItemsProperty] = control[!ItemsControl.ItemsProperty], |
|||
[!SelectingItemsControl.SelectedItemProperty] = control[!SelectingItemsControl.SelectedItemProperty], |
|||
[Grid.ColumnProperty] = 1, |
|||
} |
|||
} |
|||
}; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,8 @@ |
|||
namespace TestApplication |
|||
{ |
|||
internal class Item |
|||
{ |
|||
public string Name { get; set; } |
|||
public string Value { get; set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,16 @@ |
|||
using Perspex.Collections; |
|||
|
|||
namespace TestApplication |
|||
{ |
|||
internal class Node |
|||
{ |
|||
public Node() |
|||
{ |
|||
Children = new PerspexList<Node>(); |
|||
} |
|||
|
|||
public string Name { get; set; } |
|||
public PerspexList<Node> Children { get; set; } |
|||
} |
|||
|
|||
} |
|||
File diff suppressed because it is too large
@ -0,0 +1,128 @@ |
|||
<html> |
|||
<head> |
|||
<title>Intro</title> |
|||
<style> |
|||
h1, h2, h3 { color: navy; font-weight:normal; } |
|||
h1 { margin-bottom: .47em } |
|||
h2 { margin-bottom: .3em } |
|||
h3 { margin-bottom: .4em } |
|||
ul { margin-top: .5em } |
|||
ul li {margin: .25em} |
|||
body { font:10pt Tahoma } |
|||
pre { border:solid 1px gray; background-color:#eee; padding:1em } |
|||
a:link { text-decoration: none; } |
|||
a:hover { text-decoration: underline; } |
|||
.gray { color:gray; } |
|||
.example { background-color:#efefef; corner-radius:5px; padding:0.5em; } |
|||
.whitehole { background-color:white; corner-radius:10px; padding:15px; } |
|||
.caption { font-size: 1.1em } |
|||
.comment { color: green; margin-bottom: 5px; margin-left: 3px; } |
|||
.comment2 { color: green; } |
|||
</style> |
|||
</head> |
|||
<body style=" margin: 0; background-color: #333; background-gradient: #707; background-gradient-angle: 60;"> |
|||
<h1 align="center" style="color: white;"> |
|||
HTML Renderer Project - Perspex port |
|||
<br /> |
|||
<span style="font-size: x-small;">Beta support</span> |
|||
</h1> |
|||
<blockquote class="whitehole"> |
|||
<p style="margin-top: 0px"> |
|||
<table border="0" width="100%"> |
|||
<tr style="vertical-align: top> |
|||
<td> |
|||
Everything you see on this panel (see samples on the left) is <b>custom-painted</b> |
|||
by the <b>HTML Renderer</b>, including tables, images, links and videos.<br /> |
|||
This project allows you to have the rich format power of HTML on your desktop applications |
|||
without <b>WebBrowser</b> control or <b>MSHTML</b>.<br /> |
|||
The library is <b>100% managed code</b> without any external dependencies, the only |
|||
requirement is <b>.NET 2.0 or higher</b>, including support for Client Profile. |
|||
</td> |
|||
</tr> |
|||
</table> |
|||
</p> |
|||
<h3> |
|||
Text selection (copy to clipboard) |
|||
</h3> |
|||
<div> |
|||
The rendered html has full support for <b>text selection</b> including <b>drag-and-drop</b> |
|||
and <b>copy</b> to clipboard of rich html and plain text to handle <b>paste</b> |
|||
operation to editor that support rich or/and plain text.<br /> |
|||
Additionally there is a <b>context-menu</b> with select all, copy text, copy image, |
|||
save image, open link, copy link url, open video, copy video url. |
|||
</div> |
|||
<h3> |
|||
Cascading Style Sheets (CSS) support |
|||
</h3> |
|||
<div> |
|||
The core layout engine of the renderer was builded according to <b>CSS Level 2 specification</b>, |
|||
so you can use Cascading Style Sheets to format your html documents.<br /> |
|||
Additionally there are a couple extensions: <b>Gradients</b> on backgrounds and |
|||
<b>rounded corners</b>. |
|||
</div> |
|||
|
|||
<h3> |
|||
Benefits |
|||
</h3> |
|||
<ul> |
|||
<li>100% managed code and no external dependencies.</li> |
|||
<li>Supports .NET 2.0 or higher including Client Profile.</li> |
|||
<li>Handles "real world" malformed HTML, it doesn't have to be XHTML.</li> |
|||
<li>Lightweight (~300K).</li> |
|||
<li>High performance and low memory footprint.</li> |
|||
<li>Extendable and configurable.</li> |
|||
</ul> |
|||
<h3> |
|||
Limitations |
|||
</h3> |
|||
<ul> |
|||
<li>All HTML <b>end tags</b> marked as <a href="http://www.w3.org/TR/1999/REC-html401-19991224/index/elements.html"> |
|||
optional</a> should be there. No problem with tags marked as forbidden.</li> |
|||
</ul> |
|||
<hr /> |
|||
<h3> |
|||
On the roadmap</h3> |
|||
Of course it's not quite finished yet. Here are some of the important things to |
|||
do. |
|||
<ul> |
|||
<li>Better performance</li> |
|||
<li>Support of position CSS property</li> |
|||
<li>Support of height and min-height CSS property</li> |
|||
<li>Better tables support, especially layouts</li> |
|||
<li>Support image align</li> |
|||
<li>Handle :hover selector</li> |
|||
<li>Selection by shift+arrows</li> |
|||
<li>Better HTML tag parsing (optional closing tags)</li> |
|||
<li>More styles support</li> |
|||
</ul> |
|||
<h3> |
|||
Vision |
|||
</h3> |
|||
<ul> |
|||
<li>Most complete static HTML Renderer (no java script).</li> |
|||
<li>Commercial web browser performance level.</li> |
|||
</ul> |
|||
<hr /> |
|||
<h3> |
|||
2015 - Nikita Tsukanov (Perspex Port) |
|||
|
|||
</h3> |
|||
<blockquote> |
|||
<a href="https://perspex.github.io/">https://perspex.github.io/</a> |
|||
</blockquote> |
|||
|
|||
<h3> |
|||
2012 - Arthur Teplitzki |
|||
</h3> |
|||
<blockquote> |
|||
<a href="http://theartofdev.com/">http://TheArtOfDev.com</a> |
|||
</blockquote> |
|||
<h3> |
|||
2009 - Jose Manuel Menendez Poo |
|||
</h3> |
|||
<blockquote> |
|||
<a href="http://www.menendezpoo.com">www.menendezpoo.com</a> |
|||
</blockquote> |
|||
</blockquote> |
|||
</body> |
|||
</html> |
|||
|
After Width: | Height: | Size: 133 KiB |
@ -1,16 +1,19 @@ |
|||
namespace XamlTestApplication |
|||
{ |
|||
using System; |
|||
using Perspex; |
|||
using Perspex.Themes.Default; |
|||
// Copyright (c) The Perspex Project. All rights reserved.
|
|||
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
|||
|
|||
using System; |
|||
using Perspex; |
|||
using Perspex.Themes.Default; |
|||
|
|||
namespace XamlTestApplication |
|||
{ |
|||
public class App : Application |
|||
{ |
|||
public App() |
|||
{ |
|||
this.RegisterServices(); |
|||
this.InitializeSubsystems((int)Environment.OSVersion.Platform); |
|||
this.Styles = new DefaultTheme(); |
|||
RegisterServices(); |
|||
InitializeSubsystems((int)Environment.OSVersion.Platform); |
|||
Styles = new DefaultTheme(); |
|||
} |
|||
} |
|||
} |
|||
|
|||
@ -0,0 +1,17 @@ |
|||
using System; |
|||
using global::Cairo; |
|||
|
|||
namespace Perspex.Cairo |
|||
{ |
|||
public abstract class BrushImpl : IDisposable |
|||
{ |
|||
public Pattern PlatformBrush { get; protected set; } |
|||
|
|||
public void Dispose() |
|||
{ |
|||
if (this.PlatformBrush != null) |
|||
this.PlatformBrush.Dispose(); |
|||
} |
|||
} |
|||
} |
|||
|
|||
@ -0,0 +1,14 @@ |
|||
using System; |
|||
using global::Cairo; |
|||
|
|||
namespace Perspex.Cairo.Media |
|||
{ |
|||
public class ImageBrushImpl : BrushImpl |
|||
{ |
|||
public ImageBrushImpl(Perspex.Media.ImageBrush brush, Size destinationSize) |
|||
{ |
|||
this.PlatformBrush = TileBrushes.CreateImageBrush(brush, destinationSize); |
|||
} |
|||
} |
|||
} |
|||
|
|||
@ -1,41 +1,33 @@ |
|||
// -----------------------------------------------------------------------
|
|||
// <copyright file="BitmapImpl.cs" company="Steven Kirk">
|
|||
// Copyright 2014 MIT Licence. See licence.md for more information.
|
|||
// </copyright>
|
|||
// -----------------------------------------------------------------------
|
|||
// Copyright (c) The Perspex Project. All rights reserved.
|
|||
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
|||
|
|||
using System; |
|||
using Perspex.Platform; |
|||
|
|||
namespace Perspex.Cairo.Media.Imaging |
|||
{ |
|||
using System; |
|||
using Perspex.Platform; |
|||
using Cairo = global::Cairo; |
|||
|
|||
public class BitmapImpl : IBitmapImpl |
|||
{ |
|||
public BitmapImpl(Cairo.ImageSurface surface) |
|||
public BitmapImpl(Gdk.Pixbuf pixbuf) |
|||
{ |
|||
this.Surface = surface; |
|||
Surface = pixbuf; |
|||
} |
|||
|
|||
public int PixelWidth |
|||
{ |
|||
get { return this.Surface.Width; } |
|||
} |
|||
public int PixelWidth => Surface.Width; |
|||
|
|||
public int PixelHeight |
|||
{ |
|||
get { return this.Surface.Height; } |
|||
} |
|||
public int PixelHeight => Surface.Height; |
|||
|
|||
public Cairo.ImageSurface Surface |
|||
public Gdk.Pixbuf Surface |
|||
{ |
|||
get; |
|||
private set; |
|||
} |
|||
|
|||
public void Save(string fileName) |
|||
{ |
|||
this.Surface.WriteToPng(fileName); |
|||
// TODO: Test
|
|||
Surface.Save(fileName, "png"); |
|||
} |
|||
} |
|||
} |
|||
|
|||
@ -1,32 +1,44 @@ |
|||
// -----------------------------------------------------------------------
|
|||
// <copyright file="RenderTargetBitmapImpl.cs" company="Steven Kirk">
|
|||
// Copyright 2014 MIT Licence. See licence.md for more information.
|
|||
// </copyright>
|
|||
// -----------------------------------------------------------------------
|
|||
// Copyright (c) The Perspex Project. All rights reserved.
|
|||
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
|||
|
|||
using System; |
|||
using Perspex.Platform; |
|||
|
|||
namespace Perspex.Cairo.Media.Imaging |
|||
{ |
|||
using System; |
|||
using Perspex.Platform; |
|||
using Cairo = global::Cairo; |
|||
|
|||
public class RenderTargetBitmapImpl : BitmapImpl, IRenderTargetBitmapImpl |
|||
public class RenderTargetBitmapImpl : IRenderTargetBitmapImpl |
|||
{ |
|||
public RenderTargetBitmapImpl( |
|||
Cairo.ImageSurface surface) |
|||
: base(surface) |
|||
public RenderTargetBitmapImpl(Cairo.ImageSurface surface) |
|||
{ |
|||
Surface = surface; |
|||
renderer = new Renderer(Surface); |
|||
} |
|||
|
|||
public int PixelWidth => Surface.Width; |
|||
|
|||
public int PixelHeight => Surface.Height; |
|||
|
|||
public void Dispose() |
|||
{ |
|||
this.Surface.Dispose(); |
|||
renderer.Dispose(); |
|||
} |
|||
|
|||
public Cairo.ImageSurface Surface |
|||
{ |
|||
get; |
|||
} |
|||
|
|||
private Renderer renderer; |
|||
public void Render(IVisual visual) |
|||
{ |
|||
Renderer renderer = new Renderer(this.Surface); |
|||
renderer.Render(visual, new PlatformHandle(IntPtr.Zero, "RTB")); |
|||
} |
|||
|
|||
public void Save(string fileName) |
|||
{ |
|||
Surface.WriteToPng(fileName); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,22 @@ |
|||
using System; |
|||
using global::Cairo; |
|||
|
|||
namespace Perspex.Cairo |
|||
{ |
|||
public class LinearGradientBrushImpl : BrushImpl |
|||
{ |
|||
public LinearGradientBrushImpl(Perspex.Media.LinearGradientBrush brush, Size destinationSize) |
|||
{ |
|||
var start = brush.StartPoint.ToPixels(destinationSize); |
|||
var end = brush.EndPoint.ToPixels(destinationSize); |
|||
|
|||
this.PlatformBrush = new LinearGradient(start.X, start.Y, end.X, end.Y); |
|||
|
|||
foreach (var stop in brush.GradientStops) |
|||
((LinearGradient)this.PlatformBrush).AddColorStop(stop.Offset, stop.Color.ToCairo()); |
|||
|
|||
((LinearGradient)this.PlatformBrush).Extend = Extend.Pad; |
|||
} |
|||
} |
|||
} |
|||
|
|||
@ -0,0 +1,25 @@ |
|||
using System; |
|||
using global::Cairo; |
|||
|
|||
namespace Perspex.Cairo |
|||
{ |
|||
public class RadialGradientBrushImpl : BrushImpl |
|||
{ |
|||
public RadialGradientBrushImpl(Perspex.Media.RadialGradientBrush brush, Size destinationSize) |
|||
{ |
|||
var center = brush.Center.ToPixels(destinationSize); |
|||
var gradientOrigin = brush.GradientOrigin.ToPixels(destinationSize); |
|||
var radius = brush.Radius; |
|||
|
|||
this.PlatformBrush = new RadialGradient(center.X, center.Y, radius, gradientOrigin.X, gradientOrigin.Y, radius); |
|||
|
|||
foreach (var stop in brush.GradientStops) |
|||
{ |
|||
((LinearGradient)this.PlatformBrush).AddColorStop(stop.Offset, stop.Color.ToCairo()); |
|||
} |
|||
|
|||
((LinearGradient)this.PlatformBrush).Extend = Extend.Pad; |
|||
} |
|||
} |
|||
} |
|||
|
|||
@ -0,0 +1,22 @@ |
|||
using System; |
|||
using global::Cairo; |
|||
|
|||
namespace Perspex.Cairo |
|||
{ |
|||
public class SolidColorBrushImpl : BrushImpl |
|||
{ |
|||
public SolidColorBrushImpl(Perspex.Media.SolidColorBrush brush, double opacityOverride = 1.0f) |
|||
{ |
|||
var color = brush?.Color.ToCairo() ?? new Color(); |
|||
|
|||
if (brush != null) |
|||
color.A = Math.Min(brush.Opacity, color.A); |
|||
|
|||
if (opacityOverride < 1.0f) |
|||
color.A = Math.Min(opacityOverride, color.A); |
|||
|
|||
this.PlatformBrush = new SolidPattern(color); |
|||
} |
|||
} |
|||
} |
|||
|
|||
@ -1,107 +1,70 @@ |
|||
// -----------------------------------------------------------------------
|
|||
// <copyright file="StreamGeometryImpl.cs" company="Steven Kirk">
|
|||
// Copyright 2014 MIT Licence. See licence.md for more information.
|
|||
// </copyright>
|
|||
// -----------------------------------------------------------------------
|
|||
// Copyright (c) The Perspex Project. All rights reserved.
|
|||
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
|||
|
|||
using System; |
|||
using Perspex.Media; |
|||
using Perspex.Platform; |
|||
using Splat; |
|||
using System.Collections.Generic; |
|||
|
|||
namespace Perspex.Cairo.Media |
|||
{ |
|||
using System; |
|||
using Perspex.Media; |
|||
using Perspex.Platform; |
|||
using Cairo = global::Cairo; |
|||
using Splat; |
|||
using System.Collections.Generic; |
|||
|
|||
public enum CairoGeometryType |
|||
{ |
|||
Begin, |
|||
ArcTo, |
|||
LineTo, |
|||
End |
|||
} |
|||
|
|||
public class BeginOp : GeometryOp |
|||
{ |
|||
public Point Point { get; set; } |
|||
public bool IsFilled { get; set; } |
|||
} |
|||
|
|||
public class EndOp : GeometryOp |
|||
{ |
|||
public bool IsClosed { get; set; } |
|||
} |
|||
|
|||
public class LineToOp : GeometryOp |
|||
{ |
|||
public Point Point { get; set; } |
|||
} |
|||
|
|||
public class CurveToOp : GeometryOp |
|||
{ |
|||
public Point Point { get; set; } |
|||
public Point Point2 { get; set; } |
|||
public Point Point3 { get; set; } |
|||
} |
|||
|
|||
public abstract class GeometryOp |
|||
{ |
|||
} |
|||
|
|||
public class StreamGeometryImpl : IStreamGeometryImpl |
|||
{ |
|||
public StreamGeometryImpl() |
|||
{ |
|||
this.Operations = new Queue<GeometryOp>(); |
|||
_impl = new StreamGeometryContextImpl(null); |
|||
} |
|||
|
|||
public StreamGeometryImpl(Queue<GeometryOp> ops) |
|||
public StreamGeometryImpl(StreamGeometryContextImpl impl) |
|||
{ |
|||
this.Operations = ops; |
|||
} |
|||
|
|||
public Queue<GeometryOp> Operations |
|||
{ |
|||
get; |
|||
private set; |
|||
_impl = impl; |
|||
} |
|||
|
|||
public Rect Bounds |
|||
{ |
|||
get; |
|||
set; |
|||
} |
|||
get { return _impl.Bounds; } |
|||
} |
|||
|
|||
// TODO: Implement
|
|||
private Matrix transform = Matrix.Identity; |
|||
public Cairo.Path Path |
|||
{ |
|||
get { return _impl.Path; } |
|||
} |
|||
|
|||
private readonly StreamGeometryContextImpl _impl; |
|||
|
|||
private Matrix _transform = Matrix.Identity; |
|||
public Matrix Transform |
|||
{ |
|||
get { return this.transform; } |
|||
get { return _transform; } |
|||
set |
|||
{ |
|||
if (value != this.Transform) |
|||
if (value != Transform) |
|||
{ |
|||
if (!value.IsIdentity) |
|||
{ |
|||
this.transform = value; |
|||
} |
|||
if (!value.IsIdentity) |
|||
{ |
|||
_transform = value; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
public IStreamGeometryImpl Clone() |
|||
{ |
|||
return new StreamGeometryImpl(this.Operations); |
|||
{ |
|||
return new StreamGeometryImpl(_impl); |
|||
} |
|||
|
|||
public Rect GetRenderBounds(double strokeThickness) |
|||
{ |
|||
return this.Bounds; |
|||
// TODO: Calculate properly.
|
|||
return Bounds.Inflate(strokeThickness); |
|||
} |
|||
|
|||
public IStreamGeometryContextImpl Open() |
|||
{ |
|||
return new StreamGeometryContextImpl(this); |
|||
return _impl; |
|||
} |
|||
} |
|||
} |
|||
|
|||
@ -0,0 +1,224 @@ |
|||
// Copyright (c) The Perspex Project. All rights reserved.
|
|||
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
|||
|
|||
using System; |
|||
using Cairo; |
|||
using Perspex.Cairo.Media.Imaging; |
|||
using Perspex.Layout; |
|||
using Perspex.Media; |
|||
using Perspex.Platform; |
|||
|
|||
namespace Perspex.Cairo.Media |
|||
{ |
|||
internal static class TileBrushes |
|||
{ |
|||
public static SurfacePattern CreateImageBrush(ImageBrush brush, Size targetSize) |
|||
{ |
|||
if (brush.Source == null) |
|||
{ |
|||
return null; |
|||
} |
|||
|
|||
// TODO: This is directly ported from Direct2D and could probably be made more
|
|||
// efficient on cairo by taking advantage of the fact that cairo has Extend.None.
|
|||
var image = ((BitmapImpl)brush.Source.PlatformImpl).Surface; |
|||
var imageSize = new Size(brush.Source.PixelWidth, brush.Source.PixelHeight); |
|||
var tileMode = brush.TileMode; |
|||
var sourceRect = brush.SourceRect.ToPixels(imageSize); |
|||
var destinationRect = brush.DestinationRect.ToPixels(targetSize); |
|||
var scale = brush.Stretch.CalculateScaling(destinationRect.Size, sourceRect.Size); |
|||
var translate = CalculateTranslate(brush, sourceRect, destinationRect, scale); |
|||
var intermediateSize = CalculateIntermediateSize(tileMode, targetSize, destinationRect.Size); |
|||
|
|||
var intermediate = new ImageSurface (Format.ARGB32, (int)intermediateSize.Width, (int)intermediateSize.Height); |
|||
using (var context = new Context(intermediate)) |
|||
{ |
|||
Rect drawRect; |
|||
var transform = CalculateIntermediateTransform( |
|||
tileMode, |
|||
sourceRect, |
|||
destinationRect, |
|||
scale, |
|||
translate, |
|||
out drawRect); |
|||
context.Rectangle(drawRect.ToCairo()); |
|||
context.Clip(); |
|||
context.Transform(transform.ToCairo()); |
|||
Gdk.CairoHelper.SetSourcePixbuf(context, image, 0, 0); |
|||
context.Rectangle(0, 0, imageSize.Width, imageSize.Height); |
|||
context.Fill(); |
|||
|
|||
var result = new SurfacePattern(intermediate); |
|||
|
|||
if ((brush.TileMode & TileMode.FlipXY) != 0) |
|||
{ |
|||
// TODO: Currently always FlipXY as that's all cairo supports natively.
|
|||
// Support separate FlipX and FlipY by drawing flipped images to intermediate
|
|||
// surface.
|
|||
result.Extend = Extend.Reflect; |
|||
} |
|||
else |
|||
{ |
|||
result.Extend = Extend.Repeat; |
|||
} |
|||
|
|||
if (brush.TileMode != TileMode.None) |
|||
{ |
|||
var matrix = result.Matrix; |
|||
matrix.InitTranslate(-destinationRect.X, -destinationRect.Y); |
|||
result.Matrix = matrix; |
|||
} |
|||
|
|||
return result; |
|||
} |
|||
} |
|||
|
|||
public static SurfacePattern CreateVisualBrush(VisualBrush brush, Size targetSize) |
|||
{ |
|||
var visual = brush.Visual; |
|||
|
|||
if (visual == null) |
|||
{ |
|||
return null; |
|||
} |
|||
|
|||
var layoutable = visual as ILayoutable; |
|||
|
|||
if (layoutable?.IsArrangeValid == false) |
|||
{ |
|||
layoutable.Measure(Size.Infinity); |
|||
layoutable.Arrange(new Rect(layoutable.DesiredSize)); |
|||
} |
|||
|
|||
// TODO: This is directly ported from Direct2D and could probably be made more
|
|||
// efficient on cairo by taking advantage of the fact that cairo has Extend.None.
|
|||
var tileMode = brush.TileMode; |
|||
var sourceRect = brush.SourceRect.ToPixels(layoutable.Bounds.Size); |
|||
var destinationRect = brush.DestinationRect.ToPixels(targetSize); |
|||
var scale = brush.Stretch.CalculateScaling(destinationRect.Size, sourceRect.Size); |
|||
var translate = CalculateTranslate(brush, sourceRect, destinationRect, scale); |
|||
var intermediateSize = CalculateIntermediateSize(tileMode, targetSize, destinationRect.Size); |
|||
|
|||
using (var intermediate = new ImageSurface(Format.ARGB32, (int)intermediateSize.Width, (int)intermediateSize.Height)) |
|||
using (var context = new Context(intermediate)) |
|||
{ |
|||
Rect drawRect; |
|||
var transform = CalculateIntermediateTransform( |
|||
tileMode, |
|||
sourceRect, |
|||
destinationRect, |
|||
scale, |
|||
translate, |
|||
out drawRect); |
|||
var renderer = new Renderer(intermediate); |
|||
|
|||
context.Rectangle(drawRect.ToCairo()); |
|||
context.Clip(); |
|||
context.Transform(transform.ToCairo()); |
|||
renderer.Render(visual, new PlatformHandle(IntPtr.Zero, "RTB"), transform, drawRect); |
|||
|
|||
var result = new SurfacePattern(intermediate); |
|||
|
|||
if ((brush.TileMode & TileMode.FlipXY) != 0) |
|||
{ |
|||
// TODO: Currently always FlipXY as that's all cairo supports natively.
|
|||
// Support separate FlipX and FlipY by drawing flipped images to intermediate
|
|||
// surface.
|
|||
result.Extend = Extend.Reflect; |
|||
} |
|||
else |
|||
{ |
|||
result.Extend = Extend.Repeat; |
|||
} |
|||
|
|||
if (brush.TileMode != TileMode.None) |
|||
{ |
|||
var matrix = result.Matrix; |
|||
matrix.InitTranslate(-destinationRect.X, -destinationRect.Y); |
|||
result.Matrix = matrix; |
|||
} |
|||
|
|||
return result; |
|||
} |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Calculates a translate based on a <see cref="TileBrush"/>, a source and destination
|
|||
/// rectangle and a scale.
|
|||
/// </summary>
|
|||
/// <param name="brush">The brush.</param>
|
|||
/// <param name="sourceRect">The source rectangle.</param>
|
|||
/// <param name="destinationRect">The destination rectangle.</param>
|
|||
/// <param name="scale">The scale factor.</param>
|
|||
/// <returns>A vector with the X and Y translate.</returns>
|
|||
private static Vector CalculateTranslate( |
|||
TileBrush brush, |
|||
Rect sourceRect, |
|||
Rect destinationRect, |
|||
Vector scale) |
|||
{ |
|||
var x = 0.0; |
|||
var y = 0.0; |
|||
var size = sourceRect.Size * scale; |
|||
|
|||
switch (brush.AlignmentX) |
|||
{ |
|||
case AlignmentX.Center: |
|||
x += (destinationRect.Width - size.Width) / 2; |
|||
break; |
|||
case AlignmentX.Right: |
|||
x += destinationRect.Width - size.Width; |
|||
break; |
|||
} |
|||
|
|||
switch (brush.AlignmentY) |
|||
{ |
|||
case AlignmentY.Center: |
|||
y += (destinationRect.Height - size.Height) / 2; |
|||
break; |
|||
case AlignmentY.Bottom: |
|||
y += destinationRect.Height - size.Height; |
|||
break; |
|||
} |
|||
|
|||
return new Vector(x, y); |
|||
} |
|||
|
|||
private static Size CalculateIntermediateSize( |
|||
TileMode tileMode, |
|||
Size targetSize, |
|||
Size destinationSize) |
|||
{ |
|||
var result = tileMode == TileMode.None ? targetSize : destinationSize; |
|||
return result; |
|||
} |
|||
|
|||
private static Matrix CalculateIntermediateTransform( |
|||
TileMode tileMode, |
|||
Rect sourceRect, |
|||
Rect destinationRect, |
|||
Vector scale, |
|||
Vector translate, |
|||
out Rect drawRect) |
|||
{ |
|||
var transform = Matrix.CreateTranslation(-sourceRect.Position) * |
|||
Matrix.CreateScale(scale) * |
|||
Matrix.CreateTranslation(translate); |
|||
Rect dr; |
|||
|
|||
if (tileMode == TileMode.None) |
|||
{ |
|||
dr = destinationRect; |
|||
transform *= Matrix.CreateTranslation(destinationRect.Position); |
|||
} |
|||
else |
|||
{ |
|||
dr = new Rect(destinationRect.Size); |
|||
} |
|||
|
|||
drawRect = dr; |
|||
|
|||
return transform; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,14 @@ |
|||
using System; |
|||
using global::Cairo; |
|||
|
|||
namespace Perspex.Cairo.Media |
|||
{ |
|||
public class VisualBrushImpl : BrushImpl |
|||
{ |
|||
public VisualBrushImpl(Perspex.Media.VisualBrush brush, Size destinationSize) |
|||
{ |
|||
this.PlatformBrush = TileBrushes.CreateVisualBrush(brush, destinationSize); |
|||
} |
|||
} |
|||
} |
|||
|
|||
@ -0,0 +1,11 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<configuration> |
|||
<runtime> |
|||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> |
|||
<dependentAssembly> |
|||
<assemblyIdentity name="Mono.Cairo" publicKeyToken="0738eb9f132ed756" culture="neutral" /> |
|||
<bindingRedirect oldVersion="0.0.0.0-4.0.0.0" newVersion="4.0.0.0" /> |
|||
</dependentAssembly> |
|||
</assemblyBinding> |
|||
</runtime> |
|||
</configuration> |
|||
@ -1,48 +0,0 @@ |
|||
// -----------------------------------------------------------------------
|
|||
// <copyright file="AssetLoader.cs" company="Steven Kirk">
|
|||
// Copyright 2015 MIT Licence. See licence.md for more information.
|
|||
// </copyright>
|
|||
// -----------------------------------------------------------------------
|
|||
|
|||
namespace Perspex.Gtk |
|||
{ |
|||
using System; |
|||
using System.Globalization; |
|||
using System.IO; |
|||
using System.Reflection; |
|||
using System.Resources; |
|||
using Perspex.Platform; |
|||
|
|||
/// <summary>
|
|||
/// Loads assets compiled into the application binary.
|
|||
/// </summary>
|
|||
public class AssetLoader : IAssetLoader |
|||
{ |
|||
/// <summary>
|
|||
/// Opens the resource with the requested URI.
|
|||
/// </summary>
|
|||
/// <param name="uri">The URI.</param>
|
|||
/// <returns>A stream containing the resource contents.</returns>
|
|||
/// <exception cref="FileNotFoundException">
|
|||
/// The resource was not found.
|
|||
/// </exception>
|
|||
public Stream Open(Uri uri) |
|||
{ |
|||
var assembly = Assembly.GetEntryAssembly(); |
|||
var resourceName = assembly.GetName().Name + ".g"; |
|||
var manager = new ResourceManager(resourceName, assembly); |
|||
|
|||
using (var resourceSet = manager.GetResourceSet(CultureInfo.CurrentCulture, true, true)) |
|||
{ |
|||
var stream = (Stream)resourceSet.GetObject(uri.ToString(), true); |
|||
|
|||
if (stream == null) |
|||
{ |
|||
throw new FileNotFoundException($"The requested asset could not be found: {uri}"); |
|||
} |
|||
|
|||
return stream; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,42 @@ |
|||
// Copyright (c) The Perspex Project. All rights reserved.
|
|||
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
|||
|
|||
using System; |
|||
using System.Threading.Tasks; |
|||
using Gdk; |
|||
using Perspex.Input.Platform; |
|||
|
|||
namespace Perspex.Gtk |
|||
{ |
|||
using Gtk = global::Gtk; |
|||
|
|||
internal class ClipboardImpl : IClipboard |
|||
{ |
|||
private static Gtk.Clipboard GetClipboard() => Gtk.Clipboard.GetForDisplay(Display.Default, new Atom(IntPtr.Zero)); |
|||
|
|||
public Task<string> GetTextAsync() |
|||
{ |
|||
var clip = GetClipboard(); |
|||
var tcs = new TaskCompletionSource<string>(); |
|||
clip.RequestText((_, text) => |
|||
{ |
|||
tcs.TrySetResult(text); |
|||
}); |
|||
return tcs.Task; |
|||
} |
|||
|
|||
public Task SetTextAsync(string text) |
|||
{ |
|||
using (var cl = GetClipboard()) |
|||
cl.Text = text; |
|||
return Task.FromResult(0); |
|||
} |
|||
|
|||
public Task ClearAsync() |
|||
{ |
|||
using (var cl = GetClipboard()) |
|||
cl.Clear(); |
|||
return Task.FromResult(0); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,77 @@ |
|||
// Copyright (c) The Perspex Project. All rights reserved.
|
|||
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
|||
|
|||
using System.Collections.Generic; |
|||
using Gdk; |
|||
using Perspex.Input; |
|||
using Perspex.Platform; |
|||
|
|||
namespace Perspex.Gtk |
|||
{ |
|||
using Gtk = global::Gtk; |
|||
|
|||
internal class CursorFactory : IStandardCursorFactory |
|||
{ |
|||
public static CursorFactory Instance { get; } = new CursorFactory(); |
|||
|
|||
private CursorFactory() |
|||
{ |
|||
} |
|||
|
|||
private static readonly Dictionary<StandardCursorType, object> CursorTypeMapping = new Dictionary |
|||
<StandardCursorType, object> |
|||
{ |
|||
{ StandardCursorType.AppStarting, CursorType.Watch }, |
|||
{ StandardCursorType.Arrow, CursorType.LeftPtr }, |
|||
{ StandardCursorType.Cross, CursorType.Cross }, |
|||
{ StandardCursorType.Hand, CursorType.Hand1 }, |
|||
{ StandardCursorType.Ibeam, CursorType.Xterm }, |
|||
{ StandardCursorType.No, Gtk.Stock.Cancel}, |
|||
{ StandardCursorType.SizeAll, CursorType.Sizing }, |
|||
//{ StandardCursorType.SizeNorthEastSouthWest, 32643 },
|
|||
{ StandardCursorType.SizeNorthSouth, CursorType.SbVDoubleArrow}, |
|||
//{ StandardCursorType.SizeNorthWestSouthEast, 32642 },
|
|||
{ StandardCursorType.SizeWestEast, CursorType.SbHDoubleArrow }, |
|||
{ StandardCursorType.UpArrow, CursorType.BasedArrowUp }, |
|||
{ StandardCursorType.Wait, CursorType.Watch }, |
|||
{ StandardCursorType.Help, Gtk.Stock.Help } |
|||
}; |
|||
|
|||
private static readonly Dictionary<StandardCursorType, IPlatformHandle> Cache = |
|||
new Dictionary<StandardCursorType, IPlatformHandle>(); |
|||
|
|||
private Gdk.Cursor GetCursor(object desc) |
|||
{ |
|||
Gdk.Cursor rv; |
|||
var name = desc as string; |
|||
if (name != null) |
|||
{ |
|||
var theme = Gtk.IconTheme.Default; |
|||
var icon = theme.LoadIcon(name, 32, default(Gtk.IconLookupFlags)); |
|||
rv = icon == null ? new Gdk.Cursor(CursorType.XCursor) : new Gdk.Cursor(Display.Default, icon, 0, 0); |
|||
} |
|||
else |
|||
{ |
|||
rv = new Gdk.Cursor((CursorType)desc); |
|||
} |
|||
|
|||
rv.Owned = false; |
|||
return rv; |
|||
} |
|||
|
|||
public IPlatformHandle GetCursor(StandardCursorType cursorType) |
|||
{ |
|||
IPlatformHandle rv; |
|||
if (!Cache.TryGetValue(cursorType, out rv)) |
|||
{ |
|||
Cache[cursorType] = |
|||
rv = |
|||
new PlatformHandle( |
|||
GetCursor(CursorTypeMapping[cursorType]).Handle, |
|||
"GTKCURSOR"); |
|||
} |
|||
|
|||
return rv; |
|||
} |
|||
} |
|||
} |
|||
@ -1,62 +1,225 @@ |
|||
// -----------------------------------------------------------------------
|
|||
// <copyright file="GtkKeyboardDevice.cs" company="Steven Kirk">
|
|||
// Copyright 2014 MIT Licence. See licence.md for more information.
|
|||
// </copyright>
|
|||
// -----------------------------------------------------------------------
|
|||
// Copyright (c) The Perspex Project. All rights reserved.
|
|||
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
|||
|
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Reflection; |
|||
using System.Text; |
|||
using Perspex.Input; |
|||
|
|||
namespace Perspex.Gtk |
|||
{ |
|||
using System; |
|||
using Perspex.Input; |
|||
|
|||
public class GtkKeyboardDevice : KeyboardDevice |
|||
{ |
|||
private static GtkKeyboardDevice instance; |
|||
|
|||
static GtkKeyboardDevice() |
|||
private static readonly Dictionary<Gdk.Key, Key> KeyDic = new Dictionary<Gdk.Key, Key> |
|||
{ |
|||
instance = new GtkKeyboardDevice(); |
|||
} |
|||
{ Gdk.Key.Cancel, Key.Cancel }, |
|||
{ Gdk.Key.BackSpace, Key.Back }, |
|||
{ Gdk.Key.Tab, Key.Tab }, |
|||
{ Gdk.Key.Linefeed, Key.LineFeed }, |
|||
{ Gdk.Key.Clear, Key.Clear }, |
|||
{ Gdk.Key.Return, Key.Return }, |
|||
{ Gdk.Key.Pause, Key.Pause }, |
|||
//{ Gdk.Key.?, Key.CapsLock }
|
|||
//{ Gdk.Key.?, Key.HangulMode }
|
|||
//{ Gdk.Key.?, Key.JunjaMode }
|
|||
//{ Gdk.Key.?, Key.FinalMode }
|
|||
//{ Gdk.Key.?, Key.KanjiMode }
|
|||
{ Gdk.Key.Escape, Key.Escape }, |
|||
//{ Gdk.Key.?, Key.ImeConvert }
|
|||
//{ Gdk.Key.?, Key.ImeNonConvert }
|
|||
//{ Gdk.Key.?, Key.ImeAccept }
|
|||
//{ Gdk.Key.?, Key.ImeModeChange }
|
|||
{ Gdk.Key.space, Key.Space }, |
|||
{ Gdk.Key.Prior, Key.Prior }, |
|||
//{ Gdk.Key.?, Key.PageDown }
|
|||
{ Gdk.Key.End, Key.End }, |
|||
{ Gdk.Key.Home, Key.Home }, |
|||
{ Gdk.Key.Left, Key.Left }, |
|||
{ Gdk.Key.Up, Key.Up }, |
|||
{ Gdk.Key.Right, Key.Right }, |
|||
{ Gdk.Key.Down, Key.Down }, |
|||
{ Gdk.Key.Select, Key.Select }, |
|||
{ Gdk.Key.Print, Key.Print }, |
|||
{ Gdk.Key.Execute, Key.Execute }, |
|||
//{ Gdk.Key.?, Key.Snapshot }
|
|||
{ Gdk.Key.Insert, Key.Insert }, |
|||
{ Gdk.Key.Delete, Key.Delete }, |
|||
{ Gdk.Key.Help, Key.Help }, |
|||
//{ Gdk.Key.?, Key.D0 }
|
|||
//{ Gdk.Key.?, Key.D1 }
|
|||
//{ Gdk.Key.?, Key.D2 }
|
|||
//{ Gdk.Key.?, Key.D3 }
|
|||
//{ Gdk.Key.?, Key.D4 }
|
|||
//{ Gdk.Key.?, Key.D5 }
|
|||
//{ Gdk.Key.?, Key.D6 }
|
|||
//{ Gdk.Key.?, Key.D7 }
|
|||
//{ Gdk.Key.?, Key.D8 }
|
|||
//{ Gdk.Key.?, Key.D9 }
|
|||
{ Gdk.Key.A, Key.A }, |
|||
{ Gdk.Key.B, Key.B }, |
|||
{ Gdk.Key.C, Key.C }, |
|||
{ Gdk.Key.D, Key.D }, |
|||
{ Gdk.Key.E, Key.E }, |
|||
{ Gdk.Key.F, Key.F }, |
|||
{ Gdk.Key.G, Key.G }, |
|||
{ Gdk.Key.H, Key.H }, |
|||
{ Gdk.Key.I, Key.I }, |
|||
{ Gdk.Key.J, Key.J }, |
|||
{ Gdk.Key.K, Key.K }, |
|||
{ Gdk.Key.L, Key.L }, |
|||
{ Gdk.Key.M, Key.M }, |
|||
{ Gdk.Key.N, Key.N }, |
|||
{ Gdk.Key.O, Key.O }, |
|||
{ Gdk.Key.P, Key.P }, |
|||
{ Gdk.Key.Q, Key.Q }, |
|||
{ Gdk.Key.R, Key.R }, |
|||
{ Gdk.Key.S, Key.S }, |
|||
{ Gdk.Key.T, Key.T }, |
|||
{ Gdk.Key.U, Key.U }, |
|||
{ Gdk.Key.V, Key.V }, |
|||
{ Gdk.Key.W, Key.W }, |
|||
{ Gdk.Key.X, Key.X }, |
|||
{ Gdk.Key.Y, Key.Y }, |
|||
{ Gdk.Key.Z, Key.Z }, |
|||
{ Gdk.Key.a, Key.A }, |
|||
{ Gdk.Key.b, Key.B }, |
|||
{ Gdk.Key.c, Key.C }, |
|||
{ Gdk.Key.d, Key.D }, |
|||
{ Gdk.Key.e, Key.E }, |
|||
{ Gdk.Key.f, Key.F }, |
|||
{ Gdk.Key.g, Key.G }, |
|||
{ Gdk.Key.h, Key.H }, |
|||
{ Gdk.Key.i, Key.I }, |
|||
{ Gdk.Key.j, Key.J }, |
|||
{ Gdk.Key.k, Key.K }, |
|||
{ Gdk.Key.l, Key.L }, |
|||
{ Gdk.Key.m, Key.M }, |
|||
{ Gdk.Key.n, Key.N }, |
|||
{ Gdk.Key.o, Key.O }, |
|||
{ Gdk.Key.p, Key.P }, |
|||
{ Gdk.Key.q, Key.Q }, |
|||
{ Gdk.Key.r, Key.R }, |
|||
{ Gdk.Key.s, Key.S }, |
|||
{ Gdk.Key.t, Key.T }, |
|||
{ Gdk.Key.u, Key.U }, |
|||
{ Gdk.Key.v, Key.V }, |
|||
{ Gdk.Key.w, Key.W }, |
|||
{ Gdk.Key.x, Key.X }, |
|||
{ Gdk.Key.y, Key.Y }, |
|||
{ Gdk.Key.z, Key.Z }, |
|||
//{ Gdk.Key.?, Key.LWin }
|
|||
//{ Gdk.Key.?, Key.RWin }
|
|||
//{ Gdk.Key.?, Key.Apps }
|
|||
//{ Gdk.Key.?, Key.Sleep }
|
|||
//{ Gdk.Key.?, Key.NumPad0 }
|
|||
//{ Gdk.Key.?, Key.NumPad1 }
|
|||
//{ Gdk.Key.?, Key.NumPad2 }
|
|||
//{ Gdk.Key.?, Key.NumPad3 }
|
|||
//{ Gdk.Key.?, Key.NumPad4 }
|
|||
//{ Gdk.Key.?, Key.NumPad5 }
|
|||
//{ Gdk.Key.?, Key.NumPad6 }
|
|||
//{ Gdk.Key.?, Key.NumPad7 }
|
|||
//{ Gdk.Key.?, Key.NumPad8 }
|
|||
//{ Gdk.Key.?, Key.NumPad9 }
|
|||
{ Gdk.Key.multiply, Key.Multiply }, |
|||
//{ Gdk.Key.?, Key.Add }
|
|||
//{ Gdk.Key.?, Key.Separator }
|
|||
//{ Gdk.Key.?, Key.Subtract }
|
|||
//{ Gdk.Key.?, Key.Decimal }
|
|||
//{ Gdk.Key.?, Key.Divide }
|
|||
{ Gdk.Key.F1, Key.F1 }, |
|||
{ Gdk.Key.F2, Key.F2 }, |
|||
{ Gdk.Key.F3, Key.F3 }, |
|||
{ Gdk.Key.F4, Key.F4 }, |
|||
{ Gdk.Key.F5, Key.F5 }, |
|||
{ Gdk.Key.F6, Key.F6 }, |
|||
{ Gdk.Key.F7, Key.F7 }, |
|||
{ Gdk.Key.F8, Key.F8 }, |
|||
{ Gdk.Key.F9, Key.F9 }, |
|||
{ Gdk.Key.F10, Key.F10 }, |
|||
{ Gdk.Key.F11, Key.F11 }, |
|||
{ Gdk.Key.F12, Key.F12 }, |
|||
{ Gdk.Key.L3, Key.F13 }, |
|||
{ Gdk.Key.F14, Key.F14 }, |
|||
{ Gdk.Key.L5, Key.F15 }, |
|||
{ Gdk.Key.F16, Key.F16 }, |
|||
{ Gdk.Key.F17, Key.F17 }, |
|||
{ Gdk.Key.L8, Key.F18 }, |
|||
{ Gdk.Key.L9, Key.F19 }, |
|||
{ Gdk.Key.L10, Key.F20 }, |
|||
{ Gdk.Key.R1, Key.F21 }, |
|||
{ Gdk.Key.R2, Key.F22 }, |
|||
{ Gdk.Key.F23, Key.F23 }, |
|||
{ Gdk.Key.R4, Key.F24 }, |
|||
//{ Gdk.Key.?, Key.NumLock }
|
|||
//{ Gdk.Key.?, Key.Scroll }
|
|||
//{ Gdk.Key.?, Key.LeftShift }
|
|||
//{ Gdk.Key.?, Key.RightShift }
|
|||
//{ Gdk.Key.?, Key.LeftCtrl }
|
|||
//{ Gdk.Key.?, Key.RightCtrl }
|
|||
//{ Gdk.Key.?, Key.LeftAlt }
|
|||
//{ Gdk.Key.?, Key.RightAlt }
|
|||
//{ Gdk.Key.?, Key.BrowserBack }
|
|||
//{ Gdk.Key.?, Key.BrowserForward }
|
|||
//{ Gdk.Key.?, Key.BrowserRefresh }
|
|||
//{ Gdk.Key.?, Key.BrowserStop }
|
|||
//{ Gdk.Key.?, Key.BrowserSearch }
|
|||
//{ Gdk.Key.?, Key.BrowserFavorites }
|
|||
//{ Gdk.Key.?, Key.BrowserHome }
|
|||
//{ Gdk.Key.?, Key.VolumeMute }
|
|||
//{ Gdk.Key.?, Key.VolumeDown }
|
|||
//{ Gdk.Key.?, Key.VolumeUp }
|
|||
//{ Gdk.Key.?, Key.MediaNextTrack }
|
|||
//{ Gdk.Key.?, Key.MediaPreviousTrack }
|
|||
//{ Gdk.Key.?, Key.MediaStop }
|
|||
//{ Gdk.Key.?, Key.MediaPlayPause }
|
|||
//{ Gdk.Key.?, Key.LaunchMail }
|
|||
//{ Gdk.Key.?, Key.SelectMedia }
|
|||
//{ Gdk.Key.?, Key.LaunchApplication1 }
|
|||
//{ Gdk.Key.?, Key.LaunchApplication2 }
|
|||
//{ Gdk.Key.?, Key.OemSemicolon }
|
|||
//{ Gdk.Key.?, Key.OemPlus }
|
|||
//{ Gdk.Key.?, Key.OemComma }
|
|||
//{ Gdk.Key.?, Key.OemMinus }
|
|||
//{ Gdk.Key.?, Key.OemPeriod }
|
|||
//{ Gdk.Key.?, Key.Oem2 }
|
|||
//{ Gdk.Key.?, Key.OemTilde }
|
|||
//{ Gdk.Key.?, Key.AbntC1 }
|
|||
//{ Gdk.Key.?, Key.AbntC2 }
|
|||
//{ Gdk.Key.?, Key.Oem4 }
|
|||
//{ Gdk.Key.?, Key.OemPipe }
|
|||
//{ Gdk.Key.?, Key.OemCloseBrackets }
|
|||
//{ Gdk.Key.?, Key.Oem7 }
|
|||
//{ Gdk.Key.?, Key.Oem8 }
|
|||
//{ Gdk.Key.?, Key.Oem102 }
|
|||
//{ Gdk.Key.?, Key.ImeProcessed }
|
|||
//{ Gdk.Key.?, Key.System }
|
|||
//{ Gdk.Key.?, Key.OemAttn }
|
|||
//{ Gdk.Key.?, Key.OemFinish }
|
|||
//{ Gdk.Key.?, Key.DbeHiragana }
|
|||
//{ Gdk.Key.?, Key.OemAuto }
|
|||
//{ Gdk.Key.?, Key.DbeDbcsChar }
|
|||
//{ Gdk.Key.?, Key.OemBackTab }
|
|||
//{ Gdk.Key.?, Key.Attn }
|
|||
//{ Gdk.Key.?, Key.DbeEnterWordRegisterMode }
|
|||
//{ Gdk.Key.?, Key.DbeEnterImeConfigureMode }
|
|||
//{ Gdk.Key.?, Key.EraseEof }
|
|||
//{ Gdk.Key.?, Key.Play }
|
|||
//{ Gdk.Key.?, Key.Zoom }
|
|||
//{ Gdk.Key.?, Key.NoName }
|
|||
//{ Gdk.Key.?, Key.DbeEnterDialogConversionMode }
|
|||
//{ Gdk.Key.?, Key.OemClear }
|
|||
//{ Gdk.Key.?, Key.DeadCharProcessed }
|
|||
}; |
|||
|
|||
private GtkKeyboardDevice() |
|||
{ |
|||
} |
|||
public static GtkKeyboardDevice Instance { get; } = new GtkKeyboardDevice(); |
|||
|
|||
public static new GtkKeyboardDevice Instance |
|||
public static Key ConvertKey(Gdk.Key key) |
|||
{ |
|||
get { return instance; } |
|||
} |
|||
|
|||
public override ModifierKeys Modifiers |
|||
{ |
|||
get |
|||
{ |
|||
// TODO: Implement.
|
|||
return ModifierKeys.None; |
|||
} |
|||
} |
|||
|
|||
public static Perspex.Input.Key ConvertKey(Gdk.Key key) |
|||
{ |
|||
// TODO: Don't use reflection for this! My eyes!!!
|
|||
if (key == Gdk.Key.BackSpace) |
|||
{ |
|||
return Perspex.Input.Key.Back; |
|||
} |
|||
else |
|||
{ |
|||
var s = Enum.GetName(typeof(Gdk.Key), key); |
|||
Perspex.Input.Key result; |
|||
|
|||
if (Enum.TryParse(s, true, out result)) |
|||
{ |
|||
return result; |
|||
} |
|||
else |
|||
{ |
|||
return Perspex.Input.Key.None; |
|||
} |
|||
} |
|||
Key result; |
|||
return KeyDic.TryGetValue(key, out result) ? result : Key.None; |
|||
} |
|||
} |
|||
} |
|||
@ -1,35 +1,29 @@ |
|||
// -----------------------------------------------------------------------
|
|||
// <copyright file="GtkMouseDevice.cs" company="Steven Kirk">
|
|||
// Copyright 2014 MIT Licence. See licence.md for more information.
|
|||
// </copyright>
|
|||
// -----------------------------------------------------------------------
|
|||
// Copyright (c) The Perspex Project. All rights reserved.
|
|||
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
|||
|
|||
using Perspex.Input; |
|||
namespace Perspex.Gtk |
|||
{ |
|||
using Perspex.Input; |
|||
|
|||
public class GtkMouseDevice : MouseDevice |
|||
{ |
|||
private static GtkMouseDevice instance; |
|||
private static readonly GtkMouseDevice s_instance; |
|||
|
|||
private Point clientPosition; |
|||
private Point _clientPosition; |
|||
|
|||
static GtkMouseDevice() |
|||
{ |
|||
instance = new GtkMouseDevice(); |
|||
s_instance = new GtkMouseDevice(); |
|||
} |
|||
|
|||
private GtkMouseDevice() |
|||
{ |
|||
} |
|||
|
|||
public static new GtkMouseDevice Instance |
|||
{ |
|||
get { return instance; } |
|||
} |
|||
public static new GtkMouseDevice Instance => s_instance; |
|||
|
|||
internal void SetClientPosition(Point p) |
|||
{ |
|||
this.clientPosition = p; |
|||
_clientPosition = p; |
|||
} |
|||
} |
|||
} |
|||
@ -1,25 +1,21 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Text; |
|||
using System.Threading.Tasks; |
|||
// Copyright (c) The Perspex Project. All rights reserved.
|
|||
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
|||
|
|||
using Gtk; |
|||
using Perspex.Platform; |
|||
|
|||
namespace Perspex.Gtk |
|||
{ |
|||
using System; |
|||
using Perspex.Platform; |
|||
using global::Gtk; |
|||
|
|||
public class PopupImpl : WindowImpl, IPopupImpl |
|||
{ |
|||
public PopupImpl() |
|||
: base(WindowType.Popup) |
|||
{ |
|||
{ |
|||
} |
|||
|
|||
|
|||
public void SetPosition(Point p) |
|||
{ |
|||
this.Move((int)p.X, (int)p.Y); |
|||
Move((int)p.X, (int)p.Y); |
|||
} |
|||
} |
|||
} |
|||
|
|||
@ -0,0 +1,57 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Text; |
|||
using System.Threading.Tasks; |
|||
using Perspex.Controls; |
|||
using Perspex.Controls.Platform; |
|||
using Perspex.Platform; |
|||
|
|||
namespace Perspex.Gtk |
|||
{ |
|||
using global::Gtk; |
|||
class SystemDialogImpl : ISystemDialogImpl |
|||
{ |
|||
public Task<string[]> ShowFileDialogAsync(FileDialog dialog, IWindowImpl parent) |
|||
{ |
|||
var tcs = new TaskCompletionSource<string[]>(); |
|||
var dlg = new global::Gtk.FileChooserDialog(dialog.Title, ((WindowImpl) parent), |
|||
dialog is OpenFileDialog |
|||
? FileChooserAction.Open |
|||
: FileChooserAction.Save, |
|||
"Cancel", ResponseType.Cancel, |
|||
"Open", ResponseType.Accept) |
|||
{ |
|||
SelectMultiple = (dialog as OpenFileDialog)?.AllowMultiple ?? false, |
|||
}; |
|||
foreach (var filter in dialog.Filters) |
|||
{ |
|||
var ffilter = new FileFilter() |
|||
{ |
|||
Name = filter.Name + " (" + string.Join(";", filter.Extensions.Select(e => "*." + e)) + ")" |
|||
}; |
|||
foreach (var ext in filter.Extensions) |
|||
ffilter.AddPattern("*." + ext); |
|||
dlg.AddFilter(ffilter); |
|||
} |
|||
dlg.SetFilename(dialog.InitialFileName); |
|||
dlg.Modal = true; |
|||
|
|||
dlg.Response += (_, args) => |
|||
{ |
|||
if (args.ResponseId == ResponseType.Accept) |
|||
tcs.TrySetResult(dlg.Filenames); |
|||
dlg.Hide(); |
|||
dlg.Dispose(); |
|||
}; |
|||
|
|||
dlg.Close += delegate |
|||
{ |
|||
tcs.TrySetResult(null); |
|||
dlg.Dispose(); |
|||
}; |
|||
dlg.Show(); |
|||
return tcs.Task; |
|||
} |
|||
} |
|||
} |
|||
@ -1,44 +1,41 @@ |
|||
// -----------------------------------------------------------------------
|
|||
// <copyright file="PerspexObjectAssembler.cs" company="Steven Kirk">
|
|||
// Copyright 2015 MIT Licence. See licence.md for more information.
|
|||
// </copyright>
|
|||
// -----------------------------------------------------------------------
|
|||
// Copyright (c) The Perspex Project. All rights reserved.
|
|||
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
|||
|
|||
using System; |
|||
using OmniXaml; |
|||
using OmniXaml.ObjectAssembler; |
|||
using Perspex.Markup.Xaml.Templates; |
|||
|
|||
namespace Perspex.Markup.Xaml.Context |
|||
{ |
|||
using System; |
|||
using OmniXaml; |
|||
using OmniXaml.ObjectAssembler; |
|||
using Templates; |
|||
|
|||
public class PerspexObjectAssembler : IObjectAssembler |
|||
{ |
|||
private readonly TemplateHostingObjectAssembler objectAssembler; |
|||
private readonly TemplateHostingObjectAssembler _objectAssembler; |
|||
|
|||
public PerspexObjectAssembler(IWiringContext wiringContext, ObjectAssemblerSettings objectAssemblerSettings = null) |
|||
{ |
|||
var mapping = new DeferredLoaderMapping(); |
|||
mapping.Map<XamlDataTemplate>(template => template.Content, new TemplateLoader()); |
|||
|
|||
var assembler = new ObjectAssembler(wiringContext, new TopDownMemberValueContext(), objectAssemblerSettings); |
|||
this.objectAssembler = new TemplateHostingObjectAssembler(assembler, mapping); |
|||
var assembler = new ObjectAssembler(wiringContext, new TopDownValueContext(), objectAssemblerSettings); |
|||
_objectAssembler = new TemplateHostingObjectAssembler(assembler, mapping); |
|||
} |
|||
|
|||
|
|||
public object Result => this.objectAssembler.Result; |
|||
public object Result => _objectAssembler.Result; |
|||
|
|||
public EventHandler<XamlSetValueEventArgs> XamlSetValueHandler { get; set; } |
|||
|
|||
public IWiringContext WiringContext => this.objectAssembler.WiringContext; |
|||
public IWiringContext WiringContext => _objectAssembler.WiringContext; |
|||
|
|||
public void Process(XamlInstruction node) |
|||
{ |
|||
this.objectAssembler.Process(node); |
|||
_objectAssembler.Process(node); |
|||
} |
|||
|
|||
public void OverrideInstance(object instance) |
|||
{ |
|||
this.objectAssembler.OverrideInstance(instance); |
|||
_objectAssembler.OverrideInstance(instance); |
|||
} |
|||
} |
|||
} |
|||
@ -1,35 +1,32 @@ |
|||
// -----------------------------------------------------------------------
|
|||
// <copyright file="PerspexTypeRepository.cs" company="Steven Kirk">
|
|||
// Copyright 2015 MIT Licence. See licence.md for more information.
|
|||
// </copyright>
|
|||
// -----------------------------------------------------------------------
|
|||
// Copyright (c) The Perspex Project. All rights reserved.
|
|||
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
|||
|
|||
using System; |
|||
using Glass; |
|||
using OmniXaml; |
|||
using OmniXaml.Typing; |
|||
using Perspex.Markup.Xaml.DataBinding; |
|||
|
|||
namespace Perspex.Markup.Xaml.Context |
|||
{ |
|||
using System; |
|||
using DataBinding; |
|||
using Glass; |
|||
using OmniXaml; |
|||
using OmniXaml.Typing; |
|||
|
|||
public class PerspexTypeRepository : XamlTypeRepository |
|||
{ |
|||
private readonly ITypeFactory typeFactory; |
|||
private readonly IPerspexPropertyBinder propertyBinder; |
|||
private readonly ITypeFactory _typeFactory; |
|||
private readonly IPerspexPropertyBinder _propertyBinder; |
|||
|
|||
public PerspexTypeRepository(IXamlNamespaceRegistry xamlNamespaceRegistry, |
|||
ITypeFactory typeFactory, |
|||
ITypeFeatureProvider featureProvider, |
|||
IPerspexPropertyBinder propertyBinder) : base(xamlNamespaceRegistry, typeFactory, featureProvider) |
|||
{ |
|||
this.typeFactory = typeFactory; |
|||
this.propertyBinder = propertyBinder; |
|||
_typeFactory = typeFactory; |
|||
_propertyBinder = propertyBinder; |
|||
} |
|||
|
|||
public override XamlType GetXamlType(Type type) |
|||
{ |
|||
Guard.ThrowIfNull(type, nameof(type)); |
|||
return new PerspexXamlType(type, this, this.typeFactory, this.FeatureProvider, this.propertyBinder); |
|||
return new PerspexXamlType(type, this, _typeFactory, FeatureProvider, _propertyBinder); |
|||
} |
|||
} |
|||
} |
|||
@ -1,37 +0,0 @@ |
|||
// -----------------------------------------------------------------------
|
|||
// <copyright file="BitmapConverter.cs" company="Steven Kirk">
|
|||
// Copyright 2015 MIT Licence. See licence.md for more information.
|
|||
// </copyright>
|
|||
// -----------------------------------------------------------------------
|
|||
|
|||
namespace Perspex.Markup.Xaml.Converters |
|||
{ |
|||
using System; |
|||
using System.Globalization; |
|||
using Media.Imaging; |
|||
using OmniXaml.TypeConversion; |
|||
|
|||
public class BitmapConverter : ITypeConverter |
|||
{ |
|||
public bool CanConvertFrom(IXamlTypeConverterContext context, Type sourceType) |
|||
{ |
|||
return true; |
|||
} |
|||
|
|||
public bool CanConvertTo(IXamlTypeConverterContext context, Type destinationType) |
|||
{ |
|||
return true; |
|||
} |
|||
|
|||
public object ConvertFrom(IXamlTypeConverterContext context, CultureInfo culture, object value) |
|||
{ |
|||
var path = (string)value; |
|||
return new Bitmap(path); |
|||
} |
|||
|
|||
public object ConvertTo(IXamlTypeConverterContext context, CultureInfo culture, object value, Type destinationType) |
|||
{ |
|||
return new Bitmap(10, 10); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,33 @@ |
|||
// Copyright (c) The Perspex Project. All rights reserved.
|
|||
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
|||
|
|||
using System; |
|||
using System.Globalization; |
|||
using OmniXaml.TypeConversion; |
|||
using Perspex.Media.Imaging; |
|||
|
|||
namespace Perspex.Markup.Xaml.Converters |
|||
{ |
|||
public class BitmapTypeConverter : ITypeConverter |
|||
{ |
|||
public bool CanConvertFrom(IXamlTypeConverterContext context, Type sourceType) |
|||
{ |
|||
return sourceType == typeof(string); |
|||
} |
|||
|
|||
public bool CanConvertTo(IXamlTypeConverterContext context, Type destinationType) |
|||
{ |
|||
return false; |
|||
} |
|||
|
|||
public object ConvertFrom(IXamlTypeConverterContext context, CultureInfo culture, object value) |
|||
{ |
|||
return new Bitmap((string)value); |
|||
} |
|||
|
|||
public object ConvertTo(IXamlTypeConverterContext context, CultureInfo culture, object value, Type destinationType) |
|||
{ |
|||
throw new NotImplementedException(); |
|||
} |
|||
} |
|||
} |
|||
@ -1,89 +0,0 @@ |
|||
// -----------------------------------------------------------------------
|
|||
// <copyright file="BrushConverter.cs" company="Steven Kirk">
|
|||
// Copyright 2015 MIT Licence. See licence.md for more information.
|
|||
// </copyright>
|
|||
// -----------------------------------------------------------------------
|
|||
|
|||
namespace Perspex.Markup.Xaml.Converters |
|||
{ |
|||
using System; |
|||
using System.Globalization; |
|||
using System.Text; |
|||
using Media; |
|||
using Media.Imaging; |
|||
using OmniXaml.TypeConversion; |
|||
using Platform; |
|||
|
|||
public class BrushConverter : ITypeConverter |
|||
{ |
|||
public bool CanConvertFrom(IXamlTypeConverterContext context, Type sourceType) |
|||
{ |
|||
return true; |
|||
} |
|||
|
|||
public bool CanConvertTo(IXamlTypeConverterContext context, Type destinationType) |
|||
{ |
|||
return true; |
|||
} |
|||
|
|||
public object ConvertFrom(IXamlTypeConverterContext context, CultureInfo culture, object value) |
|||
{ |
|||
var colorString = (string)value; |
|||
|
|||
var color = DecodeColor(colorString); |
|||
|
|||
return new SolidColorBrush(color); |
|||
} |
|||
|
|||
private static Color DecodeColor(string colorString) |
|||
{ |
|||
if (colorString[0] == '#') |
|||
{ |
|||
var restOfValue = colorString.Remove(0, 1); |
|||
|
|||
if (restOfValue.Length == 8) |
|||
{ |
|||
var a = Convert.ToByte(restOfValue.Substring(0, 2), 16); |
|||
var r = Convert.ToByte(restOfValue.Substring(2, 2), 16); |
|||
var g = Convert.ToByte(restOfValue.Substring(6, 2), 16); |
|||
var b = Convert.ToByte(restOfValue.Substring(8, 2), 16); |
|||
return Color.FromArgb(a, r, g, b); |
|||
} |
|||
if (restOfValue.Length == 6) |
|||
{ |
|||
var r = Convert.ToByte(restOfValue.Substring(0, 2), 16); |
|||
var g = Convert.ToByte(restOfValue.Substring(2, 2), 16); |
|||
var b = Convert.ToByte(restOfValue.Substring(4, 2), 16); |
|||
return Color.FromRgb(r, g, b); |
|||
} |
|||
|
|||
throw new InvalidOperationException("The color code format cannot be parsed"); |
|||
} |
|||
else |
|||
{ |
|||
return DecodeFromNamedColor(colorString); |
|||
} |
|||
|
|||
throw new InvalidOperationException($"The color cannot be decoded from the string \"{colorString}\""); |
|||
} |
|||
|
|||
private static Color DecodeFromNamedColor(string colorString) |
|||
{ |
|||
if (colorString == "Crimson") |
|||
{ |
|||
return DecodeColor("#DC143C"); |
|||
} |
|||
if (colorString == "Coral") |
|||
{ |
|||
return DecodeColor("#FF7F50"); |
|||
} |
|||
|
|||
throw new NotImplementedException(); |
|||
} |
|||
|
|||
public object ConvertTo(IXamlTypeConverterContext context, CultureInfo culture, object value, Type destinationType) |
|||
{ |
|||
throw new NotImplementedException(); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,33 @@ |
|||
// Copyright (c) The Perspex Project. All rights reserved.
|
|||
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
|||
|
|||
using System; |
|||
using System.Globalization; |
|||
using OmniXaml.TypeConversion; |
|||
using Perspex.Media; |
|||
|
|||
namespace Perspex.Markup.Xaml.Converters |
|||
{ |
|||
public class BrushTypeConverter : ITypeConverter |
|||
{ |
|||
public bool CanConvertFrom(IXamlTypeConverterContext context, Type sourceType) |
|||
{ |
|||
return sourceType == typeof(string); |
|||
} |
|||
|
|||
public bool CanConvertTo(IXamlTypeConverterContext context, Type destinationType) |
|||
{ |
|||
return false; |
|||
} |
|||
|
|||
public object ConvertFrom(IXamlTypeConverterContext context, CultureInfo culture, object value) |
|||
{ |
|||
return Brush.Parse((string)value); |
|||
} |
|||
|
|||
public object ConvertTo(IXamlTypeConverterContext context, CultureInfo culture, object value, Type destinationType) |
|||
{ |
|||
throw new NotImplementedException(); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,33 @@ |
|||
// Copyright (c) The Perspex Project. All rights reserved.
|
|||
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
|||
|
|||
using System; |
|||
using System.Globalization; |
|||
using OmniXaml.TypeConversion; |
|||
using Perspex.Styling; |
|||
|
|||
namespace Perspex.Markup.Xaml.Converters |
|||
{ |
|||
public class ClassesTypeConverter : ITypeConverter |
|||
{ |
|||
public bool CanConvertFrom(IXamlTypeConverterContext context, Type sourceType) |
|||
{ |
|||
return sourceType == typeof(string); |
|||
} |
|||
|
|||
public bool CanConvertTo(IXamlTypeConverterContext context, Type destinationType) |
|||
{ |
|||
return false; |
|||
} |
|||
|
|||
public object ConvertFrom(IXamlTypeConverterContext context, CultureInfo culture, object value) |
|||
{ |
|||
return new Classes(((string)value).Split(' ')); |
|||
} |
|||
|
|||
public object ConvertTo(IXamlTypeConverterContext context, CultureInfo culture, object value, Type destinationType) |
|||
{ |
|||
throw new NotImplementedException(); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,33 @@ |
|||
// Copyright (c) The Perspex Project. All rights reserved.
|
|||
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
|||
|
|||
using System; |
|||
using System.Globalization; |
|||
using OmniXaml.TypeConversion; |
|||
using Perspex.Media; |
|||
|
|||
namespace Perspex.Markup.Xaml.Converters |
|||
{ |
|||
public class ColorTypeConverter : ITypeConverter |
|||
{ |
|||
public bool CanConvertFrom(IXamlTypeConverterContext context, Type sourceType) |
|||
{ |
|||
return sourceType == typeof(string); |
|||
} |
|||
|
|||
public bool CanConvertTo(IXamlTypeConverterContext context, Type destinationType) |
|||
{ |
|||
return false; |
|||
} |
|||
|
|||
public object ConvertFrom(IXamlTypeConverterContext context, CultureInfo culture, object value) |
|||
{ |
|||
return Color.Parse((string)value); |
|||
} |
|||
|
|||
public object ConvertTo(IXamlTypeConverterContext context, CultureInfo culture, object value, Type destinationType) |
|||
{ |
|||
throw new NotImplementedException(); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,33 @@ |
|||
// Copyright (c) The Perspex Project. All rights reserved.
|
|||
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
|||
|
|||
using System; |
|||
using System.Globalization; |
|||
using OmniXaml.TypeConversion; |
|||
using Perspex.Controls; |
|||
|
|||
namespace Perspex.Markup.Xaml.Converters |
|||
{ |
|||
public class ColumnDefinitionsTypeConverter : ITypeConverter |
|||
{ |
|||
public bool CanConvertFrom(IXamlTypeConverterContext context, Type sourceType) |
|||
{ |
|||
return sourceType == typeof(string); |
|||
} |
|||
|
|||
public bool CanConvertTo(IXamlTypeConverterContext context, Type destinationType) |
|||
{ |
|||
return false; |
|||
} |
|||
|
|||
public object ConvertFrom(IXamlTypeConverterContext context, CultureInfo culture, object value) |
|||
{ |
|||
return new ColumnDefinitions((string)value); |
|||
} |
|||
|
|||
public object ConvertTo(IXamlTypeConverterContext context, CultureInfo culture, object value, Type destinationType) |
|||
{ |
|||
throw new NotImplementedException(); |
|||
} |
|||
} |
|||
} |
|||
@ -1,51 +1,33 @@ |
|||
// -----------------------------------------------------------------------
|
|||
// <copyright file="GridLengthTypeConverter.cs" company="Steven Kirk">
|
|||
// Copyright 2015 MIT Licence. See licence.md for more information.
|
|||
// </copyright>
|
|||
// -----------------------------------------------------------------------
|
|||
// Copyright (c) The Perspex Project. All rights reserved.
|
|||
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
|||
|
|||
using System; |
|||
using System.Globalization; |
|||
using OmniXaml.TypeConversion; |
|||
using Perspex.Controls; |
|||
|
|||
namespace Perspex.Markup.Xaml.Converters |
|||
{ |
|||
using System; |
|||
using System.Globalization; |
|||
using Controls; |
|||
using OmniXaml.TypeConversion; |
|||
|
|||
public class GridLengthTypeConverter : ITypeConverter |
|||
{ |
|||
public object ConvertFrom(IXamlTypeConverterContext context, CultureInfo culture, object value) |
|||
public bool CanConvertFrom(IXamlTypeConverterContext context, Type sourceType) |
|||
{ |
|||
var str = value as string; |
|||
|
|||
if (str != null) |
|||
{ |
|||
if (string.Equals(str, "Auto")) |
|||
{ |
|||
return new GridLength(0, GridUnitType.Auto); |
|||
} |
|||
} |
|||
|
|||
return new GridLength(1, GridUnitType.Star); |
|||
return sourceType == typeof(string); |
|||
} |
|||
|
|||
public object ConvertTo(IXamlTypeConverterContext context, CultureInfo culture, object value, Type destinationType) |
|||
public bool CanConvertTo(IXamlTypeConverterContext context, Type destinationType) |
|||
{ |
|||
if ((string) value == "Auto") |
|||
{ |
|||
return new GridLength(0, GridUnitType.Auto); |
|||
} |
|||
|
|||
return new GridLength(1, GridUnitType.Star); |
|||
return false; |
|||
} |
|||
|
|||
public bool CanConvertTo(IXamlTypeConverterContext context, Type destinationType) |
|||
public object ConvertFrom(IXamlTypeConverterContext context, CultureInfo culture, object value) |
|||
{ |
|||
return true; |
|||
return GridLength.Parse((string)value, culture); |
|||
} |
|||
|
|||
public bool CanConvertFrom(IXamlTypeConverterContext context, Type sourceType) |
|||
public object ConvertTo(IXamlTypeConverterContext context, CultureInfo culture, object value, Type destinationType) |
|||
{ |
|||
return true; |
|||
throw new NotImplementedException(); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,72 @@ |
|||
// Copyright (c) The Perspex Project. All rights reserved.
|
|||
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
|||
|
|||
using System; |
|||
using System.Globalization; |
|||
using System.Linq; |
|||
using OmniXaml; |
|||
using OmniXaml.TypeConversion; |
|||
using Perspex.Styling; |
|||
|
|||
namespace Perspex.Markup.Xaml.Converters |
|||
{ |
|||
public class PerspexPropertyTypeConverter : ITypeConverter |
|||
{ |
|||
public bool CanConvertFrom(IXamlTypeConverterContext context, Type sourceType) |
|||
{ |
|||
return sourceType == typeof(string); |
|||
} |
|||
|
|||
public bool CanConvertTo(IXamlTypeConverterContext context, Type destinationType) |
|||
{ |
|||
return false; |
|||
} |
|||
|
|||
public object ConvertFrom(IXamlTypeConverterContext context, CultureInfo culture, object value) |
|||
{ |
|||
var s = (string)value; |
|||
var lastDot = s.LastIndexOf('.'); |
|||
|
|||
if (lastDot == -1) |
|||
{ |
|||
throw new NotSupportedException("PerspexProperties must currently be fully qualified."); |
|||
} |
|||
|
|||
var typeName = s.Substring(0, lastDot); |
|||
var propertyName = s.Substring(lastDot + 1); |
|||
var type = context.TypeRepository.GetByQualifiedName(typeName)?.UnderlyingType; |
|||
var styleType = context.TypeRepository.GetXamlType(typeof(Style)); |
|||
|
|||
// ATTN: SuperJMN
|
|||
//var style = ((XamlTypeConverterContext)context).TopDownValueContext.GetLastInstance(styleType);
|
|||
|
|||
if (type == null) |
|||
{ |
|||
throw new XamlParseException($"Could not find type '{typeName}'."); |
|||
} |
|||
|
|||
// First look for non-attached property on the type and then look for an attached property.
|
|||
var property = PerspexObject.GetRegisteredProperties(type) |
|||
.FirstOrDefault(x => x.Name == propertyName); |
|||
|
|||
if (property == null) |
|||
{ |
|||
property = PerspexObject.GetAttachedProperties(type) |
|||
.FirstOrDefault(x => x.Name == propertyName); |
|||
} |
|||
|
|||
if (property == null) |
|||
{ |
|||
throw new XamlParseException( |
|||
$"Could not find PerspexProperty '{typeName}'.{propertyName}."); |
|||
} |
|||
|
|||
return property; |
|||
} |
|||
|
|||
public object ConvertTo(IXamlTypeConverterContext context, CultureInfo culture, object value, Type destinationType) |
|||
{ |
|||
throw new NotImplementedException(); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,32 @@ |
|||
// Copyright (c) The Perspex Project. All rights reserved.
|
|||
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
|||
|
|||
using System; |
|||
using System.Globalization; |
|||
using OmniXaml.TypeConversion; |
|||
|
|||
namespace Perspex.Markup.Xaml.Converters |
|||
{ |
|||
public class PointTypeConverter : ITypeConverter |
|||
{ |
|||
public bool CanConvertFrom(IXamlTypeConverterContext context, Type sourceType) |
|||
{ |
|||
return sourceType == typeof(string); |
|||
} |
|||
|
|||
public bool CanConvertTo(IXamlTypeConverterContext context, Type destinationType) |
|||
{ |
|||
return false; |
|||
} |
|||
|
|||
public object ConvertFrom(IXamlTypeConverterContext context, CultureInfo culture, object value) |
|||
{ |
|||
return Point.Parse((string)value, culture); |
|||
} |
|||
|
|||
public object ConvertTo(IXamlTypeConverterContext context, CultureInfo culture, object value, Type destinationType) |
|||
{ |
|||
throw new NotImplementedException(); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,32 @@ |
|||
// Copyright (c) The Perspex Project. All rights reserved.
|
|||
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
|||
|
|||
using System; |
|||
using System.Globalization; |
|||
using OmniXaml.TypeConversion; |
|||
|
|||
namespace Perspex.Markup.Xaml.Converters |
|||
{ |
|||
public class RelativePointTypeConverter : ITypeConverter |
|||
{ |
|||
public bool CanConvertFrom(IXamlTypeConverterContext context, Type sourceType) |
|||
{ |
|||
return sourceType == typeof(string); |
|||
} |
|||
|
|||
public bool CanConvertTo(IXamlTypeConverterContext context, Type destinationType) |
|||
{ |
|||
return false; |
|||
} |
|||
|
|||
public object ConvertFrom(IXamlTypeConverterContext context, CultureInfo culture, object value) |
|||
{ |
|||
return RelativePoint.Parse((string)value, culture); |
|||
} |
|||
|
|||
public object ConvertTo(IXamlTypeConverterContext context, CultureInfo culture, object value, Type destinationType) |
|||
{ |
|||
throw new NotImplementedException(); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,33 @@ |
|||
// Copyright (c) The Perspex Project. All rights reserved.
|
|||
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
|||
|
|||
using System; |
|||
using System.Globalization; |
|||
using OmniXaml.TypeConversion; |
|||
using Perspex.Controls; |
|||
|
|||
namespace Perspex.Markup.Xaml.Converters |
|||
{ |
|||
public class RowDefinitionsTypeConverter : ITypeConverter |
|||
{ |
|||
public bool CanConvertFrom(IXamlTypeConverterContext context, Type sourceType) |
|||
{ |
|||
return sourceType == typeof(string); |
|||
} |
|||
|
|||
public bool CanConvertTo(IXamlTypeConverterContext context, Type destinationType) |
|||
{ |
|||
return false; |
|||
} |
|||
|
|||
public object ConvertFrom(IXamlTypeConverterContext context, CultureInfo culture, object value) |
|||
{ |
|||
return new RowDefinitions((string)value); |
|||
} |
|||
|
|||
public object ConvertTo(IXamlTypeConverterContext context, CultureInfo culture, object value, Type destinationType) |
|||
{ |
|||
throw new NotImplementedException(); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,34 @@ |
|||
// Copyright (c) The Perspex Project. All rights reserved.
|
|||
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
|||
|
|||
using System; |
|||
using System.Globalization; |
|||
using OmniXaml.TypeConversion; |
|||
using Perspex.Markup.Xaml.Parsers; |
|||
|
|||
namespace Perspex.Markup.Xaml.Converters |
|||
{ |
|||
public class SelectorTypeConverter : ITypeConverter |
|||
{ |
|||
public bool CanConvertFrom(IXamlTypeConverterContext context, Type sourceType) |
|||
{ |
|||
return sourceType == typeof(string); |
|||
} |
|||
|
|||
public bool CanConvertTo(IXamlTypeConverterContext context, Type destinationType) |
|||
{ |
|||
return false; |
|||
} |
|||
|
|||
public object ConvertFrom(IXamlTypeConverterContext context, CultureInfo culture, object value) |
|||
{ |
|||
var parser = new SelectorParser((t, ns) => context.TypeRepository.GetByPrefix(ns ?? "", t).UnderlyingType); |
|||
return parser.Parse((string)value); |
|||
} |
|||
|
|||
public object ConvertTo(IXamlTypeConverterContext context, CultureInfo culture, object value, Type destinationType) |
|||
{ |
|||
throw new NotImplementedException(); |
|||
} |
|||
} |
|||
} |
|||
@ -1,81 +0,0 @@ |
|||
// -----------------------------------------------------------------------
|
|||
// <copyright file="ThicknessConverter.cs" company="Steven Kirk">
|
|||
// Copyright 2015 MIT Licence. See licence.md for more information.
|
|||
// </copyright>
|
|||
// -----------------------------------------------------------------------
|
|||
|
|||
namespace Perspex.Markup.Xaml.Converters |
|||
{ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Globalization; |
|||
using System.Linq; |
|||
using OmniXaml.TypeConversion; |
|||
|
|||
public class ThicknessConverter : ITypeConverter |
|||
{ |
|||
public object ConvertFrom(IXamlTypeConverterContext context, CultureInfo culture, object value) |
|||
{ |
|||
var s = value as string; |
|||
if (s != null) |
|||
{ |
|||
return ConvertFromString(s); |
|||
} |
|||
|
|||
return null; |
|||
} |
|||
|
|||
private static Thickness ConvertFromString(string s) |
|||
{ |
|||
var parts = s.Split(',') |
|||
.Take(4) |
|||
.Select(part => part.Trim()); |
|||
|
|||
if (parts.Count() == 1) |
|||
{ |
|||
var uniformLength = double.Parse(parts.First()); |
|||
return new Thickness(uniformLength); |
|||
} |
|||
|
|||
double left = 0, top = 0, right = 0, bottom = 0; |
|||
|
|||
IList<Action<double>> setValue = new List<Action<double>> |
|||
{ |
|||
val => left = val, |
|||
val => top = val, |
|||
val => right = val, |
|||
val => bottom = val, |
|||
}; |
|||
|
|||
var i = 0; |
|||
foreach (var part in parts) |
|||
{ |
|||
var v = double.Parse(part); |
|||
setValue[i](v); |
|||
i++; |
|||
} |
|||
|
|||
return new Thickness(left, top, right, bottom); |
|||
} |
|||
|
|||
public object ConvertTo(IXamlTypeConverterContext context, CultureInfo culture, object value, Type destinationType) |
|||
{ |
|||
throw new System.NotImplementedException(); |
|||
} |
|||
|
|||
public bool CanConvertTo(IXamlTypeConverterContext context, Type destinationType) |
|||
{ |
|||
throw new NotImplementedException(); |
|||
} |
|||
|
|||
public bool CanConvertFrom(IXamlTypeConverterContext context, Type sourceType) |
|||
{ |
|||
if (sourceType == typeof(string)) |
|||
{ |
|||
return true; |
|||
} |
|||
|
|||
return false; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,32 @@ |
|||
// Copyright (c) The Perspex Project. All rights reserved.
|
|||
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
|||
|
|||
using System; |
|||
using System.Globalization; |
|||
using OmniXaml.TypeConversion; |
|||
|
|||
namespace Perspex.Markup.Xaml.Converters |
|||
{ |
|||
public class ThicknessTypeConverter : ITypeConverter |
|||
{ |
|||
public bool CanConvertFrom(IXamlTypeConverterContext context, Type sourceType) |
|||
{ |
|||
return sourceType == typeof(string); |
|||
} |
|||
|
|||
public bool CanConvertTo(IXamlTypeConverterContext context, Type destinationType) |
|||
{ |
|||
return false; |
|||
} |
|||
|
|||
public object ConvertFrom(IXamlTypeConverterContext context, CultureInfo culture, object value) |
|||
{ |
|||
return Thickness.Parse((string)value, culture); |
|||
} |
|||
|
|||
public object ConvertTo(IXamlTypeConverterContext context, CultureInfo culture, object value, Type destinationType) |
|||
{ |
|||
throw new NotImplementedException(); |
|||
} |
|||
} |
|||
} |
|||
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue