From bb4d06a79eaa2b31ad7917a4a51c3a2c559cbfc0 Mon Sep 17 00:00:00 2001 From: jiande <jiande2020@protonmail.com> Date: Wed, 28 Sep 2022 11:52:00 +0800 Subject: [PATCH 1/2] Add new features: Overlay --- CMakeLists.txt | 1 + src/ui/panel/overlay/overlay_impl.cpp | 283 ++++++++++++++++++++++++++ src/ui/panel/panel.hpp | 1 + src/ui/ui.cpp | 1 + 4 files changed, 286 insertions(+) create mode 100644 src/ui/panel/overlay/overlay_impl.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index ae3934f..438a574 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -40,6 +40,7 @@ add_executable(${PROJECT_NAME} src/ui/panel/passwd/passwd.cpp src/ui/panel/ssh/ssh.cpp src/ui/panel/service/service_impl.cpp + src/ui/panel/overlay/overlay_impl.cpp src/ui/ui.cpp src/ui/ui.hpp src/utils.hpp diff --git a/src/ui/panel/overlay/overlay_impl.cpp b/src/ui/panel/overlay/overlay_impl.cpp new file mode 100644 index 0000000..e7acead --- /dev/null +++ b/src/ui/panel/overlay/overlay_impl.cpp @@ -0,0 +1,283 @@ +#include "ftxui/component/component.hpp" +#include "ui/panel/panel.hpp" +#include "utils.hpp" + +#include <array> +#include <cstdio> +#include <filesystem> +#include <fstream> +#include <sstream> +#include <string> +#include <vector> + +using namespace ftxui; + +namespace ui { + +namespace { + +class Overlay : public ComponentBase { + public: + Overlay(std::vector<std::string>* overlay, + int pos, + int* selected, + bool* checked) + : overlays_(overlay), pos_(pos), selected_(selected), checked_(checked) { + Add(Container::Horizontal({ + checkBox_, + dropDown_, + })); + } + + ~Overlay() = default; + + private: + std::vector<std::string>* overlays_; + int pos_; + int* selected_; + bool* checked_; + Component dropDown_ = Dropdown(overlays_, selected_); + Component checkBox_ = + Checkbox("Overlay " + std::to_string(pos_) + " : ", checked_); + + Element Render() override { + return hbox({ + checkBox_->Render() | vcenter, + dropDown_->Render(), + }); + } +}; + +class overlayImpl : public PanelBase { + public: + overlayImpl() { + get_overlays(); + check_uEnv(); + build_UI(); + + Add(Container::Vertical({ + container_, + button_, + })); + } + + ~overlayImpl() = default; + + std::string Title() override { return "Overlay"; } + + private: + void get_overlays() { + overlays_.clear(); + const std::string path_version = "/proc/version"; + std::string line; + + std::ifstream versionFile(path_version); + versionFile >> line; + versionFile >> line; + versionFile >> kernel_version; + versionFile.close(); + + std::string overlay_path = "/boot/dtbs/" + kernel_version + "/overlays"; + + overlays_.push_back("<fileX>.dtbo"); + + for (const auto& file : std::filesystem::directory_iterator(overlay_path)) { + std::stringstream ss(file.path()); + + while (getline(ss, line, '/')) + ; + + overlays_.push_back(line); + } + } + + void build_UI() { + for (int i = 0; i < (int)drop_selected_.size(); i++) { + container_->Add( + Make<Overlay>(&overlays_, i, &drop_selected_[i], &box_checked_[i])); + } + + tab_->Add(container_); + tab_->Add(Container::Vertical({})); + } + + void no_overlap() { + for (int i = 0; i < (int)drop_selected_.size(); i++) { + if (drop_selected_[i] == 0) + box_checked_[i] = false; + + if (i == conSelected_) + continue; + + if (drop_selected_[conSelected_] == drop_selected_[i]) { + drop_selected_[conSelected_] = 0; + } + } + } + + void check_uEnv() { + std::ifstream infile; + infile.open(File_uEnv); + std::string lines; + + if (!infile) { + tabSelected_ = 1; + } + + while (getline(infile, lines)) { + if (!lines.compare("###Overide capes with eeprom")) { + for (int i = 0; i < 4; i++) { + getline(infile, lines); + std::stringstream ss(lines); + std::string temp, dtbo; + + getline(ss, temp, '='); + getline(ss, dtbo, '='); + + if (!temp.compare("#uboot_overlay_addr" + std::to_string(i))) { + box_checked_[i] = false; + + for (int j = 0; j < (int)overlays_.size(); j++) { + if (!overlays_[j].compare(dtbo)) { + drop_selected_[i] = j; + } + } + } else if (!temp.compare("uboot_overlay_addr" + std::to_string(i))) { + box_checked_[i] = true; + + for (int j = 0; j < (int)overlays_.size(); j++) { + if (!overlays_[j].compare(dtbo)) { + drop_selected_[i] = j; + } + } + + } else { + box_checked_[i] = false; + } + } + } + + if (!lines.compare("###Additional custom capes")) { + for (int i = 4; i < 8; i++) { + getline(infile, lines); + std::stringstream ss(lines); + std::string temp, dtbo; + + getline(ss, temp, '='); + getline(ss, dtbo, '='); + + if (!temp.compare("#uboot_overlay_addr" + std::to_string(i))) { + box_checked_[i] = false; + + for (int j = 0; j < (int)overlays_.size(); j++) { + if (!overlays_[j].compare(dtbo)) { + drop_selected_[i] = j; + } + } + } else if (!temp.compare("uboot_overlay_addr" + std::to_string(i))) { + box_checked_[i] = true; + + for (int j = 0; j < (int)overlays_.size(); j++) { + if (!overlays_[j].compare(dtbo)) { + drop_selected_[i] = j; + } + } + + } else { + box_checked_[i] = false; + } + } + } + } + infile.close(); + } + + void overwrite_uEnv() { + std::ifstream infile; + std::ofstream outfile; + + infile.open(File_uEnv); + outfile.open(File_Backup); + + std::string lines; + + while (getline(infile, lines)) { + if (!lines.compare("###Overide capes with eeprom")) { + outfile << lines << std::endl; + for (int i = 0; i < 4; i++) { + getline(infile, lines); + if (box_checked_[i]) + outfile << "uboot_overlay_addr" << i << "=" + << overlays_[drop_selected_[i]] << std::endl; + else + outfile << "#uboot_overlay_addr" << i << "=" + << overlays_[drop_selected_[i]] << std::endl; + } + continue; + } + + if (!lines.compare("###Additional custom capes")) { + outfile << lines << std::endl; + for (int i = 4; i < 8; i++) { + getline(infile, lines); + if (box_checked_[i]) + outfile << "uboot_overlay_addr" << i << "=" + << overlays_[drop_selected_[i]] << std::endl; + else + outfile << "#uboot_overlay_addr" << i << "=" + << overlays_[drop_selected_[i]] << std::endl; + } + continue; + } + + outfile << lines << std::endl; + } + + infile.close(); + outfile.close(); + + std::rename(File_Backup.c_str(), File_uEnv.c_str()); + } + + Element Render() override { + no_overlap(); + + Element content = vbox({ + text("Kernel Version : " + kernel_version), + text("Currently only support maximum 8 overlays") | color(Color::Red), + separator(), + container_->Render() | flex | frame | vscroll_indicator, + separator(), + button_->Render(), + }); + + Element error = + vbox({text("Features not support!") | color(Color::Red) | bold}); + + return (tabSelected_ == 0) ? content : error; + } + + int conSelected_ = 0; + int tabSelected_ = 0; + std::string kernel_version; + const std::string File_uEnv = "/boot/uEnv.txt"; + const std::string File_Backup = "./backup.txt"; + std::vector<std::string> overlays_; + std::array<int, 8> drop_selected_ = {0, 0, 0, 0, 0, 0, 0, 0}; + std::array<bool, 8> box_checked_ = {false, false, false, false, + false, false, false, false}; + Component tab_ = Container::Vertical({}, &tabSelected_); + Component container_ = Container::Vertical({}, &conSelected_); + Component button_ = Button("Apply", [this] { overwrite_uEnv(); }); +}; + +} // namespace + +namespace panel { +Panel overlay() { + return Make<overlayImpl>(); +} + +} // namespace panel + +} // namespace ui \ No newline at end of file diff --git a/src/ui/panel/panel.hpp b/src/ui/panel/panel.hpp index e03fa11..efc7a71 100644 --- a/src/ui/panel/panel.hpp +++ b/src/ui/panel/panel.hpp @@ -34,6 +34,7 @@ Panel PinMux(); Panel About(); Panel passwd(); Panel ssh(); +Panel overlay(); } // namespace panel } // namespace ui diff --git a/src/ui/ui.cpp b/src/ui/ui.cpp index 30bdaf5..b5a1a28 100644 --- a/src/ui/ui.cpp +++ b/src/ui/ui.cpp @@ -184,6 +184,7 @@ void Loop() { panel::PinMux(), panel::service(&screen), panel::ADC(&screen), + panel::overlay(), }}, {"Network", { -- GitLab From 769ffd8774c0a7607985a98563a43a09831e26f6 Mon Sep 17 00:00:00 2001 From: jiande <jiande2020@protonmail.com> Date: Wed, 28 Sep 2022 05:26:17 +0000 Subject: [PATCH 2/2] overlay: add comment and do clang format --- src/ui/panel/overlay/overlay_impl.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/ui/panel/overlay/overlay_impl.cpp b/src/ui/panel/overlay/overlay_impl.cpp index e7acead..69a7d6b 100644 --- a/src/ui/panel/overlay/overlay_impl.cpp +++ b/src/ui/panel/overlay/overlay_impl.cpp @@ -16,6 +16,7 @@ namespace ui { namespace { +/* Handle overlay component with checkbox, title and dropbox */ class Overlay : public ComponentBase { public: Overlay(std::vector<std::string>* overlay, @@ -66,6 +67,7 @@ class overlayImpl : public PanelBase { std::string Title() override { return "Overlay"; } private: + /* Scan all the dtbo file in /boot/dtbs and store in vector */ void get_overlays() { overlays_.clear(); const std::string path_version = "/proc/version"; @@ -91,16 +93,22 @@ class overlayImpl : public PanelBase { } } + /* Build Overlay and Tab Component */ void build_UI() { + // Create Overlay Component for (int i = 0; i < (int)drop_selected_.size(); i++) { container_->Add( Make<Overlay>(&overlays_, i, &drop_selected_[i], &box_checked_[i])); } + // Create Tab Component tab_->Add(container_); tab_->Add(Container::Vertical({})); } + /* Handle if overlay selected twice */ + /* If overlay choosed it will set to empty file */ + /* If overlay file not selected can't enable it */ void no_overlap() { for (int i = 0; i < (int)drop_selected_.size(); i++) { if (drop_selected_[i] == 0) @@ -115,6 +123,7 @@ class overlayImpl : public PanelBase { } } + /* Read file uEnv and update in BB-Config */ void check_uEnv() { std::ifstream infile; infile.open(File_uEnv); @@ -192,6 +201,7 @@ class overlayImpl : public PanelBase { infile.close(); } + /* Apply changes by updating uEnv.txt file */ void overwrite_uEnv() { std::ifstream infile; std::ofstream outfile; @@ -236,6 +246,7 @@ class overlayImpl : public PanelBase { infile.close(); outfile.close(); + // Replace old file with new file std::rename(File_Backup.c_str(), File_uEnv.c_str()); } @@ -254,6 +265,7 @@ class overlayImpl : public PanelBase { Element error = vbox({text("Features not support!") | color(Color::Red) | bold}); + // Check if tabSelected == 0 return content page return (tabSelected_ == 0) ? content : error; } -- GitLab