コード例 #1
0
ファイル: Button.cs プロジェクト: furesoft/consoleframework
        public override void Render(RenderingBuffer buffer) {
            Attr captionAttrs;
            if (Disabled) {
                captionAttrs = Colors.Blend(Color.Gray, Color.DarkGray);
            } else {
                if (HasFocus)
                    captionAttrs = Colors.Blend(Color.White, Color.DarkGreen);
                else
                    captionAttrs = Colors.Blend(Color.Black, Color.DarkGreen);
            }

            if (pressed || pressedUsingKeyboard) {
                buffer.FillRectangle(1, 0, ActualWidth - 1, ActualHeight - 1, ' ', captionAttrs);
                buffer.SetOpacityRect(0, 0, 1, ActualHeight, 3);
                buffer.FillRectangle(0, 0, 1, ActualHeight, ' ', captionAttrs);
                if (!string.IsNullOrEmpty(Caption)) {
                    RenderString(Caption, buffer, 2 + 1 +(ActualWidth - 2 * 2 - Caption.Length) / 2,
                        (ActualHeight-1)/2, ActualWidth - 2 * 2, captionAttrs);
                }
                buffer.SetOpacityRect(0, ActualHeight-1, ActualWidth, 1, 3);
                buffer.FillRectangle(0, ActualHeight - 1, ActualWidth, 1, ' ', Attr.NO_ATTRIBUTES);
            } else {
                buffer.FillRectangle(0, 0, ActualWidth - 1, ActualHeight, ' ', captionAttrs);
                if (!string.IsNullOrEmpty(Caption)) {
                    RenderString(Caption, buffer, 2 + (ActualWidth - 2 * 2 - Caption.Length) / 2, 
                        (ActualHeight - 1) / 2, ActualWidth - 2 * 2, captionAttrs);
                }
                buffer.SetPixel(0, ActualHeight-1, ' ');
                buffer.SetOpacityRect(0, ActualHeight -1, ActualWidth, 1, 3);
                buffer.FillRectangle(1, ActualHeight-1, ActualWidth - 1, 1, UnicodeTable.UpperHalfBlock, Attr.NO_ATTRIBUTES);
                buffer.SetOpacityRect(ActualWidth - 1, 0, 1, ActualHeight, 3);
                buffer.FillRectangle(ActualWidth - 1, 1, 1, ActualHeight - 2, UnicodeTable.FullBlock, Attr.NO_ATTRIBUTES);
                buffer.SetPixel(ActualWidth - 1, 0, UnicodeTable.LowerHalfBlock);
            }
        }
コード例 #2
0
 public override void Render( RenderingBuffer buffer )
 {
     Attr attr = Colors.Blend( Color.DarkCyan, Color.DarkBlue );
     buffer.FillRectangle(0, 0, ActualWidth, ActualHeight, UnicodeTable.MediumShade, attr);
     int filled = ( int ) ( ActualWidth*( Percent*0.01 ) );
     buffer.FillRectangle(0, 0, Math.Min( filled, ActualWidth ), ActualHeight, UnicodeTable.DarkShade, attr);
 }
コード例 #3
0
ファイル: Panel.cs プロジェクト: KSLcom/consoleframework
 /// <summary>
 /// Рисует исключительно себя - просто фон.
 /// </summary>
 /// <param name="buffer"></param>
 public override void Render(RenderingBuffer buffer)
 {
     for (int x = 0; x < ActualWidth; ++x) {
         for (int y = 0; y < ActualHeight; ++y) {
             buffer.SetPixel(x, y, ' ', Attr.BACKGROUND_BLUE |
                 Attr.BACKGROUND_GREEN | Attr.BACKGROUND_RED | Attr.FOREGROUND_BLUE |
                 Attr.FOREGROUND_GREEN | Attr.FOREGROUND_RED | Attr.FOREGROUND_INTENSITY);
             buffer.SetOpacity( x, y, 4 );
         }
     }
 }
コード例 #4
0
 public override void Render(RenderingBuffer buffer) {
     Attr attr = Colors.Blend(Color.Black, Color.DarkYellow);
     buffer.FillRectangle( 0, 0, ActualWidth, ActualHeight, ' ', attr);
     for (int x = 0; x < ActualWidth; ++x) {
         for (int y = 0; y < ActualHeight; ++y) {
             if (y == 0 && x < text.Length) {
                 buffer.SetPixel(x, y, text[x], attr);
             }
         }
     }
     buffer.SetOpacityRect(0, 0, ActualWidth, ActualHeight, 3);
 }
コード例 #5
0
 public void CopyFrom(RenderingBuffer renderingBuffer) {
     this.buffer = new CHAR_INFO[renderingBuffer.width, renderingBuffer.height];
     this.opacityMatrix = new int[renderingBuffer.width, renderingBuffer.height];
     this.width = renderingBuffer.width;
     this.height = renderingBuffer.height;
     //
     for (int x = 0; x < width; x++) {
         for (int y = 0; y < height; y++) {
             buffer[x, y] = renderingBuffer.buffer[x, y];
             opacityMatrix[x, y] = renderingBuffer.opacityMatrix[x, y];
         }
     }
 }
コード例 #6
0
ファイル: TabControl.cs プロジェクト: KSLcom/consoleframework
        public override void Render( RenderingBuffer buffer )
        {
            Attr attr = Colors.Blend( Color.Black, Color.DarkGreen );
            Attr inactiveAttr = Colors.Blend( Color.DarkGray, Color.DarkGreen );

            // Transparent background for borders
            buffer.SetOpacityRect( 0, 0, ActualWidth, ActualHeight, 3 );

            buffer.FillRectangle( 0, 0, ActualWidth, ActualHeight, ' ', attr );

            // Transparent child content part
            if ( ActualWidth > 2 && ActualHeight > 3 )
                buffer.SetOpacityRect( 1, 3, ActualWidth - 2, ActualHeight - 4, 2 );

            renderBorderSafe( buffer, 0, 2, Math.Max( getTabHeaderWidth( ) - 1, ActualWidth - 1 ), ActualHeight - 1 );

            // Start to render header
            buffer.FillRectangle( 0, 0, ActualWidth, Math.Min( 2, ActualHeight ), ' ', attr );

            int x = 0;

            // Render tabs before active tab
            for ( int tab = 0; tab < tabDefinitions.Count; x += TabDefinitions[ tab++ ].Title.Length + 3 ) {
                var tabDefinition = TabDefinitions[ tab ];
                if ( tab <= activeTabIndex ) {
                    buffer.SetPixelSafe( x, 0, UnicodeTable.SingleFrameTopLeftCorner );
                    buffer.SetPixelSafe( x, 1, UnicodeTable.SingleFrameVertical );
                }
                if ( tab == activeTabIndex ) {
                    buffer.SetPixelSafe( x, 2,
                        activeTabIndex == 0 ? UnicodeTable.SingleFrameVertical : UnicodeTable.SingleFrameBottomRightCorner );
                }
                for ( int i = 0; i < tabDefinition.Title.Length + 2; i++ ) {
                    buffer.SetPixelSafe( x + 1 + i, 0, UnicodeTable.SingleFrameHorizontal );
                    if ( tab == activeTabIndex )
                        buffer.SetPixelSafe( x + 1 + i, 2, ' ' );
                }
                buffer.RenderStringSafe( " " + tabDefinition.Title + " ", x + 1, 1,
                    activeTabIndex == tab ? attr : inactiveAttr );
                if ( tab >= activeTabIndex ) {
                    buffer.SetPixelSafe( x + tabDefinition.Title.Length + 3, 0, UnicodeTable.SingleFrameTopRightCorner );
                    buffer.SetPixelSafe( x + tabDefinition.Title.Length + 3, 1, UnicodeTable.SingleFrameVertical );
                }
                if ( tab == activeTabIndex ) {
                    buffer.SetPixelSafe( x + tabDefinition.Title.Length + 3, 2,
                        activeTabIndex == tabDefinitions.Count - 1 && ActualWidth - 1 == x + tabDefinition.Title.Length + 3
                            ? UnicodeTable.SingleFrameVertical
                            : UnicodeTable.SingleFrameBottomLeftCorner );
                }
            }
        }
