OSDN Git Service

ファイルを保存できない問題を解決した
[fooeditengine/FooEditEngine.git] / WPF / FooEditEngine / FooTextBox.cs
1 /*\r
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
5 \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
8 \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
10  */\r
11 using System;\r
12 using System.Text;\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
27 \r
28 namespace FooEditEngine.WPF\r
29 {\r
30     /// <summary>\r
31     /// オートインデントを行うためのデリゲートを表す\r
32     /// </summary>\r
33     /// <param name="sender">イベント発生元のオブジェクト</param>\r
34     /// <param name="e">イベントデーター</param>\r
35     public delegate void AutoIndentHookerHandler(object sender,EventArgs e);\r
36 \r
37     /// <summary>\r
38     /// WPFでのFooTextBoxの実装\r
39     /// </summary>\r
40     public sealed class FooTextBox : Control, IDisposable\r
41     {\r
42         const double MaxFontSize = 72.0f;\r
43         const double MinFontSize = 1;\r
44 \r
45         EditView View;\r
46         Controller _Controller;\r
47         D2DRender Render;\r
48         Image image;\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
55         \r
56         static FooTextBox()\r
57         {\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
61         }\r
62 \r
63         /// <summary>\r
64         /// コンストラクター\r
65         /// </summary>\r
66         public FooTextBox()\r
67         {\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
72 \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
88 \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
93 \r
94             this.Document = new Document();\r
95             this.Document.LayoutLines.Render = this.Render;\r
96 \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
106 \r
107             this._Controller = new Controller(this.Document, this.View);\r
108             this._Controller.SelectionChanged += new EventHandler(Controller_SelectionChanged);\r
109 \r
110             //Viewを作成した後に追加しないと例外が発生する\r
111             this.Document.Update += new DocumentUpdateEventHandler(Document_Update);\r
112 \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
124 \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
134 \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
138 \r
139             this.Loaded += new RoutedEventHandler(FooTextBox_Loaded);\r
140 \r
141             this.AutoIndentHooker = (s,e)=>{};\r
142 \r
143             SystemEvents.UserPreferenceChanged += new UserPreferenceChangedEventHandler(SystemEvents_UserPreferenceChanged);\r
144 \r
145             this.SystemEvents_UserPreferenceChanged(null, new UserPreferenceChangedEventArgs(UserPreferenceCategory.Keyboard));\r
146 \r
147             this.CaretMoved += (s, e) => { };\r
148         }\r
149 \r
150         /// <summary>\r
151         /// ファイナライザー\r
152         /// </summary>\r
153         ~FooTextBox()\r
154         {\r
155             //Dispose(false)を呼び出すと落ちる\r
156             this.Dispose(false);\r
157         }\r
158 \r
159         /// <summary>\r
160         /// オートインデントを行うためのイベント\r
161         /// </summary>\r
162         public AutoIndentHookerHandler AutoIndentHooker;\r
163 \r
164         /// <summary>\r
165         /// テンプレートを適用します\r
166         /// </summary>\r
167         public override void OnApplyTemplate()\r
168         {\r
169             base.OnApplyTemplate();\r
170 \r
171             Grid grid = this.GetTemplateChild("PART_Grid") as Grid;\r
172             if (grid != null)\r
173             {\r
174                 Grid.SetRow(this.image, 0);\r
175                 Grid.SetColumn(this.image, 0);\r
176                 grid.Children.Add(this.image);\r
177             }\r
178 \r
179             this.horizontalScrollBar = this.GetTemplateChild("PART_HorizontalScrollBar") as ScrollBar;\r
180             if (this.horizontalScrollBar != null)\r
181             {\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
186             }\r
187             this.verticalScrollBar = this.GetTemplateChild("PART_VerticalScrollBar") as ScrollBar;\r
188             if (this.verticalScrollBar != null)\r
189             {\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
194             }\r
195         }\r
196 \r
197         /// <summary>\r
198         /// ドキュメントを選択する\r
199         /// </summary>\r
200         /// <param name="start">開始インデックス</param>\r
201         /// <param name="length">長さ</param>\r
202         public void Select(int start, int length)\r
203         {\r
204             this._Controller.Select(start, length);\r
205             this.textStore.NotifySelectionChanged();\r
206         }\r
207 \r
208         /// <summary>\r
209         /// キャレットを指定した行に移動させます\r
210         /// </summary>\r
211         /// <param name="index">インデックス</param>\r
212         /// <remarks>このメソッドを呼び出すと選択状態は解除されます</remarks>\r
213         public void JumpCaret(int index)\r
214         {\r
215             this._Controller.JumpCaret(index);\r
216         }\r
217         /// <summary>\r
218         /// キャレットを指定した行と桁に移動させます\r
219         /// </summary>\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
224         {\r
225             this._Controller.JumpCaret(row, col);\r
226         }\r
227 \r
228         /// <summary>\r
229         /// 選択中のテキストをクリップボードにコピーします\r
230         /// </summary>\r
231         public void Copy()\r
232         {\r
233             string text = this._Controller.SelectedText;\r
234             if (text != null && text != string.Empty)\r
235                 Clipboard.SetText(text);\r
236         }\r
237 \r
238         /// <summary>\r
239         /// 選択中のテキストをクリップボードに切り取ります\r
240         /// </summary>\r
241         public void Cut()\r
242         {\r
243             string text = this._Controller.SelectedText;\r
244             if (text != null && text != string.Empty)\r
245             {\r
246                 Clipboard.SetText(text);\r
247                 this._Controller.SelectedText = "";\r
248             }\r
249         }\r
250 \r
251         /// <summary>\r
252         /// 選択中のテキストを貼り付けます\r
253         /// </summary>\r
254         public void Paste()\r
255         {\r
256             if (Clipboard.ContainsText() == false)\r
257                 return;\r
258             string text = Clipboard.GetText();\r
259             this._Controller.SelectedText = text;\r
260         }\r
261 \r
262         /// <summary>\r
263         /// 選択を解除する\r
264         /// </summary>\r
265         public void DeSelectAll()\r
266         {\r
267             this._Controller.DeSelectAll();\r
268             this.textStore.NotifySelectionChanged();\r
269         }\r
270 \r
271         /// <summary>\r
272         /// 対応する座標を返します\r
273         /// </summary>\r
274         /// <param name="tp">テキストポイント</param>\r
275         /// <returns>座標</returns>\r
276         /// <remarks>テキストポイントがクライアント領域の原点より外にある場合、返される値は原点に丸められます</remarks>\r
277         public System.Windows.Point GetPostionFromTextPoint(TextPoint tp)\r
278         {\r
279             if (this.Document.FireUpdateEvent == false)\r
280                 throw new InvalidOperationException("");\r
281             return this.View.GetPostionFromTextPoint(tp);\r
282         }\r
283 \r
284         /// <summary>\r
285         /// 対応するテキストポイントを返します\r
286         /// </summary>\r
287         /// <param name="p">クライアント領域の原点を左上とする座標</param>\r
288         /// <returns>テキストポイント</returns>\r
289         public TextPoint GetTextPointFromPostion(System.Windows.Point p)\r
290         {\r
291             if (this.Document.FireUpdateEvent == false)\r
292                 throw new InvalidOperationException("");\r
293             return this.View.GetTextPointFromPostion(p);\r
294         }\r
295 \r
296         /// <summary>\r
297         /// 行の高さを取得します\r
298         /// </summary>\r
299         /// <param name="row">レイアウト行</param>\r
300         /// <returns>行の高さ</returns>\r
301         public double GetLineHeight(int row)\r
302         {\r
303             if (this.Document.FireUpdateEvent == false)\r
304                 throw new InvalidOperationException("");\r
305             return this.View.LayoutLines.GetLayout(row).Height;;\r
306         }\r
307 \r
308         /// <summary>\r
309         /// インデックスに対応する座標を得ます\r
310         /// </summary>\r
311         /// <param name="index">インデックス</param>\r
312         /// <returns>座標を返す</returns>\r
313         public System.Windows.Point GetPostionFromIndex(int index)\r
314         {\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
319         }\r
320 \r
321         /// <summary>\r
322         /// 座標からインデックスに変換します\r
323         /// </summary>\r
324         /// <param name="p">座標</param>\r
325         /// <returns>インデックスを返す</returns>\r
326         public int GetIndexFromPostion(System.Windows.Point p)\r
327         {\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
332         }\r
333 \r
334         /// <summary>\r
335         /// 再描写する\r
336         /// </summary>\r
337         public void Refresh()\r
338         {\r
339             this.Refresh(this.View.PageBound);\r
340         }\r
341 \r
342         /// <summary>\r
343         /// レイアウト行をすべて破棄し、再度レイアウトを行う\r
344         /// </summary>\r
345         public void PerfomLayouts()\r
346         {\r
347             this.View.PerfomLayouts();\r
348         }\r
349 \r
350         /// <summary>\r
351         /// ストリームからドキュメントを構築する\r
352         /// </summary>\r
353         /// <param name="tr">TextReader</param>\r
354         /// <param name="token">キャンセル用トークン</param>\r
355         /// <returns>Taskオブジェクト</returns>\r
356         public async Task LoadAsync(System.IO.TextReader tr, System.Threading.CancellationTokenSource token)\r
357         {\r
358             WinFileReader fs = new WinFileReader(tr);\r
359             await this.LoadAsyncImpl(fs, token);\r
360         }\r
361 \r
362         /// <summary>\r
363         /// ファイルからドキュメントを構築する\r
364         /// </summary>\r
365         /// <param name="filepath">ファイルパス</param>\r
366         /// <param name="enc">エンコード</param>\r
367         /// <param name="token">キャンセル用トークン</param>\r
368         /// <returns>Taskオブジェクト</returns>\r
369         public async Task LoadFileAsync(string filepath, Encoding enc,System.Threading.CancellationTokenSource token)\r
370         {\r
371             WinFileReader fs = new WinFileReader(filepath, enc);\r
372             await this.LoadAsyncImpl(fs, token);\r
373             fs.Close();\r
374         }\r
375 \r
376         async Task LoadAsyncImpl(WinFileReader fs,System.Threading.CancellationTokenSource token)\r
377         {\r
378             this.IsEnabled = false;\r
379             this.View.LayoutLines.IsFrozneDirtyFlag = true;\r
380             await this.Document.LoadAsync(fs, token);\r
381             this.View.LayoutLines.IsFrozneDirtyFlag = false;\r
382             TextStoreHelper.NotifyTextChanged(this.textStore, 0, 0, this.Document.Length);\r
383             if (this.verticalScrollBar != null)\r
384                 this.verticalScrollBar.Maximum = this.View.LayoutLines.Count;\r
385             this.View.CalculateLineCountOnScreen();\r
386             this.IsEnabled = true;\r
387         }\r
388 \r
389         /// <summary>\r
390         /// ドキュメントの内容をファイルに保存する\r
391         /// </summary>\r
392         /// <param name="filepath">ファイルパス</param>\r
393         /// <param name="newLine">改行コード</param>\r
394         /// <param name="enc">エンコード</param>\r
395         /// <returns>Taskオブジェクト</returns>\r
396         public async Task SaveFile(string filepath, Encoding enc,string newLine, System.Threading.CancellationTokenSource token)\r
397         {\r
398             WinFileWriter fs = new WinFileWriter(filepath, enc);\r
399             fs.NewLine = newLine;\r
400             await this.Document.SaveAsync(fs, token);\r
401             fs.Close();\r
402         }\r
403 \r
404         /// <summary>\r
405         /// アンマネージドリソースを開放する\r
406         /// </summary>\r
407         public void Dispose()\r
408         {\r
409             if (this.disposed)\r
410                 return;\r
411             this.Dispose(true);\r
412             GC.SuppressFinalize(this);\r
413             this.disposed = true;\r
414         }\r
415 \r
416         /// <summary>\r
417         /// リソースを開放する\r
418         /// </summary>\r
419         /// <param name="disposing">真ならマネージドリソースも開放し、そうでないならアンマネージドリソースのみを開放する</param>\r
420         void Dispose(bool disposing)\r
421         {\r
422             if (disposing)\r
423             {\r
424                 this.textStore.Dispose();\r
425                 this.timer.Stop();\r
426                 this.View.Dispose();\r
427                 this.Render.Dispose();\r
428             }\r
429             SystemEvents.UserPreferenceChanged -= new UserPreferenceChangedEventHandler(SystemEvents_UserPreferenceChanged);\r
430         }\r
431         \r
432         void Refresh(Rectangle updateRect)\r
433         {\r
434             if (this.disposed)\r
435                 return;\r
436 \r
437             this.timer.Stop();\r
438 \r
439             this.Render.BegineDraw();\r
440             if (this.IsEnabled)\r
441                 this.View.Draw(updateRect);\r
442             else\r
443                 this.Render.FillBackground(updateRect);\r
444             this.Render.EndDraw();\r
445 \r
446             this.timer.Start();\r
447         }\r
448 \r
449         #region Commands\r
450         void CanExecute(object sender, CanExecuteRoutedEventArgs e)\r
451         {\r
452             e.CanExecute = this.IsEnabled;\r
453         }\r
454 \r
455         void ToggleCodePointCommand(object sender, RoutedEventArgs e)\r
456         {\r
457             if (!this._Controller.ConvertToChar())\r
458                 this._Controller.ConvertToCodePoint();\r
459             this.Refresh();\r
460         }\r
461 \r
462         void CopyCommand(object sender, RoutedEventArgs e)\r
463         {\r
464             this.Copy();\r
465         }\r
466 \r
467         void CutCommand(object sender, RoutedEventArgs e)\r
468         {\r
469             this.Cut();\r
470             this.Refresh();\r
471         }\r
472 \r
473         void PasteCommand(object sender, RoutedEventArgs e)\r
474         {\r
475             this.Paste();\r
476             this.Refresh();\r
477         }\r
478 \r
479         void DeleteCommand(object sender, RoutedEventArgs e)\r
480         {\r
481             int oldLength = this.Document.Length;\r
482             this._Controller.DoDeleteAction();\r
483             this.Refresh();\r
484         }\r
485 \r
486         void SelectAllCommand(object sender, RoutedEventArgs e)\r
487         {\r
488             this.Select(0, this.Document.Length);\r
489             this.Refresh();\r
490         }\r
491 \r
492         void UndoCommand(object sender, RoutedEventArgs e)\r
493         {\r
494             int oldLength = this.Document.Length;\r
495             this.Document.UndoManager.undo();\r
496             this.Refresh();\r
497         }\r
498 \r
499         void RedoCommand(object sender, RoutedEventArgs e)\r
500         {\r
501             int oldLength = this.Document.Length;\r
502             this.Document.UndoManager.redo();\r
503             this.Refresh();\r
504         }\r
505 \r
506         void ToggleInsertCommand(object sender, RoutedEventArgs e)\r
507         {\r
508             if (this.InsertMode)\r
509                 this.InsertMode = false;\r
510             else\r
511                 this.InsertMode = true;\r
512             this.Refresh();\r
513         }\r
514 \r
515         void ToggleRectSelectCommand(object sender, RoutedEventArgs e)\r
516         {\r
517             if (this.RectSelectMode)\r
518                 this.RectSelectMode = false;\r
519             else\r
520                 this.RectSelectMode = true;\r
521             this.Refresh();\r
522         }\r
523         void ToggleFlowDirectionCommand(object sender, RoutedEventArgs e)\r
524         {\r
525             if (this.FlowDirection == System.Windows.FlowDirection.LeftToRight)\r
526                 this.FlowDirection = System.Windows.FlowDirection.RightToLeft;\r
527             else\r
528                 this.FlowDirection = System.Windows.FlowDirection.LeftToRight;\r
529             this.Refresh();\r
530         }\r
531         #endregion\r
532         #region TSF\r
533         internal TextStore TextStore\r
534         {\r
535             get { return this.textStore; }\r
536         }\r
537 \r
538         double textStore_GetDpi()\r
539         {\r
540             float dpi;\r
541             this.Render.GetDpi(out dpi, out dpi);\r
542             return dpi;\r
543         }\r
544 \r
545         bool textStore_IsReadOnly()\r
546         {\r
547             return false;\r
548         }\r
549 \r
550         bool textStore_IsLoading()\r
551         {\r
552             return false;\r
553         }\r
554 \r
555         void textStore_CompositionEnded()\r
556         {\r
557             TextStoreHelper.EndCompostion(this.Document);\r
558             this.Refresh();\r
559         }\r
560 \r
561         void textStore_CompositionUpdated(int start, int end)\r
562         {\r
563             if (TextStoreHelper.ScrollToCompstionUpdated(this.textStore, this.View, start, end))\r
564                 this.Refresh();\r
565         }\r
566         bool textStore_CompositionStarted()\r
567         {\r
568             bool result = TextStoreHelper.StartCompstion(this.Document);\r
569             if (!result)\r
570                 System.Media.SystemSounds.Beep.Play();\r
571             return result;\r
572         }\r
573 \r
574         string _textStore_GetString(int start, int length)\r
575         {\r
576             return this.Document.ToString(start, length);\r
577         }\r
578 \r
579         IntPtr _textStore_GetHWnd()\r
580         {\r
581             var hwndSource = HwndSource.FromVisual(this) as HwndSource;\r
582             if (hwndSource != null)\r
583                 return hwndSource.Handle;\r
584             else\r
585                 return IntPtr.Zero;\r
586         }\r
587 \r
588         void _textStore_GetStringExtent(\r
589             int i_startIndex,\r
590             int i_endIndex,\r
591             out POINT o_topLeft,\r
592             out POINT o_bottomRight\r
593         )\r
594         {\r
595             Point startPos, endPos;\r
596             TextStoreHelper.GetStringExtent(this.Document, this.View, i_startIndex, i_endIndex, out startPos, out endPos);\r
597 \r
598             startPos = PointToScreen(this.TranslatePoint(startPos, this));\r
599             endPos = PointToScreen(this.TranslatePoint(endPos, this));\r
600             \r
601             o_topLeft = new POINT((int)startPos.X, (int)startPos.Y);\r
602             o_bottomRight = new POINT((int)endPos.X, (int)endPos.Y);\r
603         }\r
604 \r
605         void _textStore_GetScreenExtent(out POINT o_topLeft, out POINT o_bottomRight)\r
606         {\r
607             var pointTopLeft = new Point(0, 0);\r
608             var pointBottomRight = new Point(this.RenderSize.Width, this.RenderSize.Height);\r
609 \r
610             pointTopLeft = PointToScreen(pointTopLeft);\r
611             pointBottomRight = PointToScreen(pointBottomRight);\r
612 \r
613             o_topLeft = new POINT((int)pointTopLeft.X, (int)pointTopLeft.Y);\r
614             o_bottomRight = new POINT((int)pointBottomRight.X, (int)pointBottomRight.Y);\r
615         }\r
616 \r
617         void _textStore_GetSelectionIndex(out int o_startIndex, out int o_endIndex)\r
618         {\r
619             TextStoreHelper.GetSelection(this._Controller, this.View.Selections, out o_startIndex, out o_endIndex);\r
620         }\r
621 \r
622         void _textStore_SetSelectionIndex(int i_startIndex, int i_endIndex)\r
623         {\r
624             TextStoreHelper.SetSelectionIndex(this._Controller, this.View, i_startIndex, i_endIndex);\r
625             this.Refresh();\r
626         }\r
627 \r
628         void _textStore_InsertAtSelection(string i_value)\r
629         {\r
630             TextStoreHelper.InsertTextAtSelection(this._Controller, i_value);\r
631             this.Refresh();\r
632         }\r
633 \r
634         /// <summary>\r
635         /// キーボードフォーカスが取得されたときに呼ばれます\r
636         /// </summary>\r
637         /// <param name="e">イベントデーター</param>\r
638         protected override void OnGotKeyboardFocus(KeyboardFocusChangedEventArgs e)\r
639         {\r
640             base.OnGotKeyboardFocus(e);\r
641             this.textStore.SetFocus();\r
642             this.View.IsFocused = true;\r
643             this.Refresh();\r
644         }\r
645 \r
646         /// <summary>\r
647         /// キーボードフォーカスが失われたときに呼ばれます\r
648         /// </summary>\r
649         /// <param name="e">イベントデーター</param>\r
650         protected override void OnLostKeyboardFocus(KeyboardFocusChangedEventArgs e)\r
651         {\r
652             base.OnLostKeyboardFocus(e);\r
653             this.View.IsFocused = false;\r
654             this.Refresh();\r
655         }\r
656         #endregion\r
657         #region Event\r
658         /// <summary>\r
659         /// キャレットが移動したときに通知されるイベント\r
660         /// </summary>\r
661         public event EventHandler CaretMoved;\r
662 \r
663         /// <inheritdoc/>\r
664         protected override System.Windows.Automation.Peers.AutomationPeer OnCreateAutomationPeer()\r
665         {\r
666             this.peer = new FooTextBoxAutomationPeer(this);\r
667             return this.peer;\r
668         }\r
669 \r
670 \r
671         /// <inheritdoc/>\r
672         protected override void OnTextInput(TextCompositionEventArgs e)\r
673         {\r
674             if (e.Text == "\r")\r
675             {\r
676                 this._Controller.DoEnterAction();\r
677                 this.AutoIndentHooker(this, null);\r
678             }\r
679             else if (e.Text == "\b")\r
680             {\r
681                 this._Controller.DoBackSpaceAction();\r
682             }\r
683             else\r
684             {\r
685                 if(this.IsInputString(e.Text))\r
686                     this._Controller.DoInputString(e.Text);\r
687             }\r
688             this.Refresh();\r
689             base.OnTextInput(e);\r
690             e.Handled = true;\r
691         }\r
692 \r
693         bool IsInputString(string s)\r
694         {\r
695             foreach (char charCode in s)\r
696             {\r
697                 if ((0x20 <= charCode && charCode <= 0x7e)\r
698                     || 0x7f < charCode)\r
699                     return true;\r
700             }\r
701             return false;\r
702         }\r
703 \r
704         /// <inheritdoc/>\r
705         protected override void OnKeyDown(KeyEventArgs e)\r
706         {\r
707             if (this.textStore.IsLocked())\r
708                 return;\r
709 \r
710             ModifierKeys modiferKeys = e.KeyboardDevice.Modifiers;\r
711             bool movedCaret = false;\r
712             switch (e.Key)\r
713             {\r
714                 case Key.Up:\r
715                     this._Controller.MoveCaretVertical(-1, this.IsPressedModifierKey(modiferKeys, ModifierKeys.Shift));\r
716                     this.Refresh();\r
717                     e.Handled = true;\r
718                     movedCaret = true;\r
719                     break;\r
720                 case Key.Down:\r
721                     this._Controller.MoveCaretVertical(+1, this.IsPressedModifierKey(modiferKeys, ModifierKeys.Shift));\r
722                     this.Refresh();\r
723                     e.Handled = true;\r
724                     movedCaret = true;\r
725                     break;\r
726                 case Key.Left:\r
727                     this._Controller.MoveCaretHorizontical(-1, this.IsPressedModifierKey(modiferKeys, ModifierKeys.Shift), this.IsPressedModifierKey(modiferKeys, ModifierKeys.Control));\r
728                     this.Refresh();\r
729                     e.Handled = true;\r
730                     movedCaret = true;\r
731                     break;\r
732                 case Key.Right:\r
733                     this._Controller.MoveCaretHorizontical(1, this.IsPressedModifierKey(modiferKeys, ModifierKeys.Shift), this.IsPressedModifierKey(modiferKeys, ModifierKeys.Control));\r
734                     this.Refresh();\r
735                     e.Handled = true;\r
736                     movedCaret = true;\r
737                     break;\r
738                 case Key.PageUp:\r
739                     this._Controller.Scroll(ScrollDirection.Up,this.View.LineCountOnScreen, this.IsPressedModifierKey(modiferKeys, ModifierKeys.Shift),true);\r
740                     this.Refresh();\r
741                     movedCaret = true;\r
742                     break;\r
743                 case Key.PageDown:\r
744                     this._Controller.Scroll(ScrollDirection.Down,this.View.LineCountOnScreen, this.IsPressedModifierKey(modiferKeys, ModifierKeys.Shift),true);\r
745                     this.Refresh();\r
746                     movedCaret = true;\r
747                     break;\r
748                 case Key.Home:\r
749                     if (this.IsPressedModifierKey(modiferKeys, ModifierKeys.Control))\r
750                         this._Controller.JumpToHead(this.IsPressedModifierKey(modiferKeys, ModifierKeys.Shift));\r
751                     else\r
752                         this._Controller.JumpToLineHead(this.View.CaretPostion.row, this.IsPressedModifierKey(modiferKeys, ModifierKeys.Shift));\r
753                     this.Refresh();\r
754                     movedCaret = true;\r
755                     break;\r
756                 case Key.End:\r
757                     if (this.IsPressedModifierKey(modiferKeys, ModifierKeys.Control))\r
758                         this._Controller.JumpToEnd(this.IsPressedModifierKey(modiferKeys, ModifierKeys.Shift));\r
759                     else\r
760                         this._Controller.JumpToLineEnd(this.View.CaretPostion.row, this.IsPressedModifierKey(modiferKeys, ModifierKeys.Shift));\r
761                     this.Refresh();\r
762                     movedCaret = true;\r
763                     break;\r
764                 case Key.Tab:\r
765                     int oldLength = this.Document.Length;\r
766                     if (this.Selection.Length == 0)\r
767                         this._Controller.DoInputChar('\t');\r
768                     else if(this.IsPressedModifierKey(modiferKeys,ModifierKeys.Shift))\r
769                         this._Controller.DownIndent();\r
770                     else\r
771                         this._Controller.UpIndent();\r
772                     this.Refresh();\r
773                     e.Handled = true;\r
774                     break;\r
775             }\r
776             if (movedCaret && this.peer != null)\r
777                 this.peer.OnNotifyCaretChanged();\r
778             base.OnKeyDown(e);\r
779         }\r
780 \r
781         bool IsPressedModifierKey(ModifierKeys keys, ModifierKeys pressed)\r
782         {\r
783             if (keys == pressed)\r
784                 return true;\r
785             if ((keys & pressed) == pressed)\r
786                 return true;\r
787             return false;\r
788         }\r
789 \r
790         /// <summary>\r
791         /// ダブルクリックされたときに呼ばれます\r
792         /// </summary>\r
793         /// <param name="e">イベントパラメーター</param>\r
794         /// <remarks>\r
795         /// イベントパラメーターはFooMouseEventArgsにキャスト可能です。\r
796         /// e.Handledを真にした場合、単語単位の選択が行われなくなります\r
797         /// </remarks>\r
798         protected override void OnMouseDoubleClick(MouseButtonEventArgs e)\r
799         {\r
800             System.Windows.Point p = e.GetPosition(this);\r
801             TextPoint tp = this.View.GetTextPointFromPostion(p);\r
802             if (tp == TextPoint.Null)\r
803                 return;\r
804             int index = this.View.LayoutLines.GetIndexFromTextPoint(tp);\r
805 \r
806             FooMouseButtonEventArgs newEventArgs = new FooMouseButtonEventArgs(e.MouseDevice,\r
807                 e.Timestamp,\r
808                 e.ChangedButton,\r
809                 e.StylusDevice,\r
810                 index);\r
811             newEventArgs.RoutedEvent = e.RoutedEvent;\r
812             base.OnMouseDoubleClick(newEventArgs);\r
813 \r
814             if (newEventArgs.Handled)\r
815                 return;\r
816 \r
817             if (e.LeftButton == MouseButtonState.Pressed)\r
818             {\r
819 \r
820                 this._Controller.SelectWord(index);\r
821                 this.textStore.NotifySelectionChanged();\r
822                 if(this.peer != null)\r
823                     this.peer.OnNotifyCaretChanged();\r
824                 this.Refresh();\r
825             }\r
826         }\r
827 \r
828         /// <summary>\r
829         /// マウスボタンが押されたときに呼ばれます\r
830         /// </summary>\r
831         /// <param name="e">イベントパラメーター</param>\r
832         /// <remarks>\r
833         /// イベントパラメーターはFooMouseEventArgsにキャスト可能です。\r
834         /// e.Handledを真にした場合、キャレットの移動処理が行われなくなります\r
835         /// </remarks>\r
836         protected override void OnMouseDown(MouseButtonEventArgs e)\r
837         {\r
838             System.Windows.Point p = e.GetPosition(this);\r
839             TextPoint tp = this.View.GetTextPointFromPostion(p);\r
840             if (tp == TextPoint.Null)\r
841                 return;\r
842             int index = this.View.LayoutLines.GetIndexFromTextPoint(tp);\r
843 \r
844             FooMouseButtonEventArgs newEventArgs = new FooMouseButtonEventArgs(e.MouseDevice,\r
845                 e.Timestamp,\r
846                 e.ChangedButton,\r
847                 e.StylusDevice,\r
848                 index);\r
849             newEventArgs.RoutedEvent = e.RoutedEvent;\r
850             base.OnMouseDown(newEventArgs);\r
851 \r
852             if (newEventArgs.Handled)\r
853                 return;\r
854 \r
855             if (e.LeftButton == MouseButtonState.Pressed)\r
856             {\r
857                 FoldingItem foldingData = this.View.HitFoldingData(p.X,tp.row);\r
858                 if (foldingData != null)\r
859                 {\r
860                     if (foldingData.Expand)\r
861                         this.View.LayoutLines.FoldingCollection.Collapse(foldingData);\r
862                     else\r
863                         this.View.LayoutLines.FoldingCollection.Expand(foldingData);\r
864                     this._Controller.JumpCaret(foldingData.Start,false);\r
865                 }\r
866                 else\r
867                 {\r
868                     this._Controller.JumpCaret(tp.row, tp.col, false);\r
869                 }\r
870                 if (this.peer != null)\r
871                     this.peer.OnNotifyCaretChanged();\r
872                 this.View.IsFocused = true;\r
873                 this.Focus();\r
874                 this.Refresh();\r
875             }\r
876         }\r
877 \r
878         /// <summary>\r
879         /// マウスが移動したときに呼ばれます\r
880         /// </summary>\r
881         /// <param name="e">イベントパラメーター</param>\r
882         /// <remarks>\r
883         /// イベントパラメーターはFooMouseEventArgsにキャスト可能です。\r
884         /// e.Handledを真にした場合、選択処理と状況に応じたカーソルの変化が行われなくなります\r
885         /// </remarks>\r
886         protected override void  OnMouseMove(MouseEventArgs e)\r
887         {\r
888             System.Windows.Point p = e.GetPosition(this);\r
889             TextPoint tp = this.View.GetTextPointFromPostion(p);\r
890             if (tp == TextPoint.Null)\r
891             {\r
892                 base.OnMouseMove(e);\r
893                 return;\r
894             }\r
895             int index = this.View.GetIndexFromLayoutLine(tp);\r
896 \r
897             FooMouseEventArgs newEventArgs = new FooMouseEventArgs(e.MouseDevice, e.Timestamp, e.StylusDevice, index);\r
898             newEventArgs.RoutedEvent = e.RoutedEvent;\r
899             base.OnMouseMove(newEventArgs);\r
900 \r
901             if (newEventArgs.Handled)\r
902                 return;\r
903 \r
904             if (this.View.HitTextArea(p.X,p.Y))\r
905             {\r
906                 if (this._Controller.IsMarker(tp, HilightType.Url))\r
907                     this.Cursor = Cursors.Hand;\r
908                 else\r
909                     this.Cursor = Cursors.IBeam;\r
910 \r
911                 if (e.LeftButton == MouseButtonState.Pressed)\r
912                 {\r
913                     this._Controller.MoveCaretAndSelect(tp);\r
914                     if (this.peer != null)\r
915                         this.peer.OnNotifyCaretChanged();\r
916                     this.Refresh();\r
917                 }\r
918             }\r
919             else\r
920             {\r
921                 this.Cursor = Cursors.Arrow;\r
922             }\r
923         }\r
924 \r
925         /// <inheritdoc/>\r
926         protected override void OnMouseWheel(MouseWheelEventArgs e)\r
927         {\r
928             if(Keyboard.Modifiers == ModifierKeys.None)\r
929             {\r
930                 if (e.Delta > 0)\r
931                     this._Controller.Scroll(ScrollDirection.Up, SystemParameters.WheelScrollLines, false, false);\r
932                 else\r
933                     this._Controller.Scroll(ScrollDirection.Down, SystemParameters.WheelScrollLines, false, false);\r
934             }\r
935             else if (Keyboard.Modifiers == ModifierKeys.Control)\r
936             {\r
937                 double newFontSize = this.Render.FontSize;\r
938                 if (e.Delta > 0)\r
939                     newFontSize++;\r
940                 else\r
941                     newFontSize--;\r
942                 if (newFontSize > MaxFontSize)\r
943                     newFontSize = 72;\r
944                 else if (newFontSize < MinFontSize)\r
945                     newFontSize = 1;\r
946                 this.Render.FontSize = newFontSize;\r
947                 SetValue(MagnificationPowerPropertyKey, this.Render.FontSize / this.FontSize);\r
948             }\r
949             this.Refresh();\r
950             base.OnMouseWheel(e);\r
951         }\r
952 \r
953         void SystemEvents_UserPreferenceChanged(object sender, UserPreferenceChangedEventArgs e)\r
954         {\r
955             if (e.Category == UserPreferenceCategory.Keyboard)\r
956             {\r
957                 int blinkTime = (int)NativeMethods.GetCaretBlinkTime();\r
958                 this.View.CaretBlink = blinkTime >= 0;\r
959                 this.View.CaretBlinkTime = blinkTime * 2;\r
960             }\r
961             if (e.Category == UserPreferenceCategory.General)\r
962             {\r
963                 this.View.CaretWidthOnInsertMode = SystemParameters.CaretWidth;\r
964             }\r
965         }\r
966 \r
967         void Document_Update(object sender, DocumentUpdateEventArgs e)\r
968         {\r
969             if (this.textStore.IsLocked())\r
970                 return;\r
971             TextStoreHelper.NotifyTextChanged(this.textStore, e.startIndex, e.removeLength, e.insertLength);\r
972         }\r
973 \r
974         void timer_Tick(object sender, EventArgs e)\r
975         {\r
976             if (this.image.ActualWidth == 0 || this.image.ActualHeight == 0)\r
977                 return;\r
978             if (this.Resize(this.image.ActualWidth, this.image.ActualHeight))\r
979             {\r
980                 this.Refresh();\r
981                 return;\r
982             } \r
983             \r
984             ITextLayout layout = this.View.LayoutLines.GetLayout(this.View.CaretPostion.row);\r
985             double width = layout.GetWidthFromIndex(this.View.CaretPostion.col);\r
986             if (width == 0.0)\r
987                 width = this.View.CaretWidthOnInsertMode;\r
988             double height = layout.Height;\r
989             Rectangle updateRect = new Rectangle(\r
990                 this.View.CaretLocation.X,\r
991                 this.View.CaretLocation.Y,\r
992                 width,\r
993                 height);\r
994 \r
995             this.Refresh(updateRect);\r
996         }\r
997 \r
998         void horizontalScrollBar_Scroll(object sender, ScrollEventArgs e)\r
999         {\r
1000             if (this.horizontalScrollBar == null)\r
1001                 return;\r
1002             double toX;\r
1003             if (this.FlowDirection == System.Windows.FlowDirection.LeftToRight)\r
1004                 toX = this.horizontalScrollBar.Value;\r
1005             else\r
1006                 toX = -this.horizontalScrollBar.Value;\r
1007             this._Controller.Scroll(toX, this.View.Src.Row, false, false);\r
1008             this.Refresh();\r
1009         }\r
1010 \r
1011         void verticalScrollBar_Scroll(object sender, ScrollEventArgs e)\r
1012         {\r
1013             if (this.verticalScrollBar == null)\r
1014                 return;\r
1015             int newRow = (int)this.verticalScrollBar.Value;\r
1016             if (newRow >= this.View.LayoutLines.Count)\r
1017                 return;\r
1018             this._Controller.Scroll(this.View.Src.X,newRow, false, false);\r
1019             this.Refresh();\r
1020         }\r
1021 \r
1022         void View_SrcChanged(object sender, EventArgs e)\r
1023         {\r
1024             if (this.horizontalScrollBar == null || this.verticalScrollBar == null)\r
1025                 return;\r
1026             EditView view = this.View;\r
1027             if (view.Src.Row > this.verticalScrollBar.Maximum)\r
1028                 this.verticalScrollBar.Maximum = view.Src.Row + view.LineCountOnScreen + 1;\r
1029             double absoulteX = Math.Abs(view.Src.X);\r
1030             if(absoulteX > this.horizontalScrollBar.Maximum)\r
1031                 this.horizontalScrollBar.Maximum = absoulteX + view.PageBound.Width + 1;\r
1032             if(view.Src.Row != this.verticalScrollBar.Value)\r
1033                 this.verticalScrollBar.Value = view.Src.Row;\r
1034             if (view.Src.X != this.horizontalScrollBar.Value)\r
1035                 this.horizontalScrollBar.Value = Math.Abs(view.Src.X);\r
1036         }\r
1037 \r
1038         void Controller_SelectionChanged(object sender, EventArgs e)\r
1039         {\r
1040             this.View.CaretBlink = this.View.CaretBlink;\r
1041             this.CaretMoved(this, null);\r
1042             //こうしないと選択できなくなってしまう\r
1043             this.nowCaretMove = true;\r
1044             SetValue(SelectionProperty, new TextRange(this._Controller.SelectionStart, this._Controller.SelectionLength));\r
1045             SetValue(CaretPostionProperty, this.View.CaretPostion);\r
1046             this.nowCaretMove = false;            \r
1047             if(this.textStore.IsLocked() == false)\r
1048                 this.textStore.NotifySelectionChanged();\r
1049         }\r
1050 \r
1051         void FooTextBox_Loaded(object sender, RoutedEventArgs e)\r
1052         {\r
1053             this.Resize(this.image.ActualWidth, this.image.ActualHeight);\r
1054         }\r
1055 \r
1056         bool Resize(double width, double height)\r
1057         {\r
1058             if (width == 0 || height == 0)\r
1059                 throw new ArgumentOutOfRangeException();\r
1060             if (this.Render.Resize(width, height))\r
1061             {\r
1062                 this.View.PageBound = new Rectangle(0, 0, width, height);\r
1063 \r
1064                 if (this.horizontalScrollBar != null)\r
1065                 {\r
1066                     this.horizontalScrollBar.LargeChange = this.View.PageBound.Width;\r
1067                     this.horizontalScrollBar.Maximum = this.View.LongestWidth + this.horizontalScrollBar.LargeChange + 1;\r
1068                 }\r
1069                 if (this.verticalScrollBar != null)\r
1070                 {\r
1071                     this.verticalScrollBar.LargeChange = this.View.LineCountOnScreen;\r
1072                     this.verticalScrollBar.Maximum = this.View.LayoutLines.Count + this.verticalScrollBar.LargeChange + 1;\r
1073                 }\r
1074                 return true;\r
1075             }\r
1076             return false;\r
1077         }\r
1078 \r
1079         /// <summary>\r
1080         /// プロパティーが変更されたときに呼ばれます\r
1081         /// </summary>\r
1082         /// <param name="e">イベントパラメーター</param>\r
1083         protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e)\r
1084         {\r
1085             switch (e.Property.Name)\r
1086             {\r
1087                 case "Selection":\r
1088                     if(!this.nowCaretMove)\r
1089                         this.Select(this.Selection.Index, this.Selection.Length);\r
1090                     break;\r
1091                 case "CaretPostion":\r
1092                     if (!this.nowCaretMove)\r
1093                         this.JumpCaret(this.CaretPostion.row, this.CaretPostion.col);\r
1094                     break;\r
1095                 case "LineBreakMethod":\r
1096                     this.View.LineBreak = this.LineBreakMethod;\r
1097                     break;\r
1098                 case "LineBreakCharCount":\r
1099                     this.View.LineBreakCharCount = this.LineBreakCharCount;\r
1100                     break;\r
1101                 case "InsertMode":\r
1102                     this.View.InsertMode = this.InsertMode;\r
1103                     break;\r
1104                 case "TabChars":\r
1105                     this.View.TabStops = this.TabChars;\r
1106                     break;\r
1107                 case "RectSelectMode":\r
1108                     this._Controller.RectSelection = this.RectSelectMode;\r
1109                     break;\r
1110                 case "DrawCaret":\r
1111                     this.View.HideCaret = !this.DrawCaret;\r
1112                     break;\r
1113                 case "DrawCaretLine":\r
1114                     this.View.HideLineMarker = !this.DrawCaretLine;\r
1115                     break;\r
1116                 case "DrawLineNumber":\r
1117                     this.View.DrawLineNumber = this.DrawLineNumber;\r
1118                     this._Controller.JumpCaret(this.View.CaretPostion.row, this.View.CaretPostion.col);\r
1119                     break;\r
1120                 case "FontFamily":\r
1121                     this.Render.FontFamily = this.FontFamily;\r
1122                     break;\r
1123                 case "FontSize":\r
1124                     this.Render.FontSize = this.FontSize;\r
1125                     break;\r
1126                 case "FontStyle":\r
1127                     this.Render.FontStyle = this.FontStyle;\r
1128                     break;\r
1129                 case "FontWeight":\r
1130                     this.Render.FontWeigth = this.FontWeight;\r
1131                     break;\r
1132                 case "Foreground":\r
1133                     this.Render.Foreground = D2DRender.ToColor4(this.Foreground);\r
1134                     break;\r
1135                 case "Background":\r
1136                     this.Render.Background = D2DRender.ToColor4(this.Background);\r
1137                     break;\r
1138                 case "ControlChar":\r
1139                     this.Render.ControlChar =D2DRender.ToColor4( this.ControlChar);\r
1140                     break;\r
1141                 case "Hilight":\r
1142                     this.Render.Hilight = D2DRender.ToColor4(this.Hilight);\r
1143                     break;\r
1144                 case "Keyword1":\r
1145                     this.Render.Keyword1 = D2DRender.ToColor4(this.Keyword1);\r
1146                     break;\r
1147                 case "Keyword2":\r
1148                     this.Render.Keyword2 = D2DRender.ToColor4(this.Keyword2);\r
1149                     break;\r
1150                 case "Comment":\r
1151                     this.Render.Comment = D2DRender.ToColor4(this.Comment);\r
1152                     break;\r
1153                 case "Literal":\r
1154                     this.Render.Literal = D2DRender.ToColor4(this.Literal);\r
1155                     break;\r
1156                 case "URL":\r
1157                     this.Render.Url = D2DRender.ToColor4(this.URL);\r
1158                     break;\r
1159                 case "InsertCaret":\r
1160                     this.Render.InsertCaret = D2DRender.ToColor4(this.InsertCaret);\r
1161                     break;\r
1162                 case "OverwriteCaret":\r
1163                     this.Render.OverwriteCaret = D2DRender.ToColor4(this.OverwriteCaret);\r
1164                     break;\r
1165                 case "Padding":\r
1166                     this.View.Padding = new Padding((int)this.Padding.Left, (int)this.Padding.Top, (int)this.Padding.Right, (int)this.Padding.Bottom);\r
1167                     break;\r
1168                 case "LineMarker":\r
1169                     this.Render.LineMarker = D2DRender.ToColor4(this.LineMarker);\r
1170                     break;\r
1171                 case "MarkURL":\r
1172                     this.View.UrlMark = this.MarkURL;\r
1173                     break;\r
1174                 case "ShowFullSpace":\r
1175                     this.Render.ShowFullSpace = this.ShowFullSpace;\r
1176                     break;\r
1177                 case "ShowHalfSpace":\r
1178                     this.Render.ShowHalfSpace = this.ShowHalfSpace;\r
1179                     break;\r
1180                 case "ShowTab":\r
1181                     this.Render.ShowTab = this.ShowTab;\r
1182                     break;\r
1183                 case "ShowLineBreak":\r
1184                     this.Render.ShowLineBreak = this.ShowLineBreak;\r
1185                     break;\r
1186                 case "FlowDirection":\r
1187                     this.Render.RightToLeft = this.FlowDirection == System.Windows.FlowDirection.RightToLeft;\r
1188                     this.horizontalScrollBar.FlowDirection = this.FlowDirection;\r
1189                     break;\r
1190                 case "DrawRuler":\r
1191                     this.View.HideRuler = !this.DrawRuler;\r
1192                     this._Controller.JumpCaret(this.View.CaretPostion.row, this.View.CaretPostion.col);\r
1193                     break;\r
1194                 case "UpdateArea":\r
1195                     this.Render.UpdateArea = D2DRender.ToColor4(this.UpdateArea);\r
1196                     break;\r
1197             }\r
1198             base.OnPropertyChanged(e);\r
1199         }\r
1200         #endregion\r
1201         #region property\r
1202 \r
1203         internal Controller Controller\r
1204         {\r
1205             get\r
1206             {\r
1207                 return this._Controller;\r
1208             }\r
1209         }\r
1210 \r
1211         /// <summary>\r
1212         /// 文字列の描写に使用されるアンチエイリアシング モードを表します\r
1213         /// </summary>\r
1214         public TextAntialiasMode TextAntialiasMode\r
1215         {\r
1216             get\r
1217             {\r
1218                 return this.Render.TextAntialiasMode;\r
1219             }\r
1220             set\r
1221             {\r
1222                 this.Render.TextAntialiasMode = value;\r
1223             }\r
1224         }\r
1225 \r
1226         /// <summary>\r
1227         /// シンタックスハイライターを表す\r
1228         /// </summary>\r
1229         public IHilighter Hilighter\r
1230         {\r
1231             get\r
1232             {\r
1233                 return this.View.Hilighter;\r
1234             }\r
1235             set\r
1236             {\r
1237                 this.View.Hilighter = value;\r
1238                 this.View.LayoutLines.ClearLayoutCache();\r
1239             }\r
1240         }\r
1241 \r
1242         /// <summary>\r
1243         /// フォールティングを作成するインターフェイスを表す\r
1244         /// </summary>\r
1245         public IFoldingStrategy FoldingStrategy\r
1246         {\r
1247             get\r
1248             {\r
1249                 return this.View.LayoutLines.FoldingStrategy;\r
1250             }\r
1251             set\r
1252             {\r
1253                 this.View.LayoutLines.FoldingStrategy = value;\r
1254                 if (value == null)\r
1255                     this.View.LayoutLines.FoldingCollection.Clear();\r
1256             }\r
1257         }\r
1258 \r
1259         /// <summary>\r
1260         /// マーカーパターンセット\r
1261         /// </summary>\r
1262         public MarkerPatternSet MarkerPatternSet\r
1263         {\r
1264             get\r
1265             {\r
1266                 return this.View.MarkerPatternSet;\r
1267             }\r
1268         }\r
1269 \r
1270         /// <summary>\r
1271         /// ドキュメントを表す\r
1272         /// </summary>\r
1273         public Document Document\r
1274         {\r
1275             get;\r
1276             private set;\r
1277         }\r
1278 \r
1279         /// <summary>\r
1280         /// レイアウト行を表す\r
1281         /// </summary>\r
1282         public LineToIndexTable LayoutLineCollection\r
1283         {\r
1284             get { return this.View.LayoutLines; }\r
1285         }\r
1286 \r
1287         /// <summary>\r
1288         /// 選択中の文字列を表す\r
1289         /// </summary>\r
1290         public string SelectedText\r
1291         {\r
1292             get\r
1293             {\r
1294                 return this._Controller.SelectedText;\r
1295             }\r
1296             set\r
1297             {\r
1298                 int oldLength = this.Document.Length;\r
1299                 this._Controller.SelectedText = value;\r
1300             }\r
1301         }\r
1302 \r
1303         /// <summary>\r
1304         /// 選択範囲を表す\r
1305         /// </summary>\r
1306         /// <remarks>\r
1307         /// Lengthが0の場合はキャレット位置を表します。\r
1308         /// 矩形選択モードの場合、選択範囲の文字数ではなく、開始位置から終了位置までの長さとなります\r
1309         /// </remarks>\r
1310         public TextRange Selection\r
1311         {\r
1312             get { return (TextRange)GetValue(SelectionProperty); }\r
1313             set { SetValue(SelectionProperty, value); }\r
1314         }\r
1315 \r
1316         /// <summary>\r
1317         /// Selectionの依存プロパティを表す\r
1318         /// </summary>\r
1319         public static readonly DependencyProperty SelectionProperty =\r
1320             DependencyProperty.Register("Selection", typeof(TextRange), typeof(FooTextBox), new PropertyMetadata(TextRange.Null));\r
1321 \r
1322         /// <summary>\r
1323         /// 拡大率を表す\r
1324         /// </summary>\r
1325         public double MagnificationPower\r
1326         {\r
1327             get { return (double)GetValue(MagnificationPowerPropertyKey.DependencyProperty); }\r
1328         }\r
1329 \r
1330         /// <summary>\r
1331         /// 拡大率を表す依存プロパティ\r
1332         /// </summary>\r
1333         public static readonly DependencyPropertyKey MagnificationPowerPropertyKey =\r
1334             DependencyProperty.RegisterReadOnly("MagnificationPower", typeof(double), typeof(FooTextBox), new PropertyMetadata(1.0));\r
1335 \r
1336         /// <summary>\r
1337         /// レタリング方向を表す\r
1338         /// </summary>\r
1339         public new FlowDirection FlowDirection\r
1340         {\r
1341             get { return (FlowDirection)GetValue(FlowDirectionProperty); }\r
1342             set { SetValue(FlowDirectionProperty, value); }\r
1343         }\r
1344 \r
1345         /// <summary>\r
1346         /// レタリング方向を表す。これは依存プロパティです\r
1347         /// </summary>\r
1348         public new static readonly DependencyProperty FlowDirectionProperty =\r
1349             DependencyProperty.Register("FlowDirection", typeof(FlowDirection), typeof(FooTextBox), new PropertyMetadata(FlowDirection.LeftToRight));        \r
1350 \r
1351         /// <summary>\r
1352         /// キャレット位置を表す。これは依存プロパティです\r
1353         /// </summary>\r
1354         public TextPoint CaretPostion\r
1355         {\r
1356             get { return (TextPoint)GetValue(CaretPostionProperty); }\r
1357             set { SetValue(CaretPostionProperty, value); }\r
1358         }\r
1359 \r
1360         /// <summary>\r
1361         /// CaretPostionの依存プロパティを表す\r
1362         /// </summary>\r
1363         public static readonly DependencyProperty CaretPostionProperty =\r
1364             DependencyProperty.Register("CaretPostion", typeof(TextPoint), typeof(FooTextBox), new PropertyMetadata(TextPoint.Null));\r
1365         \r
1366         /// <summary>\r
1367         /// デフォルトの文字色を表す。これは依存プロパティです\r
1368         /// </summary>\r
1369         public new System.Windows.Media.Color Foreground\r
1370         {\r
1371             get { return (System.Windows.Media.Color)GetValue(ForegroundProperty); }\r
1372             set { SetValue(ForegroundProperty, value); }\r
1373         }\r
1374 \r
1375         /// <summary>\r
1376         /// Foregroundの依存プロパティを表す\r
1377         /// </summary>\r
1378         public new static readonly DependencyProperty ForegroundProperty =\r
1379             DependencyProperty.Register("Foreground", typeof(System.Windows.Media.Color), typeof(FooTextBox), new FrameworkPropertyMetadata(SystemColors.WindowTextColor));\r
1380 \r
1381         /// <summary>\r
1382         /// 背景色を表す。これは依存プロパティです\r
1383         /// </summary>\r
1384         public new System.Windows.Media.Color Background\r
1385         {\r
1386             get { return (System.Windows.Media.Color)GetValue(BackgroundProperty); }\r
1387             set { SetValue(BackgroundProperty, value); }\r
1388         }\r
1389 \r
1390         /// <summary>\r
1391         /// Backgroundの依存プロパティを表す\r
1392         /// </summary>\r
1393         public new static readonly DependencyProperty BackgroundProperty =\r
1394             DependencyProperty.Register("Background", typeof(System.Windows.Media.Color), typeof(FooTextBox), new FrameworkPropertyMetadata(SystemColors.WindowColor));\r
1395         \r
1396         /// <summary>\r
1397         /// コントロールコードの文字色を表す。これは依存プロパティです\r
1398         /// </summary>\r
1399         public System.Windows.Media.Color ControlChar\r
1400         {\r
1401             get { return (System.Windows.Media.Color)GetValue(ControlCharProperty); }\r
1402             set { SetValue(ControlCharProperty, value); }\r
1403         }\r
1404 \r
1405         /// <summary>\r
1406         /// ControlCharの依存プロパティを表す\r
1407         /// </summary>\r
1408         public static readonly DependencyProperty ControlCharProperty =\r
1409             DependencyProperty.Register("ControlChar", typeof(System.Windows.Media.Color), typeof(FooTextBox), new FrameworkPropertyMetadata(Colors.Gray));\r
1410         \r
1411         /// <summary>\r
1412         /// 選択時の背景色を表す。これは依存プロパティです\r
1413         /// </summary>\r
1414         public System.Windows.Media.Color Hilight\r
1415         {\r
1416             get { return (System.Windows.Media.Color)GetValue(HilightProperty); }\r
1417             set { SetValue(HilightProperty, value); }\r
1418         }\r
1419 \r
1420         /// <summary>\r
1421         /// Hilightの依存プロパティを表す\r
1422         /// </summary>\r
1423         public static readonly DependencyProperty HilightProperty =\r
1424             DependencyProperty.Register("Hilight", typeof(System.Windows.Media.Color), typeof(FooTextBox), new FrameworkPropertyMetadata(Colors.DeepSkyBlue));\r
1425         \r
1426         /// <summary>\r
1427         /// キーワード1の文字色を表す。これは依存プロパティです\r
1428         /// </summary>\r
1429         public System.Windows.Media.Color Keyword1\r
1430         {\r
1431             get { return (System.Windows.Media.Color)GetValue(Keyword1Property); }\r
1432             set { SetValue(Keyword1Property, value); }\r
1433         }\r
1434 \r
1435         /// <summary>\r
1436         /// Keyword1の依存プロパティを表す\r
1437         /// </summary>\r
1438         public static readonly DependencyProperty Keyword1Property =\r
1439             DependencyProperty.Register("Keyword1", typeof(System.Windows.Media.Color), typeof(FooTextBox), new FrameworkPropertyMetadata(Colors.Blue));\r
1440 \r
1441         /// <summary>\r
1442         /// キーワード2の文字色を表す。これは依存プロパティです\r
1443         /// </summary>\r
1444         public System.Windows.Media.Color Keyword2\r
1445         {\r
1446             get { return (System.Windows.Media.Color)GetValue(Keyword2Property); }\r
1447             set { SetValue(Keyword2Property, value); }\r
1448         }\r
1449 \r
1450         /// <summary>\r
1451         /// Keyword2の依存プロパティを表す\r
1452         /// </summary>\r
1453         public static readonly DependencyProperty Keyword2Property =\r
1454             DependencyProperty.Register("Keyword2", typeof(System.Windows.Media.Color), typeof(FooTextBox), new FrameworkPropertyMetadata(Colors.DarkCyan));\r
1455 \r
1456         /// <summary>\r
1457         /// コメントの文字色を表す。これは依存プロパティです\r
1458         /// </summary>\r
1459         public System.Windows.Media.Color Comment\r
1460         {\r
1461             get { return (System.Windows.Media.Color)GetValue(CommentProperty); }\r
1462             set { SetValue(CommentProperty, value); }\r
1463         }\r
1464 \r
1465         /// <summary>\r
1466         /// Commentの依存プロパティを表す\r
1467         /// </summary>\r
1468         public static readonly DependencyProperty CommentProperty =\r
1469             DependencyProperty.Register("Comment", typeof(System.Windows.Media.Color), typeof(FooTextBox), new FrameworkPropertyMetadata(Colors.Green));\r
1470 \r
1471         /// <summary>\r
1472         /// 文字リテラルの文字色を表す。これは依存プロパティです\r
1473         /// </summary>\r
1474         public System.Windows.Media.Color Literal\r
1475         {\r
1476             get { return (System.Windows.Media.Color)GetValue(LiteralProperty); }\r
1477             set { SetValue(LiteralProperty, value); }\r
1478         }\r
1479 \r
1480         /// <summary>\r
1481         /// Literalの依存プロパティを表す\r
1482         /// </summary>\r
1483         public static readonly DependencyProperty LiteralProperty =\r
1484             DependencyProperty.Register("Literal", typeof(System.Windows.Media.Color), typeof(FooTextBox), new FrameworkPropertyMetadata(Colors.Brown));\r
1485 \r
1486         /// <summary>\r
1487         /// URLの文字色を表す。これは依存プロパティです\r
1488         /// </summary>\r
1489         public System.Windows.Media.Color URL\r
1490         {\r
1491             get { return (System.Windows.Media.Color)GetValue(URLProperty); }\r
1492             set { SetValue(URLProperty, value); }\r
1493         }\r
1494 \r
1495         /// <summary>\r
1496         /// URLの依存プロパティを表す\r
1497         /// </summary>\r
1498         public static readonly DependencyProperty URLProperty =\r
1499             DependencyProperty.Register("URL", typeof(System.Windows.Media.Color), typeof(FooTextBox), new FrameworkPropertyMetadata(Colors.Blue));\r
1500 \r
1501 \r
1502         /// <summary>\r
1503         /// ラインマーカーの色を表す\r
1504         /// </summary>\r
1505         public System.Windows.Media.Color LineMarker\r
1506         {\r
1507             get { return (System.Windows.Media.Color)GetValue(LineMarkerProperty); }\r
1508             set { SetValue(LineMarkerProperty, value); }\r
1509         }\r
1510 \r
1511         /// <summary>\r
1512         /// LineMarkerの依存プロパティを表す\r
1513         /// </summary>\r
1514         public static readonly DependencyProperty LineMarkerProperty =\r
1515             DependencyProperty.Register("LineMarker", typeof(System.Windows.Media.Color), typeof(FooTextBox), new FrameworkPropertyMetadata(Colors.Silver));\r
1516 \r
1517         /// <summary>\r
1518         /// 挿入モード時のキャレットの色を表す\r
1519         /// </summary>\r
1520         public System.Windows.Media.Color InsertCaret\r
1521         {\r
1522             get { return (System.Windows.Media.Color)GetValue(InsertCaretProperty); }\r
1523             set { SetValue(InsertCaretProperty, value); }\r
1524         }\r
1525 \r
1526         /// <summary>\r
1527         /// InsertCaretの依存プロパティを表す\r
1528         /// </summary>\r
1529         public static readonly DependencyProperty InsertCaretProperty =\r
1530             DependencyProperty.Register("InsertCaret", typeof(System.Windows.Media.Color), typeof(FooTextBox), new FrameworkPropertyMetadata(SystemColors.WindowTextColor));\r
1531 \r
1532         /// <summary>\r
1533         /// 行更新フラグの色を表す\r
1534         /// </summary>\r
1535         public System.Windows.Media.Color UpdateArea\r
1536         {\r
1537             get { return (System.Windows.Media.Color)GetValue(UpdateAreaProperty); }\r
1538             set { SetValue(UpdateAreaProperty, value); }\r
1539         }\r
1540 \r
1541         /// <summary>\r
1542         /// UpdateAreaの依存プロパティを表す\r
1543         /// </summary>\r
1544         public static readonly DependencyProperty UpdateAreaProperty =\r
1545             DependencyProperty.Register("UpdateArea", typeof(System.Windows.Media.Color), typeof(FooTextBox), new PropertyMetadata(Colors.MediumSeaGreen));        \r
1546 \r
1547         /// <summary>\r
1548         /// 上書きモード時のキャレット職を表す\r
1549         /// </summary>\r
1550         public System.Windows.Media.Color OverwriteCaret\r
1551         {\r
1552             get { return (System.Windows.Media.Color)GetValue(OverwriteCaretProperty); }\r
1553             set { SetValue(OverwriteCaretProperty, value); }\r
1554         }\r
1555 \r
1556         /// <summary>\r
1557         /// OverwriteCaretの依存プロパティを表す\r
1558         /// </summary>\r
1559         public static readonly DependencyProperty OverwriteCaretProperty =\r
1560             DependencyProperty.Register("OverwriteCaret", typeof(System.Windows.Media.Color), typeof(FooTextBox), new FrameworkPropertyMetadata(SystemColors.WindowTextColor));\r
1561         \r
1562         /// <summary>\r
1563         /// 挿入モードなら真を返し、そうでないなら、偽を返す。これは依存プロパティです\r
1564         /// </summary>\r
1565         public bool InsertMode\r
1566         {\r
1567             get { return (bool)GetValue(InsertModeProperty); }\r
1568             set { SetValue(InsertModeProperty, value); }\r
1569         }\r
1570 \r
1571         /// <summary>\r
1572         /// InsertModeの依存プロパティを表す\r
1573         /// </summary>\r
1574         public static readonly DependencyProperty InsertModeProperty =\r
1575             DependencyProperty.Register("InsertMode",\r
1576             typeof(bool),\r
1577             typeof(FooTextBox),\r
1578             new FrameworkPropertyMetadata(true));\r
1579 \r
1580         /// <summary>\r
1581         /// タブの文字数を表す。これは依存プロパティです\r
1582         /// </summary>\r
1583         public int TabChars\r
1584         {\r
1585             get { return (int)GetValue(TabCharsProperty); }\r
1586             set { SetValue(TabCharsProperty, value); }\r
1587         }\r
1588 \r
1589         /// <summary>\r
1590         /// TabCharsの依存プロパティを表す\r
1591         /// </summary>\r
1592         public static readonly DependencyProperty TabCharsProperty =\r
1593             DependencyProperty.Register("TabChars",\r
1594             typeof(int),\r
1595             typeof(FooTextBox),\r
1596             new FrameworkPropertyMetadata(4));\r
1597 \r
1598         /// <summary>\r
1599         /// 矩形選択モードなら真を返し、そうでないなら偽を返す。これは依存プロパティです\r
1600         /// </summary>\r
1601         public bool RectSelectMode\r
1602         {\r
1603             get { return (bool)GetValue(RectSelectModeProperty); }\r
1604             set { SetValue(RectSelectModeProperty, value); }\r
1605         }\r
1606 \r
1607         /// <summary>\r
1608         /// RectSelectModeの依存プロパティを表す\r
1609         /// </summary>\r
1610         public static readonly DependencyProperty RectSelectModeProperty =\r
1611             DependencyProperty.Register("RectSelectMode", typeof(bool), typeof(FooTextBox), new FrameworkPropertyMetadata(false));\r
1612 \r
1613         /// <summary>\r
1614         /// 折り返しの方法を指定する\r
1615         /// </summary>\r
1616         /// <remarks>\r
1617         /// 変更した場合、レイアウトの再構築を行う必要があります\r
1618         /// </remarks>\r
1619         public LineBreakMethod LineBreakMethod\r
1620         {\r
1621             get { return (LineBreakMethod)GetValue(LineBreakProperty); }\r
1622             set { SetValue(LineBreakProperty, value); }\r
1623         }\r
1624 \r
1625         /// <summary>\r
1626         /// LineBreakMethodの依存プロパティを表す\r
1627         /// </summary>\r
1628         public static readonly DependencyProperty LineBreakProperty =\r
1629             DependencyProperty.Register("LineBreakMethod", typeof(LineBreakMethod), typeof(FooTextBox), new PropertyMetadata(LineBreakMethod.None));\r
1630 \r
1631 \r
1632         /// <summary>\r
1633         /// 折り返しの幅を指定する。LineBreakMethod.CharUnit以外の時は無視されます\r
1634         /// </summary>\r
1635         /// <remarks>\r
1636         /// 変更した場合、レイアウトの再構築を行う必要があります\r
1637         /// </remarks>\r
1638         public int LineBreakCharCount\r
1639         {\r
1640             get { return (int)GetValue(LineBreakCharCountProperty); }\r
1641             set { SetValue(LineBreakCharCountProperty, value); }\r
1642         }\r
1643 \r
1644         /// <summary>\r
1645         /// LineBreakCharCountの依存プロパティを表す\r
1646         /// </summary>\r
1647         public static readonly DependencyProperty LineBreakCharCountProperty =\r
1648             DependencyProperty.Register("LineBreakCharCount", typeof(int), typeof(FooTextBox), new PropertyMetadata(80));\r
1649 \r
1650         /// <summary>\r
1651         /// キャレットを描くなら真。そうでないなら偽を返す。これは依存プロパティです\r
1652         /// </summary>\r
1653         public bool DrawCaret\r
1654         {\r
1655             get { return (bool)GetValue(DrawCaretProperty); }\r
1656             set { SetValue(DrawCaretProperty, value); }\r
1657         }\r
1658 \r
1659         /// <summary>\r
1660         /// DrawCaretの依存プロパティを表す\r
1661         /// </summary>\r
1662         public static readonly DependencyProperty DrawCaretProperty =\r
1663             DependencyProperty.Register("DrawCaret", typeof(bool), typeof(FooTextBox), new FrameworkPropertyMetadata(true));\r
1664 \r
1665         \r
1666         /// <summary>\r
1667         /// キャレットラインを描くなら真。そうでないなら偽を返す。これは依存プロパティです\r
1668         /// </summary>\r
1669         public bool DrawCaretLine\r
1670         {\r
1671             get { return (bool)GetValue(DrawCaretLineProperty); }\r
1672             set { SetValue(DrawCaretLineProperty, value); }\r
1673         }\r
1674 \r
1675         /// <summary>\r
1676         /// DrawCaretLineの依存プロパティを表す\r
1677         /// </summary>\r
1678         public static readonly DependencyProperty DrawCaretLineProperty =\r
1679             DependencyProperty.Register("DrawCaretLine", typeof(bool), typeof(FooTextBox), new FrameworkPropertyMetadata(false));\r
1680 \r
1681         /// <summary>\r
1682         /// 行番号を描くなら真。そうでなければ偽。これは依存プロパティです\r
1683         /// </summary>\r
1684         public bool DrawLineNumber\r
1685         {\r
1686             get { return (bool)GetValue(DrawLineNumberProperty); }\r
1687             set { SetValue(DrawLineNumberProperty, value); }\r
1688         }\r
1689 \r
1690         /// <summary>\r
1691         /// ルーラーを描くなら真。そうでなければ偽。これは依存プロパティです\r
1692         /// </summary>\r
1693         public bool DrawRuler\r
1694         {\r
1695             get { return (bool)GetValue(DrawRulerProperty); }\r
1696             set { SetValue(DrawRulerProperty, value); }\r
1697         }\r
1698 \r
1699         /// <summary>\r
1700         /// DrawRulerの依存プロパティを表す\r
1701         /// </summary>\r
1702         public static readonly DependencyProperty DrawRulerProperty =\r
1703             DependencyProperty.Register("DrawRuler", typeof(bool), typeof(FooTextBox), new PropertyMetadata(false));\r
1704 \r
1705         \r
1706         /// <summary>\r
1707         /// DrawLineNumberの依存プロパティを表す\r
1708         /// </summary>\r
1709         public static readonly DependencyProperty DrawLineNumberProperty =\r
1710             DependencyProperty.Register("DrawLineNumber", typeof(bool), typeof(FooTextBox), new FrameworkPropertyMetadata(false));\r
1711 \r
1712         /// <summary>\r
1713         /// URLに下線を引くなら真。そうでないなら偽を表す。これは依存プロパティです\r
1714         /// </summary>\r
1715         public bool MarkURL\r
1716         {\r
1717             get { return (bool)GetValue(MarkURLProperty); }\r
1718             set { SetValue(MarkURLProperty, value); }\r
1719         }\r
1720 \r
1721         /// <summary>\r
1722         /// MarkURLの依存プロパティを表す\r
1723         /// </summary>\r
1724         public static readonly DependencyProperty MarkURLProperty =\r
1725             DependencyProperty.Register("MarkURL", typeof(bool), typeof(FooTextBox), new FrameworkPropertyMetadata(false));\r
1726 \r
1727         /// <summary>\r
1728         /// 全角スペースを表示するなら真。そうでないなら偽\r
1729         /// </summary>\r
1730         public bool ShowFullSpace\r
1731         {\r
1732             get { return (bool)GetValue(ShowFullSpaceProperty); }\r
1733             set { SetValue(ShowFullSpaceProperty, value); }\r
1734         }\r
1735 \r
1736         /// <summary>\r
1737         /// ShowFullSpaceの依存プロパティを表す\r
1738         /// </summary>\r
1739         public static readonly DependencyProperty ShowFullSpaceProperty =\r
1740             DependencyProperty.Register("ShowFullSpace", typeof(bool), typeof(FooTextBox), new UIPropertyMetadata(false));\r
1741 \r
1742         /// <summary>\r
1743         /// 半角スペースを表示するなら真。そうでないなら偽\r
1744         /// </summary>\r
1745         public bool ShowHalfSpace\r
1746         {\r
1747             get { return (bool)GetValue(ShowHalfSpaceProperty); }\r
1748             set { SetValue(ShowHalfSpaceProperty, value); }\r
1749         }\r
1750 \r
1751         /// <summary>\r
1752         /// ShowHalfSpaceの依存プロパティを表す\r
1753         /// </summary>\r
1754         public static readonly DependencyProperty ShowHalfSpaceProperty =\r
1755             DependencyProperty.Register("ShowHalfSpace", typeof(bool), typeof(FooTextBox), new UIPropertyMetadata(false));\r
1756 \r
1757         /// <summary>\r
1758         /// タブを表示するなら真。そうでないなら偽\r
1759         /// </summary>\r
1760         public bool ShowTab\r
1761         {\r
1762             get { return (bool)GetValue(ShowTabProperty); }\r
1763             set { SetValue(ShowTabProperty, value); }\r
1764         }\r
1765 \r
1766         /// <summary>\r
1767         /// ShowTabの依存プロパティを表す\r
1768         /// </summary>\r
1769         public static readonly DependencyProperty ShowTabProperty =\r
1770             DependencyProperty.Register("ShowTab", typeof(bool), typeof(FooTextBox), new UIPropertyMetadata(false));\r
1771 \r
1772         /// <summary>\r
1773         /// 改行マークを表示するなら真。そうでないなら偽\r
1774         /// </summary>\r
1775         public bool ShowLineBreak\r
1776         {\r
1777             get { return (bool)GetValue(ShowLineBreakProperty); }\r
1778             set { SetValue(ShowLineBreakProperty, value); }\r
1779         }\r
1780 \r
1781         /// <summary>\r
1782         /// ShowLineBreakの依存プロパティを表す\r
1783         /// </summary>\r
1784         public static readonly DependencyProperty ShowLineBreakProperty =\r
1785             DependencyProperty.Register("ShowLineBreak", typeof(bool), typeof(FooTextBox), new PropertyMetadata(false));\r
1786         \r
1787         #endregion\r
1788     }\r
1789     /// <summary>\r
1790     /// マウスボタン関連のイベントクラス\r
1791     /// </summary>\r
1792     public sealed class FooMouseButtonEventArgs : MouseButtonEventArgs\r
1793     {\r
1794         /// <summary>\r
1795         /// イベントが発生したドキュメントのインデックス\r
1796         /// </summary>\r
1797         public int Index\r
1798         {\r
1799             get;\r
1800             private set;\r
1801         }\r
1802 \r
1803         /// <summary>\r
1804         /// コンストラクター\r
1805         /// </summary>\r
1806         /// <param name="mouse">マウスデバイス</param>\r
1807         /// <param name="timestamp">タイムスタンプ</param>\r
1808         /// <param name="button">ボタン</param>\r
1809         /// <param name="stylusDevice">スタイラスデバイス</param>\r
1810         /// <param name="index">インデックス</param>\r
1811         public FooMouseButtonEventArgs(MouseDevice mouse, int timestamp, MouseButton button, StylusDevice stylusDevice, int index)\r
1812             : base(mouse, timestamp, button, stylusDevice)\r
1813         {\r
1814             this.Index = index;\r
1815         }\r
1816     }\r
1817     /// <summary>\r
1818     /// マウス関連のイベントクラス\r
1819     /// </summary>\r
1820     public sealed class FooMouseEventArgs : MouseEventArgs\r
1821     {\r
1822         /// <summary>\r
1823         /// イベントが発生したドキュメントのインデックス\r
1824         /// </summary>\r
1825         public int Index\r
1826         {\r
1827             get;\r
1828             private set;\r
1829         }\r
1830 \r
1831         /// <summary>\r
1832         /// コンストラクター\r
1833         /// </summary>\r
1834         /// <param name="mouse">マウスデバイス</param>\r
1835         /// <param name="timestamp">タイムスタンプ</param>\r
1836         /// <param name="stylusDevice">スタイラスデバイス</param>\r
1837         /// <param name="index">インデックス</param>\r
1838         public FooMouseEventArgs(MouseDevice mouse,\r
1839             int timestamp,\r
1840             StylusDevice stylusDevice,\r
1841             int index)\r
1842             : base(mouse, timestamp, stylusDevice)\r
1843         {\r
1844             this.Index = index;\r
1845         }\r
1846     }\r
1847 }\r