/// <summary>
        /// Updates the text renderer from the text control.
        /// </summary>
        /// <param name="value">The value.</param>
        private void SetTextRenderer(EditorViewRenderer value)
        {
            // If we had a previous renderer, disconnect the events.
            if (editorViewRenderer != null)
            {
                editorViewRenderer.LineChanged   -= OnLineChanged;
                editorViewRenderer.LinesInserted -= OnBufferChanged;
                editorViewRenderer.LinesDeleted  -= OnBufferChanged;
            }

            // Set the new indicator buffer.
            editorViewRenderer = value;

            // If we have a new indicator buffer, attach events.
            if (editorViewRenderer != null)
            {
                editorViewRenderer.LineChanged   += OnLineChanged;
                editorViewRenderer.LinesInserted += OnBufferChanged;
                editorViewRenderer.LinesDeleted  += OnBufferChanged;
            }

            // Rebuild the lines in the buffer.
            AssignIndicatorLines();
            QueueDraw();
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Sets the text renderer.
        /// </summary>
        /// <param name="value">The new <see cref="EditorView"/>, which can be
        /// <see langword="null"/>.
        /// <param>
        public void SetRenderer(EditorViewRenderer value)
        {
            // Detach events if we previously had a renderer.
            if (Renderer != null)
            {
                // Disconnect from the events.
                Renderer.LineChanged   -= OnLineChanged;
                Renderer.LinesDeleted  -= OnLineBufferLinesChanged;
                Renderer.LinesInserted -= OnLineBufferLinesChanged;

                // Remove the line buffer first.
                ClearLineBuffer();
            }

            // Set the new buffer.
            Renderer = value;

            if (Renderer != null)
            {
                // Hook up to the events.
                Renderer.LineChanged   += OnLineChanged;
                Renderer.LinesDeleted  += OnLineBufferLinesChanged;
                Renderer.LinesInserted += OnLineBufferLinesChanged;
            }

            // Set up the editor view for the changes made.
            HandleChangedLineBuffer();
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Caches information about a line into the cached line.
        /// </summary>
        /// <param name="view">The view.</param>
        /// <param name="line">The line.</param>
        public void Cache(
            EditorViewRenderer view,
            int line)
        {
            // If we already have a layout, we don't need to do anything.
            if (Layout != null)
            {
                return;
            }

            // Cache various elements of the rendering. This is an expensive
            // operation, so we want to minimize it.
            Layout         layout = view.GetLineLayout(line, LineContexts.None);
            LineBlockStyle style  = view.GetLineStyle(line, LineContexts.None);

            Style  = style;
            Layout = layout;
            Height = (int)(layout.GetPixelHeight() + style.Height);
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="CachedTextRenderer" /> class.
        /// </summary>
        /// <param name="displayContext">The display context.</param>
        /// <param name="editorViewRenderer">The text renderer.</param>
        public CachedTextRenderer(
            IDisplayContext displayContext,
            EditorViewRenderer editorViewRenderer)
            : base(displayContext, editorViewRenderer)
        {
            // Keep track of the thread we've been created on.
            thread = Thread.CurrentThread;

            // Set the cache window properties.
            access           = new ReaderWriterLockSlim(LockRecursionPolicy.NoRecursion);
            queuedLineEvents = new List <Action>();

            // Create a collection of the initial buffer lines.
            lines = new CachedLineList();

            AllocateLines();

            // Create a background loader that will attempt to calculate the
            // layout and heights of lines using the GUI's idle loop.
            backgroundUpdater = new BackgroundCachedLineUpdater(this, lines);
            backgroundUpdater.Restart();
        }
        /// <summary>
        /// Updates the indicator line with contents from the display.
        /// </summary>
        /// <param name="displayContext">The display context.</param>
        /// <param name="buffer">The buffer.</param>
        public void Update(
            IDisplayContext displayContext,
            EditorViewRenderer buffer)
        {
            // Clear out our indicators and reset our fields.
            Reset();

            // If the start and end are negative, then don't do anything.
            if (StartLineIndex < 0)
            {
                return;
            }

            // Gather up all the indicators for the lines assigned to this
            // indicator line.
            for (int lineIndex = StartLineIndex;
                 lineIndex <= EndLineIndex;
                 lineIndex++)
            {
                // Get the line indicators for that character range and add
                // them to the current range of indicators.
                IEnumerable <ILineIndicator> lineIndicators =
                    buffer.LineBuffer.GetLineIndicators(lineIndex);

                if (lineIndicators != null)
                {
                    if (indicators == null)
                    {
                        indicators = new List <ILineIndicator>();
                    }

                    indicators.AddRange(lineIndicators);
                }
            }

            // If we have indicators created, but they are empty, null out
            // the field again.
            if (indicators != null &&
                indicators.Count == 0)
            {
                indicators = null;
            }

            // We have the indicators, so set our flag.
            NeedIndicators = false;

            // If we don't have any indicators, then we aren't showing anything.
            if (indicators == null)
            {
                return;
            }

            // If we have indicators, we need to figure out how to render
            // this line.
            switch (displayContext.Theme.IndicatorRenderStyle)
            {
            case IndicatorRenderStyle.Highest:
                // Find the most important style and use that.
                SetHighestColor(displayContext);
                break;

            case IndicatorRenderStyle.Ratio:
                // Build up a ratio of all the indicators and keep the
                // list.
                SetColorRatios(displayContext);
                break;

            default:
                throw new Exception(
                          "Cannot identify indicator render style: "
                          + displayContext.Theme.IndicatorRenderStyle);
            }
        }
Ejemplo n.º 6
0
        public static void Up(EditorViewController controller)
        {
            // Extract a number of useful variable for this method.
            IDisplayContext    displayContext = controller.DisplayContext;
            TextPosition       position       = displayContext.Caret.Position;
            EditorViewRenderer buffer         = displayContext.Renderer;

            // Figure out the layout and wrapped line we are currently on.
            Layout     layout;
            int        wrappedLineIndex;
            LayoutLine wrappedLine = position.GetWrappedLine(
                displayContext, out layout, out wrappedLineIndex);

            // Figure out the X coordinate of the line. If there is an action context,
            // use that. Otherwise, calculate it from the character index of the position.
            int lineX = GetLineX(controller, wrappedLine, position);

            // Figure out which wrapped line we'll be moving the caret to.
            LinePosition linePosition = position.LinePosition;
            int          lineIndex    = linePosition.GetLineIndex(buffer.LineBuffer);

            if (wrappedLineIndex == 0)
            {
                // If we are the last line in the buffer, just do nothing.
                if (linePosition == 0)
                {
                    return;
                }

                // Move to the next line.
                lineIndex--;
                layout           = buffer.GetLineLayout(lineIndex, LineContexts.None);
                wrappedLineIndex = layout.LineCount - 1;
                wrappedLine      = layout.Lines[wrappedLineIndex];
            }
            else
            {
                // Just move down in the layout.
                wrappedLineIndex--;
                wrappedLine = layout.Lines[wrappedLineIndex];
            }

            // Adjust the X coordinate for the current line.
            lineX -= GetLeftStylePaddingPango(controller, lineIndex);

            // The wrapped line has the current wrapped line, so use the lineX
            // to figure out which character to use.
            int trailing;
            int unicodeIndex;

            wrappedLine.XToIndex(lineX, out unicodeIndex, out trailing);

            // Calculate the character position, but we have to map UTF-8
            // characters because Pango uses that instead of C# strings.
            string lineText = controller.DisplayContext.LineBuffer.GetLineText(lineIndex);

            unicodeIndex = NormalizeEmptyStrings(lineText, unicodeIndex);
            int characterIndex = PangoUtility.TranslateStringToPangoIndex(
                lineText, unicodeIndex);

            if (lineText.Length > 0 &&
                trailing > 0)
            {
                characterIndex++;
            }

            // Draw the new location of the caret.
            var caretPosition = new TextPosition(lineIndex, characterIndex);

            displayContext.ScrollToCaret(caretPosition);
        }