コード例 #7
0
ファイル: CheckBox.cs プロジェクト: furesoft/consoleframework
        public override void Render(RenderingBuffer buffer) {
            Attr captionAttrs;
            if (HasFocus)
                captionAttrs = Colors.Blend(Color.White, Color.DarkGreen);
            else
                captionAttrs = Colors.Blend(Color.Black, Color.DarkGreen);

            Attr buttonAttrs = captionAttrs;
//            if ( pressed )
//                buttonAttrs = Colors.Blend(Color.Black, Color.DarkGreen);

            buffer.SetOpacityRect( 0, 0, ActualWidth, ActualHeight, 3 );

            buffer.SetPixel(0, 0, pressed ? '<' : '[', buttonAttrs);
            buffer.SetPixel(1, 0, Checked ? 'X' : ' ', buttonAttrs);
            buffer.SetPixel(2, 0, pressed ? '>' : ']', buttonAttrs);
            buffer.SetPixel(3, 0, ' ', buttonAttrs);
            if (null != caption)
                RenderString( caption, buffer, 4, 0, ActualWidth - 4, captionAttrs );
        }
コード例 #8
0
ファイル: GroupBox.cs プロジェクト: furesoft/consoleframework
        public override void Render(RenderingBuffer buffer) {
            Attr attr = Colors.Blend( Color.Black, Color.DarkGreen );

            // прозрачный фон для рамки
            buffer.SetOpacityRect( 0, 0, ActualWidth, ActualHeight, 3 );
            // полностью прозрачный внутри
            if (ActualWidth > 2 && ActualHeight > 2)
                buffer.SetOpacityRect( 1, 1, ActualWidth-2, ActualHeight-2, 2 );
            // title
            int titleRenderedWidth = 0;
            if ( !string.IsNullOrEmpty( title ) )
                titleRenderedWidth = RenderString( title, buffer, 2, 0, ActualWidth - 4, attr );
            // upper border
            for ( int x = 0; x < ActualWidth; x++ ) {
                char? c = null;
                if ( x == 0 )
                    c = UnicodeTable.SingleFrameTopLeftCorner;
                else if (x == ActualWidth - 1)
                    c = UnicodeTable.SingleFrameTopRightCorner;
                else if (x == 1 || x == 2 + titleRenderedWidth)
                    c = ' ';
                else if ( x > 2 + titleRenderedWidth && x < ActualWidth - 1 )
                    c = UnicodeTable.SingleFrameHorizontal;
                if (c != null)
                    buffer.SetPixel( x, 0, c.Value, attr );
            }
            // left border
            if (ActualHeight > 2)
                buffer.FillRectangle(0, 1, 1, ActualHeight - 2, UnicodeTable.SingleFrameVertical, attr);
            if (ActualHeight > 1)
                buffer.SetPixel(0, ActualHeight - 1, UnicodeTable.SingleFrameBottomLeftCorner, attr);
            // right border
            if ( ActualWidth > 1 ) {
                if (ActualHeight > 2)
                    buffer.FillRectangle(ActualWidth - 1, 1, 1, ActualHeight - 2, UnicodeTable.SingleFrameVertical, attr);
                if (ActualHeight > 1)
                    buffer.SetPixel(ActualWidth - 1, ActualHeight - 1, UnicodeTable.SingleFrameBottomRightCorner, attr);
            }
            // bottom border
            if ( ActualHeight > 1 && ActualWidth > 2 ) {
                buffer.FillRectangle(1, ActualHeight - 1, ActualWidth - 2, 1, UnicodeTable.SingleFrameHorizontal, attr);
            }
        }
コード例 #9
0
 public override void Render(RenderingBuffer buffer)
 {
     buffer.FillRectangle(0, 0, ActualWidth, ActualHeight, ' ', Attr.BACKGROUND_BLUE);
 }
コード例 #10
0
        /// <summary>
        /// Оверлоад для оптимизированного наложения в случае, когда известно, что в дочернем
        /// контроле поменялась лишь часть, идентифицируемая параметром affectedRect.
        /// Будет обработана только эта часть дочернего контрола, и количество операций уменьшится.
        /// </summary>
        /// <param name="childBuffer"></param>
        /// <param name="actualOffset"></param>
        /// <param name="childRenderSize"></param>
        /// <param name="renderSlotRect"></param>
        /// <param name="layoutClip"></param>
        /// <param name="affectedRect">Прямоугольник в дочернем контроле, который был изменен.</param>
        public void ApplyChild(RenderingBuffer childBuffer, Vector actualOffset,
            Size childRenderSize, Rect renderSlotRect,
            Rect layoutClip, Rect? affectedRect)
        {
            // Считаем finalRect - прямоугольник относительно parent, который нужно закрасить
            Rect finalRect = layoutClip;

            if (affectedRect != null)
                finalRect.Intersect(affectedRect.Value);

            // Если child.RenderSlotRect больше child.RenderSize, а rendering buffer
            // дочернего контрола больше его RenderSize (такое бывает после уменьшения
            // размеров контрола - т.к. буфер может только увеличиваться, но не уменьшаться) -
            // то нам нужно либо передать в метод ApplyChild и child.RenderSize, либо
            // выполнить пересечение заранее
            finalRect.Intersect(new Rect(new Point(0, 0), childRenderSize));

            // Because cannot call Offset() method of empty rect
            if ( finalRect.IsEmpty ) return;

            finalRect.Offset(actualOffset);
            finalRect.Intersect( renderSlotRect );

            // Нужно также учесть размеры буфера текущего контрола
            finalRect.Intersect( new Rect(new Point(0, 0), new Size(this.width, this.height)) );

            for ( int x = finalRect.Left; x < finalRect.Right; x++ ) {
                int parentX = x;
                int childX = parentX - actualOffset.x;
                for ( int y = finalRect.Top; y < finalRect.Bottom; y++ ) {
                    int parentY = y;
                    int childY = parentY - actualOffset.y;

                    CHAR_INFO charInfo = childBuffer.buffer[childX, childY];
                    int opacity = childBuffer.opacityMatrix[childX, childY];

                    // Для полностью прозрачных пикселей родительского буфера - присваиваем и значение
                    // пикселя, и значение opacity, дальше дело за следующим родителем
                    if ( this.opacityMatrix[ parentX, parentY ] == 2 || this.opacityMatrix[ parentX, parentY ] == 6 ) {
                        this.buffer[ parentX, parentY ] = charInfo;
                        this.opacityMatrix[ parentX, parentY ] = opacity;
                    } else {
                        // В остальных случаях opacity родительского буфера остаётся, а
                        // сам пиксель зависит от opacity дочернего элемента
                        if ( opacity == 0 || opacity == 4 ) {
                            this.buffer[ parentX, parentY ] = charInfo;
                        } else if ( opacity == 1 || opacity == 5 ) {
                            charInfo.Attributes = Colors.Blend( Color.DarkGray, Color.Black );
                            charInfo.UnicodeChar = buffer[ parentX, parentY ].UnicodeChar;
                            buffer[ parentX, parentY ] = charInfo;
                        } else if ( opacity == 3 || opacity == 7 ) {
                            // берем фоновые атрибуты символа из родительского буфера
                            Attr parentAttr = buffer[ parentX, parentY ].Attributes;
                            if ( ( parentAttr & Attr.BACKGROUND_BLUE ) == Attr.BACKGROUND_BLUE ) {
                                charInfo.Attributes |= Attr.BACKGROUND_BLUE;
                            } else {
                                charInfo.Attributes &= ~Attr.BACKGROUND_BLUE;
                            }
                            if ( ( parentAttr & Attr.BACKGROUND_GREEN ) == Attr.BACKGROUND_GREEN ) {
                                charInfo.Attributes |= Attr.BACKGROUND_GREEN;
                            } else {
                                charInfo.Attributes &= ~Attr.BACKGROUND_GREEN;
                            }
                            if ( ( parentAttr & Attr.BACKGROUND_RED ) == Attr.BACKGROUND_RED ) {
                                charInfo.Attributes |= Attr.BACKGROUND_RED;
                            } else {
                                charInfo.Attributes &= ~Attr.BACKGROUND_RED;
                            }
                            if ( ( parentAttr & Attr.BACKGROUND_INTENSITY ) == Attr.BACKGROUND_INTENSITY ) {
                                charInfo.Attributes |= Attr.BACKGROUND_INTENSITY;
                            } else {
                                charInfo.Attributes &= ~Attr.BACKGROUND_INTENSITY;
                            }
                            buffer[ parentX, parentY ] = charInfo;
                        }
                    }
                }
            }
        }
