/// <summary>
        /// Called when the bar is exposed (drawn).
        /// </summary>
        /// <param name="exposeEvent">The drawing event..</param>
        /// <returns></returns>
        protected override bool OnExposeEvent(EventExpose exposeEvent)
        {
            // Figure out the area we are rendering into. We subtract one
            // from the width and height because of rounding causes one-pixel
            // borders off the bottom and right edges.
            Rectangle area      = exposeEvent.Region.Clipbox;
            var       cairoArea = new Cairo.Rectangle(
                area.X, area.Y, area.Width - 1, area.Height - 1);

            using (Context cairoContext = CairoHelper.Create(exposeEvent.Window))
            {
                // Create a render context.
                var renderContext = new RenderContext(cairoContext);
                renderContext.RenderRegion = cairoArea;

                // Paint the background of the entire indicator bar.
                BlockStyle backgroundStyle = Theme.RegionStyles[BackgroundRegionName]
                                             ?? new RegionBlockStyle();
                DrawingUtility.DrawLayout(
                    EditorView, renderContext, cairoArea, backgroundStyle);

                // Show the visible area, if we have one.
                BlockStyle visibleStyle = Theme.RegionStyles[VisibleRegionName];
                double     barX         = area.X + backgroundStyle.Left + 0.5;
                double     barWidth     = area.Width - backgroundStyle.Width - 1;
                double     barY         = area.Y + backgroundStyle.Top + 0.5;

                if (visibleStyle != null)
                {
                    // Figure out the area and adjust the bar variables with this style.
                    var visibleArea = new Cairo.Rectangle(
                        barX,
                        barY,
                        barWidth,
                        indicatorLinesUsed * Theme.IndicatorPixelHeight + visibleStyle.Height);

                    barX     += visibleStyle.Left;
                    barWidth -= visibleStyle.Width;
                    barY     += visibleStyle.Top;

                    // Draw the style's elements.
                    DrawingUtility.DrawLayout(
                        EditorView, renderContext, visibleArea, visibleStyle);
                }

                // Draw all the indicator lines on the display.
                cairoContext.LineWidth = EditorView.Theme.IndicatorPixelHeight;
                cairoContext.Antialias = Antialias.None;

                for (int index = 0;
                     index < indicatorLinesUsed;
                     index++)
                {
                    // Make sure the line has been processed and it visible.
                    IndicatorLine indicatorLine = indicatorLines[index];

                    if (!indicatorLine.NeedIndicators &&
                        indicatorLine.Visible)
                    {
                        indicatorLine.Draw(EditorView, cairoContext, barX, barY, barWidth);
                    }

                    // Shift the y-coordinate down.
                    barY += EditorView.Theme.IndicatorPixelHeight;
                }
            }

            // Return the render.
            return(base.OnExposeEvent(exposeEvent));
        }
