///////////////////////////////////////////////////////////////////////////////// /// <summary> /// Draws default border, caption and scroll bar for the window. /// </summary> /// <remarks> /// Border is drawn depending on Border, Caption and VerticalScrollBar flags: /// <pre> /// No Border With Border With Border /// and Caption /// /// Without Scrollbar: ┌──────────────┐ /// │██████████████│ /// ┌──────────────┐ ├──────────────┤ /// ▒▒▒▒▒▒▒▒▒▒▒▒▒▒ │▒▒▒▒▒▒▒▒▒▒▒▒▒▒│ │▒▒▒▒▒▒▒▒▒▒▒▒▒▒│ /// ▒▒▒▒▒▒▒▒▒▒▒▒▒▒ │▒▒▒▒▒▒▒▒▒▒▒▒▒▒│ │▒▒▒▒▒▒▒▒▒▒▒▒▒▒│ /// ▒▒▒▒▒▒▒▒▒▒▒▒▒▒ │▒▒▒▒▒▒▒▒▒▒▒▒▒▒│ │▒▒▒▒▒▒▒▒▒▒▒▒▒▒│ /// └──────────────┘ └──────────────┘ /// /// With Scrollbar: ┌──────────────┐ /// │██████████████│ /// ┌────────────┬─┐ ├────────────┬─┤ /// ▒▒▒▒▒▒▒▒▒▒▒▒│▲ │▒▒▒▒▒▒▒▒▒▒▒▒│▲│ │▒▒▒▒▒▒▒▒▒▒▒▒│▲│ /// ▒▒▒▒▒▒▒▒▒▒▒▒│█ │▒▒▒▒▒▒▒▒▒▒▒▒│█│ │▒▒▒▒▒▒▒▒▒▒▒▒│█│ /// ▒▒▒▒▒▒▒▒▒▒▒▒│▼ │▒▒▒▒▒▒▒▒▒▒▒▒│▼│ │▒▒▒▒▒▒▒▒▒▒▒▒│▼│ /// └────────────┴─┘ └────────────┴─┘ /// </pre> /// /// 3D-shadow of the border might be drawn using: /// <code> /// /// screen.SetColors( Left + 1, Top + Height + 1, Width + 2, 1, /// Color.Black, Color.Black ); /// /// screen.SetColors( Left + Width + 1, Top + 1, 2, Height, /// Color.Black, Color.Black ); /// /// </code> /// /// </remarks> /// public void DefaultDrawBorder(Screen screen, bool hasFocus) { ColorContext savedColors = new ColorContext(screen); bool hasScrollbar = VerticalScrollBar && Height >= 2 && Width >= 3; if (Border && !CaptionVisible) { // Draw normal window border without caption but with optional // border margin // screen.DrawRectangle(-1, -1, Width + 2, Height + 2); } else if (Border) { // Draw expanded window border for caption // screen.DrawRectangle(-1, -3, Width + 2, Height + 4); // Draw separator between window contents and caption // screen.Put(-1, -1, Box._UDsR); screen.Put(Width, -1, Box._UDLs); screen.DrawRectangle(0, -1, Width, 1); } // Draw vertical scrollbar with optional frame // if (hasScrollbar) { int reducedWidth = Width - 2; // Draw separator between window contents and scroll bar // if (Border) { screen.DrawRectangle(reducedWidth, 0, 1, Height); screen.Put(reducedWidth, -1, Box._sDLR); screen.Put(reducedWidth, Height, Box._UsLR); } else { screen.DrawRectangle(reducedWidth, 0, 1, Height); screen.DrawRectangle(reducedWidth + 2, 0, 1, Height); } // Draw vertical scroll bar if (hasFocus) { screen.ForeColor = ScrollBarForeColor; } else { screen.ForeColor = ScrollBarForeColorInact; } screen.DrawVerticalScrollBar(reducedWidth + 1, 0, Height, VerticalScrollBarFirstItem, VerticalScrollBarLastItem, VerticalScrollBarItemCount); } // Write caption // if (Border & CaptionVisible & Caption != null) { if (hasFocus) { screen.BackColor = CaptionBackColor; screen.ForeColor = CaptionForeColor; } else { screen.BackColor = CaptionBackColorInact; screen.ForeColor = CaptionForeColorInact; } string text = TaggedText.AlignedText(Caption, Width, CaptionTextAlign, CaptionIndent, CaptionIndent); screen.CursorTop = -2; screen.CursorLeft = 0; screen.Write(text); } savedColors.Restore(); }
///////////////////////////////////////////////////////////////////////////////// /// <summary> /// Repaints window contents on the screen. /// </summary> /// internal bool Repaint(Screen screen, bool parentHasFocus = true) { if (screen == null) // FIXME: screen null OR INVISIBLE { return(false); } if (!Visible) { Invalidated = false; return(false); } bool hasFocus = Parent == null || /* root window always has focus */ (parentHasFocus && Parent.ActiveChild == this); if (Invalidated) { OnCalculateSize(hasFocus); } // Setup clipping region and drawing offset // ClipContext clipContext = new ClipContext(screen, Left, Top); clipContext.Clip(ClientWidth, ClientHeight); bool repainted = false; bool drawBorder = false; if (Invalidated) { // Setup default cursor position and drawing colors first, then // erase background and draw contents // screen.SetCursorPosition(0, 0); if (hasFocus) { screen.BackColor = BackColor; screen.ForeColor = ForeColor; } else { screen.BackColor = BackColorInact; screen.ForeColor = ForeColorInact; } ColorContext savedColor = new ColorContext(screen); OnEraseBackground(screen); savedColor.Restore(); OnDrawContents(screen, hasFocus); savedColor.Restore(); drawBorder = true; repainted = true; Invalidated = false; } // Repaint children. // Algorithm: At the beginning, 'repainted' flag is usually false. // First child, which returns that it has repainted itself, turns-on // 'repainted' flag further on so the all consecutive siblings are // invalidated (and repainted). // foreach (Window subWindow in children) { if (repainted) { subWindow.Invalidate(); // Force child to be Repaint()-ed } if (subWindow.Repaint(screen, hasFocus)) { repainted = true; } } // Draw window edges (with parent's offset but without clipping!) // if (drawBorder) { clipContext.RestoreClipRegion(); if (hasFocus) { screen.BackColor = BorderBackColor; screen.ForeColor = BorderForeColor; } else { screen.BackColor = BorderBackColorInact; screen.ForeColor = BorderForeColorInact; } OnDrawBorder(screen, hasFocus); } // Restore clipping region and drawing offset // clipContext.Restore(); return(repainted); }