Skip to content

Commit

Permalink
fix: empty screen on startup
Browse files Browse the repository at this point in the history
  • Loading branch information
NikolaDucak committed Nov 29, 2024
1 parent 62bae33 commit 52e3e31
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 21 deletions.
9 changes: 7 additions & 2 deletions source/view/annual_view.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,16 @@ using namespace ftxui;
AnnualView::AnnualView(const std::chrono::year_month_day &today, bool sundayStart,
unsigned recentEventsWindow)
: m_screen{ScreenInteractive::Fullscreen()},
m_calendarButtons{Calendar::make(m_screen, today, makeCalendarOptions(today, sundayStart))},
m_calendarButtons{Calendar::make(ScreenSizeProvider::makeDefault(), today,
makeCalendarOptions(today, sundayStart))},
m_tagsMenu{makeTagsMenu()}, m_sectionsMenu{makeSectionsMenu()},
m_rootComponent{makeFullUIComponent()}, m_recentEventsWindow{recentEventsWindow} {}

void AnnualView::run() { m_screen.Loop(m_rootComponent); }
void AnnualView::run() {
// Caps-log expects the terminal to be at least 80x24
Terminal::SetFallbackSize(Dimensions{/*dimx=*/80, /*dimy=*/24});
m_screen.Loop(m_rootComponent);
}

void AnnualView::stop() { m_screen.ExitLoopClosure()(); }

Expand Down
20 changes: 12 additions & 8 deletions source/view/calendar_component.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
#include "view/ftxui_ext/extended_containers.hpp"

#include <ftxui/screen/screen.hpp>
#include <ftxui/screen/terminal.hpp>
#include <memory>

