diff --git a/CPF.Skia/GlView.cs b/CPF.Skia/GlView.cs
index 31b9ac8..8d290c1 100644
--- a/CPF.Skia/GlView.cs
+++ b/CPF.Skia/GlView.cs
@@ -24,6 +24,13 @@ namespace CPF.Skia
/// 支持OpenGL绘制的控件,在GLRender事件里绘制,开启GPU硬件加速才能使用 new SkiaDrawingFactory { UseGPU = true }
///
public GLView() { }
+ ///
+ /// 绑定的FB id
+ ///
+ public int FramebufferId
+ {
+ get { return Id; }
+ }
//IGlContext context;
protected unsafe override void OnRender(DrawingContext dc)
diff --git a/CPF/Controls/ITextBoxView.cs b/CPF/Controls/ITextBoxView.cs
index 7dd9d68..0ee3025 100644
--- a/CPF/Controls/ITextBoxView.cs
+++ b/CPF/Controls/ITextBoxView.cs
@@ -8,7 +8,7 @@ using System.Text;
namespace CPF.Controls
{
[Browsable(false)]
- public class ITextBoxView : UIElement, IDocumentStyle
+ public abstract class ITextBoxView : UIElement, IDocumentStyle
{
private void Error() {
throw new Exception("你看到此错误说明没有被重写,禁止调用,请使用override重写");
diff --git a/CPF/Controls/MessageBox.cs b/CPF/Controls/MessageBox.cs
index 29fe6ab..6d54c1b 100644
--- a/CPF/Controls/MessageBox.cs
+++ b/CPF/Controls/MessageBox.cs
@@ -58,7 +58,7 @@ namespace CPF.Controls
throw new Exception("需要有主窗体");
}
}
- Window window = new Window { CanResize = false, Background = null, Title = title == null ? "" : title, Icon = main.Icon, MinWidth = 200, Name = "messageBox" };
+ Window window = new Window { CanResize = false, Background = null, Title = title == null ? "" : title, Icon = main.Icon, MinWidth = 200, Name = "messageBox", TopMost = main.TopMost };
window.LoadStyle(main);
window.Children.Add(new WindowFrame(window, new Panel
{
diff --git a/CPF/Controls/TextBox.cs b/CPF/Controls/TextBox.cs
index 8fca306..82f1bb3 100644
--- a/CPF/Controls/TextBox.cs
+++ b/CPF/Controls/TextBox.cs
@@ -15,9 +15,9 @@ using System.ComponentModel;
namespace CPF.Controls
{
///
- /// 表示一个控件,该控件可用于显示或编辑无格式文本。
+ /// 表示一个控件,该控件可用于显示或编辑简单富文本。
///
- [Description("表示一个控件,该控件可用于显示或编辑无格式文本。")]
+ [Description("表示一个控件,该控件可用于显示或编辑简单富文本。")]
[DefaultProperty(nameof(TextBox.Text))]
public class TextBox : Control, IDocumentStyle, IEditor
{
diff --git a/CPF/Controls/TextBoxView.cs b/CPF/Controls/TextBoxView.cs
index 330955d..af868b4 100644
--- a/CPF/Controls/TextBoxView.cs
+++ b/CPF/Controls/TextBoxView.cs
@@ -602,8 +602,8 @@ namespace CPF.Controls
void Render(DrawingContext dc, Rect source, Point location, HybridDictionary cache, IDocumentContainer documentContainer, Cache parent)
{
- float lastOffset = 0;
- float lastTop = 0;
+ float lastOffset = location.X;
+ float lastTop = location.Y;
float lastHeight = 0;
foreach (var line in documentContainer.Lines)
{
@@ -663,8 +663,8 @@ namespace CPF.Controls
dc.FillRectangle(backBrush, backRect);
}
}
- lastOffset = document.Left + line.X + line.Width;
- lastTop = document.Top + line.Y;
+ lastOffset = location.X + line.X + line.Width;
+ lastTop = location.Y + line.Y;
}
foreach (var line in documentContainer.Lines)
{
diff --git a/ConsoleApp1/OpenGLWindow.cs b/ConsoleApp1/OpenGLWindow.cs
index e7fb0ca..32c4a79 100644
--- a/ConsoleApp1/OpenGLWindow.cs
+++ b/ConsoleApp1/OpenGLWindow.cs
@@ -1,11 +1,14 @@
-using CPF;
+#if !NET40
+using CPF;
using CPF.Animation;
using CPF.Charts;
using CPF.Controls;
using CPF.Drawing;
+using CPF.OpenGL;
using CPF.Shapes;
using CPF.Styling;
using CPF.Svg;
+using LibMpv.Client;
using System;
using System.Collections.Generic;
using System.Linq;
@@ -24,6 +27,7 @@ namespace ConsoleApp1
Width = 500;
Height = 400;
Background = null;
+ CanResize = true;
Children.Add(new WindowFrame(this, new Panel
{
Width = "100%",
@@ -37,10 +41,12 @@ namespace ConsoleApp1
Width = 35,
Height = 236,
},
- new CPF.Skia.GlView
+ new VideoView
{
- Height = 252,
- Width = 337,
+ Height = "100%",
+ Width = "100%",
+ PresenterFor=this,
+ Name="view"
},
new TextBox
{
@@ -50,20 +56,141 @@ namespace ConsoleApp1
Width = 153,
},
}
- }));
+ })
+ { MaximizeBox = true });
if (!DesignMode)//设计模式下不执行,也可以用#if !DesignMode
{
-
+
}
}
+ VideoView video;
#if !DesignMode //用户代码写到这里,设计器下不执行,防止设计器出错
protected override void OnInitialized()
{
base.OnInitialized();
-
+ video = FindPresenterByName("view");
+ VideoView.InitMpv();
+ DynamicallyLoadedBindings.ThrowErrorIfFunctionNotFound = true;
+ video.MpvContext = new MpvContext() { };
+ //video.LoadFile(@"D:\xhm\Videos\202204201620.mp4");
+ //video.Play();
+ WindowState = WindowState.Maximized;
}
//用户代码
#endif
}
+
+ public class VideoView : CPF.Skia.GLView, IMpvVideoView
+ {
+ public static void InitMpv()
+ {
+ var platform = IntPtr.Size == 8 ? "" : "x86";
+ var platformId = FunctionResolverFactory.GetPlatformId();
+ if (platformId == LibMpvPlatformID.Win32NT)
+ {
+ var path = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, platform);
+ LibMpv.Client.LibMpv.UseLibMpv(2).UseLibraryPath(path);
+ }
+ else if (platformId == LibMpvPlatformID.Unix)
+ {
+ var path = $"/usr/lib/{platform}-linux-gnu";
+ LibMpv.Client.LibMpv.UseLibMpv(0).UseLibraryPath(path);
+ }
+ }
+
+ public void LoadFile(string fileName, string mode = "replace")
+ {
+ //mpvContext.SetOptionString("opengl-glfinish", "yes");
+ //mpvContext.SetLogLevel(MpvLogLevel.MpvLogLevelDebug);
+ mpvContext.Command("loadfile", fileName, mode);
+ }
+ public void Play()
+ {
+ mpvContext.SetPropertyFlag("pause", false);
+ }
+ public MpvContext? MpvContext
+ {
+ get { return mpvContext; }
+ set
+ {
+ if (ReferenceEquals(value, mpvContext))
+ return;
+ if (mpvContext != null)
+ DetachMpvContext(mpvContext);
+ mpvContext = value;
+ if (mpvContext != null)
+ AttachMpvContext(mpvContext);
+ }
+ }
+
+ protected override void OnGLRender(IGlContext gl)
+ {
+ base.OnGLRender(gl);
+ if (mpvContext != null && getProcAddres != null)
+ {
+ var scaling = Root.RenderScaling;
+ var Bounds = ActualSize;
+ var width = Math.Max(1, (int)(Bounds.Width * scaling));
+ var height = Math.Max(1, (int)(Bounds.Height * scaling));
+ var stop = new System.Diagnostics.Stopwatch();
+ stop.Start();
+ mpvContext.RenderOpenGl(width, height, FramebufferId, 1);
+ stop.Stop();
+ System.Diagnostics.Debug.WriteLine(stop.ElapsedMilliseconds);
+ }
+ update = false;
+ }
+
+ private void DetachMpvContext(MpvContext context)
+ {
+ context.StopRendering();
+ }
+
+ private void AttachMpvContext(MpvContext context)
+ {
+ if (getProcAddres != null)
+ {
+ mpvContext?.ConfigureRenderer(new OpenGlRendererConfiguration() { OpnGlGetProcAddress = getProcAddres, UpdateCallback = this.UpdateVideoView });
+ }
+ }
+
+ protected override void OnGLLoaded(IGlContext gl)
+ {
+ base.OnGLLoaded(gl);
+ if (getProcAddres != null) return;
+
+ getProcAddres = gl.GetProcAddress;
+ if (mpvContext != null)
+ {
+ AttachMpvContext(mpvContext);//需要绑定之后才能加载视频
+ //LoadFile(@"F:\新建文件夹\....mp4");
+ }
+ }
+
+
+ protected override void Dispose(bool disposing)
+ {
+ base.Dispose(disposing);
+ if (mpvContext != null)
+ DetachMpvContext(mpvContext);
+ }
+ bool update;
+ private void UpdateVideoView()
+ {
+ if (!update)
+ {
+ update = true;
+ CPF.Threading.Dispatcher.MainThread.BeginInvoke(() =>
+ {
+ Invalidate();
+ });
+ }
+
+ }
+
+ private MpvContext? mpvContext = null;
+ private OpenGlGetProcAddressDelegate getProcAddres;
+ }
}
+#endif
\ No newline at end of file