OSDN Git Service

ドラッグしながらの選択ができなくなるので元に戻した
[fooeditengine/FooEditEngine.git] / WPF / FooEditEngine / FooTextBox.cs
index 133bbbd..30a3bb8 100644 (file)
@@ -46,7 +46,11 @@ namespace FooEditEngine.WPF
         FooTextBoxAutomationPeer peer;
         bool isNotifyChanged = false;
         Document _Document;
-        
+        Popup popup;
+
+        const int Interval = 96;
+        const int IntervalWhenLostFocuse = 160;
+
         static FooTextBox()
         {
             DefaultStyleKeyProperty.OverrideMetadata(typeof(FooTextBox), new FrameworkPropertyMetadata(typeof(FooTextBox)));
@@ -59,6 +63,8 @@ namespace FooEditEngine.WPF
         /// </summary>
         public FooTextBox()
         {
+            this.popup = new Popup();
+
             this.image = new Image();
             this.image.Stretch = Stretch.Fill;
             this.image.HorizontalAlignment = HorizontalAlignment.Left;
@@ -80,9 +86,6 @@ namespace FooEditEngine.WPF
             this.textStore.CompositionEnded += textStore_CompositionEnded;
 
             this.Render = new D2DRender(this, 200, 200,this.image);
-            this.Render.ShowFullSpace = this.ShowFullSpace;
-            this.Render.ShowHalfSpace = this.ShowHalfSpace;
-            this.Render.ShowTab = this.ShowTab;
 
             this.Document = new Document();
 
@@ -95,6 +98,9 @@ namespace FooEditEngine.WPF
             this.Document.HideRuler = !this.DrawRuler;
             this.Document.UrlMark = this.MarkURL;
             this.Document.TabStops = this.TabChars;
+            this.Document.ShowFullSpace = this.ShowFullSpace;
+            this.Document.ShowHalfSpace = this.ShowHalfSpace;
+            this.Document.ShowTab = this.ShowTab;
 
             this._Controller = new Controller(this.Document, this.View);
             this._Document.SelectionChanged += new EventHandler(Controller_SelectionChanged);
@@ -122,7 +128,7 @@ namespace FooEditEngine.WPF
             this.InputBindings.Add(new InputBinding(FooTextBoxCommands.ToggleCodePoint, new KeyGesture(Key.X, ModifierKeys.Alt)));
 
             this.timer = new DispatcherTimer();
-            this.timer.Interval = new TimeSpan(0, 0, 0, 0, 100);
+            this.timer.Interval = new TimeSpan(0, 0, 0, 0, Interval);
             this.timer.Tick += new EventHandler(timer_Tick);
 
             this.Loaded += new RoutedEventHandler(FooTextBox_Loaded);
@@ -166,6 +172,12 @@ namespace FooEditEngine.WPF
                 Grid.SetRow(this.image, 0);
                 Grid.SetColumn(this.image, 0);
                 grid.Children.Add(this.image);
+
+                Grid.SetRow(this.popup, 0);
+                Grid.SetColumn(this.popup, 0);
+                grid.Children.Add(this.popup);
+                //this.popup.PlacementTarget = this;
+                this.popup.Placement = PlacementMode.Absolute;
             }
 
             this.horizontalScrollBar = this.GetTemplateChild("PART_HorizontalScrollBar") as ScrollBar;
@@ -181,7 +193,7 @@ namespace FooEditEngine.WPF
             {
                 this.verticalScrollBar.SmallChange = 1;
                 this.verticalScrollBar.LargeChange = 10;
-                this.verticalScrollBar.Maximum = this.View.LayoutLines.Count;
+                this.verticalScrollBar.Maximum = this.Document.LayoutLines.Count - 1;
                 this.verticalScrollBar.Scroll += new ScrollEventHandler(verticalScrollBar_Scroll);
             }
         }
@@ -385,8 +397,10 @@ namespace FooEditEngine.WPF
                 TextStoreHelper.NotifyTextChanged(this.textStore, 0, 0, this.Document.Length);
                 if (this.verticalScrollBar != null)
                     this.verticalScrollBar.Maximum = this.View.LayoutLines.Count;
+                this.View.CalculateWhloeViewPort();
                 this.View.CalculateLineCountOnScreen();
                 this.IsEnabled = true;
+                this.Refresh(this.View.PageBound);
             }
         }
 