namespace caps_log::view {
using namespace ftxui;
Expand All @@ -20,9 +22,9 @@ namespace {
*/
class MonthComponentArranger {
public:
static Element arrange(const Screen &screen, const Components &monthComponents,
static Element arrange(const Dimensions screenDimensions, const Components &monthComponents,
std::chrono::year displayedYear) {
const auto availableMonthColumns = computeNumberOfMonthsPerRow(screen);
const auto availableMonthColumns = computeNumberOfMonthsPerRow(screenDimensions);
const auto renderData = arrangeMonthsInCalendar(monthComponents, availableMonthColumns);
return window(text(std::to_string(static_cast<int>(displayedYear))),
vbox(renderData) | frame) |
Expand All @@ -40,8 +42,8 @@ class MonthComponentArranger {
/**
* @brief Computes the number of months that can be displayed in a row.
*/
static int computeNumberOfMonthsPerRow(const Screen &screen) {
int availableMonthColumns = screen.dimx() / kCharsPerMonthComponet;
static int computeNumberOfMonthsPerRow(const Dimensions &screenDimensions) {
int availableMonthColumns = screenDimensions.dimx / kCharsPerMonthComponet;
// prevent spliting 12 months into 2 rows of unequal elements
if (availableMonthColumns == 5) { // NOLINT
availableMonthColumns = 4;
Expand Down Expand Up @@ -70,9 +72,10 @@ class MonthComponentArranger {

} // namespace

Calendar::Calendar(const Screen &screen, const std::chrono::year_month_day &today,
CalendarOption option)
: m_screen{&screen}, m_option(std::move(option)), m_today(today),
Calendar::Calendar(std::unique_ptr<ScreenSizeProvider> screenSizeProvider,
const std::chrono::year_month_day &today, CalendarOption option)
: m_screenSizeProvider{std::move(screenSizeProvider)}, m_option(std::move(option)),
m_today(today),
// TODO: SetActiveChild does nothing, this is the only
// way to focus a specific date on startup. Investigate.
m_selectedMonthComponentIdx{(static_cast<int>(static_cast<unsigned>(today.month()))) - 1},
Expand Down Expand Up @@ -130,7 +133,8 @@ Component Calendar::createYear(std::chrono::year year) {
const auto container = ftxui_ext::AnyDir(monthComponents, &m_selectedMonthComponentIdx);

return Renderer(container, [this, monthComponents]() {
return MonthComponentArranger::arrange(*m_screen, monthComponents, m_displayedYear);
return MonthComponentArranger::arrange(m_screenSizeProvider->getScreenSize(),
monthComponents, m_displayedYear);
});
}

Expand Down
28 changes: 22 additions & 6 deletions source/view/calendar_component.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,24 @@ struct CalendarOption {
bool sundayStart = false;
};

class ScreenSizeProvider {
public:
virtual ~ScreenSizeProvider() = default;
virtual ftxui::Dimensions getScreenSize() const = 0;

static std::unique_ptr<ScreenSizeProvider> makeDefault() {
// Caps-log runs only in full screen mode, so we can use the terminal size as the screen
// size
class DefaultScreenSizeProvider : public ScreenSizeProvider {
public:
ftxui::Dimensions getScreenSize() const override { return ftxui::Terminal::Size(); }
};
return std::make_unique<DefaultScreenSizeProvider>();
}
};

class Calendar : public ftxui::ComponentBase {
const ftxui::Screen *m_screen;
std::unique_ptr<ScreenSizeProvider> m_screenSizeProvider;
CalendarOption m_option;
std::chrono::year_month_day m_today;
ftxui::Component m_root;
Expand All @@ -27,8 +43,8 @@ class Calendar : public ftxui::ComponentBase {
std::chrono::year m_displayedYear;

public:
Calendar(const ftxui::Screen &screen, const std::chrono::year_month_day &today,
CalendarOption option = {});
Calendar(std::unique_ptr<ScreenSizeProvider> ScreenSizeProvider,
const std::chrono::year_month_day &today, CalendarOption option = {});

bool OnEvent(ftxui::Event event) override;
ftxui::Element Render() override;
Expand All @@ -40,9 +56,9 @@ class Calendar : public ftxui::ComponentBase {
* @brief A utility factory method to create a shared pointer to a Calendar instance. This is
* useful as FTXUI works with shared pointers to ComponentBase instances.
*/
static inline auto make(const ftxui::Screen &screen, const std::chrono::year_month_day &today,
CalendarOption option = {}) {
return std::make_shared<Calendar>(screen, today, option);
static inline auto make(std::unique_ptr<ScreenSizeProvider> screenSizeProvider,
const std::chrono::year_month_day &today, CalendarOption option = {}) {
return std::make_shared<Calendar>(std::move(screenSizeProvider), today, option);
}

private:
Expand Down
28 changes: 23 additions & 5 deletions test/calendar_component_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,16 @@ std::string readFile(const std::string &path) {
buffer << ifs.rdbuf();
return buffer.str();
}

class MockScreenSizeProvider : public caps_log::view::ScreenSizeProvider {
public:
MockScreenSizeProvider(ftxui::Dimensions size) : m_size{size} {}
ftxui::Dimensions getScreenSize() const override { return m_size; }

private:
ftxui::Dimensions m_size;
};

} // namespace

TEST(CalnedarComponentTest, Render) {
Expand All @@ -37,13 +47,16 @@ TEST(CalnedarComponentTest, Render) {
};
// NOLINTEND
for (const auto &data : testData) {
ftxui::Screen screen{data.screen_width, 41}; // NOLINT
caps_log::view::Calendar calendar{screen, {2024y, std::chrono::January, 1d}}; // NOLINT

ftxui::Dimensions dimensions{data.screen_width, 41}; // NOLINT
ftxui::Screen screen{data.screen_width, 41}; // NOLINT
auto sizeProvider = std::make_unique<MockScreenSizeProvider>(dimensions);
caps_log::view::Calendar calendar{std::move(sizeProvider),
{2024y, std::chrono::January, 1d}}; // NOLINT
ftxui::Render(screen, calendar.Render());
const auto screenRender = screen.ToString();
std::string expectedOutput = readFile(filePath(data));
EXPECT_EQ(screenRender, expectedOutput) << "Got: " << screenRender;
EXPECT_EQ(screenRender, expectedOutput) << "Expected" << expectedOutput << "\n\n"
<< "Got: " << screenRender;
}
}

Expand All @@ -52,15 +65,20 @@ TEST(CalnedarComponentTest, EventHandling) {
std::chrono::year_month_day next{2024y, std::chrono::January, 2d}; // NOLINT
std::chrono::year_month_day next_month{2024y, std::chrono::February, 1d}; // NOLINT
ftxui::Screen screen{184, 41}; // NOLINT
caps_log::view::Calendar calendar{screen, start}; // NOLINT
auto sizeProvider = std::make_unique<MockScreenSizeProvider>(ftxui::Dimensions{184, 41});

caps_log::view::Calendar calendar{std::move(sizeProvider), start};

calendar.OnEvent(ftxui::Event::ArrowRight);
EXPECT_EQ(calendar.getFocusedDate(), next)
<< "Got date: " << caps_log::utils::date::formatToString(calendar.getFocusedDate());

calendar.OnEvent(ftxui::Event::ArrowDown);
calendar.OnEvent(ftxui::Event::ArrowDown);
calendar.OnEvent(ftxui::Event::ArrowDown);
calendar.OnEvent(ftxui::Event::ArrowDown);
calendar.OnEvent(ftxui::Event::ArrowDown);

EXPECT_EQ(calendar.getFocusedDate(), next_month)
<< "Got date: " << caps_log::utils::date::formatToString(calendar.getFocusedDate());
}

0 comments on commit 52e3e31

Please sign in to comment.