Enable C++20 and use cmake 4
This commit is contained in:
		| @@ -2,7 +2,7 @@ | ||||
| # License, v. 2.0. If a copy of the MPL was not distributed with this | ||||
| # file, You can obtain one at https://mozilla.org/MPL/2.0/. | ||||
|  | ||||
| cmake_minimum_required(VERSION 3.21) | ||||
| cmake_minimum_required(VERSION 4.0) | ||||
| project(Katja) | ||||
|  | ||||
| include(CTest) | ||||
| @@ -10,7 +10,8 @@ include(FetchContent) | ||||
|  | ||||
| set(CMAKE_EXPORT_COMPILE_COMMANDS 1) | ||||
| set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) | ||||
| set(CMAKE_CXX_STANDARD 17) | ||||
| set(CMAKE_CXX_STANDARD 20) | ||||
| set(CMAKE_CXX_MODULE_STD 1) | ||||
|  | ||||
| add_library(katja | ||||
|        katja/database.cpp include/katja/database.hpp | ||||
|   | ||||
| @@ -11,7 +11,7 @@ implementation, that exposes the library to a user. | ||||
| ## Build instructions | ||||
|  | ||||
| ```sh | ||||
| cmake -B build | ||||
| cmake -B build -G Ninja | ||||
| make -C build | ||||
| ``` | ||||
|  | ||||
|   | ||||
| @@ -4,7 +4,7 @@ | ||||
|  | ||||
| FetchContent_Declare(ftxui | ||||
| 	GIT_REPOSITORY https://github.com/ArthurSonzogni/ftxui | ||||
| 	GIT_TAG v6.1.8 | ||||
| 	GIT_TAG v6.1.9 | ||||
| 	GIT_PROGRESS TRUE | ||||
| 	GIT_SHALLOW TRUE | ||||
| 	EXCLUDE_FROM_ALL | ||||
| @@ -18,7 +18,8 @@ FetchContent_Declare(toml11 | ||||
| ) | ||||
| FetchContent_MakeAvailable(toml11) | ||||
|  | ||||
| add_executable(katja-cli main.cpp component.hpp component.cpp page.hpp page.cpp) | ||||
| add_executable(katja-cli main.cpp component.hpp component.cpp) | ||||
| target_sources(katja-cli PUBLIC FILE_SET all_my_modules TYPE CXX_MODULES FILES page.cpp) | ||||
| target_include_directories(katja-cli PRIVATE ${Boost_INCLUDE_DIR}) | ||||
| target_link_libraries(katja-cli | ||||
| 	LINK_PUBLIC katja | ||||
|   | ||||
| @@ -7,11 +7,13 @@ | ||||
|  | ||||
| #include <ftxui/component/screen_interactive.hpp> | ||||
| #include <ftxui/dom/elements.hpp> | ||||
| #include <ftxui/component/component.hpp> | ||||
| #include <toml.hpp> | ||||
|  | ||||
| #include "katja/sbo.hpp" | ||||
| #include "katja/database.hpp" | ||||
| #include "page.hpp" | ||||
|  | ||||
| import page; | ||||
|  | ||||
| int main(int argc, const char **argv) | ||||
| { | ||||
|   | ||||
							
								
								
									
										286
									
								
								cli/page.cpp
									
									
									
									
									
								
							
							
						
						
									
										286
									
								
								cli/page.cpp
									
									
									
									
									
								
							| @@ -3,150 +3,198 @@ | ||||
|  * License, v. 2.0. If a copy of the MPL was not distributed with this | ||||
|  * file, You can obtain one at https://mozilla.org/MPL/2.0/. | ||||
|  */ | ||||
| #include "page.hpp" | ||||
| module; | ||||
|  | ||||
| #include <algorithm> | ||||
|  | ||||
| namespace katja | ||||
| #include "component.hpp" | ||||
|  | ||||
| export module page; | ||||
|  | ||||
| export namespace katja | ||||
| { | ||||
|     ScreenContainer::ScreenContainer(std::vector<std::pair<std::string, Page>> pages, std::function<void()> on_enter) | ||||
|         : on_enter(on_enter) | ||||
|     class PageBase : public ftxui::ComponentBase | ||||
|     { | ||||
|         ftxui::Components menu_pages; | ||||
|     public: | ||||
|         virtual void Load() = 0; | ||||
|     }; | ||||
|  | ||||
|         std::transform(std::cbegin(pages), std::cend(pages), std::back_inserter(menu_entries), | ||||
|                 [](const std::pair<std::string, Page>& pair) { return pair.first; }); | ||||
|         std::transform(std::cbegin(pages), std::cend(pages), std::back_inserter(this->menu_pages), | ||||
|                 [](const std::pair<std::string, Page>& pair) { return pair.second; }); | ||||
|         std::copy(std::cbegin(this->menu_pages), std::cend(this->menu_pages), std::back_inserter(menu_pages)); | ||||
|     using Page = std::shared_ptr<PageBase>; | ||||
|     using Pages = std::vector<Page>; | ||||
|  | ||||
|         ftxui::MenuOption menu_option = ftxui::MenuOption::Horizontal(); | ||||
|         this->menu = ftxui::Toggle(&this->menu_entries, &this->menu_selected); | ||||
|  | ||||
|         this->content = ftxui::Container::Tab(std::move(menu_pages), &this->menu_selected); | ||||
|     } | ||||
|  | ||||
|     ftxui::Element ScreenContainer::OnRender() | ||||
|     class ScreenContainer final : public ftxui::ComponentBase | ||||
|     { | ||||
|         return ftxui::vbox({ | ||||
|             this->menu->Render(), | ||||
|             ftxui::separator(), | ||||
|             this->content->Render() | ||||
|         }); | ||||
|     } | ||||
|         int menu_selected{ 0 }; | ||||
|         ftxui::Component menu; | ||||
|         ftxui::Component content; | ||||
|         std::vector<std::string> menu_entries; | ||||
|         Pages menu_pages; | ||||
|         std::function<void()> on_enter; | ||||
|  | ||||
|     bool ScreenContainer::OnEvent(ftxui::Event event) | ||||
|     { | ||||
|         if (event == ftxui::Event::CtrlQ && this->on_enter) | ||||
|     public: | ||||
|         ScreenContainer(std::vector<std::pair<std::string, Page>> pages, std::function<void()> on_enter) | ||||
|             : on_enter(on_enter) | ||||
|         { | ||||
|             on_enter(); | ||||
|             return true; | ||||
|         } | ||||
|         int previously = this->menu_selected; | ||||
|         bool result{ false }; | ||||
|             ftxui::Components menu_pages; | ||||
|  | ||||
|         if (event == ftxui::Event::CtrlP) | ||||
|         { | ||||
|             result = menu->OnEvent(ftxui::Event::ArrowLeft); | ||||
|             std::transform(std::cbegin(pages), std::cend(pages), std::back_inserter(menu_entries), | ||||
|                     [](const std::pair<std::string, Page>& pair) { return pair.first; }); | ||||
|             std::transform(std::cbegin(pages), std::cend(pages), std::back_inserter(this->menu_pages), | ||||
|                     [](const std::pair<std::string, Page>& pair) { return pair.second; }); | ||||
|             std::copy(std::cbegin(this->menu_pages), std::cend(this->menu_pages), std::back_inserter(menu_pages)); | ||||
|  | ||||
|             ftxui::MenuOption menu_option = ftxui::MenuOption::Horizontal(); | ||||
|             this->menu = ftxui::Toggle(&this->menu_entries, &this->menu_selected); | ||||
|  | ||||
|             this->content = ftxui::Container::Tab(std::move(menu_pages), &this->menu_selected); | ||||
|         } | ||||
|         else if (event == ftxui::Event::CtrlN) | ||||
|  | ||||
|         ftxui::Element OnRender() override | ||||
|         { | ||||
|             result = menu->OnEvent(ftxui::Event::ArrowRight); | ||||
|             return ftxui::vbox({ | ||||
|                 this->menu->Render(), | ||||
|                 ftxui::separator(), | ||||
|                 this->content->Render() | ||||
|             }); | ||||
|         } | ||||
|         if (previously != this->menu_selected) | ||||
|  | ||||
|         bool OnEvent(ftxui::Event event) override | ||||
|         { | ||||
|             this->menu_pages.at(this->menu_selected)->Load(); | ||||
|             if (event == ftxui::Event::CtrlQ && this->on_enter) | ||||
|             { | ||||
|                 on_enter(); | ||||
|                 return true; | ||||
|             } | ||||
|             int previously = this->menu_selected; | ||||
|             bool result{ false }; | ||||
|  | ||||
|             if (event == ftxui::Event::CtrlP) | ||||
|             { | ||||
|                 result = menu->OnEvent(ftxui::Event::ArrowLeft); | ||||
|             } | ||||
|             else if (event == ftxui::Event::CtrlN) | ||||
|             { | ||||
|                 result = menu->OnEvent(ftxui::Event::ArrowRight); | ||||
|             } | ||||
|             if (previously != this->menu_selected) | ||||
|             { | ||||
|                 this->menu_pages.at(this->menu_selected)->Load(); | ||||
|             } | ||||
|             if (!result) | ||||
|             { | ||||
|                 result = this->menu_pages.at(this->menu_selected)->OnEvent(event); | ||||
|             } | ||||
|             return result; | ||||
|         } | ||||
|         if (!result) | ||||
|         { | ||||
|             result = this->menu_pages.at(this->menu_selected)->OnEvent(event); | ||||
|         } | ||||
|         return result; | ||||
|     } | ||||
|     }; | ||||
|  | ||||
|     ftxui::Component Screen(std::vector<std::pair<std::string, Page>> pages, std::function<void()> on_enter) | ||||
|     { | ||||
|         return std::make_shared<ScreenContainer>(std::move(pages), on_enter); | ||||
|     } | ||||
|  | ||||
|     ftxui::Element WelcomePage::OnRender() | ||||
|     class WelcomePage final : public PageBase | ||||
|     { | ||||
|         return ftxui::paragraph("Select an action in the menu."); | ||||
|     } | ||||
|  | ||||
|     void WelcomePage::Load() | ||||
|     { | ||||
|     } | ||||
|  | ||||
|     UpdatesPage::UpdatesPage(std::shared_ptr<struct repository> repository, package_database database) | ||||
|         : repository(repository), database(database) | ||||
|     { | ||||
|     } | ||||
|  | ||||
|     void UpdatesPage::Load() | ||||
|     { | ||||
|         this->updatable = PackageList("Updates", repository->get_updates(this->database)); | ||||
|     } | ||||
|  | ||||
|     ftxui::Element UpdatesPage::OnRender() | ||||
|     { | ||||
|         return this->updatable->Render(); | ||||
|     } | ||||
|  | ||||
|     SearchPage::SearchPage(std::shared_ptr<struct repository> repository, const std::string& architecture) | ||||
|         : repository(repository), architecture(architecture) | ||||
|     { | ||||
|         ftxui::InputOption search_input_option = { .multiline = false }; | ||||
|         this->search_input = ftxui::Input(&this->needle, "Search", search_input_option); | ||||
|         this->type_input = ftxui::Radiobox(std::vector<std::string>{ "Names", "Description" }, &this->search_type); | ||||
|     } | ||||
|  | ||||
|     void SearchPage::Load() | ||||
|     { | ||||
|         this->needle.erase(); | ||||
|     } | ||||
|  | ||||
|     ftxui::Element SearchPage::OnRender() | ||||
|     { | ||||
|         std::vector<ftxui::Element> lines; | ||||
|  | ||||
|         ftxui::FlexboxConfig config; | ||||
|         config.justify_content = ftxui::FlexboxConfig::JustifyContent::SpaceAround; | ||||
|         config.align_items = ftxui::FlexboxConfig::AlignItems::FlexStart; | ||||
|         config.direction = ftxui::FlexboxConfig::Direction::Row; | ||||
|         config.wrap = ftxui::FlexboxConfig::Wrap::NoWrap; | ||||
|         config.SetGap(3, 0); | ||||
|  | ||||
|         return ftxui::vbox({ | ||||
|             ftxui::flexbox({ | ||||
|                 this->search_input->Render(), | ||||
|                 ftxui::window(ftxui::text("Search in"), type_input->Render()) | ||||
|             }, config), | ||||
|             this->search_results->Render() | ftxui::flex | ||||
|         }); | ||||
|     } | ||||
|  | ||||
|     bool SearchPage::OnEvent(ftxui::Event event) | ||||
|     { | ||||
|         if (event == ftxui::Event::Return) | ||||
|     public: | ||||
|         void Load() override | ||||
|         { | ||||
|             if (!this->needle.empty()) | ||||
|         } | ||||
|  | ||||
|         ftxui::Element OnRender() override | ||||
|         { | ||||
|             return ftxui::paragraph("Select an action in the menu."); | ||||
|         } | ||||
|     }; | ||||
|  | ||||
|     class UpdatesPage final : public PageBase | ||||
|     { | ||||
|         ftxui::Component updatable = PackageList("Updates"); | ||||
|         std::shared_ptr<struct repository> repository; | ||||
|         package_database database; | ||||
|  | ||||
|     public: | ||||
|         UpdatesPage(std::shared_ptr<struct repository> repository, package_database database) | ||||
|             : repository(repository), database(database) | ||||
|         { | ||||
|         } | ||||
|  | ||||
|         void Load() override | ||||
|         { | ||||
|             this->updatable = PackageList("Updates", repository->get_updates(this->database)); | ||||
|         } | ||||
|  | ||||
|         ftxui::Element OnRender() override | ||||
|         { | ||||
|             return this->updatable->Render(); | ||||
|         } | ||||
|     }; | ||||
|  | ||||
|     class SearchPage final : public PageBase | ||||
|     { | ||||
|         std::string needle; | ||||
|         ftxui::Component search_input; | ||||
|         ftxui::Component type_input; | ||||
|         std::shared_ptr<struct repository> repository; | ||||
|         std::string architecture; | ||||
|         ftxui::Component search_results = PackageList("Results"); | ||||
|         int search_type{ 0 }; | ||||
|  | ||||
|     public: | ||||
|         SearchPage(std::shared_ptr<struct repository> repository, const std::string& architecture) | ||||
|             : repository(repository), architecture(architecture) | ||||
|         { | ||||
|             ftxui::InputOption search_input_option = { .multiline = false }; | ||||
|             this->search_input = ftxui::Input(&this->needle, "Search", search_input_option); | ||||
|             this->type_input = ftxui::Radiobox(std::vector<std::string>{ "Names", "Description" }, &this->search_type); | ||||
|         } | ||||
|  | ||||
|         void Load() override | ||||
|         { | ||||
|             this->needle.erase(); | ||||
|         } | ||||
|  | ||||
|         ftxui::Element OnRender() override | ||||
|         { | ||||
|             std::vector<ftxui::Element> lines; | ||||
|  | ||||
|             ftxui::FlexboxConfig config; | ||||
|             config.justify_content = ftxui::FlexboxConfig::JustifyContent::SpaceAround; | ||||
|             config.align_items = ftxui::FlexboxConfig::AlignItems::FlexStart; | ||||
|             config.direction = ftxui::FlexboxConfig::Direction::Row; | ||||
|             config.wrap = ftxui::FlexboxConfig::Wrap::NoWrap; | ||||
|             config.SetGap(3, 0); | ||||
|  | ||||
|             return ftxui::vbox({ | ||||
|                 ftxui::flexbox({ | ||||
|                     this->search_input->Render(), | ||||
|                     ftxui::window(ftxui::text("Search in"), type_input->Render()) | ||||
|                 }, config), | ||||
|                 this->search_results->Render() | ftxui::flex | ||||
|             }); | ||||
|         } | ||||
|  | ||||
|         bool OnEvent(ftxui::Event event) override | ||||
|         { | ||||
|             if (event == ftxui::Event::Return) | ||||
|             { | ||||
|                 std::vector<package_identifier> result = | ||||
|                     this->repository->search_names(this->architecture, this->needle); | ||||
|                 this->search_results = PackageList("Search", std::move(result)); | ||||
|                 if (!this->needle.empty()) | ||||
|                 { | ||||
|                     std::vector<package_identifier> result = | ||||
|                         this->repository->search_names(this->architecture, this->needle); | ||||
|                     this->search_results = PackageList("Search", std::move(result)); | ||||
|                 } | ||||
|                 return true; | ||||
|             } | ||||
|             return true; | ||||
|             else if (event == ftxui::Event::ArrowUp || event == ftxui::Event::ArrowDown) | ||||
|             { | ||||
|                 this->search_results->OnEvent(event); | ||||
|                 return true; | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 return this->search_input->OnEvent(event); | ||||
|             } | ||||
|             return false; | ||||
|         } | ||||
|         else if (event == ftxui::Event::ArrowUp || event == ftxui::Event::ArrowDown) | ||||
|         { | ||||
|             this->search_results->OnEvent(event); | ||||
|             return true; | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             return this->search_input->OnEvent(event); | ||||
|         } | ||||
|         return false; | ||||
|     } | ||||
|     }; | ||||
| } | ||||
|   | ||||
							
								
								
									
										83
									
								
								cli/page.hpp
									
									
									
									
									
								
							
							
						
						
									
										83
									
								
								cli/page.hpp
									
									
									
									
									
								
							| @@ -1,83 +0,0 @@ | ||||
| /* | ||||
|  * This Source Code Form is subject to the terms of the Mozilla Public | ||||
|  * License, v. 2.0. If a copy of the MPL was not distributed with this | ||||
|  * file, You can obtain one at https://mozilla.org/MPL/2.0/. | ||||
|  */ | ||||
| #pragma once | ||||
|  | ||||
| #include <ftxui/component/event.hpp> | ||||
| #include <ftxui/component/component_base.hpp> | ||||
| #include <ftxui/component/component.hpp> | ||||
|  | ||||
| #include "katja/repository.hpp" | ||||
| #include "katja/database.hpp" | ||||
|  | ||||
| #include "component.hpp" | ||||
|  | ||||
| namespace katja | ||||
| { | ||||
|     class PageBase : public ftxui::ComponentBase | ||||
|     { | ||||
|     public: | ||||
|         virtual void Load() = 0; | ||||
|     }; | ||||
|  | ||||
|     using Page = std::shared_ptr<PageBase>; | ||||
|     using Pages = std::vector<Page>; | ||||
|  | ||||
|     class ScreenContainer final : public ftxui::ComponentBase | ||||
|     { | ||||
|         int menu_selected{ 0 }; | ||||
|         ftxui::Component menu; | ||||
|         ftxui::Component content; | ||||
|         std::vector<std::string> menu_entries; | ||||
|         Pages menu_pages; | ||||
|         std::function<void()> on_enter; | ||||
|  | ||||
|     public: | ||||
|         ScreenContainer(std::vector<std::pair<std::string, Page>> pages, std::function<void()> on_enter); | ||||
|  | ||||
|         ftxui::Element OnRender() override; | ||||
|         bool OnEvent(ftxui::Event event) override; | ||||
|     }; | ||||
|  | ||||
|     ftxui::Component Screen(std::vector<std::pair<std::string, Page>> pages, std::function<void()> on_enter); | ||||
|  | ||||
|     class WelcomePage final : public PageBase | ||||
|     { | ||||
|     public: | ||||
|         void Load() override; | ||||
|         ftxui::Element OnRender() override; | ||||
|     }; | ||||
|  | ||||
|     class UpdatesPage final : public PageBase | ||||
|     { | ||||
|         ftxui::Component updatable = PackageList("Updates"); | ||||
|         std::shared_ptr<struct repository> repository; | ||||
|         package_database database; | ||||
|  | ||||
|     public: | ||||
|         UpdatesPage(std::shared_ptr<struct repository> repository, package_database database); | ||||
|  | ||||
|         void Load() override; | ||||
|         ftxui::Element OnRender() override; | ||||
|     }; | ||||
|  | ||||
|     class SearchPage final : public PageBase | ||||
|     { | ||||
|         std::string needle; | ||||
|         ftxui::Component search_input; | ||||
|         ftxui::Component type_input; | ||||
|         std::shared_ptr<struct repository> repository; | ||||
|         std::string architecture; | ||||
|         ftxui::Component search_results = PackageList("Results"); | ||||
|         int search_type{ 0 }; | ||||
|  | ||||
|     public: | ||||
|         SearchPage(std::shared_ptr<struct repository> repository, const std::string& architecture); | ||||
|  | ||||
|         void Load() override; | ||||
|         ftxui::Element OnRender() override; | ||||
|         bool OnEvent(ftxui::Event event) override; | ||||
|     }; | ||||
| } | ||||
| @@ -126,7 +126,7 @@ namespace katja | ||||
|         std::ifstream info_stream{ info_filepath }; | ||||
|         std::string info_line, info_variable, info_value; | ||||
|         std::string program_name, version, homepage, email, maintainer; | ||||
|         std::vector<std::string> download, md5sum, download_x86_64, md5sum_x86_64, requires; | ||||
|         std::vector<std::string> download, md5sum, download_x86_64, md5sum_x86_64, requirements; | ||||
|         bool continuation{ false }; | ||||
|  | ||||
|         while (std::getline(info_stream, info_line)) | ||||
| @@ -193,7 +193,7 @@ namespace katja | ||||
|                 } | ||||
|                 else if (info_variable == "REQUIRES") | ||||
|                 { | ||||
|                     boost::split(requires, info_value, boost::is_any_of(" "), boost::token_compress_on); | ||||
|                     boost::split(requirements, info_value, boost::is_any_of(" "), boost::token_compress_on); | ||||
|                 } | ||||
|            } | ||||
|         } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user