コード例 #11
0
ファイル: Menu.cs プロジェクト: CxSoftware/consoleframework
        public override void Render(RenderingBuffer buffer) {
            Attr captionAttrs;
            if (HasFocus)
                captionAttrs = Colors.Blend(Color.Black, Color.DarkGreen);
            else
                captionAttrs = Colors.Blend(Color.Black, Color.Gray);

            buffer.FillRectangle(0, 0, ActualWidth, ActualHeight, UnicodeTable.SingleFrameHorizontal, captionAttrs);
        }
コード例 #12
0
ファイル: Menu.cs プロジェクト: CxSoftware/consoleframework
        /// <summary>
        /// Renders string using attr, but if character is prefixed with underscore,
        /// symbol will use specialAttrs instead. To render underscore pass two underscores.
        /// Example: "_File" renders File when 'F' is rendered using specialAttrs.
        /// </summary>
        private static int renderString( string s, RenderingBuffer buffer,
                                         int x, int y, int maxWidth, Attr attr,
                                         Attr specialAttr) {
            bool underscore = false;
            int j = 0;
            for ( int i = 0; i < s.Length && j < maxWidth; i++ ) {
                char c;
                if ( underscore ) {
                    c = s[ i ];
                } else {
                    if ( s[ i ] == '_' ) {
                        underscore = true;
                        continue;
                    } else {
                        c = s[ i ];
                    }
                }

                Attr a;
                if ( j + 2 >= maxWidth && j >= 2 && s.Length > maxWidth ) {
                    c = '.';
                    a = attr;
                } else {
                    a = underscore ? specialAttr : attr;
                }
                buffer.SetPixel( x + j, y, c, a );

                j++;
                underscore = false;
            }
            return j;
        }
コード例 #13
0
        public override void Render(RenderingBuffer buffer) {
            Attr attr = Colors.Blend(Color.DarkCyan, Color.DarkBlue);

            buffer.SetOpacityRect( 0,0, ActualWidth, ActualHeight, 2 );

            if ( horizontalScrollVisible ) {
                buffer.SetOpacityRect( 0, ActualHeight-1, ActualWidth, 1, 0 );
                buffer.SetPixel(0, ActualHeight - 1, UnicodeTable.ArrowLeft, attr); // ◄
                // оставляем дополнительный пиксель справа, если одновременно видны оба скроллбара
                int rightOffset = verticalScrollVisible ? 1 : 0;
                if ( ActualWidth > 2 + rightOffset ) {
                    buffer.FillRectangle(1, ActualHeight - 1, ActualWidth - (2 + rightOffset), 1, 
                        UnicodeTable.MediumShade, attr); // ▒
                }
                if ( ActualWidth > 1 + rightOffset ) {
                    buffer.SetPixel(ActualWidth - (1 + rightOffset), ActualHeight - 1,
                        UnicodeTable.ArrowRight, attr); // ►
                }

                // определим, в каком месте находится ползунок
                if ( ActualWidth > 3 + ( verticalScrollVisible ? 1 : 0 ) ) {
                    int remainingWidth = ActualWidth - ( verticalScrollVisible ? 1 : 0 );
                    int extraWidth = Content.RenderSize.Width - remainingWidth;
                    int pages = extraWidth/( remainingWidth - 2 - 1 );

                    //Debugger.Log( 1, "", "pages: " + pages + "\n" );

                    int scrollerPos;
                    if ( pages == 0 ) {
                        double posInDelta = ( remainingWidth*1.0 - 2 - 1 )/extraWidth;
                        //Debugger.Log( 1, "", "posInDelta: " + posInDelta + "\n" );
                        scrollerPos = ( int ) Math.Round( posInDelta*deltaX );
                    } else {
                        double deltaInPos = ( extraWidth*1.0 )/( remainingWidth - 2 - 1 );
                        //Debugger.Log( 1, "", "deltaX/( deltaInPos ): " + deltaX/( deltaInPos ) + "\n" );
                        scrollerPos = ( int ) Math.Round( deltaX/( deltaInPos ) );
                    }

                    buffer.SetPixel(1 + scrollerPos, ActualHeight - 1, UnicodeTable.BlackSquare, attr); // ■
                } else if ( ActualWidth == 3 + ( verticalScrollVisible ? 1 : 0 ) ) {
                    buffer.SetPixel(1, ActualHeight - 1, UnicodeTable.BlackSquare, attr); // ■
                }
            }
            if ( verticalScrollVisible ) {
                buffer.SetOpacityRect(ActualWidth-1, 0, 1, ActualHeight, 0);

                buffer.SetPixel(ActualWidth - 1, 0, UnicodeTable.ArrowUp, attr); // ▲
                // оставляем дополнительный пиксель снизу, если одновременно видны оба скроллбара
                int downOffset = horizontalScrollVisible ? 1 : 0;
                if ( ActualHeight > 2 + downOffset ) {
                    buffer.FillRectangle(ActualWidth - 1, 1, 1, ActualHeight - (2 + downOffset), UnicodeTable.MediumShade, attr); // ▒
                }
                if ( ActualHeight > 1 + downOffset ) {
                    buffer.SetPixel(ActualWidth - 1, ActualHeight - (1 + downOffset), UnicodeTable.ArrowDown, attr); // ▼
                }

                // определим, в каком месте находится ползунок
                if ( ActualHeight > 3 + ( horizontalScrollVisible ? 1 : 0 ) ) {
                    int remainingHeight = ActualHeight - (horizontalScrollVisible ? 1 : 0);
                    int extraHeight = Content.RenderSize.Height - remainingHeight;
                    int pages = extraHeight/( remainingHeight - 2 - 1 );

                    //Debugger.Log( 1, "", "pages: " + pages + "\n" );

                    int scrollerPos;
                    if ( pages == 0 ) {
                        double posInDelta = ( remainingHeight*1.0 - 2 - 1 )/extraHeight;
                        //Debugger.Log( 1, "", "posInDelta: " + posInDelta + "\n" );
                        scrollerPos = ( int ) Math.Round( posInDelta*deltaY );
                    } else {
                        double deltaInPos = ( extraHeight*1.0 )/( remainingHeight - 2 - 1 );
                        //Debugger.Log( 1, "", "deltaY/( deltaInPos ): " + deltaY/( deltaInPos ) + "\n" );
                        scrollerPos = ( int ) Math.Round( deltaY/( deltaInPos ) );
                    }

                    buffer.SetPixel(ActualWidth - 1, 1 + scrollerPos, UnicodeTable.BlackSquare, attr); // ■
                } else if ( ActualHeight == 3 + ( horizontalScrollVisible ? 1 : 0 ) ) {
                    buffer.SetPixel(ActualWidth - 1, 1, UnicodeTable.BlackSquare, attr); // ■
                }
            }
            if ( horizontalScrollVisible && verticalScrollVisible ) {
                buffer.SetPixel(ActualWidth - 1, ActualHeight - 1, UnicodeTable.SingleFrameBottomRightCorner, attr); // ┘
            }
        }
コード例 #14
0
ファイル: Window.cs プロジェクト: furesoft/consoleframework
 protected void RenderBorders( RenderingBuffer buffer, Point a, Point b, bool singleOrDouble, Attr attrs ) {
     if ( singleOrDouble ) {
         // Corners
         buffer.SetPixel(a.X, a.Y, UnicodeTable.SingleFrameTopLeftCorner, attrs);
         buffer.SetPixel(b.X, b.Y, UnicodeTable.SingleFrameBottomRightCorner, attrs);
         buffer.SetPixel(a.X, b.Y, UnicodeTable.SingleFrameBottomLeftCorner, attrs);
         buffer.SetPixel(b.X, a.Y, UnicodeTable.SingleFrameTopRightCorner, attrs);
         // Horizontal & vertical frames
         buffer.FillRectangle(a.X + 1, a.Y, b.X - a.X - 1, 1, UnicodeTable.SingleFrameHorizontal, attrs);
         buffer.FillRectangle(a.X + 1, b.Y, b.X - a.X - 1, 1, UnicodeTable.SingleFrameHorizontal, attrs);
         buffer.FillRectangle(a.X, a.Y + 1, 1, b.Y - a.Y - 1, UnicodeTable.SingleFrameVertical, attrs);
         buffer.FillRectangle(b.X, a.Y + 1, 1, b.Y - a.Y - 1, UnicodeTable.SingleFrameVertical, attrs);
     } else {
         // Corners
         buffer.SetPixel( a.X, a.Y, UnicodeTable.DoubleFrameTopLeftCorner, attrs );
         buffer.SetPixel( b.X, b.Y, UnicodeTable.DoubleFrameBottomRightCorner, attrs );
         buffer.SetPixel( a.X, b.Y, UnicodeTable.DoubleFrameBottomLeftCorner, attrs );
         buffer.SetPixel( b.X, a.Y, UnicodeTable.DoubleFrameTopRightCorner, attrs );
         // Horizontal & vertical frames
         buffer.FillRectangle( a.X + 1, a.Y, b.X - a.X - 1, 1, UnicodeTable.DoubleFrameHorizontal, attrs );
         buffer.FillRectangle( a.X + 1, b.Y, b.X - a.X - 1, 1, UnicodeTable.DoubleFrameHorizontal, attrs );
         buffer.FillRectangle( a.X, a.Y + 1, 1, b.Y - a.Y - 1, UnicodeTable.DoubleFrameVertical, attrs );
         buffer.FillRectangle( b.X, a.Y + 1, 1, b.Y - a.Y - 1, UnicodeTable.DoubleFrameVertical, attrs );
     }
 }
コード例 #15
0
ファイル: Renderer.cs プロジェクト: KSLcom/consoleframework
 private RenderingBuffer getOrCreateFullBufferForControl(Control control)
 {
     RenderingBuffer value;
     if (fullBuffers.TryGetValue(control, out value)) {
         return value;
     } else {
         RenderingBuffer buffer = new RenderingBuffer(control.ActualWidth, control.ActualHeight);
         fullBuffers.Add(control, buffer);
         return buffer;
     }
 }
コード例 #16
0
ファイル: Renderer.cs プロジェクト: znamenap/consoleframework
        private RenderingBuffer processControl(Control control, List <Control> revalidatedControls)
        {
            RenderingBuffer buffer     = getOrCreateBufferForControl(control);
            RenderingBuffer fullBuffer = getOrCreateFullBufferForControl(control);
            //
            LayoutInfo lastLayoutInfo = control.lastLayoutInfo;
            LayoutInfo layoutInfo     = control.layoutInfo;

            //
            control.Measure(lastLayoutInfo.measureArgument);
            control.Arrange(lastLayoutInfo.renderSlotRect);
            // if lastLayoutInfo eq layoutInfo we can use last rendered buffer
//            if (layoutInfo.Equals(lastLayoutInfo) && lastLayoutInfo.validity == LayoutValidity.Render) {
            if (checkRenderingWasNotChangedRecursively(control))
            {
                if (control.SetValidityToRender())
                {
                    revalidatedControls.Add(control);
                }
                return(fullBuffer);
            }
            // replace buffers if control has grown
            if (layoutInfo.renderSize.width > buffer.Width || layoutInfo.renderSize.height > buffer.Height)
            {
                buffer               = new RenderingBuffer(layoutInfo.renderSize.width, layoutInfo.renderSize.height);
                fullBuffer           = new RenderingBuffer(layoutInfo.renderSize.width, layoutInfo.renderSize.height);
                buffers[control]     = buffer;
                fullBuffers[control] = fullBuffer;
            }
            // otherwise we should assemble full rendered buffer using childs
            buffer.Clear();
            if (control.RenderSize.Width != 0 && control.RenderSize.Height != 0)
            {
                control.Render(buffer);
            }
            //
            fullBuffer.CopyFrom(buffer);
            foreach (Control child in control.Children)
            {
                if (child.Visibility == Visibility.Visible)
                {
                    RenderingBuffer fullChildBuffer = processControl(child, revalidatedControls);
                    fullBuffer.ApplyChild(fullChildBuffer, child.ActualOffset,
                                          child.RenderSize, child.RenderSlotRect, child.LayoutClip);
                }
                else
                {
                    // чтобы следующий Invalidate для этого контрола
                    // перезаписал lastLayoutInfo
                    if (child.SetValidityToRender())
                    {
                        revalidatedControls.Add(child);
                    }
                }
            }

            // Save overlappingRect for each control child
            refreshChildrenLastOverlappedRects(control, false);

            if (control.SetValidityToRender())
            {
                revalidatedControls.Add(control);
            }
            return(fullBuffer);
        }
コード例 #17
0
ファイル: Renderer.cs プロジェクト: znamenap/consoleframework
        private void updateLayout(Control control, List <Control> revalidatedControls)
        {
            LayoutInfo lastLayoutInfo = control.lastLayoutInfo;

            // работаем с родительским элементом управления
            if (control.Parent != null)
            {
                bool needUpdateParentLayout = true;
                // если размер текущего контрола не изменился, то состояние ревалидации не распространяется
                // вверх по дереву элементов, и мы переходим к работе с дочерними элементами
                // в противном случае мы добавляем родительский элемент в конец очереди ревалидации, и
                // возвращаем управление
                if (lastLayoutInfo.validity != LayoutValidity.Nothing)
                {
                    control.Measure(lastLayoutInfo.measureArgument);
//                    if (lastLayoutInfo.unclippedDesiredSize == control.layoutInfo.unclippedDesiredSize) {
                    if (checkDesiredSizeNotChangedRecursively(control))
                    {
                        needUpdateParentLayout = false;
                    }
                }
                if (needUpdateParentLayout)
                {
                    // mark the parent control for invalidation too and enqueue them
                    control.Parent.Invalidate();
                    // мы можем закончить с этим элементом, поскольку мы уже добавили
                    // в конец очереди его родителя, и мы все равно вернемся к нему в след. раз
                    return;
                }
            }
            // работаем с дочерними элементами управления
            // вызываем для текущего контрола Measure&Arrange с последними значениями аргументов
            if (lastLayoutInfo.validity == LayoutValidity.Nothing && control.Parent != null)
            {
                throw new InvalidOperationException("Assertion failed.");
            }
            // rootElement - особый случай
            if (control.Parent == null)
            {
                if (control != RootElement)
                {
                    throw new InvalidOperationException("Control has no parent but is not known rootElement.");
                }
                control.Measure(RootElementRect.Size);
                control.Arrange(RootElementRect);
            }
            else
            {
                control.Measure(lastLayoutInfo.measureArgument);
                control.Arrange(lastLayoutInfo.renderSlotRect);
            }
            // update render buffers of current control and its children
            RenderingBuffer buffer     = getOrCreateBufferForControl(control);
            RenderingBuffer fullBuffer = getOrCreateFullBufferForControl(control);
            // replace buffers if control has grown
            LayoutInfo layoutInfo = control.layoutInfo;

            if (layoutInfo.renderSize.width > buffer.Width || layoutInfo.renderSize.height > buffer.Height)
            {
                buffer               = new RenderingBuffer(layoutInfo.renderSize.width, layoutInfo.renderSize.height);
                fullBuffer           = new RenderingBuffer(layoutInfo.renderSize.width, layoutInfo.renderSize.height);
                buffers[control]     = buffer;
                fullBuffers[control] = fullBuffer;
            }
            buffer.Clear();
            if (control.RenderSize.Width != 0 && control.RenderSize.Height != 0)
            {
                control.Render(buffer);
            }
            // проверяем дочерние контролы - если их layoutInfo не изменился по сравнению с последним,
            // то мы можем взять их последний renderBuffer без обновления и применить к текущему контролу
            fullBuffer.CopyFrom(buffer);
            IList <Control> children = control.Children;

            foreach (Control child in children)
            {
                if (child.Visibility == Visibility.Visible)
                {
                    RenderingBuffer fullChildBuffer = processControl(child, revalidatedControls);
                    fullBuffer.ApplyChild(fullChildBuffer, child.ActualOffset,
                                          child.RenderSize,
                                          child.RenderSlotRect, child.LayoutClip);
                }
                else
                {
                    // чтобы следующий Invalidate перезаписал lastLayoutInfo
                    if (child.SetValidityToRender())
                    {
                        revalidatedControls.Add(child);
                    }
                }
            }

            // Save overlappingRect for each control child
            refreshChildrenLastOverlappedRects(control, false);

            if (control.SetValidityToRender())
            {
                revalidatedControls.Add(control);
            }
            addControlToRenderingUpdatedList(control);
        }
