OSDN Git Service

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