Skip to content

Commit 857866c

Browse files
committed
Terminal/Layout
1 parent edc814a commit 857866c

File tree

8 files changed

+83
-14
lines changed

8 files changed

+83
-14
lines changed

modules/Terminal/Area.mpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,11 @@ export namespace CppUtils::Terminal
4343
return m_viewport;
4444
}
4545

46+
[[nodiscard]] inline auto getSize() const noexcept -> Container::Size2 final
47+
{
48+
return DynamicAreaBuffer::getSize();
49+
}
50+
4651
inline auto fill(const CharAttributes& c) noexcept -> void
4752
{
4853
auto view = WritableAreaView{*this, m_viewport};

modules/Terminal/DynamicAreaBuffer.mpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ export namespace CppUtils::Terminal
3333
m_buffer = Buffer{m_size.height(), Line{m_size.width()}};
3434
}
3535

36-
[[nodiscard]] inline auto getSize() const noexcept -> Container::Size2 final
36+
[[nodiscard]] inline auto getSize() const noexcept -> Container::Size2 override
3737
{
3838
auto lock = std::unique_lock{m_mutex};
3939
return m_size;

modules/Terminal/Layout.mpp

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,20 @@
11
export module CppUtils.Terminal.Layout;
22

33
import std;
4+
import CppUtils.Container.Size;
45
import CppUtils.Terminal.Area;
56

67
export namespace CppUtils::Terminal
78
{
89
class Layout: public Widget
910
{
1011
public:
12+
enum class Direction
13+
{
14+
Horizontal,
15+
Vertical
16+
};
17+
1118
virtual ~Layout() = default;
1219

1320
template<std::derived_from<Widget> T>
@@ -17,12 +24,55 @@ export namespace CppUtils::Terminal
1724
return dynamic_cast<T&>(*m_widgets.emplace_back(std::move(widget)));
1825
}
1926

27+
[[nodiscard]] inline auto getSize() const noexcept -> Container::Size2 final
28+
{
29+
auto totalSize = Container::Size2{0, 0};
30+
for (const auto& widget : m_widgets)
31+
{
32+
if (direction == Direction::Horizontal)
33+
{
34+
totalSize.width() += widget->getSize().width();
35+
totalSize.height() = std::max(totalSize.height(), widget->getSize().height());
36+
}
37+
else
38+
{
39+
totalSize.width() = std::max(totalSize.width(), widget->getSize().width());
40+
totalSize.height() += widget->getSize().height();
41+
}
42+
}
43+
return totalSize;
44+
}
45+
2046
inline auto draw(WritableAreaView& view) noexcept -> void override final
2147
{
48+
auto origin = view.getViewport().getPosition();
49+
auto size = view.getViewport().getSize();
2250
for (const auto& widget : m_widgets)
23-
widget->draw(view);
51+
{
52+
auto widgetSize = widget->getSize();
53+
widgetSize.width() = std::min(widgetSize.width(), size.width());
54+
widgetSize.height() = std::min(widgetSize.height(), size.height());
55+
56+
auto subview = view.getSubView(Viewport{widgetSize, origin});
57+
if (not subview)
58+
continue;
59+
widget->draw(subview.value());
60+
61+
if (direction == Direction::Horizontal and size.width() < widgetSize.width())
62+
{
63+
origin.width() += widgetSize.width();
64+
size.width() -= widgetSize.width();
65+
}
66+
else
67+
{
68+
origin.height() += widgetSize.height();
69+
size.height() -= widgetSize.height();
70+
}
71+
}
2472
}
2573

74+
Direction direction = Direction::Vertical;
75+
2676
private:
2777
std::vector<std::unique_ptr<Widget>> m_widgets;
2878
};

modules/Terminal/ProgressBar.mpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,16 @@ export namespace CppUtils::Terminal
2020
requestUpdate(10ms);
2121
}
2222