コード例 #18
0
ファイル: Renderer.cs プロジェクト: znamenap/consoleframework
        /// <summary>
        /// Получает для указанного контрола full render buffer и применяет его последовательно
        /// ко всем родительским элементам управления, вплоть до изображения на экране.
        /// Возвращает прямоугольник, необходимый для ревалидации на экране (affected rect).
        /// Учитывает Z-Order контролов-соседей (если родительский контрол имеет несколько дочерних, они могут перекрывать
        /// друг друга).
        /// Первый вызов производится с affectedRect = control.RenderSize.
        /// </summary>
        /// <returns>Affected rectangle in canvas should be copyied to console screen.</returns>
        private Rect applyChangesToCanvas(Control control, Rect affectedRect)
        {
            // если системой лайаута были определены размеры дочернего контрола, превышающие размеры слота
            // (такое может произойти, если дочерний контрол игнорирует переданные аргументы в MeasureOverride
            // и ArrangeOverride), то в этом месте может прийти affectedRect, выходящий за рамки
            // текущего RenderSize контрола, и мы должны выполнить intersection для корректного наложения
            affectedRect.Intersect(new Rect(new Point(0, 0), control.RenderSize));
            RenderingBuffer fullBuffer = getOrCreateFullBufferForControl(control);

            if (control.Parent != null)
            {
                RenderingBuffer fullParentBuffer = getOrCreateFullBufferForControl(control.Parent);
                // если буфер контрола содержит opacity пиксели в affectedRect, то мы вынуждены переинициализировать
                // буфер парента целиком (не вызывая Render, конечно, но переналожением буферов дочерних элементов)
                if (fullBuffer.ContainsOpacity(affectedRect))
                {
                    fullParentBuffer.Clear();
                    fullParentBuffer.CopyFrom(getOrCreateBufferForControl(control.Parent));
                    foreach (Control child in control.Parent.Children)
                    {
                        if (child.Visibility == Visibility.Visible)
                        {
                            RenderingBuffer childBuffer = getOrCreateFullBufferForControl(child);
                            fullParentBuffer.ApplyChild(childBuffer, child.ActualOffset,
                                                        child.RenderSize, child.RenderSlotRect, child.LayoutClip);
                        }
                    }
                }

                if (control.Visibility == Visibility.Visible)
                {
                    if (affectedRect == new Rect(new Point(0, 0), control.RenderSize))
                    {
                        fullParentBuffer.ApplyChild(fullBuffer, control.ActualOffset,
                                                    control.RenderSize, control.RenderSlotRect, control.LayoutClip);
                    }
                    else
                    {
                        fullParentBuffer.ApplyChild(fullBuffer, control.ActualOffset,
                                                    control.RenderSize, control.RenderSlotRect, control.LayoutClip,
                                                    affectedRect);
                    }
                }

                // определим соседей контрола, которые могут перекрывать его
                IList <Control> neighbors = control.Parent.GetChildrenOrderedByZIndex();

                // восстанавливаем изображение поверх обновленного контрола, если
                // имеются контролы, лежащие выше по z-order
                int controlIndex = neighbors.IndexOf(control);
                // начиная с controlIndex + 1 в списке лежат контролы с z-index больше чем z-index текущего контрола
                for (int i = controlIndex + 1; i < neighbors.Count; i++)
                {
                    Control neighbor = neighbors[i];
                    fullParentBuffer.ApplyChild(getOrCreateFullBufferForControl(neighbor),
                                                neighbor.ActualOffset, neighbor.RenderSize,
                                                neighbor.RenderSlotRect, neighbor.LayoutClip);
                }
                Rect parentAffectedRect = control.RenderSlotRect;
                parentAffectedRect.Intersect(new Rect(affectedRect.x + control.ActualOffset.x,
                                                      affectedRect.y + control.ActualOffset.y,
                                                      affectedRect.width,
                                                      affectedRect.height));
                // нет смысла продолжать подъем вверх по дереву, если контрола точно уже не видно
                if (parentAffectedRect.IsEmpty)
                {
                    return(Rect.Empty);
                }
                return(applyChangesToCanvas(control.Parent, parentAffectedRect));
            }
            else
            {
                if (control != RootElement)
                {
                    throw new InvalidOperationException("Assertion failed.");
                }

                // мы добрались до экрана консоли
                fullBuffer.CopyToPhysicalCanvas(Canvas, affectedRect, RootElementRect.TopLeft);
                return(affectedRect);
            }
        }
コード例 #19
0
ファイル: ComboBox.cs プロジェクト: KSLcom/consoleframework
        public override void Render(RenderingBuffer buffer)
        {
            Attr attrs;
            if ( HasFocus ) {
                attrs = Colors.Blend(Color.White, Color.DarkGreen);
            } else attrs = Colors.Blend( Color.Black, Color.DarkCyan );

            buffer.SetPixel( 0, 0, ' ', attrs );
            int usedForCurrentItem = 0;
            if ( Items.Count != 0 && ActualWidth > 4 ) {
                usedForCurrentItem = RenderString(Items[SelectedItemIndex ?? 0], buffer, 1, 0, ActualWidth - 4, attrs);
            }
            buffer.FillRectangle( 1 + usedForCurrentItem, 0, ActualWidth - (usedForCurrentItem + 1), 1, ' ', attrs );
            if (ActualWidth > 2)
            {
                buffer.SetPixel(ActualWidth - 2, 0, opened ? '^' : 'v', attrs);
            }
        }
コード例 #20
0
ファイル: ComboBox.cs プロジェクト: KSLcom/consoleframework
            public override void Render(RenderingBuffer buffer)
            {
                Attr borderAttrs = Colors.Blend(Color.Black, Color.DarkCyan);

                // Background
                buffer.FillRectangle(1, 1, this.ActualWidth - 1, this.ActualHeight - 1, ' ', borderAttrs);

                // First row and first column are transparent
                // Column is also transparent for mouse events
                buffer.SetOpacityRect( 0,0,ActualWidth, 1, 2 );
                buffer.SetOpacityRect( 0, 1, 1, ActualHeight-1, 6 );
                if ( shadow ) {
                    buffer.SetOpacity( 1, ActualHeight - 1, 2+4 );
                    buffer.SetOpacity( ActualWidth - 1, 0, 2+4 );
                    buffer.SetOpacityRect( ActualWidth - 1, 1, 1, ActualHeight - 1, 1+4 );
                    buffer.FillRectangle(ActualWidth - 1, 1, 1, ActualHeight - 1, UnicodeTable.FullBlock, borderAttrs);
                    buffer.SetOpacityRect( 2, ActualHeight - 1, ActualWidth - 2, 1, 3+4 );
                    buffer.FillRectangle(2, ActualHeight - 1, ActualWidth - 2, 1, UnicodeTable.UpperHalfBlock,
                                          Attr.NO_ATTRIBUTES );
                }
            }
コード例 #21
0
ファイル: Grid.cs プロジェクト: CxSoftware/consoleframework
 public override void Render( RenderingBuffer buffer ) {
     buffer.SetOpacityRect( 0, 0, ActualWidth, ActualHeight, 2 );
 }
