OSDN Git Service

WatchDogPatternプロパティを追加した
[fooeditengine/FooEditEngine.git] / Windows / 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.Threading;\r
13 using System.Windows.Forms;\r
14 using System.Drawing;\r
15 using System.ComponentModel;\r
16 using Microsoft.Win32;\r
17 \r
18 namespace FooEditEngine.Windows\r
19 {\r
20     /// <summary>\r
21     /// タブの幅が変更されたときに呼びされるデリゲート\r
22     /// </summary>\r
23     /// <param name="sender">送り主が属するクラス</param>\r
24     /// <param name="e">イベントデータ</param>\r
25     public delegate void TabStopChangeEventHandler(object sender, EventArgs e);\r
26 \r
27     /// <summary>\r
28     /// InsetModeが変更されたときに呼び出されるデリゲート\r
29     /// </summary>\r
30     /// <param name="sender">送り主が属するクラス</param>\r
31     /// <param name="e">イベントデータ</param>\r
32     public delegate void InsertModeChangeEventHandler(object sender, EventArgs e);\r
33 \r
34     /// <summary>\r
35     /// FooEditEngineを表します\r
36     /// </summary>\r
37     public class FooTextBox : Control\r
38     {\r
39         EditView View;\r
40         Controller Controller;\r
41         D2DTextRender render;\r
42         BorderStyle _BoderStyle;\r
43         HScrollBar HScrollBar;\r
44         VScrollBar VScrollBar;\r
45         WinIME Ime;\r
46         System.Windows.Forms.Timer Timer;\r
47 \r
48         const int Interval = 100;\r
49 \r
50         /// <summary>\r
51         /// コンストラクター\r
52         /// </summary>\r
53         public FooTextBox()\r
54         {\r
55             this.VScrollBar = new VScrollBar();\r
56             this.VScrollBar.Scroll += new ScrollEventHandler(VScrollBar_Scroll);\r
57             this.VScrollBar.Dock = DockStyle.Right;\r
58             this.VScrollBar.Visible = true;\r
59             this.Controls.Add(this.VScrollBar);\r
60 \r
61             this.HScrollBar = new HScrollBar();\r
62             this.HScrollBar.Scroll += new ScrollEventHandler(HScrollBar_Scroll);\r
63             this.HScrollBar.Dock = DockStyle.Bottom;\r
64             this.HScrollBar.Visible = true;\r
65             this.Controls.Add(this.HScrollBar);\r
66 \r
67             this.SetStyle(ControlStyles.ResizeRedraw, true);\r
68             this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);\r
69             this.SetStyle(ControlStyles.UserPaint, true);\r
70             this.SetStyle(ControlStyles.Opaque, true);\r
71 \r
72             this.Document = new Document();\r
73             DocumentExtend.Progress += Document_Progress;\r
74 \r
75             this.render = new D2DTextRender(this);\r
76             this.View = new EditView(this.Document,this.render,new Margin(5,5,5,5));\r
77             this.View.SrcChanged += View_SrcChanged;\r
78             \r
79             this.Controller = new Controller(this.Document, this.View);\r
80             this.Controller.SelectionChanged += new EventHandler(Controller_CaretMoved);\r
81 \r
82             this.Ime = new WinIME(this);\r
83             this.Ime.ImeCompstion += new ImeCompstionEventHandeler(Ime_ImeCompstion);\r
84             this.Ime.StartCompstion += new StartCompstionEventHandeler(Ime_StartCompstion);\r
85             this.Ime.EndCompstion += new EndCompstionEventHandeler(Ime_EndCompstion);\r
86             this.Ime.ImeDocumentFeed += new ImeDocumentFeedEventHandler(Ime_ImeDocumentFeed);\r
87             this.Ime.ImeReconvert += new ImeReconvertStringEventHandler(Ime_ImeReconvert);\r
88             this.Ime.ImeQueryReconvert += new ImeQueryReconvertStringEventHandler(Ime_ImeQueryReconvert);\r
89 \r
90             this.Timer = new System.Windows.Forms.Timer();\r
91             this.Timer.Tick += new EventHandler(this.Timer_Tick);\r
92             this.Timer.Interval = Interval;\r
93             this.SetSystemParamaters();\r
94 \r
95             this.TabStopChange += new TabStopChangeEventHandler((s, e) => { });\r
96             this.InsetModeChange += new InsertModeChangeEventHandler((s, e) => { });\r
97             this.SelectionChanged +=new EventHandler((s,e)=>{});\r
98 \r
99             this.RightToLeftChanged += FooTextBox_RightToLeftChanged;\r
100 \r
101             SystemEvents.UserPreferenceChanged += new UserPreferenceChangedEventHandler(SystemEvents_UserPreferenceChanged);\r
102         }\r
103 \r
104         /// <summary>\r
105         /// キャレットが移動したときに通知されるイベント\r
106         /// </summary>\r
107         public event EventHandler SelectionChanged;\r
108 \r
109         /// <summary>\r
110         /// タブの幅が変更された時に発生するイベント\r
111         /// </summary>\r
112         public event TabStopChangeEventHandler TabStopChange;\r
113 \r
114         /// <summary>\r
115         /// InsertModeが変更されたときに呼び出されるイベント\r
116         /// </summary>\r
117         public event InsertModeChangeEventHandler InsetModeChange;\r
118 \r
119         /// <summary>\r
120         /// テキスト描写に使用するアンチエイリアシングモードを表す\r
121         /// </summary>\r
122         [BrowsableAttribute(false)]\r
123         public TextAntialiasMode TextAntialiasMode\r
124         {\r
125             get\r
126             {\r
127                 return this.render.TextAntialiasMode;\r
128             }\r
129             set\r
130             {\r
131                 this.render.TextAntialiasMode = value;\r
132             }\r
133         }\r
134 \r
135         /// <summary>\r
136         /// ワッチドックパターンセットを表す\r
137         /// </summary>\r
138         [BrowsableAttribute(false)]\r
139         public WatchDogSet WatchDogPattern\r
140         {\r
141             get\r
142             {\r
143                 return this.View.WacthDogPattern;\r
144             }\r
145         }\r
146 \r
147         /// <summary>\r
148         /// 保持しているドキュメント\r
149         /// </summary>\r
150         [BrowsableAttribute(false)]\r
151         public Document Document\r
152         {\r
153             get;\r
154             private set;\r
155         }\r
156 \r
157         /// <summary>\r
158         /// 保持しているレイアウト行\r
159         /// </summary>\r
160         [BrowsableAttribute(false)]\r
161         public LineToIndexTable LayoutLines\r
162         {\r
163             get { return this.View.LayoutLines; }\r
164         }\r
165 \r
166         /// <summary>\r
167         /// シンタックスハイライター\r
168         /// </summary>\r
169         [BrowsableAttribute(false)]\r
170         public IHilighter Hilighter\r
171         {\r
172             get { return this.View.Hilighter; }\r
173             set { this.View.Hilighter = value; this.View.LayoutLines.ClearLayoutCache(); }\r
174         }\r
175 \r
176         /// <summary>\r
177         /// フォールティングを作成するインターフェイスを表す\r
178         /// </summary>\r
179         [BrowsableAttribute(false)]\r
180         public IFoldingStrategy FoldingStrategy\r
181         {\r
182             get\r
183             {\r
184                 return this.View.LayoutLines.FoldingStrategy;\r
185             }\r
186             set\r
187             {\r
188                 this.View.LayoutLines.FoldingStrategy = value;\r
189                 if (value == null)\r
190                     this.View.LayoutLines.FoldingCollection.Clear();\r
191             }\r
192         }\r
193 \r
194         /// <summary>\r
195         /// 境界線のスタイルを指定します\r
196         /// </summary>\r
197         public BorderStyle BorderStyle\r
198         {\r
199             get { return this._BoderStyle; }\r
200             set { this._BoderStyle = value; this.UpdateStyles(); }\r
201         }\r
202 \r
203 \r
204         /// <summary>\r
205         /// 行番号を表示するかどうか\r
206         /// </summary>\r
207         [DefaultValue(false)]\r
208         public bool DrawLineNumber\r
209         {\r
210             get\r
211             {\r
212                 return this.View.DrawLineNumber;\r
213             }\r
214             set\r
215             {\r
216                 this.View.DrawLineNumber = value;\r
217                 this.JumpCaret(this.CaretPostion.row,this.CaretPostion.col);\r
218             }\r
219         }\r
220         \r
221         /// <summary>\r
222         /// ルーラーを表示するかどうか\r
223         /// </summary>\r
224         [DefaultValue(false)]\r
225         public bool DrawRuler\r
226         {\r
227             get\r
228             {\r
229                 return !this.View.HideRuler;\r
230             }\r
231             set\r
232             {\r
233                 this.View.HideRuler = !value;\r
234                 this.JumpCaret(this.CaretPostion.row, this.CaretPostion.col);\r
235             }\r
236         }\r
237 \r
238         /// <summary>\r
239         /// 桁折りを行う方法を指定する\r
240         /// </summary>\r
241         /// <remarks>\r
242         /// 反映させるためにはレイアウト行の再構築を行う必要があります\r
243         /// </remarks>\r
244         [DefaultValue(LineBreakMethod.None)]\r
245         public LineBreakMethod LineBreakMethod\r
246         {\r
247             get\r
248             {\r
249                 return this.View.LineBreak;\r
250             }\r
251             set\r
252             {\r
253                 this.View.LineBreak = value;\r
254             }\r
255         }\r
256 \r
257         /// <summary>\r
258         /// 桁折り時の文字数を指定する。\r
259         /// </summary>\r
260         /// <remarks>\r
261         /// 反映させるためにはレイアウト行の再構築を行う必要があります\r
262         /// </remarks>\r
263         [DefaultValue(80)]\r
264         public int LineBreakCharCount\r
265         {\r
266             get\r
267             {\r
268                 return this.View.LineBreakCharCount;\r
269             }\r
270             set\r
271             {\r
272                 this.View.LineBreakCharCount = value;\r
273             }\r
274         }\r
275 \r
276         /// <summary>\r
277         /// URLをマークするかどうか\r
278         /// </summary>\r
279         [DefaultValue(false)]\r
280         public bool UrlMark\r
281         {\r
282             get\r
283             {\r
284                 return this.View.UrlMark;\r
285             }\r
286             set\r
287             {\r
288                 this.View.UrlMark = value;\r
289             }\r
290         }\r
291 \r
292         /// <summary>\r
293         /// タブストップの幅\r
294         /// </summary>\r
295         [DefaultValue(4)]\r
296         public int TabStops\r
297         {\r
298             get { return this.View.TabStops; }\r
299             set {\r
300                 this.View.TabStops = value;\r
301                 this.View.AdjustCaretAndSrc();\r
302                 this.TabStopChange(this, null);\r
303             }\r
304         }\r
305 \r
306         /// <summary>\r
307         /// 全角スペースを表示するなら真。そうでないなら偽\r
308         /// </summary>\r
309         [DefaultValue(false)]\r
310         public bool ShowFullSpace\r
311         {\r
312             get\r
313             {\r
314                 return this.render.ShowFullSpace;\r
315             }\r
316             set\r
317             {\r
318                 this.render.ShowFullSpace = value;\r
319             }\r
320         }\r
321 \r
322         /// <summary>\r
323         /// 半角スペースを表示するなら真。そうでないなら偽\r
324         /// </summary>\r
325         [DefaultValue(false)]\r
326         public bool ShowHalfSpace\r
327         {\r
328             get\r
329             {\r
330                 return this.render.ShowHalfSpace;\r
331             }\r
332             set\r
333             {\r
334                 this.render.ShowHalfSpace = value;\r
335             }\r
336         }\r
337 \r
338         /// <summary>\r
339         /// タブを表示するなら真。そうでないなら偽\r
340         /// </summary>\r
341         [DefaultValue(false)]\r
342         public bool ShowTab\r
343         {\r
344             get\r
345             {\r
346                 return this.render.ShowTab;\r
347             }\r
348             set\r
349             {\r
350                 this.render.ShowTab = value;\r
351             }\r
352         }\r
353 \r
354         /// <summary>\r
355         /// 改行マークを表示するなら真。そうでないなら偽\r
356         /// </summary>\r
357         [DefaultValue(false)]\r
358         public bool ShowLineBreak\r
359         {\r
360             get\r
361             {\r
362                 return this.render.ShowLineBreak;\r
363             }\r
364             set\r
365             {\r
366                 this.render.ShowLineBreak = value;\r
367             }\r
368         }\r
369 \r
370         /// <summary>\r
371         /// 選択中の文字列\r
372         /// </summary>\r
373         /// <remarks>\r
374         /// 未選択状態で文字列を代入した場合、キャレット位置に挿入され、そうでないときは置き換えられます。\r
375         /// </remarks>\r
376         [BrowsableAttribute(false)]\r
377         public string SelectedText\r
378         {\r
379             get { return this.Controller.SelectedText; }\r
380             set { this.Controller.SelectedText = value; }\r
381         }\r
382 \r
383         /// <summary>\r
384         /// キャレット位置を表す\r
385         /// </summary>\r
386         [BrowsableAttribute(false)]\r
387         public TextPoint CaretPostion\r
388         {\r
389             get { return this.View.CaretPostion; }\r
390         }\r
391 \r
392         /// <summary>\r
393         /// 選択範囲を表す\r
394         /// </summary>\r
395         /// <remarks>\r
396         /// Lengthが0の場合はキャレット位置を表します\r
397         /// 矩形選択モードの場合、選択範囲の文字数ではなく、開始位置から終了位置までの長さとなります\r
398         /// </remarks>\r
399         [BrowsableAttribute(false)]\r
400         public TextRange Selection\r
401         {\r
402             get { return new TextRange(this.Controller.SelectionStart,this.Controller.SelectionLength); }\r
403             set\r
404             {\r
405                 this.Controller.Select(value.Index, value.Length);\r
406             }\r
407         }\r
408 \r
409         /// <summary>\r
410         /// 挿入モードかどうか\r
411         /// </summary>\r
412         [DefaultValue(true)]\r
413         public bool InsertMode\r
414         {\r
415             get { return this.View.InsertMode; }\r
416             set\r
417             {\r
418                 this.View.InsertMode = value;\r
419                 this.InsetModeChange(this, null);\r
420             }\r
421         }\r
422 \r
423         /// <summary>\r
424         /// 矩形選択を行うかどうか\r
425         /// </summary>\r
426         [DefaultValue(false)]\r
427         public bool RectSelection\r
428         {\r
429             get { return this.Controller.RectSelection; }\r
430             set { this.Controller.RectSelection = value; }\r
431         }\r
432 \r
433         /// <summary>\r
434         /// 前景色\r
435         /// </summary>\r
436         public System.Drawing.Color Foreground\r
437         {\r
438             get\r
439             {\r
440                 return this.render.Foreground;\r
441             }\r
442             set\r
443             {\r
444                 this.render.Foreground = value;\r
445             }\r
446         }\r
447 \r
448         /// <summary>\r
449         /// 背景色\r
450         /// </summary>\r
451         public System.Drawing.Color Background\r
452         {\r
453             get\r
454             {\r
455                 return this.render.Background;\r
456             }\r
457             set\r
458             {\r
459                 this.render.Background = value;\r
460             }\r
461         }\r
462 \r
463         /// <summary>\r
464         /// 挿入モード時のキャレット色\r
465         /// </summary>\r
466         public System.Drawing.Color InsertCaret\r
467         {\r
468             get\r
469             {\r
470                 return this.render.InsertCaret;\r
471             }\r
472             set\r
473             {\r
474                 this.render.InsertCaret = value;\r
475             }\r
476         }\r
477 \r
478         /// <summary>\r
479         /// 上書きモード時のキャレット色\r
480         /// </summary>\r
481         public System.Drawing.Color OverwriteCaret\r
482         {\r
483             get\r
484             {\r
485                 return this.render.OverwriteCaret;\r
486             }\r
487             set\r
488             {\r
489                 this.render.OverwriteCaret = value;\r
490             }\r
491         }\r
492 \r
493         /// <summary>\r
494         /// ラインマーカーの色\r
495         /// </summary>\r
496         public System.Drawing.Color LineMarker\r
497         {\r
498             get\r
499             {\r
500                 return this.render.LineMarker;\r
501             }\r
502             set\r
503             {\r
504                 this.render.LineMarker = value;\r
505             }\r
506         }\r
507 \r
508         /// <summary>\r
509         /// コントロールの色\r
510         /// </summary>\r
511         public System.Drawing.Color ControlChar\r
512         {\r
513             get\r
514             {\r
515                 return this.render.ControlChar;\r
516             }\r
517             set\r
518             {\r
519                 this.render.ControlChar = value;\r
520             }\r
521         }\r
522 \r
523         /// <summary>\r
524         /// URLの色\r
525         /// </summary>\r
526         public System.Drawing.Color Url\r
527         {\r
528             get\r
529             {\r
530                 return this.render.Url;\r
531             }\r
532             set\r
533             {\r
534                 this.render.Url = value;\r
535             }\r
536         }\r
537 \r
538         /// <summary>\r
539         /// 選択領域の色\r
540         /// </summary>\r
541         public System.Drawing.Color Hilight\r
542         {\r
543             get\r
544             {\r
545                 return this.render.Hilight;\r
546             }\r
547             set\r
548             {\r
549                 this.render.Hilight = value;\r
550             }\r
551         }\r
552 \r
553         /// <summary>\r
554         /// コメントの色\r
555         /// </summary>\r
556         public System.Drawing.Color Comment\r
557         {\r
558             get\r
559             {\r
560                 return this.render.Comment;\r
561             }\r
562             set\r
563             {\r
564                 this.render.Comment = value;\r
565             }\r
566         }\r
567 \r
568         /// <summary>\r
569         /// 文字リテラルの色\r
570         /// </summary>\r
571         public System.Drawing.Color Literal\r
572         {\r
573             get\r
574             {\r
575                 return this.render.Literal;\r
576             }\r
577             set\r
578             {\r
579                 this.render.Literal = value;\r
580             }\r
581         }\r
582 \r
583         /// <summary>\r
584         /// キーワード1の色\r
585         /// </summary>\r
586         public System.Drawing.Color Keyword1\r
587         {\r
588             get\r
589             {\r
590                 return this.render.Keyword1;\r
591             }\r
592             set\r
593             {\r
594                 this.render.Keyword1 = value;\r
595             }\r
596         }\r
597 \r
598         /// <summary>\r
599         /// キーワード2の色\r
600         /// </summary>\r
601         public System.Drawing.Color Keyword2\r
602         {\r
603             get\r
604             {\r
605                 return this.render.Keyword2;\r
606             }\r
607             set\r
608             {\r
609                 this.render.Keyword2 = value;\r
610             }\r
611         }\r
612 \r
613         /// <summary>\r
614         /// キャレットに下線を描くかどうか\r
615         /// </summary>\r
616         [DefaultValue(false)]\r
617         public bool DrawCaretLine\r
618         {\r
619             get { return !this.View.HideLineMarker; }\r
620             set { this.View.HideLineMarker = !value; }\r
621         }\r
622 \r
623         /// <summary>\r
624         /// ドキュメントを選択する\r
625         /// </summary>\r
626         /// <param name="start">開始インデックス</param>\r
627         /// <param name="length">長さ</param>\r
628         public void Select(int start, int length)\r
629         {\r
630             if (this.Document.State == AsyncState.Loading)\r
631                 throw new InvalidOperationException();\r
632             this.Controller.Select(start, length);\r
633             this.HScrollBar.Value = (int)this.View.Src.X;\r
634             this.VScrollBar.Value = this.View.Src.Row;\r
635         }\r
636 \r
637         /// <summary>\r
638         /// ドキュメント全体を選択する\r
639         /// </summary>\r
640         public void SelectAll()\r
641         {\r
642             if (this.Document.State == AsyncState.Loading)\r
643                 throw new InvalidOperationException();\r
644             this.Controller.Select(0, this.Document.Length - 1);\r
645         }\r
646 \r
647         /// <summary>\r
648         /// 選択を解除する\r
649         /// </summary>\r
650         public void DeSelectAll()\r
651         {\r
652             if (this.Document.State == AsyncState.Loading)\r
653                 throw new InvalidOperationException();\r
654             this.Controller.DeSelectAll();\r
655         }\r
656 \r
657         /// <summary>\r
658         /// クリップボードにコピーする\r
659         /// </summary>\r
660         public void Copy()\r
661         {\r
662             if (this.Document.State == AsyncState.Loading)\r
663                 throw new InvalidOperationException();\r
664             string text = this.SelectedText;\r
665             if(text != null && text != string.Empty)\r
666                 Clipboard.SetText(text);\r
667         }\r
668 \r
669         /// <summary>\r
670         /// クリップボードにコピーし、指定した範囲にある文字列をすべて削除します\r
671         /// </summary>\r
672         public void Cut()\r
673         {\r
674             if (this.Document.State == AsyncState.Loading)\r
675                 throw new InvalidOperationException();\r
676             string text = this.SelectedText;\r
677             if (text != null && text != string.Empty)\r
678             {\r
679                 Clipboard.SetText(text);\r
680                 this.Controller.SelectedText = "";\r
681             }\r
682         }\r
683 \r
684         /// <summary>\r
685         /// クリップボードの内容をペーストします\r
686         /// </summary>\r
687         public void Paste()\r
688         {\r
689             if (this.Document.State == AsyncState.Loading)\r
690                 throw new InvalidOperationException();\r
691             if (Clipboard.ContainsText() == false)\r
692                 return;\r
693             this.Controller.SelectedText = Clipboard.GetText();\r
694         }\r
695 \r
696         /// <summary>\r
697         /// キャレットを指定した行に移動させます\r
698         /// </summary>\r
699         /// <param name="index">インデックス</param>\r
700         /// <remarks>このメソッドを呼び出すと選択状態は解除されます</remarks>\r
701         public void JumpCaret(int index)\r
702         {\r
703             if (this.Document.State == AsyncState.Loading)\r
704                 throw new InvalidOperationException();\r
705             this.Controller.JumpCaret(index);\r
706         }\r
707         /// <summary>\r
708         /// キャレットを指定した行と桁に移動させます\r
709         /// </summary>\r
710         /// <param name="row">行番号</param>\r
711         /// <param name="col">桁</param>\r
712         /// <remarks>このメソッドを呼び出すと選択状態は解除されます</remarks>\r
713         public void JumpCaret(int row, int col)\r
714         {\r
715             if (this.Document.State == AsyncState.Loading)\r
716                 throw new InvalidOperationException();\r
717             this.Controller.JumpCaret(row, col);\r
718         }\r
719 \r
720         /// <summary>\r
721         /// 再描写します\r
722         /// </summary>\r
723         public new void Refresh()\r
724         {\r
725             if (this.Document.State == AsyncState.Loading)\r
726                 return;\r
727             if (this.Document.FireUpdateEvent == false)\r
728                 throw new InvalidOperationException("");\r
729             if(this.View.CaretBlink)\r
730                 this.View.CaretBlink = true;\r
731             this.Invalidate();\r
732             this.Update();\r
733         }\r
734 \r
735         /// <summary>\r
736         /// 行の高さを取得する\r
737         /// </summary>\r
738         /// <param name="row">行</param>\r
739         /// <returns>高さ</returns>\r
740         public double GetLineHeight(int row)\r
741         {\r
742             if (this.Document.State == AsyncState.Loading)\r
743                 throw new InvalidOperationException();\r
744             if (this.Document.FireUpdateEvent == false)\r
745                 throw new InvalidOperationException("");\r
746             return this.View.LayoutLines.GetLayout(row).Height;\r
747         }\r
748 \r
749         /// <summary>\r
750         /// 対応する座標を返す\r
751         /// </summary>\r
752         /// <param name="tp">テキストポイント</param>\r
753         /// <returns>座標</returns>\r
754         /// <remarks>テキストポイントがクライアント領域の原点より外にある場合、返される値は原点に丸められます</remarks>\r
755         public System.Drawing.Point GetPostionFromTextPoint(TextPoint tp)\r
756         {\r
757             if (this.Document.State == AsyncState.Loading)\r
758                 throw new InvalidOperationException();\r
759             if (this.Document.FireUpdateEvent == false)\r
760                 throw new InvalidOperationException("");\r
761             return this.View.GetPostionFromTextPoint(tp);\r
762         }\r
763 \r
764         /// <summary>\r
765         /// 対応するテキストポイントを返す\r
766         /// </summary>\r
767         /// <param name="p">クライアント領域の原点を左上とする座標</param>\r
768         /// <returns>テキストポイント</returns>\r
769         public TextPoint GetTextPointFromPostion(System.Drawing.Point p)\r
770         {\r
771             if (this.Document.State == AsyncState.Loading)\r
772                 throw new InvalidOperationException();\r
773             if (this.Document.FireUpdateEvent == false)\r
774                 throw new InvalidOperationException("");\r
775             return this.View.GetTextPointFromPostion(p);\r
776         }\r
777 \r
778         /// <summary>\r
779         /// インデックスに対応する座標を得ます\r
780         /// </summary>\r
781         /// <param name="index">インデックス</param>\r
782         /// <returns>座標を返す</returns>\r
783         public System.Drawing.Point GetPostionFromIndex(int index)\r
784         {\r
785             if (this.Document.State == AsyncState.Loading)\r
786                 throw new InvalidOperationException();\r
787             if (this.Document.FireUpdateEvent == false)\r
788                 throw new InvalidOperationException("");\r
789             TextPoint tp = this.View.GetLayoutLineFromIndex(index);\r
790             return this.View.GetPostionFromTextPoint(tp);\r
791         }\r
792 \r
793         /// <summary>\r
794         /// 座標からインデックスに変換します\r
795         /// </summary>\r
796         /// <param name="p">座標</param>\r
797         /// <returns>インデックスを返す</returns>\r
798         public int GetIndexFromPostion(System.Drawing.Point p)\r
799         {\r
800             if (this.Document.State == AsyncState.Loading)\r
801                 throw new InvalidOperationException();\r
802             if (this.Document.FireUpdateEvent == false)\r
803                 throw new InvalidOperationException("");\r
804             TextPoint tp = this.View.GetTextPointFromPostion(p);\r
805             return this.View.GetIndexFromLayoutLine(tp);\r
806         }\r
807 \r
808         /// <summary>\r
809         /// レイアウト行をすべて破棄し、再度レイアウトを行う\r
810         /// </summary>\r
811         public void PerfomLayouts()\r
812         {\r
813             this.View.PerfomLayouts();\r
814             initScrollBars();\r
815         }\r
816 \r
817         /// <summary>\r
818         /// マウスカーソルを指定します\r
819         /// </summary>\r
820         public override Cursor Cursor\r
821         {\r
822             get\r
823             {\r
824                 return base.Cursor;\r
825             }\r
826             set\r
827             {\r
828                 base.Cursor = value;\r
829                 this.VScrollBar.Cursor = DefaultCursor;\r
830                 this.HScrollBar.Cursor = DefaultCursor;\r
831             }\r
832         }\r
833 \r
834         private const int WS_BORDER = 0x00800000;\r
835         private const int WS_EX_CLIENTEDGE = 0x00000200;\r
836         /// <summary>\r
837         /// コントロールの外観を指定します\r
838         /// </summary>\r
839         protected override CreateParams CreateParams\r
840         {\r
841             get\r
842             {\r
843                 CreateParams cp = base.CreateParams;\r
844                 switch (this.BorderStyle)\r
845                 {\r
846                     case BorderStyle.Fixed3D:\r
847                         cp.ExStyle |= WS_EX_CLIENTEDGE;\r
848                         break;\r
849                     case BorderStyle.FixedSingle:\r
850                         cp.Style |= WS_BORDER;\r
851                         break;\r
852                 }\r
853                 return cp;\r
854             }\r
855         }\r
856 \r
857         /// <summary>\r
858         /// コマンド キーを処理します\r
859         /// </summary>\r
860         /// <param name="msg">メッセージ</param>\r
861         /// <param name="keyData">キーデータ</param>\r
862         /// <returns>文字がコントロールによって処理された場合は true。それ以外の場合は false。 </returns>\r
863         protected override bool ProcessCmdKey(ref Message msg, Keys keyData)\r
864         {\r
865             if (this.Document.State == AsyncState.Loading)\r
866                 return false;\r
867             const int WM_KEYDOWN = 0x100;\r
868             if (msg.Msg != WM_KEYDOWN)\r
869                 return base.ProcessCmdKey(ref msg, keyData);\r
870             switch (keyData)\r
871             {\r
872                 case Keys.Control | Keys.C:\r
873                     this.Copy();\r
874                     break;\r
875                 case Keys.Control | Keys.V:\r
876                     this.Paste();\r
877                     this.Refresh();\r
878                     break;\r
879                 case Keys.Control | Keys.X:\r
880                     this.Cut();\r
881                     this.Refresh();\r
882                     break;\r
883                 case Keys.Control | Keys.Z:\r
884                     this.Document.UndoManager.undo();\r
885                     this.Refresh();\r
886                     break;\r
887                 case Keys.Control | Keys.Y:\r
888                     this.Document.UndoManager.redo();\r
889                     this.Refresh();\r
890                     break;\r
891                 case Keys.Control | Keys.B:\r
892                     if (this.Controller.RectSelection)\r
893                         this.Controller.RectSelection = false;\r
894                     else\r
895                         this.Controller.RectSelection = true;\r
896                     break;\r
897                 default:\r
898                     return base.ProcessCmdKey(ref msg,keyData);\r
899             }\r
900             return true;\r
901         }\r
902 \r
903         /// <summary>\r
904         /// インスタンスを破棄します\r
905         /// </summary>\r
906         /// <param name="disposing">マネージ リソースとアンマネージ リソースの両方を解放する場合は true。アンマネージ リソースだけを解放する場合は false。</param>\r
907         protected override void Dispose(bool disposing)\r
908         {\r
909             SystemEvents.UserPreferenceChanged -= new UserPreferenceChangedEventHandler(this.SystemEvents_UserPreferenceChanged);\r
910             DocumentExtend.Progress -= this.Document_Progress;\r
911             this.render.Dispose();\r
912             this.Timer.Dispose();\r
913             base.Dispose(disposing);\r
914         }\r
915 \r
916         /// <summary>\r
917         /// 入力可能な文字かチェックします\r
918         /// </summary>\r
919         /// <param name="charCode">入力しようとした文字</param>\r
920         /// <returns>可能なら真。そうでなければ偽</returns>\r
921         protected override bool IsInputChar(char charCode)\r
922         {\r
923             if ((0x20 <= charCode && charCode <= 0x7e)\r
924                 || charCode == '\r'\r
925                 || charCode == '\n'\r
926                 || charCode == ' '\r
927                 || charCode == '\t'\r
928                 || charCode == ' '\r
929                 || 0x7f < charCode)\r
930             {\r
931                 return true;\r
932             }\r
933 \r
934             return false;\r
935         }\r
936 \r
937         /// <summary>\r
938         /// GotFocusイベントを発生させます\r
939         /// </summary>\r
940         /// <param name="e">インベントデータ</param>\r
941         protected override void OnGotFocus(EventArgs e)\r
942         {\r
943             base.OnGotFocus(e);\r
944             this.View.IsFocused = true;\r
945             this.Refresh();\r
946         }\r
947 \r
948         /// <summary>\r
949         /// LostFocusイベントを発生させます\r
950         /// </summary>\r
951         /// <param name="e">インベントデータ</param>\r
952         protected override void OnLostFocus(EventArgs e)\r
953         {\r
954             base.OnLostFocus(e);\r
955             this.View.IsFocused = false;\r
956             this.Refresh();\r
957         }\r
958 \r
959         /// <summary>\r
960         /// FontChangedイベントを発生させます\r
961         /// </summary>\r
962         /// <param name="e">インベントデータ</param>\r
963         protected override void OnFontChanged(EventArgs e)\r
964         {\r
965             if (this.DesignMode)\r
966                 return;\r
967             base.OnFontChanged(e);\r
968             initScrollBars();\r
969         }\r
970 \r
971         /// <summary>\r
972         /// MouseDownイベントを発生させます\r
973         /// </summary>\r
974         /// <param name="e">インベントデータ</param>\r
975         protected override void OnMouseDown(MouseEventArgs e)\r
976         {\r
977             if (this.Document.State == AsyncState.Loading)\r
978                 return;\r
979 \r
980             TextPoint tp = this.View.GetTextPointFromPostion(e.Location);\r
981             if (tp == TextPoint.Null)\r
982                 return;\r
983             int index = this.View.LayoutLines.GetIndexFromTextPoint(tp);\r
984             \r
985             FooMouseEventArgs mouseEvent = new FooMouseEventArgs(index, e.Button, e.Clicks, e.X, e.Y, e.Delta);\r
986             \r
987             base.OnMouseDown(mouseEvent);\r
988             \r
989             if (mouseEvent.Handled)\r
990                 return;\r
991 \r
992             if (e.Button == MouseButtons.Left)\r
993             {\r
994                 FoldingItem foldingData = this.View.HitFoldingData(e.Location.X, tp.row);\r
995                 if (foldingData != null)\r
996                 {\r
997                     if (foldingData.Expand)\r
998                         this.View.LayoutLines.FoldingCollection.Collapse(foldingData);\r
999                     else\r
1000                         this.View.LayoutLines.FoldingCollection.Expand(foldingData);\r
1001                     this.Controller.JumpCaret(foldingData.Start, false);\r
1002                 }\r
1003                 else\r
1004                 {\r
1005                     this.Controller.JumpCaret(tp.row, tp.col, false);\r
1006                 }\r
1007                 this.Refresh();\r
1008             }\r
1009         }\r
1010 \r
1011         /// <summary>\r
1012         /// MouseClickイベントを発生させます\r
1013         /// </summary>\r
1014         /// <param name="e">インベントデータ</param>\r
1015         protected override void OnMouseClick(MouseEventArgs e)\r
1016         {\r
1017             if (this.Document.State == AsyncState.Loading)\r
1018                 return;\r
1019 \r
1020             int index = this.GetIndexFromPostion(e.Location);\r
1021 \r
1022             FooMouseEventArgs mouseEvent = new FooMouseEventArgs(index, e.Button, e.Clicks, e.X, e.Y, e.Delta);\r
1023 \r
1024             base.OnMouseClick(mouseEvent);\r
1025         }\r
1026 \r
1027         /// <summary>\r
1028         /// MouseDoubleClickイベントを発生させます\r
1029         /// </summary>\r
1030         /// <param name="e">インベントデータ</param>\r
1031         protected override void OnMouseDoubleClick(MouseEventArgs e)\r
1032         {\r
1033             if (this.Document.State == AsyncState.Loading)\r
1034                 return;\r
1035 \r
1036             TextPoint tp = this.View.GetTextPointFromPostion(e.Location);\r
1037             if (tp == TextPoint.Null)\r
1038                 return;\r
1039             int index = this.View.LayoutLines.GetIndexFromTextPoint(tp);\r
1040 \r
1041             FooMouseEventArgs mouseEvent = new FooMouseEventArgs(index, e.Button, e.Clicks, e.X, e.Y, e.Delta);\r
1042             \r
1043             base.OnMouseDoubleClick(mouseEvent);\r
1044 \r
1045             if (mouseEvent.Handled)\r
1046                 return;\r
1047 \r
1048             this.Controller.SelectWord(index);\r
1049             \r
1050             this.Refresh();\r
1051         }\r
1052 \r
1053         /// <summary>\r
1054         /// MouseMoveイベントを発生させます\r
1055         /// </summary>\r
1056         /// <param name="e">インベントデータ</param>\r
1057         protected override void OnMouseMove(MouseEventArgs e)\r
1058         {\r
1059             if (this.Document.State == AsyncState.Loading)\r
1060             {\r
1061                 this.Cursor = Cursors.WaitCursor;\r
1062                 return;\r
1063             }\r
1064             if (this.Focused == false)\r
1065                 return;\r
1066 \r
1067             base.OnMouseMove(e);\r
1068 \r
1069             if (this.View.HitTextArea(e.Location.X, e.Location.Y))\r
1070             {\r
1071                 TextPoint tp = this.View.GetTextPointFromPostion(e.Location);\r
1072                 if (this.Controller.IsMarker(tp, HilightType.Url))\r
1073                     this.Cursor = Cursors.Hand;\r
1074                 else\r
1075                     this.Cursor = Cursors.IBeam;\r
1076 \r
1077                 if (e.Button == MouseButtons.Left)\r
1078                 {\r
1079                     this.Controller.MoveCaretAndSelect(tp);\r
1080                     this.Refresh();\r
1081                 }\r
1082             }\r
1083             else\r
1084             {\r
1085                 this.Cursor = Cursors.Arrow;\r
1086             }\r
1087         }\r
1088 \r
1089         /// <summary>\r
1090         /// MouseWheelイベントを発生させます\r
1091         /// </summary>\r
1092         /// <param name="e">インベントデータ</param>\r
1093         protected override void OnMouseWheel(MouseEventArgs e)\r
1094         {\r
1095             if (this.Document.State == AsyncState.Loading)\r
1096                 return;\r
1097 \r
1098             base.OnMouseWheel(e);\r
1099 \r
1100             ScrollDirection dir = e.Delta > 0 ? ScrollDirection.Up : ScrollDirection.Down;\r
1101             this.Controller.Scroll(dir, SystemInformation.MouseWheelScrollLines, false, false);\r
1102             this.Refresh();\r
1103         }\r
1104 \r
1105         /// <summary>\r
1106         /// Paintイベントを発生させます\r
1107         /// </summary>\r
1108         /// <param name="e">インベントデータ</param>\r
1109         protected override void OnPaint(PaintEventArgs e)\r
1110         {\r
1111             if (DesignMode || this.Document.State == AsyncState.Loading)\r
1112             {\r
1113                 SolidBrush brush = new SolidBrush(this.BackColor);\r
1114                 e.Graphics.FillRectangle(brush, this.ClientRectangle);\r
1115                 brush.Dispose();\r
1116             }else if (this.Document.FireUpdateEvent){\r
1117                 this.render.BeginDraw();\r
1118                 this.View.Draw(e.ClipRectangle);\r
1119                 this.render.EndDraw();\r
1120             }\r
1121             base.OnPaint(e);\r
1122         }\r
1123 \r
1124         /// <summary>\r
1125         /// PaintBackgroundイベントを発生させます\r
1126         /// </summary>\r
1127         /// <param name="e">インベントデータ</param>\r
1128         protected override void OnPaintBackground(PaintEventArgs e)\r
1129         {\r
1130         }\r
1131 \r
1132         /// <summary>\r
1133         /// PreviewKeyDownイベントを発生させます\r
1134         /// </summary>\r
1135         /// <param name="e">インベントデータ</param>\r
1136         protected override void OnPreviewKeyDown(PreviewKeyDownEventArgs e)\r
1137         {\r
1138             base.OnPreviewKeyDown(e);\r
1139             switch (e.KeyCode)\r
1140             {\r
1141                 case Keys.Up:\r
1142                 case Keys.Down:\r
1143                 case Keys.Left:\r
1144                 case Keys.Right:\r
1145                 case Keys.Tab:\r
1146                     e.IsInputKey = true;\r
1147                     break;\r
1148             }\r
1149         }\r
1150 \r
1151         /// <summary>\r
1152         /// KeyDownイベントを発生させます\r
1153         /// </summary>\r
1154         /// <param name="e">インベントデータ</param>\r
1155         protected override void OnKeyDown(KeyEventArgs e)\r
1156         {\r
1157             if (this.Document.State == AsyncState.Loading)\r
1158                 return;\r
1159 \r
1160             base.OnKeyDown(e);\r
1161             \r
1162             if (e.Handled)\r
1163                 return;\r
1164 \r
1165             switch (e.KeyCode)\r
1166             {\r
1167                 case Keys.Up:\r
1168                     this.Controller.MoveCaretVertical(-1, e.Shift);\r
1169                     this.Refresh();\r
1170                     break;\r
1171                 case Keys.Down:\r
1172                     this.Controller.MoveCaretVertical(+1, e.Shift);\r
1173                     this.Refresh();\r
1174                     break;\r
1175                 case Keys.Left:\r
1176                     this.Controller.MoveCaretHorizontical(-1, e.Shift, e.Control);\r
1177                     this.Refresh();\r
1178                     break;\r
1179                 case Keys.Right:\r
1180                     this.Controller.MoveCaretHorizontical(1, e.Shift, e.Control);\r
1181                     this.Refresh();\r
1182                     break;\r
1183                 case Keys.PageUp:\r
1184                     this.Controller.Scroll(ScrollDirection.Up, this.VScrollBar.LargeChange,e.Shift,true);\r
1185                     this.Refresh();\r
1186                     break;\r
1187                 case Keys.PageDown:\r
1188                     this.Controller.Scroll(ScrollDirection.Down, this.VScrollBar.LargeChange,e.Shift,true);\r
1189                     this.Refresh();\r
1190                     break;\r
1191                 case Keys.Insert:\r
1192                     if (this.InsertMode)\r
1193                         this.InsertMode = false;\r
1194                     else\r
1195                         this.InsertMode = true;\r
1196                     break;\r
1197                 case Keys.Delete:\r
1198                     this.Controller.DoDeleteAction();\r
1199                     this.Refresh();\r
1200                     break;\r
1201                 case Keys.Back:\r
1202                     this.Controller.DoBackSpaceAction();\r
1203                     this.Refresh();\r
1204                     break;\r
1205                 case Keys.Home:\r
1206                     if (e.Control)\r
1207                         this.Controller.JumpToHead(false);\r
1208                     else\r
1209                         this.Controller.JumpCaret(this.View.CaretPostion.row, 0);\r
1210                     this.Refresh();\r
1211                     break;\r
1212                 case Keys.End:\r
1213                     if (e.Control)\r
1214                         this.Controller.JumpToEnd(false);\r
1215                     else\r
1216                         this.Controller.JumpCaret(this.View.CaretPostion.row, this.View.LayoutLines[this.View.CaretPostion.row].Length - 1);\r
1217                     this.Refresh();\r
1218                     break;\r
1219                 case Keys.Tab:\r
1220                     if (this.Controller.SelectionLength == 0)\r
1221                         this.Controller.DoInputChar('\t');\r
1222                     else if (e.Shift)\r
1223                         this.Controller.DownIndent();\r
1224                     else\r
1225                         this.Controller.UpIndent();\r
1226                     this.Refresh();\r
1227                     break;\r
1228             }\r
1229         }\r
1230 \r
1231         /// <summary>\r
1232         /// KeyPressイベントを発生させます\r
1233         /// </summary>\r
1234         /// <param name="e">インベントデータ</param>\r
1235         protected override void OnKeyPress(KeyPressEventArgs e)\r
1236         {\r
1237             if (this.Document.State == AsyncState.Loading)\r
1238                 return;\r
1239 \r
1240             base.OnKeyPress(e);\r
1241 \r
1242             if (e.Handled)\r
1243                 return;\r
1244             \r
1245             switch (e.KeyChar)\r
1246             {\r
1247                 case '\r':\r
1248                     this.Controller.DoEnterAction();\r
1249                     this.Refresh();\r
1250                     break;\r
1251                 case '\t':\r
1252                     break;  //OnKeyDownで処理しているので不要\r
1253                 default:\r
1254                     if (IsInputChar(e.KeyChar) == false)\r
1255                         break;\r
1256                     this.Controller.DoInputChar(e.KeyChar);\r
1257                     this.Refresh();\r
1258                     break;\r
1259             }\r
1260         }\r
1261 \r
1262         /// <summary>\r
1263         /// ClientSizeChangedイベントを発生させます\r
1264         /// </summary>\r
1265         /// <param name="e">インベントデータ</param>\r
1266         protected override void OnClientSizeChanged(EventArgs e)\r
1267         {\r
1268             if (this.DesignMode)\r
1269                 return;\r
1270             base.OnClientSizeChanged(e);\r
1271             \r
1272             this.View.PageBound = new Rectangle(0,\r
1273                 0,\r
1274                 Math.Max(this.ClientRectangle.Width - this.VScrollBar.Width,0),\r
1275                 Math.Max(this.ClientRectangle.Height - this.HScrollBar.Height, 0));\r
1276 \r
1277             initScrollBars();\r
1278             this.Refresh();\r
1279         }\r
1280 \r
1281         void View_SrcChanged(object sender, EventArgs e)\r
1282         {\r
1283             if (this.View.Src.Row > this.VScrollBar.Maximum)\r
1284                 this.VScrollBar.Maximum = this.View.Src.Row + this.View.LineCountOnScreen + 1;\r
1285 \r
1286             int srcX = (int)Math.Abs(this.View.Src.X);\r
1287             if (srcX > this.HScrollBar.Maximum)\r
1288                 this.HScrollBar.Maximum = srcX + (int)this.View.PageBound.Width + 1;\r
1289 \r
1290             this.HScrollBar.Value = srcX;\r
1291 \r
1292             this.VScrollBar.Value = this.View.Src.Row;\r
1293         }\r
1294 \r
1295         void FooTextBox_RightToLeftChanged(object sender, EventArgs e)\r
1296         {\r
1297             this.render.RightToLeft = this.RightToLeft == System.Windows.Forms.RightToLeft.Yes;\r
1298         }\r
1299 \r
1300         void VScrollBar_Scroll(object sender, ScrollEventArgs e)\r
1301         {\r
1302             if (this.Document.State == AsyncState.Loading)\r
1303                 return;\r
1304             this.View.TryScroll(this.View.Src.X, e.NewValue);\r
1305             this.Refresh();\r
1306         }\r
1307 \r
1308         void HScrollBar_Scroll(object sender, ScrollEventArgs e)\r
1309         {\r
1310             if (this.Document.State == AsyncState.Loading)\r
1311                 return;\r
1312             int toX;\r
1313             if (this.RightToLeft == System.Windows.Forms.RightToLeft.Yes)\r
1314                 toX = -e.NewValue;\r
1315             else\r
1316                 toX = e.NewValue;\r
1317             this.View.TryScroll(toX, this.View.Src.Row);\r
1318             this.Refresh();\r
1319         }\r
1320 \r
1321         void Ime_StartCompstion(object sender, StartCompstionEventArgs e)\r
1322         {\r
1323             if (this.Document.State == AsyncState.Loading)\r
1324                 return;\r
1325             this.Ime.Font = this.Font;\r
1326             this.Ime.Location = this.GetPostionFromIndex(this.Controller.SelectionStart);\r
1327             this.View.HideCaret = true;\r
1328         }\r
1329 \r
1330         void Ime_EndCompstion(object sender, EndCompstionEventArgs e)\r
1331         {\r
1332             this.View.HideCaret = false;\r
1333         }\r
1334 \r
1335         void Ime_ImeCompstion(object sender, ImeCompstionEventArgs e)\r
1336         {\r
1337             if (this.Document.State == AsyncState.Loading)\r
1338                 return;\r
1339             this.Controller.DoInputString(e.InputText);\r
1340             this.Refresh();\r
1341         }\r
1342 \r
1343         void Ime_ImeDocumentFeed(object sender, ImeDocumentFeedEventArgs e)\r
1344         {\r
1345             if (this.Document.State == AsyncState.Loading)\r
1346                 return;\r
1347             TextPoint tp = this.CaretPostion;\r
1348             e.Pragraph = this.LayoutLines[tp.row];\r
1349             e.pos = tp.col;\r
1350         }\r
1351 \r
1352         void Ime_ImeReconvert(object sender, ImeReconvertStringEventArgs e)\r
1353         {\r
1354             if (this.Document.State == AsyncState.Loading)\r
1355                 return;\r
1356             if (this.RectSelection)\r
1357                 return;\r
1358             if (this.Controller.SelectionLength == 0)\r
1359             {\r
1360                 TextPoint tp = this.LayoutLines.GetTextPointFromIndex(this.Controller.SelectionStart);\r
1361                 e.TargetString = this.LayoutLines[tp.row];\r
1362                 e.AutoAdjust = true;\r
1363             }\r
1364             else\r
1365             {\r
1366                 e.TargetString = this.SelectedText;\r
1367                 if (e.TargetString.Length > 40)\r
1368                     e.TargetString.Remove(40);\r
1369             }\r
1370             e.CaretPostion = this.View.CaretLocation;\r
1371         }\r
1372 \r
1373         void Ime_ImeQueryReconvert(object sender, ImeQueryRecovertStringEventArgs e)\r
1374         {\r
1375             if (this.Document.State == AsyncState.Loading)\r
1376                 return;\r
1377 \r
1378             TextPoint tp = this.LayoutLines.GetTextPointFromIndex(this.Controller.SelectionStart);\r
1379             tp.col = e.offset;\r
1380 \r
1381             int index = this.View.GetIndexFromLayoutLine(tp);\r
1382 \r
1383             this.Select(index, index + e.length);\r
1384         }\r
1385 \r
1386         void Controller_CaretMoved(object sender, EventArgs e)\r
1387         {\r
1388             this.SelectionChanged(this, null);\r
1389         }\r
1390 \r
1391         void Document_Progress(object sender, ProgressEventArgs e)\r
1392         {\r
1393             if (this.Document.State == AsyncState.Saving)\r
1394                 return;\r
1395             if (e.state == ProgressState.Complete)\r
1396             {\r
1397                 this.initScrollBars();\r
1398                 this.OnMouseMove(new MouseEventArgs(MouseButtons.None, 0, MousePosition.X, MousePosition.Y, 0));\r
1399                 this.View.CalculateLineCountOnScreen();\r
1400             }\r
1401         }\r
1402 \r
1403         void initScrollBars()\r
1404         {\r
1405             this.VScrollBar.SmallChange = 1;\r
1406             this.VScrollBar.LargeChange = this.View.LineCountOnScreen;\r
1407             this.VScrollBar.Maximum = this.View.LayoutLines.Count + this.View.LineCountOnScreen + 1;\r
1408             this.HScrollBar.SmallChange = 10;\r
1409             this.HScrollBar.LargeChange = (int)this.View.PageBound.Width;\r
1410             this.HScrollBar.Maximum = this.HScrollBar.LargeChange + 1;\r
1411         }\r
1412 \r
1413         void Timer_Tick(object sender,EventArgs e)\r
1414         {\r
1415             if (this.Document.State == AsyncState.Loading)\r
1416                 return;\r
1417             if (this.View.CaretPostion.row >= this.View.LayoutLines.Count || DesignMode)\r
1418                 return;\r
1419 \r
1420             ITextLayout layout = this.View.LayoutLines.GetLayout(this.View.CaretPostion.row);\r
1421 \r
1422             Size redrawSize = new Size();\r
1423             redrawSize.Width = layout.GetWidthFromIndex(this.View.CaretPostion.col);\r
1424             if (redrawSize.Width == 0.0)\r
1425                 redrawSize.Width = this.View.CaretWidthOnInsertMode;\r
1426             redrawSize.Height = layout.Height;\r
1427 \r
1428             this.Invalidate(new System.Drawing.Rectangle(this.View.CaretLocation, redrawSize));\r
1429         }\r
1430 \r
1431         void SystemEvents_UserPreferenceChanged(object sender, UserPreferenceChangedEventArgs e)\r
1432         {\r
1433             this.SetSystemParamaters();\r
1434             this.Refresh();\r
1435         }\r
1436 \r
1437         void SetSystemParamaters()\r
1438         {\r
1439             int CaretBlinkTime = SystemInformation.CaretBlinkTime;\r
1440             if (CaretBlinkTime == -1)\r
1441             {\r
1442                 this.View.CaretBlink = false;\r
1443                 this.BeginInvoke(new Action(() => {\r
1444                     this.Timer.Stop();\r
1445                 }));\r
1446             }\r
1447             else\r
1448             {\r
1449                 this.View.CaretBlink = true;\r
1450                 this.View.CaretBlinkTime = CaretBlinkTime * 2;\r
1451                 this.BeginInvoke(new Action(() =>\r
1452                 {\r
1453                     this.Timer.Start();\r
1454                 }));\r
1455             }\r
1456             this.View.CaretWidthOnInsertMode = SystemInformation.CaretWidth;\r
1457         }\r
1458 \r
1459     }\r
1460 \r
1461     /// <summary>\r
1462     /// FooEditEngineで使用するマウスイベント\r
1463     /// </summary>\r
1464     public class FooMouseEventArgs : MouseEventArgs\r
1465     {\r
1466         /// <summary>\r
1467         /// イベントが発生したインデックス\r
1468         /// </summary>\r
1469         public int index;\r
1470         /// <summary>\r
1471         /// 既定の処理を省略するなら真。そうでなければ偽\r
1472         /// </summary>\r
1473         public bool Handled;\r
1474         /// <summary>\r
1475         /// コンストラクター\r
1476         /// </summary>\r
1477         /// <param name="index">インデックス</param>\r
1478         /// <param name="button">押されているボタン</param>\r
1479         /// <param name="clicks">ボタンが押された回数</param>\r
1480         /// <param name="x">マウスカーソルがあるX座標</param>\r
1481         /// <param name="y">マウスカーソルがあるY座標</param>\r
1482         /// <param name="delta">ホイールの回転方向</param>\r
1483         public FooMouseEventArgs(int index, MouseButtons button, int clicks, int x, int y, int delta)\r
1484             : base(button, clicks, x, y, delta)\r
1485         {\r
1486             this.index = index;\r
1487         }\r
1488     }\r
1489 \r
1490 }\r