display

Layout and Rendering TUI library
git clone git://git.dimitrijedobrota.com/display.git
Log | Files | Refs | README | LICENSE | HACKING | CONTRIBUTING | CODE_OF_CONDUCT | BUILDING

commit b8053e4af8e8d4ffce5a834a423bbc16c80ae12f
parent 7ab20e8f93307b6e9e69366997d3f776fc37072c
author Dimitrije Dobrota < mail@dimitrijedobrota.com >
date Sat, 8 Feb 2025 15:27:13 +0100

Add and use resize event to redraw

Diffstat:
M CMakeLists.txt | + -
M example/example.cpp | ++++++++++++++++++++++++++++++++++++++++++++ ------------------------
M include/display/display.hpp | ++++ -
M include/display/layout.hpp | ++ --
M source/display.cpp | ++++++++++++ ---

5 files changed, 63 insertions(+), 31 deletions(-)


diff --git a/ CMakeLists.txt b/ CMakeLists.txt

@@ -4,7 +4,7 @@ include(cmake/prelude.cmake)


project(
display
VERSION 0.1.6
VERSION 0.1.7
DESCRIPTION "TUI library"
HOMEPAGE_URL "https://example.com/"
LANGUAGES CXX

diff --git a/ example/example.cpp b/ example/example.cpp

@@ -10,8 +10,7 @@ namespace


int renderer(display::Window& win)
{
using display::PvtX;
using display::PvtY;
using display::PvtX, display::PvtY;

static int color_red = 0;

@@ -50,7 +49,8 @@ int renderer(display::Window& win)

break;
}

std::cout << alec::background(color_red += 25, 65, 65);
color_red = (color_red + 25) % 256;
std::cout << alec::background(color_red, 65, 65);
for (auto ypos = start_y; ypos <= end_y; ypos++) {
std::cout << alec::cursor_position(ypos, start_x);
std::cout << std::string(win.dim().width, ' ');

@@ -66,30 +66,50 @@ int renderer(display::Window& win)

int main()
{
try {
display::start();

const auto [cols, rows] = alec::get_screen_size();
const std::uint16_t colsm = cols / 2;
const std::uint16_t rowm = rows / 2;

using display::PvtX;
using display::PvtY;

display::LayoutFree layout;
layout.append({{0, 0}, {20, 10}, {PvtX::Left, PvtY::Top}});
layout.append({{colsm, 0}, {20, 10}, {PvtX::Center, PvtY::Top}});
layout.append({{cols, 0}, {20, 10}, {PvtX::Right, PvtY::Top}});
layout.append({{cols, rowm}, {20, 10}, {PvtX::Right, PvtY::Center}});
layout.append({{cols, rows}, {20, 10}, {PvtX::Right, PvtY::Bottom}});
layout.append({{colsm, rows}, {20, 10}, {PvtX::Center, PvtY::Bottom}});
layout.append({{0, rows}, {20, 10}, {PvtX::Left, PvtY::Bottom}});
layout.append({{0, rowm}, {20, 10}, {PvtX::Left, PvtY::Center}});
layout.append({{colsm, rowm}, {20, 10}, {PvtX::Center, PvtY::Center}});
layout.render(renderer);

auto redraw = [&]()
{
const auto [cols, rows] = alec::get_screen_size();
const std::uint16_t colsm = cols / 2;
const std::uint16_t rowm = rows / 2;

layout[0].pos() = {0, 0};
layout[1].pos() = {colsm, 0};
layout[2].pos() = {cols, 0};
layout[3].pos() = {cols, rowm};
layout[4].pos() = {cols, rows};
layout[5].pos() = {colsm, rows};
layout[6].pos() = {0, rows};
layout[7].pos() = {0, rowm};
layout[8].pos() = {colsm, rowm};

layout.render(renderer);
};

using display::PvtX, display::PvtY;

layout.append({{}, {20, 10}, {PvtX::Left, PvtY::Top}});
layout.append({{}, {20, 10}, {PvtX::Center, PvtY::Top}});
layout.append({{}, {20, 10}, {PvtX::Right, PvtY::Top}});
layout.append({{}, {20, 10}, {PvtX::Right, PvtY::Center}});
layout.append({{}, {20, 10}, {PvtX::Right, PvtY::Bottom}});
layout.append({{}, {20, 10}, {PvtX::Center, PvtY::Bottom}});
layout.append({{}, {20, 10}, {PvtX::Left, PvtY::Bottom}});
layout.append({{}, {20, 10}, {PvtX::Left, PvtY::Center}});
layout.append({{}, {20, 10}, {PvtX::Center, PvtY::Center}});

display::start();
redraw();
while (true) {
const auto event = alec::get_event();
if (event.type() == alec::event::Type::KEY && event.key() == 'q') {
const auto event = display::get_event();
if (event.type() == display::event::Type::RESIZE) {
std::cout << alec::erase_display_v<alec::Motion::WHOLE>;
redraw();
continue;
}

if (event.type() == display::event::Type::KEY && event.key() == 'q') {
break;
}
}

diff --git a/ include/display/display.hpp b/ include/display/display.hpp

@@ -1,14 +1,17 @@

#pragma once

#include <alec/alec.hpp>

namespace display
{

using exit_f = void();
using event = alec::event;

void exit();
void start(exit_f f_exit = exit);
void stop(bool force = false);

int get_key();
event get_event();

} // namespace display

diff --git a/ include/display/layout.hpp b/ include/display/layout.hpp

@@ -91,8 +91,8 @@ class LayoutFree

public:
using render_f = int(Window&);

auto operator[](std::size_t idx) const { return m_windows[idx]; }
auto operator[](std::size_t idx) { return m_windows[idx]; }
const auto& operator[](std::size_t idx) const { return m_windows[idx]; }
auto& operator[](std::size_t idx) { return m_windows[idx]; }

void append(Window window);

diff --git a/ source/display.cpp b/ source/display.cpp

@@ -3,7 +3,6 @@


#include "display/display.hpp"

#include <alec/alec.hpp>
#include <signal.h>
#include <termios.h>
#include <unistd.h>

@@ -23,11 +22,21 @@ namespace display

{

static int start_count = 0; // NOLINT
static bool resized = false; // NOLINT

void handle_sigwinch(int)
{
const auto [col, row] = alec::get_screen_size();
std::cout << col << " " << row << std::endl;
resized = true;
}

event get_event()
{
if (resized) {
resized = false;
return {event::Type::RESIZE, 0, 0};
}

return alec::get_event();
}

void exit()