Beispiel #1
0
 /// <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;
 }
Beispiel #2
0
        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;
        }
Beispiel #3
0
        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);
            }
        }
Beispiel #4
0
        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();
        }
Beispiel #5
0
        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);
        }
Beispiel #6
0
        /// <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);
        }
Beispiel #7
0
        /// <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);
        }
Beispiel #8
0
        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);
        }
Beispiel #9
0
        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);
                }
            }
        }
Beispiel #10
0
 public DummyView(Document doc, IEditorRender render)
     : base(doc, render, new Padding(0, 0, 0, 0))
 {
 }
Beispiel #11
0
 /// <summary>
 /// コンストラクター
 /// </summary>
 public EditView(Document doc, IEditorRender r, int MarginLeftAndRight = 5)
     : this(doc, r, new Padding(MarginLeftAndRight, 0, MarginLeftAndRight, 0))
 {
 }
Beispiel #12
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);
        }
Beispiel #13
0
        /// <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();
        }