mirror of
https://gitee.com/csharpui/CPF.git
synced 2025-04-05 17:37:51 +08:00
Merge branch 'master' into Toolkit
This commit is contained in:
commit
0a12d33d15
@ -9,198 +9,159 @@ using System.Runtime.InteropServices;
|
||||
namespace CPF.Skia
|
||||
{
|
||||
/// <summary>
|
||||
/// 支持OpenGL绘制的控件
|
||||
/// 支持OpenGL绘制的控件,在GLRender事件里绘制,开启GPU硬件加速才能使用 new SkiaDrawingFactory { UseGPU = true }
|
||||
/// </summary>
|
||||
public class GlView : CPF.UIElement
|
||||
public class GLView : UIElement
|
||||
{
|
||||
int fb;
|
||||
int texture;
|
||||
//int[] g_Renderbuffer;
|
||||
int Id;
|
||||
int ColorBuffer;
|
||||
int DepthRenderBuffer;
|
||||
Size oldSize;
|
||||
bool f;
|
||||
protected override void OnRender(DrawingContext dc)
|
||||
SKImage image;
|
||||
SKPaint paint;
|
||||
GRBackendTexture backendTexture;
|
||||
/// <summary>
|
||||
/// 支持OpenGL绘制的控件,在GLRender事件里绘制,开启GPU硬件加速才能使用 new SkiaDrawingFactory { UseGPU = true }
|
||||
/// </summary>
|
||||
public GLView() { }
|
||||
|
||||
//IGlContext context;
|
||||
protected unsafe override void OnRender(DrawingContext dc)
|
||||
{
|
||||
var size1 = ActualSize;
|
||||
if (size1.Width <= 0 || size1.Height <= 0 || DesignMode)
|
||||
var cSize = ActualSize;
|
||||
if (cSize.Width <= 0 || cSize.Height <= 0 || DesignMode)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var size = new PixelSize((int)Math.Round(size1.Width * Root.RenderScaling), (int)Math.Round(size1.Height * Root.RenderScaling));
|
||||
var size = new PixelSize((int)Math.Round(cSize.Width * Root.RenderScaling), (int)Math.Round(cSize.Height * Root.RenderScaling));
|
||||
var skia = dc as SkiaDrawingContext;
|
||||
var gl = skia.GlContext;
|
||||
|
||||
var fbs = new int[1];
|
||||
if (fb == 0)
|
||||
var _gl = skia.GlContext;
|
||||
if (paint == null)
|
||||
{
|
||||
gl.GenFramebuffers(1, fbs);
|
||||
fb = fbs[0];
|
||||
paint = new SKPaint();
|
||||
}
|
||||
else
|
||||
paint.IsAntialias = IsAntiAlias;
|
||||
paint.FilterQuality = IsAntiAlias ? SKFilterQuality.Medium : SKFilterQuality.None;
|
||||
|
||||
if (Id == 0)
|
||||
{
|
||||
fbs[0] = fb;
|
||||
Id = _gl.GenFramebuffer();
|
||||
ColorBuffer = _gl.GenTexture();
|
||||
DepthRenderBuffer = _gl.GenRenderbuffer();
|
||||
|
||||
_gl.BindTexture(GlConsts.GL_TEXTURE_2D, ColorBuffer);
|
||||
|
||||
_gl.TexParameteri(GlConsts.GL_TEXTURE_2D, GlConsts.GL_TEXTURE_MIN_FILTER, (int)GlConsts.GL_LINEAR);
|
||||
_gl.TexParameteri(GlConsts.GL_TEXTURE_2D, GlConsts.GL_TEXTURE_MAG_FILTER, GlConsts.GL_LINEAR);
|
||||
|
||||
_gl.BindTexture(GlConsts.GL_TEXTURE_2D, 0);
|
||||
|
||||
|
||||
OnGLLoaded(_gl);
|
||||
}
|
||||
gl.GetIntegerv(GlConsts.GL_FRAMEBUFFER_BINDING, out var oldfb);
|
||||
gl.GetIntegerv(GlConsts.GL_TEXTURE_BINDING_2D, out var oldTexture);
|
||||
gl.GetIntegerv(GlConsts.GL_RENDERBUFFER_BINDING, out var oldRenderbuffer);
|
||||
gl.Enable(GlConsts.GL_TEXTURE_2D);
|
||||
|
||||
//保存旧的状态
|
||||
gl.PushAttrib(GlConsts.GL_VIEWPORT_BIT);
|
||||
gl.MatrixMode(GlConsts.GL_PROJECTION);
|
||||
gl.PushMatrix();
|
||||
gl.MatrixMode(GlConsts.GL_MODELVIEW);
|
||||
gl.PushMatrix();
|
||||
|
||||
gl.BindFramebuffer(GlConsts.GL_FRAMEBUFFER, fb);
|
||||
|
||||
if (size1 != oldSize)
|
||||
if (cSize != oldSize)
|
||||
{
|
||||
oldSize = size1;
|
||||
oldSize = cSize;
|
||||
|
||||
var textures = new int[1] { texture };
|
||||
_gl.BindTexture(GlConsts.GL_TEXTURE_2D, ColorBuffer);
|
||||
_gl.TexImage2D(GlConsts.GL_TEXTURE_2D, 0, GlConsts.GL_RGBA, (int)size.Width, (int)size.Height, 0, GlConsts.GL_RGB, GlConsts.GL_UNSIGNED_BYTE, IntPtr.Zero);
|
||||
_gl.BindTexture(GlConsts.GL_TEXTURE_2D, 0);
|
||||
|
||||
if (texture > 0)
|
||||
_gl.BindRenderbuffer(GlConsts.GL_RENDERBUFFER, DepthRenderBuffer);
|
||||
_gl.RenderbufferStorage(GlConsts.GL_RENDERBUFFER, GlConsts.GL_DEPTH32F_STENCIL8, (int)size.Width, (int)size.Height);
|
||||
|
||||
_gl.BindRenderbuffer(GlConsts.GL_RENDERBUFFER, 0);
|
||||
|
||||
_gl.BindFramebuffer(GlConsts.GL_FRAMEBUFFER, Id);
|
||||
|
||||
_gl.FramebufferTexture2D(GlConsts.GL_FRAMEBUFFER, GlConsts.GL_COLOR_ATTACHMENT0, GlConsts.GL_TEXTURE_2D, ColorBuffer, 0);
|
||||
|
||||
_gl.FramebufferRenderbuffer(GlConsts.GL_FRAMEBUFFER, GlConsts.GL_DEPTH_STENCIL_ATTACHMENT, GlConsts.GL_RENDERBUFFER, DepthRenderBuffer);
|
||||
_gl.BindFramebuffer(GlConsts.GL_FRAMEBUFFER, 0);
|
||||
|
||||
|
||||
if (image != null)
|
||||
{
|
||||
gl.DeleteTextures(1, textures);
|
||||
//gl.DeleteRenderbuffers(1, g_Renderbuffer);
|
||||
image.Dispose();
|
||||
}
|
||||
|
||||
gl.GenTextures(1, textures);
|
||||
texture = textures[0];
|
||||
//gl.ActiveTexture(GlConsts.GL_TEXTURE0);
|
||||
gl.BindTexture(GlConsts.GL_TEXTURE_2D, textures[0]);
|
||||
gl.TexImage2D(GlConsts.GL_TEXTURE_2D, 0, GlConsts.GL_RGBA8, (int)size.Width, (int)size.Height, 0, GlConsts.GL_RGBA, GlConsts.GL_UNSIGNED_BYTE, IntPtr.Zero);
|
||||
gl.TexParameteri(GlConsts.GL_TEXTURE_2D, GlConsts.GL_TEXTURE_MAG_FILTER, GlConsts.GL_NEAREST);
|
||||
gl.TexParameteri(GlConsts.GL_TEXTURE_2D, GlConsts.GL_TEXTURE_MIN_FILTER, GlConsts.GL_NEAREST);
|
||||
gl.FramebufferTexture2D(GlConsts.GL_FRAMEBUFFER, GlConsts.GL_COLOR_ATTACHMENT0, GlConsts.GL_TEXTURE_2D, texture, 0);
|
||||
//gl.BindTexture(GlConsts.GL_TEXTURE_2D, 0);
|
||||
|
||||
//g_Renderbuffer = new int[1];
|
||||
//gl.GenRenderbuffers(1, g_Renderbuffer);
|
||||
//gl.BindRenderbuffer(GlConsts.GL_RENDERBUFFER, g_Renderbuffer[0]);
|
||||
//gl.RenderbufferStorage(GlConsts.GL_RENDERBUFFER, GlConsts.GL_DEPTH_COMPONENT, (int)size.Width, (int)size.Height);
|
||||
//gl.FramebufferRenderbuffer(GlConsts.GL_FRAMEBUFFER, GlConsts.GL_DEPTH_ATTACHMENT, GlConsts.GL_RENDERBUFFER, g_Renderbuffer[0]);
|
||||
//gl.BindRenderbuffer(GlConsts.GL_RENDERBUFFER_EXT, 0);
|
||||
|
||||
}
|
||||
//gl.BindTexture(GlConsts.GL_TEXTURE_2D, texture);
|
||||
// gl.BindRenderbuffer(GlConsts.GL_RENDERBUFFER, g_Renderbuffer[0]);
|
||||
// GlConsts.GL_FRAMEBUFFER_COMPLETE
|
||||
var status = gl.CheckFramebufferStatus(GlConsts.GL_FRAMEBUFFER);
|
||||
gl.Viewport(0, 0, size.Width, size.Height);
|
||||
|
||||
|
||||
//var MODELVIEW = new float[16];
|
||||
//gl.GetFloatv(GlConsts.GL_MODELVIEW_MATRIX, MODELVIEW);
|
||||
|
||||
|
||||
//var status = gl.CheckFramebufferStatus(GlConsts.GL_FRAMEBUFFER) == GlConsts.GL_FRAMEBUFFER_COMPLETE;
|
||||
|
||||
//if (!f)
|
||||
{
|
||||
OnGlRender(skia.GlContext, size);
|
||||
f = true;
|
||||
}
|
||||
|
||||
//var framebufferInfo = new GRGlFramebufferInfo((uint)fb, SKColorType.Rgba8888.ToGlSizedFormat());
|
||||
|
||||
//gl.GetIntegerv(GlConsts.GL_FRAMEBUFFER_BINDING, out var framebuffer);
|
||||
//gl.GetIntegerv(3415, out var stencil);
|
||||
//gl.GetIntegerv(32937, out var samples);
|
||||
gl.BindRenderbuffer(GlConsts.GL_RENDERBUFFER, oldRenderbuffer);
|
||||
gl.BindTexture(GlConsts.GL_TEXTURE_2D, oldTexture);
|
||||
gl.BindFramebuffer(GlConsts.GL_FRAMEBUFFER, oldfb);
|
||||
// using (var backendTexture = new GRBackendRenderTarget(size.Width, size.Height, samples, stencil, framebufferInfo))
|
||||
using (var backendTexture = new GRBackendTexture((int)size.Width, (int)size.Height, false, new GRGlTextureInfo { Format = GlConsts.GL_RGBA8, Id = (uint)texture, Target = GlConsts.GL_TEXTURE_2D }))
|
||||
{
|
||||
// using (var surface = SKSurface.Create((GRContext)skia.GlContext.GRContext, backendTexture, GRSurfaceOrigin.TopLeft, SKColorType.Rgba8888))
|
||||
using (var surface = SKSurface.Create((GRContext)skia.GlContext.GRContext, backendTexture, GRSurfaceOrigin.TopLeft, SKColorType.Rgba8888))
|
||||
if (backendTexture != null)
|
||||
{
|
||||
//if (surface == null)
|
||||
// return;
|
||||
//byte[] data = new byte[size.Width * size.Height * 4];
|
||||
//gl.GetTexImage(GlConsts.GL_TEXTURE_2D, 0, GlConsts.GL_RGBA, GlConsts.GL_UNSIGNED_BYTE, data);
|
||||
|
||||
//System.Diagnostics.Debug.WriteLine($"{oldfb},{oldRenderbuffer},{oldTexture}");
|
||||
|
||||
//恢复状态
|
||||
gl.MatrixMode(GlConsts.GL_MODELVIEW);
|
||||
gl.PopMatrix();
|
||||
gl.MatrixMode(GlConsts.GL_PROJECTION);
|
||||
gl.PopMatrix();
|
||||
gl.PopAttrib();
|
||||
|
||||
skia.SKCanvas.DrawSurface(surface, 0, 0);
|
||||
backendTexture.Dispose();
|
||||
}
|
||||
backendTexture = new GRBackendTexture((int)(size.Width), (int)(size.Height), false, new GRGlTextureInfo(0x0DE1, (uint)ColorBuffer, SKColorType.Rgba8888.ToGlSizedFormat()));
|
||||
|
||||
image = SKImage.FromTexture((GRContext)skia.GlContext.GRContext, backendTexture, GRSurfaceOrigin.BottomLeft, SKColorType.Rgba8888);
|
||||
}
|
||||
//unsafe
|
||||
//{
|
||||
// fixed (byte* p = data)
|
||||
// {
|
||||
// using (var bitmap = new Bitmap(size.Width, size.Height, size.Width * 4, PixelFormat.Rgba, (IntPtr)p))
|
||||
// {
|
||||
// dc.DrawImage(bitmap, new Rect(0, 0, size.Width, size.Height), new Rect(0, 0, size.Width, size.Height));
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
//gl.DeleteTextures(1, textures);
|
||||
//gl.DeleteRenderbuffers(1, g_Renderbuffer);
|
||||
//gl.DeleteFramebuffers(1, fbs);
|
||||
base.OnRender(dc);
|
||||
|
||||
_gl.BindFramebuffer(GlConsts.GL_FRAMEBUFFER, Id);
|
||||
var vp = new float[4];
|
||||
_gl.GetFloatv(GlConsts.GL_VIEWPORT, vp);
|
||||
_gl.Viewport(0, 0, (int)size.Width, (int)size.Height);
|
||||
OnGLRender(_gl);
|
||||
_gl.Viewport((int)vp[0], (int)vp[1], (int)vp[2], (int)vp[3]);
|
||||
_gl.BindFramebuffer(GlConsts.GL_FRAMEBUFFER, 0);
|
||||
//_gl.Flush();
|
||||
skia.SKCanvas.DrawImage(image, new SKRect(0, 0, size.Width, size.Height), new SKRect(0, 0, cSize.Width, cSize.Height), paint);
|
||||
}
|
||||
|
||||
Random random = new Random();
|
||||
protected void OnGlRender(IGlContext gl, PixelSize viewPort)
|
||||
|
||||
protected virtual void OnGLRender(IGlContext gl)
|
||||
{
|
||||
gl.MatrixMode(GlConsts.GL_PROJECTION);
|
||||
// gl.LoadIdentity();
|
||||
//gl.Ortho(-250, 250, -250, 250, -100, 100);
|
||||
gl.MatrixMode(GlConsts.GL_MODELVIEW);
|
||||
gl.LoadIdentity();
|
||||
//var PROJECTION = new float[4];
|
||||
//gl.GetFloatv(GlConsts.GL_VIEWPORT, PROJECTION);
|
||||
gl.ClearColor((float)random.NextDouble(), 0.25f, 0.75f, 0.5f);
|
||||
gl.Clear(GlConsts.GL_COLOR_BUFFER_BIT);
|
||||
gl.Color4f(1, 1, 1, 1);
|
||||
gl.Begin(GlConsts.GL_TRIANGLES); // Drawing Using Triangles
|
||||
// gl.Color4f(1.0f, 0.0f, 0.0f, 1); // Set The Color To Red
|
||||
gl.Vertex3f(0.0f, 0.0f, 0.0f); // Top
|
||||
// gl.Color4f(0.0f, 1.0f, 0.0f, 1); // Set The Color To Green
|
||||
gl.Vertex3f(-1.0f, -1.0f, 0.0f); // Bottom Left
|
||||
// gl.Color4f(0.0f, 0.0f, 1.0f, 1); // Set The Color To Blue
|
||||
gl.Vertex3f(1.0f, -1.0f, 0.0f); // Bottom Right
|
||||
// Drawing Using Triangles
|
||||
// gl.Color4f(1.0f, 0.0f, 0.0f, 1); // Set The Color To Red
|
||||
gl.Vertex3f((float)viewPort.Width, (float)viewPort.Height, 0.0f); // Top
|
||||
// gl.Color4f(0.0f, 1.0f, 0.0f, 1); // Set The Color To Green
|
||||
gl.Vertex3f(-1.0f, 21.0f, 0.0f); // Bottom Left
|
||||
// gl.Color4f(0.0f, 0.0f, 1.0f, 1); // Set The Color To Blue
|
||||
gl.Vertex3f(21.0f, 5.0f, 0.0f); // Bottom Right
|
||||
gl.End();
|
||||
|
||||
var PROJECTION = new float[16];
|
||||
gl.GetFloatv(GlConsts.GL_PROJECTION_MATRIX, PROJECTION);
|
||||
|
||||
this.RaiseEvent(new GLEventArgs(gl), nameof(GLRender));
|
||||
}
|
||||
|
||||
protected virtual void OnGLLoaded(IGlContext gl)
|
||||
{
|
||||
this.RaiseEvent(new GLEventArgs(gl), nameof(GLLoaded));
|
||||
}
|
||||
|
||||
public event EventHandler<GLEventArgs> GLLoaded
|
||||
{
|
||||
add { AddHandler(value); }
|
||||
remove { RemoveHandler(value); }
|
||||
}
|
||||
public event EventHandler<GLEventArgs> GLRender
|
||||
{
|
||||
add { AddHandler(value); }
|
||||
remove { RemoveHandler(value); }
|
||||
}
|
||||
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (Id != 0)
|
||||
{
|
||||
OpenglEx.DeleteFramebuffers(null, 1, new int[] { Id });
|
||||
OpenglEx.DeleteTextures(null, 1, new int[] { ColorBuffer });
|
||||
OpenglEx.DeleteRenderbuffers(null, 1, new int[] { DepthRenderBuffer });
|
||||
Id = 0;
|
||||
}
|
||||
if (image != null)
|
||||
{
|
||||
image.Dispose();
|
||||
image = null;
|
||||
}
|
||||
if (paint != null)
|
||||
{
|
||||
paint.Dispose();
|
||||
paint = null;
|
||||
}
|
||||
if (backendTexture != null)
|
||||
{
|
||||
backendTexture.Dispose();
|
||||
backendTexture = null;
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
if (fb > 0)
|
||||
{
|
||||
OpenglEx.DeleteFramebuffers(null, 1, new int[] { fb });
|
||||
fb = 0;
|
||||
}
|
||||
if (texture > 0)
|
||||
{
|
||||
OpenglEx.DeleteTextures(null, 1, new int[] { texture });
|
||||
//OpenglEx.DeleteRenderbuffers(null, 1, g_Renderbuffer);
|
||||
texture = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//[DllImport("opengl32", SetLastError = true)]
|
||||
//private static extern void glOrtho(double left, double right, double bottom, double top, double zNear, double zFar);
|
||||
public class GLEventArgs : EventArgs
|
||||
{
|
||||
public GLEventArgs(IGlContext gl)
|
||||
{
|
||||
Context = gl;
|
||||
}
|
||||
public IGlContext Context { get; private set; }
|
||||
}
|
||||
}
|
||||
|
@ -156,6 +156,11 @@ namespace CPF.Skia
|
||||
surface.Dispose();
|
||||
surface = null;
|
||||
}
|
||||
if (gRContext != null)
|
||||
{
|
||||
//gRContext.Flush();
|
||||
gRContext.ResetContext();
|
||||
}
|
||||
//if (grContext != null)
|
||||
//{
|
||||
// //grContext.Flush();
|
||||
@ -729,7 +734,7 @@ namespace CPF.Skia
|
||||
}
|
||||
lines = newText.Split('\n');
|
||||
var ws = paint.Paint.MeasureAllChar(lines[0]);
|
||||
|
||||
|
||||
var wsEnd = new List<(string, float)>();
|
||||
for (int i = ws.Count - 1; i >= 0; i--)
|
||||
{
|
||||
@ -742,7 +747,7 @@ namespace CPF.Skia
|
||||
{
|
||||
//lenEnd = (lenEnd.Item1, lenEnd.Item2, newText.Substring(newText.Length - lenEnd.Item1, lenEnd.Item1));
|
||||
lenEnd.Item3 = newText.Substring(newText.Length - lenEnd.Item1, lenEnd.Item1);
|
||||
if (lenEnd.Item3.Length>2)
|
||||
if (lenEnd.Item3.Length > 2)
|
||||
{
|
||||
lenEnd.Item3 = lenEnd.Item3.Substring(1, lenEnd.Item3.Length - 1);
|
||||
}
|
||||
|
@ -807,6 +807,7 @@ namespace CPF.Windows
|
||||
}
|
||||
break;
|
||||
case WindowsMessage.WM_DESTROY:
|
||||
Closed?.Invoke();
|
||||
if (handle != IntPtr.Zero)
|
||||
{
|
||||
try
|
||||
@ -857,7 +858,6 @@ namespace CPF.Windows
|
||||
RenderBitmap = null;
|
||||
}
|
||||
handle = IntPtr.Zero;
|
||||
Closed?.Invoke();
|
||||
foreach (var item in invokeQueue)
|
||||
{
|
||||
item.SendOrPostCallback(item.Data);
|
||||
|
@ -226,15 +226,31 @@ namespace CPF
|
||||
BindingMode = bindingMode;
|
||||
}
|
||||
internal Binding() { }
|
||||
|
||||
/// <summary>
|
||||
/// 多级绑定的属性集合
|
||||
/// </summary>
|
||||
string[] sourcePropertyNames;
|
||||
internal bool IsDataContext = true;
|
||||
|
||||
string sourcePropertyName;
|
||||
/// <summary>
|
||||
/// 数据源字段名
|
||||
/// </summary>
|
||||
public string SourcePropertyName
|
||||
{
|
||||
get;
|
||||
internal set;
|
||||
get { return sourcePropertyName; }
|
||||
internal set
|
||||
{
|
||||
sourcePropertyName = value;
|
||||
if (value != null)
|
||||
{
|
||||
sourcePropertyNames = SourcePropertyName.Split('.');
|
||||
}
|
||||
else
|
||||
{
|
||||
sourcePropertyNames = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 链式绑定下标
|
||||
@ -362,7 +378,7 @@ namespace CPF
|
||||
current.Push(this);
|
||||
try
|
||||
{
|
||||
|
||||
|
||||
if (Source == null || !Source.IsAlive)
|
||||
{
|
||||
if (Owner.HasProperty(TargetPropertyName))
|
||||
@ -389,8 +405,9 @@ namespace CPF
|
||||
value = Source.Target.GetPropretyValue(SourcePropertyName);
|
||||
}*/
|
||||
value = GetPropertySource(SourcePropertyName, Source.Target);
|
||||
if (value != null) {
|
||||
value = value.GetPropretyValue(SourcePropertyName.Split('.').LastOrDefault());
|
||||
if (value != null)
|
||||
{
|
||||
value = value.GetPropretyValue(sourcePropertyNames.LastOrDefault());
|
||||
}
|
||||
if (Convert != null)
|
||||
{
|
||||
@ -456,7 +473,7 @@ namespace CPF
|
||||
{
|
||||
if (!b.SetValue(nv, SourcePropertyName))
|
||||
{
|
||||
/*var SourcePropertyNames = SourcePropertyName.Split('.');
|
||||
/*var SourcePropertyNames = sourcePropertyNames;
|
||||
if (SourcePropertyNames.Length == 1)
|
||||
{
|
||||
b.SetValue(SourcePropertyName, nv);
|
||||
@ -466,12 +483,13 @@ namespace CPF
|
||||
{
|
||||
Target = Target.GetPropretyValue(SourcePropertyNames[i]) as CpfObject;
|
||||
}*/
|
||||
var SourcePropertyNames = SourcePropertyName.Split('.');
|
||||
var SourcePropertyNames = sourcePropertyNames;
|
||||
var Target = GetPropertySource(SourcePropertyName, b);
|
||||
if (Target != null) {
|
||||
if (Target != null)
|
||||
{
|
||||
Target.SetValue(SourcePropertyNames.LastOrDefault(), nv);
|
||||
}
|
||||
|
||||
|
||||
//b.Type.GetProperty(SourcePropertyName).FastSetValue(b, nv);
|
||||
}
|
||||
}
|
||||
@ -551,7 +569,7 @@ namespace CPF
|
||||
}
|
||||
void PropertyChanged(object sender, PropertyChangedEventArgs e)
|
||||
{
|
||||
var Temp_SourcePropertyName = SourcePropertyName.Split('.').LastOrDefault();
|
||||
var Temp_SourcePropertyName = sourcePropertyNames.LastOrDefault();
|
||||
if (Temp_SourcePropertyName == e.PropertyName)
|
||||
{
|
||||
//CPFObject s = sender as CPFObject;
|
||||
@ -576,11 +594,11 @@ namespace CPF
|
||||
}
|
||||
}
|
||||
}
|
||||
internal object GetPropertySource(string SourcePropertyName,object Source)
|
||||
internal object GetPropertySource(string SourcePropertyName, object Source)
|
||||
{
|
||||
try
|
||||
{
|
||||
var SourcePropertyNames = SourcePropertyName.Split('.');
|
||||
var SourcePropertyNames = sourcePropertyNames;
|
||||
if (SourcePropertyNames.Length == 1)
|
||||
{
|
||||
return Source;
|
||||
@ -610,7 +628,7 @@ namespace CPF
|
||||
BindingMode == BindingMode.OneWay ||
|
||||
BindingMode == BindingMode.OneTime)
|
||||
{
|
||||
var SourcePropertyNames = SourcePropertyName.Split('.');
|
||||
var SourcePropertyNames = sourcePropertyNames;
|
||||
var Temp_Target = GetPropertySource(SourcePropertyName, Source.Target);
|
||||
var data = (Temp_Target as CpfObject)?.GetValue(SourcePropertyNames.LastOrDefault());
|
||||
Owner.SetPropretyValue(TargetPropertyName, data);
|
||||
@ -624,7 +642,7 @@ namespace CPF
|
||||
//{
|
||||
// throw new Exception("错误");
|
||||
//}
|
||||
var SourcePropertyNames = SourcePropertyName.Split('.');
|
||||
var SourcePropertyNames = sourcePropertyNames;
|
||||
if (SourcePropertyNames.Length == 1)
|
||||
{
|
||||
RegisterPropertyChanged(notify, PropertyChanged);
|
||||
|
@ -24,23 +24,48 @@ namespace CPF
|
||||
PropertyName = sourceProperty;
|
||||
BindingMode = binding;
|
||||
}
|
||||
/// <summary>
|
||||
/// 设置绑定
|
||||
/// </summary>
|
||||
/// <param name="source">如果是int或者byte,0是自己,1是Parent,2是Parent.Parent....</param>
|
||||
/// <param name="sourceProperty"></param>
|
||||
/// <param name="binding"></param>
|
||||
public BindingDescribe(object source, string sourceProperty, BindingMode binding)
|
||||
{
|
||||
PropertyName = sourceProperty;
|
||||
BindingMode = binding;
|
||||
Source = source;
|
||||
}
|
||||
/// <summary>
|
||||
/// 设置绑定
|
||||
/// </summary>
|
||||
/// <param name="source">如果是int或者byte,0是自己,1是Parent,2是Parent.Parent....</param>
|
||||
/// <param name="source"></param>
|
||||
/// <param name="sourceProperty"></param>
|
||||
public BindingDescribe(object source, string sourceProperty)
|
||||
{
|
||||
PropertyName = sourceProperty;
|
||||
Source = source;
|
||||
}
|
||||
/// <summary>
|
||||
/// 设置绑定
|
||||
/// </summary>
|
||||
/// <param name="source">如果是int或者byte,0是自己,1是Parent,2是Parent.Parent....</param>
|
||||
/// <param name="sourceProperty"></param>
|
||||
/// <param name="convert"></param>
|
||||
public BindingDescribe(object source, string sourceProperty, Func<object, object> convert)
|
||||
{
|
||||
PropertyName = sourceProperty;
|
||||
Source = source;
|
||||
Convert = convert;
|
||||
}
|
||||
/// <summary>
|
||||
/// 设置绑定
|
||||
/// </summary>
|
||||
/// <param name="source">如果是int或者byte,0是自己,1是Parent,2是Parent.Parent....</param>
|
||||
/// <param name="sourceProperty"></param>
|
||||
/// <param name="binding"></param>
|
||||
/// <param name="convert"></param>
|
||||
public BindingDescribe(object source, string sourceProperty, BindingMode binding, Func<object, object> convert)
|
||||
{
|
||||
BindingMode = binding;
|
||||
@ -48,6 +73,14 @@ namespace CPF
|
||||
Source = source;
|
||||
Convert = convert;
|
||||
}
|
||||
/// <summary>
|
||||
/// 设置绑定
|
||||
/// </summary>
|
||||
/// <param name="source">如果是int或者byte,0是自己,1是Parent,2是Parent.Parent....</param>
|
||||
/// <param name="sourceProperty"></param>
|
||||
/// <param name="binding"></param>
|
||||
/// <param name="convert"></param>
|
||||
/// <param name="convertBack"></param>
|
||||
public BindingDescribe(object source, string sourceProperty, BindingMode binding, Func<object, object> convert, Func<object, object> convertBack)
|
||||
{
|
||||
BindingMode = binding;
|
||||
@ -56,6 +89,16 @@ namespace CPF
|
||||
Convert = convert;
|
||||
ConvertBack = convertBack;
|
||||
}
|
||||
/// <summary>
|
||||
/// 设置绑定
|
||||
/// </summary>
|
||||
/// <param name="source">如果是int或者byte,0是自己,1是Parent,2是Parent.Parent....</param>
|
||||
/// <param name="sourceProperty"></param>
|
||||
/// <param name="binding"></param>
|
||||
/// <param name="convert"></param>
|
||||
/// <param name="convertBack"></param>
|
||||
/// <param name="SourceToTargetError"></param>
|
||||
/// <param name="TargetToSourceError"></param>
|
||||
public BindingDescribe(object source, string sourceProperty, BindingMode binding, Func<object, object> convert, Func<object, object> convertBack, Action<Binding, object, Exception> SourceToTargetError, Action<Binding, object, Exception> TargetToSourceError)
|
||||
{
|
||||
BindingMode = binding;
|
||||
@ -82,6 +125,10 @@ namespace CPF
|
||||
/// 简化绑定命令的命令,如果设置了该属性,则使用命令绑定
|
||||
/// </summary>
|
||||
public CommandDescribe Command { get; set; }
|
||||
/// <summary>
|
||||
/// 简化触发器设置
|
||||
/// </summary>
|
||||
public CPF.Styling.TriggerDescribe Trigger { get; set; }
|
||||
|
||||
//public CpfObject Owner { get; internal set; }
|
||||
|
||||
@ -357,6 +404,10 @@ namespace CPF
|
||||
{
|
||||
return new BindingDescribe { Command = command };
|
||||
}
|
||||
public static implicit operator BindingDescribe(CPF.Styling.TriggerDescribe trigger)
|
||||
{
|
||||
return new BindingDescribe { Trigger = trigger };
|
||||
}
|
||||
public static implicit operator BindingDescribe((string sourceProperty, BindingMode binding) item)
|
||||
{
|
||||
return new BindingDescribe { PropertyName = item.sourceProperty, BindingMode = item.binding };
|
||||
|
@ -10,7 +10,7 @@ namespace CPF.Controls
|
||||
/// 内容模板
|
||||
/// </summary>
|
||||
[Description("内容模板"), Browsable(false)]
|
||||
public class ContentTemplate : Decorator
|
||||
public class ContentTemplate : Control
|
||||
{
|
||||
[PropertyMetadata(null)]
|
||||
public object Content
|
||||
@ -85,9 +85,56 @@ namespace CPF.Controls
|
||||
overridePropertys.Override(nameof(Width), new UIPropertyMetadataAttribute(typeof(FloatField), "100%", UIPropertyOptions.AffectsMeasure));
|
||||
overridePropertys.Override(nameof(Height), new UIPropertyMetadataAttribute(typeof(FloatField), "100%", UIPropertyOptions.AffectsMeasure));
|
||||
}
|
||||
//protected override Size MeasureOverride(in Size availableSize)
|
||||
|
||||
/// <summary>
|
||||
/// 获取或设置 单一子元素。
|
||||
/// </summary>
|
||||
[Browsable(false)]
|
||||
protected UIElement Child
|
||||
{
|
||||
get { return GetValue<UIElement>(); }
|
||||
set { SetValue(value); }
|
||||
}
|
||||
|
||||
[PropertyChanged(nameof(Child))]
|
||||
void OnChild(object newValue, object oldValue, PropertyMetadataAttribute attribute)
|
||||
{
|
||||
var o = oldValue as UIElement;
|
||||
if (o != null)
|
||||
{
|
||||
Children.Remove(o);
|
||||
}
|
||||
var c = newValue as UIElement;
|
||||
if (c != null)
|
||||
{
|
||||
Children.Add(c);
|
||||
}
|
||||
}
|
||||
//protected override void OnPropertyChanged(string propertyName, object oldValue, object newValue, PropertyMetadataAttribute propertyMetadata)
|
||||
//{
|
||||
// return base.MeasureOverride(availableSize);
|
||||
// base.OnPropertyChanged(propertyName, oldValue, newValue, propertyMetadata);
|
||||
// if (propertyName == nameof(Child))
|
||||
// {
|
||||
// var o = oldValue as UIElement;
|
||||
// if (o != null)
|
||||
// {
|
||||
// Children.Remove(o);
|
||||
// }
|
||||
// var c = newValue as UIElement;
|
||||
// if (c != null)
|
||||
// {
|
||||
// Children.Add(c);
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
|
||||
protected override void OnUIElementRemoved(UIElementRemovedEventArgs e)
|
||||
{
|
||||
base.OnUIElementRemoved(e);
|
||||
if (e.Element == Child)
|
||||
{
|
||||
Child = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -90,8 +90,11 @@ namespace CPF.Controls
|
||||
Name = "contentPresenter",
|
||||
PresenterFor = this
|
||||
});
|
||||
Triggers.Add(new Styling.Trigger { Property = nameof(IsMouseOver), PropertyConditions = a => (bool)a && !IsSelected, Setters = { { nameof(Background), "229,243,251" } } });
|
||||
Triggers.Add(new Styling.Trigger { Property = nameof(IsSelected), Setters = { { nameof(Background), "203,233,246" } } });
|
||||
//Triggers.Add(new Styling.Trigger { Property = nameof(IsMouseOver), PropertyConditions = a => (bool)a && !IsSelected, Setters = { { nameof(Background), "229,243,251" } } });
|
||||
//Triggers.Add(new Styling.Trigger { Property = nameof(IsSelected), Setters = { { nameof(Background), "203,233,246" } } });
|
||||
|
||||
this[nameof(IsMouseOver)] = new Styling.TriggerDescribe(a => (bool)a && !IsSelected, (nameof(Background), "229,243,251"));
|
||||
this[nameof(IsSelected)] = new Styling.TriggerDescribe((nameof(Background), "203,233,246"));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -214,12 +214,33 @@ namespace CPF
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (value.Trigger != null)
|
||||
{
|
||||
OnAddTriggerDescribe(propertyName, value.Trigger);
|
||||
}
|
||||
else
|
||||
{
|
||||
Bindings.Add(propertyName, value.PropertyName, value.Source, value.BindingMode, value.Convert, value.ConvertBack, value.SourceToTargetError, value.TargetToSourceError);
|
||||
if (value.Source is int layer)
|
||||
{
|
||||
Bindings.Add(propertyName, value.PropertyName, (byte)layer, value.BindingMode, value.Convert, value.ConvertBack, value.SourceToTargetError, value.TargetToSourceError);
|
||||
}
|
||||
if (value.Source is byte layer1)
|
||||
{
|
||||
Bindings.Add(propertyName, value.PropertyName, layer1, value.BindingMode, value.Convert, value.ConvertBack, value.SourceToTargetError, value.TargetToSourceError);
|
||||
}
|
||||
else
|
||||
{
|
||||
Bindings.Add(propertyName, value.PropertyName, value.Source, value.BindingMode, value.Convert, value.ConvertBack, value.SourceToTargetError, value.TargetToSourceError);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal protected virtual void OnAddTriggerDescribe(string property, TriggerDescribe trigger)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 读取或者设置附加属性,参数必须是附加属性
|
||||
/// </summary>
|
||||
|
@ -12,7 +12,7 @@ namespace CPF.OpenGL
|
||||
/// 用来获取和保存Skia创建的GRContext
|
||||
/// </summary>
|
||||
IDisposable GRContext { get; set; }
|
||||
//void MakeCurrent();
|
||||
void MakeCurrent();
|
||||
//void SwapBuffers();
|
||||
//void Dispose();
|
||||
//public abstract GRGlTextureInfo CreateTexture(SKSizeI textureSize);
|
||||
@ -35,7 +35,7 @@ namespace CPF.OpenGL
|
||||
public static class OpenglEx
|
||||
{
|
||||
static bool loaded;
|
||||
private static void Load(IGlContext context)
|
||||
public static void Load(IGlContext context)
|
||||
{
|
||||
if (!loaded)
|
||||
{
|
||||
@ -124,13 +124,13 @@ namespace CPF.OpenGL
|
||||
flush();
|
||||
}
|
||||
|
||||
[GlImport("glFinish")]
|
||||
static Action finish;
|
||||
public static void Finish(this IGlContext context)
|
||||
{
|
||||
Load(context);
|
||||
finish();
|
||||
}
|
||||
//[GlImport("glFinish")]
|
||||
//static Action finish;
|
||||
//public static void Finish(this IGlContext context)
|
||||
//{
|
||||
// Load(context);
|
||||
// finish();
|
||||
//}
|
||||
|
||||
public delegate IntPtr GlGetString(int v);
|
||||
[GlImport("glGetString")]
|
||||
@ -163,6 +163,13 @@ namespace CPF.OpenGL
|
||||
genFramebuffers(count, res);
|
||||
}
|
||||
|
||||
public static int GenFramebuffer(this IGlContext context)
|
||||
{
|
||||
int[] fbs = new int[1];
|
||||
context.GenFramebuffers(1, fbs);
|
||||
return fbs[0];
|
||||
}
|
||||
|
||||
public delegate void GlDeleteFramebuffers(int count, int[] framebuffers);
|
||||
[GlImport("glDeleteFramebuffers")]
|
||||
static GlDeleteFramebuffers deleteFramebuffers;
|
||||
@ -211,6 +218,12 @@ namespace CPF.OpenGL
|
||||
Load(context);
|
||||
genRenderbuffers(count, res);
|
||||
}
|
||||
public static int GenRenderbuffer(this IGlContext context)
|
||||
{
|
||||
var res = new int[1];
|
||||
context.GenRenderbuffers(1, res);
|
||||
return res[0];
|
||||
}
|
||||
|
||||
public delegate void GlDeleteRenderbuffers(int count, int[] renderbuffers);
|
||||
[GlImport("glDeleteRenderbuffers")]
|
||||
@ -258,6 +271,13 @@ namespace CPF.OpenGL
|
||||
Load(context);
|
||||
genTextures(count, res);
|
||||
}
|
||||
public static int GenTexture(this IGlContext context)
|
||||
{
|
||||
var res = new int[1];
|
||||
context.GenTextures(1, res);
|
||||
return res[0];
|
||||
}
|
||||
|
||||
|
||||
public delegate void GlBindTexture(int target, int fb);
|
||||
[GlImport("glBindTexture")]
|
||||
@ -378,41 +398,41 @@ namespace CPF.OpenGL
|
||||
deleteShader(shader);
|
||||
}
|
||||
|
||||
public delegate void GlColor4f(float red, float green, float blue, float alpha);
|
||||
[GlImport("glColor4f")]
|
||||
static GlColor4f color4f;
|
||||
public static void Color4f(this IGlContext context, float red, float green, float blue, float alpha)
|
||||
{
|
||||
Load(context);
|
||||
color4f(red, green, blue, alpha);
|
||||
}
|
||||
//public delegate void GlColor4f(float red, float green, float blue, float alpha);
|
||||
//[GlImport("glColor4f")]
|
||||
//static GlColor4f color4f;
|
||||
//public static void Color4f(this IGlContext context, float red, float green, float blue, float alpha)
|
||||
//{
|
||||
// Load(context);
|
||||
// color4f(red, green, blue, alpha);
|
||||
//}
|
||||
|
||||
public delegate void GlBegin(uint mode);
|
||||
[GlImport("glBegin")]
|
||||
static GlBegin begin;
|
||||
public static void Begin(this IGlContext context, uint mode)
|
||||
{
|
||||
Load(context);
|
||||
begin(mode);
|
||||
}
|
||||
//public delegate void GlBegin(uint mode);
|
||||
//[GlImport("glBegin")]
|
||||
//static GlBegin begin;
|
||||
//public static void Begin(this IGlContext context, uint mode)
|
||||
//{
|
||||
// Load(context);
|
||||
// begin(mode);
|
||||
//}
|
||||
|
||||
public delegate void GlVertex3f(float x, float y, float z);
|
||||
[GlImport("glVertex3f")]
|
||||
static GlVertex3f vertex3f;
|
||||
public static void Vertex3f(this IGlContext context, float x, float y, float z)
|
||||
{
|
||||
Load(context);
|
||||
vertex3f(x, y, z);
|
||||
}
|
||||
//public delegate void GlVertex3f(float x, float y, float z);
|
||||
//[GlImport("glVertex3f")]
|
||||
//static GlVertex3f vertex3f;
|
||||
//public static void Vertex3f(this IGlContext context, float x, float y, float z)
|
||||
//{
|
||||
// Load(context);
|
||||
// vertex3f(x, y, z);
|
||||
//}
|
||||
|
||||
public delegate void GlEnd();
|
||||
[GlImport("glEnd")]
|
||||
static GlEnd end;
|
||||
public static void End(this IGlContext context)
|
||||
{
|
||||
Load(context);
|
||||
end();
|
||||
}
|
||||
//public delegate void GlEnd();
|
||||
//[GlImport("glEnd")]
|
||||
//static GlEnd end;
|
||||
//public static void End(this IGlContext context)
|
||||
//{
|
||||
// Load(context);
|
||||
// end();
|
||||
//}
|
||||
|
||||
public delegate void GlLoadIdentity();
|
||||
[GlImport("glLoadIdentity")]
|
||||
@ -477,14 +497,14 @@ namespace CPF.OpenGL
|
||||
popAttrib();
|
||||
}
|
||||
|
||||
public delegate void GlOrtho(double left, double right, double bottom, double top, double zNear, double zFar);
|
||||
[GlImport("glOrtho")]
|
||||
static GlOrtho ortho;
|
||||
public static void Ortho(this IGlContext context, double left, double right, double bottom, double top, double zNear, double zFar)
|
||||
{
|
||||
Load(context);
|
||||
ortho(left, right, bottom, top, zNear, zFar);
|
||||
}
|
||||
//public delegate void GlOrtho(double left, double right, double bottom, double top, double zNear, double zFar);
|
||||
//[GlImport("glOrtho")]
|
||||
//static GlOrtho ortho;
|
||||
//public static void Ortho(this IGlContext context, double left, double right, double bottom, double top, double zNear, double zFar)
|
||||
//{
|
||||
// Load(context);
|
||||
// ortho(left, right, bottom, top, zNear, zFar);
|
||||
//}
|
||||
|
||||
public delegate void GlGetFloatv(uint pname, float[] params_notkeyword);
|
||||
[GlImport("glGetFloatv")]
|
||||
|
@ -43,8 +43,12 @@ namespace CPF.Styling
|
||||
this.PropertyConditions = DefaultPropertyConditions;
|
||||
}
|
||||
}
|
||||
|
||||
bool DefaultPropertyConditions(object v)
|
||||
/// <summary>
|
||||
/// 属性为true的条件
|
||||
/// </summary>
|
||||
/// <param name="v"></param>
|
||||
/// <returns></returns>
|
||||
public bool DefaultPropertyConditions(object v)
|
||||
{
|
||||
return (bool)v;
|
||||
}
|
||||
@ -143,6 +147,110 @@ namespace CPF.Styling
|
||||
internal HybridDictionary<CpfObject, List<string>> SetPropertys;
|
||||
}
|
||||
|
||||
public class TriggerDescribe
|
||||
{
|
||||
/// <summary>
|
||||
/// 触发器
|
||||
/// </summary>
|
||||
public TriggerDescribe(Relation TargetRelation, Func<object, bool> PropertyConditions, params (string, object)[] propertyAndValues)
|
||||
{
|
||||
this.TargetRelation = TargetRelation;
|
||||
this.PropertyConditions = PropertyConditions;
|
||||
this.Setters = propertyAndValues;
|
||||
}
|
||||
/// <summary>
|
||||
/// 触发器
|
||||
/// </summary>
|
||||
public TriggerDescribe(params (string, object)[] propertyAndValues)
|
||||
{
|
||||
this.Setters = propertyAndValues;
|
||||
}
|
||||
/// <summary>
|
||||
/// 触发器
|
||||
/// </summary>
|
||||
public TriggerDescribe(Func<object, bool> PropertyConditions, params (string, object)[] propertyAndValues)
|
||||
{
|
||||
this.PropertyConditions = PropertyConditions;
|
||||
this.Setters = propertyAndValues;
|
||||
}
|
||||
/// <summary>
|
||||
/// 触发器
|
||||
/// </summary>
|
||||
/// <param name="TargetRelation"></param>
|
||||
/// <param name="PropertyConditions"></param>
|
||||
/// <param name="Animation"></param>
|
||||
/// <param name="AnimationDuration"></param>
|
||||
/// <param name="AnimationIterationCount"></param>
|
||||
/// <param name="AnimationEndBehavior"></param>
|
||||
/// <param name="propertyAndValues"></param>
|
||||
public TriggerDescribe(Relation TargetRelation = null, Func<object, bool> PropertyConditions = default, Storyboard Animation = null, TimeSpan? AnimationDuration = null, uint AnimationIterationCount = 1, EndBehavior AnimationEndBehavior = EndBehavior.Recovery, params (string, object)[] propertyAndValues)
|
||||
{
|
||||
this.TargetRelation = TargetRelation;
|
||||
this.PropertyConditions = PropertyConditions;
|
||||
this.PropertyConditions = PropertyConditions;
|
||||
this.Setters = propertyAndValues;
|
||||
this.Animation = Animation;
|
||||
if (AnimationDuration.HasValue)
|
||||
{
|
||||
this.AnimationDuration = AnimationDuration.Value;
|
||||
}
|
||||
this.AnimationIterationCount = AnimationIterationCount;
|
||||
this.AnimationEndBehavior = AnimationEndBehavior;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 满足条件之后播放的动画
|
||||
/// </summary>
|
||||
public Storyboard Animation { get; set; }
|
||||
|
||||
///// <summary>
|
||||
///// 条件属性
|
||||
///// </summary>
|
||||
//public string Property { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 属性条件,参数是属性值,返回条件结果
|
||||
/// </summary>
|
||||
public Func<object, bool> PropertyConditions { get; set; }
|
||||
|
||||
public (string, object)[] Setters { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 相对位置元素,用来设置值或者动画
|
||||
/// </summary>
|
||||
public Relation TargetRelation { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 动画持续时间
|
||||
/// </summary>
|
||||
public TimeSpan AnimationDuration
|
||||
{
|
||||
get;
|
||||
set;
|
||||
} = TimeSpan.FromSeconds(0.5);
|
||||
|
||||
/// <summary>
|
||||
/// 动画播放次数,0为无限循环
|
||||
/// </summary>
|
||||
public uint AnimationIterationCount
|
||||
{
|
||||
get;
|
||||
set;
|
||||
} = 1;
|
||||
|
||||
/// <summary>
|
||||
/// 动画结束之后的行为
|
||||
/// </summary>
|
||||
public EndBehavior AnimationEndBehavior
|
||||
{
|
||||
get;
|
||||
set;
|
||||
} = EndBehavior.Recovery;
|
||||
}
|
||||
|
||||
//public enum Conditions
|
||||
//{
|
||||
// NotEqual,
|
||||
|
@ -3046,7 +3046,7 @@ namespace CPF
|
||||
/// 子级,一般自定义组件的时候使用
|
||||
/// </summary>
|
||||
[NotCpfProperty]
|
||||
internal protected virtual UIElementCollection Children
|
||||
internal protected UIElementCollection Children
|
||||
{
|
||||
get
|
||||
{
|
||||
@ -3280,6 +3280,23 @@ namespace CPF
|
||||
}
|
||||
}
|
||||
|
||||
protected internal override void OnAddTriggerDescribe(string property, TriggerDescribe trigger)
|
||||
{
|
||||
var t = new Trigger { Animation = trigger.Animation, AnimationDuration = trigger.AnimationDuration, AnimationEndBehavior = trigger.AnimationEndBehavior, AnimationIterationCount = trigger.AnimationIterationCount, PropertyConditions = trigger.PropertyConditions, TargetRelation = trigger.TargetRelation, Property = property };
|
||||
if (trigger.Setters != null && trigger.Setters.Length > 0)
|
||||
{
|
||||
foreach (var item in trigger.Setters)
|
||||
{
|
||||
t.Setters.Add(item.Item1, item.Item2);
|
||||
}
|
||||
}
|
||||
if (t.PropertyConditions == null)
|
||||
{
|
||||
t.PropertyConditions = t.DefaultPropertyConditions;
|
||||
}
|
||||
Triggers.Add(t);
|
||||
}
|
||||
|
||||
//Styles styles;
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
|
@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>netcoreapp3.0;net40;net5;net6;net8</TargetFrameworks>
|
||||
<TargetFrameworks>netcoreapp3.0;net40;net5;net6</TargetFrameworks>
|
||||
<ApplicationIcon />
|
||||
<StartupObject />
|
||||
<OutputType>WinExe</OutputType>
|
||||
@ -102,11 +102,12 @@
|
||||
<ProjectReference Include="..\CPF.Linux\CPF.Linux.csproj" />
|
||||
<ProjectReference Include="..\CPF.Mac\CPF.Mac.csproj" />
|
||||
</ItemGroup>
|
||||
<!--<ItemGroup Condition="'$(TargetFramework)'!='net40'">
|
||||
<PackageReference Include="System.Reactive">
|
||||
<ItemGroup Condition="'$(TargetFramework)'!='net40'">
|
||||
<!--<PackageReference Include="System.Reactive">
|
||||
<Version>5.0.0</Version>
|
||||
</PackageReference>
|
||||
</ItemGroup>-->
|
||||
</PackageReference>-->
|
||||
<PackageReference Condition="'$(TargetFramework)'!='netcoreapp3.0'" Include="Silk.NET.OpenGLES" Version="2.19.0" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup>
|
||||
<DefineConstants Condition="'$(TargetFramework)'=='net40'">Net4</DefineConstants>
|
||||
<AutoGenerateBindingRedirects>false</AutoGenerateBindingRedirects>
|
||||
|
98
ConsoleApp1/GLView.cs
Normal file
98
ConsoleApp1/GLView.cs
Normal file
@ -0,0 +1,98 @@
|
||||
#if !NET40
|
||||
using CPF;
|
||||
using CPF.Drawing;
|
||||
using CPF.OpenGL;
|
||||
using CPF.Skia;
|
||||
using SkiaSharp;
|
||||
using System;
|
||||
|
||||
namespace ConsoleApp1
|
||||
{
|
||||
[CPF.Design.DesignerLoadStyle("res://$safeprojectname$/Stylesheet1.css")]//用于设计的时候加载样式
|
||||
public class GLView : CPF.Skia.GLView
|
||||
{
|
||||
#if !NETCOREAPP3_0
|
||||
Silk.NET.OpenGLES.GL _gl;
|
||||
|
||||
uint vao;
|
||||
uint shaderProgram;
|
||||
|
||||
protected unsafe override void OnGLLoaded(IGlContext gl)
|
||||
{
|
||||
_gl = Silk.NET.OpenGLES.GL.GetApi(gl.GetProcAddress);
|
||||
_gl.ClearColor(0.2f, 0.3f, 0.3f, 1.0f);
|
||||
float[] vertices = {
|
||||
-0.5f, -0.5f, 0.0f,
|
||||
0.5f, -0.5f, 0.0f,
|
||||
0.0f, 0.5f, 0.0f
|
||||
};
|
||||
|
||||
_gl.GenBuffers(1, out uint vbo);
|
||||
_gl.GenVertexArrays(1, out vao);
|
||||
|
||||
_gl.BindBuffer(Silk.NET.OpenGLES.GLEnum.ArrayBuffer, vbo);
|
||||
_gl.BindVertexArray(vao);
|
||||
|
||||
_gl.BufferData<float>(Silk.NET.OpenGLES.GLEnum.ArrayBuffer,vertices, Silk.NET.OpenGLES.GLEnum.StaticDraw);
|
||||
|
||||
_gl.VertexAttribPointer(0, 3, Silk.NET.OpenGLES.GLEnum.Float, false, 3 * sizeof(float), null);
|
||||
_gl.EnableVertexAttribArray(0);
|
||||
|
||||
_gl.BindVertexArray(0);
|
||||
_gl.BindBuffer(Silk.NET.OpenGLES.GLEnum.ArrayBuffer, 0);
|
||||
|
||||
string vertexShaderSource = @"#version 330 core
|
||||
layout (location = 0) in vec3 aPos;
|
||||
void main()
|
||||
{
|
||||
gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);
|
||||
}
|
||||
";
|
||||
|
||||
string fragmentShaderSource = @"#version 330 core
|
||||
out vec4 FragColor;
|
||||
void main()
|
||||
{
|
||||
FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);
|
||||
}
|
||||
";
|
||||
|
||||
uint vertexShader = _gl.CreateShader(Silk.NET.OpenGLES.GLEnum.VertexShader);
|
||||
_gl.ShaderSource(vertexShader, vertexShaderSource);
|
||||
_gl.CompileShader(vertexShader);
|
||||
|
||||
uint fragmentShader = _gl.CreateShader(Silk.NET.OpenGLES.GLEnum.FragmentShader);
|
||||
_gl.ShaderSource(fragmentShader, fragmentShaderSource);
|
||||
_gl.CompileShader(fragmentShader);
|
||||
|
||||
shaderProgram = _gl.CreateProgram();
|
||||
_gl.AttachShader(shaderProgram, vertexShader);
|
||||
_gl.AttachShader(shaderProgram, fragmentShader);
|
||||
_gl.LinkProgram(shaderProgram);
|
||||
|
||||
_gl.DeleteShader(vertexShader);
|
||||
_gl.DeleteShader(fragmentShader);
|
||||
//base.OnGLLoaded(gl);
|
||||
}
|
||||
|
||||
|
||||
protected override void OnGLRender(IGlContext gl)
|
||||
{
|
||||
_gl.ClearColor(0.5f, 1, 0, 0.5f);
|
||||
_gl.Clear(Silk.NET.OpenGLES.ClearBufferMask.ColorBufferBit | Silk.NET.OpenGLES.ClearBufferMask.DepthBufferBit | Silk.NET.OpenGLES.ClearBufferMask.StencilBufferBit);
|
||||
|
||||
_gl.UseProgram(shaderProgram);
|
||||
_gl.BindVertexArray(vao);
|
||||
|
||||
_gl.DrawArrays(Silk.NET.OpenGLES.GLEnum.Triangles, 0, 3);
|
||||
|
||||
_gl.BindVertexArray(0);
|
||||
_gl.UseProgram(0);
|
||||
//base.OnGLRender(gl);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
@ -38,9 +38,14 @@ namespace ConsoleApp1
|
||||
#if Net4
|
||||
(OperatingSystemType.Windows, new WindowsPlatform(), new CPF.GDIPlus.GDIPlusDrawingFactory { ClearType = true })
|
||||
#else
|
||||
(OperatingSystemType.Windows, new WindowsPlatform(false), new SkiaDrawingFactory { })
|
||||
(OperatingSystemType.Windows, new WindowsPlatform(false), new SkiaDrawingFactory
|
||||
{
|
||||
#if NETCOREAPP3_1_OR_GREATER
|
||||
UseGPU=true
|
||||
#endif
|
||||
})
|
||||
, (OperatingSystemType.OSX, new CPF.Mac.MacPlatform(), new SkiaDrawingFactory { UseGPU = false })
|
||||
, (OperatingSystemType.Linux, new CPF.Linux.LinuxPlatform(), new SkiaDrawingFactory { UseGPU = false })
|
||||
, (OperatingSystemType.Linux, new CPF.Linux.LinuxPlatform(), new SkiaDrawingFactory { UseGPU = true })
|
||||
#endif
|
||||
);
|
||||
|
||||
@ -87,9 +92,21 @@ namespace ConsoleApp1
|
||||
////Thread.Sleep(10000);
|
||||
////Application.AllowDeveloperTool = false;
|
||||
////Application.DisablePopupClose = true;
|
||||
|
||||
|
||||
//Console.SetOut(new tr());
|
||||
//Console.WriteLine("123");
|
||||
//data aa = new data();
|
||||
//aa.test.test.test.Name = "11111";
|
||||
//model.Test1.test = aa;
|
||||
|
||||
//var test1 = new TextBlock
|
||||
//{
|
||||
// [nameof(TextBlock.Text)] = new CPF.Obx<MainModel>(a => a.Test1.test.test.test.test.Name),
|
||||
//};
|
||||
//test1.DataContext=model;
|
||||
|
||||
//aa = new data();
|
||||
//aa.test.test.test.Name = "666666";
|
||||
//model.Test1.test = aa;
|
||||
Application.Run(new Window2 { DataContext = model, CommandContext = model });
|
||||
|
||||
//Application.Run(new Window
|
||||
@ -139,7 +156,7 @@ namespace ConsoleApp1
|
||||
}
|
||||
class tr : TextWriter
|
||||
{
|
||||
public override Encoding Encoding => Encoding.Unicode;
|
||||
public override Encoding Encoding => Encoding.Unicode;
|
||||
|
||||
public override void Write(string value)
|
||||
{
|
||||
|
@ -105,7 +105,7 @@ namespace ConsoleApp1
|
||||
},
|
||||
new RowDefinition
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
},
|
||||
});
|
||||
@ -419,7 +419,7 @@ namespace ConsoleApp1
|
||||
},
|
||||
new Separator
|
||||
{
|
||||
|
||||
|
||||
},
|
||||
new MenuItem
|
||||
{
|
||||
@ -429,10 +429,13 @@ namespace ConsoleApp1
|
||||
new MenuItem
|
||||
{
|
||||
Header = "21",
|
||||
Commands =
|
||||
{
|
||||
{nameof(MenuItem.Click),MenuItemClick }
|
||||
}
|
||||
Commands =
|
||||
{
|
||||
{
|
||||
nameof(MenuItem.Click),
|
||||
MenuItemClick
|
||||
}
|
||||
}
|
||||
},
|
||||
new MenuItem
|
||||
{
|
||||
@ -444,7 +447,10 @@ namespace ConsoleApp1
|
||||
Header = "221",
|
||||
Commands =
|
||||
{
|
||||
{nameof(MenuItem.Click),MenuItemClick }
|
||||
{
|
||||
nameof(MenuItem.Click),
|
||||
MenuItemClick
|
||||
}
|
||||
}
|
||||
},
|
||||
new MenuItem
|
||||
@ -452,7 +458,10 @@ namespace ConsoleApp1
|
||||
Header = "222",
|
||||
Commands =
|
||||
{
|
||||
{nameof(MenuItem.Click),MenuItemClick }
|
||||
{
|
||||
nameof(MenuItem.Click),
|
||||
MenuItemClick
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -468,10 +477,13 @@ namespace ConsoleApp1
|
||||
new MenuItem
|
||||
{
|
||||
Header = "31",
|
||||
Commands =
|
||||
{
|
||||
{nameof(MenuItem.Click),MenuItemClick }
|
||||
}
|
||||
Commands =
|
||||
{
|
||||
{
|
||||
nameof(MenuItem.Click),
|
||||
MenuItemClick
|
||||
}
|
||||
}
|
||||
},
|
||||
new MenuItem
|
||||
{
|
||||
@ -1362,7 +1374,8 @@ namespace ConsoleApp1
|
||||
},
|
||||
new ListBox
|
||||
{
|
||||
//Background="#aaa",
|
||||
MarginLeft = 57,
|
||||
MarginTop = 63,//Background="#aaa",
|
||||
Name="listbox",
|
||||
IsVirtualizing=true,//VirtualizationMode= VirtualizationMode.Recycling,
|
||||
SelectionMode= SelectionMode.Extended,
|
||||
@ -1372,7 +1385,18 @@ namespace ConsoleApp1
|
||||
{
|
||||
Width="100%",
|
||||
FontSize=22,
|
||||
Tag=this,
|
||||
Tag=this,
|
||||
Template=(e,c)=>{
|
||||
c.Add(new Border
|
||||
{
|
||||
Background="#f00",
|
||||
Height = "100%",
|
||||
Width = "100%",
|
||||
BorderFill = null,
|
||||
Name = "contentPresenter",
|
||||
PresenterFor = this
|
||||
});
|
||||
}
|
||||
},
|
||||
Bindings=
|
||||
{
|
||||
@ -1398,6 +1422,65 @@ namespace ConsoleApp1
|
||||
}
|
||||
}
|
||||
},//new Button{ Content="排序" },
|
||||
new ListBox
|
||||
{
|
||||
MarginLeft = 463,
|
||||
MarginTop = 44,
|
||||
Height = 431,
|
||||
Width = 283,
|
||||
Background = "white",
|
||||
BorderFill = new SolidColorFill
|
||||
{
|
||||
Color = Color.Silver
|
||||
},
|
||||
BorderThickness = new Thickness(0, 1, 0, 0),
|
||||
BorderType = BorderType.BorderThickness,
|
||||
ItemsPanel = new StackPanel
|
||||
{
|
||||
Orientation = Orientation.Horizontal
|
||||
},
|
||||
ItemTemplate = new ListBoxItem
|
||||
{
|
||||
Width = 100,
|
||||
MarginRight = 1,
|
||||
FontSize = 16f,
|
||||
BorderFill = "Silver",
|
||||
BorderThickness = new Thickness(1),
|
||||
Margin = new ThicknessField(1),
|
||||
CornerRadius = new CornerRadius(2),
|
||||
IsAntiAlias = true,
|
||||
UseLayoutRounding = true,
|
||||
BorderType = BorderType.BorderThickness,
|
||||
Template=(e,c)=>{
|
||||
Children.Add(new Border
|
||||
{
|
||||
Background="#f00",
|
||||
Height = "100%",
|
||||
Width = "100%",
|
||||
BorderFill = null,
|
||||
Name = "contentPresenter",
|
||||
PresenterFor = this
|
||||
});
|
||||
}
|
||||
//ContentTemplate = new ContentTemplate
|
||||
//{
|
||||
// Size = SizeField.Fill,
|
||||
// Content = new StackPanel
|
||||
// {
|
||||
// Orientation = Orientation.Horizontal,
|
||||
// Size = SizeField.Fill,
|
||||
// Children =
|
||||
// {
|
||||
// new TextBlock
|
||||
// {
|
||||
// //[nameof(TextBlock.Text)] = new BindingDescribe("Title",BindingMode.OneWay)
|
||||
// Text = "test"
|
||||
// }
|
||||
// }
|
||||
// },
|
||||
//},
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -1719,7 +1802,7 @@ namespace ConsoleApp1
|
||||
nameof(DragEnter),
|
||||
(s,e)=>
|
||||
{
|
||||
//(e as DragEventArgs).DragEffects= DragDropEffects.Link;
|
||||
//(e as DragEventArgs).DragEffects= DragDropEffects.Link;
|
||||
}
|
||||
},
|
||||
}
|
||||
@ -1762,7 +1845,7 @@ namespace ConsoleApp1
|
||||
Content="模糊,你撸多了",
|
||||
Effect=new BlurEffect
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
},
|
||||
new Button
|
||||
@ -1789,7 +1872,7 @@ namespace ConsoleApp1
|
||||
Content="灰色",
|
||||
Effect=new GrayScaleEffect
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
},
|
||||
new Picture
|
||||
@ -1998,7 +2081,7 @@ namespace ConsoleApp1
|
||||
{
|
||||
new RowDefinition
|
||||
{
|
||||
|
||||
|
||||
},
|
||||
},
|
||||
Children =
|
||||
|
@ -472,9 +472,9 @@ namespace ConsoleApp1
|
||||
},
|
||||
new ScrollViewer
|
||||
{
|
||||
MarginLeft = 421,
|
||||
HorizontalScrollBarVisibility= ScrollBarVisibility.Disabled,
|
||||
VerticalScrollBarVisibility= ScrollBarVisibility.Visible,
|
||||
Background = "url(res://ConsoleApp1/icon.png) Tile None 0,0,0,0",
|
||||
MarginLeft = 421,//HorizontalScrollBarVisibility= ScrollBarVisibility.Disabled,
|
||||
//VerticalScrollBarVisibility= ScrollBarVisibility.Visible,
|
||||
Commands =
|
||||
{
|
||||
{
|
||||
@ -499,6 +499,16 @@ namespace ConsoleApp1
|
||||
// Name = nameof(pic),
|
||||
// Source="http://219.239.12.91:5001/bookimage//bookimage3/cate1826979600058c0bd3/file253320e4000582XXXX/253320e4000582XXXX.jpg"
|
||||
//}
|
||||
|
||||
|
||||
#if !Net4&&!NETCOREAPP3_0
|
||||
new GLView
|
||||
{
|
||||
Height = 336,
|
||||
Width = 421,
|
||||
IsAntiAlias=true,
|
||||
},
|
||||
#else
|
||||
new WrapPanel
|
||||
{
|
||||
Width="100%",
|
||||
@ -562,6 +572,7 @@ namespace ConsoleApp1
|
||||
},
|
||||
}
|
||||
},
|
||||
#endif
|
||||
Height=300,
|
||||
MarginTop=19,
|
||||
MarginRight=29
|
||||
@ -616,7 +627,7 @@ namespace ConsoleApp1
|
||||
Value=0.001,
|
||||
Bindings =
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
},
|
||||
new Button
|
||||
@ -738,16 +749,8 @@ namespace ConsoleApp1
|
||||
MarginTop = 450,
|
||||
Height = 58,
|
||||
Width = 121,
|
||||
},//#if !Net4
|
||||
//new CPF.Skia.GlView
|
||||
//{
|
||||
// MarginRight = 56,
|
||||
// MarginTop = 44,
|
||||
// Height = 132,
|
||||
// Width = 151,
|
||||
//},
|
||||
//#endif
|
||||
new Button
|
||||
},
|
||||
new Button
|
||||
{
|
||||
Commands =
|
||||
{
|
||||
@ -1386,8 +1389,7 @@ namespace ConsoleApp1
|
||||
MarginLeft = 252,
|
||||
MarginTop = 76,
|
||||
Height = 23,
|
||||
Width = 219,
|
||||
//[nameof(Slider.Value)]= new Obx<MainModel>(a => a.Type.Name),
|
||||
Width = 219,//[nameof(Slider.Value)]= new Obx<MainModel>(a => a.Type.Name),
|
||||
[nameof(Slider.Value)]= new BindingDescribe(null, nameof(MainModel.ColumnWidth),BindingMode.OneWayToSource,null,a=>new GridLength((float)(double)a))
|
||||
},
|
||||
}
|
||||
@ -1967,7 +1969,7 @@ namespace ConsoleApp1
|
||||
},
|
||||
new Separator
|
||||
{
|
||||
|
||||
|
||||
},
|
||||
new MenuItem
|
||||
{
|
||||
@ -2437,21 +2439,19 @@ new TabItemTemplate{
|
||||
Orientation= Orientation.Vertical,
|
||||
Children=
|
||||
{
|
||||
|
||||
new TextBlock
|
||||
{
|
||||
[nameof(TextBlock.Text)]= new Obx<MainModel>(a => a.Test1.test.test.test.test.Name,
|
||||
BindingMode.OneWay),
|
||||
Name = "hmbb"
|
||||
},
|
||||
new TextBox
|
||||
{
|
||||
Width = 130,
|
||||
Height= 60,
|
||||
Background =Color.Gray,
|
||||
[nameof(TextBox.Text)]= new Obx<MainModel>(a => a.Test1.test.test.test.test.Name,
|
||||
BindingMode.OneWayToSource),
|
||||
},
|
||||
},//new TextBox
|
||||
//{
|
||||
// Width = 130,
|
||||
// Height= 60,
|
||||
// Background =Color.Gray,
|
||||
// [nameof(TextBox.Text)]= new Obx<MainModel>(a => a.Test1.test.test.test.test.Name,
|
||||
// BindingMode.OneWayToSource),
|
||||
//},
|
||||
new Button
|
||||
{
|
||||
Content="创建对象",
|
||||
@ -2467,8 +2467,6 @@ new TabItemTemplate{
|
||||
Content="删除对象",
|
||||
[nameof(Button.Click)]=new CommandDescribe((s,e)=>
|
||||
{
|
||||
data a = new data();
|
||||
a.test.test.Name = "666666";
|
||||
(DataContext as MainModel).Test1.test.test = null;
|
||||
})
|
||||
},
|
||||
@ -2478,13 +2476,12 @@ new TabItemTemplate{
|
||||
[nameof(Button.Click)]=new CommandDescribe((s,e)=>
|
||||
{
|
||||
data a = new data();
|
||||
a.test.test.Name = "666666";
|
||||
a.test.test.Name = "8888";
|
||||
(DataContext as MainModel).Test1.test.test = a;
|
||||
})
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -3459,10 +3456,19 @@ new TabItemTemplate{
|
||||
{
|
||||
MaximizeBox = true,
|
||||
ShadowBlur = 10,
|
||||
#if !DesignMode
|
||||
#if !DesignMode
|
||||
//Effect = effect
|
||||
#endif
|
||||
});
|
||||
|
||||
//#if !Net4 && !NETCOREAPP3_0
|
||||
// Children.Add(new GLView
|
||||
// {
|
||||
// Height = "30%",
|
||||
// Width = "30%",
|
||||
// IsAntiAlias = true,
|
||||
// });
|
||||
//#endif
|
||||
LoadStyleFile("res://ConsoleApp1/Stylesheet3.css");
|
||||
//加载样式文件,文件需要设置为内嵌资源
|
||||
Console.WriteLine(testBtn[DockPanel.Dock]);
|
||||
|
Loading…
Reference in New Issue
Block a user