2 * Copyright (C) 2013 FooProject
3 * * This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; either version 3 of the License, or (at your option) any later version.
6 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
7 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
9 You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>.
13 using System.Threading.Tasks;
14 using System.Runtime.InteropServices;
16 using System.Windows.Input;
17 using System.Windows.Media;
18 using System.Windows.Controls;
19 using System.Windows.Controls.Primitives;
20 using System.Windows.Documents;
21 using System.Windows.Interop;
22 using System.Windows.Threading;
23 using DotNetTextStore;
24 using DotNetTextStore.UnmanagedAPI.TSF;
25 using DotNetTextStore.UnmanagedAPI.WinDef;
26 using Microsoft.Win32;
28 namespace FooEditEngine.WPF
31 /// オートインデントを行うためのデリゲートを表す
33 /// <param name="sender">イベント発生元のオブジェクト</param>
34 /// <param name="e">イベントデーター</param>
35 public delegate void AutoIndentHookerHandler(object sender,EventArgs e);
38 /// WPFでのFooTextBoxの実装
40 public sealed class FooTextBox : Control, IDisposable
42 const double MaxFontSize = 72.0f;
43 const double MinFontSize = 1;
46 Controller _Controller;
49 ScrollBar verticalScrollBar, horizontalScrollBar;
51 DispatcherTimer timer;
52 bool disposed = false;
53 FooTextBoxAutomationPeer peer;
54 bool nowCaretMove = false;
58 DefaultStyleKeyProperty.OverrideMetadata(typeof(FooTextBox), new FrameworkPropertyMetadata(typeof(FooTextBox)));
59 KeyboardNavigation.IsTabStopProperty.OverrideMetadata(typeof(FooTextBox), new FrameworkPropertyMetadata(true));
60 KeyboardNavigation.TabNavigationProperty.OverrideMetadata(typeof(FooTextBox), new FrameworkPropertyMetadata(KeyboardNavigationMode.None));
68 this.image = new Image();
69 this.image.Stretch = Stretch.Fill;
70 this.image.HorizontalAlignment = HorizontalAlignment.Left;
71 this.image.VerticalAlignment = VerticalAlignment.Top;
73 this.textStore = new TextStore();
74 this.textStore.IsLoading += textStore_IsLoading;
75 this.textStore.IsReadOnly += textStore_IsReadOnly;
76 this.textStore.GetStringLength += () => this.Document.Length;
77 this.textStore.GetString += _textStore_GetString;
78 this.textStore.GetSelectionIndex += _textStore_GetSelectionIndex;
79 this.textStore.SetSelectionIndex += _textStore_SetSelectionIndex;
80 this.textStore.InsertAtSelection += _textStore_InsertAtSelection;
81 this.textStore.GetHWnd += _textStore_GetHWnd;
82 this.textStore.GetScreenExtent += _textStore_GetScreenExtent;
83 this.textStore.GetStringExtent += _textStore_GetStringExtent;
84 this.textStore.CompositionStarted += textStore_CompositionStarted;
85 this.textStore.CompositionUpdated += textStore_CompositionUpdated;
86 this.textStore.CompositionEnded += textStore_CompositionEnded;
88 this.Render = new D2DRender(this, 200, 200,this.image);
89 this.Render.ShowFullSpace = this.ShowFullSpace;
90 this.Render.ShowHalfSpace = this.ShowHalfSpace;
91 this.Render.ShowTab = this.ShowTab;
93 this.Document = new Document();
94 this.Document.LayoutLines.Render = this.Render;
96 this.View = new EditView(this.Document, this.Render, new Padding(5, 5, 5, 5));
97 this.View.SrcChanged += View_SrcChanged;
98 this.View.InsertMode = this.InsertMode;
99 this.Document.DrawLineNumber = this.DrawLineNumber;
100 this.View.HideCaret = !this.DrawCaret;
101 this.View.HideLineMarker = !this.DrawCaretLine;
102 this.Document.HideRuler = !this.DrawRuler;
103 this.Document.UrlMark = this.MarkURL;
104 this.Document.TabStops = this.TabChars;
106 this._Controller = new Controller(this.Document, this.View);
107 this._Controller.SelectionChanged += new EventHandler(Controller_SelectionChanged);
109 //Viewを作成した後に追加しないと例外が発生する
110 this.Document.Update += new DocumentUpdateEventHandler(Document_Update);
112 this.CommandBindings.Add(new CommandBinding(ApplicationCommands.Copy, CopyCommand, CanExecute));
113 this.CommandBindings.Add(new CommandBinding(ApplicationCommands.Cut, CutCommand, CanExecute));
114 this.CommandBindings.Add(new CommandBinding(ApplicationCommands.Paste, PasteCommand, CanExecute));
115 this.CommandBindings.Add(new CommandBinding(ApplicationCommands.Delete, DeleteCommand, CanExecute));
116 this.CommandBindings.Add(new CommandBinding(ApplicationCommands.SelectAll, SelectAllCommand, CanExecute));
117 this.CommandBindings.Add(new CommandBinding(ApplicationCommands.Undo, UndoCommand, CanExecute));
118 this.CommandBindings.Add(new CommandBinding(ApplicationCommands.Redo, RedoCommand, CanExecute));
119 this.CommandBindings.Add(new CommandBinding(EditingCommands.ToggleInsert, ToggleInsertCommand, CanExecute));
120 this.CommandBindings.Add(new CommandBinding(FooTextBoxCommands.ToggleRectSelectMode, ToggleRectSelectCommand, CanExecute));
121 this.CommandBindings.Add(new CommandBinding(FooTextBoxCommands.ToggleFlowDirection, ToggleFlowDirectionCommand, CanExecute));
122 this.CommandBindings.Add(new CommandBinding(FooTextBoxCommands.ToggleCodePoint, ToggleCodePointCommand, CanExecute));
124 this.InputBindings.Add(new InputBinding(ApplicationCommands.Copy, new KeyGesture(Key.C, ModifierKeys.Control)));
125 this.InputBindings.Add(new InputBinding(ApplicationCommands.Cut, new KeyGesture(Key.X, ModifierKeys.Control)));
126 this.InputBindings.Add(new InputBinding(ApplicationCommands.Paste, new KeyGesture(Key.V, ModifierKeys.Control)));
127 this.InputBindings.Add(new InputBinding(ApplicationCommands.Delete, new KeyGesture(Key.Delete, ModifierKeys.None)));
128 this.InputBindings.Add(new InputBinding(ApplicationCommands.SelectAll, new KeyGesture(Key.A, ModifierKeys.Control)));
129 this.InputBindings.Add(new InputBinding(ApplicationCommands.Undo, new KeyGesture(Key.Z, ModifierKeys.Control)));
130 this.InputBindings.Add(new InputBinding(ApplicationCommands.Redo, new KeyGesture(Key.Y, ModifierKeys.Control)));
131 this.InputBindings.Add(new InputBinding(EditingCommands.ToggleInsert, new KeyGesture(Key.Insert, ModifierKeys.None)));
132 this.InputBindings.Add(new InputBinding(FooTextBoxCommands.ToggleCodePoint, new KeyGesture(Key.X, ModifierKeys.Alt)));
134 this.timer = new DispatcherTimer();
135 this.timer.Interval = new TimeSpan(0, 0, 0, 0, 100);
136 this.timer.Tick += new EventHandler(timer_Tick);
138 this.Loaded += new RoutedEventHandler(FooTextBox_Loaded);
140 this.AutoIndentHooker = (s,e)=>{};
142 SystemEvents.UserPreferenceChanged += new UserPreferenceChangedEventHandler(SystemEvents_UserPreferenceChanged);
144 this.SystemEvents_UserPreferenceChanged(null, new UserPreferenceChangedEventArgs(UserPreferenceCategory.Keyboard));
146 this.CaretMoved += (s, e) => { };
154 //Dispose(false)を呼び出すと落ちる
159 /// オートインデントを行うためのイベント
161 public AutoIndentHookerHandler AutoIndentHooker;
166 public override void OnApplyTemplate()
168 base.OnApplyTemplate();
170 Grid grid = this.GetTemplateChild("PART_Grid") as Grid;
173 Grid.SetRow(this.image, 0);
174 Grid.SetColumn(this.image, 0);
175 grid.Children.Add(this.image);
178 this.horizontalScrollBar = this.GetTemplateChild("PART_HorizontalScrollBar") as ScrollBar;
179 if (this.horizontalScrollBar != null)
181 this.horizontalScrollBar.SmallChange = 10;
182 this.horizontalScrollBar.LargeChange = 100;
183 this.horizontalScrollBar.Maximum = this.horizontalScrollBar.LargeChange + 1;
184 this.horizontalScrollBar.Scroll += new ScrollEventHandler(horizontalScrollBar_Scroll);
186 this.verticalScrollBar = this.GetTemplateChild("PART_VerticalScrollBar") as ScrollBar;
187 if (this.verticalScrollBar != null)
189 this.verticalScrollBar.SmallChange = 1;
190 this.verticalScrollBar.LargeChange = 10;
191 this.verticalScrollBar.Maximum = this.View.LayoutLines.Count;
192 this.verticalScrollBar.Scroll += new ScrollEventHandler(verticalScrollBar_Scroll);
199 /// <param name="start">開始インデックス</param>
200 /// <param name="length">長さ</param>
201 public void Select(int start, int length)
203 this._Controller.Select(start, length);
204 this.textStore.NotifySelectionChanged();
208 /// キャレットを指定した行に移動させます
210 /// <param name="index">インデックス</param>
211 /// <remarks>このメソッドを呼び出すと選択状態は解除されます</remarks>
212 public void JumpCaret(int index)
214 this._Controller.JumpCaret(index);
217 /// キャレットを指定した行と桁に移動させます
219 /// <param name="row">行番号</param>
220 /// <param name="col">桁</param>
221 /// <remarks>このメソッドを呼び出すと選択状態は解除されます</remarks>
222 public void JumpCaret(int row, int col)
224 this._Controller.JumpCaret(row, col);
228 /// 選択中のテキストをクリップボードにコピーします
232 string text = this._Controller.SelectedText;
233 if (text != null && text != string.Empty)
234 Clipboard.SetText(text);
238 /// 選択中のテキストをクリップボードに切り取ります
242 string text = this._Controller.SelectedText;
243 if (text != null && text != string.Empty)
245 Clipboard.SetText(text);
246 this._Controller.SelectedText = "";
255 if (Clipboard.ContainsText() == false)
257 string text = Clipboard.GetText();
258 this._Controller.SelectedText = text;
264 public void DeSelectAll()
266 this._Controller.DeSelectAll();
267 this.textStore.NotifySelectionChanged();
273 /// <param name="tp">テキストポイント</param>
274 /// <returns>座標</returns>
275 /// <remarks>テキストポイントがクライアント領域の原点より外にある場合、返される値は原点に丸められます</remarks>
276 public System.Windows.Point GetPostionFromTextPoint(TextPoint tp)
278 if (this.Document.FireUpdateEvent == false)
279 throw new InvalidOperationException("");
280 return this.View.GetPostionFromTextPoint(tp);
284 /// 対応するテキストポイントを返します
286 /// <param name="p">クライアント領域の原点を左上とする座標</param>
287 /// <returns>テキストポイント</returns>
288 public TextPoint GetTextPointFromPostion(System.Windows.Point p)
290 if (this.Document.FireUpdateEvent == false)
291 throw new InvalidOperationException("");
292 return this.View.GetTextPointFromPostion(p);
298 /// <param name="row">レイアウト行</param>
299 /// <returns>行の高さ</returns>
300 public double GetLineHeight(int row)
302 if (this.Document.FireUpdateEvent == false)
303 throw new InvalidOperationException("");
304 return this.View.LayoutLines.GetLayout(row).Height;;
308 /// インデックスに対応する座標を得ます
310 /// <param name="index">インデックス</param>
311 /// <returns>座標を返す</returns>
312 public System.Windows.Point GetPostionFromIndex(int index)
314 if (this.Document.FireUpdateEvent == false)
315 throw new InvalidOperationException("");
316 TextPoint tp = this.View.GetLayoutLineFromIndex(index);
317 return this.View.GetPostionFromTextPoint(tp);
323 /// <param name="p">座標</param>
324 /// <returns>インデックスを返す</returns>
325 public int GetIndexFromPostion(System.Windows.Point p)
327 if (this.Document.FireUpdateEvent == false)
328 throw new InvalidOperationException("");
329 TextPoint tp = this.View.GetTextPointFromPostion(p);
330 return this.View.GetIndexFromLayoutLine(tp);
336 public void Refresh()
338 this.Refresh(this.View.PageBound);
342 /// レイアウト行をすべて破棄し、再度レイアウトを行う
344 public void PerfomLayouts()
346 this.View.PerfomLayouts();
352 /// <param name="row">行</param>
353 /// <param name="alignTop">指定行を画面上に置くなら真。そうでないなら偽</param>
354 public void ScrollIntoView(int row, bool alignTop)
356 this.View.ScrollIntoView(row, alignTop);
360 /// ストリームからドキュメントを構築する
362 /// <param name="tr">TextReader</param>
363 /// <param name="token">キャンセル用トークン</param>
364 /// <returns>Taskオブジェクト</returns>
365 public async Task LoadAsync(System.IO.TextReader tr, System.Threading.CancellationTokenSource token)
367 WinFileReader fs = new WinFileReader(tr);
368 await this.LoadAsyncImpl(fs, token);
372 /// ファイルからドキュメントを構築する
374 /// <param name="filepath">ファイルパス</param>
375 /// <param name="enc">エンコード</param>
376 /// <param name="token">キャンセル用トークン</param>
377 /// <returns>Taskオブジェクト</returns>
378 public async Task LoadFileAsync(string filepath, Encoding enc,System.Threading.CancellationTokenSource token)
380 WinFileReader fs = new WinFileReader(filepath, enc);
381 await this.LoadAsyncImpl(fs, token);
385 async Task LoadAsyncImpl(WinFileReader fs,System.Threading.CancellationTokenSource token)
387 this.IsEnabled = false;
388 this.View.LayoutLines.IsFrozneDirtyFlag = true;
389 await this.Document.LoadAsync(fs, token);
390 this.View.LayoutLines.IsFrozneDirtyFlag = false;
391 TextStoreHelper.NotifyTextChanged(this.textStore, 0, 0, this.Document.Length);
392 if (this.verticalScrollBar != null)
393 this.verticalScrollBar.Maximum = this.View.LayoutLines.Count;
394 this.View.CalculateLineCountOnScreen();
395 this.IsEnabled = true;
399 /// ドキュメントの内容をファイルに保存する
401 /// <param name="filepath">ファイルパス</param>
402 /// <param name="newLine">改行コード</param>
403 /// <param name="enc">エンコード</param>
404 /// <returns>Taskオブジェクト</returns>
405 public async Task SaveFile(string filepath, Encoding enc,string newLine, System.Threading.CancellationTokenSource token)
407 WinFileWriter fs = new WinFileWriter(filepath, enc);
408 fs.NewLine = newLine;
409 await this.Document.SaveAsync(fs, token);
416 public void Dispose()
421 GC.SuppressFinalize(this);
422 this.disposed = true;
428 /// <param name="disposing">真ならマネージドリソースも開放し、そうでないならアンマネージドリソースのみを開放する</param>
429 void Dispose(bool disposing)
433 this.textStore.Dispose();
436 this.Render.Dispose();
438 SystemEvents.UserPreferenceChanged -= new UserPreferenceChangedEventHandler(SystemEvents_UserPreferenceChanged);
441 void Refresh(Rectangle updateRect)
443 if (this.disposed || this.Visibility == Visibility.Collapsed)
446 this.Render.BegineDraw();
448 this.View.Draw(updateRect);
450 this.Render.FillBackground(updateRect);
451 this.Render.EndDraw();
455 void CanExecute(object sender, CanExecuteRoutedEventArgs e)
457 e.CanExecute = this.IsEnabled;
460 void ToggleCodePointCommand(object sender, RoutedEventArgs e)
462 if (!this._Controller.ConvertToChar())
463 this._Controller.ConvertToCodePoint();
467 void CopyCommand(object sender, RoutedEventArgs e)
472 void CutCommand(object sender, RoutedEventArgs e)
478 void PasteCommand(object sender, RoutedEventArgs e)
484 void DeleteCommand(object sender, RoutedEventArgs e)
486 int oldLength = this.Document.Length;
487 this._Controller.DoDeleteAction();
491 void SelectAllCommand(object sender, RoutedEventArgs e)
493 this.Select(0, this.Document.Length);
497 void UndoCommand(object sender, RoutedEventArgs e)
499 int oldLength = this.Document.Length;
500 this.Document.UndoManager.undo();
504 void RedoCommand(object sender, RoutedEventArgs e)
506 int oldLength = this.Document.Length;
507 this.Document.UndoManager.redo();
511 void ToggleInsertCommand(object sender, RoutedEventArgs e)
514 this.InsertMode = false;
516 this.InsertMode = true;
520 void ToggleRectSelectCommand(object sender, RoutedEventArgs e)
522 if (this.RectSelectMode)
523 this.RectSelectMode = false;
525 this.RectSelectMode = true;
528 void ToggleFlowDirectionCommand(object sender, RoutedEventArgs e)
530 if (this.FlowDirection == System.Windows.FlowDirection.LeftToRight)
531 this.FlowDirection = System.Windows.FlowDirection.RightToLeft;
533 this.FlowDirection = System.Windows.FlowDirection.LeftToRight;
538 internal TextStore TextStore
540 get { return this.textStore; }
543 bool textStore_IsReadOnly()
548 bool textStore_IsLoading()
553 void textStore_CompositionEnded()
555 TextStoreHelper.EndCompostion(this.Document);
559 void textStore_CompositionUpdated(int start, int end)
561 if (TextStoreHelper.ScrollToCompstionUpdated(this.textStore, this.View, start, end))
564 bool textStore_CompositionStarted()
566 bool result = TextStoreHelper.StartCompstion(this.Document);
568 System.Media.SystemSounds.Beep.Play();
572 string _textStore_GetString(int start, int length)
574 return this.Document.ToString(start, length);
577 IntPtr _textStore_GetHWnd()
579 var hwndSource = HwndSource.FromVisual(this) as HwndSource;
580 if (hwndSource != null)
581 return hwndSource.Handle;
586 void _textStore_GetStringExtent(
590 out POINT o_bottomRight
593 Point startPos, endPos;
594 TextStoreHelper.GetStringExtent(this.Document, this.View, i_startIndex, i_endIndex, out startPos, out endPos);
596 double scale = this.Render.GetScale();
598 startPos = PointToScreen(this.TranslatePoint(startPos.Scale(scale), this));
599 endPos = PointToScreen(this.TranslatePoint(endPos.Scale(scale), this));
601 o_topLeft = new POINT((int)startPos.X, (int)startPos.Y);
602 o_bottomRight = new POINT((int)endPos.X, (int)endPos.Y);
605 void _textStore_GetScreenExtent(out POINT o_topLeft, out POINT o_bottomRight)
607 var pointTopLeft = new Point(0, 0);
608 var pointBottomRight = new Point(this.RenderSize.Width, this.RenderSize.Height);
610 pointTopLeft = PointToScreen(pointTopLeft);
611 pointBottomRight = PointToScreen(pointBottomRight);
613 o_topLeft = new POINT((int)pointTopLeft.X, (int)pointTopLeft.Y);
614 o_bottomRight = new POINT((int)pointBottomRight.X, (int)pointBottomRight.Y);
617 void _textStore_GetSelectionIndex(out int o_startIndex, out int o_endIndex)
619 TextStoreHelper.GetSelection(this._Controller, this.View.Selections, out o_startIndex, out o_endIndex);
622 void _textStore_SetSelectionIndex(int i_startIndex, int i_endIndex)
624 TextStoreHelper.SetSelectionIndex(this._Controller, this.View, i_startIndex, i_endIndex);
628 void _textStore_InsertAtSelection(string i_value, ref int o_startIndex, ref int o_endIndex)
630 TextStoreHelper.InsertTextAtSelection(this._Controller, i_value);
635 /// キーボードフォーカスが取得されたときに呼ばれます
637 /// <param name="e">イベントデーター</param>
638 protected override void OnGotKeyboardFocus(KeyboardFocusChangedEventArgs e)
640 base.OnGotKeyboardFocus(e);
641 this.textStore.SetFocus();
642 this.View.IsFocused = true;
647 /// キーボードフォーカスが失われたときに呼ばれます
649 /// <param name="e">イベントデーター</param>
650 protected override void OnLostKeyboardFocus(KeyboardFocusChangedEventArgs e)
652 base.OnLostKeyboardFocus(e);
653 this.View.IsFocused = false;
659 /// キャレットが移動したときに通知されるイベント
661 public event EventHandler CaretMoved;
664 protected override System.Windows.Automation.Peers.AutomationPeer OnCreateAutomationPeer()
666 this.peer = new FooTextBoxAutomationPeer(this);
672 protected override void OnTextInput(TextCompositionEventArgs e)
676 this._Controller.DoEnterAction();
677 this.AutoIndentHooker(this, null);
679 else if (e.Text == "\b")
681 this._Controller.DoBackSpaceAction();
685 if(this.IsInputString(e.Text))
686 this._Controller.DoInputString(e.Text);
693 bool IsInputString(string s)
695 foreach (char charCode in s)
697 if ((0x20 <= charCode && charCode <= 0x7e)
705 protected override void OnKeyDown(KeyEventArgs e)
707 if (this.textStore.IsLocked())
710 ModifierKeys modiferKeys = e.KeyboardDevice.Modifiers;
711 bool movedCaret = false;
715 this._Controller.MoveCaretVertical(-1, this.IsPressedModifierKey(modiferKeys, ModifierKeys.Shift));
721 this._Controller.MoveCaretVertical(+1, this.IsPressedModifierKey(modiferKeys, ModifierKeys.Shift));
727 this._Controller.MoveCaretHorizontical(-1, this.IsPressedModifierKey(modiferKeys, ModifierKeys.Shift), this.IsPressedModifierKey(modiferKeys, ModifierKeys.Control));
733 this._Controller.MoveCaretHorizontical(1, this.IsPressedModifierKey(modiferKeys, ModifierKeys.Shift), this.IsPressedModifierKey(modiferKeys, ModifierKeys.Control));
739 this._Controller.Scroll(ScrollDirection.Up,this.View.LineCountOnScreen, this.IsPressedModifierKey(modiferKeys, ModifierKeys.Shift),true);
744 this._Controller.Scroll(ScrollDirection.Down,this.View.LineCountOnScreen, this.IsPressedModifierKey(modiferKeys, ModifierKeys.Shift),true);
749 if (this.IsPressedModifierKey(modiferKeys, ModifierKeys.Control))
750 this._Controller.JumpToHead(this.IsPressedModifierKey(modiferKeys, ModifierKeys.Shift));
752 this._Controller.JumpToLineHead(this.Document.CaretPostion.row, this.IsPressedModifierKey(modiferKeys, ModifierKeys.Shift));
757 if (this.IsPressedModifierKey(modiferKeys, ModifierKeys.Control))
758 this._Controller.JumpToEnd(this.IsPressedModifierKey(modiferKeys, ModifierKeys.Shift));
760 this._Controller.JumpToLineEnd(this.Document.CaretPostion.row, this.IsPressedModifierKey(modiferKeys, ModifierKeys.Shift));
765 int oldLength = this.Document.Length;
766 if (this.Selection.Length == 0)
767 this._Controller.DoInputChar('\t');
768 else if(this.IsPressedModifierKey(modiferKeys,ModifierKeys.Shift))
769 this._Controller.DownIndent();
771 this._Controller.UpIndent();
776 if (movedCaret && this.peer != null)
777 this.peer.OnNotifyCaretChanged();
781 bool IsPressedModifierKey(ModifierKeys keys, ModifierKeys pressed)
785 if ((keys & pressed) == pressed)
791 /// ダブルクリックされたときに呼ばれます
793 /// <param name="e">イベントパラメーター</param>
795 /// イベントパラメーターはFooMouseEventArgsにキャスト可能です。
796 /// e.Handledを真にした場合、単語単位の選択が行われなくなります
798 protected override void OnMouseDoubleClick(MouseButtonEventArgs e)
800 var p = this.GetDipFromPoint(e.GetPosition(this));
801 TextPoint tp = this.View.GetTextPointFromPostion(p);
802 if (tp == TextPoint.Null)
804 int index = this.View.LayoutLines.GetIndexFromTextPoint(tp);
806 FooMouseButtonEventArgs newEventArgs = new FooMouseButtonEventArgs(e.MouseDevice,
811 newEventArgs.RoutedEvent = e.RoutedEvent;
812 base.OnMouseDoubleClick(newEventArgs);
814 if (newEventArgs.Handled)
817 if (e.LeftButton == MouseButtonState.Pressed)
820 this._Controller.SelectWord(index);
821 this.textStore.NotifySelectionChanged();
822 if(this.peer != null)
823 this.peer.OnNotifyCaretChanged();
829 /// マウスボタンが押されたときに呼ばれます
831 /// <param name="e">イベントパラメーター</param>
833 /// イベントパラメーターはFooMouseEventArgsにキャスト可能です。
834 /// e.Handledを真にした場合、キャレットの移動処理が行われなくなります
836 protected override void OnMouseDown(MouseButtonEventArgs e)
838 var p = this.GetDipFromPoint(e.GetPosition(this));
839 TextPoint tp = this.View.GetTextPointFromPostion(p);
840 if (tp == TextPoint.Null)
842 int index = this.View.LayoutLines.GetIndexFromTextPoint(tp);
844 FooMouseButtonEventArgs newEventArgs = new FooMouseButtonEventArgs(e.MouseDevice,
849 newEventArgs.RoutedEvent = e.RoutedEvent;
850 base.OnMouseDown(newEventArgs);
852 if (newEventArgs.Handled)
855 if (e.LeftButton == MouseButtonState.Pressed)
857 FoldingItem foldingData = this.View.HitFoldingData(p.X,tp.row);
858 if (foldingData != null)
860 if (foldingData.Expand)
861 this.View.LayoutLines.FoldingCollection.Collapse(foldingData);
863 this.View.LayoutLines.FoldingCollection.Expand(foldingData);
864 this._Controller.JumpCaret(foldingData.Start,false);
868 this._Controller.JumpCaret(tp.row, tp.col, false);
870 if (this.peer != null)
871 this.peer.OnNotifyCaretChanged();
872 this.View.IsFocused = true;
881 /// <param name="e">イベントパラメーター</param>
883 /// イベントパラメーターはFooMouseEventArgsにキャスト可能です。
884 /// e.Handledを真にした場合、選択処理と状況に応じたカーソルの変化が行われなくなります
886 protected override void OnMouseMove(MouseEventArgs e)
888 var p = this.GetDipFromPoint(e.GetPosition(this));
889 TextPoint tp = this.View.GetTextPointFromPostion(p);
890 if (tp == TextPoint.Null)
895 int index = this.View.GetIndexFromLayoutLine(tp);
897 FooMouseEventArgs newEventArgs = new FooMouseEventArgs(e.MouseDevice, e.Timestamp, e.StylusDevice, index);
898 newEventArgs.RoutedEvent = e.RoutedEvent;
899 base.OnMouseMove(newEventArgs);
901 if (newEventArgs.Handled)
904 if (this.View.HitTextArea(p.X,p.Y))
906 if (this._Controller.IsMarker(tp, HilightType.Url))
907 this.Cursor = Cursors.Hand;
909 this.Cursor = Cursors.IBeam;
911 if (e.LeftButton == MouseButtonState.Pressed)
913 this._Controller.MoveCaretAndSelect(tp);
914 if (this.peer != null)
915 this.peer.OnNotifyCaretChanged();
921 this.Cursor = Cursors.Arrow;
925 private Point GetDipFromPoint(Point p)
928 this.Render.GetDpi(out dpi,out dpi);
929 double scale = dpi / 96.0;
930 return p.Scale(1 / scale);
934 protected override void OnMouseWheel(MouseWheelEventArgs e)
936 if(Keyboard.Modifiers == ModifierKeys.None)
939 this._Controller.Scroll(ScrollDirection.Up, SystemParameters.WheelScrollLines, false, false);
941 this._Controller.Scroll(ScrollDirection.Down, SystemParameters.WheelScrollLines, false, false);
943 else if (Keyboard.Modifiers == ModifierKeys.Control)
945 double newFontSize = this.Render.FontSize;
950 if (newFontSize > MaxFontSize)
952 else if (newFontSize < MinFontSize)
954 this.Render.FontSize = newFontSize;
955 SetValue(MagnificationPowerPropertyKey, this.Render.FontSize / this.FontSize);
958 base.OnMouseWheel(e);
961 void SystemEvents_UserPreferenceChanged(object sender, UserPreferenceChangedEventArgs e)
963 if (e.Category == UserPreferenceCategory.Keyboard)
965 int blinkTime = (int)NativeMethods.GetCaretBlinkTime();
966 this.View.CaretBlink = blinkTime >= 0;
967 this.View.CaretBlinkTime = blinkTime * 2;
969 if (e.Category == UserPreferenceCategory.General)
971 this.View.CaretWidthOnInsertMode = SystemParameters.CaretWidth;
975 void Document_Update(object sender, DocumentUpdateEventArgs e)
977 if (this.textStore.IsLocked())
979 if(e.type == UpdateType.Replace)
980 TextStoreHelper.NotifyTextChanged(this.textStore, e.startIndex, e.removeLength, e.insertLength);
981 this.peer.OnNotifyTextChanged();
984 void timer_Tick(object sender, EventArgs e)
986 if (this.image.ActualWidth == 0 || this.image.ActualHeight == 0)
988 if (this.Resize(this.image.ActualWidth, this.image.ActualHeight))
994 bool updateAll = this.View.LayoutLines.HilightAll() || this.View.LayoutLines.GenerateFolding();
999 this.Refresh(this.View.GetCurrentCaretRect());
1002 void horizontalScrollBar_Scroll(object sender, ScrollEventArgs e)
1004 if (this.horizontalScrollBar == null)
1007 if (this.FlowDirection == System.Windows.FlowDirection.LeftToRight)
1008 toX = this.horizontalScrollBar.Value;
1010 toX = -this.horizontalScrollBar.Value;
1011 this._Controller.Scroll(toX, this.View.Src.Row, false, false);
1015 void verticalScrollBar_Scroll(object sender, ScrollEventArgs e)
1017 if (this.verticalScrollBar == null)
1019 int newRow = (int)this.verticalScrollBar.Value;
1020 if (newRow >= this.View.LayoutLines.Count)
1022 this._Controller.Scroll(this.View.Src.X,newRow, false, false);
1026 void View_SrcChanged(object sender, EventArgs e)
1028 if (this.horizontalScrollBar == null || this.verticalScrollBar == null)
1030 EditView view = this.View;
1031 if (view.Src.Row > this.verticalScrollBar.Maximum)
1032 this.verticalScrollBar.Maximum = view.Src.Row + view.LineCountOnScreen + 1;
1033 double absoulteX = Math.Abs(view.Src.X);
1034 if(absoulteX > this.horizontalScrollBar.Maximum)
1035 this.horizontalScrollBar.Maximum = absoulteX + view.PageBound.Width + 1;
1036 if(view.Src.Row != this.verticalScrollBar.Value)
1037 this.verticalScrollBar.Value = view.Src.Row;
1038 if (view.Src.X != this.horizontalScrollBar.Value)
1039 this.horizontalScrollBar.Value = Math.Abs(view.Src.X);
1042 void Controller_SelectionChanged(object sender, EventArgs e)
1044 this.View.CaretBlink = this.View.CaretBlink;
1045 this.CaretMoved(this, null);
1046 //こうしないと選択できなくなってしまう
1047 this.nowCaretMove = true;
1048 SetValue(SelectionProperty, new TextRange(this._Controller.SelectionStart, this._Controller.SelectionLength));
1049 SetValue(CaretPostionProperty, this.Document.CaretPostion);
1050 this.nowCaretMove = false;
1051 if(this.textStore.IsLocked() == false)
1052 this.textStore.NotifySelectionChanged();
1055 void FooTextBox_Loaded(object sender, RoutedEventArgs e)
1057 this.Resize(this.image.ActualWidth, this.image.ActualHeight);
1062 bool Resize(double width, double height)
1064 if (width == 0 || height == 0)
1065 throw new ArgumentOutOfRangeException();
1066 if (this.Render.Resize(width, height))
1068 double scale = this.Render.GetScale();
1069 // RenderはレタリングはDIPだが、widthとheightの値はDPI依存なのでDIPに変換する
1070 this.View.PageBound = new Rectangle(0, 0, width / scale, height / scale);
1072 if (this.horizontalScrollBar != null)
1074 this.horizontalScrollBar.LargeChange = this.View.PageBound.Width;
1075 this.horizontalScrollBar.Maximum = this.View.LongestWidth + this.horizontalScrollBar.LargeChange + 1;
1077 if (this.verticalScrollBar != null)
1079 this.verticalScrollBar.LargeChange = this.View.LineCountOnScreen;
1080 this.verticalScrollBar.Maximum = this.View.LayoutLines.Count + this.verticalScrollBar.LargeChange + 1;
1088 /// プロパティーが変更されたときに呼ばれます
1090 /// <param name="e">イベントパラメーター</param>
1091 protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e)
1093 switch (e.Property.Name)
1096 this._Controller.IndentMode = this.IndentMode;
1099 if(!this.nowCaretMove)
1100 this.Select(this.Selection.Index, this.Selection.Length);
1102 case "CaretPostion":
1103 if (!this.nowCaretMove)
1104 this.JumpCaret(this.CaretPostion.row, this.CaretPostion.col);
1106 case "LineBreakMethod":
1107 this.Document.LineBreak = this.LineBreakMethod;
1109 case "LineBreakCharCount":
1110 this.Document.LineBreakCharCount = this.LineBreakCharCount;
1113 this.View.InsertMode = this.InsertMode;
1116 this.Document.TabStops = this.TabChars;
1118 case "RectSelectMode":
1119 this._Controller.RectSelection = this.RectSelectMode;
1122 this.View.HideCaret = !this.DrawCaret;
1124 case "DrawCaretLine":
1125 this.View.HideLineMarker = !this.DrawCaretLine;
1127 case "DrawLineNumber":
1128 this.Document.DrawLineNumber = this.DrawLineNumber;
1131 this.Render.FontFamily = this.FontFamily;
1134 this.Render.FontSize = this.FontSize;
1137 this.Render.FontStyle = this.FontStyle;
1140 this.Render.FontWeigth = this.FontWeight;
1143 this.Render.Foreground = D2DRender.ToColor4(this.Foreground);
1146 this.Render.Background = D2DRender.ToColor4(this.Background);
1149 this.Render.ControlChar =D2DRender.ToColor4( this.ControlChar);
1152 this.Render.Hilight = D2DRender.ToColor4(this.Hilight);
1155 this.Render.Keyword1 = D2DRender.ToColor4(this.Keyword1);
1158 this.Render.Keyword2 = D2DRender.ToColor4(this.Keyword2);
1161 this.Render.Comment = D2DRender.ToColor4(this.Comment);
1164 this.Render.Literal = D2DRender.ToColor4(this.Literal);
1167 this.Render.Url = D2DRender.ToColor4(this.URL);
1170 this.Render.InsertCaret = D2DRender.ToColor4(this.InsertCaret);
1172 case "OverwriteCaret":
1173 this.Render.OverwriteCaret = D2DRender.ToColor4(this.OverwriteCaret);
1176 this.View.Padding = new Padding((int)this.Padding.Left, (int)this.Padding.Top, (int)this.Padding.Right, (int)this.Padding.Bottom);
1179 this.Render.LineMarker = D2DRender.ToColor4(this.LineMarker);
1182 this.Document.UrlMark = this.MarkURL;
1184 case "ShowFullSpace":
1185 this.Document.ShowFullSpace = this.ShowFullSpace;
1187 case "ShowHalfSpace":
1188 this.Document.ShowHalfSpace = this.ShowHalfSpace;
1191 this.Document.ShowTab = this.ShowTab;
1193 case "ShowLineBreak":
1194 this.Document.ShowLineBreak = this.ShowLineBreak;
1196 case "FlowDirection":
1197 this.Document.RightToLeft = this.FlowDirection == System.Windows.FlowDirection.RightToLeft;
1198 this.horizontalScrollBar.FlowDirection = this.FlowDirection;
1201 this.Document.HideRuler = !this.DrawRuler;
1202 this._Controller.JumpCaret(this.Document.CaretPostion.row, this.Document.CaretPostion.col);
1205 this.Render.UpdateArea = D2DRender.ToColor4(this.UpdateArea);
1208 this.Render.LineNumber = D2DRender.ToColor4(this.LineNumber);
1211 base.OnPropertyChanged(e);
1216 internal Controller Controller
1220 return this._Controller;
1225 /// 文字列の描写に使用されるアンチエイリアシング モードを表します
1227 public TextAntialiasMode TextAntialiasMode
1231 return this.Render.TextAntialiasMode;
1235 this.Render.TextAntialiasMode = value;
1242 public IHilighter Hilighter
1246 return this.View.Hilighter;
1250 this.View.Hilighter = value;
1251 this.View.LayoutLines.ClearLayoutCache();
1256 /// フォールティングを作成するインターフェイスを表す
1258 public IFoldingStrategy FoldingStrategy
1262 return this.View.LayoutLines.FoldingStrategy;
1266 this.View.LayoutLines.FoldingStrategy = value;
1268 this.View.LayoutLines.FoldingCollection.Clear();
1275 public MarkerPatternSet MarkerPatternSet
1279 return this.Document.MarkerPatternSet;
1286 public Document Document
1295 public LineToIndexTable LayoutLineCollection
1297 get { return this.View.LayoutLines; }
1303 public string SelectedText
1307 return this._Controller.SelectedText;
1311 int oldLength = this.Document.Length;
1312 this._Controller.SelectedText = value;
1319 public IndentMode IndentMode
1321 get { return (IndentMode)GetValue(IndentModeProperty); }
1322 set { SetValue(IndentModeProperty, value); }
1326 /// IndentModeの依存プロパティを表す
1328 public static readonly DependencyProperty IndentModeProperty =
1329 DependencyProperty.Register("IndentMode", typeof(IndentMode), typeof(FooTextBox), new PropertyMetadata(IndentMode.Tab));
1335 /// Lengthが0の場合はキャレット位置を表します。
1336 /// 矩形選択モードの場合、選択範囲の文字数ではなく、開始位置から終了位置までの長さとなります
1338 public TextRange Selection
1340 get { return (TextRange)GetValue(SelectionProperty); }
1341 set { SetValue(SelectionProperty, value); }
1345 /// Selectionの依存プロパティを表す
1347 public static readonly DependencyProperty SelectionProperty =
1348 DependencyProperty.Register("Selection", typeof(TextRange), typeof(FooTextBox), new PropertyMetadata(TextRange.Null));
1353 public double MagnificationPower
1355 get { return (double)GetValue(MagnificationPowerPropertyKey.DependencyProperty); }
1361 public static readonly DependencyPropertyKey MagnificationPowerPropertyKey =
1362 DependencyProperty.RegisterReadOnly("MagnificationPower", typeof(double), typeof(FooTextBox), new PropertyMetadata(1.0));
1367 public new FlowDirection FlowDirection
1369 get { return (FlowDirection)GetValue(FlowDirectionProperty); }
1370 set { SetValue(FlowDirectionProperty, value); }
1374 /// レタリング方向を表す。これは依存プロパティです
1376 public new static readonly DependencyProperty FlowDirectionProperty =
1377 DependencyProperty.Register("FlowDirection", typeof(FlowDirection), typeof(FooTextBox), new PropertyMetadata(FlowDirection.LeftToRight));
1380 /// キャレット位置を表す。これは依存プロパティです
1382 public TextPoint CaretPostion
1384 get { return (TextPoint)GetValue(CaretPostionProperty); }
1385 set { SetValue(CaretPostionProperty, value); }
1389 /// CaretPostionの依存プロパティを表す
1391 public static readonly DependencyProperty CaretPostionProperty =
1392 DependencyProperty.Register("CaretPostion", typeof(TextPoint), typeof(FooTextBox), new PropertyMetadata(TextPoint.Null));
1395 /// デフォルトの文字色を表す。これは依存プロパティです
1397 public new System.Windows.Media.Color Foreground
1399 get { return (System.Windows.Media.Color)GetValue(ForegroundProperty); }
1400 set { SetValue(ForegroundProperty, value); }
1404 /// Foregroundの依存プロパティを表す
1406 public new static readonly DependencyProperty ForegroundProperty =
1407 DependencyProperty.Register("Foreground", typeof(System.Windows.Media.Color), typeof(FooTextBox), new FrameworkPropertyMetadata(SystemColors.WindowTextColor));
1410 /// 背景色を表す。これは依存プロパティです
1412 public new System.Windows.Media.Color Background
1414 get { return (System.Windows.Media.Color)GetValue(BackgroundProperty); }
1415 set { SetValue(BackgroundProperty, value); }
1419 /// Backgroundの依存プロパティを表す
1421 public new static readonly DependencyProperty BackgroundProperty =
1422 DependencyProperty.Register("Background", typeof(System.Windows.Media.Color), typeof(FooTextBox), new FrameworkPropertyMetadata(SystemColors.WindowColor));
1425 /// コントロールコードの文字色を表す。これは依存プロパティです
1427 public System.Windows.Media.Color ControlChar
1429 get { return (System.Windows.Media.Color)GetValue(ControlCharProperty); }
1430 set { SetValue(ControlCharProperty, value); }
1434 /// ControlCharの依存プロパティを表す
1436 public static readonly DependencyProperty ControlCharProperty =
1437 DependencyProperty.Register("ControlChar", typeof(System.Windows.Media.Color), typeof(FooTextBox), new FrameworkPropertyMetadata(Colors.Gray));
1440 /// 選択時の背景色を表す。これは依存プロパティです
1442 public System.Windows.Media.Color Hilight
1444 get { return (System.Windows.Media.Color)GetValue(HilightProperty); }
1445 set { SetValue(HilightProperty, value); }
1449 /// Hilightの依存プロパティを表す
1451 public static readonly DependencyProperty HilightProperty =
1452 DependencyProperty.Register("Hilight", typeof(System.Windows.Media.Color), typeof(FooTextBox), new FrameworkPropertyMetadata(Colors.DeepSkyBlue));
1455 /// キーワード1の文字色を表す。これは依存プロパティです
1457 public System.Windows.Media.Color Keyword1
1459 get { return (System.Windows.Media.Color)GetValue(Keyword1Property); }
1460 set { SetValue(Keyword1Property, value); }
1464 /// Keyword1の依存プロパティを表す
1466 public static readonly DependencyProperty Keyword1Property =
1467 DependencyProperty.Register("Keyword1", typeof(System.Windows.Media.Color), typeof(FooTextBox), new FrameworkPropertyMetadata(Colors.Blue));
1470 /// キーワード2の文字色を表す。これは依存プロパティです
1472 public System.Windows.Media.Color Keyword2
1474 get { return (System.Windows.Media.Color)GetValue(Keyword2Property); }
1475 set { SetValue(Keyword2Property, value); }
1479 /// Keyword2の依存プロパティを表す
1481 public static readonly DependencyProperty Keyword2Property =
1482 DependencyProperty.Register("Keyword2", typeof(System.Windows.Media.Color), typeof(FooTextBox), new FrameworkPropertyMetadata(Colors.DarkCyan));
1485 /// コメントの文字色を表す。これは依存プロパティです
1487 public System.Windows.Media.Color Comment
1489 get { return (System.Windows.Media.Color)GetValue(CommentProperty); }
1490 set { SetValue(CommentProperty, value); }
1494 /// Commentの依存プロパティを表す
1496 public static readonly DependencyProperty CommentProperty =
1497 DependencyProperty.Register("Comment", typeof(System.Windows.Media.Color), typeof(FooTextBox), new FrameworkPropertyMetadata(Colors.Green));
1500 /// 文字リテラルの文字色を表す。これは依存プロパティです
1502 public System.Windows.Media.Color Literal
1504 get { return (System.Windows.Media.Color)GetValue(LiteralProperty); }
1505 set { SetValue(LiteralProperty, value); }
1509 /// Literalの依存プロパティを表す
1511 public static readonly DependencyProperty LiteralProperty =
1512 DependencyProperty.Register("Literal", typeof(System.Windows.Media.Color), typeof(FooTextBox), new FrameworkPropertyMetadata(Colors.Brown));
1515 /// URLの文字色を表す。これは依存プロパティです
1517 public System.Windows.Media.Color URL
1519 get { return (System.Windows.Media.Color)GetValue(URLProperty); }
1520 set { SetValue(URLProperty, value); }
1526 public static readonly DependencyProperty URLProperty =
1527 DependencyProperty.Register("URL", typeof(System.Windows.Media.Color), typeof(FooTextBox), new FrameworkPropertyMetadata(Colors.Blue));
1533 public System.Windows.Media.Color LineMarker
1535 get { return (System.Windows.Media.Color)GetValue(LineMarkerProperty); }
1536 set { SetValue(LineMarkerProperty, value); }
1540 /// LineMarkerの依存プロパティを表す
1542 public static readonly DependencyProperty LineMarkerProperty =
1543 DependencyProperty.Register("LineMarker", typeof(System.Windows.Media.Color), typeof(FooTextBox), new FrameworkPropertyMetadata(Colors.Silver));
1546 /// 挿入モード時のキャレットの色を表す
1548 public System.Windows.Media.Color InsertCaret
1550 get { return (System.Windows.Media.Color)GetValue(InsertCaretProperty); }
1551 set { SetValue(InsertCaretProperty, value); }
1555 /// InsertCaretの依存プロパティを表す
1557 public static readonly DependencyProperty InsertCaretProperty =
1558 DependencyProperty.Register("InsertCaret", typeof(System.Windows.Media.Color), typeof(FooTextBox), new FrameworkPropertyMetadata(SystemColors.WindowTextColor));
1563 public System.Windows.Media.Color UpdateArea
1565 get { return (System.Windows.Media.Color)GetValue(UpdateAreaProperty); }
1566 set { SetValue(UpdateAreaProperty, value); }
1570 /// UpdateAreaの依存プロパティを表す
1572 public static readonly DependencyProperty UpdateAreaProperty =
1573 DependencyProperty.Register("UpdateArea", typeof(System.Windows.Media.Color), typeof(FooTextBox), new PropertyMetadata(Colors.MediumSeaGreen));
1576 /// 上書きモード時のキャレット職を表す
1578 public System.Windows.Media.Color OverwriteCaret
1580 get { return (System.Windows.Media.Color)GetValue(OverwriteCaretProperty); }
1581 set { SetValue(OverwriteCaretProperty, value); }
1585 /// OverwriteCaretの依存プロパティを表す
1587 public static readonly DependencyProperty OverwriteCaretProperty =
1588 DependencyProperty.Register("OverwriteCaret", typeof(System.Windows.Media.Color), typeof(FooTextBox), new FrameworkPropertyMetadata(SystemColors.WindowTextColor));
1593 public System.Windows.Media.Color LineNumber
1595 get { return (System.Windows.Media.Color)GetValue(LineNumberProperty); }
1596 set { SetValue(LineNumberProperty, value); }
1600 /// Using a DependencyProperty as the backing store for LineNumber. This enables animation, styling, binding, etc...
1602 public static readonly DependencyProperty LineNumberProperty =
1603 DependencyProperty.Register("LineNumber", typeof(System.Windows.Media.Color), typeof(FooTextBox), new PropertyMetadata(Colors.DimGray));
1606 /// 挿入モードなら真を返し、そうでないなら、偽を返す。これは依存プロパティです
1608 public bool InsertMode
1610 get { return (bool)GetValue(InsertModeProperty); }
1611 set { SetValue(InsertModeProperty, value); }
1615 /// InsertModeの依存プロパティを表す
1617 public static readonly DependencyProperty InsertModeProperty =
1618 DependencyProperty.Register("InsertMode",
1621 new FrameworkPropertyMetadata(true));
1624 /// タブの文字数を表す。これは依存プロパティです
1628 get { return (int)GetValue(TabCharsProperty); }
1629 set { SetValue(TabCharsProperty, value); }
1633 /// TabCharsの依存プロパティを表す
1635 public static readonly DependencyProperty TabCharsProperty =
1636 DependencyProperty.Register("TabChars",
1639 new FrameworkPropertyMetadata(4));
1642 /// 矩形選択モードなら真を返し、そうでないなら偽を返す。これは依存プロパティです
1644 public bool RectSelectMode
1646 get { return (bool)GetValue(RectSelectModeProperty); }
1647 set { SetValue(RectSelectModeProperty, value); }
1651 /// RectSelectModeの依存プロパティを表す
1653 public static readonly DependencyProperty RectSelectModeProperty =
1654 DependencyProperty.Register("RectSelectMode", typeof(bool), typeof(FooTextBox), new FrameworkPropertyMetadata(false));
1660 /// 変更した場合、レイアウトの再構築を行う必要があります
1662 public LineBreakMethod LineBreakMethod
1664 get { return (LineBreakMethod)GetValue(LineBreakProperty); }
1665 set { SetValue(LineBreakProperty, value); }
1669 /// LineBreakMethodの依存プロパティを表す
1671 public static readonly DependencyProperty LineBreakProperty =
1672 DependencyProperty.Register("LineBreakMethod", typeof(LineBreakMethod), typeof(FooTextBox), new PropertyMetadata(LineBreakMethod.None));
1676 /// 折り返しの幅を指定する。LineBreakMethod.CharUnit以外の時は無視されます
1679 /// 変更した場合、レイアウトの再構築を行う必要があります
1681 public int LineBreakCharCount
1683 get { return (int)GetValue(LineBreakCharCountProperty); }
1684 set { SetValue(LineBreakCharCountProperty, value); }
1688 /// LineBreakCharCountの依存プロパティを表す
1690 public static readonly DependencyProperty LineBreakCharCountProperty =
1691 DependencyProperty.Register("LineBreakCharCount", typeof(int), typeof(FooTextBox), new PropertyMetadata(80));
1694 /// キャレットを描くなら真。そうでないなら偽を返す。これは依存プロパティです
1696 public bool DrawCaret
1698 get { return (bool)GetValue(DrawCaretProperty); }
1699 set { SetValue(DrawCaretProperty, value); }
1703 /// DrawCaretの依存プロパティを表す
1705 public static readonly DependencyProperty DrawCaretProperty =
1706 DependencyProperty.Register("DrawCaret", typeof(bool), typeof(FooTextBox), new FrameworkPropertyMetadata(true));
1710 /// キャレットラインを描くなら真。そうでないなら偽を返す。これは依存プロパティです
1712 public bool DrawCaretLine
1714 get { return (bool)GetValue(DrawCaretLineProperty); }
1715 set { SetValue(DrawCaretLineProperty, value); }
1719 /// DrawCaretLineの依存プロパティを表す
1721 public static readonly DependencyProperty DrawCaretLineProperty =
1722 DependencyProperty.Register("DrawCaretLine", typeof(bool), typeof(FooTextBox), new FrameworkPropertyMetadata(false));
1725 /// 行番号を描くなら真。そうでなければ偽。これは依存プロパティです
1727 public bool DrawLineNumber
1729 get { return (bool)GetValue(DrawLineNumberProperty); }
1730 set { SetValue(DrawLineNumberProperty, value); }
1734 /// ルーラーを描くなら真。そうでなければ偽。これは依存プロパティです
1736 public bool DrawRuler
1738 get { return (bool)GetValue(DrawRulerProperty); }
1739 set { SetValue(DrawRulerProperty, value); }
1743 /// DrawRulerの依存プロパティを表す
1745 public static readonly DependencyProperty DrawRulerProperty =
1746 DependencyProperty.Register("DrawRuler", typeof(bool), typeof(FooTextBox), new PropertyMetadata(false));
1750 /// DrawLineNumberの依存プロパティを表す
1752 public static readonly DependencyProperty DrawLineNumberProperty =
1753 DependencyProperty.Register("DrawLineNumber", typeof(bool), typeof(FooTextBox), new FrameworkPropertyMetadata(false));
1756 /// URLに下線を引くなら真。そうでないなら偽を表す。これは依存プロパティです
1760 get { return (bool)GetValue(MarkURLProperty); }
1761 set { SetValue(MarkURLProperty, value); }
1765 /// MarkURLの依存プロパティを表す
1767 public static readonly DependencyProperty MarkURLProperty =
1768 DependencyProperty.Register("MarkURL", typeof(bool), typeof(FooTextBox), new FrameworkPropertyMetadata(false));
1771 /// 全角スペースを表示するなら真。そうでないなら偽
1773 public bool ShowFullSpace
1775 get { return (bool)GetValue(ShowFullSpaceProperty); }
1776 set { SetValue(ShowFullSpaceProperty, value); }
1780 /// ShowFullSpaceの依存プロパティを表す
1782 public static readonly DependencyProperty ShowFullSpaceProperty =
1783 DependencyProperty.Register("ShowFullSpace", typeof(bool), typeof(FooTextBox), new UIPropertyMetadata(false));
1786 /// 半角スペースを表示するなら真。そうでないなら偽
1788 public bool ShowHalfSpace
1790 get { return (bool)GetValue(ShowHalfSpaceProperty); }
1791 set { SetValue(ShowHalfSpaceProperty, value); }
1795 /// ShowHalfSpaceの依存プロパティを表す
1797 public static readonly DependencyProperty ShowHalfSpaceProperty =
1798 DependencyProperty.Register("ShowHalfSpace", typeof(bool), typeof(FooTextBox), new UIPropertyMetadata(false));
1801 /// タブを表示するなら真。そうでないなら偽
1805 get { return (bool)GetValue(ShowTabProperty); }
1806 set { SetValue(ShowTabProperty, value); }
1810 /// ShowTabの依存プロパティを表す
1812 public static readonly DependencyProperty ShowTabProperty =
1813 DependencyProperty.Register("ShowTab", typeof(bool), typeof(FooTextBox), new UIPropertyMetadata(false));
1816 /// 改行マークを表示するなら真。そうでないなら偽
1818 public bool ShowLineBreak
1820 get { return (bool)GetValue(ShowLineBreakProperty); }
1821 set { SetValue(ShowLineBreakProperty, value); }
1825 /// ShowLineBreakの依存プロパティを表す
1827 public static readonly DependencyProperty ShowLineBreakProperty =
1828 DependencyProperty.Register("ShowLineBreak", typeof(bool), typeof(FooTextBox), new PropertyMetadata(false));
1833 /// マウスボタン関連のイベントクラス
1835 public sealed class FooMouseButtonEventArgs : MouseButtonEventArgs
1838 /// イベントが発生したドキュメントのインデックス
1849 /// <param name="mouse">マウスデバイス</param>
1850 /// <param name="timestamp">タイムスタンプ</param>
1851 /// <param name="button">ボタン</param>
1852 /// <param name="stylusDevice">スタイラスデバイス</param>
1853 /// <param name="index">インデックス</param>
1854 public FooMouseButtonEventArgs(MouseDevice mouse, int timestamp, MouseButton button, StylusDevice stylusDevice, int index)
1855 : base(mouse, timestamp, button, stylusDevice)
1863 public sealed class FooMouseEventArgs : MouseEventArgs
1866 /// イベントが発生したドキュメントのインデックス
1877 /// <param name="mouse">マウスデバイス</param>
1878 /// <param name="timestamp">タイムスタンプ</param>
1879 /// <param name="stylusDevice">スタイラスデバイス</param>
1880 /// <param name="index">インデックス</param>
1881 public FooMouseEventArgs(MouseDevice mouse,
1883 StylusDevice stylusDevice,
1885 : base(mouse, timestamp, stylusDevice)