@@ -638,6 +652,7 @@ namespace FooEditEngine.WPF
             base.OnGotKeyboardFocus(e);
             this.textStore.SetFocus();
             this.View.IsFocused = true;
+            this.timer.Interval = new TimeSpan(0,0,0,0,Interval);
             this.Refresh();
         }
 
@@ -649,6 +664,7 @@ namespace FooEditEngine.WPF
         {
             base.OnLostKeyboardFocus(e);
             this.View.IsFocused = false;
+            this.timer.Interval = new TimeSpan(0, 0, 0, 0, IntervalWhenLostFocuse);
             this.Refresh();
         }
         #endregion
@@ -706,6 +722,15 @@ namespace FooEditEngine.WPF
                 return;
 
             ModifierKeys modiferKeys = e.KeyboardDevice.Modifiers;
+
+            var autocomplete = this.Document.AutoComplete as AutoCompleteBox;
+            if (autocomplete != null &&
+                autocomplete.ProcessKeyDown(this,e, this.IsPressedModifierKey(modiferKeys, ModifierKeys.Control), this.IsPressedModifierKey(modiferKeys, ModifierKeys.Shift)))
+            {
+                e.Handled = true;
+                return;
+            }
+
             bool movedCaret = false;
             switch (e.Key)
             {
@@ -814,8 +839,11 @@ namespace FooEditEngine.WPF
 
             if (e.LeftButton == MouseButtonState.Pressed)
             {
+                if (p.X < this.Render.TextArea.X)
+                    this.Document.SelectLine((int)index);
+                else
+                    this.Document.SelectWord((int)index);
 
-                this.Document.SelectWord((int)index);
                 this.textStore.NotifySelectionChanged();
                 if(this.peer != null)
                     this.peer.OnNotifyCaretChanged();
@@ -903,16 +931,25 @@ namespace FooEditEngine.WPF
 
             TextPointSearchRange searchRange;
             if (this.View.HitTextArea(p.X, p.Y))
+            {
                 searchRange = TextPointSearchRange.TextAreaOnly;
+            }
             else if (leftPressed)
+            {
                 searchRange = TextPointSearchRange.Full;
+            }
             else
-                searchRange = TextPointSearchRange.TextAreaOnly;
+            {
+                this.Cursor = Cursors.Arrow;
+                base.OnMouseMove(e);
+                return;
+            }
 
             TextPoint tp = this.View.GetTextPointFromPostion(p, searchRange);
 
             if (tp == TextPoint.Null)
             {
+                this.Cursor = Cursors.Arrow;
                 base.OnMouseMove(e);
                 return;
             }
@@ -938,10 +975,10 @@ namespace FooEditEngine.WPF
             {
                 this.Cursor = Cursors.Arrow;
             }
-
             if (leftPressed)
             {
-                this._Controller.MoveCaretAndSelect(tp);
+                bool controlPressed = (Keyboard.GetKeyStates(Key.LeftCtrl) & KeyStates.Down) == KeyStates.Down;
+                this._Controller.MoveCaretAndSelect(tp, controlPressed);
                 if (this.peer != null)
                     this.peer.OnNotifyCaretChanged();
                 this.Refresh();
@@ -1114,14 +1151,14 @@ namespace FooEditEngine.WPF
                 return;
             if (this.Resize(this.image.ActualWidth, this.image.ActualHeight))
             {
-                this.Refresh();
+                this.Refresh(this.View.PageBound);
                 return;
             }
 
             bool updateAll = this.View.LayoutLines.HilightAll() || this.View.LayoutLines.GenerateFolding() || this.Document.IsRequestRedraw;
 
             if (updateAll)
-                this.Refresh();
+                this.Refresh(this.View.PageBound);
             else
                 this.Refresh(this.View.GetCurrentCaretRect());
         }
@@ -1135,7 +1172,7 @@ namespace FooEditEngine.WPF
                 toX = this.horizontalScrollBar.Value;
             else
                 toX = -this.horizontalScrollBar.Value;
-            this._Controller.Scroll(toX, this.View.Src.Row, false, false);
+            this.Controller.ScrollByPixel(ScrollDirection.Left, (int)toX, false, false);
             this.Refresh();
         }
 
@@ -1143,10 +1180,7 @@ namespace FooEditEngine.WPF
         {
             if (this.verticalScrollBar == null)
                 return;
-            int newRow = (int)this.verticalScrollBar.Value;
-            if (newRow >= this.View.LayoutLines.Count)
-                return;
-            this._Controller.Scroll(this.View.Src.X,newRow, false, false);
+            this.Controller.Scroll(this.Document.Src.X, (int)this.verticalScrollBar.Value, false, false);
             this.Refresh();
         }
 
@@ -1155,8 +1189,8 @@ namespace FooEditEngine.WPF
             if (this.horizontalScrollBar == null || this.verticalScrollBar == null)
                 return;
             EditView view = this.View;
-            if (view.Src.Row > this.verticalScrollBar.Maximum)
-                this.verticalScrollBar.Maximum = view.Src.Row + view.LineCountOnScreen + 1;
+            if (view.Src.Row > this.Document.LayoutLines.Count)
+                this.verticalScrollBar.Maximum = this.Document.LayoutLines.Count - 1;
             double absoulteX = Math.Abs(view.Src.X);
             if(absoulteX > this.horizontalScrollBar.Maximum)
                 this.horizontalScrollBar.Maximum = absoulteX + view.PageBound.Width + 1;
@@ -1223,14 +1257,24 @@ namespace FooEditEngine.WPF
             {
                 old_doc.Update -= new DocumentUpdateEventHandler(Document_Update);
                 old_doc.LoadProgress -= Document_LoadProgress;
-                old_doc.SelectionChanged += new EventHandler(Controller_SelectionChanged);
+                old_doc.SelectionChanged -= new EventHandler(Controller_SelectionChanged);
+                old_doc.AutoCompleteChanged -= _Document_AutoCompleteChanged;
                 oldLength = old_doc.Length;
+                if (this._Document.AutoComplete != null)
+                {
+                    ((AutoCompleteBox)this._Document.AutoComplete).TargetPopup = null;
+                    this._Document.AutoComplete.GetPostion = null;
+                    this._Document.AutoComplete = null;
+                }
             }
 
             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.textStore != null)
             {
@@ -1260,6 +1304,20 @@ namespace FooEditEngine.WPF
                 this.Refresh();
             }
         }
