OSDN Git Service

ファイル読み込み後の再描写はすぐ行わなくても構わない
[fooeditengine/FooEditEngine.git] / UWP / FooEditEngine.UWP / FooTextBox.cs
index ae93a70..71da92f 100644 (file)
@@ -8,6 +8,7 @@
 
 You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>.
  */
+
 using System;
 using System.Text;
 using System.ComponentModel;
@@ -39,7 +40,11 @@ namespace FooEditEngine.UWP
     {
         EditView View;
         Controller _Controller;
+#if !DUMMY_RENDER
         D2DRender Render;
+#else
+        DummyRender Render;
+#endif
         ScrollBar horizontalScrollBar, verticalScrollBar;
         Windows.UI.Xaml.Shapes.Rectangle rectangle;
         GestureRecognizer gestureRecongnizer = new GestureRecognizer();
@@ -50,23 +55,31 @@ namespace FooEditEngine.UWP
 #endif
         bool nowCaretMove = false;
         bool nowCompstion = false;
+        bool requestSizeChange = false;
         Document _Document;
         DispatcherTimer timer = new DispatcherTimer();
 
+        const int Interval = 32;
+        const int IntervalWhenLostFocus = 160;
+
         /// <summary>
         /// コンストラクター
         /// </summary>
         public FooTextBox()
         {
             this.DefaultStyleKey = typeof(FooTextBox);
-
+            
             this.rectangle = new Windows.UI.Xaml.Shapes.Rectangle();
             this.rectangle.Margin = this.Padding;
+#if !DUMMY_RENDER
             this.Render = new D2DRender(this,this.rectangle);
+#else
+            this.Render = new DummyRender();
+#endif
 
             this.Document = new Document();
 
-            this.View = new EditView(this.Document, this.Render, new Padding(5, Gripper.HitAreaWidth, Gripper.HitAreaWidth / 2, Gripper.HitAreaWidth));
+            this.View = new EditView(this.Document, this.Render, new Padding(5, 5, Gripper.HitAreaWidth / 2, Gripper.HitAreaWidth));
             this.View.SrcChanged += View_SrcChanged;
             this.View.InsertMode = this.InsertMode;
             this.Document.DrawLineNumber = this.DrawLineNumber;
@@ -95,10 +108,13 @@ namespace FooEditEngine.UWP
             this.gestureRecongnizer.ManipulationUpdated += gestureRecongnizer_ManipulationUpdated;
             this.gestureRecongnizer.ManipulationCompleted += gestureRecongnizer_ManipulationCompleted;
 
-            this.timer.Interval = new TimeSpan(0, 0, 0, 0, 500);
+            this.timer.Interval = new TimeSpan(0, 0, 0, 0, Interval);
             this.timer.Tick += this.timer_Tick;
             this.timer.Start();
 
+            this.GettingFocus += FooTextBox_GettingFocus;
+            this.LosingFocus += FooTextBox_LosingFocus;
+
             this.SizeChanged += FooTextBox_SizeChanged;
 
             this.Loaded += FooTextBox_Loaded;
@@ -205,7 +221,13 @@ namespace FooEditEngine.UWP
             var dataPackageView = Clipboard.GetContent();
             if (dataPackageView.Contains(StandardDataFormats.Text))
             {
-                this._Controller.SelectedText = await dataPackageView.GetTextAsync();
+                try
+                {
+                    this._Controller.SelectedText = await dataPackageView.GetTextAsync();
+                }catch(Exception e)
+                {
+                    System.Diagnostics.Debug.WriteLine("past error:" + e.Message);
+                }
             }
         }
 
@@ -292,9 +314,12 @@ namespace FooEditEngine.UWP
         /// <summary>
         /// 再描写する
         /// </summary>
-        public void Refresh()
+        public void Refresh(bool immidately=true)
         {
-            this.Refresh(this.View.PageBound);
+            if(immidately)
+                this.Refresh(this.View.PageBound);
+            else
+                this.Document.RequestRedraw();
         }
 
         /// <summary>
@@ -302,7 +327,7 @@ namespace FooEditEngine.UWP
         /// </summary>
         public void PerfomLayouts()
         {
-            this.View.PerfomLayouts();
+            this.Document.PerformLayout();
         }
 
         /// <summary>
@@ -322,23 +347,29 @@ namespace FooEditEngine.UWP
         /// <returns>Taskオブジェクト</returns>
         public async Task LoadFileAsync(System.IO.StreamReader sr, System.Threading.CancellationTokenSource token)
         {
-            this.IsEnabled = false;
-            this.View.LayoutLines.IsFrozneDirtyFlag = true;
-            WinFileReader fs = new WinFileReader(sr);
-            await this.Document.LoadAsync(fs, token);
-            this.View.LayoutLines.IsFrozneDirtyFlag = false;
+            await this.Document.LoadAsync(sr, token);
+        }
 
-            CoreTextRange modified_range = new CoreTextRange();
-            modified_range.StartCaretPosition = 0;
-            modified_range.EndCaretPosition = 0;
-            //キャレット位置はロード前と同じにしないと違和感を感じる
-            if(this.textEditContext != null)
-                this.textEditContext.NotifyTextChanged(modified_range, this.Document.Length, modified_range);
+        private void Document_LoadProgress(object sender, ProgressEventArgs e)
+        {
+            if(e.state == ProgressState.Start)
+            {
+                this.IsEnabled = false;
+            }
+            else if(e.state == ProgressState.Complete)
+            {
+                CoreTextRange modified_range = new CoreTextRange();
+                modified_range.StartCaretPosition = 0;
+                modified_range.EndCaretPosition = 0;
+                //キャレット位置はロード前と同じにしないと違和感を感じる
+                if (this.textEditContext != null)
+                    this.textEditContext.NotifyTextChanged(modified_range, this.Document.Length, modified_range);
 
-            if (this.verticalScrollBar != null)
-                this.verticalScrollBar.Maximum = this.View.LayoutLines.Count;
-            this.View.CalculateLineCountOnScreen();
-            this.IsEnabled = true;
+                if (this.verticalScrollBar != null)
+                    this.verticalScrollBar.Maximum = this.View.LayoutLines.Count;
+                this.IsEnabled = true;
+                this.Refresh(false);
+            }
         }
 
         /// <summary>
@@ -349,8 +380,7 @@ namespace FooEditEngine.UWP
         /// <returns>Taskオブジェクト</returns>
         public async Task SaveFile(System.IO.StreamWriter sw, System.Threading.CancellationTokenSource token)
         {
-            WinFileWriter fs = new WinFileWriter(sw);
-            await this.Document.SaveAsync(fs, token);
+            await this.Document.SaveAsync(sw, token);
         }
 
 #region command
@@ -414,12 +444,23 @@ namespace FooEditEngine.UWP
             }
         }
 
