mirror of
https://github.com/qmlnet/qmlnet.git
synced 2026-05-15 14:15:54 -06:00
QQuickPaintedItem support (#219)
* First support for QQuickPaintedItem Implements some basic drawing functionalities * Less string passing during drawing Colors get registered and are referenced via id Font parameters can be set separately * Color string to id conversion is now an implementation detail of QmlNetPaintedItem * Adds Font metrics functionality * Adds DrawText overload with bounding rectangle * Dont copy the actions on each draw but lock the vector * Optional Text support for QmlNetPaintedItem (including preedit) * Adds Flags to the DrawText (Rect) method * Adds an interface to interact with a QPainter This interface can be implemented by a QPainter abstraction in the future For now QmlNetPaintedItem implements INetQPainter * Native submodule: Adds QMutex include * Native submodule: Adds missing include * Adds a lot of the QPainter interface * Fixes Polygon point handling Adds new QPainter API to QmlNetPaintedItem * Renames QmlNetPaintedItem to QmlNetRecordingPaintedItem * Deactivates painthandler reset in destructor of RecordingPaintedItem * Registering a QuickPaintedItem * Hide QmlNetQuickPaintedItem from QML * First theoretically working PaintedItem implementation * getStringSize is now static * new native submodule version * new native submodule (build error fix) * Cleanup Removes RecordingPaintedItem Removes INetQPainter (functionality moved to NetQPainter) * references native that fixes type registration * Draw Image file * Adds testing infrastructure for QmlNetQuickPaintedItem * DrawArc test * DrawConvexPolygon test * Fixes GCHandle handling in QmlNetQuickPaintedItem * Adds setWindowIcon support to QGuiApplication * Adds DrawEllipse and DrawLine test * Adds DrawPoint test * Adds DrawPolygon test * Adds DrawRoundedRect test * Draw Pie Unit Test * Test source formatting * DrawPolyline Unit test * Erase Rect Unit Test * Unit Tests for ClipRect and Opacity * Disables transformations Real world use cases would want to use the QTransform functionality instead of passing the raw transformation matrix * Unit Test for Sheer * Adds Unit test for Translate * Cleanup * Link to native/origin/master * Re-Trigger CI Co-authored-by: Paul Knopf <pauldotknopf@gmail.com>
This commit is contained in:
parent
4e54f975cb
commit
0836ae783a
15 changed files with 1825 additions and 18 deletions
4
.gitignore
vendored
4
.gitignore
vendored
|
|
@ -3,4 +3,6 @@ output/
|
|||
samples/PhotoFrame/\.vscode/
|
||||
samples/PhotoFrame/\.idea/
|
||||
build/Qt/
|
||||
build/qtci/
|
||||
build/qtci/
|
||||
src/native/.DS_Store
|
||||
.DS_Store
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
Subproject commit b4cf9f8dacad14e74a52e26cad1915f34da792f1
|
||||
Subproject commit 4510e0109d3a6c3e74be5f2876e3681ae3f75723
|
||||
|
|
@ -9,6 +9,7 @@
|
|||
<PackageReference Include="Mono.Posix.NETStandard" Version="1.0.0" />
|
||||
<PackageReference Include="Moq" Version="4.10.1" />
|
||||
<PackageReference Include="SharpCompress" Version="0.23.0" />
|
||||
<PackageReference Include="SixLabors.ImageSharp" Version="1.0.1" />
|
||||
<PackageReference Include="xunit" Version="2.4.1" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.1" />
|
||||
<DotNetCliToolReference Include="dotnet-xunit" Version="2.3.1" />
|
||||
|
|
|
|||
|
|
@ -32,31 +32,61 @@ namespace Qml.Net.Tests.Qml
|
|||
_registeredTypes.Add(typeof(T));
|
||||
Net.Qml.RegisterType<T>("tests");
|
||||
}
|
||||
|
||||
protected void RunQmlTest(string instanceId, string componentOnCompletedCode, bool runEvents = false, bool failOnQmlWarnings = true)
|
||||
|
||||
protected virtual void RegisterPaintedQuickItemType<T>()
|
||||
where T : QmlNetQuickPaintedItem
|
||||
{
|
||||
var result = NetTestHelper.RunQml(
|
||||
qmlApplicationEngine,
|
||||
string.Format(
|
||||
@"
|
||||
if (_registeredTypes.Contains(typeof(T))) return;
|
||||
_registeredTypes.Add(typeof(T));
|
||||
Net.Qml.RegisterPaintedQuickItemType<T>("tests");
|
||||
}
|
||||
|
||||
protected void RunQmlTest(string instanceId, string componentOnCompletedCode, bool runEvents = false, bool failOnQmlWarnings = true, string additionalProperties = "")
|
||||
{
|
||||
var qml = string.Format(
|
||||
@"
|
||||
import QtQuick 2.0
|
||||
import tests 1.0
|
||||
{0} {{
|
||||
id: {1}
|
||||
{2}
|
||||
property var testQObject: null
|
||||
function runTest() {{
|
||||
{2}
|
||||
{3}
|
||||
}}
|
||||
}}
|
||||
",
|
||||
typeof(TTypeToRegister).Name,
|
||||
instanceId,
|
||||
componentOnCompletedCode),
|
||||
runEvents,
|
||||
failOnQmlWarnings);
|
||||
typeof(TTypeToRegister).Name,
|
||||
instanceId,
|
||||
additionalProperties,
|
||||
componentOnCompletedCode);
|
||||
var result = true;
|
||||
Exception exception= null;
|
||||
try
|
||||
{
|
||||
result = NetTestHelper.RunQml(
|
||||
qmlApplicationEngine,
|
||||
qml,
|
||||
runEvents,
|
||||
failOnQmlWarnings);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
exception = ex;
|
||||
result = false;
|
||||
}
|
||||
|
||||
if (result == false)
|
||||
{
|
||||
throw new Exception($"Couldn't execute qml: {componentOnCompletedCode}");
|
||||
var msg = $"Couldn't execute qml: {Environment.NewLine}{qml}";
|
||||
if (exception != null)
|
||||
{
|
||||
throw new Exception(msg, exception);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -84,6 +114,32 @@ namespace Qml.Net.Tests.Qml
|
|||
TypeCreator.SetInstance(typeof(T), Mock.Object);
|
||||
}
|
||||
}
|
||||
|
||||
public abstract class BaseQmlQuickPaintedItemTests<T> : AbstractBaseQmlTests<T>
|
||||
where T : QmlNetQuickPaintedItem
|
||||
{
|
||||
protected readonly Mock<T> Mock;
|
||||
|
||||
protected BaseQmlQuickPaintedItemTests()
|
||||
{
|
||||
RegisterPaintedQuickItemType<T>();
|
||||
Mock = new Mock<T>();
|
||||
TypeCreator.SetInstance(typeof(T), Mock.Object);
|
||||
}
|
||||
}
|
||||
|
||||
public abstract class BaseQmlQuickPaintedItemTestsWithInstance<T> : AbstractBaseQmlTests<T>
|
||||
where T : QmlNetQuickPaintedItem, new()
|
||||
{
|
||||
protected readonly T Instance;
|
||||
|
||||
protected BaseQmlQuickPaintedItemTestsWithInstance()
|
||||
{
|
||||
RegisterPaintedQuickItemType<T>();
|
||||
Instance = new T();
|
||||
TypeCreator.SetInstance(typeof(T), Instance);
|
||||
}
|
||||
}
|
||||
|
||||
public abstract class BaseQmlTestsWithInstance<T> : AbstractBaseQmlTests<T>
|
||||
where T : class, new()
|
||||
|
|
|
|||
|
|
@ -180,7 +180,6 @@ namespace Qml.Net.Tests.Qml
|
|||
})
|
||||
viewModelContainer.changeStringPropertyTo('new value')
|
||||
");
|
||||
|
||||
Instance.TestResult.Should().Be(true);
|
||||
}
|
||||
|
||||
|
|
|
|||
709
src/net/Qml.Net.Tests/Qml/QmlNetQuickPaintedItemTests.cs
Normal file
709
src/net/Qml.Net.Tests/Qml/QmlNetQuickPaintedItemTests.cs
Normal file
|
|
@ -0,0 +1,709 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.IO;
|
||||
using Moq;
|
||||
using SixLabors.ImageSharp;
|
||||
using SixLabors.ImageSharp.PixelFormats;
|
||||
using Xunit;
|
||||
using Xunit.Abstractions;
|
||||
using Xunit.Sdk;
|
||||
using Color = System.Drawing.Color;
|
||||
using Point = System.Drawing.Point;
|
||||
|
||||
namespace Qml.Net.Tests.Qml
|
||||
{
|
||||
public class QmlNetQuickPaintedItemTests : BaseQmlQuickPaintedItemTests<QmlNetQuickPaintedItemTests.TestPaintedItem>
|
||||
{
|
||||
public class TestPaintedItem : QmlNetQuickPaintedItem
|
||||
{
|
||||
public TestPaintedItem()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public virtual string SomeProperty { get; set; }
|
||||
|
||||
public object QmlValue { get; set; }
|
||||
|
||||
public override void Paint(NetQPainter painter)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Can_get_and_set_additional_properties()
|
||||
{
|
||||
Mock.SetupGet(x => x.SomeProperty).Returns("Some property value");
|
||||
|
||||
RunQmlTest(
|
||||
"test",
|
||||
@"
|
||||
test.someProperty = test.someProperty
|
||||
");
|
||||
|
||||
Mock.VerifyGet(x => x.SomeProperty, Times.Once);
|
||||
Mock.VerifySet(x => x.SomeProperty = "Some property value");
|
||||
}
|
||||
}
|
||||
|
||||
public class QmlNetQuickPaintedItemInstanceTests : BaseQmlQuickPaintedItemTestsWithInstance<
|
||||
QmlNetQuickPaintedItemInstanceTests.TestPaintedItem>
|
||||
{
|
||||
public class TestPaintedItem : QmlNetQuickPaintedItem
|
||||
{
|
||||
public TestPaintedItem()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public virtual string SomeProperty { get; set; }
|
||||
|
||||
public object QmlValue { get; set; }
|
||||
|
||||
public override void Paint(NetQPainter painter)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Do_quickitem_properties_exist()
|
||||
{
|
||||
RunQmlTest(
|
||||
"test",
|
||||
@"
|
||||
test.height = 20;
|
||||
test.qmlValue = test.height;
|
||||
");
|
||||
|
||||
Assert.NotNull(Instance.QmlValue);
|
||||
Assert.Equal(20d, Instance.QmlValue);
|
||||
}
|
||||
}
|
||||
|
||||
public class QmlNetQuickPaintedItemRenderingTests : BaseQmlQuickPaintedItemTestsWithInstance<
|
||||
QmlNetQuickPaintedItemRenderingTests.TestPaintedItem>
|
||||
{
|
||||
private readonly ITestOutputHelper _testOutputHelper;
|
||||
|
||||
public QmlNetQuickPaintedItemRenderingTests(ITestOutputHelper testOutputHelper)
|
||||
{
|
||||
_testOutputHelper = testOutputHelper;
|
||||
}
|
||||
|
||||
public class TestPaintedItem : QmlNetQuickPaintedItem
|
||||
{
|
||||
private byte[] _imgData;
|
||||
|
||||
public byte[] ImageData => _imgData;
|
||||
|
||||
public TestPaintedItem()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public override void Paint(NetQPainter painter)
|
||||
{
|
||||
foreach (var paintAction in _paintActions)
|
||||
{
|
||||
paintAction(painter);
|
||||
}
|
||||
}
|
||||
|
||||
public void AddPaintAction(Action<NetQPainter> paintAction)
|
||||
{
|
||||
_paintActions.Add(paintAction);
|
||||
}
|
||||
|
||||
private List<Action<NetQPainter>> _paintActions = new List<Action<NetQPainter>>();
|
||||
|
||||
public void DoStoreImageData()
|
||||
{
|
||||
_imgData = PaintToImage("bmp");
|
||||
}
|
||||
}
|
||||
|
||||
Image<Rgba32> RunQmlRendering(params Action<NetQPainter>[] paintActions)
|
||||
{
|
||||
foreach (var pa in paintActions)
|
||||
{
|
||||
Instance.AddPaintAction(pa);
|
||||
}
|
||||
|
||||
RunQmlTest(
|
||||
"test",
|
||||
@"
|
||||
test.doStoreImageData();
|
||||
",
|
||||
additionalProperties: "height: 200" + Environment.NewLine + "width:300" + Environment.NewLine +
|
||||
"fillColor:'#FFFFFFFF'");
|
||||
|
||||
return Image.Load<Rgba32>(Instance.ImageData);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void FillRect_works()
|
||||
{
|
||||
var img = RunQmlRendering((p) => { p.FillRect(0, 0, 150, 100, "#FF0000"); });
|
||||
|
||||
var red = new Rgba32(0xFF, 0x00, 0x00);
|
||||
var white = new Rgba32(0xFF, 0xFF, 0xFF);
|
||||
|
||||
Assert.Equal(white, img[299, 199]);
|
||||
|
||||
Assert.Equal(red, img[0, 0]);
|
||||
Assert.Equal(red, img[149, 0]);
|
||||
Assert.Equal(red, img[0, 99]);
|
||||
Assert.Equal(red, img[149, 99]);
|
||||
Assert.Equal(white, img[150, 0]);
|
||||
Assert.Equal(white, img[149, 100]);
|
||||
Assert.Equal(white, img[150, 99]);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void FillRectWithImplicitColor_works()
|
||||
{
|
||||
var img = RunQmlRendering((p) =>
|
||||
{
|
||||
p.SetBrush("#FF0000");
|
||||
p.FillRect(0, 0, 150, 100);
|
||||
});
|
||||
|
||||
var red = new Rgba32(0xFF, 0x00, 0x00);
|
||||
var white = new Rgba32(0xFF, 0xFF, 0xFF);
|
||||
|
||||
Assert.Equal(white, img[299, 199]);
|
||||
|
||||
Assert.Equal(red, img[0, 0]);
|
||||
Assert.Equal(red, img[149, 0]);
|
||||
Assert.Equal(red, img[0, 99]);
|
||||
Assert.Equal(red, img[149, 99]);
|
||||
Assert.Equal(white, img[150, 0]);
|
||||
Assert.Equal(white, img[149, 100]);
|
||||
Assert.Equal(white, img[150, 99]);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void DrawRect_works()
|
||||
{
|
||||
var img = RunQmlRendering((p) =>
|
||||
{
|
||||
p.SetPen("#00FF00", 1);
|
||||
p.DrawRect(0, 0, 150, 100);
|
||||
});
|
||||
|
||||
var green = new Rgba32(0x00, 0xFF, 0x00);
|
||||
var white = new Rgba32(0xFF, 0xFF, 0xFF);
|
||||
|
||||
Assert.Equal(white, img[299, 199]);
|
||||
|
||||
Assert.Equal(green, img[0, 0]);
|
||||
Assert.Equal(green, img[149, 0]);
|
||||
Assert.Equal(white, img[151, 0]);
|
||||
Assert.Equal(white, img[148, 5]);
|
||||
Assert.Equal(green, img[0, 99]);
|
||||
Assert.Equal(white, img[5, 98]);
|
||||
Assert.Equal(green, img[150, 100]);
|
||||
Assert.Equal(white, img[151, 0]);
|
||||
Assert.Equal(white, img[149, 101]);
|
||||
Assert.Equal(white, img[151, 100]);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void DrawArc_works()
|
||||
{
|
||||
var img = RunQmlRendering((p) =>
|
||||
{
|
||||
p.SetPen("#00FF00", 1);
|
||||
p.DrawArc(0, 0, 150, 100, 0, 45 * 16);
|
||||
});
|
||||
|
||||
var green = new Rgba32(0x00, 0xFF, 0x00);
|
||||
var white = new Rgba32(0xFF, 0xFF, 0xFF);
|
||||
|
||||
Assert.Equal(green, img[128, 14]);
|
||||
Assert.Equal(white, img[129, 14]);
|
||||
Assert.Equal(white, img[127, 14]);
|
||||
Assert.Equal(white, img[128, 15]);
|
||||
Assert.Equal(white, img[128, 13]);
|
||||
|
||||
Assert.Equal(green, img[129, 15]);
|
||||
|
||||
Assert.Equal(green, img[130, 16]);
|
||||
|
||||
Assert.Equal(green, img[131, 17]);
|
||||
Assert.Equal(green, img[132, 17]);
|
||||
|
||||
Assert.Equal(green, img[150, 50]);
|
||||
Assert.Equal(white, img[151, 50]);
|
||||
Assert.Equal(white, img[149, 50]);
|
||||
Assert.Equal(white, img[150, 51]);
|
||||
Assert.Equal(white, img[150, 49]);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void DrawConvexPolygon_works()
|
||||
{
|
||||
var img = RunQmlRendering((p) =>
|
||||
{
|
||||
p.SetPen("#00FF00", 1);
|
||||
p.DrawConvexPolygon(new[]
|
||||
{
|
||||
new Point(10, 10),
|
||||
new Point(10, 100),
|
||||
new Point(100, 100),
|
||||
new Point(100, 10),
|
||||
new Point(10, 10)
|
||||
});
|
||||
});
|
||||
|
||||
var green = new Rgba32(0x00, 0xFF, 0x00);
|
||||
var white = new Rgba32(0xFF, 0xFF, 0xFF);
|
||||
|
||||
Assert.Equal(green, img[10, 10]);
|
||||
Assert.Equal(green, img[10, 50]);
|
||||
Assert.Equal(green, img[10, 100]);
|
||||
Assert.Equal(green, img[50, 100]);
|
||||
Assert.Equal(green, img[100, 100]);
|
||||
Assert.Equal(green, img[100, 50]);
|
||||
Assert.Equal(green, img[100, 10]);
|
||||
Assert.Equal(green, img[50, 10]);
|
||||
|
||||
Assert.Equal(white, img[8, 10]);
|
||||
Assert.Equal(white, img[12, 12]);
|
||||
Assert.Equal(white, img[8, 100]);
|
||||
|
||||
Assert.Equal(white, img[100, 8]);
|
||||
Assert.Equal(white, img[102, 10]);
|
||||
Assert.Equal(white, img[102, 100]);
|
||||
Assert.Equal(white, img[50, 102]);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void DrawEllipse_works()
|
||||
{
|
||||
var img = RunQmlRendering((p) =>
|
||||
{
|
||||
p.SetPen("#00FF00", 1);
|
||||
p.DrawEllipse(10, 10, 100, 20);
|
||||
});
|
||||
|
||||
var green = new Rgba32(0x00, 0xFF, 0x00);
|
||||
var white = new Rgba32(0xFF, 0xFF, 0xFF);
|
||||
|
||||
// left side
|
||||
Assert.Equal(green, img[10, 19]);
|
||||
Assert.Equal(green, img[10, 20]);
|
||||
Assert.Equal(green, img[10, 21]);
|
||||
|
||||
Assert.Equal(white, img[9, 20]);
|
||||
Assert.Equal(white, img[9, 21]);
|
||||
Assert.Equal(white, img[10, 22]);
|
||||
Assert.Equal(white, img[10, 18]);
|
||||
|
||||
Assert.Equal(white, img[11, 20]);
|
||||
Assert.Equal(white, img[11, 21]);
|
||||
|
||||
Assert.Equal(green, img[11, 18]);
|
||||
Assert.Equal(green, img[11, 22]);
|
||||
|
||||
// right side
|
||||
Assert.Equal(green, img[110, 19]);
|
||||
Assert.Equal(green, img[110, 20]);
|
||||
Assert.Equal(green, img[110, 21]);
|
||||
|
||||
Assert.Equal(white, img[111, 20]);
|
||||
Assert.Equal(white, img[111, 21]);
|
||||
Assert.Equal(white, img[110, 22]);
|
||||
Assert.Equal(white, img[110, 18]);
|
||||
|
||||
Assert.Equal(white, img[109, 20]);
|
||||
Assert.Equal(white, img[109, 21]);
|
||||
|
||||
Assert.Equal(green, img[109, 18]);
|
||||
Assert.Equal(green, img[109, 22]);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void DrawLine_works()
|
||||
{
|
||||
var img = RunQmlRendering((p) =>
|
||||
{
|
||||
p.SetPen("#00FF00", 1);
|
||||
p.DrawLine(10, 10, 100, 100);
|
||||
});
|
||||
|
||||
var green = new Rgba32(0x00, 0xFF, 0x00);
|
||||
var white = new Rgba32(0xFF, 0xFF, 0xFF);
|
||||
|
||||
Assert.Equal(white, img[9, 8]);
|
||||
Assert.Equal(white, img[9, 9]);
|
||||
Assert.Equal(white, img[9, 10]);
|
||||
|
||||
Assert.Equal(green, img[10, 10]);
|
||||
Assert.Equal(green, img[11, 11]);
|
||||
Assert.Equal(green, img[12, 12]);
|
||||
|
||||
Assert.Equal(green, img[98, 98]);
|
||||
Assert.Equal(green, img[99, 99]);
|
||||
Assert.Equal(green, img[100, 100]);
|
||||
|
||||
Assert.Equal(white, img[101, 101]);
|
||||
|
||||
Assert.Equal(white, img[10, 9]);
|
||||
Assert.Equal(white, img[10, 11]);
|
||||
Assert.Equal(white, img[11, 10]);
|
||||
Assert.Equal(white, img[11, 12]);
|
||||
|
||||
Assert.Equal(white, img[99, 98]);
|
||||
Assert.Equal(white, img[99, 100]);
|
||||
Assert.Equal(white, img[100, 99]);
|
||||
Assert.Equal(white, img[100, 101]);
|
||||
|
||||
Assert.Equal(white, img[101, 100]);
|
||||
Assert.Equal(white, img[101, 101]);
|
||||
Assert.Equal(white, img[101, 102]);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void DrawPoint_works()
|
||||
{
|
||||
var img = RunQmlRendering((p) =>
|
||||
{
|
||||
p.SetPen("#00FF00", 1);
|
||||
p.DrawPoint(47, 11);
|
||||
p.DrawPoint(78, 110);
|
||||
p.DrawPoint(60, 3);
|
||||
});
|
||||
|
||||
var green = new Rgba32(0x00, 0xFF, 0x00);
|
||||
var white = new Rgba32(0xFF, 0xFF, 0xFF);
|
||||
|
||||
Assert.Equal(green, img[47, 11]);
|
||||
Assert.Equal(white, img[46, 11]);
|
||||
Assert.Equal(white, img[48, 11]);
|
||||
Assert.Equal(white, img[47, 10]);
|
||||
Assert.Equal(white, img[47, 12]);
|
||||
|
||||
Assert.Equal(green, img[78, 110]);
|
||||
Assert.Equal(white, img[77, 110]);
|
||||
Assert.Equal(white, img[79, 110]);
|
||||
Assert.Equal(white, img[78, 109]);
|
||||
Assert.Equal(white, img[78, 111]);
|
||||
|
||||
Assert.Equal(green, img[60, 3]);
|
||||
Assert.Equal(white, img[59, 3]);
|
||||
Assert.Equal(white, img[61, 3]);
|
||||
Assert.Equal(white, img[60, 2]);
|
||||
Assert.Equal(white, img[60, 4]);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void DrawPolygon_works()
|
||||
{
|
||||
var img = RunQmlRendering((p) =>
|
||||
{
|
||||
p.SetPen("#00FF00", 1);
|
||||
p.DrawPolygon(
|
||||
new[]
|
||||
{
|
||||
new Point(10, 10),
|
||||
new Point(10, 100),
|
||||
new Point(100, 100),
|
||||
new Point(100, 10),
|
||||
new Point(10, 10)
|
||||
},
|
||||
false);
|
||||
});
|
||||
|
||||
var green = new Rgba32(0x00, 0xFF, 0x00);
|
||||
var white = new Rgba32(0xFF, 0xFF, 0xFF);
|
||||
|
||||
Assert.Equal(green, img[10, 10]);
|
||||
Assert.Equal(green, img[10, 50]);
|
||||
Assert.Equal(green, img[10, 100]);
|
||||
Assert.Equal(green, img[50, 100]);
|
||||
Assert.Equal(green, img[100, 100]);
|
||||
Assert.Equal(green, img[100, 50]);
|
||||
Assert.Equal(green, img[100, 10]);
|
||||
Assert.Equal(green, img[50, 10]);
|
||||
|
||||
Assert.Equal(white, img[8, 10]);
|
||||
Assert.Equal(white, img[12, 12]);
|
||||
Assert.Equal(white, img[8, 100]);
|
||||
|
||||
Assert.Equal(white, img[100, 8]);
|
||||
Assert.Equal(white, img[102, 10]);
|
||||
Assert.Equal(white, img[102, 100]);
|
||||
Assert.Equal(white, img[50, 102]);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void DrawRoundedRect_works()
|
||||
{
|
||||
var img = RunQmlRendering((p) =>
|
||||
{
|
||||
p.SetPen("#00FF00", 1);
|
||||
p.DrawRoundedRect(10, 10, 50, 50, 20, 20, false);
|
||||
});
|
||||
|
||||
var green = new Rgba32(0x00, 0xFF, 0x00);
|
||||
var white = new Rgba32(0xFF, 0xFF, 0xFF);
|
||||
|
||||
// check vertical left
|
||||
Assert.Equal(white, img[10, 10]);
|
||||
Assert.Equal(white, img[10, 11]);
|
||||
Assert.Equal(white, img[10, 12]);
|
||||
Assert.Equal(green, img[10, 13]);
|
||||
|
||||
Assert.Equal(green, img[10, 35]);
|
||||
|
||||
Assert.Equal(green, img[10, 57]);
|
||||
Assert.Equal(white, img[10, 58]);
|
||||
Assert.Equal(white, img[10, 59]);
|
||||
Assert.Equal(white, img[10, 60]);
|
||||
|
||||
// check horizontal top
|
||||
Assert.Equal(white, img[10, 10]);
|
||||
Assert.Equal(white, img[11, 10]);
|
||||
Assert.Equal(white, img[12, 10]);
|
||||
Assert.Equal(green, img[13, 10]);
|
||||
|
||||
Assert.Equal(green, img[35, 10]);
|
||||
|
||||
Assert.Equal(green, img[57, 10]);
|
||||
Assert.Equal(white, img[58, 10]);
|
||||
Assert.Equal(white, img[59, 10]);
|
||||
Assert.Equal(white, img[60, 10]);
|
||||
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void DrawPie_works()
|
||||
{
|
||||
var img = RunQmlRendering((p) =>
|
||||
{
|
||||
p.SetPen("#00FF00", 1);
|
||||
p.DrawPie(0, 0, 150, 100, 0, 45 * 16);
|
||||
});
|
||||
|
||||
var green = new Rgba32(0x00, 0xFF, 0x00);
|
||||
var white = new Rgba32(0xFF, 0xFF, 0xFF);
|
||||
|
||||
Assert.Equal(green, img[128, 14]);
|
||||
Assert.Equal(white, img[129, 14]);
|
||||
Assert.Equal(white, img[127, 14]);
|
||||
Assert.Equal(white, img[128, 15]);
|
||||
Assert.Equal(white, img[128, 13]);
|
||||
|
||||
Assert.Equal(green, img[129, 15]);
|
||||
|
||||
Assert.Equal(green, img[130, 16]);
|
||||
|
||||
Assert.Equal(green, img[131, 17]);
|
||||
Assert.Equal(green, img[132, 17]);
|
||||
|
||||
Assert.Equal(green, img[149, 50]);
|
||||
Assert.Equal(white, img[150, 50]);
|
||||
Assert.Equal(green, img[148, 50]);
|
||||
Assert.Equal(white, img[149, 51]);
|
||||
Assert.Equal(green, img[149, 49]);
|
||||
Assert.Equal(green, img[147, 50]);
|
||||
Assert.Equal(green, img[146, 50]);
|
||||
Assert.Equal(green, img[145, 50]);
|
||||
Assert.Equal(green, img[144, 50]);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void DrawPolyline_works()
|
||||
{
|
||||
var img = RunQmlRendering((p) =>
|
||||
{
|
||||
p.SetPen("#00FF00", 1);
|
||||
p.DrawPolyline(
|
||||
new[]
|
||||
{
|
||||
new Point(10, 10),
|
||||
new Point(10, 100),
|
||||
new Point(100, 100),
|
||||
new Point(100, 10),
|
||||
new Point(10, 10)
|
||||
});
|
||||
});
|
||||
|
||||
var green = new Rgba32(0x00, 0xFF, 0x00);
|
||||
var white = new Rgba32(0xFF, 0xFF, 0xFF);
|
||||
|
||||
Assert.Equal(green, img[10, 10]);
|
||||
Assert.Equal(green, img[10, 50]);
|
||||
Assert.Equal(green, img[10, 100]);
|
||||
Assert.Equal(green, img[50, 100]);
|
||||
Assert.Equal(green, img[100, 100]);
|
||||
Assert.Equal(green, img[100, 50]);
|
||||
Assert.Equal(green, img[100, 10]);
|
||||
Assert.Equal(green, img[50, 10]);
|
||||
|
||||
Assert.Equal(white, img[8, 10]);
|
||||
Assert.Equal(white, img[12, 12]);
|
||||
Assert.Equal(white, img[8, 100]);
|
||||
|
||||
Assert.Equal(white, img[100, 8]);
|
||||
Assert.Equal(white, img[102, 10]);
|
||||
Assert.Equal(white, img[102, 100]);
|
||||
Assert.Equal(white, img[50, 102]);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void EraseRect_works()
|
||||
{
|
||||
var img = RunQmlRendering((p) =>
|
||||
{
|
||||
p.SetBrush("#00FF00");
|
||||
p.SetBackground("#FFFFFF");
|
||||
p.FillRect(0, 0, 150, 150);
|
||||
p.EraseRect(10, 10, 10, 10);
|
||||
});
|
||||
|
||||
var green = new Rgba32(0x00, 0xFF, 0x00);
|
||||
var white = new Rgba32(0xFF, 0xFF, 0xFF);
|
||||
|
||||
Assert.Equal(green, img[0, 0]);
|
||||
Assert.Equal(green, img[9, 0]);
|
||||
Assert.Equal(green, img[0, 9]);
|
||||
|
||||
Assert.Equal(white, img[10, 10]);
|
||||
Assert.Equal(white, img[19, 10]);
|
||||
|
||||
Assert.Equal(green, img[20, 10]);
|
||||
|
||||
Assert.Equal(white, img[10, 19]);
|
||||
|
||||
Assert.Equal(green, img[10, 20]);
|
||||
|
||||
Assert.Equal(white, img[19, 19]);
|
||||
|
||||
Assert.Equal(green, img[20, 20]);
|
||||
Assert.Equal(green, img[19, 20]);
|
||||
Assert.Equal(green, img[20, 19]);
|
||||
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SetClipRect_works()
|
||||
{
|
||||
var img = RunQmlRendering((p) =>
|
||||
{
|
||||
p.SetBrush("#00FF00");
|
||||
p.SetClipRect(10, 10, 10, 10, NetQPainter.ClipOperation.IntersectClip);
|
||||
p.FillRect(0, 0, 150, 150);
|
||||
});
|
||||
|
||||
var green = new Rgba32(0x00, 0xFF, 0x00);
|
||||
var white = new Rgba32(0xFF, 0xFF, 0xFF);
|
||||
|
||||
Assert.Equal(white, img[0, 0]);
|
||||
Assert.Equal(white, img[9, 0]);
|
||||
Assert.Equal(white, img[0, 9]);
|
||||
|
||||
Assert.Equal(green, img[10, 10]);
|
||||
Assert.Equal(green, img[19, 10]);
|
||||
|
||||
Assert.Equal(white, img[20, 10]);
|
||||
|
||||
Assert.Equal(green, img[10, 19]);
|
||||
|
||||
Assert.Equal(white, img[10, 20]);
|
||||
|
||||
Assert.Equal(green, img[19, 19]);
|
||||
|
||||
Assert.Equal(white, img[20, 20]);
|
||||
Assert.Equal(white, img[19, 20]);
|
||||
Assert.Equal(white, img[20, 19]);
|
||||
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SetOpacity_works()
|
||||
{
|
||||
var img = RunQmlRendering((p) =>
|
||||
{
|
||||
p.SetOpacity(0.5);
|
||||
p.SetBrush("#00FF00");
|
||||
p.FillRect(0, 0, 150, 150);
|
||||
});
|
||||
|
||||
var opaqueGreen = new Rgba32(0x80, 0xFF, 0x80);
|
||||
|
||||
Assert.Equal(opaqueGreen, img[50, 50]);
|
||||
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Shear_works()
|
||||
{
|
||||
var img = RunQmlRendering((p) =>
|
||||
{
|
||||
p.SetPen("#00FF00", 1);
|
||||
p.Shear(0.5, 1);
|
||||
p.DrawPoint(50, 50);
|
||||
});
|
||||
|
||||
var green = new Rgba32(0x00, 0xFF, 0x00);
|
||||
|
||||
Assert.Equal(green, img[75, 100]);
|
||||
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Translate_works()
|
||||
{
|
||||
var img = RunQmlRendering((p) =>
|
||||
{
|
||||
p.SetPen("#00FF00", 1);
|
||||
p.Translate(30, 20);
|
||||
p.DrawPoint(50, 50);
|
||||
});
|
||||
|
||||
var green = new Rgba32(0x00, 0xFF, 0x00);
|
||||
|
||||
Assert.Equal(green, img[80, 70]);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public class QmlNetQuickPaintedItemTwoLevelClassHierarchyTests : BaseQmlQuickPaintedItemTests<QmlNetQuickPaintedItemTwoLevelClassHierarchyTests.TestPaintedItem>
|
||||
{
|
||||
public class TestPaintedItem : TestPaintedItemBase
|
||||
{
|
||||
public virtual string SomeProperty { get; set; }
|
||||
}
|
||||
|
||||
public class TestPaintedItemBase : QmlNetQuickPaintedItem
|
||||
{
|
||||
public virtual string SomeBaseProperty { get; set; }
|
||||
|
||||
public override void Paint(NetQPainter painter)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Can_get_and_set_additional_properties()
|
||||
{
|
||||
Mock.SetupGet(x => x.SomeProperty).Returns("Some property value");
|
||||
Mock.SetupGet(x => x.SomeBaseProperty).Returns("Some base property value");
|
||||
|
||||
RunQmlTest(
|
||||
"test",
|
||||
@"
|
||||
test.someProperty = test.someProperty
|
||||
test.someBaseProperty = test.someBaseProperty
|
||||
");
|
||||
|
||||
Mock.VerifyGet(x => x.SomeProperty, Times.Once);
|
||||
Mock.VerifyGet(x => x.SomeBaseProperty, Times.Once);
|
||||
Mock.VerifySet(x => x.SomeProperty = "Some property value");
|
||||
Mock.VerifySet(x => x.SomeBaseProperty = "Some base property value");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -36,7 +36,7 @@ namespace Qml.Net.Internal
|
|||
}
|
||||
|
||||
var baseType = typeInfo.BaseType;
|
||||
if (baseType != null)
|
||||
if (baseType != null && !Helpers.ShouldBeHiddenFromQml(baseType))
|
||||
{
|
||||
type.BaseType = baseType.AssemblyQualifiedName;
|
||||
}
|
||||
|
|
@ -58,7 +58,7 @@ namespace Qml.Net.Internal
|
|||
}
|
||||
|
||||
// Don't grab properties and methods for system-level types.
|
||||
if (Helpers.IsPrimitive(typeInfo))
|
||||
if (Helpers.IsPrimitive(typeInfo) || Helpers.ShouldBeHiddenFromQml(typeInfo))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,6 +31,17 @@ namespace Qml.Net.Internal
|
|||
return false;
|
||||
}
|
||||
|
||||
public static bool ShouldBeHiddenFromQml(Type type)
|
||||
{
|
||||
// we don't mirror QmlNetQuickPaintedItem properties and methods into QML because they (partly) mirror the QML type (QQuickPaintedItem)
|
||||
if (type == typeof(QmlNetQuickPaintedItem))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void Pack(object source, NetVariant destination, Type type)
|
||||
{
|
||||
if (type == typeof(bool))
|
||||
|
|
|
|||
|
|
@ -76,6 +76,8 @@ namespace Qml.Net.Internal
|
|||
NetQObject = LoadInteropType<NetQObjectInterop>(library, loader);
|
||||
NetQObjectSignalConnection = LoadInteropType<NetQObjectSignalConnectionInterop>(library, loader);
|
||||
QLocale = LoadInteropType<QLocaleInterop>(library, loader);
|
||||
QmlNetPaintedItem = LoadInteropType<QmlNetPaintedItemInterop>(library, loader);
|
||||
NetQPainter = LoadInteropType<NetQPainterInterop>(library, loader);
|
||||
|
||||
// RuntimeManager.ConfigureRuntimeDirectory may set these environment variables.
|
||||
// However, they only really work when called with Qt.PutEnv.
|
||||
|
|
@ -131,6 +133,10 @@ namespace Qml.Net.Internal
|
|||
public static NetQObjectSignalConnectionInterop NetQObjectSignalConnection { get; }
|
||||
|
||||
public static QLocaleInterop QLocale { get; set; }
|
||||
|
||||
public static QmlNetPaintedItemInterop QmlNetPaintedItem { get; set; }
|
||||
|
||||
public static NetQPainterInterop NetQPainter { get; set; }
|
||||
|
||||
private static T LoadInteropType<T>(IntPtr library, IPlatformLoader loader)
|
||||
where T : new()
|
||||
|
|
|
|||
779
src/net/Qml.Net/NetQPainter.cs
Normal file
779
src/net/Qml.Net/NetQPainter.cs
Normal file
|
|
@ -0,0 +1,779 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Drawing;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security;
|
||||
using Qml.Net.Internal;
|
||||
using static System.Runtime.InteropServices.UnmanagedType;
|
||||
|
||||
// ReSharper disable InconsistentNaming
|
||||
namespace Qml.Net
|
||||
{
|
||||
public class NetQPainter
|
||||
{
|
||||
private IntPtr _qPainterRef;
|
||||
private Dictionary<string, int> _registeredColors = new Dictionary<string, int>();
|
||||
private Dictionary<string, int> _registeredFontFamilies = new Dictionary<string, int>();
|
||||
|
||||
public NetQPainter(IntPtr qPainterRef)
|
||||
{
|
||||
_qPainterRef = qPainterRef;
|
||||
}
|
||||
|
||||
public void SetPen(string colorString, int width)
|
||||
{
|
||||
var colorId = GetColorId(colorString);
|
||||
Interop.NetQPainter.SetPen(_qPainterRef, colorId, width);
|
||||
}
|
||||
|
||||
public void ResetPen()
|
||||
{
|
||||
Interop.NetQPainter.ResetPen(_qPainterRef);
|
||||
}
|
||||
|
||||
public void SetBrush(string colorString)
|
||||
{
|
||||
var colorId = GetColorId(colorString);
|
||||
Interop.NetQPainter.SetBrush(_qPainterRef, colorId);
|
||||
}
|
||||
|
||||
public void ResetBrush()
|
||||
{
|
||||
Interop.NetQPainter.ResetBrush(_qPainterRef);
|
||||
}
|
||||
|
||||
public void SetFont(string fontFamilyName, bool isBold, bool isItalic, bool isUnderline, int pxSize)
|
||||
{
|
||||
int fontFamilyId = GetFontFamilyId(fontFamilyName);
|
||||
Interop.NetQPainter.SetFont(_qPainterRef, fontFamilyId, isBold, isItalic, isUnderline, pxSize);
|
||||
}
|
||||
|
||||
public void SetFontFamily(string fontFamilyName)
|
||||
{
|
||||
int fontFamilyId = GetFontFamilyId(fontFamilyName);
|
||||
Interop.NetQPainter.SetFontFamily(_qPainterRef, fontFamilyId);
|
||||
}
|
||||
|
||||
public void SetFontBold(bool isBold)
|
||||
{
|
||||
Interop.NetQPainter.SetFontBold(_qPainterRef, isBold);
|
||||
}
|
||||
|
||||
public void SetFontItalic(bool isItalic)
|
||||
{
|
||||
Interop.NetQPainter.SetFontItalic(_qPainterRef, isItalic);
|
||||
}
|
||||
|
||||
public void SetFontUnderline(bool isUnderline)
|
||||
{
|
||||
Interop.NetQPainter.SetFontUnderline(_qPainterRef, isUnderline);
|
||||
}
|
||||
|
||||
public void SetFontSize(int pxSize)
|
||||
{
|
||||
Interop.NetQPainter.SetFontSize(_qPainterRef, pxSize);
|
||||
}
|
||||
|
||||
public void DrawText(int x, int y, string text)
|
||||
{
|
||||
Interop.NetQPainter.DrawText(_qPainterRef, x, y, text);
|
||||
}
|
||||
|
||||
[Flags]
|
||||
public enum DrawTextFlags
|
||||
{
|
||||
None = 0x0000,
|
||||
AlignLeft = 0x0001,
|
||||
AlignRight = 0x0002,
|
||||
AlignHCenter = 0x0004,
|
||||
AlignJustify = 0x0008,
|
||||
AlignTop = 0x0020,
|
||||
AlignBottom = 0x0040,
|
||||
AlignVCenter = 0x0080,
|
||||
AlignCenter = AlignVCenter | AlignHCenter,
|
||||
TextSingleLine = 0x0100,
|
||||
TextDontClip = 0x0200,
|
||||
TextExpandTabs = 0x0400,
|
||||
TextShowMnemonic = 0x0800,
|
||||
TextWordWrap = 0x1000,
|
||||
TextIncludeTrailingSpaces = 0x08000000
|
||||
}
|
||||
|
||||
public void DrawText(int x, int y, int width, int height, DrawTextFlags flags, string text)
|
||||
{
|
||||
Interop.NetQPainter.DrawTextRect(_qPainterRef, x, y, width, height, (int)flags, text);
|
||||
}
|
||||
|
||||
public void DrawRect(int x, int y, int width, int height)
|
||||
{
|
||||
Interop.NetQPainter.DrawRect(_qPainterRef, x, y, width, height);
|
||||
}
|
||||
|
||||
public void FillRect(int x, int y, int width, int height, string color)
|
||||
{
|
||||
var colorId = GetColorId(color);
|
||||
Interop.NetQPainter.FillRectColor(_qPainterRef, x, y, width, height, colorId);
|
||||
}
|
||||
|
||||
public void FillRect(int x, int y, int width, int height)
|
||||
{
|
||||
Interop.NetQPainter.FillRect(_qPainterRef, x, y, width, height);
|
||||
}
|
||||
|
||||
private int RegisterColor(string colorString)
|
||||
{
|
||||
return Interop.NetQPainter.RegisterColor(_qPainterRef, colorString);
|
||||
}
|
||||
|
||||
// ReSharper disable once UnusedMember.Local
|
||||
private void FreeColor(int colorId)
|
||||
{
|
||||
Interop.NetQPainter.FreeColor(_qPainterRef, colorId);
|
||||
}
|
||||
|
||||
private int RegisterFontFamily(string fontFamily)
|
||||
{
|
||||
return Interop.NetQPainter.RegisterFontFamily(_qPainterRef, fontFamily);
|
||||
}
|
||||
|
||||
// ReSharper disable once UnusedMember.Local
|
||||
private void FreeFontFamily(int fontFamilyId)
|
||||
{
|
||||
Interop.NetQPainter.FreeFontFamily(_qPainterRef, fontFamilyId);
|
||||
}
|
||||
|
||||
public static Size GetStringSize(string fontFamily, int fontSizePx, string text)
|
||||
{
|
||||
var res = Interop.NetQPainter.GetStringSize(fontFamily, fontSizePx, text);
|
||||
return new Size(res.width, res.height);
|
||||
}
|
||||
|
||||
public void DrawArc(int x, int y, int width, int height, int startAngle, int spanAngle)
|
||||
{
|
||||
Interop.NetQPainter.DrawArc(_qPainterRef, x, y, width, height, startAngle, spanAngle);
|
||||
}
|
||||
|
||||
public void DrawChord(int x, int y, int width, int height, int startAngle, int spanAngle)
|
||||
{
|
||||
Interop.NetQPainter.DrawChord(_qPainterRef, x, y, width, height, startAngle, spanAngle);
|
||||
}
|
||||
|
||||
public void DrawConvexPolygon(Point[] points)
|
||||
{
|
||||
var count = points.Length;
|
||||
var pointsArray = new NetQPainterInterop.netqpainter_Point[count];
|
||||
for (var i = 0; i < count; i++)
|
||||
{
|
||||
var p = points[i];
|
||||
pointsArray[i] = new NetQPainterInterop.netqpainter_Point()
|
||||
{
|
||||
x = p.X,
|
||||
y = p.Y
|
||||
};
|
||||
}
|
||||
|
||||
Interop.NetQPainter.DrawConvexPolygon(_qPainterRef, pointsArray, pointsArray.Length);
|
||||
}
|
||||
|
||||
public void DrawEllipse(int x, int y, int width, int height)
|
||||
{
|
||||
Interop.NetQPainter.DrawEllipse(_qPainterRef, x, y, width, height);
|
||||
}
|
||||
|
||||
public enum ImageConversionFlag
|
||||
{
|
||||
None = 0x00000000,
|
||||
ColorMode_Mask = 0x00000003,
|
||||
AutoColor = 0x00000000,
|
||||
ColorOnly = 0x00000003,
|
||||
MonoOnly = 0x00000002,
|
||||
|
||||
AlphaDither_Mask = 0x0000000c,
|
||||
ThresholdAlphaDither = 0x00000000,
|
||||
OrderedAlphaDither = 0x00000004,
|
||||
DiffuseAlphaDither = 0x00000008,
|
||||
NoAlpha = 0x0000000c, // Not supported
|
||||
|
||||
Dither_Mask = 0x00000030,
|
||||
DiffuseDither = 0x00000000,
|
||||
OrderedDither = 0x00000010,
|
||||
ThresholdDither = 0x00000020,
|
||||
|
||||
DitherMode_Mask = 0x000000c0,
|
||||
AutoDither = 0x00000000,
|
||||
PreferDither = 0x00000040,
|
||||
AvoidDither = 0x00000080,
|
||||
|
||||
NoOpaqueDetection = 0x00000100,
|
||||
NoFormatConversion = 0x00000200
|
||||
}
|
||||
|
||||
public void DrawImage(Point start, string imagePath, Rectangle source, ImageConversionFlag flags)
|
||||
{
|
||||
var p = new NetQPainterInterop.netqpainter_Point()
|
||||
{
|
||||
x = start.X,
|
||||
y = start.Y
|
||||
};
|
||||
var sourceRect = new NetQPainterInterop.netqpainter_Rect()
|
||||
{
|
||||
x = source.X,
|
||||
y = source.Y,
|
||||
width = source.Width,
|
||||
height = source.Height
|
||||
};
|
||||
Interop.NetQPainter.DrawImageFile(_qPainterRef, p, imagePath, sourceRect, flags);
|
||||
}
|
||||
|
||||
public void DrawImage(Point start, byte[] imageData, Rectangle source, ImageConversionFlag flags)
|
||||
{
|
||||
var p = new NetQPainterInterop.netqpainter_Point()
|
||||
{
|
||||
x = start.X,
|
||||
y = start.Y
|
||||
};
|
||||
var sourceRect = new NetQPainterInterop.netqpainter_Rect()
|
||||
{
|
||||
x = source.X,
|
||||
y = source.Y,
|
||||
width = source.Width,
|
||||
height = source.Height
|
||||
};
|
||||
Interop.NetQPainter.DrawImage(_qPainterRef, p, imageData, imageData.Length, sourceRect, flags);
|
||||
}
|
||||
|
||||
public void DrawLine(int x1, int y1, int x2, int y2)
|
||||
{
|
||||
Interop.NetQPainter.DrawLine(_qPainterRef, x1, y1, x2, y2);
|
||||
}
|
||||
|
||||
public void DrawPie(int x, int y, int width, int height, int startAngle, int spanAngle)
|
||||
{
|
||||
Interop.NetQPainter.DrawPie(_qPainterRef, x, y, width, height, startAngle, spanAngle);
|
||||
}
|
||||
|
||||
public void DrawPoint(int x, int y)
|
||||
{
|
||||
Interop.NetQPainter.DrawPoint(_qPainterRef, x, y);
|
||||
}
|
||||
|
||||
public void DrawPolygon(Point[] points, bool oddFill)
|
||||
{
|
||||
var count = points.Length;
|
||||
var pointsArray = new NetQPainterInterop.netqpainter_Point[count];
|
||||
for (var i = 0; i < count; i++)
|
||||
{
|
||||
var p = points[i];
|
||||
pointsArray[i] = new NetQPainterInterop.netqpainter_Point()
|
||||
{
|
||||
x = p.X,
|
||||
y = p.Y
|
||||
};
|
||||
}
|
||||
|
||||
Interop.NetQPainter.DrawPolygon(_qPainterRef, pointsArray, pointsArray.Length, oddFill);
|
||||
}
|
||||
|
||||
public void DrawPolyline(Point[] points)
|
||||
{
|
||||
var count = points.Length;
|
||||
var pointsArray = new NetQPainterInterop.netqpainter_Point[count];
|
||||
for (var i = 0; i < count; i++)
|
||||
{
|
||||
var p = points[i];
|
||||
pointsArray[i] = new NetQPainterInterop.netqpainter_Point()
|
||||
{
|
||||
x = p.X,
|
||||
y = p.Y
|
||||
};
|
||||
}
|
||||
|
||||
Interop.NetQPainter.DrawPolyline(_qPainterRef, pointsArray, pointsArray.Length);
|
||||
}
|
||||
|
||||
public void DrawRoundedRect(int x, int y, int w, int h, double xRadius, double yRadius, bool absoluteSize)
|
||||
{
|
||||
Interop.NetQPainter.DrawRoundedRect(_qPainterRef, x, y, w, h, xRadius, yRadius, absoluteSize);
|
||||
}
|
||||
|
||||
public void EraseRect(int x, int y, int width, int height)
|
||||
{
|
||||
Interop.NetQPainter.EraseRect(_qPainterRef, x, y, width, height);
|
||||
}
|
||||
|
||||
public void SetBackground(string color)
|
||||
{
|
||||
var colorId = GetColorId(color);
|
||||
Interop.NetQPainter.SetBackground(_qPainterRef, colorId);
|
||||
}
|
||||
|
||||
public void SetBackgroundMode(bool opaque)
|
||||
{
|
||||
Interop.NetQPainter.SetBackgroundMode(_qPainterRef, opaque);
|
||||
}
|
||||
|
||||
public enum ClipOperation
|
||||
{
|
||||
NoClip = 1,
|
||||
ReplaceClip,
|
||||
IntersectClip
|
||||
}
|
||||
|
||||
public void SetClipRect(int x, int y, int width, int height, ClipOperation operation)
|
||||
{
|
||||
Interop.NetQPainter.SetClipRect(_qPainterRef, x, y, width, height, operation);
|
||||
}
|
||||
|
||||
public void SetClipping(bool enable)
|
||||
{
|
||||
Interop.NetQPainter.SetClipping(_qPainterRef, enable);
|
||||
}
|
||||
|
||||
public enum CompositionMode
|
||||
{
|
||||
CompositionMode_SourceOver = 1,
|
||||
CompositionMode_DestinationOver,
|
||||
CompositionMode_Clear,
|
||||
CompositionMode_Source,
|
||||
CompositionMode_Destination,
|
||||
CompositionMode_SourceIn,
|
||||
CompositionMode_DestinationIn,
|
||||
CompositionMode_SourceOut,
|
||||
CompositionMode_DestinationOut,
|
||||
CompositionMode_SourceAtop,
|
||||
CompositionMode_DestinationAtop,
|
||||
CompositionMode_Xor,
|
||||
|
||||
// svg 1.2 blend modes
|
||||
CompositionMode_Plus,
|
||||
CompositionMode_Multiply,
|
||||
CompositionMode_Screen,
|
||||
CompositionMode_Overlay,
|
||||
CompositionMode_Darken,
|
||||
CompositionMode_Lighten,
|
||||
CompositionMode_ColorDodge,
|
||||
CompositionMode_ColorBurn,
|
||||
CompositionMode_HardLight,
|
||||
CompositionMode_SoftLight,
|
||||
CompositionMode_Difference,
|
||||
CompositionMode_Exclusion,
|
||||
|
||||
// ROPs
|
||||
RasterOp_SourceOrDestination,
|
||||
RasterOp_SourceAndDestination,
|
||||
RasterOp_SourceXorDestination,
|
||||
RasterOp_NotSourceAndNotDestination,
|
||||
RasterOp_NotSourceOrNotDestination,
|
||||
RasterOp_NotSourceXorDestination,
|
||||
RasterOp_NotSource,
|
||||
RasterOp_NotSourceAndDestination,
|
||||
RasterOp_SourceAndNotDestination,
|
||||
RasterOp_NotSourceOrDestination,
|
||||
RasterOp_SourceOrNotDestination,
|
||||
RasterOp_ClearDestination,
|
||||
RasterOp_SetDestination,
|
||||
RasterOp_NotDestination
|
||||
}
|
||||
|
||||
public void SetCompositionMode(CompositionMode mode)
|
||||
{
|
||||
Interop.NetQPainter.SetCompositionMode(_qPainterRef, mode);
|
||||
}
|
||||
|
||||
public enum LayoutDirection
|
||||
{
|
||||
LeftToRight = 1,
|
||||
RightToLeft,
|
||||
LayoutDirectionAuto
|
||||
}
|
||||
|
||||
public void SetLayoutDirection(LayoutDirection direction)
|
||||
{
|
||||
Interop.NetQPainter.SetLayoutDirection(_qPainterRef, direction);
|
||||
}
|
||||
|
||||
public void SetOpacity(double opacity)
|
||||
{
|
||||
Interop.NetQPainter.SetOpacity(_qPainterRef, opacity);
|
||||
}
|
||||
|
||||
public enum RenderHint
|
||||
{
|
||||
Antialiasing = 0x01,
|
||||
TextAntialiasing = 0x02,
|
||||
SmoothPixmapTransform = 0x04,
|
||||
Qt4CompatiblePainting = 0x20,
|
||||
LosslessImageRendering = 0x40,
|
||||
}
|
||||
|
||||
public void SetRenderHint(RenderHint hint, bool on)
|
||||
{
|
||||
Interop.NetQPainter.SetRenderHint(_qPainterRef, hint, on);
|
||||
}
|
||||
|
||||
public void Shear(double sh, double sv)
|
||||
{
|
||||
Interop.NetQPainter.Shear(_qPainterRef, sh, sv);
|
||||
}
|
||||
|
||||
public void Translate(double dx, double dy)
|
||||
{
|
||||
Interop.NetQPainter.Translate(_qPainterRef, dx, dy);
|
||||
}
|
||||
|
||||
private int GetColorId(string colorString)
|
||||
{
|
||||
if (_registeredColors.ContainsKey(colorString))
|
||||
{
|
||||
return _registeredColors[colorString];
|
||||
}
|
||||
|
||||
var colorId = RegisterColor(colorString);
|
||||
_registeredColors.Add(colorString, colorId);
|
||||
return colorId;
|
||||
}
|
||||
|
||||
private int GetFontFamilyId(string fontFamilyName)
|
||||
{
|
||||
if (_registeredFontFamilies.ContainsKey(fontFamilyName))
|
||||
{
|
||||
return _registeredFontFamilies[fontFamilyName];
|
||||
}
|
||||
|
||||
var fontFamilyId = RegisterFontFamily(fontFamilyName);
|
||||
_registeredFontFamilies.Add(fontFamilyName, fontFamilyId);
|
||||
return fontFamilyId;
|
||||
}
|
||||
}
|
||||
|
||||
[SuppressMessage("ReSharper", "UnusedAutoPropertyAccessor.Global", Justification = "Properties get set via Reflection")]
|
||||
internal class NetQPainterInterop
|
||||
{
|
||||
[NativeSymbol(Entrypoint = "netqpainter_setPen")]
|
||||
public SetPenDel SetPen { get; set; }
|
||||
|
||||
[SuppressUnmanagedCodeSecurity]
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
public delegate void SetPenDel(IntPtr paintedItem, int colorId, int width);
|
||||
|
||||
[NativeSymbol(Entrypoint = "netqpainter_resetPen")]
|
||||
public ResetPenDel ResetPen { get; set; }
|
||||
|
||||
[SuppressUnmanagedCodeSecurity]
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
public delegate void ResetPenDel(IntPtr paintedItem);
|
||||
|
||||
[NativeSymbol(Entrypoint = "netqpainter_setBrush")]
|
||||
public SetBrushDel SetBrush { get; set; }
|
||||
|
||||
[SuppressUnmanagedCodeSecurity]
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
public delegate void SetBrushDel(IntPtr paintedItem, int colorId);
|
||||
|
||||
[NativeSymbol(Entrypoint = "netqpainter_resetBrush")]
|
||||
public ResetBrushDel ResetBrush { get; set; }
|
||||
|
||||
[SuppressUnmanagedCodeSecurity]
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
public delegate void ResetBrushDel(IntPtr paintedItem);
|
||||
|
||||
[NativeSymbol(Entrypoint = "netqpainter_setFont")]
|
||||
public SetFontDel SetFont { get; set; }
|
||||
|
||||
[SuppressUnmanagedCodeSecurity]
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
public delegate void SetFontDel(IntPtr paintedItem, int fontFamilyId, bool isBold, bool isItalic, bool isUnderline, int pxSize);
|
||||
|
||||
[NativeSymbol(Entrypoint = "netqpainter_setFontFamily")]
|
||||
public SetFontFamilyDel SetFontFamily { get; set; }
|
||||
|
||||
[SuppressUnmanagedCodeSecurity]
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
public delegate void SetFontFamilyDel(IntPtr paintedItem, int fontFamilyId);
|
||||
|
||||
[NativeSymbol(Entrypoint = "netqpainter_setFontBold")]
|
||||
public SetFontBoldDel SetFontBold { get; set; }
|
||||
|
||||
[SuppressUnmanagedCodeSecurity]
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
public delegate void SetFontBoldDel(IntPtr paintedItem, bool isBold);
|
||||
|
||||
[NativeSymbol(Entrypoint = "netqpainter_setFontItalic")]
|
||||
public SetFontItalicDel SetFontItalic { get; set; }
|
||||
|
||||
[SuppressUnmanagedCodeSecurity]
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
public delegate void SetFontItalicDel(IntPtr paintedItem, bool isItalic);
|
||||
|
||||
[NativeSymbol(Entrypoint = "netqpainter_setFontUnderline")]
|
||||
public SetFontUnderlineDel SetFontUnderline { get; set; }
|
||||
|
||||
[SuppressUnmanagedCodeSecurity]
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
public delegate void SetFontUnderlineDel(IntPtr paintedItem, bool isUnderline);
|
||||
|
||||
[NativeSymbol(Entrypoint = "netqpainter_setFontSize")]
|
||||
public SetFontSizeDel SetFontSize { get; set; }
|
||||
|
||||
[SuppressUnmanagedCodeSecurity]
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
public delegate void SetFontSizeDel(IntPtr paintedItem, int pxSize);
|
||||
|
||||
[NativeSymbol(Entrypoint = "netqpainter_drawText")]
|
||||
public DrawTextDel DrawText { get; set; }
|
||||
|
||||
[SuppressUnmanagedCodeSecurity]
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
public delegate void DrawTextDel(IntPtr paintedItem, int x, int y, [MarshalAs(LPWStr)] string text);
|
||||
|
||||
[NativeSymbol(Entrypoint = "netqpainter_drawTextRect")]
|
||||
public DrawTextRectDel DrawTextRect { get; set; }
|
||||
|
||||
[SuppressUnmanagedCodeSecurity]
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
public delegate void DrawTextRectDel(IntPtr paintedItem, int x, int y, int width, int height, int flags, [MarshalAs(LPWStr)] string text);
|
||||
|
||||
[NativeSymbol(Entrypoint = "netqpainter_drawRect")]
|
||||
public DrawRectDel DrawRect { get; set; }
|
||||
|
||||
[SuppressUnmanagedCodeSecurity]
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
public delegate void DrawRectDel(IntPtr paintedItem, int x, int y, int width, int height);
|
||||
|
||||
[NativeSymbol(Entrypoint = "netqpainter_fillRectColor")]
|
||||
public FillRectColorDel FillRectColor { get; set; }
|
||||
|
||||
[SuppressUnmanagedCodeSecurity]
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
public delegate void FillRectColorDel(IntPtr paintedItem, int x, int y, int width, int height, int colorId);
|
||||
|
||||
[NativeSymbol(Entrypoint = "netqpainter_fillRect")]
|
||||
public FillRectDel FillRect { get; set; }
|
||||
|
||||
[SuppressUnmanagedCodeSecurity]
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
public delegate void FillRectDel(IntPtr paintedItem, int x, int y, int width, int height);
|
||||
|
||||
[NativeSymbol(Entrypoint = "netqpainter_registerColor")]
|
||||
public RegisterColorDel RegisterColor { get; set; }
|
||||
|
||||
[SuppressUnmanagedCodeSecurity]
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
public delegate int RegisterColorDel(IntPtr paintedItem, [MarshalAs(LPWStr)] string colorString);
|
||||
|
||||
[NativeSymbol(Entrypoint = "netqpainter_freeColor")]
|
||||
public FreeColorDel FreeColor { get; set; }
|
||||
|
||||
[SuppressUnmanagedCodeSecurity]
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
public delegate void FreeColorDel(IntPtr paintedItem, int colorId);
|
||||
|
||||
[NativeSymbol(Entrypoint = "netqpainter_registerFontFamily")]
|
||||
public RegisterFontFamilyDel RegisterFontFamily { get; set; }
|
||||
|
||||
[SuppressUnmanagedCodeSecurity]
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
public delegate int RegisterFontFamilyDel(
|
||||
IntPtr paintedItem,
|
||||
[MarshalAs(LPWStr)] string fontFamilyString);
|
||||
|
||||
[NativeSymbol(Entrypoint = "netqpainter_freeFontFamily")]
|
||||
public FreeFontFamilyDel FreeFontFamily { get; set; }
|
||||
|
||||
[SuppressUnmanagedCodeSecurity]
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
public delegate void FreeFontFamilyDel(IntPtr paintedItem, int fontFamilyId);
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct StringSizeResult
|
||||
{
|
||||
public int width;
|
||||
public int height;
|
||||
}
|
||||
|
||||
[NativeSymbol(Entrypoint = "netqpainter_getStringSize")]
|
||||
public GetStringSizeDel GetStringSize { get; set; }
|
||||
|
||||
[SuppressUnmanagedCodeSecurity]
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
public delegate StringSizeResult GetStringSizeDel([MarshalAs(LPWStr)] string fontFamily, int sizePx, [MarshalAs(LPWStr)] string text);
|
||||
|
||||
[NativeSymbol(Entrypoint = "netqpainter_drawArc")]
|
||||
public DrawArcDel DrawArc { get; set; }
|
||||
|
||||
[SuppressUnmanagedCodeSecurity]
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
public delegate void DrawArcDel(IntPtr paintedItem, int x, int y, int width, int height, int startAngle, int spanAngle);
|
||||
|
||||
[NativeSymbol(Entrypoint = "netqpainter_drawChord")]
|
||||
public DrawChordDel DrawChord { get; set; }
|
||||
|
||||
[SuppressUnmanagedCodeSecurity]
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
public delegate void DrawChordDel(IntPtr paintedItem, int x, int y, int width, int height, int startAngle, int spanAngle);
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct netqpainter_Point
|
||||
{
|
||||
public int x;
|
||||
public int y;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct netqpainter_Rect
|
||||
{
|
||||
public int x;
|
||||
public int y;
|
||||
public int width;
|
||||
public int height;
|
||||
}
|
||||
|
||||
[NativeSymbol(Entrypoint = "netqpainter_drawConvexPolygon")]
|
||||
public DrawConvexPolygonDel DrawConvexPolygon { get; set; }
|
||||
|
||||
[SuppressUnmanagedCodeSecurity]
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
public delegate void DrawConvexPolygonDel(IntPtr paintedItem, netqpainter_Point[] points, int pointCount);
|
||||
|
||||
[NativeSymbol(Entrypoint = "netqpainter_drawEllipse")]
|
||||
public DrawEllipseDel DrawEllipse { get; set; }
|
||||
|
||||
[SuppressUnmanagedCodeSecurity]
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
public delegate void DrawEllipseDel(IntPtr paintedItem, int x, int y, int width, int height);
|
||||
|
||||
[NativeSymbol(Entrypoint = "netqpainter_drawImage")]
|
||||
public DrawImageDel DrawImage { get; set; }
|
||||
|
||||
[SuppressUnmanagedCodeSecurity]
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
public delegate void DrawImageDel(IntPtr paintedItem, netqpainter_Point point, byte[] imgData, int imgDataSize, netqpainter_Rect sourceRect, NetQPainter.ImageConversionFlag flags);
|
||||
|
||||
[NativeSymbol(Entrypoint = "netqpainter_drawImageFile")]
|
||||
public DrawImageFileDel DrawImageFile { get; set; }
|
||||
|
||||
[SuppressUnmanagedCodeSecurity]
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
public delegate void DrawImageFileDel(IntPtr paintedItem, netqpainter_Point point, [MarshalAs(LPWStr)] string imageFilePath, netqpainter_Rect sourceRect, NetQPainter.ImageConversionFlag flags);
|
||||
|
||||
[NativeSymbol(Entrypoint = "netqpainter_drawLine")]
|
||||
public DrawLineDel DrawLine { get; set; }
|
||||
|
||||
[SuppressUnmanagedCodeSecurity]
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
public delegate void DrawLineDel(IntPtr paintedItem, int x1, int y1, int x2, int y2);
|
||||
|
||||
[NativeSymbol(Entrypoint = "netqpainter_drawPie")]
|
||||
public DrawPieDel DrawPie { get; set; }
|
||||
|
||||
[SuppressUnmanagedCodeSecurity]
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
public delegate void DrawPieDel(IntPtr paintedItem, int x, int y, int width, int height, int startAngle, int spanAngle);
|
||||
|
||||
[NativeSymbol(Entrypoint = "netqpainter_drawPoint")]
|
||||
public DrawPointDel DrawPoint { get; set; }
|
||||
|
||||
[SuppressUnmanagedCodeSecurity]
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
public delegate void DrawPointDel(IntPtr paintedItem, int x, int y);
|
||||
|
||||
[NativeSymbol(Entrypoint = "netqpainter_drawPolygon")]
|
||||
public DrawPolygonDel DrawPolygon { get; set; }
|
||||
|
||||
[SuppressUnmanagedCodeSecurity]
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
public delegate void DrawPolygonDel(IntPtr paintedItem, netqpainter_Point[] points, int pointCount, bool oddFill);
|
||||
|
||||
[NativeSymbol(Entrypoint = "netqpainter_drawPolyline")]
|
||||
public DrawPolylineDel DrawPolyline { get; set; }
|
||||
|
||||
[SuppressUnmanagedCodeSecurity]
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
public delegate void DrawPolylineDel(IntPtr paintedItem, netqpainter_Point[] points, int pointCount);
|
||||
|
||||
[NativeSymbol(Entrypoint = "netqpainter_drawRoundedRect")]
|
||||
public DrawRoundedRectDel DrawRoundedRect { get; set; }
|
||||
|
||||
[SuppressUnmanagedCodeSecurity]
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
public delegate void DrawRoundedRectDel(IntPtr paintedItem, int x, int y, int w, int h, double xRadius, double yRadius, bool absoluteSize);
|
||||
|
||||
[NativeSymbol(Entrypoint = "netqpainter_eraseRect")]
|
||||
public EraseRectDel EraseRect { get; set; }
|
||||
|
||||
[SuppressUnmanagedCodeSecurity]
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
public delegate void EraseRectDel(IntPtr paintedItem, int x, int y, int width, int height);
|
||||
|
||||
[NativeSymbol(Entrypoint = "netqpainter_setBackground")]
|
||||
public SetBackgroundDel SetBackground { get; set; }
|
||||
|
||||
[SuppressUnmanagedCodeSecurity]
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
public delegate void SetBackgroundDel(IntPtr paintedItem, int colorId);
|
||||
|
||||
[NativeSymbol(Entrypoint = "netqpainter_setBackgroundMode")]
|
||||
public SetBackgroundModeDel SetBackgroundMode { get; set; }
|
||||
|
||||
[SuppressUnmanagedCodeSecurity]
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
public delegate void SetBackgroundModeDel(IntPtr paintedItem, bool opaque);
|
||||
|
||||
[NativeSymbol(Entrypoint = "netqpainter_setClipRect")]
|
||||
public SetClipRectDel SetClipRect { get; set; }
|
||||
|
||||
[SuppressUnmanagedCodeSecurity]
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
public delegate void SetClipRectDel(IntPtr paintedItem, int x, int y, int width, int height, NetQPainter.ClipOperation operation);
|
||||
|
||||
[NativeSymbol(Entrypoint = "netqpainter_setClipping")]
|
||||
public SetClippingDel SetClipping { get; set; }
|
||||
|
||||
[SuppressUnmanagedCodeSecurity]
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
public delegate void SetClippingDel(IntPtr paintedItem, bool enable);
|
||||
|
||||
[NativeSymbol(Entrypoint = "netqpainter_setCompositionMode")]
|
||||
public SetCompositionModeDel SetCompositionMode { get; set; }
|
||||
|
||||
[SuppressUnmanagedCodeSecurity]
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
public delegate void SetCompositionModeDel(IntPtr paintedItem, NetQPainter.CompositionMode mode);
|
||||
|
||||
[NativeSymbol(Entrypoint = "netqpainter_setLayoutDirection")]
|
||||
public SetLayoutDirectionDel SetLayoutDirection { get; set; }
|
||||
|
||||
[SuppressUnmanagedCodeSecurity]
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
public delegate void SetLayoutDirectionDel(IntPtr paintedItem, NetQPainter.LayoutDirection dir);
|
||||
|
||||
[NativeSymbol(Entrypoint = "netqpainter_setOpacity")]
|
||||
public SetOpacityDel SetOpacity { get; set; }
|
||||
|
||||
[SuppressUnmanagedCodeSecurity]
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
public delegate void SetOpacityDel(IntPtr paintedItem, double opacity);
|
||||
|
||||
[NativeSymbol(Entrypoint = "netqpainter_setRenderHint")]
|
||||
public SetRenderHintDel SetRenderHint { get; set; }
|
||||
|
||||
[SuppressUnmanagedCodeSecurity]
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
public delegate void SetRenderHintDel(IntPtr paintedItem, NetQPainter.RenderHint hint, bool on);
|
||||
|
||||
[NativeSymbol(Entrypoint = "netqpainter_shear")]
|
||||
public ShearDel Shear { get; set; }
|
||||
|
||||
[SuppressUnmanagedCodeSecurity]
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
public delegate void ShearDel(IntPtr paintedItem, double sh, double sv);
|
||||
|
||||
[NativeSymbol(Entrypoint = "netqpainter_translate")]
|
||||
public TranslateDel Translate { get; set; }
|
||||
|
||||
[SuppressUnmanagedCodeSecurity]
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
public delegate void TranslateDel(IntPtr paintedItem, double dx, double dy);
|
||||
}
|
||||
}
|
||||
|
|
@ -434,6 +434,13 @@ namespace Qml.Net
|
|||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
public delegate void AddCallbacksDel(IntPtr app, ref QCoreAppCallbacks callbacks);
|
||||
|
||||
[NativeSymbol(Entrypoint = "qapp_setWindowIcon")]
|
||||
public SetWindowIconDel SetWindowIcon { get; set; }
|
||||
|
||||
[SuppressUnmanagedCodeSecurity]
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
public delegate void SetWindowIconDel(IntPtr app, [MarshalAs(UnmanagedType.LPWStr)]string pngFilePath);
|
||||
|
||||
[NativeSymbol(Entrypoint = "qapp_requestTrigger")]
|
||||
public RequestTriggerDel RequestTrigger { get; set; }
|
||||
|
||||
|
|
|
|||
|
|
@ -24,5 +24,10 @@ namespace Qml.Net
|
|||
: base(existingApp)
|
||||
{
|
||||
}
|
||||
|
||||
public void SetWindowIcon(string pngFilePath)
|
||||
{
|
||||
Interop.QCoreApplication.SetWindowIcon(Handle, pngFilePath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -80,6 +80,11 @@ namespace Qml.Net
|
|||
return Interop.QQmlApplicationEngine.RegisterType(type.Handle, uri, versionMajor, versionMinor, qmlName);
|
||||
}
|
||||
|
||||
internal static int RegisterPaintedQuickItemType(NetTypeInfo type, string uri, string qmlName, int versionMajor = 1, int versionMinor = 0)
|
||||
{
|
||||
return Interop.QQmlApplicationEngine.RegisterPaintedQuickItemType(type.Handle, uri, versionMajor, versionMinor, qmlName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Activates the MVVM behavior.
|
||||
/// This Behavior automatically connects INotifyPropertyChanged instances with appropriate signals on the QML side
|
||||
|
|
@ -137,6 +142,13 @@ namespace Qml.Net
|
|||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
public delegate int RegisterTypeDel(IntPtr type, [MarshalAs(UnmanagedType.LPWStr)]string uri, int versionMajor, int versionMinor, [MarshalAs(UnmanagedType.LPWStr)]string qmlName);
|
||||
|
||||
[NativeSymbol(Entrypoint = "qqmlapplicationengine_registerPaintedQuickItemType")]
|
||||
public RegisterPaintedQuickItemTypeDel RegisterPaintedQuickItemType { get; set; }
|
||||
|
||||
[SuppressUnmanagedCodeSecurity]
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
public delegate int RegisterPaintedQuickItemTypeDel(IntPtr type, [MarshalAs(UnmanagedType.LPWStr)]string uri, int versionMajor, int versionMinor, [MarshalAs(UnmanagedType.LPWStr)]string qmlName);
|
||||
|
||||
[NativeSymbol(Entrypoint = "qqmlapplicationengine_registerSingletonTypeQml")]
|
||||
public RegisterSingletonTypeQmlDel RegisterSingletonTypeQml { get; set; }
|
||||
|
||||
|
|
|
|||
|
|
@ -20,6 +20,20 @@ namespace Qml.Net
|
|||
}
|
||||
}
|
||||
|
||||
public static int RegisterPaintedQuickItemType<T>(string uri, int versionMajor = 1, int versionMinor = 0)
|
||||
where T : QmlNetQuickPaintedItem
|
||||
{
|
||||
return RegisterPaintedQuickItemType(typeof(T), typeof(T).Name, uri, versionMajor, versionMinor);
|
||||
}
|
||||
|
||||
public static int RegisterPaintedQuickItemType(Type type, string qmlName, string uri, int versionMajor = 1, int versionMinor = 0)
|
||||
{
|
||||
using (var typeInfo = NetTypeManager.GetTypeInfo(type))
|
||||
{
|
||||
return QQmlApplicationEngine.RegisterPaintedQuickItemType(typeInfo, uri, qmlName, versionMajor, versionMinor);
|
||||
}
|
||||
}
|
||||
|
||||
public static int RegisterSingletonType(string url, string qmlName, string uri, int versionMajor = 1, int versionMinor = 0)
|
||||
{
|
||||
return Interop.QQmlApplicationEngine.RegisterSingletonTypeQml(url, uri, versionMajor, versionMinor, qmlName);
|
||||
|
|
|
|||
206
src/net/Qml.Net/QmlNetQuickPaintedItem.cs
Normal file
206
src/net/Qml.Net/QmlNetQuickPaintedItem.cs
Normal file
|
|
@ -0,0 +1,206 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security;
|
||||
using Qml.Net.Internal;
|
||||
using Qml.Net.Internal.Types;
|
||||
using static System.Runtime.InteropServices.UnmanagedType;
|
||||
|
||||
namespace Qml.Net
|
||||
{
|
||||
public abstract class QmlNetQuickPaintedItem
|
||||
{
|
||||
private IntPtr _ref;
|
||||
|
||||
public int Height => _ref != IntPtr.Zero ? Interop.QmlNetPaintedItem.GetHeight(_ref) : 0;
|
||||
|
||||
public int Width => _ref != IntPtr.Zero ? Interop.QmlNetPaintedItem.GetWidth(_ref) : 0;
|
||||
|
||||
public QmlNetQuickPaintedItem()
|
||||
{
|
||||
if (_callbacks == null)
|
||||
{
|
||||
_callbacks = new QmlNetPaintedItemCallbacksImpl();
|
||||
}
|
||||
}
|
||||
|
||||
internal void SetRef(IntPtr @ref)
|
||||
{
|
||||
_ref = @ref;
|
||||
}
|
||||
|
||||
public void Update()
|
||||
{
|
||||
if (_ref != IntPtr.Zero)
|
||||
{
|
||||
Interop.QmlNetPaintedItem.Update(_ref);
|
||||
}
|
||||
}
|
||||
|
||||
public byte[] PaintToImage(string format)
|
||||
{
|
||||
var arrayPtr = Interop.QmlNetPaintedItem.PaintToImage(_ref, out var size, format);
|
||||
byte[] result = new byte[size];
|
||||
Marshal.Copy(arrayPtr, result, 0, (int)size);
|
||||
Marshal.FreeHGlobal(arrayPtr);
|
||||
return result;
|
||||
}
|
||||
|
||||
public abstract void Paint(NetQPainter painter);
|
||||
|
||||
public virtual void OnHeightChanged(int height)
|
||||
{
|
||||
}
|
||||
|
||||
public virtual void OnWidthChanged(int width)
|
||||
{
|
||||
}
|
||||
|
||||
private static QmlNetPaintedItemCallbacksImpl _callbacks;
|
||||
}
|
||||
|
||||
internal class QmlNetPaintedItemCallbacksImpl
|
||||
{
|
||||
private List<GCHandle> _handles = new List<GCHandle>();
|
||||
|
||||
internal QmlNetPaintedItemCallbacksImpl()
|
||||
{
|
||||
_setRef = SetRef;
|
||||
_handles.Add(GCHandle.Alloc(_setRef));
|
||||
_paint = Paint;
|
||||
_handles.Add(GCHandle.Alloc(_paint));
|
||||
_heightChanged = HeightChanged;
|
||||
_handles.Add(GCHandle.Alloc(_heightChanged));
|
||||
_widthChanged = WidthChanged;
|
||||
_handles.Add(GCHandle.Alloc(_widthChanged));
|
||||
|
||||
var cb = Callbacks();
|
||||
|
||||
Interop.QmlNetPaintedItem.SetCallbacks(ref cb);
|
||||
}
|
||||
|
||||
~QmlNetPaintedItemCallbacksImpl()
|
||||
{
|
||||
foreach (var gcHandle in _handles)
|
||||
{
|
||||
gcHandle.Free();
|
||||
}
|
||||
_handles.Clear();
|
||||
}
|
||||
|
||||
internal QmlNetPaintedItemCallbacks Callbacks()
|
||||
{
|
||||
return new QmlNetPaintedItemCallbacks
|
||||
{
|
||||
SetRef = Marshal.GetFunctionPointerForDelegate(_setRef),
|
||||
Paint = Marshal.GetFunctionPointerForDelegate(_paint),
|
||||
HeightChanged = Marshal.GetFunctionPointerForDelegate(_heightChanged),
|
||||
WidthChanged = Marshal.GetFunctionPointerForDelegate(_widthChanged)
|
||||
};
|
||||
}
|
||||
|
||||
SetRefDel _setRef;
|
||||
PaintDel _paint;
|
||||
HeightChangedDel _heightChanged;
|
||||
WidthChangedDel _widthChanged;
|
||||
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
[SuppressUnmanagedCodeSecurity]
|
||||
delegate void SetRefDel(ulong objectId, IntPtr @ref);
|
||||
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
[SuppressUnmanagedCodeSecurity]
|
||||
delegate void PaintDel(ulong objectId, IntPtr netQPainter);
|
||||
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
[SuppressUnmanagedCodeSecurity]
|
||||
delegate void HeightChangedDel(ulong objectId, int height);
|
||||
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
[SuppressUnmanagedCodeSecurity]
|
||||
delegate void WidthChangedDel(ulong objectId, int height);
|
||||
|
||||
internal void SetRef(ulong objectId, IntPtr @ref)
|
||||
{
|
||||
object obj = null;
|
||||
if (ObjectIdReferenceTracker.TryGetObjectFor(objectId, out obj))
|
||||
{
|
||||
(obj as QmlNetQuickPaintedItem)?.SetRef(@ref);
|
||||
}
|
||||
}
|
||||
|
||||
internal void Paint(ulong objectId, IntPtr netQPainter)
|
||||
{
|
||||
object obj = null;
|
||||
if (ObjectIdReferenceTracker.TryGetObjectFor(objectId, out obj))
|
||||
{
|
||||
(obj as QmlNetQuickPaintedItem)?.Paint(new NetQPainter(netQPainter));
|
||||
}
|
||||
}
|
||||
|
||||
internal void HeightChanged(ulong objectId, int height)
|
||||
{
|
||||
object obj = null;
|
||||
if (ObjectIdReferenceTracker.TryGetObjectFor(objectId, out obj))
|
||||
{
|
||||
(obj as QmlNetQuickPaintedItem)?.OnHeightChanged(height);
|
||||
}
|
||||
}
|
||||
|
||||
internal void WidthChanged(ulong objectId, int width)
|
||||
{
|
||||
object obj = null;
|
||||
if (ObjectIdReferenceTracker.TryGetObjectFor(objectId, out obj))
|
||||
{
|
||||
(obj as QmlNetQuickPaintedItem)?.OnWidthChanged(width);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal struct QmlNetPaintedItemCallbacks
|
||||
{
|
||||
public IntPtr SetRef;
|
||||
public IntPtr Paint;
|
||||
public IntPtr HeightChanged;
|
||||
public IntPtr WidthChanged;
|
||||
}
|
||||
|
||||
internal class QmlNetPaintedItemInterop
|
||||
{
|
||||
[NativeSymbol(Entrypoint = "qqmlnetpainteditembase_setCallbacks")]
|
||||
public SetCallbacksDel SetCallbacks { get; set; }
|
||||
|
||||
[SuppressUnmanagedCodeSecurity]
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
public delegate void SetCallbacksDel(ref QmlNetPaintedItemCallbacks callbacks);
|
||||
|
||||
[NativeSymbol(Entrypoint = "qqmlnetpainteditembase_update")]
|
||||
public UpdateDel Update { get; set; }
|
||||
|
||||
[SuppressUnmanagedCodeSecurity]
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
public delegate void UpdateDel(IntPtr paintedItem);
|
||||
|
||||
[NativeSymbol(Entrypoint = "qqmlnetpainteditembase_getHeight")]
|
||||
public GetHeightDel GetHeight { get; set; }
|
||||
|
||||
[SuppressUnmanagedCodeSecurity]
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
public delegate int GetHeightDel(IntPtr paintedItem);
|
||||
|
||||
[NativeSymbol(Entrypoint = "qqmlnetpainteditembase_getWidth")]
|
||||
public GetWidthDel GetWidth { get; set; }
|
||||
|
||||
[SuppressUnmanagedCodeSecurity]
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
public delegate int GetWidthDel(IntPtr paintedItem);
|
||||
|
||||
[NativeSymbol(Entrypoint = "qqmlnetpainteditembase_paintToImage")]
|
||||
public PaintToImageDel PaintToImage { get; set; }
|
||||
|
||||
[SuppressUnmanagedCodeSecurity]
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
public delegate IntPtr PaintToImageDel(IntPtr paintedItem, out long sizeOut, [MarshalAs(LPWStr)] string format);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue