/// <summary> /// コンストラクター /// </summary> /// <param name="doc">ドキュメント</param> /// <param name="r">レンダー</param> /// <param name="margin">マージン(1番目:左、2番目:上、3番目:右、4番目:下)</param> public EditView(Document doc, IEditorRender r, Padding margin) : base(doc, r, margin) { this.CaretBlinkTime = 500; this.CaretWidthOnInsertMode = 1; this.LayoutLines.FoldingCollection.StatusChanged += FoldingCollection_StatusChanged; this.IsFocused = false; }
protected override void CalculateClipRect() { IEditorRender render = (IEditorRender)base.render; double x, y, width, height; if (this.Document.DrawLineNumber) { if (this.Document.RightToLeft) { x = this.Padding.Left; } else { x = this.Padding.Left + UpdateAreaTotalWidth + this.render.LineNemberWidth + this.LineNumberMargin + render.FoldingWidth; } width = this.PageBound.Width - this.render.LineNemberWidth - this.LineNumberMargin - this.Padding.Left - this.Padding.Right - render.FoldingWidth - UpdateAreaTotalWidth; } else { double foldingWidth = this.render != null ? render.FoldingWidth : 0; if (this.Document.RightToLeft) { x = this.Padding.Left; } else { x = this.Padding.Left + UpdateAreaTotalWidth + foldingWidth; } width = this.PageBound.Width - this.Padding.Left - this.Padding.Right - foldingWidth - UpdateAreaTotalWidth; } y = this.Padding.Top; height = this.PageBound.Height - this.Padding.Top - this.Padding.Bottom; if (this.Document.HideRuler == false) { double rulerHeight = this.render.emSize.Height + LineMarkerThickness; y += rulerHeight; height -= rulerHeight; } if (width < 0) { width = 0; } if (height < 0) { height = 0; } if (this.render != null) { this.render.TextArea = new Rectangle(x, y, width, height); } this.LineBreakingMarginWidth = width * 5 / 100; }
void DrawUpdateArea(int row, double ypos) { IEditorRender render = (IEditorRender)base.render; if (this.LayoutLines.GetDirtyFlag(row)) { Point pos = new Point(this.PageBound.X + this.GetRealtiveX(AreaType.UpdateArea), ypos); Rectangle rect = new Rectangle(pos.X, pos.Y, UpdateAreaWidth, this.LayoutLines.GetLayout(row).Height); render.FillRectangle(rect, FillRectType.UpdateArea); } }
double GetRealtiveX(AreaType type) { IEditorRender render = (IEditorRender)base.render; switch (type) { case AreaType.UpdateArea: if (this.Document.RightToLeft) { return(this.PageBound.TopRight.X - UpdateAreaTotalWidth); } if (this.Document.DrawLineNumber) { return(this.render.TextArea.X - this.render.LineNemberWidth - this.LineNumberMargin - render.FoldingWidth - UpdateAreaTotalWidth); } else { return(this.render.TextArea.X - render.FoldingWidth - UpdateAreaTotalWidth); } case AreaType.FoldingArea: if (this.Document.RightToLeft) { return(this.PageBound.TopRight.X - render.FoldingWidth); } if (this.Document.DrawLineNumber) { return(this.render.TextArea.X - this.render.LineNemberWidth - this.LineNumberMargin - render.FoldingWidth); } else { return(this.render.TextArea.X - render.FoldingWidth); } case AreaType.LineNumberArea: if (this.Document.DrawLineNumber == false) { throw new InvalidOperationException(); } if (this.Document.RightToLeft) { return(this.PageBound.TopRight.X - UpdateAreaTotalWidth - render.FoldingWidth - this.render.LineNemberWidth); } else { return(this.render.TextArea.X - this.render.LineNemberWidth - this.LineNumberMargin); } case AreaType.TextArea: return(this.render.TextArea.X); } throw new ArgumentOutOfRangeException(); }
public void DrawLineMarker(Point pos, ITextLayout layout) { if (this.HideLineMarker) { return; } IEditorRender render = (IEditorRender)base.render; Point p = this.CaretLocation; double height = layout.Height; double width = this.render.TextArea.Width; render.FillRectangle(new Rectangle(this.PageBound.X + this.render.TextArea.X, pos.Y, width, height), FillRectType.LineMarker); }
/// <summary> /// キャレットがあるところまでスクロールする /// </summary> /// <return>再描写する必要があるなら真を返す</return> /// <remarks>Document.Update(type == UpdateType.Clear)イベント時に呼び出した場合、例外が発生します</remarks> public bool AdjustCaretAndSrc(AdjustFlow flow = AdjustFlow.Both) { IEditorRender render = (IEditorRender)base.render; bool result; Point pos; if (this.PageBound.Width == 0 || this.PageBound.Height == 0) { this.SetCaretPostion(this.Padding.Left + render.FoldingWidth, 0); return(false); } (result, pos) = this.AdjustSrc(this.Document.CaretPostion, flow); this.SetCaretPostion(pos.X, pos.Y); return(result); }
/// <summary> /// ヒットテストを行う /// </summary> /// <param name="x">x座標</param> /// <param name="row">行</param> /// <returns>ヒットした場合はFoldingDataオブジェクトが返され、そうでない場合はnullが返る</returns> public FoldingItem HitFoldingData(double x, int row) { IEditorRender render = (IEditorRender)base.render; if (render == null) { return(null); } if (x >= this.GetRealtiveX(AreaType.FoldingArea) && x <= this.GetRealtiveX(AreaType.FoldingArea) + render.FoldingWidth) { int lineHeadIndex = this.LayoutLines.GetIndexFromLineNumber(row); int lineLength = this.LayoutLines.GetLengthFromLineNumber(row); FoldingItem foldingData = this.LayoutLines.FoldingCollection.Get(lineHeadIndex, lineLength); if (foldingData != null && foldingData.IsFirstLine(this.LayoutLines, row)) { return(foldingData); } } return(null); }
bool DrawCaret() { if (this.HideCaret || !this.IsFocused) { return(false); } long diff = DateTime.Now.Ticks - this.tickCount; long blinkTime = this.To100nsTime(this.CaretBlinkTime); if (this.CaretBlink && diff % blinkTime >= blinkTime / 2) { return(false); } Rectangle CaretRect = new Rectangle(); IEditorRender render = (IEditorRender)base.render; int row = this.Document.CaretPostion.row; ITextLayout layout = this.LayoutLines.GetLayout(row); double lineHeight = render.emSize.Height; double charWidth = layout.GetWidthFromIndex(this.Document.CaretPostion.col); if (this.InsertMode || charWidth == 0) { CaretRect.Size = new Size(CaretWidthOnInsertMode, lineHeight); CaretRect.Location = new Point(this.CaretLocation.X, this.CaretLocation.Y); render.FillRectangle(CaretRect, FillRectType.InsertCaret); } else { double height = lineHeight / 3; CaretRect.Size = new Size(charWidth, height); CaretRect.Location = new Point(this.CaretLocation.X, this.CaretLocation.Y + lineHeight - height); render.FillRectangle(CaretRect, FillRectType.OverwriteCaret); } return(true); }
void DrawInsertPoint() { //一つしかない場合は行選択の可能性がある if (this.Selections.Count <= 1) { return; } IEditorRender render = (IEditorRender)base.render; foreach (Selection sel in this.Selections) { if (sel.length == 0) { TextPoint tp = this.GetLayoutLineFromIndex(sel.start); Point left = this.GetPostionFromTextPoint(tp); double lineHeight = render.emSize.Height; Rectangle InsertRect = new Rectangle(left.X, left.Y, CaretWidthOnInsertMode, lineHeight); render.FillRectangle(InsertRect, FillRectType.InsertPoint); } } }
public DummyView(Document doc, IEditorRender render) : base(doc, render, new Padding(0, 0, 0, 0)) { }
/// <summary> /// コンストラクター /// </summary> public EditView(Document doc, IEditorRender r, int MarginLeftAndRight = 5) : this(doc, r, new Padding(MarginLeftAndRight, 0, MarginLeftAndRight, 0)) { }
void DrawRuler() { IEditorRender render = (IEditorRender)base.render; Point pos, from, to; Size emSize = render.emSize; Rectangle clipRect = this.render.TextArea; int count = 0; double markerHeight = emSize.Height / 2; if (this.Document.RightToLeft) { pos = new Point(clipRect.TopRight.X, clipRect.TopRight.Y - emSize.Height - LineMarkerThickness); for (; pos.X >= clipRect.TopLeft.X; pos.X -= emSize.Width, count++) { from = pos; to = new Point(pos.X, pos.Y + emSize.Height); int mod = count % 10; if (mod == 0) { string countStr = (count / 10).ToString(); double counterWidth = emSize.Width * countStr.Length; this.render.DrawString(countStr, pos.X - counterWidth, pos.Y, StringAlignment.Right, new Size(counterWidth, double.MaxValue)); } else if (mod == 5) { from.Y = from.Y + emSize.Height / 2; } else { from.Y = from.Y + emSize.Height * 3 / 4; } render.DrawLine(from, to); if (this.CaretLocation.X >= pos.X && this.CaretLocation.X < pos.X + emSize.Width) { render.FillRectangle(new Rectangle(pos.X, pos.Y + markerHeight, emSize.Width, markerHeight), FillRectType.OverwriteCaret); } } } else { pos = new Point(clipRect.TopLeft.X, clipRect.TopLeft.Y - emSize.Height - LineMarkerThickness); for (; pos.X < clipRect.TopRight.X; pos.X += emSize.Width, count++) { from = pos; to = new Point(pos.X, pos.Y + emSize.Height); int mod = count % 10; if (mod == 0) { this.render.DrawString((count / 10).ToString(), pos.X, pos.Y, StringAlignment.Left, new Size(double.MaxValue, double.MaxValue)); } else if (mod == 5) { from.Y = from.Y + emSize.Height / 2; } else { from.Y = from.Y + emSize.Height * 3 / 4; } render.DrawLine(from, to); if (this.CaretLocation.X >= pos.X && this.CaretLocation.X < pos.X + emSize.Width) { render.FillRectangle(new Rectangle(pos.X, pos.Y + markerHeight, emSize.Width, markerHeight), FillRectType.OverwriteCaret); } } } from = clipRect.TopLeft; from.Y -= LineMarkerThickness; to = clipRect.TopRight; to.Y -= LineMarkerThickness; render.DrawLine(from, to); }
/// <summary> /// Rectで指定された範囲にドキュメントを描く /// </summary> /// <param name="updateRect">描写する範囲</param> /// <param name="force">キャッシュした内容を使用しない場合は真を指定する</param> /// <remarks>描写する範囲がPageBoundより小さい場合、キャッシュされた内容を使用することがあります。なお、レタリング後にrender.CacheContent()を呼び出さなかった場合は更新範囲にかかわらずキャッシュを使用しません</remarks> public override void Draw(Rectangle updateRect, bool force = false) { if (this.LayoutLines.Count == 0) { return; } IEditorRender render = (IEditorRender)base.render; if (render == null) { return; } if ((updateRect.Height < this.PageBound.Height || updateRect.Width < this.PageBound.Width) && render.IsVaildCache() && !force) { render.DrawCachedBitmap(updateRect, updateRect); } else { Rectangle background = this.PageBound; render.FillBackground(background); if (this.Document.HideRuler == false) { this.DrawRuler(); } double endposy = this.render.TextArea.Bottom; Point pos = this.render.TextArea.TopLeft; pos.X -= this.Src.X; //画面上では行をずらして表示する pos.Y += this.Src.OffsetY; this.render.BeginClipRect(this.render.TextArea); for (int i = this.Src.Row; i < this.LayoutLines.Count; i++) { int lineIndex = this.LayoutLines.GetIndexFromLineNumber(i); int lineLength = this.LayoutLines.GetLengthFromLineNumber(i); ITextLayout layout = this.LayoutLines.GetLayout(i); if (pos.Y > endposy) { break; } FoldingItem foldingData = this.LayoutLines.FoldingCollection.Get(lineIndex, lineLength); if (foldingData != null) { if (this.LayoutLines.FoldingCollection.IsHidden(lineIndex)) { continue; } } this.render.DrawOneLine(this.Document, this.LayoutLines, i, pos.X, pos.Y); pos.Y += layout.Height; } this.render.EndClipRect(); //リセットしないと行が正しく描けない pos = this.render.TextArea.TopLeft; //画面上では行をずらして表示する pos.Y += this.Src.OffsetY; Size lineNumberSize = new Size(this.render.LineNemberWidth, this.render.TextArea.Height); for (int i = this.Src.Row; i < this.LayoutLines.Count; i++) { int lineIndex = this.LayoutLines.GetIndexFromLineNumber(i); int lineLength = this.LayoutLines.GetLengthFromLineNumber(i); ITextLayout layout = this.LayoutLines.GetLayout(i); if (pos.Y > endposy) { break; } FoldingItem foldingData = this.LayoutLines.FoldingCollection.Get(lineIndex, lineLength); if (foldingData != null) { if (this.LayoutLines.FoldingCollection.IsHidden(lineIndex)) { continue; } if (foldingData.IsFirstLine(this.LayoutLines, i) && foldingData.End >= lineIndex + lineLength) { render.DrawFoldingMark(foldingData.Expand, this.PageBound.X + this.GetRealtiveX(AreaType.FoldingArea), pos.Y); } } if (this.Document.DrawLineNumber) { this.render.DrawString((i + 1).ToString(), this.PageBound.X + this.GetRealtiveX(AreaType.LineNumberArea), pos.Y, StringAlignment.Right, lineNumberSize, StringColorType.LineNumber); } DrawUpdateArea(i, pos.Y); if (i == this.Document.CaretPostion.row) { this.DrawLineMarker(pos, layout); } pos.Y += layout.Height; } this.Document.SelectGrippers.BottomLeft.Draw(this.render); this.Document.SelectGrippers.BottomRight.Draw(this.render); render.CacheContent(); } this.DrawInsertPoint(); this.DrawCaret(); }