コード例 #22
0
ファイル: Renderer.cs プロジェクト: KSLcom/consoleframework
        private RenderingBuffer processControl(Control control, List<Control> revalidatedControls)
        {
            RenderingBuffer buffer = getOrCreateBufferForControl(control);
            RenderingBuffer fullBuffer = getOrCreateFullBufferForControl(control);
            //
            LayoutInfo lastLayoutInfo = control.lastLayoutInfo;
            LayoutInfo layoutInfo = control.layoutInfo;
            //
            control.Measure(lastLayoutInfo.measureArgument);
            control.Arrange(lastLayoutInfo.renderSlotRect);
            // if lastLayoutInfo eq layoutInfo we can use last rendered buffer
            //            if (layoutInfo.Equals(lastLayoutInfo) && lastLayoutInfo.validity == LayoutValidity.Render) {
            if (checkRenderingWasNotChangedRecursively(control)) {
                if (control.SetValidityToRender()) {
                    revalidatedControls.Add(control);
                }
                return fullBuffer;
            }
            // replace buffers if control has grown
            if (layoutInfo.renderSize.width > buffer.Width || layoutInfo.renderSize.height > buffer.Height) {
                buffer = new RenderingBuffer(layoutInfo.renderSize.width, layoutInfo.renderSize.height);
                fullBuffer = new RenderingBuffer(layoutInfo.renderSize.width, layoutInfo.renderSize.height);
                buffers[control] = buffer;
                fullBuffers[control] = fullBuffer;
            }
            // otherwise we should assemble full rendered buffer using childs
            buffer.Clear();
            if (control.RenderSize.Width != 0 && control.RenderSize.Height != 0)
                control.Render(buffer);
            //
            fullBuffer.CopyFrom(buffer);
            foreach (Control child in control.Children) {
                if (child.Visibility == Visibility.Visible) {
                    RenderingBuffer fullChildBuffer = processControl(child, revalidatedControls);
                    fullBuffer.ApplyChild(fullChildBuffer, child.ActualOffset,
                        child.RenderSize, child.RenderSlotRect, child.LayoutClip);
                } else {
                    // чтобы следующий Invalidate для этого контрола
                    // перезаписал lastLayoutInfo
                    if (child.SetValidityToRender()) {
                        revalidatedControls.Add(child);
                    }
                }
            }

            // Save overlappingRect for each control child
            refreshChildrenLastOverlappedRects( control, false );

            if (control.SetValidityToRender()) {
                revalidatedControls.Add(control);
            }
            return fullBuffer;
        }
コード例 #23
0
ファイル: Window.cs プロジェクト: furesoft/consoleframework
 public override void Render(RenderingBuffer buffer)
 {
     Attr borderAttrs = moving ? Colors.Blend(Color.Green, Color.Gray) : Colors.Blend(Color.White, Color.Gray);
     // background
     buffer.FillRectangle(0, 0, this.ActualWidth, this.ActualHeight, ' ', borderAttrs);
     // Borders
     RenderBorders(buffer, new Point(0, 0), new Point(ActualWidth - 3, ActualHeight - 2),
         this.moving || this.resizing, borderAttrs);
     // close button
     if (ActualWidth > 4) {
         buffer.SetPixel(2, 0, '[');
         buffer.SetPixel(3, 0, showClosingGlyph ? UnicodeTable.WindowClosePressedSymbol : UnicodeTable.WindowCloseSymbol,
             Colors.Blend(Color.Green, Color.Gray));
         buffer.SetPixel(4, 0, ']');
     }
     // shadows
     buffer.SetOpacity(0, ActualHeight - 1, 2+4);
     buffer.SetOpacity(1, ActualHeight - 1, 2+4);
     buffer.SetOpacity(ActualWidth - 1, 0, 2+4);
     buffer.SetOpacity(ActualWidth - 2, 0, 2+4);
     buffer.SetOpacityRect(2, ActualHeight - 1, ActualWidth - 2, 1, 1+4);
     buffer.SetOpacityRect(ActualWidth - 2, 1, 2, ActualHeight - 1, 1+4);
     // title
     if (!string.IsNullOrEmpty(Title)) {
         int titleStartX = 7;
         bool renderTitle = false;
         string renderTitleString = null;
         int availablePixelsCount = ActualWidth - titleStartX*2;
         if (availablePixelsCount > 0) {
             renderTitle = true;
             if (Title.Length <= availablePixelsCount) {
                 // dont truncate title
                 titleStartX += (availablePixelsCount - Title.Length)/2;
                 renderTitleString = Title;
             } else {
                 renderTitleString = Title.Substring(0, availablePixelsCount);
                 if (renderTitleString.Length > 2) {
                     renderTitleString = renderTitleString.Substring(0, renderTitleString.Length - 2) + "..";
                 } else {
                     renderTitle = false;
                 }
             }
         }
         if (renderTitle) {
             // assert !string.IsNullOrEmpty(renderingTitleString);
             buffer.SetPixel(titleStartX - 1, 0, ' ', borderAttrs);
             for (int i = 0; i < renderTitleString.Length; i++) {
                 buffer.SetPixel(titleStartX + i, 0, renderTitleString[i], borderAttrs);
             }
             buffer.SetPixel(titleStartX + renderTitleString.Length, 0, ' ', borderAttrs);
         }
     }
 }
コード例 #24
0
ファイル: Renderer.cs プロジェクト: KSLcom/consoleframework
        private void updateLayout(Control control, List<Control> revalidatedControls)
        {
            LayoutInfo lastLayoutInfo = control.lastLayoutInfo;
            // работаем с родительским элементом управления
            if (control.Parent != null) {
                bool needUpdateParentLayout = true;
                // если размер текущего контрола не изменился, то состояние ревалидации не распространяется
                // вверх по дереву элементов, и мы переходим к работе с дочерними элементами
                // в противном случае мы добавляем родительский элемент в конец очереди ревалидации, и
                // возвращаем управление
                if (lastLayoutInfo.validity != LayoutValidity.Nothing) {
                    control.Measure(lastLayoutInfo.measureArgument);
            //                    if (lastLayoutInfo.unclippedDesiredSize == control.layoutInfo.unclippedDesiredSize) {
                    if (checkDesiredSizeNotChangedRecursively(control)) {
                        needUpdateParentLayout = false;
                    }
                }
                if (needUpdateParentLayout) {
                    // mark the parent control for invalidation too and enqueue them
                    control.Parent.Invalidate();
                    // мы можем закончить с этим элементом, поскольку мы уже добавили
                    // в конец очереди его родителя, и мы все равно вернемся к нему в след. раз
                    return;
                }
            }
            // работаем с дочерними элементами управления
            // вызываем для текущего контрола Measure&Arrange с последними значениями аргументов
            if (lastLayoutInfo.validity == LayoutValidity.Nothing && control.Parent != null) {
                throw new InvalidOperationException("Assertion failed.");
            }
            // rootElement - особый случай
            if (control.Parent == null) {
                if (control != RootElement) {
                    throw new InvalidOperationException("Control has no parent but is not known rootElement.");
                }
                control.Measure(RootElementRect.Size);
                control.Arrange(RootElementRect);
            } else {
                control.Measure(lastLayoutInfo.measureArgument);
                control.Arrange(lastLayoutInfo.renderSlotRect);
            }
            // update render buffers of current control and its children
            RenderingBuffer buffer = getOrCreateBufferForControl(control);
            RenderingBuffer fullBuffer = getOrCreateFullBufferForControl(control);
            // replace buffers if control has grown
            LayoutInfo layoutInfo = control.layoutInfo;
            if (layoutInfo.renderSize.width > buffer.Width || layoutInfo.renderSize.height > buffer.Height) {
                buffer = new RenderingBuffer(layoutInfo.renderSize.width, layoutInfo.renderSize.height);
                fullBuffer = new RenderingBuffer(layoutInfo.renderSize.width, layoutInfo.renderSize.height);
                buffers[control] = buffer;
                fullBuffers[control] = fullBuffer;
            }
            buffer.Clear();
            if (control.RenderSize.Width != 0 && control.RenderSize.Height != 0)
                control.Render(buffer);
            // проверяем дочерние контролы - если их layoutInfo не изменился по сравнению с последним,
            // то мы можем взять их последний renderBuffer без обновления и применить к текущему контролу
            fullBuffer.CopyFrom(buffer);
            IList<Control> children = control.Children;
            foreach (Control child in children) {
                if (child.Visibility == Visibility.Visible) {
                    RenderingBuffer fullChildBuffer = processControl(child, revalidatedControls);
                    fullBuffer.ApplyChild(fullChildBuffer, child.ActualOffset,
                        child.RenderSize,
                        child.RenderSlotRect, child.LayoutClip);
                } else {
                    // чтобы следующий Invalidate перезаписал lastLayoutInfo
                    if (child.SetValidityToRender()) {
                        revalidatedControls.Add(child);
                    }
                }
            }

            // Save overlappingRect for each control child
            refreshChildrenLastOverlappedRects( control, false );

            if (control.SetValidityToRender()) {
                revalidatedControls.Add(control);
            }
            addControlToRenderingUpdatedList(control);
        }