-            /// <inheritdoc/>
-        protected override async void OnGotFocus(RoutedEventArgs e)
+        private void FooTextBox_LosingFocus(UIElement sender, LosingFocusEventArgs args)
         {
-            base.OnGotFocus(e);
+            this.RemoveTextContext();
+            
+            if (this.textServiceManager != null)
+            {
+                this.textServiceManager.InputLanguageChanged -= TextServiceManager_InputLanguageChanged;
+                this.textServiceManager = null;
+            }
+
+            System.Diagnostics.Debug.WriteLine("losing focus");
+        }
 
-            if(this.textServiceManager == null)
+        private async void FooTextBox_GettingFocus(UIElement sender, GettingFocusEventArgs args)
+        {
+            System.Diagnostics.Debug.WriteLine("getting focus");
+            if (this.textServiceManager == null)
             {
                 await Task.Delay(500);
                 this.textServiceManager = CoreTextServicesManager.GetForCurrentView();
@@ -427,27 +468,35 @@ namespace FooEditEngine.UWP
             }
 
             this.CreateTextContext();
+        }
+
+        /// <inheritdoc/>
+        protected override void OnGotFocus(RoutedEventArgs e)
+        {
+            base.OnGotFocus(e);
+
+            System.Diagnostics.Debug.WriteLine("got focus");
 
             this.View.IsFocused = true;
-            this.Refresh();
+            this.timer.Interval = new TimeSpan(0, 0, 0, 0, Interval);
+            this.Refresh(false);
         }
 
         private void TextServiceManager_InputLanguageChanged(CoreTextServicesManager sender, object args)
         {
             System.Diagnostics.Debug.WriteLine("input language changed input script:"+  this.textServiceManager.InputLanguage.Script);
-            this.RemoveTextContext();
-            this.CreateTextContext();
         }
 
