OSDN Git Service

メトロ版でもカーソルを点滅できるようにしてみた&コードの整理 metro_caret_blink
authorgdkhd812 <test@nnn.co.jp>
Tue, 27 Oct 2015 02:25:32 +0000 (07:55 +0530)
committergdkhd812 <test@nnn.co.jp>
Tue, 27 Oct 2015 02:25:32 +0000 (07:55 +0530)
Core/Direct2D/D2DRenderCommon.cs
Core/EditView.cs
Metro/FooEditEngine/Direct2D/D2DRender.cs
Metro/FooEditEngine/Direct2D/D2DRenderBase.cs
Metro/FooEditEngine/FooTextBox.cs
WPF/FooEditEngine/Direct2D/D2DRender.cs
Windows/FooEditEngine/D2DTextRender.cs

index 2238410..bb850ae 100644 (file)
@@ -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();
index 1a4ad02..730c454 100644 (file)
@@ -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();
 
index f8003b6..6c31ec5 100644 (file)
@@ -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;
         }
 
index f2a13e6..38723d4 100644 (file)
@@ -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<Selection> SelectRanges)
         {
             this.DrawOneLine(lti,
index ebb25ea..03e88b6 100644 (file)
@@ -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<object>(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:ユーザーの設定を反映させる
         }
 
         /// <summary>
@@ -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);
         }
 
         /// <inheritdoc/>
index e9c0832..daa8413 100644 (file)
@@ -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);
index bb6e5fe..e9b9c48 100644 (file)
@@ -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);