Buffer Views

Buffer views expose a rectangular window onto a larger readable buffer.

They are the right tool whenever your logical content is larger than the visible terminal area—for example in scrollable panels, editors, minimaps, or diagnostic tools.

BufferViewBase provides the shared view behavior, BufferView owns a shared pointer to the underlying content, and BufferConstRefView is the lightweight, stack-friendly variant for temporary rendering.

Usage

Viewing a Portion of a Larger Buffer

Use a buffer view when you want to render only a specific region of a larger logical canvas.

auto world = Buffer{Size{120, 40}};
world.fill(Char{" ", Color{fg::Inherited, bg::Black}});
world.drawText("Visible window", Rectangle{10, 6, 20, 3}, Alignment::Center);

auto view = BufferConstRefView{world, Rectangle{8, 4, 40, 12}};

auto settings = UpdateSettings{};
settings.setShowCropMarks(true);
terminal.updateScreen(view, settings);

The view translates its local coordinates into the corresponding positions of the underlying buffer. This allows you to render just the visible portion without copying or modifying the original content.

Scrolling by Moving the View Rectangle

BufferViewBase stores the currently visible rectangle, which you can update as the user scrolls or pans through the content.

auto sharedWorld = std::make_shared<Buffer>(world);
auto view = BufferView{sharedWorld, Rectangle{0, 0, 40, 12}};

view.setViewRect(Rectangle{16, 10, 40, 12});
terminal.updateScreen(view);

By moving the view rectangle, you change which part of the content is visible—without copying, reallocating, or redrawing the underlying buffer.

Choosing Between Shared and Referenced Views

Choose BufferView when the view needs to outlive the current scope or be stored as part of a larger object.

Choose BufferConstRefView when you only need a short-lived wrapper around an existing buffer.

auto sharedBuffer = std::make_shared<Buffer>(Size{80, 24});
auto cachedView = BufferView{sharedBuffer, Rectangle{4, 4, 30, 10}};

auto preview = BufferConstRefView{*sharedBuffer, Rectangle{0, 0, 20, 6}};
terminal.updateScreen(preview);

Both variants implement ReadableBuffer, so the rest of your rendering pipeline can treat them just like any other source of terminal cells.

Showing Cropped Edges Explicitly

CropEdges describes which sides of a view are clipped by the available content.

BufferViewBase can use this information to render custom crop indicators directly inside the view.

auto sharedBuffer = std::make_shared<Buffer>(world);
auto view = BufferView{sharedBuffer, Rectangle{8, 4, 40, 12}};

view.setShowCropCharacters(true);
view.setCropCharacter(Direction::East, Char{U'▶', fg::BrightYellow});
view.setCropCharacter(Direction::South, Char{U'▼', fg::BrightYellow});

const auto cropEdges = CropEdges::fromView(view.viewRect(), sharedBuffer->rect());
if (cropEdges.isSet(Direction::East)) {
    terminal.printLine("There is more content to the right.");
}

This is especially helpful in scrollable views, where users should immediately recognize that additional content exists beyond the visible window.

Interface

class BufferViewBase : public erbsland::cterm::ReadableBuffer

The base class for all buffer views.

Subclassed by erbsland::cterm::BufferConstRefView, erbsland::cterm::BufferView

Public Functions

inline explicit BufferViewBase(const Rectangle viewRectangle) noexcept

Create a buffer view with the given visible rectangle in the source buffer.

Parameters:

viewRectangle – The rectangle of the underlying content that shall be exposed through the view.

virtual Size size() const noexcept override

Get the configured size of the buffer.

Returns:

The width and height of the buffer.

virtual Rectangle rect() const noexcept override

Get a rectangle representing this buffer.

Returns:

The rectangle for this buffer.

virtual WritableBufferPtr clone() const override

Create a writeable copy of this buffer.

This will copy every block from this buffer into a new independent instance.

const Rectangle &viewRect() const noexcept

Get the rectangle in the underlying content that is currently visible through this view.

void setViewRect(Rectangle rect) noexcept

Set the rectangle in the underlying content that shall be visible through this view.

