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
*/\r
using System;\r
+using System.Text;\r
using System.Threading;\r
+using System.Threading.Tasks;\r
using System.Windows.Forms;\r
using System.Drawing;\r
using System.ComponentModel;\r
this.SetStyle(ControlStyles.Opaque, true);\r
\r
this.Document = new Document();\r
- DocumentExtend.Progress += Document_Progress;\r
\r
this.render = new D2DTextRender(this);\r
- this.View = new EditView(this.Document,this.render,new Margin(5,5,5,5));\r
+ this.View = new EditView(this.Document,this.render,new FooEditEngine.Padding(5,5,5,5));\r
this.View.SrcChanged += View_SrcChanged;\r
\r
this.Controller = new Controller(this.Document, this.View);\r
this.RightToLeftChanged += FooTextBox_RightToLeftChanged;\r
\r
SystemEvents.UserPreferenceChanged += new UserPreferenceChangedEventHandler(SystemEvents_UserPreferenceChanged);\r
+\r
}\r
\r
/// <summary>\r
}\r
\r
/// <summary>\r
- /// ã\83¯ã\83\83ã\83\81ã\83\89ã\83\83ã\82¯パターンセットを表す\r
+ /// ã\83\9eã\83¼ã\82«ã\83¼パターンセットを表す\r
/// </summary>\r
[BrowsableAttribute(false)]\r
- public WatchDogSet WatchDogPattern\r
+ public MarkerPatternSet MarkerPatternSet\r
{\r
get\r
{\r
- return this.View.WacthDogPattern;\r
+ return this.View.MarkerPatternSet;\r
}\r
}\r
\r
set { this.Controller.RectSelection = value; }\r
}\r
\r
+ System.Drawing.Color ForegroundColor = SystemColors.ControlText,\r
+ BackgroundColor = SystemColors.Control,\r
+ HilightColor = System.Drawing.Color.DeepSkyBlue,\r
+ Keyword1Color = System.Drawing.Color.Blue,\r
+ Keyword2Color = System.Drawing.Color.DarkCyan,\r
+ LiteralColor = System.Drawing.Color.Brown,\r
+ UrlColor = System.Drawing.Color.Blue,\r
+ ControlCharColor = System.Drawing.Color.Gray,\r
+ CommentColor = System.Drawing.Color.Green,\r
+ InsertCaretColor = System.Drawing.Color.Black,\r
+ OverwriteCaretColor = System.Drawing.Color.Black,\r
+ LineMarkerColor = System.Drawing.Color.WhiteSmoke,\r
+ UpdateAreaColor = System.Drawing.Color.MediumSeaGreen;\r
+\r
/// <summary>\r
/// 前景色\r
/// </summary>\r
{\r
get\r
{\r
- return this.render.Foreground;\r
+ return this.ForegroundColor;\r
}\r
set\r
{\r
- this.render.Foreground = value;\r
+ this.render.Foreground = D2DTextRender.ToColor4(value);\r
+ this.ForegroundColor = value;\r
}\r
}\r
\r
{\r
get\r
{\r
- return this.render.Background;\r
+ return this.BackgroundColor;\r
}\r
set\r
{\r
- this.render.Background = value;\r
+ this.render.Background = D2DTextRender.ToColor4(value);\r
+ this.BackgroundColor = value;\r
}\r
}\r
\r
{\r
get\r
{\r
- return this.render.InsertCaret;\r
+ return this.InsertCaretColor;\r
}\r
set\r
{\r
- this.render.InsertCaret = value;\r
+ this.InsertCaretColor = value;\r
+ this.render.InsertCaret = D2DTextRender.ToColor4(value);\r
}\r
}\r
\r
{\r
get\r
{\r
- return this.render.OverwriteCaret;\r
+ return this.OverwriteCaretColor;\r
}\r
set\r
{\r
- this.render.OverwriteCaret = value;\r
+ this.OverwriteCaretColor = value;\r
+ this.render.OverwriteCaret = D2DTextRender.ToColor4(value);\r
}\r
}\r
\r
{\r
get\r
{\r
- return this.render.LineMarker;\r
+ return this.LineMarkerColor;\r
}\r
set\r
{\r
- this.render.LineMarker = value;\r
+ this.LineMarkerColor = value;\r
+ this.render.LineMarker = D2DTextRender.ToColor4(value);\r
}\r
}\r
\r
{\r
get\r
{\r
- return this.render.ControlChar;\r
+ return this.ControlCharColor;\r
+ }\r
+ set\r
+ {\r
+ this.ControlCharColor = value;\r
+ this.render.ControlChar = D2DTextRender.ToColor4(value);\r
+ }\r
+ }\r
+\r
+ /// <summary>\r
+ /// 編集行フラグの色\r
+ /// </summary>\r
+ public System.Drawing.Color UpdateArea\r
+ {\r
+ get\r
+ {\r
+ return this.UpdateAreaColor;\r
}\r
set\r
{\r
- this.render.ControlChar = value;\r
+ this.UpdateAreaColor = value;\r
+ this.render.UpdateArea = D2DTextRender.ToColor4(value);\r
}\r
}\r
\r
{\r
get\r
{\r
- return this.render.Url;\r
+ return this.UrlColor;\r
}\r
set\r
{\r
- this.render.Url = value;\r
+ this.UrlColor = value;\r
+ this.render.Url = D2DTextRender.ToColor4(value);\r
}\r
}\r
\r
{\r
get\r
{\r
- return this.render.Hilight;\r
+ return this.HilightColor;\r
}\r
set\r
{\r
- this.render.Hilight = value;\r
+ this.HilightColor = value;\r
+ this.render.Hilight = D2DTextRender.ToColor4(value);\r
}\r
}\r
\r
{\r
get\r
{\r
- return this.render.Comment;\r
+ return this.CommentColor;\r
}\r
set\r
{\r
- this.render.Comment = value;\r
+ this.CommentColor = value;\r
+ this.render.Comment = D2DTextRender.ToColor4(value);\r
}\r
}\r
\r
{\r
get\r
{\r
- return this.render.Literal;\r
+ return this.LiteralColor;\r
}\r
set\r
{\r
- this.render.Literal = value;\r
+ this.LiteralColor = value;\r
+ this.render.Literal = D2DTextRender.ToColor4(value);\r
}\r
}\r
\r
{\r
get\r
{\r
- return this.render.Keyword1;\r
+ return this.Keyword1Color;\r
}\r
set\r
{\r
- this.render.Keyword1 = value;\r
+ this.Keyword1Color = value;\r
+ this.render.Keyword1 = D2DTextRender.ToColor4(value);\r
}\r
}\r
\r
{\r
get\r
{\r
- return this.render.Keyword2;\r
+ return this.Keyword2Color;\r
}\r
set\r
{\r
- this.render.Keyword2 = value;\r
+ this.Keyword2Color = value;\r
+ this.render.Keyword2 = D2DTextRender.ToColor4(value);\r
}\r
}\r
\r
/// <param name="length">長さ</param>\r
public void Select(int start, int length)\r
{\r
- if (this.Document.State == AsyncState.Loading)\r
- throw new InvalidOperationException();\r
this.Controller.Select(start, length);\r
this.HScrollBar.Value = (int)this.View.Src.X;\r
this.VScrollBar.Value = this.View.Src.Row;\r
/// </summary>\r
public void SelectAll()\r
{\r
- if (this.Document.State == AsyncState.Loading)\r
- throw new InvalidOperationException();\r
this.Controller.Select(0, this.Document.Length - 1);\r
}\r
\r
/// </summary>\r
public void DeSelectAll()\r
{\r
- if (this.Document.State == AsyncState.Loading)\r
- throw new InvalidOperationException();\r
this.Controller.DeSelectAll();\r
}\r
\r
/// </summary>\r
public void Copy()\r
{\r
- if (this.Document.State == AsyncState.Loading)\r
- throw new InvalidOperationException();\r
string text = this.SelectedText;\r
if(text != null && text != string.Empty)\r
Clipboard.SetText(text);\r
/// </summary>\r
public void Cut()\r
{\r
- if (this.Document.State == AsyncState.Loading)\r
- throw new InvalidOperationException();\r
string text = this.SelectedText;\r
if (text != null && text != string.Empty)\r
{\r
/// </summary>\r
public void Paste()\r
{\r
- if (this.Document.State == AsyncState.Loading)\r
- throw new InvalidOperationException();\r
if (Clipboard.ContainsText() == false)\r
return;\r
this.Controller.SelectedText = Clipboard.GetText();\r
/// <remarks>このメソッドを呼び出すと選択状態は解除されます</remarks>\r
public void JumpCaret(int index)\r
{\r
- if (this.Document.State == AsyncState.Loading)\r
- throw new InvalidOperationException();\r
this.Controller.JumpCaret(index);\r
}\r
/// <summary>\r
/// <remarks>このメソッドを呼び出すと選択状態は解除されます</remarks>\r
public void JumpCaret(int row, int col)\r
{\r
- if (this.Document.State == AsyncState.Loading)\r
- throw new InvalidOperationException();\r
this.Controller.JumpCaret(row, col);\r
}\r
\r
/// </summary>\r
public new void Refresh()\r
{\r
- if (this.Document.State == AsyncState.Loading)\r
- return;\r
if (this.Document.FireUpdateEvent == false)\r
throw new InvalidOperationException("");\r
if(this.View.CaretBlink)\r
/// <returns>高さ</returns>\r
public double GetLineHeight(int row)\r
{\r
- if (this.Document.State == AsyncState.Loading)\r
- throw new InvalidOperationException();\r
if (this.Document.FireUpdateEvent == false)\r
throw new InvalidOperationException("");\r
return this.View.LayoutLines.GetLayout(row).Height;\r
/// <remarks>テキストポイントがクライアント領域の原点より外にある場合、返される値は原点に丸められます</remarks>\r
public System.Drawing.Point GetPostionFromTextPoint(TextPoint tp)\r
{\r
- if (this.Document.State == AsyncState.Loading)\r
- throw new InvalidOperationException();\r
if (this.Document.FireUpdateEvent == false)\r
throw new InvalidOperationException("");\r
return this.View.GetPostionFromTextPoint(tp);\r
/// <returns>テキストポイント</returns>\r
public TextPoint GetTextPointFromPostion(System.Drawing.Point p)\r
{\r
- if (this.Document.State == AsyncState.Loading)\r
- throw new InvalidOperationException();\r
if (this.Document.FireUpdateEvent == false)\r
throw new InvalidOperationException("");\r
return this.View.GetTextPointFromPostion(p);\r
/// <returns>座標を返す</returns>\r
public System.Drawing.Point GetPostionFromIndex(int index)\r
{\r
- if (this.Document.State == AsyncState.Loading)\r
- throw new InvalidOperationException();\r
if (this.Document.FireUpdateEvent == false)\r
throw new InvalidOperationException("");\r
TextPoint tp = this.View.GetLayoutLineFromIndex(index);\r
/// <returns>インデックスを返す</returns>\r
public int GetIndexFromPostion(System.Drawing.Point p)\r
{\r
- if (this.Document.State == AsyncState.Loading)\r
- throw new InvalidOperationException();\r
if (this.Document.FireUpdateEvent == false)\r
throw new InvalidOperationException("");\r
TextPoint tp = this.View.GetTextPointFromPostion(p);\r
}\r
\r
/// <summary>\r
+ /// ストリームからドキュメントを構築する\r
+ /// </summary>\r
+ /// <param name="tr">TextReader</param>\r
+ /// <param name="token">キャンセル用トークン</param>\r
+ /// <returns>Taskオブジェクト</returns>\r
+ public async Task LoadAsync(System.IO.TextReader tr, System.Threading.CancellationTokenSource token)\r
+ {\r
+ WinFileReader fs = new WinFileReader(tr);\r
+ await this.LoadAsyncImpl(fs, token);\r
+ }\r
+\r
+ /// <summary>\r
+ /// ファイルからドキュメントを構築する\r
+ /// </summary>\r
+ /// <param name="filepath">ファイルパス</param>\r
+ /// <param name="enc">エンコード</param>\r
+ /// <param name="token">キャンセル用トークン</param>\r
+ /// <returns>Taskオブジェクト</returns>\r
+ public async Task LoadFileAsync(string filepath, Encoding enc, System.Threading.CancellationTokenSource token)\r
+ {\r
+ WinFileReader fs = new WinFileReader(filepath, enc);\r
+ await this.LoadAsyncImpl(fs, token);\r
+ }\r
+\r
+ async Task LoadAsyncImpl(WinFileReader fs, System.Threading.CancellationTokenSource token)\r
+ {\r
+ this.Enabled = false;\r
+ this.View.LayoutLines.IsFrozneDirtyFlag = true;\r
+ await this.Document.LoadAsync(fs, token);\r
+ this.View.LayoutLines.IsFrozneDirtyFlag = false;\r
+ this.initScrollBars();\r
+ this.OnMouseMove(new MouseEventArgs(MouseButtons.None, 0, MousePosition.X, MousePosition.Y, 0));\r
+ this.View.CalculateLineCountOnScreen();\r
+ this.Enabled = true;\r
+ }\r
+\r
+ /// <summary>\r
+ /// ドキュメントの内容をファイルに保存する\r
+ /// </summary>\r
+ /// <param name="filepath">ファイルパス</param>\r
+ /// <param name="newLine">改行コード</param>\r
+ /// <param name="enc">エンコード</param>\r
+ /// <returns>Taskオブジェクト</returns>\r
+ public async Task SaveFile(string filepath, Encoding enc, string newLine, System.Threading.CancellationTokenSource token)\r
+ {\r
+ WinFileWriter fs = new WinFileWriter(filepath, enc);\r
+ fs.NewLine = newLine;\r
+ await this.Document.SaveAsync(fs, token);\r
+ }\r
+\r
+ /// <summary>\r
/// マウスカーソルを指定します\r
/// </summary>\r
public override Cursor Cursor\r
/// <returns>文字がコントロールによって処理された場合は true。それ以外の場合は false。 </returns>\r
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)\r
{\r
- if (this.Document.State == AsyncState.Loading)\r
- return false;\r
const int WM_KEYDOWN = 0x100;\r
if (msg.Msg != WM_KEYDOWN)\r
return base.ProcessCmdKey(ref msg, keyData);\r
protected override void Dispose(bool disposing)\r
{\r
SystemEvents.UserPreferenceChanged -= new UserPreferenceChangedEventHandler(this.SystemEvents_UserPreferenceChanged);\r
- DocumentExtend.Progress -= this.Document_Progress;\r
this.render.Dispose();\r
this.Timer.Dispose();\r
base.Dispose(disposing);\r
}\r
\r
/// <summary>\r
+ /// PaddingChangedイベントを発生させます\r
+ /// </summary>\r
+ /// <param name="e">インベントデータ</param>\r
+ protected override void OnPaddingChanged(EventArgs e)\r
+ {\r
+ base.OnPaddingChanged(e);\r
+ this.View.Padding = new Padding(this.Padding.Left, this.Padding.Top, this.Padding.Right, this.Padding.Bottom);\r
+ }\r
+\r
+ /// <summary>\r
/// GotFocusイベントを発生させます\r
/// </summary>\r
/// <param name="e">インベントデータ</param>\r
/// <param name="e">インベントデータ</param>\r
protected override void OnMouseDown(MouseEventArgs e)\r
{\r
- if (this.Document.State == AsyncState.Loading)\r
- return;\r
-\r
TextPoint tp = this.View.GetTextPointFromPostion(e.Location);\r
if (tp == TextPoint.Null)\r
return;\r
{\r
this.Controller.JumpCaret(tp.row, tp.col, false);\r
}\r
+ this.View.IsFocused = true;\r
+ this.Focus();\r
this.Refresh();\r
}\r
}\r
/// <param name="e">インベントデータ</param>\r
protected override void OnMouseClick(MouseEventArgs e)\r
{\r
- if (this.Document.State == AsyncState.Loading)\r
- return;\r
-\r
int index = this.GetIndexFromPostion(e.Location);\r
\r
FooMouseEventArgs mouseEvent = new FooMouseEventArgs(index, e.Button, e.Clicks, e.X, e.Y, e.Delta);\r
/// <param name="e">インベントデータ</param>\r
protected override void OnMouseDoubleClick(MouseEventArgs e)\r
{\r
- if (this.Document.State == AsyncState.Loading)\r
- return;\r
-\r
TextPoint tp = this.View.GetTextPointFromPostion(e.Location);\r
if (tp == TextPoint.Null)\r
return;\r
/// <param name="e">インベントデータ</param>\r
protected override void OnMouseMove(MouseEventArgs e)\r
{\r
- if (this.Document.State == AsyncState.Loading)\r
- {\r
- this.Cursor = Cursors.WaitCursor;\r
- return;\r
- }\r
if (this.Focused == false)\r
return;\r
\r
/// <param name="e">インベントデータ</param>\r
protected override void OnMouseWheel(MouseEventArgs e)\r
{\r
- if (this.Document.State == AsyncState.Loading)\r
- return;\r
-\r
base.OnMouseWheel(e);\r
\r
ScrollDirection dir = e.Delta > 0 ? ScrollDirection.Up : ScrollDirection.Down;\r
/// <param name="e">インベントデータ</param>\r
protected override void OnPaint(PaintEventArgs e)\r
{\r
- if (DesignMode || this.Document.State == AsyncState.Loading)\r
+ if (DesignMode)\r
{\r
SolidBrush brush = new SolidBrush(this.BackColor);\r
e.Graphics.FillRectangle(brush, this.ClientRectangle);\r
brush.Dispose();\r
}else if (this.Document.FireUpdateEvent){\r
- this.render.BeginDraw();\r
+ this.render.BegineDraw();\r
this.View.Draw(e.ClipRectangle);\r
this.render.EndDraw();\r
}\r
/// <param name="e">インベントデータ</param>\r
protected override void OnKeyDown(KeyEventArgs e)\r
{\r
- if (this.Document.State == AsyncState.Loading)\r
- return;\r
-\r
base.OnKeyDown(e);\r
\r
if (e.Handled)\r
break;\r
case Keys.Home:\r
if (e.Control)\r
- this.Controller.JumpToHead(false);\r
+ this.Controller.JumpToHead(e.Shift);\r
else\r
- this.Controller.JumpCaret(this.View.CaretPostion.row, 0);\r
+ this.Controller.JumpToLineHead(this.View.CaretPostion.row, e.Shift);\r
this.Refresh();\r
break;\r
case Keys.End:\r
if (e.Control)\r
- this.Controller.JumpToEnd(false);\r
+ this.Controller.JumpToEnd(e.Shift);\r
else\r
- this.Controller.JumpCaret(this.View.CaretPostion.row, this.View.LayoutLines[this.View.CaretPostion.row].Length - 1);\r
+ this.Controller.JumpToLineEnd(this.View.CaretPostion.row, e.Shift);\r
this.Refresh();\r
break;\r
case Keys.Tab:\r
/// <param name="e">インベントデータ</param>\r
protected override void OnKeyPress(KeyPressEventArgs e)\r
{\r
- if (this.Document.State == AsyncState.Loading)\r
- return;\r
-\r
base.OnKeyPress(e);\r
\r
if (e.Handled)\r
\r
void VScrollBar_Scroll(object sender, ScrollEventArgs e)\r
{\r
- if (this.Document.State == AsyncState.Loading)\r
- return;\r
this.View.TryScroll(this.View.Src.X, e.NewValue);\r
this.Refresh();\r
}\r
\r
void HScrollBar_Scroll(object sender, ScrollEventArgs e)\r
{\r
- if (this.Document.State == AsyncState.Loading)\r
- return;\r
int toX;\r
if (this.RightToLeft == System.Windows.Forms.RightToLeft.Yes)\r
toX = -e.NewValue;\r
\r
void Ime_StartCompstion(object sender, StartCompstionEventArgs e)\r
{\r
- if (this.Document.State == AsyncState.Loading)\r
- return;\r
this.Ime.Font = this.Font;\r
- this.Ime.Location = this.GetPostionFromIndex(this.Controller.SelectionStart);\r
+ System.Drawing.Point p = this.GetPostionFromIndex(this.Controller.SelectionStart);\r
+ float dpi;\r
+ this.render.GetDpi(out dpi, out dpi);\r
+ p.X = (int)(p.X * dpi / 96);\r
+ p.Y = (int)(p.Y * dpi / 96);\r
+ this.Ime.Location = p;\r
this.View.HideCaret = true;\r
}\r
\r
\r
void Ime_ImeCompstion(object sender, ImeCompstionEventArgs e)\r
{\r
- if (this.Document.State == AsyncState.Loading)\r
- return;\r
this.Controller.DoInputString(e.InputText);\r
this.Refresh();\r
}\r
\r
void Ime_ImeDocumentFeed(object sender, ImeDocumentFeedEventArgs e)\r
{\r
- if (this.Document.State == AsyncState.Loading)\r
- return;\r
TextPoint tp = this.CaretPostion;\r
e.Pragraph = this.LayoutLines[tp.row];\r
e.pos = tp.col;\r
\r
void Ime_ImeReconvert(object sender, ImeReconvertStringEventArgs e)\r
{\r
- if (this.Document.State == AsyncState.Loading)\r
- return;\r
if (this.RectSelection)\r
return;\r
if (this.Controller.SelectionLength == 0)\r
\r
void Ime_ImeQueryReconvert(object sender, ImeQueryRecovertStringEventArgs e)\r
{\r
- if (this.Document.State == AsyncState.Loading)\r
- return;\r
-\r
TextPoint tp = this.LayoutLines.GetTextPointFromIndex(this.Controller.SelectionStart);\r
tp.col = e.offset;\r
\r
this.SelectionChanged(this, null);\r
}\r
\r
- void Document_Progress(object sender, ProgressEventArgs e)\r
- {\r
- if (this.Document.State == AsyncState.Saving)\r
- return;\r
- if (e.state == ProgressState.Complete)\r
- {\r
- this.initScrollBars();\r
- this.OnMouseMove(new MouseEventArgs(MouseButtons.None, 0, MousePosition.X, MousePosition.Y, 0));\r
- this.View.CalculateLineCountOnScreen();\r
- }\r
- }\r
-\r
void initScrollBars()\r
{\r
this.VScrollBar.SmallChange = 1;\r
\r
void Timer_Tick(object sender,EventArgs e)\r
{\r
- if (this.Document.State == AsyncState.Loading)\r
- return;\r
if (this.View.CaretPostion.row >= this.View.LayoutLines.Count || DesignMode)\r
return;\r
\r
if (CaretBlinkTime == -1)\r
{\r
this.View.CaretBlink = false;\r
- this.BeginInvoke(new Action(() => {\r
+ if (this.IsHandleCreated)\r
+ this.BeginInvoke(new Action(() =>\r
+ {\r
this.Timer.Stop();\r
- }));\r
+ }));\r
}\r
else\r
{\r
this.View.CaretBlink = true;\r
this.View.CaretBlinkTime = CaretBlinkTime * 2;\r
- this.BeginInvoke(new Action(() =>\r
- {\r
- this.Timer.Start();\r
- }));\r
+ if(this.IsHandleCreated)\r
+ this.BeginInvoke(new Action(() =>\r
+ {\r
+ this.Timer.Start();\r
+ }));\r
}\r
this.View.CaretWidthOnInsertMode = SystemInformation.CaretWidth;\r
}\r