-        /// <inheritdoc/>
+       /// <inheritdoc/>
         protected override void OnLostFocus(RoutedEventArgs e)
         {
             base.OnLostFocus(e);
 
-            this.RemoveTextContext();
-
+            System.Diagnostics.Debug.WriteLine("lost focus");
+            
             this.View.IsFocused = false;
-            this.Refresh();
+            this.Refresh(false);
+            this.timer.Interval = new TimeSpan(0, 0, 0, 0, IntervalWhenLostFocus);
         }
 
         private void CreateTextContext()
@@ -455,6 +504,7 @@ namespace FooEditEngine.UWP
             if(this.textServiceManager != null)
             {
                 this.textEditContext = this.textServiceManager.CreateEditContext();
+                this.textEditContext.InputScope = CoreTextInputScope.Text;
                 this.textEditContext.CompositionStarted += TextEditContext_CompositionStarted;
                 this.textEditContext.CompositionCompleted += TextEditContext_CompositionCompleted;
                 this.textEditContext.LayoutRequested += TextEditContext_LayoutRequested;
@@ -473,6 +523,7 @@ namespace FooEditEngine.UWP
         {
             if(this.textEditContext != null)
             {
+                this.textEditContext.NotifyFocusLeave();
                 this.textEditContext.CompositionStarted -= TextEditContext_CompositionStarted;
                 this.textEditContext.CompositionCompleted -= TextEditContext_CompositionCompleted;
                 this.textEditContext.LayoutRequested -= TextEditContext_LayoutRequested;
@@ -483,7 +534,6 @@ namespace FooEditEngine.UWP
                 this.textEditContext.FormatUpdating -= TextEditContext_FormatUpdating;
                 this.textEditContext.FocusRemoved -= TextEditContext_FocusRemoved;
                 this.textEditContext.NotifyFocusLeaveCompleted -= TextEditContext_NotifyFocusLeaveCompleted;
-                this.textEditContext.NotifyFocusLeave();
                 this.textEditContext = null;
             }
         }
@@ -494,6 +544,11 @@ namespace FooEditEngine.UWP
             bool isControlPressed = this.IsModiferKeyPressed(VirtualKey.Control);
             bool isShiftPressed = this.IsModiferKeyPressed(VirtualKey.Shift);
             bool isMovedCaret = false;
+
+            var autocomplete = this.Document.AutoComplete as AutoCompleteBox;
+            if (autocomplete != null && autocomplete.ProcessKeyDown(this, e, isControlPressed, isShiftPressed))
+                return;
+
             switch (e.Key)
             {
                 case VirtualKey.Up:
@@ -649,6 +704,7 @@ namespace FooEditEngine.UWP
         /// <inheritdoc/>
         protected override void OnPointerPressed(PointerRoutedEventArgs e)
         {
+            System.Diagnostics.Debug.WriteLine("pointer pressed");
             this.CapturePointer(e.Pointer);
             this.gestureRecongnizer.ProcessDownEvent(e.GetCurrentPoint(this));
             e.Handled = true;
@@ -657,7 +713,15 @@ namespace FooEditEngine.UWP
         /// <inheritdoc/>
         protected override void OnPointerMoved(PointerRoutedEventArgs e)
         {
-            this.gestureRecongnizer.ProcessMoveEvents(e.GetIntermediatePoints(this));
+            System.Diagnostics.Debug.WriteLine("pointer moved");
+            try
+            {
+                this.gestureRecongnizer.ProcessMoveEvents(e.GetIntermediatePoints(this));
+            }catch(System.Runtime.InteropServices.COMException ex)
+            {
+                //ピンチズームでこの例外が発生するが、回避できない
+                System.Diagnostics.Debug.WriteLine("expection:" + ex);
+            }
             e.Handled = true;
 
             if (e.Pointer.PointerDeviceType == PointerDeviceType.Mouse)
@@ -681,6 +745,7 @@ namespace FooEditEngine.UWP
         /// <inheritdoc/>
         protected override void OnPointerReleased(PointerRoutedEventArgs e)
         {
+            System.Diagnostics.Debug.WriteLine("pointer released");
             this.gestureRecongnizer.ProcessUpEvent(e.GetCurrentPoint(this));
             e.Handled = true;
         }
@@ -688,6 +753,7 @@ namespace FooEditEngine.UWP
         /// <inheritdoc/>
         protected override void OnPointerCanceled(PointerRoutedEventArgs e)
         {
+            System.Diagnostics.Debug.WriteLine("pointer canceled");
             this.gestureRecongnizer.CompleteGesture();
             e.Handled = true;
         }
@@ -695,6 +761,7 @@ namespace FooEditEngine.UWP
         /// <inheritdoc/>
         protected override void OnPointerWheelChanged(PointerRoutedEventArgs e)
         {
+            System.Diagnostics.Debug.WriteLine("pointer wheelchanged");
             bool shift = (e.KeyModifiers & Windows.System.VirtualKeyModifiers.Shift) ==
                 Windows.System.VirtualKeyModifiers.Shift;
             bool ctrl = (e.KeyModifiers & Windows.System.VirtualKeyModifiers.Control) ==
@@ -767,14 +834,16 @@ namespace FooEditEngine.UWP
             }
 
             int start = req.Range.StartCaretPosition;
-            int length = req.Range.EndCaretPosition - req.Range.StartCaretPosition;
-            if (length > this.Document.Length)
-                length = this.Document.Length;
+            int end = req.Range.EndCaretPosition;
+            if (end > this.Document.Length)
+                end = this.Document.Length;
+
+            int length = end - start;
 
             System.Diagnostics.Debug.WriteLine("req text start:{0} length:{1}", start, length);
 
             //キャレット位置も含むので+1する必要はない
-            req.Text = this.Document.ToString(start, length);
+            req.Text = this.Document.ToString(start,length);
         }
 
         private void TextEditContext_LayoutRequested(CoreTextEditContext sender, CoreTextLayoutRequestedEventArgs args)
@@ -803,7 +872,7 @@ namespace FooEditEngine.UWP
                 args.Request.LayoutBounds.TextBounds = new Rect(
                     screenStartPos.X,
                     screenStartPos.Y,
-                    screenEndPos.X - screenStartPos.X,
+                    Math.Max(0,screenEndPos.X - screenStartPos.X),  //折り返されている場合、負になることがある
                     screenEndPos.Y - screenStartPos.Y);
             }
 
@@ -940,16 +1009,6 @@ namespace FooEditEngine.UWP
 
         void gestureRecongnizer_ManipulationUpdated(GestureRecognizer sender, ManipulationUpdatedEventArgs e)
         {
-            if (this._Controller.MoveCaretAndGripper(e.Position, this.hittedGripper))
-            {
-#if ENABLE_AUTMATION
-                if (this.peer != null)
-                    this.peer.OnNotifyCaretChanged();
-#endif
-                this.Refresh();                
-                return;
-            }
-
             if (e.Delta.Scale < 1)
             {
                 double newSize = this.Render.FontSize - 1;
@@ -960,7 +1019,7 @@ namespace FooEditEngine.UWP
                 SetValue(MagnificationPowerPropertyKey, this.Render.FontSize / this.FontSize);
                 return;
             }
-            
+
             if (e.Delta.Scale > 1)
             {
                 double newSize = this.Render.FontSize + 1;
@@ -971,6 +1030,16 @@ namespace FooEditEngine.UWP
                 SetValue(MagnificationPowerPropertyKey, this.Render.FontSize / this.FontSize);
                 return;
             }
+
+            if (this._Controller.MoveCaretAndGripper(e.Position, this.hittedGripper))
+            {
+#if ENABLE_AUTMATION
+                if (this.peer != null)
+                    this.peer.OnNotifyCaretChanged();
+#endif
+                this.Refresh();                
+                return;
+            }
             
             Point translation = e.Delta.Translation;
 
@@ -1039,22 +1108,36 @@ namespace FooEditEngine.UWP
                             this._Controller.RectSelection = true;
                         }));
                     }
