Render the Screen from a Buffer
Now we replace the direct output example with a small buffer-based layout. This is the point where the library starts to feel more like a terminal UI toolkit than a simple print helper.
Instead of writing text directly to the terminal, the application now prepares the entire screen in memory and renders it in a single update.
Replace signal-board/src/main.cpp
Replace the contents of the file with the following version:
#include <erbsland/cterm/all.hpp>
using namespace erbsland::cterm;
auto main() -> int {
auto terminal = Terminal{Size{80, 25}};
terminal.initializeScreen();
auto buffer = Buffer{terminal.size()};
buffer.fill(Char{" ", Color{fg::Default, bg::Black}});
const auto rect = Rectangle{0, 0, buffer.size().width(), 6};
buffer.drawFilledFrame(
rect,
FrameStyle::LightWithRoundedCorners,
Char{" ", bg::Blue});
buffer.drawText(
"Signal Board",
Rectangle{2, 1, rect.width() - 4, 1},
Alignment::Center,
Color{fg::BrightWhite, bg::Blue});
buffer.drawText(
"The whole screen is prepared in memory and rendered in one pass.",
Rectangle{2, 3, rect.width() - 4, 2},
Alignment::CenterLeft,
Color{fg::BrightWhite, bg::Blue});
auto settings = UpdateSettings{};
settings.setMinimumSize(Size{40, 8});
settings.setSwitchToAlternateBuffer(false);
terminal.updateScreen(buffer, settings);
terminal.flush();
terminal.restoreScreen();
return 0;
}
What Changed
This version introduces several important concepts:
Bufferstores a complete screen-sized grid of colored terminal cells.fill()clears the buffer and defines the background color.Inheritedkeeps the color from below, whileDefaultexplicitly resets to the terminal default.drawFilledFrame()draws both the frame and its interior in a single call.drawText()places text inside rectangles without manually managing the cursor.UpdateSettingsallows you to define constraints such as the minimum supported terminal size.setSwitchToAlternateBuffer(false)keeps this short example on the main screen instead of using the alternate full-screen buffer.Terminalstarts inOutputMode::FullControl, which enables screen refresh, cursor control, and buffer-based rendering. UseOutputMode::Textonly for plain-text output without terminal control features.
Because the entire scene is prepared in memory, the application can update the terminal in a single operation. This approach scales much better once the layout contains multiple panels, text blocks, or animated elements.
By default, Terminal::size() already returns the safe drawable size for
screen updates. If you need to use the full detected terminal size, disable the
compatibility margin with setSafeMarginEnabled(false).