Skip to content

Commit

Permalink
Refactored TUI elements into a separater library.
Browse files Browse the repository at this point in the history
  • Loading branch information
nalevi committed Dec 29, 2023
1 parent 2ea1137 commit d926da3
Show file tree
Hide file tree
Showing 5 changed files with 198 additions and 86 deletions.
66 changes: 66 additions & 0 deletions include/recipe_agent/tui/tui.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
//
// Created by Nagy Levente on 29/12/2023.
//

#ifndef RECIPE_AGENT_TUI_H
#define RECIPE_AGENT_TUI_H

#include "ftxui/component/captured_mouse.hpp"
#include "ftxui/component/component.hpp"
#include "ftxui/component/component_base.hpp"
#include "ftxui/component/component_options.hpp"
#include "ftxui/component/screen_interactive.hpp"
#include <ftxui/dom/elements.hpp>
#include <ftxui/screen/screen.hpp>

#include <ftxui/component/loop.hpp>
#include <vector>

namespace recipeagent {

namespace tui {
// TODO: Refactor this into indigent module.
const std::vector<std::string> INDIGENT_TYPES{
"SEED",
"FRUIT",
"VEGETABLE",
"DAIRY",
"MEAT",
"FAT",
"BREAD",
"SNACK",
"CONDIMENT",
};

/// @brief This object encapsulates the tab of the Indigents menu.
struct IndigentsMenu {
IndigentsMenu();

std::vector<std::string> tab_indigents_entries;

std::string indigent_name_field;
ftxui::Component indigent_name_input;

int selected_indigent_type;
ftxui::Component indigent_type_dropdown;

ftxui::Component indigent_add_button;

int tab_indigents_selected;

};

/// @brief This function is the main entry point of the tui module.
void display_menu();

/// @brief This function is the entry point to draw all the indigent related menus, tabs, etc.
ftxui::Component display_indigents_menu(IndigentsMenu &indigents_menu);

ftxui::Component create_indigents_component(IndigentsMenu &indigents_menu);

ftxui::ButtonOption button_style();

}// namespace tui

} // namespace recipeagent
#endif// RECIPE_AGENT_TUI_H
6 changes: 4 additions & 2 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
add_subdirectory(tui)
add_executable(recipeagent
main.cpp
)
)

target_link_libraries(
recipeagent
PRIVATE recipe_agent::recipe_agent_options
recipe_agent::recipe_agent_warnings)
recipe_agent::recipe_agent_warnings
tui)

target_link_system_libraries(
recipeagent
Expand Down
88 changes: 4 additions & 84 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,47 +2,16 @@
// Created by Nagy Levente on 22/12/2023.
//

#include "recipe_agent/tui/tui.h"

#include <CLI/CLI.hpp>
#include <fmt/core.h>
#include <spdlog/spdlog.h>

#include "ftxui/component/captured_mouse.hpp"// for ftxui
#include "ftxui/component/component.hpp"// for Radiobox, Horizontal, Menu, Renderer, Tab
#include "ftxui/component/component_base.hpp"// for ComponentBase
#include "ftxui/component/component_options.hpp"
#include "ftxui/component/screen_interactive.hpp"
#include <ftxui/dom/elements.hpp>
#include <ftxui/screen/screen.hpp>
#include <memory>

#include <internal_use_only/config.hpp>

using namespace ftxui;

ButtonOption button_style()
{
auto option = ButtonOption::Animated();
option.transform = [](const EntryState &s) {
auto element = text(s.label);
if (s.focused) { element |= bold; }
return element | center | borderEmpty;
};
return option;
}

void add_indigent() { spdlog::info("Indigent successfully added!"); }

const std::vector<std::string> INDIGENT_TYPES{
"SEED",
"FRUIT",
"VEGETABLE",
"DAIRY",
"MEAT",
"FAT",
"BREAD",
"SNACK",
"CONDIMENT",
};

int main(int argc, char **argv)
{
Expand All @@ -60,60 +29,11 @@ int main(int argc, char **argv)
return EXIT_SUCCESS;
}

recipeagent::tui::display_menu();

} catch (const std::exception &e) {
spdlog::error("Unhandled exception in main: {}", e.what());
}

// Menu with tabs.
std::vector<std::string> tab_values{
"Indigents",
"Recipes",
"Generation",
};
int tab_selected = 0;
auto tab_main_menu = Menu(&tab_values, &tab_selected);