-                    await ContextMenu.ShowAsync(e.Position);
+                    var windowStartPos = Util.GetPointInWindow(e.Position, this);
+                    await ContextMenu.ShowAsync(windowStartPos);
                 }
             }
         }
 
+        long lastDouleTapTick;
+        const long allowTripleTapTimeSpan = 500;
         void gestureRecongnizer_Tapped(GestureRecognizer sender, TappedEventArgs e)
         {
             bool touched = e.PointerDeviceType == PointerDeviceType.Touch;
             this.Document.SelectGrippers.BottomLeft.Enabled = false;
             this.Document.SelectGrippers.BottomRight.Enabled = touched;
             this.JumpCaret(e.Position);
-            if (e.TapCount == 2)
+            if(e.TapCount == 1 && System.DateTime.Now.Ticks - lastDouleTapTick < allowTripleTapTimeSpan * 10000)    //トリプルタップ
+            {
+                //タッチスクリーンで行選択した場合、アンカーインデックスを単語の先頭にしないとバグる
+                this.Document.SelectGrippers.BottomLeft.Enabled = touched;
+                this.Document.SelectLine(this.Controller.SelectionStart, touched);
+                this.Refresh();
+            }
+            else  if(e.TapCount == 2)   //ダブルタップ
             {
+                //タッチスクリーンで単語選択した場合、アンカーインデックスを単語の先頭にしないとバグる
                 this.Document.SelectGrippers.BottomLeft.Enabled = touched;
-                //タッチスクリーンでダブルタップした場合、アンカーインデックスを単語の先頭にしないとバグる
-                this.Document.SelectWord(this.Controller.SelectionStart, touched);
+                if (e.Position.X < this.Render.TextArea.X)
+                    this.Document.SelectLine(this.Controller.SelectionStart, touched);
+                else
+                    this.Document.SelectWord(this.Controller.SelectionStart, touched);
+                this.lastDouleTapTick = System.DateTime.Now.Ticks;
                 this.Refresh();
             }
         }
