OSDN Git Service

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