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