23+
[[nodiscard]] inline auto getSize() const noexcept -> Container::Size2 final
24+
{
25+
return Container::Size2{std::numeric_limits<std::size_t>::max(), 1};
26+
}
27+
2328
inline auto draw(WritableAreaView& view) noexcept -> void final
2429
{
25-
const auto size = view.getSize();
30+
const auto size = view.getViewport().getSize();
2631
const auto titleSize = std::size(m_title);
27-
const auto barWidth = size.width() - titleSize - 2 - 5;
32+
const auto barWidth = size.width() - titleSize - 2 - 6;
2833
const auto progress = static_cast<std::size_t>(static_cast<float>(barWidth) * m_percent / 100.f);
2934

3035
auto text = std::format("{} [{}{}] {:>3}% ", m_title, std::string(progress, '#'), std::string(barWidth - progress, ' '), static_cast<std::size_t>(m_percent));

modules/Terminal/Spinner.mpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,11 @@ export namespace CppUtils::Terminal
2121
m_duration{duration}
2222
{}
2323

24+
[[nodiscard]] inline auto getSize() const noexcept -> Container::Size2 final
25+
{
26+
return size;
27+
}
28+
2429
inline auto draw(WritableAreaView& view) noexcept -> void
2530
{
2631
if (std::empty(m_frames))

modules/Terminal/Widget.mpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ export namespace CppUtils::Terminal
1212
{
1313
public:
1414
virtual ~Widget() = default;
15+
[[nodiscard]] virtual auto getSize() const noexcept -> Container::Size2 = 0;
1516
virtual auto draw(WritableAreaView& view) noexcept -> void = 0;
1617

1718
inline auto drawFinished() noexcept -> void

modules/Terminal/WritableAreaView.mpp

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@ export namespace CppUtils::Terminal
1515
m_viewport{std::move(viewport)}
1616
{}
1717

18-
[[nodiscard]] inline auto getSize() const noexcept -> const auto&
18+
[[nodiscard]] inline auto getViewport() const noexcept -> const auto&
1919
{
20-
return m_viewport.getSize();
20+
return m_viewport;
2121
}
2222

2323
inline auto printText(const Container::Size2& position, std::string_view text) noexcept -> void
@@ -27,7 +27,7 @@ export namespace CppUtils::Terminal
2727
{
2828
setChar(currentPosition, CharAttributes{c});
2929
currentPosition.x()++;
30-
if (currentPosition.x() >= getSize().width())
30+
if (currentPosition.x() >= getViewport().getSize().width())
3131
{
3232
currentPosition.x() = 0;
3333
currentPosition.y()++;
@@ -58,9 +58,10 @@ export namespace CppUtils::Terminal
5858

5959
inline auto setChar(const Container::Size2& position, const CharAttributes& c) noexcept -> void
6060
{
61-
if (not m_viewport.contains(position))
61+
const auto absolutePosition = m_viewport.getPosition() + position;
62+
if (not m_viewport.contains(absolutePosition))
6263
return;
63-
m_areaBuffer.setChar(m_viewport.getPosition() + position, c);
64+
m_areaBuffer.setChar(absolutePosition, c);
6465
}
6566

6667
inline auto fill(const CharAttributes& c) noexcept -> void

tests/Terminal/Canvas.mpp

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,8 @@ export namespace CppUtils::UnitTest::Terminal::Canvas
6767
});
6868

6969
suite.addTest("Progress bar", [&] {
70-
auto canvas = CppUtils::Terminal::v2::Canvas{CppUtils::Container::Size2{50, 1}};
70+
const auto terminalWidth = CppUtils::Terminal::getTerminalSize().width();
71+
auto canvas = CppUtils::Terminal::v2::Canvas{CppUtils::Container::Size2{terminalWidth, 1}};
7172
auto& progressBar = canvas.addWidget(std::make_unique<CppUtils::Terminal::ProgressBar>("Progress bar"));
7273

7374
auto scheduler = CppUtils::Thread::Scheduler{};
@@ -85,7 +86,8 @@ export namespace CppUtils::UnitTest::Terminal::Canvas
8586
});
8687

8788
suite.addTest("Multiple Progress Bars", [&] {
88-
auto canvas = CppUtils::Terminal::v2::Canvas{CppUtils::Container::Size2{50, 3}};
89+
const auto terminalWidth = CppUtils::Terminal::getTerminalSize().width();
90+
auto canvas = CppUtils::Terminal::v2::Canvas{CppUtils::Container::Size2{terminalWidth, 3}};
8991
auto& layout = canvas.addWidget(std::make_unique<CppUtils::Terminal::Layout>());
9092

9193
auto& bar1 = layout.addWidget(std::make_unique<CppUtils::Terminal::ProgressBar>("Bar 1"));
@@ -95,14 +97,14 @@ export namespace CppUtils::UnitTest::Terminal::Canvas
9597
auto scheduler = CppUtils::Thread::Scheduler{};
9698
scheduler.schedule([&canvas]() mutable {
9799
canvas.close();
98-
}, 500ms);
100+
}, 1'000ms);
99101

100-
for (auto i = 0.f; i <= 100.f; i += 2.f)
102+
for (auto i = 0.f; i <= 100.f; i += 1.f)
101103
{
102104
bar1.setPercent(i);
103105
bar2.setPercent(CppUtils::Math::Easing::inQuad(i / 100.f) * 100.f);
104106
bar3.setPercent(CppUtils::Math::Easing::outCubic(i / 100.f) * 100.f);
105-
std::this_thread::sleep_for(5ms);
107+
std::this_thread::sleep_for(10ms);
106108
}
107109

108110
canvas.wait();

0 commit comments

Comments
 (0)