예제 #1
0
 public ColorString AppendPushPopFg(ConsoleColor foreground, string content)
 {
     _CheckReadOnly(true);
     m_elements.Add(new SgrControlSequence(new int[] { PUSH,
                                                       CaStringUtil.ForegroundColorMap[foreground] }));
     m_elements.Add(new ContentElement(content));
     // The content might not be "pure"; it might be pre-rendered colorized text.
     m_apparentLength += CaStringUtil.Length(content);
     m_elements.Add(new SgrControlSequence(new int[] { POP }));
     return(this);
 }
예제 #2
0
        // This constructor is private, used only by the string -> ColorString implicit conversion
        // because if it is public, the C# compiler will favor it over the FormattableString constructor
        // for interpolated strings
        private ColorString(string content)
        {
            // The content might not be "pure"; it might be pre-rendered colorized text.
            var noColorLength = CaStringUtil.Length(content);

            if (noColorLength == content.Length)
            {
                m_elements.Add(new ContentElement(content));
            }
            else
            {
                // TODO: Might be handy to be able to decompose a pre-rendered color
                // string. For now we'll just dump it in.
                m_elements.Add(new ContentElement(content));
            }
            m_apparentLength = noColorLength;
        }
예제 #3
0
        public ColorString Append(string content)
        {
            _CheckReadOnly(true);
            // The content might not be "pure"; it might be pre-rendered colorized text.
            var noColorLength = CaStringUtil.Length(content);

            if (noColorLength == content.Length)
            {
                m_elements.Add(new ContentElement(content));
            }
            else
            {
                // TODO: Might be handy to be able to decompose a pre-rendered color
                // string. For now we'll just dump it in.
                m_elements.Add(new ContentElement(content));
            }
            m_apparentLength += noColorLength;
            return(this);
        }
예제 #4
0
        protected static string PadAndAlign(string s,
                                            int width,
                                            ColumnAlignment alignment,
                                            TrimLocation trimLocation)
        {
            Util.Assert(ColumnAlignment.Default != alignment);

            int len = CaStringUtil.Length(s);
            int pad = width - len;

            if (0 == pad)
            {
                return(s);
            }

            if (pad < 0)
            {
                // Oh dear... too big to fit.
                return(CaStringUtil.Truncate(s, width, true, trimLocation));
            }

            switch (alignment)
            {
            case ColumnAlignment.Left:
                return(s + new String(' ', pad));

            case ColumnAlignment.Center:
                int leftpad  = pad / 2;
                int rightpad = pad - leftpad;
                return(new String(' ', leftpad) + s + new String(' ', rightpad));

            case ColumnAlignment.Right:
                return(new String(' ', pad) + s);

            default:
                throw new ArgumentException(Util.Sprintf("Invalid ColumnAlignment value: {0}",
                                                         alignment),
                                            "alignment");
            }
        } // end PadAndAlign()
예제 #5
0
        } // end ResetState()

        private void _WriteHeaders()
        {
            ColorString headers = new ColorString(sm_tableHeaderColors);

            // Write labels:
            for (int colIdx = 0; colIdx < m_view.Columns.Count; colIdx++)
            {
                Column c = m_view.Columns[colIdx];
                headers.Append(PadAndAlign(c.Label,
                                           c.CalculatedWidth,
                                           c.CalculatedAlignment,
                                           c.TrimLocation));
                if (colIdx != (m_view.Columns.Count - 1))
                {
                    headers.Append(" ");   // separator
                }
            }
            // Clear the header color:
            headers.Append(sm_pop);

            headers.AppendLine();

            // Write -------:
            for (int colIdx = 0; colIdx < m_view.Columns.Count; colIdx++)
            {
                Column c   = m_view.Columns[colIdx];
                int    len = CaStringUtil.Length(c.Label);
                headers.Append(PadAndAlign(new String('-', Math.Min(len, c.CalculatedWidth)),
                                           c.CalculatedWidth,
                                           c.CalculatedAlignment,
                                           c.TrimLocation));
                if (colIdx != (m_view.Columns.Count - 1))
                {
                    headers.Append(" ");   // separator
                }
            }
            SafeWriteObject(headers);
        } // end _WriteHeaders()
        } // end property AutoSizeColumns


        internal void CalculateWidthsAndAlignments(int bufferWidth, PSObject exampleObj)
        {
            if (bufferWidth <= 0)
            {
                throw new ArgumentOutOfRangeException("bufferWidth");
            }

            if (m_lastUsedBufferWidth == bufferWidth)
            {
                return;
            }

            int availableWidth = bufferWidth - AccountedWidth - 1; // -1 for newline which takes a column

            if (availableWidth < (4 * AutoSizeColumns.Count))
            {
                // TODO: proper error. Or... what?
                throw new ArgumentException("View is too wide.");
            }

            m_lastUsedBufferWidth = bufferWidth;

            if (AutoSizeColumns.Count > 0)
            {
                int totalSeparatorWidth = Columns.Count - 1;
                availableWidth -= totalSeparatorWidth;
                // Note that availableWidth (and therefore perCol) could be negative.
                int perCol    = availableWidth / AutoSizeColumns.Count;
                int remainder = availableWidth - (perCol * AutoSizeColumns.Count);
                foreach (var c in AutoSizeColumns)
                {
                    int fieldWidth = 0;
                    // TODO: Maybe it would be better to just get the values for the first
                    // line of the table and use that...
                    if (c is PropertyColumn)
                    {
                        // This returns 0 if it doesn't know.
                        try
                        {
                            fieldWidth = GetWidthForProperty(exampleObj, c.Label);
                        }
                        catch (RuntimeException rte)
                        {
                            LogManager.Trace("Cannot attempt to determine width of property {0} on object of type {1}: {2}",
                                             c.Label,
                                             Util.GetGenericTypeName(exampleObj.BaseObject),
                                             Util.GetExceptionMessages(rte));
                        }
                        if (0 == fieldWidth)
                        {
                            fieldWidth = perCol;
                            if (remainder > 0)
                            {
                                remainder--;
                                fieldWidth++;
                            }
                        }
                    }
                    else
                    {
                        fieldWidth = perCol;
                        if (remainder > 0)
                        {
                            remainder--;
                            fieldWidth++;
                        }
                    }

                    c.CalculatedWidth = Math.Max(CaStringUtil.Length(c.Label), fieldWidth);
                }
            } // end if( we have auto-size columns )

            for (int colIdx = 0; colIdx < Columns.Count; colIdx++)
            {
                var c = Columns[colIdx];
                if (ColumnAlignment.Default == c.Alignment)
                {
                    if (0 == colIdx)
                    {
                        c.CalculatedAlignment = ColumnAlignment.Right;
                    }
                    else if ((Columns.Count - 1) == colIdx)
                    {
                        c.CalculatedAlignment = ColumnAlignment.Left;
                    }
                    else
                    {
                        c.CalculatedAlignment = ColumnAlignment.Center;
                    }
                }
            }
        } // end CalculateWidthsAndAlignments()