/// <summary> /// 折り畳みを考慮して行を調整します /// </summary> /// <param name="row">調整前の行</param> /// <param name="isMoveNext">移動方向</param> /// <returns>調整後の行</returns> public int AdjustRow(int row, bool isMoveNext) { if (this.LayoutLines.FoldingStrategy == null) { return(row); } int lineHeadIndex = this.LayoutLines.GetIndexFromLineNumber(row); int lineLength = this.LayoutLines.GetLengthFromLineNumber(row); FoldingItem foldingData = this.LayoutLines.FoldingCollection.GetFarestHiddenFoldingData(lineHeadIndex, lineLength); if (foldingData != null && !foldingData.Expand) { if (foldingData.End == this.Document.Length) { return(row); } if (isMoveNext && lineHeadIndex > foldingData.Start) { row = this.LayoutLines.GetLineNumberFromIndex(foldingData.End) + 1; } else { row = this.LayoutLines.GetLineNumberFromIndex(foldingData.Start); } if (row > this.LayoutLines.Count - 1) { row = this.LayoutLines.GetLineNumberFromIndex(foldingData.Start); } } return(row); }
/// <summary> /// キャレット位置に文字列を挿入し、その分だけキャレットを進める。isInsertModeの値により動作が変わります /// </summary> /// <param name="str">挿入したい文字列</param> /// <param name="fromTip">真の場合、矩形選択の幅にかかわらず矩形編集モードとして動作します。そうでない場合は選択領域を文字列で置き換えます</param> public void DoInputString(string str, bool fromTip = false) { TextPoint CaretPos = this.Document.CaretPostion; if (str == "\t" && this.IndentMode == IndentMode.Space) { str = this.GetIndentSpace(CaretPos.col); } if (this.IsRectInsertMode()) { this.ReplaceBeforeSelectionArea(this.View.Selections, 0, str); return; } else if (this.SelectionLength != 0) { this.RepleaceSelectionArea(this.View.Selections, str, fromTip); return; } if (this.Document.FireUpdateEvent == false) { throw new InvalidOperationException(""); } int index = this.View.GetIndexFromLayoutLine(this.Document.CaretPostion); int length = 0; if (this.View.InsertMode == false && index < this.Document.Length && this.Document[index] != Document.NewLine) { string lineString = this.View.LayoutLines[CaretPos.row]; int end = this.View.LayoutLines.GetLayout(CaretPos.row).AlignIndexToNearestCluster(CaretPos.col + str.Length - 1, AlignDirection.Forward); if (end > lineString.Length - 1) { end = lineString.Length - 1; } end += this.View.LayoutLines.GetIndexFromLineNumber(CaretPos.row); length = end - index; } if (str == Document.NewLine.ToString()) { int lineHeadIndex = this.View.LayoutLines.GetIndexFromLineNumber(CaretPos.row); int lineLength = this.View.LayoutLines.GetLengthFromLineNumber(CaretPos.row); FoldingItem foldingData = this.View.LayoutLines.FoldingCollection.GetFarestHiddenFoldingData(lineHeadIndex, lineLength); if (foldingData != null && !foldingData.Expand && index > foldingData.Start && index <= foldingData.End) { index = foldingData.End + 1; } } this.Document.Replace(index, length, str, true); }
/// <summary> /// キャレットを指定した位置に移動させる /// </summary> /// <param name="row"></param> /// <param name="col"></param> /// <param name="autoExpand">折り畳みを展開するなら真</param> public void JumpCaret(int row, int col, bool autoExpand = true) { if (autoExpand) { int lineHeadIndex = this.LayoutLines.GetIndexFromLineNumber(row); int lineLength = this.LayoutLines.GetLengthFromLineNumber(row); FoldingItem foldingData = this.LayoutLines.FoldingCollection.Get(lineHeadIndex, lineLength); if (foldingData != null) { if (this.LayoutLines.FoldingCollection.IsParentHidden(foldingData) || !foldingData.IsFirstLine(this.LayoutLines, row)) { this.LayoutLines.FoldingCollection.Expand(foldingData); } } } //イベント呼び出しの再入防止のため this.Document.SetCaretPostionWithoutEvent(new TextPoint(row, col)); }
/// <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); }
/// <summary> /// コンストラクター /// </summary> /// <param name="item">FoldingItemオブジェクト</param> public FoldingItemStatusChangedEventArgs(FoldingItem item) { this.Item = item; }
/// <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(); }