@@ -1100,7 +1183,7 @@ namespace FooEditEngine.UWP
             else
                 return;
             TextPoint tp = this.View.GetTextPointFromPostion(p, searchRange);
-            this._Controller.MoveCaretAndSelect(tp);
+            this._Controller.MoveCaretAndSelect(tp, this.IsModiferKeyPressed(VirtualKey.LeftControl));
 #if ENABLE_AUTMATION
             if (this.peer != null)
                 this.peer.OnNotifyCaretChanged();
@@ -1119,6 +1202,8 @@ namespace FooEditEngine.UWP
                 return;
 
             this.Render.DrawContent(this.View, this.IsEnabled, updateRect);
+
+            this.Document.IsRequestRedraw = false;
         }
 
 
@@ -1163,11 +1248,8 @@ namespace FooEditEngine.UWP
 
         void FooTextBox_SizeChanged(object sender, SizeChangedEventArgs e)
         {
-            if (this.Resize(this.rectangle.ActualWidth, this.rectangle.ActualHeight))
-            {
-                this.Refresh();
-                return;
-            }
+            //LostFocusやGotFocusなどと競合するとDirect2Dでエラーが起きるので、timer_tickイベントでサイズ変更を行うことにした
+            this.requestSizeChange = true;
         }
 
         void horizontalScrollBar_Scroll(object sender, ScrollEventArgs e)
