2 * Copyright (C) 2013 FooProject
\r
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
\r
4 * the Free Software Foundation; either version 3 of the License, or (at your option) any later version.
\r
6 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
7 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
\r
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/>.
\r
13 using System.Threading.Tasks;
\r
14 using System.Runtime.InteropServices;
\r
15 using System.Windows;
\r
16 using System.Windows.Input;
\r
17 using System.Windows.Media;
\r
18 using System.Windows.Controls;
\r
19 using System.Windows.Controls.Primitives;
\r
20 using System.Windows.Documents;
\r
21 using System.Windows.Interop;
\r
22 using System.Windows.Threading;
\r
23 using DotNetTextStore;
\r
24 using DotNetTextStore.UnmanagedAPI.TSF;
\r
25 using DotNetTextStore.UnmanagedAPI.WinDef;
\r
26 using Microsoft.Win32;
\r
28 namespace FooEditEngine.WPF
\r
31 /// オートインデントを行うためのデリゲートを表す
\r
33 /// <param name="sender">イベント発生元のオブジェクト</param>
\r
34 /// <param name="e">イベントデーター</param>
\r
35 public delegate void AutoIndentHookerHandler(object sender,EventArgs e);
\r
38 /// WPFでのFooTextBoxの実装
\r
40 public sealed class FooTextBox : Control, IDisposable
\r
42 const double MaxFontSize = 72.0f;
\r
43 const double MinFontSize = 1;
\r
46 Controller _Controller;
\r
49 ScrollBar verticalScrollBar, horizontalScrollBar;
\r
50 TextStore textStore;
\r
51 DispatcherTimer timer;
\r
52 bool disposed = false;
\r
53 FooTextBoxAutomationPeer peer;
\r
54 bool nowCaretMove = false;
\r
58 DefaultStyleKeyProperty.OverrideMetadata(typeof(FooTextBox), new FrameworkPropertyMetadata(typeof(FooTextBox)));
\r
59 KeyboardNavigation.IsTabStopProperty.OverrideMetadata(typeof(FooTextBox), new FrameworkPropertyMetadata(true));
\r
60 KeyboardNavigation.TabNavigationProperty.OverrideMetadata(typeof(FooTextBox), new FrameworkPropertyMetadata(KeyboardNavigationMode.None));
\r
68 this.image = new Image();
\r
69 this.image.Stretch = Stretch.Fill;
\r
70 this.image.HorizontalAlignment = HorizontalAlignment.Left;
\r
71 this.image.VerticalAlignment = VerticalAlignment.Top;
\r
73 this.textStore = new TextStore();
\r
74 this.textStore.IsLoading += textStore_IsLoading;
\r
75 this.textStore.IsReadOnly += textStore_IsReadOnly;
\r
76 this.textStore.GetDpi += textStore_GetDpi;
\r
77 this.textStore.GetStringLength += () => this.Document.Length;
\r
78 this.textStore.GetString += _textStore_GetString;
\r
79 this.textStore.GetSelectionIndex += _textStore_GetSelectionIndex;
\r
80 this.textStore.SetSelectionIndex += _textStore_SetSelectionIndex;
\r
81 this.textStore.InsertAtSelection += _textStore_InsertAtSelection;
\r
82 this.textStore.GetHWnd += _textStore_GetHWnd;
\r
83 this.textStore.GetScreenExtent += _textStore_GetScreenExtent;
\r
84 this.textStore.GetStringExtent += _textStore_GetStringExtent;
\r
85 this.textStore.CompositionStarted += textStore_CompositionStarted;
\r
86 this.textStore.CompositionUpdated += textStore_CompositionUpdated;
\r
87 this.textStore.CompositionEnded += textStore_CompositionEnded;
\r
89 this.Render = new D2DRender(this, 200, 200,this.image);
\r
90 this.Render.ShowFullSpace = this.ShowFullSpace;
\r
91 this.Render.ShowHalfSpace = this.ShowHalfSpace;
\r
92 this.Render.ShowTab = this.ShowTab;
\r
94 this.Document = new Document();
\r
95 this.Document.LayoutLines.Render = this.Render;
\r
97 this.View = new EditView(this.Document, this.Render, new Padding(5, 5, 5, 5));
\r
98 this.View.SrcChanged += View_SrcChanged;
\r
99 this.View.InsertMode = this.InsertMode;
\r
100 this.View.DrawLineNumber = this.DrawLineNumber;
\r
101 this.View.HideCaret = !this.DrawCaret;
\r
102 this.View.HideLineMarker = !this.DrawCaretLine;
\r
103 this.View.HideRuler = !this.DrawRuler;
\r
104 this.View.UrlMark = this.MarkURL;
\r
105 this.View.TabStops = this.TabChars;
\r
107 this._Controller = new Controller(this.Document, this.View);
\r
108 this._Controller.SelectionChanged += new EventHandler(Controller_SelectionChanged);
\r
110 //Viewを作成した後に追加しないと例外が発生する
\r
111 this.Document.Update += new DocumentUpdateEventHandler(Document_Update);
\r
113 this.CommandBindings.Add(new CommandBinding(ApplicationCommands.Copy, CopyCommand, CanExecute));
\r
114 this.CommandBindings.Add(new CommandBinding(ApplicationCommands.Cut, CutCommand, CanExecute));
\r
115 this.CommandBindings.Add(new CommandBinding(ApplicationCommands.Paste, PasteCommand, CanExecute));
\r
116 this.CommandBindings.Add(new CommandBinding(ApplicationCommands.Delete, DeleteCommand, CanExecute));
\r
117 this.CommandBindings.Add(new CommandBinding(ApplicationCommands.SelectAll, SelectAllCommand, CanExecute));
\r
118 this.CommandBindings.Add(new CommandBinding(ApplicationCommands.Undo, UndoCommand, CanExecute));
\r
119 this.CommandBindings.Add(new CommandBinding(ApplicationCommands.Redo, RedoCommand, CanExecute));
\r
120 this.CommandBindings.Add(new CommandBinding(EditingCommands.ToggleInsert, ToggleInsertCommand, CanExecute));
\r
121 this.CommandBindings.Add(new CommandBinding(FooTextBoxCommands.ToggleRectSelectMode, ToggleRectSelectCommand, CanExecute));
\r
122 this.CommandBindings.Add(new CommandBinding(FooTextBoxCommands.ToggleFlowDirection, ToggleFlowDirectionCommand, CanExecute));
\r
123 this.CommandBindings.Add(new CommandBinding(FooTextBoxCommands.ToggleCodePoint, ToggleCodePointCommand, CanExecute));
\r
125 this.InputBindings.Add(new InputBinding(ApplicationCommands.Copy, new KeyGesture(Key.C, ModifierKeys.Control)));
\r
126 this.InputBindings.Add(new InputBinding(ApplicationCommands.Cut, new KeyGesture(Key.X, ModifierKeys.Control)));
\r
127 this.InputBindings.Add(new InputBinding(ApplicationCommands.Paste, new KeyGesture(Key.V, ModifierKeys.Control)));
\r
128 this.InputBindings.Add(new InputBinding(ApplicationCommands.Delete, new KeyGesture(Key.Delete, ModifierKeys.None)));
\r
129 this.InputBindings.Add(new InputBinding(ApplicationCommands.SelectAll, new KeyGesture(Key.A, ModifierKeys.Control)));
\r
130 this.InputBindings.Add(new InputBinding(ApplicationCommands.Undo, new KeyGesture(Key.Z, ModifierKeys.Control)));
\r
131 this.InputBindings.Add(new InputBinding(ApplicationCommands.Redo, new KeyGesture(Key.Y, ModifierKeys.Control)));
\r
132 this.InputBindings.Add(new InputBinding(EditingCommands.ToggleInsert, new KeyGesture(Key.Insert, ModifierKeys.None)));
\r
133 this.InputBindings.Add(new InputBinding(FooTextBoxCommands.ToggleCodePoint, new KeyGesture(Key.X, ModifierKeys.Alt)));
\r
135 this.timer = new DispatcherTimer();
\r
136 this.timer.Interval = new TimeSpan(0, 0, 0, 0, 100);
\r
137 this.timer.Tick += new EventHandler(timer_Tick);
\r
139 this.Loaded += new RoutedEventHandler(FooTextBox_Loaded);
\r
141 this.AutoIndentHooker = (s,e)=>{};
\r
143 SystemEvents.UserPreferenceChanged += new UserPreferenceChangedEventHandler(SystemEvents_UserPreferenceChanged);
\r
145 this.SystemEvents_UserPreferenceChanged(null, new UserPreferenceChangedEventArgs(UserPreferenceCategory.Keyboard));
\r
147 this.CaretMoved += (s, e) => { };
\r
155 //Dispose(false)を呼び出すと落ちる
\r
156 this.Dispose(false);
\r
160 /// オートインデントを行うためのイベント
\r
162 public AutoIndentHookerHandler AutoIndentHooker;
\r
167 public override void OnApplyTemplate()
\r
169 base.OnApplyTemplate();
\r
171 Grid grid = this.GetTemplateChild("PART_Grid") as Grid;
\r
174 Grid.SetRow(this.image, 0);
\r
175 Grid.SetColumn(this.image, 0);
\r
176 grid.Children.Add(this.image);
\r
179 this.horizontalScrollBar = this.GetTemplateChild("PART_HorizontalScrollBar") as ScrollBar;
\r
180 if (this.horizontalScrollBar != null)
\r
182 this.horizontalScrollBar.SmallChange = 10;
\r
183 this.horizontalScrollBar.LargeChange = 100;
\r
184 this.horizontalScrollBar.Maximum = this.horizontalScrollBar.LargeChange + 1;
\r
185 this.horizontalScrollBar.Scroll += new ScrollEventHandler(horizontalScrollBar_Scroll);
\r
187 this.verticalScrollBar = this.GetTemplateChild("PART_VerticalScrollBar") as ScrollBar;
\r
188 if (this.verticalScrollBar != null)
\r
190 this.verticalScrollBar.SmallChange = 1;
\r
191 this.verticalScrollBar.LargeChange = 10;
\r
192 this.verticalScrollBar.Maximum = this.View.LayoutLines.Count;
\r
193 this.verticalScrollBar.Scroll += new ScrollEventHandler(verticalScrollBar_Scroll);
\r
200 /// <param name="start">開始インデックス</param>
\r
201 /// <param name="length">長さ</param>
\r
202 public void Select(int start, int length)
\r
204 this._Controller.Select(start, length);
\r
205 this.textStore.NotifySelectionChanged();
\r
209 /// キャレットを指定した行に移動させます
\r
211 /// <param name="index">インデックス</param>
\r
212 /// <remarks>このメソッドを呼び出すと選択状態は解除されます</remarks>
\r
213 public void JumpCaret(int index)
\r
215 this._Controller.JumpCaret(index);
\r
218 /// キャレットを指定した行と桁に移動させます
\r
220 /// <param name="row">行番号</param>
\r
221 /// <param name="col">桁</param>
\r
222 /// <remarks>このメソッドを呼び出すと選択状態は解除されます</remarks>
\r
223 public void JumpCaret(int row, int col)
\r
225 this._Controller.JumpCaret(row, col);
\r
229 /// 選択中のテキストをクリップボードにコピーします
\r
233 string text = this._Controller.SelectedText;
\r
234 if (text != null && text != string.Empty)
\r
235 Clipboard.SetText(text);
\r
239 /// 選択中のテキストをクリップボードに切り取ります
\r
243 string text = this._Controller.SelectedText;
\r
244 if (text != null && text != string.Empty)
\r
246 Clipboard.SetText(text);
\r
247 this._Controller.SelectedText = "";
\r
252 /// 選択中のテキストを貼り付けます
\r
254 public void Paste()
\r
256 if (Clipboard.ContainsText() == false)
\r
258 string text = Clipboard.GetText();
\r
259 this._Controller.SelectedText = text;
\r
265 public void DeSelectAll()
\r
267 this._Controller.DeSelectAll();
\r
268 this.textStore.NotifySelectionChanged();
\r
274 /// <param name="tp">テキストポイント</param>
\r
275 /// <returns>座標</returns>
\r
276 /// <remarks>テキストポイントがクライアント領域の原点より外にある場合、返される値は原点に丸められます</remarks>
\r
277 public System.Windows.Point GetPostionFromTextPoint(TextPoint tp)
\r
279 if (this.Document.FireUpdateEvent == false)
\r
280 throw new InvalidOperationException("");
\r
281 return this.View.GetPostionFromTextPoint(tp);
\r
285 /// 対応するテキストポイントを返します
\r
287 /// <param name="p">クライアント領域の原点を左上とする座標</param>
\r
288 /// <returns>テキストポイント</returns>
\r
289 public TextPoint GetTextPointFromPostion(System.Windows.Point p)
\r
291 if (this.Document.FireUpdateEvent == false)
\r
292 throw new InvalidOperationException("");
\r
293 return this.View.GetTextPointFromPostion(p);
\r
299 /// <param name="row">レイアウト行</param>
\r
300 /// <returns>行の高さ</returns>
\r
301 public double GetLineHeight(int row)
\r
303 if (this.Document.FireUpdateEvent == false)
\r
304 throw new InvalidOperationException("");
\r
305 return this.View.LayoutLines.GetLayout(row).Height;;
\r
309 /// インデックスに対応する座標を得ます
\r
311 /// <param name="index">インデックス</param>
\r
312 /// <returns>座標を返す</returns>
\r
313 public System.Windows.Point GetPostionFromIndex(int index)
\r
315 if (this.Document.FireUpdateEvent == false)
\r
316 throw new InvalidOperationException("");
\r
317 TextPoint tp = this.View.GetLayoutLineFromIndex(index);
\r
318 return this.View.GetPostionFromTextPoint(tp);
\r
322 /// 座標からインデックスに変換します
\r
324 /// <param name="p">座標</param>
\r
325 /// <returns>インデックスを返す</returns>
\r
326 public int GetIndexFromPostion(System.Windows.Point p)
\r
328 if (this.Document.FireUpdateEvent == false)
\r
329 throw new InvalidOperationException("");
\r
330 TextPoint tp = this.View.GetTextPointFromPostion(p);
\r
331 return this.View.GetIndexFromLayoutLine(tp);
\r
337 public void Refresh()
\r
339 this.Refresh(this.View.PageBound);
\r
343 /// レイアウト行をすべて破棄し、再度レイアウトを行う
\r
345 public void PerfomLayouts()
\r
347 this.View.PerfomLayouts();
\r
353 /// <param name="row">行</param>
\r
354 /// <param name="alignTop">指定行を画面上に置くなら真。そうでないなら偽</param>
\r
355 public void ScrollIntoView(int row, bool alignTop)
\r
357 this.View.ScrollIntoView(row, alignTop);
\r
361 /// ストリームからドキュメントを構築する
\r
363 /// <param name="tr">TextReader</param>
\r
364 /// <param name="token">キャンセル用トークン</param>
\r
365 /// <returns>Taskオブジェクト</returns>
\r
366 public async Task LoadAsync(System.IO.TextReader tr, System.Threading.CancellationTokenSource token)
\r
368 WinFileReader fs = new WinFileReader(tr);
\r
369 await this.LoadAsyncImpl(fs, token);
\r
373 /// ファイルからドキュメントを構築する
\r
375 /// <param name="filepath">ファイルパス</param>
\r
376 /// <param name="enc">エンコード</param>
\r
377 /// <param name="token">キャンセル用トークン</param>
\r
378 /// <returns>Taskオブジェクト</returns>
\r
379 public async Task LoadFileAsync(string filepath, Encoding enc,System.Threading.CancellationTokenSource token)
\r
381 WinFileReader fs = new WinFileReader(filepath, enc);
\r
382 await this.LoadAsyncImpl(fs, token);
\r
386 async Task LoadAsyncImpl(WinFileReader fs,System.Threading.CancellationTokenSource token)
\r
388 this.IsEnabled = false;
\r
389 this.View.LayoutLines.IsFrozneDirtyFlag = true;
\r
390 await this.Document.LoadAsync(fs, token);
\r
391 this.View.LayoutLines.IsFrozneDirtyFlag = false;
\r
392 TextStoreHelper.NotifyTextChanged(this.textStore, 0, 0, this.Document.Length);
\r
393 if (this.verticalScrollBar != null)
\r
394 this.verticalScrollBar.Maximum = this.View.LayoutLines.Count;
\r
395 this.View.CalculateLineCountOnScreen();
\r
396 this.IsEnabled = true;
\r
400 /// ドキュメントの内容をファイルに保存する
\r
402 /// <param name="filepath">ファイルパス</param>
\r
403 /// <param name="newLine">改行コード</param>
\r
404 /// <param name="enc">エンコード</param>
\r
405 /// <returns>Taskオブジェクト</returns>
\r
406 public async Task SaveFile(string filepath, Encoding enc,string newLine, System.Threading.CancellationTokenSource token)
\r
408 WinFileWriter fs = new WinFileWriter(filepath, enc);
\r
409 fs.NewLine = newLine;
\r
410 await this.Document.SaveAsync(fs, token);
\r
415 /// アンマネージドリソースを開放する
\r
417 public void Dispose()
\r
421 this.Dispose(true);
\r
422 GC.SuppressFinalize(this);
\r
423 this.disposed = true;
\r
429 /// <param name="disposing">真ならマネージドリソースも開放し、そうでないならアンマネージドリソースのみを開放する</param>
\r
430 void Dispose(bool disposing)
\r
434 this.textStore.Dispose();
\r
436 this.View.Dispose();
\r
437 this.Render.Dispose();
\r
439 SystemEvents.UserPreferenceChanged -= new UserPreferenceChangedEventHandler(SystemEvents_UserPreferenceChanged);
\r
442 void Refresh(Rectangle updateRect)
\r
444 if (this.disposed || this.Visibility == Visibility.Collapsed)
\r
449 this.Render.BegineDraw();
\r
450 if (this.IsEnabled)
\r
451 this.View.Draw(updateRect);
\r
453 this.Render.FillBackground(updateRect);
\r
454 this.Render.EndDraw();
\r
456 this.timer.Start();
\r
460 void CanExecute(object sender, CanExecuteRoutedEventArgs e)
\r
462 e.CanExecute = this.IsEnabled;
\r
465 void ToggleCodePointCommand(object sender, RoutedEventArgs e)
\r
467 if (!this._Controller.ConvertToChar())
\r
468 this._Controller.ConvertToCodePoint();
\r
472 void CopyCommand(object sender, RoutedEventArgs e)
\r
477 void CutCommand(object sender, RoutedEventArgs e)
\r
483 void PasteCommand(object sender, RoutedEventArgs e)
\r
489 void DeleteCommand(object sender, RoutedEventArgs e)
\r
491 int oldLength = this.Document.Length;
\r
492 this._Controller.DoDeleteAction();
\r
496 void SelectAllCommand(object sender, RoutedEventArgs e)
\r
498 this.Select(0, this.Document.Length);
\r
502 void UndoCommand(object sender, RoutedEventArgs e)
\r
504 int oldLength = this.Document.Length;
\r
505 this.Document.UndoManager.undo();
\r
509 void RedoCommand(object sender, RoutedEventArgs e)
\r
511 int oldLength = this.Document.Length;
\r
512 this.Document.UndoManager.redo();
\r
516 void ToggleInsertCommand(object sender, RoutedEventArgs e)
\r
518 if (this.InsertMode)
\r
519 this.InsertMode = false;
\r
521 this.InsertMode = true;
\r
525 void ToggleRectSelectCommand(object sender, RoutedEventArgs e)
\r
527 if (this.RectSelectMode)
\r
528 this.RectSelectMode = false;
\r
530 this.RectSelectMode = true;
\r
533 void ToggleFlowDirectionCommand(object sender, RoutedEventArgs e)
\r
535 if (this.FlowDirection == System.Windows.FlowDirection.LeftToRight)
\r
536 this.FlowDirection = System.Windows.FlowDirection.RightToLeft;
\r
538 this.FlowDirection = System.Windows.FlowDirection.LeftToRight;
\r
543 internal TextStore TextStore
\r
545 get { return this.textStore; }
\r
548 double textStore_GetDpi()
\r
551 this.Render.GetDpi(out dpi, out dpi);
\r
555 bool textStore_IsReadOnly()
\r
560 bool textStore_IsLoading()
\r
565 void textStore_CompositionEnded()
\r
567 TextStoreHelper.EndCompostion(this.Document);
\r
571 void textStore_CompositionUpdated(int start, int end)
\r
573 if (TextStoreHelper.ScrollToCompstionUpdated(this.textStore, this.View, start, end))
\r
576 bool textStore_CompositionStarted()
\r
578 bool result = TextStoreHelper.StartCompstion(this.Document);
\r
580 System.Media.SystemSounds.Beep.Play();
\r
584 string _textStore_GetString(int start, int length)
\r
586 return this.Document.ToString(start, length);
\r
589 IntPtr _textStore_GetHWnd()
\r
591 var hwndSource = HwndSource.FromVisual(this) as HwndSource;
\r
592 if (hwndSource != null)
\r
593 return hwndSource.Handle;
\r
595 return IntPtr.Zero;
\r
598 void _textStore_GetStringExtent(
\r
601 out POINT o_topLeft,
\r
602 out POINT o_bottomRight
\r
605 Point startPos, endPos;
\r
606 TextStoreHelper.GetStringExtent(this.Document, this.View, i_startIndex, i_endIndex, out startPos, out endPos);
\r
608 startPos = PointToScreen(this.TranslatePoint(startPos, this));
\r
609 endPos = PointToScreen(this.TranslatePoint(endPos, this));
\r
611 o_topLeft = new POINT((int)startPos.X, (int)startPos.Y);
\r
612 o_bottomRight = new POINT((int)endPos.X, (int)endPos.Y);
\r
615 void _textStore_GetScreenExtent(out POINT o_topLeft, out POINT o_bottomRight)
\r
617 var pointTopLeft = new Point(0, 0);
\r
618 var pointBottomRight = new Point(this.RenderSize.Width, this.RenderSize.Height);
\r
620 pointTopLeft = PointToScreen(pointTopLeft);
\r
621 pointBottomRight = PointToScreen(pointBottomRight);
\r
623 o_topLeft = new POINT((int)pointTopLeft.X, (int)pointTopLeft.Y);
\r
624 o_bottomRight = new POINT((int)pointBottomRight.X, (int)pointBottomRight.Y);
\r
627 void _textStore_GetSelectionIndex(out int o_startIndex, out int o_endIndex)
\r
629 TextStoreHelper.GetSelection(this._Controller, this.View.Selections, out o_startIndex, out o_endIndex);
\r
632 void _textStore_SetSelectionIndex(int i_startIndex, int i_endIndex)
\r
634 TextStoreHelper.SetSelectionIndex(this._Controller, this.View, i_startIndex, i_endIndex);
\r
638 void _textStore_InsertAtSelection(string i_value, ref int o_startIndex, ref int o_endIndex)
\r
640 TextStoreHelper.InsertTextAtSelection(this._Controller, i_value);
\r
645 /// キーボードフォーカスが取得されたときに呼ばれます
\r
647 /// <param name="e">イベントデーター</param>
\r
648 protected override void OnGotKeyboardFocus(KeyboardFocusChangedEventArgs e)
\r
650 base.OnGotKeyboardFocus(e);
\r
651 this.textStore.SetFocus();
\r
652 this.View.IsFocused = true;
\r
657 /// キーボードフォーカスが失われたときに呼ばれます
\r
659 /// <param name="e">イベントデーター</param>
\r
660 protected override void OnLostKeyboardFocus(KeyboardFocusChangedEventArgs e)
\r
662 base.OnLostKeyboardFocus(e);
\r
663 this.View.IsFocused = false;
\r
669 /// キャレットが移動したときに通知されるイベント
\r
671 public event EventHandler CaretMoved;
\r
674 protected override System.Windows.Automation.Peers.AutomationPeer OnCreateAutomationPeer()
\r
676 this.peer = new FooTextBoxAutomationPeer(this);
\r
682 protected override void OnTextInput(TextCompositionEventArgs e)
\r
684 if (e.Text == "\r")
\r
686 this._Controller.DoEnterAction();
\r
687 this.AutoIndentHooker(this, null);
\r
689 else if (e.Text == "\b")
\r
691 this._Controller.DoBackSpaceAction();
\r
695 if(this.IsInputString(e.Text))
\r
696 this._Controller.DoInputString(e.Text);
\r
699 base.OnTextInput(e);
\r
703 bool IsInputString(string s)
\r
705 foreach (char charCode in s)
\r
707 if ((0x20 <= charCode && charCode <= 0x7e)
\r
708 || 0x7f < charCode)
\r
715 protected override void OnKeyDown(KeyEventArgs e)
\r
717 if (this.textStore.IsLocked())
\r
720 ModifierKeys modiferKeys = e.KeyboardDevice.Modifiers;
\r
721 bool movedCaret = false;
\r
725 this._Controller.MoveCaretVertical(-1, this.IsPressedModifierKey(modiferKeys, ModifierKeys.Shift));
\r
731 this._Controller.MoveCaretVertical(+1, this.IsPressedModifierKey(modiferKeys, ModifierKeys.Shift));
\r
737 this._Controller.MoveCaretHorizontical(-1, this.IsPressedModifierKey(modiferKeys, ModifierKeys.Shift), this.IsPressedModifierKey(modiferKeys, ModifierKeys.Control));
\r
743 this._Controller.MoveCaretHorizontical(1, this.IsPressedModifierKey(modiferKeys, ModifierKeys.Shift), this.IsPressedModifierKey(modiferKeys, ModifierKeys.Control));
\r
749 this._Controller.Scroll(ScrollDirection.Up,this.View.LineCountOnScreen, this.IsPressedModifierKey(modiferKeys, ModifierKeys.Shift),true);
\r
754 this._Controller.Scroll(ScrollDirection.Down,this.View.LineCountOnScreen, this.IsPressedModifierKey(modiferKeys, ModifierKeys.Shift),true);
\r
759 if (this.IsPressedModifierKey(modiferKeys, ModifierKeys.Control))
\r
760 this._Controller.JumpToHead(this.IsPressedModifierKey(modiferKeys, ModifierKeys.Shift));
\r
762 this._Controller.JumpToLineHead(this.View.CaretPostion.row, this.IsPressedModifierKey(modiferKeys, ModifierKeys.Shift));
\r
767 if (this.IsPressedModifierKey(modiferKeys, ModifierKeys.Control))
\r
768 this._Controller.JumpToEnd(this.IsPressedModifierKey(modiferKeys, ModifierKeys.Shift));
\r
770 this._Controller.JumpToLineEnd(this.View.CaretPostion.row, this.IsPressedModifierKey(modiferKeys, ModifierKeys.Shift));
\r
775 int oldLength = this.Document.Length;
\r
776 if (this.Selection.Length == 0)
\r
777 this._Controller.DoInputChar('\t');
\r
778 else if(this.IsPressedModifierKey(modiferKeys,ModifierKeys.Shift))
\r
779 this._Controller.DownIndent();
\r
781 this._Controller.UpIndent();
\r
786 if (movedCaret && this.peer != null)
\r
787 this.peer.OnNotifyCaretChanged();
\r
791 bool IsPressedModifierKey(ModifierKeys keys, ModifierKeys pressed)
\r
793 if (keys == pressed)
\r
795 if ((keys & pressed) == pressed)
\r
801 /// ダブルクリックされたときに呼ばれます
\r
803 /// <param name="e">イベントパラメーター</param>
\r
805 /// イベントパラメーターはFooMouseEventArgsにキャスト可能です。
\r
806 /// e.Handledを真にした場合、単語単位の選択が行われなくなります
\r
808 protected override void OnMouseDoubleClick(MouseButtonEventArgs e)
\r
810 System.Windows.Point p = e.GetPosition(this);
\r
811 TextPoint tp = this.View.GetTextPointFromPostion(p);
\r
812 if (tp == TextPoint.Null)
\r
814 int index = this.View.LayoutLines.GetIndexFromTextPoint(tp);
\r
816 FooMouseButtonEventArgs newEventArgs = new FooMouseButtonEventArgs(e.MouseDevice,
\r
821 newEventArgs.RoutedEvent = e.RoutedEvent;
\r
822 base.OnMouseDoubleClick(newEventArgs);
\r
824 if (newEventArgs.Handled)
\r
827 if (e.LeftButton == MouseButtonState.Pressed)
\r
830 this._Controller.SelectWord(index);
\r
831 this.textStore.NotifySelectionChanged();
\r
832 if(this.peer != null)
\r
833 this.peer.OnNotifyCaretChanged();
\r
839 /// マウスボタンが押されたときに呼ばれます
\r
841 /// <param name="e">イベントパラメーター</param>
\r
843 /// イベントパラメーターはFooMouseEventArgsにキャスト可能です。
\r
844 /// e.Handledを真にした場合、キャレットの移動処理が行われなくなります
\r
846 protected override void OnMouseDown(MouseButtonEventArgs e)
\r
848 System.Windows.Point p = e.GetPosition(this);
\r
849 TextPoint tp = this.View.GetTextPointFromPostion(p);
\r
850 if (tp == TextPoint.Null)
\r
852 int index = this.View.LayoutLines.GetIndexFromTextPoint(tp);
\r
854 FooMouseButtonEventArgs newEventArgs = new FooMouseButtonEventArgs(e.MouseDevice,
\r
859 newEventArgs.RoutedEvent = e.RoutedEvent;
\r
860 base.OnMouseDown(newEventArgs);
\r
862 if (newEventArgs.Handled)
\r
865 if (e.LeftButton == MouseButtonState.Pressed)
\r
867 FoldingItem foldingData = this.View.HitFoldingData(p.X,tp.row);
\r
868 if (foldingData != null)
\r
870 if (foldingData.Expand)
\r
871 this.View.LayoutLines.FoldingCollection.Collapse(foldingData);
\r
873 this.View.LayoutLines.FoldingCollection.Expand(foldingData);
\r
874 this._Controller.JumpCaret(foldingData.Start,false);
\r
878 this._Controller.JumpCaret(tp.row, tp.col, false);
\r
880 if (this.peer != null)
\r
881 this.peer.OnNotifyCaretChanged();
\r
882 this.View.IsFocused = true;
\r
889 /// マウスが移動したときに呼ばれます
\r
891 /// <param name="e">イベントパラメーター</param>
\r
893 /// イベントパラメーターはFooMouseEventArgsにキャスト可能です。
\r
894 /// e.Handledを真にした場合、選択処理と状況に応じたカーソルの変化が行われなくなります
\r
896 protected override void OnMouseMove(MouseEventArgs e)
\r
898 System.Windows.Point p = e.GetPosition(this);
\r
899 TextPoint tp = this.View.GetTextPointFromPostion(p);
\r
900 if (tp == TextPoint.Null)
\r
902 base.OnMouseMove(e);
\r
905 int index = this.View.GetIndexFromLayoutLine(tp);
\r
907 FooMouseEventArgs newEventArgs = new FooMouseEventArgs(e.MouseDevice, e.Timestamp, e.StylusDevice, index);
\r
908 newEventArgs.RoutedEvent = e.RoutedEvent;
\r
909 base.OnMouseMove(newEventArgs);
\r
911 if (newEventArgs.Handled)
\r
914 if (this.View.HitTextArea(p.X,p.Y))
\r
916 if (this._Controller.IsMarker(tp, HilightType.Url))
\r
917 this.Cursor = Cursors.Hand;
\r
919 this.Cursor = Cursors.IBeam;
\r
921 if (e.LeftButton == MouseButtonState.Pressed)
\r
923 this._Controller.MoveCaretAndSelect(tp);
\r
924 if (this.peer != null)
\r
925 this.peer.OnNotifyCaretChanged();
\r
931 this.Cursor = Cursors.Arrow;
\r
936 protected override void OnMouseWheel(MouseWheelEventArgs e)
\r
938 if(Keyboard.Modifiers == ModifierKeys.None)
\r
941 this._Controller.Scroll(ScrollDirection.Up, SystemParameters.WheelScrollLines, false, false);
\r
943 this._Controller.Scroll(ScrollDirection.Down, SystemParameters.WheelScrollLines, false, false);
\r
945 else if (Keyboard.Modifiers == ModifierKeys.Control)
\r
947 double newFontSize = this.Render.FontSize;
\r
952 if (newFontSize > MaxFontSize)
\r
954 else if (newFontSize < MinFontSize)
\r
956 this.Render.FontSize = newFontSize;
\r
957 SetValue(MagnificationPowerPropertyKey, this.Render.FontSize / this.FontSize);
\r
960 base.OnMouseWheel(e);
\r
963 void SystemEvents_UserPreferenceChanged(object sender, UserPreferenceChangedEventArgs e)
\r
965 if (e.Category == UserPreferenceCategory.Keyboard)
\r
967 int blinkTime = (int)NativeMethods.GetCaretBlinkTime();
\r
968 this.View.CaretBlink = blinkTime >= 0;
\r
969 this.View.CaretBlinkTime = blinkTime * 2;
\r
971 if (e.Category == UserPreferenceCategory.General)
\r
973 this.View.CaretWidthOnInsertMode = SystemParameters.CaretWidth;
\r
977 void Document_Update(object sender, DocumentUpdateEventArgs e)
\r
979 if (this.textStore.IsLocked())
\r
981 TextStoreHelper.NotifyTextChanged(this.textStore, e.startIndex, e.removeLength, e.insertLength);
\r
984 void timer_Tick(object sender, EventArgs e)
\r
986 if (this.image.ActualWidth == 0 || this.image.ActualHeight == 0)
\r
988 if (this.Resize(this.image.ActualWidth, this.image.ActualHeight))
\r
994 ITextLayout layout = this.View.LayoutLines.GetLayout(this.View.CaretPostion.row);
\r
995 double width = layout.GetWidthFromIndex(this.View.CaretPostion.col);
\r
997 width = this.View.CaretWidthOnInsertMode;
\r
998 double height = layout.Height;
\r
999 Rectangle updateRect = new Rectangle(
\r
1000 this.View.CaretLocation.X,
\r
1001 this.View.CaretLocation.Y,
\r
1005 this.Refresh(updateRect);
\r
1008 void horizontalScrollBar_Scroll(object sender, ScrollEventArgs e)
\r
1010 if (this.horizontalScrollBar == null)
\r
1013 if (this.FlowDirection == System.Windows.FlowDirection.LeftToRight)
\r
1014 toX = this.horizontalScrollBar.Value;
\r
1016 toX = -this.horizontalScrollBar.Value;
\r
1017 this._Controller.Scroll(toX, this.View.Src.Row, false, false);
\r
1021 void verticalScrollBar_Scroll(object sender, ScrollEventArgs e)
\r
1023 if (this.verticalScrollBar == null)
\r
1025 int newRow = (int)this.verticalScrollBar.Value;
\r
1026 if (newRow >= this.View.LayoutLines.Count)
\r
1028 this._Controller.Scroll(this.View.Src.X,newRow, false, false);
\r
1032 void View_SrcChanged(object sender, EventArgs e)
\r
1034 if (this.horizontalScrollBar == null || this.verticalScrollBar == null)
\r
1036 EditView view = this.View;
\r
1037 if (view.Src.Row > this.verticalScrollBar.Maximum)
\r
1038 this.verticalScrollBar.Maximum = view.Src.Row + view.LineCountOnScreen + 1;
\r
1039 double absoulteX = Math.Abs(view.Src.X);
\r
1040 if(absoulteX > this.horizontalScrollBar.Maximum)
\r
1041 this.horizontalScrollBar.Maximum = absoulteX + view.PageBound.Width + 1;
\r
1042 if(view.Src.Row != this.verticalScrollBar.Value)
\r
1043 this.verticalScrollBar.Value = view.Src.Row;
\r
1044 if (view.Src.X != this.horizontalScrollBar.Value)
\r
1045 this.horizontalScrollBar.Value = Math.Abs(view.Src.X);
\r
1048 void Controller_SelectionChanged(object sender, EventArgs e)
\r
1050 this.View.CaretBlink = this.View.CaretBlink;
\r
1051 this.CaretMoved(this, null);
\r
1052 //こうしないと選択できなくなってしまう
\r
1053 this.nowCaretMove = true;
\r
1054 SetValue(SelectionProperty, new TextRange(this._Controller.SelectionStart, this._Controller.SelectionLength));
\r
1055 SetValue(CaretPostionProperty, this.View.CaretPostion);
\r
1056 this.nowCaretMove = false;
\r
1057 if(this.textStore.IsLocked() == false)
\r
1058 this.textStore.NotifySelectionChanged();
\r
1061 void FooTextBox_Loaded(object sender, RoutedEventArgs e)
\r
1063 this.Resize(this.image.ActualWidth, this.image.ActualHeight);
\r
1066 bool Resize(double width, double height)
\r
1068 if (width == 0 || height == 0)
\r
1069 throw new ArgumentOutOfRangeException();
\r
1070 if (this.Render.Resize(width, height))
\r
1072 this.View.PageBound = new Rectangle(0, 0, width, height);
\r
1074 if (this.horizontalScrollBar != null)
\r
1076 this.horizontalScrollBar.LargeChange = this.View.PageBound.Width;
\r
1077 this.horizontalScrollBar.Maximum = this.View.LongestWidth + this.horizontalScrollBar.LargeChange + 1;
\r
1079 if (this.verticalScrollBar != null)
\r
1081 this.verticalScrollBar.LargeChange = this.View.LineCountOnScreen;
\r
1082 this.verticalScrollBar.Maximum = this.View.LayoutLines.Count + this.verticalScrollBar.LargeChange + 1;
\r
1090 /// プロパティーが変更されたときに呼ばれます
\r
1092 /// <param name="e">イベントパラメーター</param>
\r
1093 protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e)
\r
1095 switch (e.Property.Name)
\r
1097 case "IndentMode":
\r
1098 this._Controller.IndentMode = this.IndentMode;
\r
1101 if(!this.nowCaretMove)
\r
1102 this.Select(this.Selection.Index, this.Selection.Length);
\r
1104 case "CaretPostion":
\r
1105 if (!this.nowCaretMove)
\r
1106 this.JumpCaret(this.CaretPostion.row, this.CaretPostion.col);
\r
1108 case "LineBreakMethod":
\r
1109 this.View.LineBreak = this.LineBreakMethod;
\r
1111 case "LineBreakCharCount":
\r
1112 this.View.LineBreakCharCount = this.LineBreakCharCount;
\r
1114 case "InsertMode":
\r
1115 this.View.InsertMode = this.InsertMode;
\r
1118 this.View.TabStops = this.TabChars;
\r
1120 case "RectSelectMode":
\r
1121 this._Controller.RectSelection = this.RectSelectMode;
\r
1124 this.View.HideCaret = !this.DrawCaret;
\r
1126 case "DrawCaretLine":
\r
1127 this.View.HideLineMarker = !this.DrawCaretLine;
\r
1129 case "DrawLineNumber":
\r
1130 this.View.DrawLineNumber = this.DrawLineNumber;
\r
1131 this._Controller.JumpCaret(this.View.CaretPostion.row, this.View.CaretPostion.col);
\r
1133 case "FontFamily":
\r
1134 this.Render.FontFamily = this.FontFamily;
\r
1137 this.Render.FontSize = this.FontSize;
\r
1140 this.Render.FontStyle = this.FontStyle;
\r
1142 case "FontWeight":
\r
1143 this.Render.FontWeigth = this.FontWeight;
\r
1145 case "Foreground":
\r
1146 this.Render.Foreground = D2DRender.ToColor4(this.Foreground);
\r
1148 case "Background":
\r
1149 this.Render.Background = D2DRender.ToColor4(this.Background);
\r
1151 case "ControlChar":
\r
1152 this.Render.ControlChar =D2DRender.ToColor4( this.ControlChar);
\r
1155 this.Render.Hilight = D2DRender.ToColor4(this.Hilight);
\r
1158 this.Render.Keyword1 = D2DRender.ToColor4(this.Keyword1);
\r
1161 this.Render.Keyword2 = D2DRender.ToColor4(this.Keyword2);
\r
1164 this.Render.Comment = D2DRender.ToColor4(this.Comment);
\r
1167 this.Render.Literal = D2DRender.ToColor4(this.Literal);
\r
1170 this.Render.Url = D2DRender.ToColor4(this.URL);
\r
1172 case "InsertCaret":
\r
1173 this.Render.InsertCaret = D2DRender.ToColor4(this.InsertCaret);
\r
1175 case "OverwriteCaret":
\r
1176 this.Render.OverwriteCaret = D2DRender.ToColor4(this.OverwriteCaret);
\r
1179 this.View.Padding = new Padding((int)this.Padding.Left, (int)this.Padding.Top, (int)this.Padding.Right, (int)this.Padding.Bottom);
\r
1181 case "LineMarker":
\r
1182 this.Render.LineMarker = D2DRender.ToColor4(this.LineMarker);
\r
1185 this.View.UrlMark = this.MarkURL;
\r
1187 case "ShowFullSpace":
\r
1188 this.Render.ShowFullSpace = this.ShowFullSpace;
\r
1190 case "ShowHalfSpace":
\r
1191 this.Render.ShowHalfSpace = this.ShowHalfSpace;
\r
1194 this.Render.ShowTab = this.ShowTab;
\r
1196 case "ShowLineBreak":
\r
1197 this.Render.ShowLineBreak = this.ShowLineBreak;
\r
1199 case "FlowDirection":
\r
1200 this.Render.RightToLeft = this.FlowDirection == System.Windows.FlowDirection.RightToLeft;
\r
1201 this.horizontalScrollBar.FlowDirection = this.FlowDirection;
\r
1204 this.View.HideRuler = !this.DrawRuler;
\r
1205 this._Controller.JumpCaret(this.View.CaretPostion.row, this.View.CaretPostion.col);
\r
1207 case "UpdateArea":
\r
1208 this.Render.UpdateArea = D2DRender.ToColor4(this.UpdateArea);
\r
1211 base.OnPropertyChanged(e);
\r
1216 internal Controller Controller
\r
1220 return this._Controller;
\r
1225 /// 文字列の描写に使用されるアンチエイリアシング モードを表します
\r
1227 public TextAntialiasMode TextAntialiasMode
\r
1231 return this.Render.TextAntialiasMode;
\r
1235 this.Render.TextAntialiasMode = value;
\r
1240 /// シンタックスハイライターを表す
\r
1242 public IHilighter Hilighter
\r
1246 return this.View.Hilighter;
\r
1250 this.View.Hilighter = value;
\r
1251 this.View.LayoutLines.ClearLayoutCache();
\r
1256 /// フォールティングを作成するインターフェイスを表す
\r
1258 public IFoldingStrategy FoldingStrategy
\r
1262 return this.View.LayoutLines.FoldingStrategy;
\r
1266 this.View.LayoutLines.FoldingStrategy = value;
\r
1267 if (value == null)
\r
1268 this.View.LayoutLines.FoldingCollection.Clear();
\r
1275 public MarkerPatternSet MarkerPatternSet
\r
1279 return this.View.MarkerPatternSet;
\r
1286 public Document Document
\r
1295 public LineToIndexTable LayoutLineCollection
\r
1297 get { return this.View.LayoutLines; }
\r
1303 public string SelectedText
\r
1307 return this._Controller.SelectedText;
\r
1311 int oldLength = this.Document.Length;
\r
1312 this._Controller.SelectedText = value;
\r
1319 public IndentMode IndentMode
\r
1321 get { return (IndentMode)GetValue(IndentModeProperty); }
\r
1322 set { SetValue(IndentModeProperty, value); }
\r
1326 /// IndentModeの依存プロパティを表す
\r
1328 public static readonly DependencyProperty IndentModeProperty =
\r
1329 DependencyProperty.Register("IndentMode", typeof(IndentMode), typeof(FooTextBox), new PropertyMetadata(IndentMode.Tab));
\r
1335 /// Lengthが0の場合はキャレット位置を表します。
\r
1336 /// 矩形選択モードの場合、選択範囲の文字数ではなく、開始位置から終了位置までの長さとなります
\r
1338 public TextRange Selection
\r
1340 get { return (TextRange)GetValue(SelectionProperty); }
\r
1341 set { SetValue(SelectionProperty, value); }
\r
1345 /// Selectionの依存プロパティを表す
\r
1347 public static readonly DependencyProperty SelectionProperty =
\r
1348 DependencyProperty.Register("Selection", typeof(TextRange), typeof(FooTextBox), new PropertyMetadata(TextRange.Null));
\r
1353 public double MagnificationPower
\r
1355 get { return (double)GetValue(MagnificationPowerPropertyKey.DependencyProperty); }
\r
1361 public static readonly DependencyPropertyKey MagnificationPowerPropertyKey =
\r
1362 DependencyProperty.RegisterReadOnly("MagnificationPower", typeof(double), typeof(FooTextBox), new PropertyMetadata(1.0));
\r
1367 public new FlowDirection FlowDirection
\r
1369 get { return (FlowDirection)GetValue(FlowDirectionProperty); }
\r
1370 set { SetValue(FlowDirectionProperty, value); }
\r
1374 /// レタリング方向を表す。これは依存プロパティです
\r
1376 public new static readonly DependencyProperty FlowDirectionProperty =
\r
1377 DependencyProperty.Register("FlowDirection", typeof(FlowDirection), typeof(FooTextBox), new PropertyMetadata(FlowDirection.LeftToRight));
\r
1380 /// キャレット位置を表す。これは依存プロパティです
\r
1382 public TextPoint CaretPostion
\r
1384 get { return (TextPoint)GetValue(CaretPostionProperty); }
\r
1385 set { SetValue(CaretPostionProperty, value); }
\r
1389 /// CaretPostionの依存プロパティを表す
\r
1391 public static readonly DependencyProperty CaretPostionProperty =
\r
1392 DependencyProperty.Register("CaretPostion", typeof(TextPoint), typeof(FooTextBox), new PropertyMetadata(TextPoint.Null));
\r
1395 /// デフォルトの文字色を表す。これは依存プロパティです
\r
1397 public new System.Windows.Media.Color Foreground
\r
1399 get { return (System.Windows.Media.Color)GetValue(ForegroundProperty); }
\r
1400 set { SetValue(ForegroundProperty, value); }
\r
1404 /// Foregroundの依存プロパティを表す
\r
1406 public new static readonly DependencyProperty ForegroundProperty =
\r
1407 DependencyProperty.Register("Foreground", typeof(System.Windows.Media.Color), typeof(FooTextBox), new FrameworkPropertyMetadata(SystemColors.WindowTextColor));
\r
1410 /// 背景色を表す。これは依存プロパティです
\r
1412 public new System.Windows.Media.Color Background
\r
1414 get { return (System.Windows.Media.Color)GetValue(BackgroundProperty); }
\r
1415 set { SetValue(BackgroundProperty, value); }
\r
1419 /// Backgroundの依存プロパティを表す
\r
1421 public new static readonly DependencyProperty BackgroundProperty =
\r
1422 DependencyProperty.Register("Background", typeof(System.Windows.Media.Color), typeof(FooTextBox), new FrameworkPropertyMetadata(SystemColors.WindowColor));
\r
1425 /// コントロールコードの文字色を表す。これは依存プロパティです
\r
1427 public System.Windows.Media.Color ControlChar
\r
1429 get { return (System.Windows.Media.Color)GetValue(ControlCharProperty); }
\r
1430 set { SetValue(ControlCharProperty, value); }
\r
1434 /// ControlCharの依存プロパティを表す
\r
1436 public static readonly DependencyProperty ControlCharProperty =
\r
1437 DependencyProperty.Register("ControlChar", typeof(System.Windows.Media.Color), typeof(FooTextBox), new FrameworkPropertyMetadata(Colors.Gray));
\r
1440 /// 選択時の背景色を表す。これは依存プロパティです
\r
1442 public System.Windows.Media.Color Hilight
\r
1444 get { return (System.Windows.Media.Color)GetValue(HilightProperty); }
\r
1445 set { SetValue(HilightProperty, value); }
\r
1449 /// Hilightの依存プロパティを表す
\r
1451 public static readonly DependencyProperty HilightProperty =
\r
1452 DependencyProperty.Register("Hilight", typeof(System.Windows.Media.Color), typeof(FooTextBox), new FrameworkPropertyMetadata(Colors.DeepSkyBlue));
\r
1455 /// キーワード1の文字色を表す。これは依存プロパティです
\r
1457 public System.Windows.Media.Color Keyword1
\r
1459 get { return (System.Windows.Media.Color)GetValue(Keyword1Property); }
\r
1460 set { SetValue(Keyword1Property, value); }
\r
1464 /// Keyword1の依存プロパティを表す
\r
1466 public static readonly DependencyProperty Keyword1Property =
\r
1467 DependencyProperty.Register("Keyword1", typeof(System.Windows.Media.Color), typeof(FooTextBox), new FrameworkPropertyMetadata(Colors.Blue));
\r
1470 /// キーワード2の文字色を表す。これは依存プロパティです
\r
1472 public System.Windows.Media.Color Keyword2
\r
1474 get { return (System.Windows.Media.Color)GetValue(Keyword2Property); }
\r
1475 set { SetValue(Keyword2Property, value); }
\r
1479 /// Keyword2の依存プロパティを表す
\r
1481 public static readonly DependencyProperty Keyword2Property =
\r
1482 DependencyProperty.Register("Keyword2", typeof(System.Windows.Media.Color), typeof(FooTextBox), new FrameworkPropertyMetadata(Colors.DarkCyan));
\r
1485 /// コメントの文字色を表す。これは依存プロパティです
\r
1487 public System.Windows.Media.Color Comment
\r
1489 get { return (System.Windows.Media.Color)GetValue(CommentProperty); }
\r
1490 set { SetValue(CommentProperty, value); }
\r
1494 /// Commentの依存プロパティを表す
\r
1496 public static readonly DependencyProperty CommentProperty =
\r
1497 DependencyProperty.Register("Comment", typeof(System.Windows.Media.Color), typeof(FooTextBox), new FrameworkPropertyMetadata(Colors.Green));
\r
1500 /// 文字リテラルの文字色を表す。これは依存プロパティです
\r
1502 public System.Windows.Media.Color Literal
\r
1504 get { return (System.Windows.Media.Color)GetValue(LiteralProperty); }
\r
1505 set { SetValue(LiteralProperty, value); }
\r
1509 /// Literalの依存プロパティを表す
\r
1511 public static readonly DependencyProperty LiteralProperty =
\r
1512 DependencyProperty.Register("Literal", typeof(System.Windows.Media.Color), typeof(FooTextBox), new FrameworkPropertyMetadata(Colors.Brown));
\r
1515 /// URLの文字色を表す。これは依存プロパティです
\r
1517 public System.Windows.Media.Color URL
\r
1519 get { return (System.Windows.Media.Color)GetValue(URLProperty); }
\r
1520 set { SetValue(URLProperty, value); }
\r
1524 /// URLの依存プロパティを表す
\r
1526 public static readonly DependencyProperty URLProperty =
\r
1527 DependencyProperty.Register("URL", typeof(System.Windows.Media.Color), typeof(FooTextBox), new FrameworkPropertyMetadata(Colors.Blue));
\r
1533 public System.Windows.Media.Color LineMarker
\r
1535 get { return (System.Windows.Media.Color)GetValue(LineMarkerProperty); }
\r
1536 set { SetValue(LineMarkerProperty, value); }
\r
1540 /// LineMarkerの依存プロパティを表す
\r
1542 public static readonly DependencyProperty LineMarkerProperty =
\r
1543 DependencyProperty.Register("LineMarker", typeof(System.Windows.Media.Color), typeof(FooTextBox), new FrameworkPropertyMetadata(Colors.Silver));
\r
1546 /// 挿入モード時のキャレットの色を表す
\r
1548 public System.Windows.Media.Color InsertCaret
\r
1550 get { return (System.Windows.Media.Color)GetValue(InsertCaretProperty); }
\r
1551 set { SetValue(InsertCaretProperty, value); }
\r
1555 /// InsertCaretの依存プロパティを表す
\r
1557 public static readonly DependencyProperty InsertCaretProperty =
\r
1558 DependencyProperty.Register("InsertCaret", typeof(System.Windows.Media.Color), typeof(FooTextBox), new FrameworkPropertyMetadata(SystemColors.WindowTextColor));
\r
1563 public System.Windows.Media.Color UpdateArea
\r
1565 get { return (System.Windows.Media.Color)GetValue(UpdateAreaProperty); }
\r
1566 set { SetValue(UpdateAreaProperty, value); }
\r
1570 /// UpdateAreaの依存プロパティを表す
\r
1572 public static readonly DependencyProperty UpdateAreaProperty =
\r
1573 DependencyProperty.Register("UpdateArea", typeof(System.Windows.Media.Color), typeof(FooTextBox), new PropertyMetadata(Colors.MediumSeaGreen));
\r
1576 /// 上書きモード時のキャレット職を表す
\r
1578 public System.Windows.Media.Color OverwriteCaret
\r
1580 get { return (System.Windows.Media.Color)GetValue(OverwriteCaretProperty); }
\r
1581 set { SetValue(OverwriteCaretProperty, value); }
\r
1585 /// OverwriteCaretの依存プロパティを表す
\r
1587 public static readonly DependencyProperty OverwriteCaretProperty =
\r
1588 DependencyProperty.Register("OverwriteCaret", typeof(System.Windows.Media.Color), typeof(FooTextBox), new FrameworkPropertyMetadata(SystemColors.WindowTextColor));
\r
1591 /// 挿入モードなら真を返し、そうでないなら、偽を返す。これは依存プロパティです
\r
1593 public bool InsertMode
\r
1595 get { return (bool)GetValue(InsertModeProperty); }
\r
1596 set { SetValue(InsertModeProperty, value); }
\r
1600 /// InsertModeの依存プロパティを表す
\r
1602 public static readonly DependencyProperty InsertModeProperty =
\r
1603 DependencyProperty.Register("InsertMode",
\r
1605 typeof(FooTextBox),
\r
1606 new FrameworkPropertyMetadata(true));
\r
1609 /// タブの文字数を表す。これは依存プロパティです
\r
1611 public int TabChars
\r
1613 get { return (int)GetValue(TabCharsProperty); }
\r
1614 set { SetValue(TabCharsProperty, value); }
\r
1618 /// TabCharsの依存プロパティを表す
\r
1620 public static readonly DependencyProperty TabCharsProperty =
\r
1621 DependencyProperty.Register("TabChars",
\r
1623 typeof(FooTextBox),
\r
1624 new FrameworkPropertyMetadata(4));
\r
1627 /// 矩形選択モードなら真を返し、そうでないなら偽を返す。これは依存プロパティです
\r
1629 public bool RectSelectMode
\r
1631 get { return (bool)GetValue(RectSelectModeProperty); }
\r
1632 set { SetValue(RectSelectModeProperty, value); }
\r
1636 /// RectSelectModeの依存プロパティを表す
\r
1638 public static readonly DependencyProperty RectSelectModeProperty =
\r
1639 DependencyProperty.Register("RectSelectMode", typeof(bool), typeof(FooTextBox), new FrameworkPropertyMetadata(false));
\r
1645 /// 変更した場合、レイアウトの再構築を行う必要があります
\r
1647 public LineBreakMethod LineBreakMethod
\r
1649 get { return (LineBreakMethod)GetValue(LineBreakProperty); }
\r
1650 set { SetValue(LineBreakProperty, value); }
\r
1654 /// LineBreakMethodの依存プロパティを表す
\r
1656 public static readonly DependencyProperty LineBreakProperty =
\r
1657 DependencyProperty.Register("LineBreakMethod", typeof(LineBreakMethod), typeof(FooTextBox), new PropertyMetadata(LineBreakMethod.None));
\r
1661 /// 折り返しの幅を指定する。LineBreakMethod.CharUnit以外の時は無視されます
\r
1664 /// 変更した場合、レイアウトの再構築を行う必要があります
\r
1666 public int LineBreakCharCount
\r
1668 get { return (int)GetValue(LineBreakCharCountProperty); }
\r
1669 set { SetValue(LineBreakCharCountProperty, value); }
\r
1673 /// LineBreakCharCountの依存プロパティを表す
\r
1675 public static readonly DependencyProperty LineBreakCharCountProperty =
\r
1676 DependencyProperty.Register("LineBreakCharCount", typeof(int), typeof(FooTextBox), new PropertyMetadata(80));
\r
1679 /// キャレットを描くなら真。そうでないなら偽を返す。これは依存プロパティです
\r
1681 public bool DrawCaret
\r
1683 get { return (bool)GetValue(DrawCaretProperty); }
\r
1684 set { SetValue(DrawCaretProperty, value); }
\r
1688 /// DrawCaretの依存プロパティを表す
\r
1690 public static readonly DependencyProperty DrawCaretProperty =
\r
1691 DependencyProperty.Register("DrawCaret", typeof(bool), typeof(FooTextBox), new FrameworkPropertyMetadata(true));
\r
1695 /// キャレットラインを描くなら真。そうでないなら偽を返す。これは依存プロパティです
\r
1697 public bool DrawCaretLine
\r
1699 get { return (bool)GetValue(DrawCaretLineProperty); }
\r
1700 set { SetValue(DrawCaretLineProperty, value); }
\r
1704 /// DrawCaretLineの依存プロパティを表す
\r
1706 public static readonly DependencyProperty DrawCaretLineProperty =
\r
1707 DependencyProperty.Register("DrawCaretLine", typeof(bool), typeof(FooTextBox), new FrameworkPropertyMetadata(false));
\r
1710 /// 行番号を描くなら真。そうでなければ偽。これは依存プロパティです
\r
1712 public bool DrawLineNumber
\r
1714 get { return (bool)GetValue(DrawLineNumberProperty); }
\r
1715 set { SetValue(DrawLineNumberProperty, value); }
\r
1719 /// ルーラーを描くなら真。そうでなければ偽。これは依存プロパティです
\r
1721 public bool DrawRuler
\r
1723 get { return (bool)GetValue(DrawRulerProperty); }
\r
1724 set { SetValue(DrawRulerProperty, value); }
\r
1728 /// DrawRulerの依存プロパティを表す
\r
1730 public static readonly DependencyProperty DrawRulerProperty =
\r
1731 DependencyProperty.Register("DrawRuler", typeof(bool), typeof(FooTextBox), new PropertyMetadata(false));
\r
1735 /// DrawLineNumberの依存プロパティを表す
\r
1737 public static readonly DependencyProperty DrawLineNumberProperty =
\r
1738 DependencyProperty.Register("DrawLineNumber", typeof(bool), typeof(FooTextBox), new FrameworkPropertyMetadata(false));
\r
1741 /// URLに下線を引くなら真。そうでないなら偽を表す。これは依存プロパティです
\r
1743 public bool MarkURL
\r
1745 get { return (bool)GetValue(MarkURLProperty); }
\r
1746 set { SetValue(MarkURLProperty, value); }
\r
1750 /// MarkURLの依存プロパティを表す
\r
1752 public static readonly DependencyProperty MarkURLProperty =
\r
1753 DependencyProperty.Register("MarkURL", typeof(bool), typeof(FooTextBox), new FrameworkPropertyMetadata(false));
\r
1756 /// 全角スペースを表示するなら真。そうでないなら偽
\r
1758 public bool ShowFullSpace
\r
1760 get { return (bool)GetValue(ShowFullSpaceProperty); }
\r
1761 set { SetValue(ShowFullSpaceProperty, value); }
\r
1765 /// ShowFullSpaceの依存プロパティを表す
\r
1767 public static readonly DependencyProperty ShowFullSpaceProperty =
\r
1768 DependencyProperty.Register("ShowFullSpace", typeof(bool), typeof(FooTextBox), new UIPropertyMetadata(false));
\r
1771 /// 半角スペースを表示するなら真。そうでないなら偽
\r
1773 public bool ShowHalfSpace
\r
1775 get { return (bool)GetValue(ShowHalfSpaceProperty); }
\r
1776 set { SetValue(ShowHalfSpaceProperty, value); }
\r
1780 /// ShowHalfSpaceの依存プロパティを表す
\r
1782 public static readonly DependencyProperty ShowHalfSpaceProperty =
\r
1783 DependencyProperty.Register("ShowHalfSpace", typeof(bool), typeof(FooTextBox), new UIPropertyMetadata(false));
\r
1786 /// タブを表示するなら真。そうでないなら偽
\r
1788 public bool ShowTab
\r
1790 get { return (bool)GetValue(ShowTabProperty); }
\r
1791 set { SetValue(ShowTabProperty, value); }
\r
1795 /// ShowTabの依存プロパティを表す
\r
1797 public static readonly DependencyProperty ShowTabProperty =
\r
1798 DependencyProperty.Register("ShowTab", typeof(bool), typeof(FooTextBox), new UIPropertyMetadata(false));
\r
1801 /// 改行マークを表示するなら真。そうでないなら偽
\r
1803 public bool ShowLineBreak
\r
1805 get { return (bool)GetValue(ShowLineBreakProperty); }
\r
1806 set { SetValue(ShowLineBreakProperty, value); }
\r
1810 /// ShowLineBreakの依存プロパティを表す
\r
1812 public static readonly DependencyProperty ShowLineBreakProperty =
\r
1813 DependencyProperty.Register("ShowLineBreak", typeof(bool), typeof(FooTextBox), new PropertyMetadata(false));
\r
1818 /// マウスボタン関連のイベントクラス
\r
1820 public sealed class FooMouseButtonEventArgs : MouseButtonEventArgs
\r
1823 /// イベントが発生したドキュメントのインデックス
\r
1834 /// <param name="mouse">マウスデバイス</param>
\r
1835 /// <param name="timestamp">タイムスタンプ</param>
\r
1836 /// <param name="button">ボタン</param>
\r
1837 /// <param name="stylusDevice">スタイラスデバイス</param>
\r
1838 /// <param name="index">インデックス</param>
\r
1839 public FooMouseButtonEventArgs(MouseDevice mouse, int timestamp, MouseButton button, StylusDevice stylusDevice, int index)
\r
1840 : base(mouse, timestamp, button, stylusDevice)
\r
1842 this.Index = index;
\r
1848 public sealed class FooMouseEventArgs : MouseEventArgs
\r
1851 /// イベントが発生したドキュメントのインデックス
\r
1862 /// <param name="mouse">マウスデバイス</param>
\r
1863 /// <param name="timestamp">タイムスタンプ</param>
\r
1864 /// <param name="stylusDevice">スタイラスデバイス</param>
\r
1865 /// <param name="index">インデックス</param>
\r
1866 public FooMouseEventArgs(MouseDevice mouse,
\r
1868 StylusDevice stylusDevice,
\r
1870 : base(mouse, timestamp, stylusDevice)
\r
1872 this.Index = index;
\r