std::vector<std::string> tab_indigents_entries{
"Add indigent",
"Get indigent",
"List all indigents",
"Get indigents by category",
};
int tab_indigents_selected = 0;


auto tab_indigents_menu = Menu(&tab_indigents_entries, &tab_indigents_selected);

// Add indigents tab
std::string indigent_name;
auto indigent_name_field = Input(&indigent_name, "indigent name");

int selected_indigent_type = 0;
auto indigent_type_dropdown = Dropdown(&INDIGENT_TYPES, &selected_indigent_type);

auto indigent_add_button = Button("Add", [&] { add_indigent(); }, button_style());

auto add_indigents_component =
Container::Vertical({ indigent_name_field, indigent_type_dropdown, indigent_add_button });

auto container = Container::Horizontal({ tab_main_menu, tab_indigents_menu, add_indigents_component });

auto renderer = Renderer(container, [&] {
return hbox({ tab_main_menu->Render(),
separator(),
tab_indigents_menu->Render(),
separator(),
vbox({
hbox({text("Indigent name : "), indigent_name_field->Render()}),
hbox({text("Indigent type : "), indigent_type_dropdown->Render()}),
indigent_add_button->Render()
})
})
| border;
});

auto screen = ScreenInteractive::TerminalOutput();
screen.Loop(renderer);

return 0;
}
30 changes: 30 additions & 0 deletions src/tui/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
include(GenerateExportHeader)

add_library(tui tui.cpp)

add_library(recipe_agent::tui ALIAS tui)

target_link_libraries(tui PRIVATE recipe_agent_options recipe_agent_warnings)

target_link_system_libraries(tui PRIVATE ftxui::screen
ftxui::dom
ftxui::component
fmt::fmt
spdlog::spdlog)

target_include_directories(tui ${WARNING_GUARD} PUBLIC $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>
$<BUILD_INTERFACE:${PROJECT_BINARY_DIR}/include>)

target_compile_features(tui PUBLIC cxx_std_20)

set_target_properties(
tui
PROPERTIES VERSION ${PROJECT_VERSION}
CXX_VISIBILITY_PRESET hidden
VISIBILITY_INLINES_HIDDEN YES)

generate_export_header(tui EXPORT_FILE_NAME ${PROJECT_BINARY_DIR}/include/recipe_agent/tui_export.hpp)

if(NOT BUILD_SHARED_LIBS)
target_compile_definitions(tui PUBLIC SAMPLE_LIBRARY_STATIC_DEFINE)
endif()
94 changes: 94 additions & 0 deletions src/tui/tui.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
//
// Created by Nagy Levente on 29/12/2023.
//
#include "recipe_agent/tui/tui.h"
#include <ftxui/component/loop.hpp>

#include <spdlog/spdlog.h>