@@ -1236,21 +1318,115 @@ namespace FooEditEngine.UWP
 
         void timer_Tick(object sender, object e)
         {
-            if (this.View.LayoutLines.HilightAll() || this.View.LayoutLines.GenerateFolding())
+            this.timer.Stop();
+            if(this.requestSizeChange)
+            {
+                if (this.Resize(this.rectangle.ActualWidth, this.rectangle.ActualHeight))
+                {
+                    //普通に再描写するとちらつく
+                    this.Refresh(this.View.PageBound);
+                }
+                this.requestSizeChange = false;
+            }
+            else if (this.View.LayoutLines.HilightAll() || this.View.LayoutLines.GenerateFolding() || this.Document.IsRequestRedraw)
+            {
                 this.Refresh(this.View.PageBound);
+            }
+            this.timer.Start();
+        }
+
+        private void SetDocument(Document value)
+        {
+            if (value == null)
+                return;
+
+            Document old_doc = this._Document;
+
+            if (this._Document != null)
+            {
+                old_doc.Update -= new DocumentUpdateEventHandler(Document_Update);
+                this._Document.SelectionChanged -= Controller_SelectionChanged;
+                this._Document.LoadProgress -= Document_LoadProgress;
+                this._Document.AutoCompleteChanged -= _Document_AutoCompleteChanged;
+                if (this._Document.AutoComplete != null)
+                {
+                    this._Document.AutoComplete.GetPostion = null;
+                    this._Document.AutoComplete = null;
+                }
+
+                //NotifyTextChanged()を呼び出すと落ちるのでTextConextをごっそり作り替える
+                this.RemoveTextContext();
+            }
+
+            System.Diagnostics.Debug.WriteLine("document switched");
+
+            this._Document = value;
+            this._Document.LayoutLines.Render = this.Render;
+            this._Document.Update += new DocumentUpdateEventHandler(Document_Update);
+            this._Document.LoadProgress += Document_LoadProgress;
+            this._Document.AutoCompleteChanged += _Document_AutoCompleteChanged;
+            if (this._Document.AutoComplete != null && this._Document.AutoComplete.GetPostion == null)
+                this._Document_AutoCompleteChanged(this._Document, null);
+            //初期化が終わっていればすべて存在する
+            if (this.Controller != null && this.View != null)
+            {
+                this.Controller.Document = value;
+                this.View.Document = value;
+
+                this.Controller.AdjustCaret();
+
+                this.CreateTextContext();
+
+                //依存プロパティとドキュメント内容が食い違っているので再設定する
+                this.ShowFullSpace = value.ShowFullSpace;
+                this.ShowHalfSpace = value.ShowHalfSpace;
+                this.ShowLineBreak = value.ShowLineBreak;
+                this.ShowTab = value.ShowTab;
+                this.FlowDirection = value.RightToLeft ? FlowDirection.RightToLeft : FlowDirection.LeftToRight;
+                this.IndentMode = value.IndentMode;
+                this.DrawCaretLine = !value.HideLineMarker;
+                this.InsertMode = value.InsertMode;
+                this.DrawRuler = !value.HideRuler;
+                this.DrawLineNumber = value.DrawLineNumber;
+                this.MarkURL = value.UrlMark;
+                this.LineBreakMethod = value.LineBreak;
+                this.LineBreakCharCount = value.LineBreakCharCount;
+                this.TabChars = value.TabStops;
+
+                this.Refresh();
+            }
+            //TextEditContext作成後に設定しないと落ちることがある
+            this._Document.SelectionChanged += Controller_SelectionChanged;
+        }
+
+        private void _Document_AutoCompleteChanged(object sender, EventArgs e)
+        {
+            Document doc = (Document)sender;
+            doc.AutoComplete.GetPostion = (tp, e_doc) =>
+            {
+                var p = this.View.GetPostionFromTextPoint(tp);
+                int height = (int)e_doc.LayoutLines.GetLayout(e_doc.CaretPostion.row).Height;
+
+                if (p.Y + AutoCompleteBox.CompleteListBoxHeight + height > e_doc.LayoutLines.Render.TextArea.Height)
+                    p.Y -= AutoCompleteBox.CompleteListBoxHeight;
+                else
+                    p.Y += height;
+                //AutoCompleteBox内ではCanvasで位置を指定しているので変換する必要がある
+                var pointInWindow = Util.GetPointInWindow(p, this);
+                return pointInWindow;
+            };
         }
 
         /// <inheritdoc/>
         public static void OnPropertyChanged(object sender, DependencyPropertyChangedEventArgs e)
         {
-#if !DUMMY_RENDER
             FooTextBox source = (FooTextBox)sender;
             if(e.Property.Equals(SelectedTextProperty) && !source.nowCaretMove)
                 source._Controller.SelectedText = source.SelectedText;
+            if (e.Property.Equals(DocumentProperty))
+                source.SetDocument(source.Document);
             if(e.Property.Equals(HilighterProperty))
                 source.View.Hilighter = source.Hilighter;
-            if (e.Property.Equals(TextAntialiasModeProperty))
-                source.Render.TextAntialiasMode = source.TextAntialiasMode;
             if (e.Property.Equals(FoldingStrategyProperty))
                 source.View.LayoutLines.FoldingStrategy = source.FoldingStrategy;
             if (e.Property.Equals(IndentModeProperty))
@@ -1271,6 +1447,26 @@ namespace FooEditEngine.UWP
                 source.View.HideLineMarker = !source.DrawCaretLine;
             if (e.Property.Equals(DrawLineNumberProperty))
                 source.Document.DrawLineNumber = source.DrawLineNumber;
+            if (e.Property.Equals(MarkURLProperty))
+                source.Document.UrlMark = source.MarkURL;
+            if (e.Property.Equals(LineBreakProperty))
+                source.Document.LineBreak = source.LineBreakMethod;
+            if (e.Property.Equals(LineBreakCharCountProperty))
+                source.Document.LineBreakCharCount = source.LineBreakCharCount;
+            if (e.Property.Equals(FlowDirectionProperty))
+            {
+                source.Document.RightToLeft = source.FlowDirection == Windows.UI.Xaml.FlowDirection.RightToLeft;
+                if (source.horizontalScrollBar != null)
+                    source.horizontalScrollBar.FlowDirection = source.FlowDirection;
+            }
+            if (e.Property.Equals(DrawRulerProperty))
+            {
+                source.Document.HideRuler = !source.DrawRuler;
+                source._Controller.JumpCaret(source.Document.CaretPostion.row, source.Document.CaretPostion.col);
+            }
+#if !DUMMY_RENDER
+            if (e.Property.Equals(TextAntialiasModeProperty))
+                source.Render.TextAntialiasMode = source.TextAntialiasMode;
             if(e.Property.Equals(MagnificationPowerPropertyKey))
                 source.Render.FontSize = source.FontSize * source.MagnificationPower;
             if (e.Property.Equals(FontFamilyProperty))
@@ -1283,6 +1479,8 @@ namespace FooEditEngine.UWP
                 source.Render.FontSize = source.FontSize;
             if (e.Property.Equals(ForegroundProperty))
                 source.Render.Foreground = D2DRenderBase.ToColor4(source.Foreground);
+            if (e.Property.Equals(HilightForegroundProperty))
+                source.Render.HilightForeground = D2DRenderBase.ToColor4(source.HilightForeground);
             if (e.Property.Equals(BackgroundProperty))
                 source.Render.Background = D2DRenderBase.ToColor4(source.Background);
             if (e.Property.Equals(ControlCharProperty))
@@ -1307,8 +1505,6 @@ namespace FooEditEngine.UWP
                 source.View.Padding = new Padding((int)source.Padding.Left, (int)source.Padding.Top, (int)source.Padding.Right, (int)source.Padding.Bottom);
             if (e.Property.Equals(LineMarkerProperty))
                 source.Render.LineMarker = D2DRenderBase.ToColor4(source.LineMarker);
-            if (e.Property.Equals(MarkURLProperty))
-                source.Document.UrlMark = source.MarkURL;
             if (e.Property.Equals(ShowFullSpaceProperty))
                 source.Render.ShowFullSpace = source.ShowFullSpace;
             if (e.Property.Equals(ShowHalfSpaceProperty))
@@ -1317,30 +1513,15 @@ namespace FooEditEngine.UWP
                 source.Render.ShowTab = source.ShowTab;
             if (e.Property.Equals(ShowLineBreakProperty))
                 source.Render.ShowLineBreak = source.ShowLineBreak;
-            if (e.Property.Equals(LineBreakProperty))
-                source.Document.LineBreak = source.LineBreakMethod;
-            if (e.Property.Equals(LineBreakCharCountProperty))
-                source.Document.LineBreakCharCount = source.LineBreakCharCount;
             if (e.Property.Equals(UpdateAreaProperty))
                 source.Render.UpdateArea = D2DRenderBase.ToColor4(source.UpdateArea);
             if (e.Property.Equals(LineNumberProperty))
                 source.Render.LineNumber = D2DRenderBase.ToColor4(source.LineNumber);
-            if (e.Property.Equals(FlowDirectionProperty))
-            {
-                source.Document.RightToLeft = source.FlowDirection == Windows.UI.Xaml.FlowDirection.RightToLeft;
-                if(source.horizontalScrollBar != null)
-                    source.horizontalScrollBar.FlowDirection = source.FlowDirection;
-            }
-            if (e.Property.Equals(DrawRulerProperty))
-            {
-                source.Document.HideRuler = !source.DrawRuler;
-                source._Controller.JumpCaret(source.Document.CaretPostion.row, source.Document.CaretPostion.col);
-            }
 #endif
         }