コード例 #25
0
ファイル: Menu.cs プロジェクト: CxSoftware/consoleframework
        public override void Render(RenderingBuffer buffer) {
            Attr captionAttrs;
            Attr specialAttrs;
            if ( HasFocus || this.expanded ) {
                captionAttrs = Colors.Blend( Color.Black, Color.DarkGreen );
                specialAttrs = Colors.Blend( Color.DarkRed, Color.DarkGreen );
            } else {
                captionAttrs = Colors.Blend( Color.Black, Color.Gray );
                specialAttrs = Colors.Blend( Color.DarkRed, Color.Gray );
            }
            if ( disabled )
                captionAttrs = Colors.Blend( Color.DarkGray, Color.Gray );

            buffer.FillRectangle( 0, 0, ActualWidth, ActualHeight, ' ', captionAttrs );
            if ( null != Title ) {
                renderString( Title, buffer, 1, 0, ActualWidth, captionAttrs, 
                    Disabled ? captionAttrs : specialAttrs );
            }
            if ( null != TitleRight )
                RenderString( TitleRight, buffer, ActualWidth - TitleRight.Length - 1, 0,
                              TitleRight.Length, captionAttrs );
        }
コード例 #26
0
ファイル: ListBox.cs プロジェクト: KSLcom/consoleframework
        public override void Render(RenderingBuffer buffer)
        {
            Attr selectedAttr = Colors.Blend(Color.White, Color.DarkGreen);
            Attr attr = Colors.Blend(Color.Black, Color.DarkCyan);
            Attr disabledAttr = Colors.Blend(Color.Gray, Color.DarkCyan);
            for ( int y = 0; y < ActualHeight; y++ ) {
                string item = y < items.Count ? items[ y ] : null;

                if ( item != null ) {
                    Attr currentAttr = disabledItemsIndexes.Contains(y) ? disabledAttr :
                        (SelectedItemIndex == y ? selectedAttr : attr);

                    buffer.SetPixel( 0, y, ' ', currentAttr );
                    if ( ActualWidth > 1 ) {
                        // минус 2 потому что у нас есть по пустому пикселю слева и справа
                        int rendered = RenderString( item, buffer, 1, y, ActualWidth - 2, currentAttr );
                        buffer.FillRectangle( 1 + rendered, y, ActualWidth - (1 + rendered), 1, ' ',
                            currentAttr);
                    }
                } else {
                    buffer.FillRectangle(0, y, ActualWidth, 1, ' ', attr);
                }
            }
        }
コード例 #27
0
ファイル: Menu.cs プロジェクト: CxSoftware/consoleframework
            public override void Render(RenderingBuffer buffer)
            {
                Attr borderAttrs = Colors.Blend(Color.Black, Color.Gray);

                // Background
                buffer.FillRectangle(0, 1, ActualWidth, ActualHeight - 1, ' ', borderAttrs);

                // Первые width пикселей первой строки - прозрачные, но события мыши не пропускают
                // По нажатию на них мы закрываем всплывающее окно вручную
                buffer.SetOpacityRect(0, 0, parentItemWidth, 1, 2);
                // Оставшиеся пиксели первой строки - пропускают события мыши
                // И WindowsHost закроет всплывающее окно автоматически при нажатии или
                // перемещении нажатого курсора над этим местом
                buffer.SetOpacityRect( parentItemWidth, 0, ActualWidth - parentItemWidth, 1, 6 );

                if (shadow) {
                    buffer.SetOpacity(0, ActualHeight - 1, 2 + 4);
                    buffer.SetOpacity(ActualWidth - 1, 1, 2 + 4);
                    buffer.SetOpacityRect(ActualWidth - 1, 2, 1, ActualHeight - 2, 1 + 4);
                    buffer.FillRectangle(ActualWidth - 1, 2, 1, ActualHeight - 2, UnicodeTable.FullBlock, borderAttrs);
                    buffer.SetOpacityRect(1, ActualHeight - 1, ActualWidth - 1, 1, 3 + 4);
                    buffer.FillRectangle(1, ActualHeight - 1, ActualWidth - 1, 1, UnicodeTable.UpperHalfBlock,
                                          Attr.NO_ATTRIBUTES);
                }

                RenderBorders( buffer, new Point( 1, 1 ),
                               shadow
                                   ? new Point( ActualWidth - 3, ActualHeight - 2 )
                                   : new Point( ActualWidth - 2, ActualHeight - 1 ),
                               true, borderAttrs );
            }
コード例 #28
0
            public override void Render(RenderingBuffer buffer)
            {
                Attr borderAttrs = Colors.Blend(Color.Black, Color.DarkCyan);
                // устанавливаем прозрачными первую строку и первый столбец
                // для столбца дополнительно включена прозрачность для событий мыши

                // background
                buffer.FillRectangle(1, 1, this.ActualWidth - 1, this.ActualHeight - 1, ' ', borderAttrs);

                buffer.SetOpacityRect( 0,0,ActualWidth, 1, 2 );
                buffer.SetOpacityRect( 0, 1, 1, ActualHeight-1, 6 );
                if ( shadow ) {
                    buffer.SetOpacity( 1, ActualHeight - 1, 2+4 );
                    buffer.SetOpacity( ActualWidth - 1, 0, 2+4 );
                    buffer.SetOpacityRect( ActualWidth - 1, 1, 1, ActualHeight - 1, 1+4 );
                    buffer.FillRectangle(ActualWidth - 1, 1, 1, ActualHeight - 1, UnicodeTable.FullBlock, borderAttrs);
                    buffer.SetOpacityRect( 2, ActualHeight - 1, ActualWidth - 2, 1, 3+4 );
                    buffer.FillRectangle(2, ActualHeight - 1, ActualWidth - 2, 1, UnicodeTable.UpperHalfBlock,
                                          Attr.NO_ATTRIBUTES );
                }
            }
コード例 #29
0
ファイル: Menu.cs プロジェクト: CxSoftware/consoleframework
 public override void Render( RenderingBuffer buffer ) {
     Attr attr = Colors.Blend( Color.Black, Color.Gray );
     buffer.FillRectangle(0, 0, ActualWidth, ActualHeight, ' ', attr);
 }
コード例 #30
0
ファイル: TabControl.cs プロジェクト: KSLcom/consoleframework
 private void renderBorderSafe( RenderingBuffer buffer, int x, int y, int x2, int y2 )
 {
     if ( ActualWidth > x && ActualHeight > y )
         buffer.SetPixel( x, y, UnicodeTable.SingleFrameTopLeftCorner );
     if ( ActualWidth > x && ActualHeight > y2 && y2 > y )
         buffer.SetPixel( x, y2, UnicodeTable.SingleFrameBottomLeftCorner );
     if ( ActualHeight > y )
         for ( int i = x + 1; i <= Math.Min( x2 - 1, ActualWidth - 1 ); i++ )
             buffer.SetPixel( i, y, UnicodeTable.SingleFrameHorizontal );
     if ( ActualHeight > y2 )
         for ( int i = x + 1; i <= Math.Min( x2 - 1, ActualWidth - 1 ); i++ )
             buffer.SetPixel( i, y2, UnicodeTable.SingleFrameHorizontal );
     if ( ActualWidth > x )
         for ( int j = y + 1; j <= Math.Min( y2 - 1, ActualHeight - 1 ); j++ )
             buffer.SetPixel( x, j, UnicodeTable.SingleFrameVertical );
     if ( ActualWidth > x2 )
         for ( int j = y + 1; j <= Math.Min( y2 - 1, ActualHeight - 1 ); j++ )
             buffer.SetPixel( x2, j, UnicodeTable.SingleFrameVertical );
     if ( ActualWidth > x2 && ActualHeight > y && x2 > x )
         buffer.SetPixel( x2, y, UnicodeTable.SingleFrameTopRightCorner );
     if ( ActualWidth > x2 && ActualHeight > y2 && y2 > y && x2 > x )
         buffer.SetPixel( x2, y2, UnicodeTable.SingleFrameBottomRightCorner );
 }
