From: gdkhd812 Date: Tue, 27 Oct 2015 02:25:32 +0000 (+0530) Subject: メトロ版でもカーソルを点滅できるようにしてみた&コードの整理 X-Git-Url: http://git.osdn.net/view?p=fooeditengine%2FFooEditEngine.git;a=commitdiff_plain;h=refs%2Fheads%2Fmetro_caret_blink メトロ版でもカーソルを点滅できるようにしてみた&コードの整理 --- diff --git a/Core/Direct2D/D2DRenderCommon.cs b/Core/Direct2D/D2DRenderCommon.cs index 2238410..bb850ae 100644 --- a/Core/Direct2D/D2DRenderCommon.cs +++ b/Core/Direct2D/D2DRenderCommon.cs @@ -186,13 +186,15 @@ namespace FooEditEngine D2D.Factory D2DFactory; #endif DW.TextFormat format; - D2D.Bitmap bitmap; + protected D2D.Bitmap CachedBitmap; D2D.RenderTarget render; CustomTextRenderer textRender; int tabLength = 8; - bool hasCache, _ShowLineBreak; - Size renderSize = new Size(); + bool _ShowLineBreak; Color4 _Comment, _Literal, _Keyword1, _Keyword2; + protected bool hasCache; + + protected Size renderSize { get; private set; } public D2DRenderCommon() { @@ -205,6 +207,7 @@ namespace FooEditEngine this.Strokes.Factory = this.D2DFactory; this.ChangedRenderResource += (s, e) => { }; this.ChangedRightToLeft += (s, e) => { }; + this.renderSize = new Size(); } public event ChangedRenderResourceEventHandler ChangedRenderResource; @@ -213,6 +216,13 @@ namespace FooEditEngine public const int MiniumeWidth = 40; //これ以上ないと誤操作が起こる + public double GetScale() + { + float dpi; + this.GetDpi(out dpi, out dpi); + return dpi / 96.0; + } + public void InitTextFormat(string fontName, float fontSize, DW.FontWeight fontWeigth = DW.FontWeight.Normal,DW.FontStyle fontStyle = DW.FontStyle.Normal) { if(this.format != null) @@ -557,21 +567,12 @@ namespace FooEditEngine this.DestructDeviceResource(); this.ConstructDeviceResource(width, height); } - public virtual void DrawCachedBitmap(Rectangle rect) { - if (this.render == null || this.render.IsDisposed) - return; - render.DrawBitmap(this.bitmap, rect, 1.0f, D2D.BitmapInterpolationMode.Linear, rect); } public virtual void CacheContent() { - if (this.render == null || this.bitmap == null || this.bitmap.IsDisposed || this.render.IsDisposed) - return; - render.Flush(); - this.bitmap.CopyFromRenderTarget(this.render, new SharpDX.Point(), new SharpDX.Rectangle(0, 0, (int)this.renderSize.Width, (int)this.renderSize.Height)); - this.hasCache = true; } public virtual bool IsVaildCache() @@ -855,7 +856,7 @@ namespace FooEditEngine this.GetDpi(out dpiX, out dpiY); D2D.RenderTargetProperties prop = new D2D.RenderTargetProperties( D2D.RenderTargetType.Default, - new D2D.PixelFormat(DXGI.Format.B8G8R8A8_UNorm, D2D.AlphaMode.Ignore), + new D2D.PixelFormat(DXGI.Format.B8G8R8A8_UNorm, D2D.AlphaMode.Premultiplied), dpiX, dpiY, D2D.RenderTargetUsage.None, @@ -868,16 +869,15 @@ namespace FooEditEngine D2D.BitmapProperties bmpProp = new D2D.BitmapProperties(); bmpProp.DpiX = dpiX; bmpProp.DpiY = dpiY; - bmpProp.PixelFormat = new D2D.PixelFormat(DXGI.Format.B8G8R8A8_UNorm, D2D.AlphaMode.Ignore); - this.bitmap = new D2D.Bitmap(this.render, new SharpDX.Size2((int)width, (int)height), bmpProp); + bmpProp.PixelFormat = new D2D.PixelFormat(DXGI.Format.B8G8R8A8_UNorm, D2D.AlphaMode.Premultiplied); + this.CachedBitmap = new D2D.Bitmap(this.render, new SharpDX.Size2((int)width, (int)height), bmpProp); this.hasCache = false; this.ConstrctedResource(); this.textRender = new CustomTextRenderer(this.render, this.Brushes,this.Strokes, this.Foreground); - this.renderSize.Width = width; - this.renderSize.Height = height; + this.renderSize = new Size(width,height); this.TextAntialiasMode = this._TextAntialiasMode; } @@ -915,8 +915,8 @@ namespace FooEditEngine public void DestructDeviceResource() { this.hasCache = false; - if (this.bitmap != null) - this.bitmap.Dispose(); + if (this.CachedBitmap != null) + this.CachedBitmap.Dispose(); this.Brushes.Clear(); this.Strokes.Clear(); this.Effects.Clear(); diff --git a/Core/EditView.cs b/Core/EditView.cs index 1a4ad02..730c454 100644 --- a/Core/EditView.cs +++ b/Core/EditView.cs @@ -216,6 +216,9 @@ namespace FooEditEngine IEditorRender render = (IEditorRender)base.render; + Rectangle background = this.PageBound; + render.FillBackground(background); + if ((updateRect.Height < this.PageBound.Height || updateRect.Width < this.PageBound.Width) && render.IsVaildCache()) @@ -224,9 +227,6 @@ namespace FooEditEngine } else { - Rectangle background = this.PageBound; - render.FillBackground(background); - if (this.Document.HideRuler == false) this.DrawRuler(); diff --git a/Metro/FooEditEngine/Direct2D/D2DRender.cs b/Metro/FooEditEngine/Direct2D/D2DRender.cs index f8003b6..6c31ec5 100644 --- a/Metro/FooEditEngine/Direct2D/D2DRender.cs +++ b/Metro/FooEditEngine/Direct2D/D2DRender.cs @@ -133,18 +133,34 @@ namespace FooEditEngine return this.Size.Height != 0 && this.Size.Width != 0; } + public override void DrawCachedBitmap(Rectangle rect) + { + if (this.D2DContext == null || this.D2DContext.IsDisposed) + return; + this.D2DContext.DrawBitmap(this.CachedBitmap, rect, 1.0f, D2D.BitmapInterpolationMode.Linear, rect); + } + + public override void CacheContent() + { + if (this.D2DContext == null || this.CachedBitmap == null || this.CachedBitmap.IsDisposed || this.D2DContext.IsDisposed) + return; + this.D2DContext.Flush(); + this.CachedBitmap.CopyFromRenderTarget(this.D2DContext, new SharpDX.Point(), new SharpDX.Rectangle(0, 0, (int)this.renderSize.Width, (int)this.renderSize.Height)); + this.hasCache = true; + } + + SharpDX.Point offset; public override void BegineDraw() { - SharpDX.Point offset; this.Surface = this.SurfaceImageNative.BeginDraw( - new SharpDX.Rectangle(0, 0, (int)this.Size.Width, (int)this.Size.Height), out offset); + new SharpDX.Rectangle(0, 0, (int)this.Size.Width, (int)this.Size.Height), out this.offset); float dpix, dpiy; this.GetDpi(out dpix, out dpiy); D2D.BitmapProperties1 prop = new D2D.BitmapProperties1(new D2D.PixelFormat(DXGI.Format.B8G8R8A8_UNorm, D2D.AlphaMode.Premultiplied), dpix, dpiy, D2D.BitmapOptions.Target | D2D.BitmapOptions.CannotDraw); this.Bitmap = new D2D.Bitmap1(this.D2DContext, this.Surface, prop); this.D2DContext.Target = this.Bitmap; - this.D2DContext.Transform = Matrix3x2.Translation(offset.X,offset.Y); + this.D2DContext.Transform = Matrix3x2.Translation(this.offset.X,this.offset.Y); base.BegineDraw(); } @@ -174,6 +190,7 @@ namespace FooEditEngine { this.D2DDevice = new D2D.Device(factory,this.DXGIDevice); this.D2DContext = new D2D.DeviceContext(this.D2DDevice, D2D.DeviceContextOptions.None); + this.D2DContext.DotsPerInch = new Size2F(prop.DpiX, prop.DpiY); return this.D2DContext; } diff --git a/Metro/FooEditEngine/Direct2D/D2DRenderBase.cs b/Metro/FooEditEngine/Direct2D/D2DRenderBase.cs index f2a13e6..38723d4 100644 --- a/Metro/FooEditEngine/Direct2D/D2DRenderBase.cs +++ b/Metro/FooEditEngine/Direct2D/D2DRenderBase.cs @@ -144,19 +144,6 @@ namespace FooEditEngine protected delegate void PreDrawOneLineHandler(MyTextLayout layout, LineToIndexTable lti, int row, double x, double y); protected PreDrawOneLineHandler PreDrawOneLine; - public override void CacheContent() - { - } - - public override void DrawCachedBitmap(Rectangle rect) - { - } - - public override bool IsVaildCache() - { - return false; - } - public void DrawOneLine(LineToIndexTable lti, int row, double x, double y, IEnumerable SelectRanges) { this.DrawOneLine(lti, diff --git a/Metro/FooEditEngine/FooTextBox.cs b/Metro/FooEditEngine/FooTextBox.cs index ebb25ea..03e88b6 100644 --- a/Metro/FooEditEngine/FooTextBox.cs +++ b/Metro/FooEditEngine/FooTextBox.cs @@ -112,7 +112,6 @@ namespace FooEditEngine.Metro this.timer = new DispatcherTimer(); this.timer.Interval = new TimeSpan(0, 0, 0, 0, 100); this.timer.Tick += new EventHandler(this.timer_Tick); - this.timer.Start(); //Viewの初期化が終わった直後に置かないと例外が発生する this.Document.Update += Document_Update; @@ -122,6 +121,10 @@ namespace FooEditEngine.Metro this.SizeChanged += FooTextBox_SizeChanged; this.Loaded += FooTextBox_Loaded; + + this.View.CaretBlink = true; + this.View.CaretBlinkTime = 1000; //TODO:ユーザーの設定を反映させる + this.View.CaretWidthOnInsertMode = 1; //TODO:ユーザーの設定を反映させる } /// @@ -620,7 +623,7 @@ namespace FooEditEngine.Metro if (e.Pointer.PointerDeviceType == PointerDeviceType.Mouse) { - Point p = e.GetCurrentPoint(this).Position; + Point p = ((Point)e.GetCurrentPoint(this).Position).Scale(this.Render.GetScale()); if (this.View.HitTextArea(p.X, p.Y)) { TextPoint tp = this.View.GetTextPointFromPostion(p); @@ -725,16 +728,12 @@ namespace FooEditEngine.Metro Point startPos, endPos; TextStoreHelper.GetStringExtent(this.Document, this.View, i_startIndex, i_endIndex, out startPos, out endPos); - float dpi; - this.Render.GetDpi(out dpi, out dpi); - double scale = dpi / 96.0; - - var gt = this.TransformToVisual(Window.Current.Content); - startPos = gt.TransformPoint(startPos.Scale(scale)); - endPos = gt.TransformPoint(endPos.Scale(scale)); + double scale = this.Render.GetScale(); + var screen_startPos = Util.GetScreentPoint(startPos.Scale(scale), this); + var screen_endPos = Util.GetScreentPoint(endPos.Scale(scale), this); - o_topLeft = new POINT((int)startPos.X, (int)startPos.Y); - o_bottomRight = new POINT((int)endPos.X, (int)endPos.Y); + o_topLeft = new POINT((int)screen_startPos.X, (int)screen_startPos.Y); + o_bottomRight = new POINT((int)screen_endPos.X, (int)screen_endPos.Y); } void _textStore_GetScreenExtent(out POINT o_topLeft, out POINT o_bottomRight) @@ -787,11 +786,19 @@ namespace FooEditEngine.Metro //sender.InertiaRotationDeceleration = 720.0f / (1000.0f * 1000.0f); } + private Point GetDipFromPoint(Point p) + { + float dpi; + this.Render.GetDpi(out dpi, out dpi); + double scale = dpi / 96.0; + return p.Scale(1 / scale); + } + Gripper hittedGripper; void gestureRecongnizer_ManipulationStarted(GestureRecognizer sender, ManipulationStartedEventArgs e) { //Updateedの段階でヒットテストしてしまうとグリッパーを触ってもヒットしないことがある - this.hittedGripper = this.View.HitGripperFromPoint(e.Position); + this.hittedGripper = this.View.HitGripperFromPoint(this.GetDipFromPoint(e.Position)); } const int WheelNoti = 120; @@ -800,7 +807,8 @@ namespace FooEditEngine.Metro void gestureRecongnizer_ManipulationUpdated(GestureRecognizer sender, ManipulationUpdatedEventArgs e) { - if (this._Controller.MoveCaretAndGripper(e.Position, this.hittedGripper)) + Point p = this.GetDipFromPoint(e.Position); + if (this._Controller.MoveCaretAndGripper(p, this.hittedGripper)) { if (this.peer != null) this.peer.OnNotifyCaretChanged(); @@ -830,7 +838,7 @@ namespace FooEditEngine.Metro return; } - Point translation = e.Delta.Translation; + Point translation = this.GetDipFromPoint(e.Delta.Translation); //Xの絶対値が大きければ横方向のスクロールで、そうでなければ縦方向らしい if (Math.Abs(e.Cumulative.Translation.X) < Math.Abs(e.Cumulative.Translation.Y)) @@ -883,7 +891,8 @@ namespace FooEditEngine.Metro { ResourceMap map = ResourceManager.Current.MainResourceMap.GetSubtree("FooEditEngine.Metro/Resources"); ResourceContext context = ResourceContext.GetForCurrentView(); - if (this.View.HitTextArea(e.Position.X, e.Position.Y)) + Point p = this.GetDipFromPoint(e.Position); + if (this.View.HitTextArea(p.X, p.Y)) { FooContextMenuEventArgs args = new FooContextMenuEventArgs(e.Position); if (this.ContextMenuOpening != null) @@ -924,10 +933,11 @@ namespace FooEditEngine.Metro void gestureRecongnizer_Tapped(GestureRecognizer sender, TappedEventArgs e) { + Point p = this.GetDipFromPoint(e.Position); bool touched = e.PointerDeviceType == PointerDeviceType.Touch; this.Document.SelectGrippers.BottomLeft.Enabled = false; this.Document.SelectGrippers.BottomRight.Enabled = touched; - this.JumpCaret(e.Position); + this.JumpCaret(p); System.Diagnostics.Debug.WriteLine(e.TapCount); if (e.TapCount == 2) { @@ -967,7 +977,7 @@ namespace FooEditEngine.Metro void gestureRecongnizer_Dragging(GestureRecognizer sender, DraggingEventArgs e) { - Point p = e.Position; + Point p = this.GetDipFromPoint(e.Position); if (this.View.HitTextArea(p.X, p.Y)) { TextPoint tp = this.View.GetTextPointFromPostion(p); @@ -985,7 +995,7 @@ namespace FooEditEngine.Metro } void Refresh(Rectangle updateRect) { - if (this.rectangle.ActualWidth == 0 || this.rectangle.ActualHeight == 0 || this.Visibility == Windows.UI.Xaml.Visibility.Collapsed) + if (this.rectangle.ActualWidth == 0 || this.rectangle.ActualHeight == 0 || this.Visibility == Windows.UI.Xaml.Visibility.Collapsed || !this.Render.IsCanDraw()) return; this.Render.BegineDraw(); @@ -1038,11 +1048,6 @@ namespace FooEditEngine.Metro void FooTextBox_SizeChanged(object sender, SizeChangedEventArgs e) { - if (this.Resize(this.rectangle.ActualWidth, this.rectangle.ActualHeight)) - { - this.Refresh(); - return; - } } void horizontalScrollBar_Scroll(object sender, ScrollEventArgs e) @@ -1084,13 +1089,34 @@ namespace FooEditEngine.Metro void FooTextBox_Loaded(object sender, RoutedEventArgs e) { this.Focus(FocusState.Programmatic); + this.timer.Start(); } void timer_Tick(object sender, object e) { + if (this.Resize(this.rectangle.ActualWidth, this.rectangle.ActualHeight)) + { + this.Refresh(); + return; + } + bool updateAll = this.View.LayoutLines.HilightAll() || this.View.LayoutLines.GenerateFolding(); + + ITextLayout layout = this.View.LayoutLines.GetLayout(this.Document.CaretPostion.row); + double width = layout.GetWidthFromIndex(this.Document.CaretPostion.col); + if (width == 0.0) + width = this.View.CaretWidthOnInsertMode; + double height = layout.Height; + Rectangle updateRect = new Rectangle( + this.View.CaretLocation.X, + this.View.CaretLocation.Y, + width, + height); + if (updateAll) this.Refresh(); + else + this.Refresh(updateRect); } /// diff --git a/WPF/FooEditEngine/Direct2D/D2DRender.cs b/WPF/FooEditEngine/Direct2D/D2DRender.cs index e9c0832..daa8413 100644 --- a/WPF/FooEditEngine/Direct2D/D2DRender.cs +++ b/WPF/FooEditEngine/Direct2D/D2DRender.cs @@ -127,6 +127,22 @@ namespace FooEditEngine.WPF } } + public override void DrawCachedBitmap(Rectangle rect) + { + if (this.render == null || this.render.IsDisposed) + return; + render.DrawBitmap(this.CachedBitmap, rect, 1.0f, D2D.BitmapInterpolationMode.Linear, rect); + } + + public override void CacheContent() + { + if (this.render == null || this.CachedBitmap == null || this.CachedBitmap.IsDisposed || this.render.IsDisposed) + return; + render.Flush(); + this.CachedBitmap.CopyFromRenderTarget(this.render, new SharpDX.Point(), new SharpDX.Rectangle(0, 0, (int)this.renderSize.Width, (int)this.renderSize.Height)); + this.hasCache = true; + } + public static Color4 ToColor4(System.Windows.Media.Color color) { return new Color4(color.R / 255.0f, color.G / 255.0f, color.B / 255.0f, color.A / 255.0f); @@ -384,13 +400,6 @@ namespace FooEditEngine.WPF { } - public double GetScale() - { - float dpi; - this.GetDpi(out dpi, out dpi); - return dpi / 96.0; - } - public override void GetDpi(out float dpix, out float dpiy) { IntPtr hDc = NativeMethods.GetDC(IntPtr.Zero); diff --git a/Windows/FooEditEngine/D2DTextRender.cs b/Windows/FooEditEngine/D2DTextRender.cs index bb6e5fe..e9b9c48 100644 --- a/Windows/FooEditEngine/D2DTextRender.cs +++ b/Windows/FooEditEngine/D2DTextRender.cs @@ -68,6 +68,22 @@ namespace FooEditEngine.Windows this.ReConstructDeviceResource(this.TextBox.Width, this.TextBox.Height); } + public override void DrawCachedBitmap(Rectangle rect) + { + if (this.WindowRender == null || this.WindowRender.IsDisposed) + return; + this.WindowRender.DrawBitmap(this.CachedBitmap, rect, 1.0f, D2D.BitmapInterpolationMode.Linear, rect); + } + + public override void CacheContent() + { + if (this.WindowRender == null || this.CachedBitmap == null || this.CachedBitmap.IsDisposed || this.WindowRender.IsDisposed) + return; + this.WindowRender.Flush(); + this.CachedBitmap.CopyFromRenderTarget(this.WindowRender, new SharpDX.Point(), new SharpDX.Rectangle(0, 0, (int)this.renderSize.Width, (int)this.renderSize.Height)); + this.hasCache = true; + } + public static Color4 ToColor4(System.Drawing.Color color) { return new Color4(color.R / 255.0f, color.G / 255.0f, color.B / 255.0f, color.A / 255.0f);