+
+        private void _Document_AutoCompleteChanged(object sender, EventArgs e)
+        {
+            Document doc = (Document)sender;
+            ((AutoCompleteBox)this._Document.AutoComplete).TargetPopup = this.popup;
+            this._Document.AutoComplete.GetPostion = (tp, edoc) =>
+            {
+                var p = this.View.GetPostionFromTextPoint(tp);
+                int height = (int)this.Render.emSize.Height;
+                p.Y += height;
+                return PointToScreen(this.TranslatePoint(p.Scale(Util.GetScale()), this));
+            };
+        }
+
         /// <summary>
         /// プロパティーが変更されたときに呼ばれます
         /// </summary>
@@ -1334,6 +1392,9 @@ namespace FooEditEngine.WPF
                 case "Foreground":
                     this.Render.Foreground = D2DRender.ToColor4(this.Foreground);
                     break;
+                case "HilightForeground":
+                    this.Render.HilightForeground = D2DRender.ToColor4(this.HilightForeground);
+                    break;
                 case "Background":
                     this.Render.Background = D2DRender.ToColor4(this.Background);
                     break;
@@ -1616,7 +1677,22 @@ namespace FooEditEngine.WPF
         /// </summary>
         public new static readonly DependencyProperty BackgroundProperty =
             DependencyProperty.Register("Background", typeof(System.Windows.Media.Color), typeof(FooTextBox), new FrameworkPropertyMetadata(SystemColors.WindowColor));
-        
+
+        /// <summary>
+        /// 選択時の文字色を表す。これは依存プロパティです
+        /// </summary>
+        public System.Windows.Media.Color HilightForeground
+        {
+            get { return (System.Windows.Media.Color)GetValue(HilightForegroundProperty); }
+            set { SetValue(HilightForegroundProperty, value); }
+        }
+
+        /// <summary>
+        /// ControlCharの依存プロパティを表す
+        /// </summary>
+        public static readonly DependencyProperty HilightForegroundProperty =
+            DependencyProperty.Register("HilightForeground", typeof(System.Windows.Media.Color), typeof(FooTextBox), new FrameworkPropertyMetadata(Colors.White));
+
         /// <summary>
         /// コントロールコードの文字色を表す。これは依存プロパティです
         /// </summary>