-#endregion
+        #endregion
 
-#region event
+        #region event
 
         /// <summary>
         /// コンテキストメニューが表示されるときに呼び出されます
@@ -1418,62 +1599,18 @@ namespace FooEditEngine.UWP
         /// <summary>
         /// ドキュメントを表す
         /// </summary>
+        /// <remarks>切り替え後に再描写が行われます</remarks>
         public Document Document
         {
-            get
-            {
-                return this._Document;
-            }
-            set
-            {
-                Document old_doc = this._Document;
-
-                if (this._Document != null)
-                {
-                    old_doc.Update -= new DocumentUpdateEventHandler(Document_Update);
-                    this._Document.SelectionChanged -= Controller_SelectionChanged;
+            get { return (Document)GetValue(DocumentProperty); }
+            set { SetValue(DocumentProperty, value); }
+        }
 
-                    //NotifyTextChanged()を呼び出すと落ちるのでTextConextをごっそり作り替える
-                    this.RemoveTextContext();
-                }
+        // Using a DependencyProperty as the backing store for Document.  This enables animation, styling, binding, etc...
+        public static readonly DependencyProperty DocumentProperty =
+            DependencyProperty.Register("Document", typeof(Document), typeof(FooTextBox), new PropertyMetadata(null, OnPropertyChanged));
 
-                System.Diagnostics.Debug.WriteLine("document switched");
 
-                this._Document = value;
-                this._Document.LayoutLines.Render = this.Render;
-                this._Document.Update += new DocumentUpdateEventHandler(Document_Update);
-                //初期化が終わっていればすべて存在する
-                if (this.Controller != null && this.View != null)
-                {
-                    this.Controller.Document = value;
-                    this.View.Document = value;
-
-                    this.Controller.AdjustCaret();
-
-                    this.CreateTextContext();
-
-                    //依存プロパティとドキュメント内容が食い違っているので再設定する
-                    this.ShowFullSpace = value.ShowFullSpace;
-                    this.ShowHalfSpace = value.ShowHalfSpace;
-                    this.ShowLineBreak = value.ShowLineBreak;
-                    this.ShowTab = value.ShowTab;
-                    this.FlowDirection = value.RightToLeft ? FlowDirection.RightToLeft : FlowDirection.LeftToRight;
-                    this.IndentMode = value.IndentMode;
-                    this.DrawCaretLine = !value.HideLineMarker;
-                    this.InsertMode = value.InsertMode;
-                    this.DrawRuler = !value.HideRuler;
-                    this.DrawLineNumber = value.DrawLineNumber;
-                    this.MarkURL = value.UrlMark;
-                    this.LineBreakMethod = value.LineBreak;
-                    this.LineBreakCharCount = value.LineBreakCharCount;
-                    this.TabChars = value.TabStops;
-
-                    this.Refresh();
-                }
-                //TextEditContext作成後に設定しないと落ちることがある
-                this._Document.SelectionChanged += Controller_SelectionChanged;
-            }
-        }
 
         /// <summary>
         /// レイアウト行を表す