コード例 #31
0
 /// <summary>
 /// Накладывает буфер дочернего элемента на текущий. Дочерний буфер виртуально накладывается на текущий
 /// в соответствии с переданным actualOffset, а потом та часть дочернего буфера, которая попадает в 
 /// renderSlotRect, прорисовывается. renderSlotRect определен отн-но текущего буфера (а не дочернего).
 /// layoutClip определяет, какая часть дочернего буфера будет прорисована в текущий буфер (клиппинг,
 /// возникающий при применении Margin и Alignment'ов).
 /// </summary>
 /// <param name="childBuffer"></param>
 /// <param name="actualOffset">Смещение буфера дочернего элемента относительно текущего.</param>
 /// <param name="childRenderSize">Размер отрендеренного дочерним элементом контента - может
 /// быть меньше размера childBuffer, поэтому нужно передавать явно.</param>
 /// <param name="renderSlotRect">Размер и положение слота, выделенного дочернему элементу.</param>
 /// <param name="layoutClip">Часть дочернего буфера, которая будет отрисована - по размеру может быть
 /// меньше или равна RenderSlotRect.Size. По координатам соотносится с childBuffer.</param>
 public void ApplyChild(RenderingBuffer childBuffer, Vector actualOffset,
     Size childRenderSize, Rect renderSlotRect, Rect layoutClip)
 {
     ApplyChild( childBuffer, actualOffset, childRenderSize, renderSlotRect, layoutClip, null );
 }
コード例 #32
0
        /// <summary>
        /// Оверлоад для оптимизированного наложения в случае, когда известно, что в дочернем
        /// контроле поменялась лишь часть, идентифицируемая параметром affectedRect.
        /// Будет обработана только эта часть дочернего контрола, и количество операций уменьшится.
        /// </summary>
        /// <param name="childBuffer"></param>
        /// <param name="actualOffset"></param>
        /// <param name="childRenderSize"></param>
        /// <param name="renderSlotRect"></param>
        /// <param name="layoutClip"></param>
        /// <param name="affectedRect">Прямоугольник в дочернем контроле, который был изменен.</param>
        public void ApplyChild(RenderingBuffer childBuffer, Vector actualOffset,
                               Size childRenderSize, Rect renderSlotRect,
                               Rect layoutClip, Rect?affectedRect)
        {
            // Считаем finalRect - прямоугольник относительно parent, который нужно закрасить
            Rect finalRect = layoutClip;

            if (affectedRect != null)
            {
                finalRect.Intersect(affectedRect.Value);
            }

            // Если child.RenderSlotRect больше child.RenderSize, а rendering buffer
            // дочернего контрола больше его RenderSize (такое бывает после уменьшения
            // размеров контрола - т.к. буфер может только увеличиваться, но не уменьшаться) -
            // то нам нужно либо передать в метод ApplyChild и child.RenderSize, либо
            // выполнить пересечение заранее
            finalRect.Intersect(new Rect(new Point(0, 0), childRenderSize));

            // Because cannot call Offset() method of empty rect
            if (finalRect.IsEmpty)
            {
                return;
            }

            finalRect.Offset(actualOffset);
            finalRect.Intersect(renderSlotRect);

            // Нужно также учесть размеры буфера текущего контрола
            finalRect.Intersect(new Rect(new Point(0, 0), new Size(this.width, this.height)));

            for (int x = finalRect.Left; x < finalRect.Right; x++)
            {
                int parentX = x;
                int childX  = parentX - actualOffset.x;
                for (int y = finalRect.Top; y < finalRect.Bottom; y++)
                {
                    int parentY = y;
                    int childY  = parentY - actualOffset.y;

                    CHAR_INFO charInfo = childBuffer.buffer[childX, childY];
                    int       opacity  = childBuffer.opacityMatrix[childX, childY];

                    // Для полностью прозрачных пикселей родительского буфера - присваиваем и значение
                    // пикселя, и значение opacity, дальше дело за следующим родителем
                    if (this.opacityMatrix[parentX, parentY] == 2 || this.opacityMatrix[parentX, parentY] == 6)
                    {
                        this.buffer[parentX, parentY]        = charInfo;
                        this.opacityMatrix[parentX, parentY] = opacity;
                    }
                    else
                    {
                        // В остальных случаях opacity родительского буфера остаётся, а
                        // сам пиксель зависит от opacity дочернего элемента
                        if (opacity == 0 || opacity == 4)
                        {
                            this.buffer[parentX, parentY] = charInfo;
                        }
                        else if (opacity == 1 || opacity == 5)
                        {
                            charInfo.Attributes      = Colors.Blend(Color.DarkGray, Color.Black);
                            charInfo.UnicodeChar     = buffer[parentX, parentY].UnicodeChar;
                            buffer[parentX, parentY] = charInfo;
                        }
                        else if (opacity == 3 || opacity == 7)
                        {
                            // берем фоновые атрибуты символа из родительского буфера
                            Attr parentAttr = buffer[parentX, parentY].Attributes;
                            if ((parentAttr & Attr.BACKGROUND_BLUE) == Attr.BACKGROUND_BLUE)
                            {
                                charInfo.Attributes |= Attr.BACKGROUND_BLUE;
                            }
                            else
                            {
                                charInfo.Attributes &= ~Attr.BACKGROUND_BLUE;
                            }
                            if ((parentAttr & Attr.BACKGROUND_GREEN) == Attr.BACKGROUND_GREEN)
                            {
                                charInfo.Attributes |= Attr.BACKGROUND_GREEN;
                            }
                            else
                            {
                                charInfo.Attributes &= ~Attr.BACKGROUND_GREEN;
                            }
                            if ((parentAttr & Attr.BACKGROUND_RED) == Attr.BACKGROUND_RED)
                            {
                                charInfo.Attributes |= Attr.BACKGROUND_RED;
                            }
                            else
                            {
                                charInfo.Attributes &= ~Attr.BACKGROUND_RED;
                            }
                            if ((parentAttr & Attr.BACKGROUND_INTENSITY) == Attr.BACKGROUND_INTENSITY)
                            {
                                charInfo.Attributes |= Attr.BACKGROUND_INTENSITY;
                            }
                            else
                            {
                                charInfo.Attributes &= ~Attr.BACKGROUND_INTENSITY;
                            }
                            buffer[parentX, parentY] = charInfo;
                        }
                    }
                }
            }
        }
コード例 #33
0
ファイル: TextBox.cs プロジェクト: furesoft/consoleframework
 public override void Render(RenderingBuffer buffer) {
     Attr attr = Colors.Blend(Color.White, Color.DarkBlue);
     buffer.FillRectangle(0, 0, ActualWidth, ActualHeight, ' ', attr);
     if (null != text) {
         for (int i = displayOffset; i < text.Length; i++) {
             if (i - displayOffset < ActualWidth - 2 && i - displayOffset >= 0) {
                 buffer.SetPixel(1 + i - displayOffset, 0, text[i]);
             }
         }
     }
     Attr arrowsAttr = Colors.Blend(Color.Green, Color.DarkBlue);
     if (displayOffset > 0)
         buffer.SetPixel(0, 0, '<', arrowsAttr);
     if (!String.IsNullOrEmpty(text) && ActualWidth - 2 + displayOffset < text.Length)
         buffer.SetPixel(ActualWidth - 1, 0, '>', arrowsAttr);
 }
コード例 #34
0
 /// <summary>
 /// Накладывает буфер дочернего элемента на текущий. Дочерний буфер виртуально накладывается на текущий
 /// в соответствии с переданным actualOffset, а потом та часть дочернего буфера, которая попадает в
 /// renderSlotRect, прорисовывается. renderSlotRect определен отн-но текущего буфера (а не дочернего).
 /// layoutClip определяет, какая часть дочернего буфера будет прорисована в текущий буфер (клиппинг,
 /// возникающий при применении Margin и Alignment'ов).
 /// </summary>
 /// <param name="childBuffer"></param>
 /// <param name="actualOffset">Смещение буфера дочернего элемента относительно текущего.</param>
 /// <param name="childRenderSize">Размер отрендеренного дочерним элементом контента - может
 /// быть меньше размера childBuffer, поэтому нужно передавать явно.</param>
 /// <param name="renderSlotRect">Размер и положение слота, выделенного дочернему элементу.</param>
 /// <param name="layoutClip">Часть дочернего буфера, которая будет отрисована - по размеру может быть
 /// меньше или равна RenderSlotRect.Size. По координатам соотносится с childBuffer.</param>
 public void ApplyChild(RenderingBuffer childBuffer, Vector actualOffset,
                        Size childRenderSize, Rect renderSlotRect, Rect layoutClip)
 {
     ApplyChild(childBuffer, actualOffset, childRenderSize, renderSlotRect, layoutClip, null);
 }