OSDN Git Service

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