Example #2
0
        /// <summary>
        /// Called when the widget is exposed or drawn.
        /// </summary>
        /// <param name="e">The e.</param>
        /// <returns></returns>
        protected override bool OnExposeEvent(EventExpose e)
        {
            // Figure out the area we are rendering into.
            Gdk.Rectangle area      = e.Region.Clipbox;
            var           cairoArea = new Rectangle(area.X, area.Y, area.Width, area.Height);

            using (Context cairoContext = CairoHelper.Create(e.Window))
            {
                // Create a render context.
                var renderContext = new RenderContext(cairoContext);
                renderContext.RenderRegion = cairoArea;

                // If we don't have a buffer at this point, don't render anything.
                if (Renderer == null ||
                    LineBuffer == null)
                {
                    return(true);
                }

                // Paint the background color of the window.
                RegionBlockStyle backgroundStyle =
                    Theme.RegionStyles[Theme.BackgroundRegionStyleName];
                DrawingUtility.DrawLayout(this, renderContext, cairoArea, backgroundStyle);

                // Reset the layout and its properties.
                Renderer.Width = area.Width - margins.Width;

                // Figure out the viewport area we'll be drawing.
                int offsetY = 0;

                if (verticalAdjustment != null)
                {
                    offsetY += (int)verticalAdjustment.Value;
                }

                var viewArea = new Rectangle(
                    area.X, area.Y + offsetY, area.Width, area.Height);

                // Determine the line range visible in the given area.
                int startLine,
                    endLine;
                Renderer.GetLineLayoutRange(viewArea, out startLine, out endLine);

                // Determine where the first line actually starts.
                int startLineY = 0;

                if (startLine > 0)
                {
                    startLineY = Renderer.GetLineLayoutHeight(0, startLine - 1);
                }

                // Go through the lines and draw each one in the correct position.
                double currentY = startLineY - offsetY;

                for (int lineIndex = startLine;
                     lineIndex <= endLine;
                     lineIndex++)
                {
                    // Figure out if we are on the current line.
                    var  lineContexts = LineContexts.None;
                    bool currentLine  = false;

                    if (lineIndex == caret.Position.LinePosition)
                    {
                        // Add the curent line to the context.
                        lineContexts |= LineContexts.CurrentLine;
                        currentLine   = true;
                    }

                    // Pull out the layout and style since we'll use it.
                    Layout         layout = Renderer.GetLineLayout(lineIndex, lineContexts);
                    LineBlockStyle style  = Renderer.GetLineStyle(lineIndex, lineContexts);

                    // Get the extents for that line.
                    int layoutWidth,
                        layoutHeight;
                    layout.GetPixelSize(out layoutWidth, out layoutHeight);

                    // Figure out the height of the line including padding.
                    double height = layoutHeight + style.Height;

                    if (currentLine)
                    {
                        // If we have a full-line background color, display it.
                        RegionBlockStyle currentLineStyle =
                            Theme.RegionStyles[Theme.CurrentLineRegionStyleName];

                        if (currentLineStyle != null)
                        {
                            var lineArea = new Rectangle(TextX, currentY, TextWidth, height);

                            DrawingUtility.DrawLayout(
                                this, renderContext, lineArea, currentLineStyle);
                        }

                        // If we have a wrapped line background color, draw it.
                        RegionBlockStyle currentWrappedLineStyle =
                            Theme.RegionStyles[Theme.CurrentWrappedLineRegionStyleName];

                        if (currentWrappedLineStyle != null)
                        {
                            // Get the wrapped line for the caret's position.
                            LayoutLine      wrappedLine = caret.Position.GetWrappedLine(this);
                            Pango.Rectangle wrappedLineExtents;

                            wrappedLine.GetPixelExtents(out wrappedLineExtents);

                            // Draw the current wrapped line index.
                            var wrappedLineArea = new Rectangle(
                                TextX,
                                currentY + wrappedLineExtents.Y + style.Top,
                                TextWidth,
                                wrappedLineExtents.Height);

                            DrawingUtility.DrawLayout(
                                this, renderContext, wrappedLineArea, currentWrappedLineStyle);
                        }
                    }

                    // Draw the current line along with wrapping and padding.
                    DrawingUtility.DrawLayout(
                        this,
                        renderContext,
                        new Rectangle(TextX, currentY, TextWidth, height),
                        layout,
                        style);

                    // Render out the margin renderers.
                    margins.Draw(
                        this, renderContext, lineIndex, new PointD(0, currentY), height, style);

                    // Move down a line.
                    currentY += height;
                }

                // Draw the caret on the screen, but only if we have focus.
                if (IsFocus)
                {
                    caret.Draw(renderContext);
                }

                // Show the scroll region, if requested.
                if (editorViewSettings.ShowScrollPadding)
                {
                    cairoContext.Color = new Color(1, 0.5, 0.5);
                    cairoContext.Rectangle(scrollPaddingRegion);
                    cairoContext.Stroke();
                }
            }

            return(true);
        }