namespace recipeagent {

Check failure on line 10 in src/tui/tui.cpp

View workflow job for this annotation

GitHub Actions / Test (ubuntu-20.04, gcc-11, Ninja Multi-Config, Release, OFF, OFF)

nested namespaces can be concatenated [modernize-concat-nested-namespaces,-warnings-as-errors]

Check failure on line 10 in src/tui/tui.cpp

View workflow job for this annotation

GitHub Actions / Test (ubuntu-20.04, gcc-11, Ninja Multi-Config, Debug, OFF, OFF)

nested namespaces can be concatenated [modernize-concat-nested-namespaces,-warnings-as-errors]

Check failure on line 10 in src/tui/tui.cpp

View workflow job for this annotation

GitHub Actions / Test (ubuntu-20.04, llvm-15.0.2, Ninja Multi-Config, Debug, OFF, OFF)

nested namespaces can be concatenated [modernize-concat-nested-namespaces,-warnings-as-errors]

Check failure on line 10 in src/tui/tui.cpp

View workflow job for this annotation

GitHub Actions / Test (ubuntu-20.04, llvm-15.0.2, Ninja Multi-Config, Release, OFF, OFF)

nested namespaces can be concatenated [modernize-concat-nested-namespaces,-warnings-as-errors]

Check failure on line 10 in src/tui/tui.cpp

View workflow job for this annotation

GitHub Actions / Test (windows-2019, llvm-15.0.2, Ninja Multi-Config, Release, OFF, OFF)

nested namespaces can be concatenated [modernize-concat-nested-namespaces,-warnings-as-errors]

Check failure on line 10 in src/tui/tui.cpp

View workflow job for this annotation

GitHub Actions / Test (windows-2019, llvm-15.0.2, Ninja Multi-Config, Debug, OFF, OFF)

nested namespaces can be concatenated [modernize-concat-nested-namespaces,-warnings-as-errors]
namespace tui {

IndigentsMenu::IndigentsMenu()
: tab_indigents_entries({
"Add indigent",
"Get indigent",
"List all indigents",
"Get indigents by category",
}),
indigent_name_field(), indigent_name_input(ftxui::Input(&indigent_name_field, "name here")),

Check failure on line 20 in src/tui/tui.cpp

View workflow job for this annotation

GitHub Actions / Test (ubuntu-20.04, gcc-11, Ninja Multi-Config, Release, OFF, OFF)

initializer for member 'indigent_name_field' is redundant [readability-redundant-member-init,-warnings-as-errors]

Check failure on line 20 in src/tui/tui.cpp

View workflow job for this annotation

GitHub Actions / Test (ubuntu-20.04, gcc-11, Ninja Multi-Config, Debug, OFF, OFF)

initializer for member 'indigent_name_field' is redundant [readability-redundant-member-init,-warnings-as-errors]

Check failure on line 20 in src/tui/tui.cpp

View workflow job for this annotation

GitHub Actions / Test (ubuntu-20.04, llvm-15.0.2, Ninja Multi-Config, Debug, OFF, OFF)

initializer for member 'indigent_name_field' is redundant [readability-redundant-member-init,-warnings-as-errors]

Check failure on line 20 in src/tui/tui.cpp

View workflow job for this annotation

GitHub Actions / Test (ubuntu-20.04, llvm-15.0.2, Ninja Multi-Config, Release, OFF, OFF)

initializer for member 'indigent_name_field' is redundant [readability-redundant-member-init,-warnings-as-errors]

Check failure on line 20 in src/tui/tui.cpp

View workflow job for this annotation

GitHub Actions / Test (windows-2019, llvm-15.0.2, Ninja Multi-Config, Release, OFF, OFF)

initializer for member 'indigent_name_field' is redundant [readability-redundant-member-init,-warnings-as-errors]

Check failure on line 20 in src/tui/tui.cpp

View workflow job for this annotation

GitHub Actions / Test (windows-2019, llvm-15.0.2, Ninja Multi-Config, Debug, OFF, OFF)

initializer for member 'indigent_name_field' is redundant [readability-redundant-member-init,-warnings-as-errors]
selected_indigent_type(0), indigent_type_dropdown(ftxui::Dropdown(&INDIGENT_TYPES, &selected_indigent_type)),
indigent_add_button(ftxui::Button(
"Add",
[&] { spdlog::info("Indigent added!"); },
button_style())),
tab_indigents_selected(0)
{}

void display_menu()
{
using namespace ftxui;

std::vector<std::string> tab_values{

Check failure on line 33 in src/tui/tui.cpp

View workflow job for this annotation

GitHub Actions / Test (ubuntu-20.04, gcc-11, Ninja Multi-Config, Release, OFF, OFF)

variable 'tab_values' of type 'std::vector<std::string>' (aka 'vector<basic_string<char>>') can be declared 'const' [misc-const-correctness,-warnings-as-errors]

Check failure on line 33 in src/tui/tui.cpp

View workflow job for this annotation

GitHub Actions / Test (ubuntu-20.04, gcc-11, Ninja Multi-Config, Debug, OFF, OFF)

variable 'tab_values' of type 'std::vector<std::string>' (aka 'vector<basic_string<char>>') can be declared 'const' [misc-const-correctness,-warnings-as-errors]

Check failure on line 33 in src/tui/tui.cpp

View workflow job for this annotation

GitHub Actions / Test (ubuntu-20.04, llvm-15.0.2, Ninja Multi-Config, Debug, OFF, OFF)

variable 'tab_values' of type 'std::vector<std::string>' (aka 'vector<basic_string<char>>') can be declared 'const' [misc-const-correctness,-warnings-as-errors]

Check failure on line 33 in src/tui/tui.cpp

View workflow job for this annotation

GitHub Actions / Test (ubuntu-20.04, llvm-15.0.2, Ninja Multi-Config, Release, OFF, OFF)

variable 'tab_values' of type 'std::vector<std::string>' (aka 'vector<basic_string<char>>') can be declared 'const' [misc-const-correctness,-warnings-as-errors]

Check failure on line 33 in src/tui/tui.cpp

View workflow job for this annotation

GitHub Actions / Test (windows-2019, llvm-15.0.2, Ninja Multi-Config, Release, OFF, OFF)

variable 'tab_values' of type 'std::vector<std::string>' (aka 'vector<basic_string<char, char_traits<char>, allocator<char>>>') can be declared 'const' [misc-const-correctness,-warnings-as-errors]

Check failure on line 33 in src/tui/tui.cpp

View workflow job for this annotation

GitHub Actions / Test (windows-2019, llvm-15.0.2, Ninja Multi-Config, Debug, OFF, OFF)

variable 'tab_values' of type 'std::vector<std::string>' (aka 'vector<basic_string<char, char_traits<char>, allocator<char>>>') can be declared 'const' [misc-const-correctness,-warnings-as-errors]
"Indigents",
"Recipes",
"Generation",
};
int tab_selected = 0;
auto tab_main_menu = Menu(&tab_values, &tab_selected);

auto indigents_menu = IndigentsMenu{};
auto tab_indigents_menu = display_indigents_menu(indigents_menu);
auto add_indigents_component = create_indigents_component(indigents_menu);

auto container = Container::Horizontal({ tab_main_menu, tab_indigents_menu, add_indigents_component });

auto renderer = Renderer(container, [&] {
return hbox({ tab_main_menu->Render(),
separator(),
tab_indigents_menu->Render(),
separator(),
vbox({ hbox({ text("Indigent name : "), indigents_menu.indigent_name_input->Render() }),
hbox({ text("Indigent type : "), indigents_menu.indigent_type_dropdown->Render() }),
indigents_menu.indigent_add_button->Render() }) })
| border;
});

auto screen = ScreenInteractive::TerminalOutput();
screen.Loop(renderer);
}

ftxui::Component display_indigents_menu(IndigentsMenu &indigents_menu)
{
using namespace ftxui;

return Menu(&indigents_menu.tab_indigents_entries, &indigents_menu.tab_indigents_selected);
}

ftxui::Component create_indigents_component(IndigentsMenu &indigents_menu)
{
using namespace ftxui;

return Container::Vertical({ indigents_menu.indigent_name_input,
indigents_menu.indigent_type_dropdown,
indigents_menu.indigent_add_button });
}

ftxui::ButtonOption button_style()
{
using namespace ftxui;

auto option = ButtonOption::Animated();
option.transform = [](const EntryState &s) {

Check failure on line 83 in src/tui/tui.cpp

View workflow job for this annotation

GitHub Actions / Test (ubuntu-20.04, gcc-11, Ninja Multi-Config, Release, OFF, OFF)

parameter name 's' is too short, expected at least 3 characters [readability-identifier-length,-warnings-as-errors]

Check failure on line 83 in src/tui/tui.cpp

View workflow job for this annotation

GitHub Actions / Test (ubuntu-20.04, gcc-11, Ninja Multi-Config, Debug, OFF, OFF)

parameter name 's' is too short, expected at least 3 characters [readability-identifier-length,-warnings-as-errors]

Check failure on line 83 in src/tui/tui.cpp

View workflow job for this annotation

GitHub Actions / Test (ubuntu-20.04, llvm-15.0.2, Ninja Multi-Config, Debug, OFF, OFF)

parameter name 's' is too short, expected at least 3 characters [readability-identifier-length,-warnings-as-errors]

Check failure on line 83 in src/tui/tui.cpp

View workflow job for this annotation

GitHub Actions / Test (ubuntu-20.04, llvm-15.0.2, Ninja Multi-Config, Release, OFF, OFF)

parameter name 's' is too short, expected at least 3 characters [readability-identifier-length,-warnings-as-errors]

Check failure on line 83 in src/tui/tui.cpp

View workflow job for this annotation

GitHub Actions / Test (windows-2019, llvm-15.0.2, Ninja Multi-Config, Release, OFF, OFF)

parameter name 's' is too short, expected at least 3 characters [readability-identifier-length,-warnings-as-errors]

Check failure on line 83 in src/tui/tui.cpp

View workflow job for this annotation

GitHub Actions / Test (windows-2019, llvm-15.0.2, Ninja Multi-Config, Debug, OFF, OFF)

parameter name 's' is too short, expected at least 3 characters [readability-identifier-length,-warnings-as-errors]
auto element = text(s.label);
if (s.focused) { element |= bold; }
return element | center | borderEmpty;
};

return option;
}


}// namespace tui
}// namespace recipeagent

0 comments on commit d926da3

Please sign in to comment.