Parameters:

rect – The new source rectangle for the view.

bool showCropCharacters() const noexcept

Test whether crop indicator characters are shown when the view is clipped by the source buffer.

void setShowCropCharacters(bool show) noexcept

Enable or disable crop indicator characters.

Parameters:

showtrue to render crop indicators inside the view.

Char cropCharacter(Direction direction) const noexcept

Get the crop indicator character for one direction.

Parameters:

direction – The direction for which to retrieve the crop indicator.

Returns:

The configured crop character, or an empty character for an invalid direction.

void setCropCharacter(Direction direction, Char character) noexcept

Set the crop indicator character for one direction.

Parameters:
  • direction – The direction to update.

  • character – The new crop indicator character.

class BufferView : public erbsland::cterm::BufferViewBase

A view that uses a shared pointer to the content.

Public Functions

BufferView() = default

Create an empty view.

This creates a 1x1 view that returns the ‘Direction::None’ character.

inline explicit BufferView(const Size viewSize) noexcept

Create an empty view of a given size.

This creates a view that returns the ‘Direction::None’ character.

Parameters:

viewSize – The size of the view.

inline BufferView(ReadableBufferPtr content, const Size viewSize) noexcept

Create a view of the given content, with a given size.

The view shares the top-left corner with the buffer.

Parameters:
  • content – The buffer to create the view from.

  • viewSize – The size of the view.

inline BufferView(ReadableBufferPtr content, const Rectangle viewRect) noexcept

Create a view of the given content.

Parameters:
  • content – The buffer to create the view from.

  • viewRect – The rectangle of the view.

inline virtual const Char &get(const Position pos) const noexcept override

Read the block stored at the given position.

Parameters:

pos – The coordinates within the buffer.

Returns:

A reference to the stored block.

const ReadableBufferPtr &content() const noexcept

Access the content.

void setContent(ReadableBufferPtr buffer) noexcept

Replace the content.

class BufferConstRefView : public erbsland::cterm::BufferViewBase

A view that uses a reference to the content.

This view is to use as a thin temporary wrapper on the stack.

Public Functions

inline BufferConstRefView(const ReadableBuffer &content, const Size viewSize) noexcept

Create a view of the given content, with a given size.

The view shares the top-left corner with the buffer.

Parameters:
  • content – A reference to the content buffer.

  • viewSize – The size of the view.

inline BufferConstRefView(const ReadableBuffer &content, const Rectangle viewRect) noexcept

Create a view of the given content.

Parameters:
  • content – A reference to the content buffer.

  • viewRect – The rectangle of the view.

inline virtual const Char &get(const Position pos) const noexcept override

Read the block stored at the given position.

Parameters:

pos – The coordinates within the buffer.

Returns:

A reference to the stored block.

class CropEdges

Flags for crop edges and corners.

Public Types

using Flags = std::bitset<8>

Bitset type storing the eight crop-edge directions.

Public Functions

CropEdges() = default

No crop edges.

bool operator==(const CropEdges&) const noexcept = default

Compare two crop-edges objects.

bool operator!=(const CropEdges&) const noexcept = default

Compare two crop-edges objects.

inline Flags flags() const noexcept

Get the raw flags.

inline bool isSet(const Direction direction) const noexcept

Test if a crop edge is set.

inline void set(const Direction direction, bool value = true) noexcept

Set a crop edge.

inline void clear(const Direction direction) noexcept

Clear a crop edge.

inline void reset() noexcept

Reset all crop edges.

inline Direction edgeForView(const Position pos, const Rectangle viewRect) const noexcept

Test if a frame position in a view rectangle matches a given crop direction.

This function automatically handles the corners of the view rectangle correctly. Corner directions, like Direction::NorthEast are only returned if Direction::North and Direction::East are set. Otherwise, the corner direction matches the main direction.

Public Static Functions

static inline CropEdges fromView(const Rectangle viewRect, const Rectangle contentRect)

Create a crop edge instance for the given view/content situation.

Parameters:
  • viewRect – The view rectangle.

  • contentRect – The content rectangle.