@@ -1650,6 +1787,21 @@ namespace FooEditEngine.UWP
             DependencyProperty.Register("Foreground", typeof(Windows.UI.Color), typeof(FooTextBox), new PropertyMetadata(Colors.Black, OnPropertyChanged));
 
         /// <summary>
+        /// 選択時の文字色を表す。これは依存プロパティです
+        /// </summary>
+        public Windows.UI.Color HilightForeground
+        {
+            get { return (Windows.UI.Color)GetValue(HilightForegroundProperty); }
+            set { SetValue(HilightForegroundProperty, value); }
+        }
+
+        /// <summary>
+        /// HilightForegroundForegroundの依存プロパティを表す
+        /// </summary>
+        public static readonly DependencyProperty HilightForegroundProperty =
+            DependencyProperty.Register("HilightForeground", typeof(Windows.UI.Color), typeof(FooTextBox), new PropertyMetadata(Colors.White, OnPropertyChanged));
+
+        /// <summary>
         /// 背景色を表す。これは依存プロパティです
         /// </summary>
         public new Windows.UI.Color Background
@@ -1692,7 +1844,7 @@ namespace FooEditEngine.UWP
         /// Hilightの依存プロパティを表す
         /// </summary>
         public static readonly DependencyProperty HilightProperty =
-            DependencyProperty.Register("Hilight", typeof(Windows.UI.Color), typeof(FooTextBox), new PropertyMetadata(Colors.DeepSkyBlue, OnPropertyChanged));
+            DependencyProperty.Register("Hilight", typeof(Windows.UI.Color), typeof(FooTextBox), new PropertyMetadata(Colors.DodgerBlue, OnPropertyChanged));
 
         /// <summary>
         /// キーワード1の文字色を表す。これは依存プロパティです