From e25a7c9719dbc7e81f6397b07bd32092fbd1df1e Mon Sep 17 00:00:00 2001 From: Viktar Lukashonak Date: Tue, 28 Feb 2023 15:32:28 +0300 Subject: [PATCH] ISSUE#1977. AModule implements module actions call Signed-off-by: Viktar Lukashonak --- include/AModule.hpp | 9 +++- include/IModule.hpp | 1 + include/modules/clock.hpp | 26 +++++++++--- src/AModule.cpp | 48 ++++++++++++++++++---- src/modules/clock.cpp | 86 ++++++++++++--------------------------- 5 files changed, 96 insertions(+), 74 deletions(-) diff --git a/include/AModule.hpp b/include/AModule.hpp index 35625cd1..d221caca 100644 --- a/include/AModule.hpp +++ b/include/AModule.hpp @@ -11,16 +11,20 @@ namespace waybar { class AModule : public IModule { public: - AModule(const Json::Value &, const std::string &, const std::string &, bool enable_click = false, - bool enable_scroll = false); virtual ~AModule(); virtual auto update() -> void; virtual auto refresh(int) -> void{}; virtual operator Gtk::Widget &(); + virtual auto doAction(const std::string& name) -> void; Glib::Dispatcher dp; protected: + // Don't need to make an object directly + // Derived classes are able to use it + AModule(const Json::Value &, const std::string &, const std::string &, bool enable_click = false, + bool enable_scroll = false); + enum SCROLL_DIR { NONE, UP, DOWN, LEFT, RIGHT }; SCROLL_DIR getScrollDir(GdkEventScroll *e); @@ -37,6 +41,7 @@ class AModule : public IModule { std::vector pid_; gdouble distance_scrolled_y_; gdouble distance_scrolled_x_; + std::map eventActionMap_; static const inline std::map, std::string> eventMap_{ {std::make_pair(1, GdkEventType::GDK_BUTTON_PRESS), "on-click"}, {std::make_pair(1, GdkEventType::GDK_2BUTTON_PRESS), "on-double-click"}, diff --git a/include/IModule.hpp b/include/IModule.hpp index 961a4612..b76c33e3 100644 --- a/include/IModule.hpp +++ b/include/IModule.hpp @@ -9,6 +9,7 @@ class IModule { virtual ~IModule() = default; virtual auto update() -> void = 0; virtual operator Gtk::Widget&() = 0; + virtual auto doAction(const std::string& name) -> void = 0; }; } // namespace waybar diff --git a/include/modules/clock.hpp b/include/modules/clock.hpp index c318e8ba..8d9f79fd 100644 --- a/include/modules/clock.hpp +++ b/include/modules/clock.hpp @@ -15,26 +15,26 @@ enum class WeeksSide { HIDDEN, }; -enum class CldMode { MONTH, YEAR }; +enum class CldMode { + MONTH, + YEAR +}; -class Clock : public ALabel { +class Clock final : public ALabel { public: Clock(const std::string&, const Json::Value&); ~Clock() = default; auto update() -> void; + auto doAction(const std::string& name) -> void override; private: util::SleeperThread thread_; - std::map, void (waybar::modules::Clock::*)()> eventMap_; std::locale locale_; std::vector time_zones_; int current_time_zone_idx_; bool is_calendar_in_tooltip_; bool is_timezoned_list_in_tooltip_; - bool handleScroll(GdkEventScroll* e); - bool handleToggle(GdkEventButton* const& e); - auto first_day_of_week() -> date::weekday; const date::time_zone* current_timezone(); bool is_timezone_fixed(); @@ -56,6 +56,20 @@ class Clock : public ALabel { /*Calendar functions*/ auto get_calendar(const date::zoned_seconds& now, const date::zoned_seconds& wtime) -> std::string; + /*Clock actions*/ void cldModeSwitch(); + void cldShift_up(); + void cldShift_down(); + void tz_up(); + void tz_down(); + + // ModuleActionMap + static inline std::map actionMap_{ + {"mode", &waybar::modules::Clock::cldModeSwitch}, + {"shift_up", &waybar::modules::Clock::cldShift_up}, + {"shift_down", &waybar::modules::Clock::cldShift_down}, + {"tz_up", &waybar::modules::Clock::tz_up}, + {"tz_down", &waybar::modules::Clock::tz_down} + }; }; } // namespace waybar::modules diff --git a/src/AModule.cpp b/src/AModule.cpp index b19594a1..1566e88b 100644 --- a/src/AModule.cpp +++ b/src/AModule.cpp @@ -32,6 +32,18 @@ AModule::AModule(const Json::Value& config, const std::string& name, const std:: event_box_.add_events(Gdk::SCROLL_MASK | Gdk::SMOOTH_SCROLL_MASK); event_box_.signal_scroll_event().connect(sigc::mem_fun(*this, &AModule::handleScroll)); } + + // Configure module action Map + const Json::Value actions{config_["actions"]}; + for (Json::Value::const_iterator it = actions.begin(); it != actions.end(); ++it) { + if (it.key().isString() && it->isString()) + if (eventActionMap_.count(it.key().asString()) == 0) + eventActionMap_.insert({it.key().asString(), it->asString()}); + else + spdlog::warn("Dublicate action is ignored: {0}", it.key().asString()); + else + spdlog::warn("Wrong actions section configuration. See config by index: {}", it.index()); + } } AModule::~AModule() { @@ -48,19 +60,33 @@ auto AModule::update() -> void { pid_.push_back(util::command::forkExec(config_["on-update"].asString())); } } +// Get mapping between event name and module action name +// Then call overrided doAction in order to call appropriate module action +auto AModule::doAction(const std::string& name) -> void { + if (!name.empty()) { + const std::map::const_iterator& recA{eventActionMap_.find(name)}; + // Call overrided action if derrived class has implemented it + if (recA != eventActionMap_.cend() && name != recA->second) this->doAction(recA->second); + } +} bool AModule::handleToggle(GdkEventButton* const& e) { + std::string format{}; const std::map, std::string>::const_iterator& rec{ eventMap_.find(std::pair(e->button, e->type))}; - std::string format{(rec != eventMap_.cend()) ? rec->second : std::string{""}}; + if (rec != eventMap_.cend()) { + // First call module actions + this->AModule::doAction(rec->second); + format = rec->second; + } + // Second call user scripts if (!format.empty()) { if (config_[format].isString()) format = config_[format].asString(); else format.clear(); } - if (!format.empty()) { pid_.push_back(util::command::forkExec(format)); } @@ -122,11 +148,19 @@ AModule::SCROLL_DIR AModule::getScrollDir(GdkEventScroll* e) { bool AModule::handleScroll(GdkEventScroll* e) { auto dir = getScrollDir(e); - if (dir == SCROLL_DIR::UP && config_["on-scroll-up"].isString()) { - pid_.push_back(util::command::forkExec(config_["on-scroll-up"].asString())); - } else if (dir == SCROLL_DIR::DOWN && config_["on-scroll-down"].isString()) { - pid_.push_back(util::command::forkExec(config_["on-scroll-down"].asString())); - } + std::string eventName{}; + + if (dir == SCROLL_DIR::UP) + eventName = "on-scroll-up"; + else if (dir == SCROLL_DIR::DOWN) + eventName = "on-scroll-down"; + + // First call module actions + this->AModule::doAction(eventName); + // Second call user scripts + if (config_[eventName].isString()) + pid_.push_back(util::command::forkExec(config_[eventName].asString())); + dp.emit(); return true; } diff --git a/src/modules/clock.cpp b/src/modules/clock.cpp index 414ee337..af161d91 100644 --- a/src/modules/clock.cpp +++ b/src/modules/clock.cpp @@ -125,16 +125,6 @@ waybar::modules::Clock::Clock(const std::string& id, const Json::Value& config) return false; }); } - if (config_[kCalendarPlaceholder]["on-click-left"].isString()) { - if (config_[kCalendarPlaceholder]["on-click-left"].asString() == "mode") - eventMap_.insert({std::make_pair(1, GdkEventType::GDK_BUTTON_PRESS), - &waybar::modules::Clock::cldModeSwitch}); - } - if (config_[kCalendarPlaceholder]["on-click-right"].isString()) { - if (config_[kCalendarPlaceholder]["on-click-right"].asString() == "mode") - eventMap_.insert({std::make_pair(3, GdkEventType::GDK_BUTTON_PRESS), - &waybar::modules::Clock::cldModeSwitch}); - } } if (config_["locale"].isString()) @@ -203,56 +193,12 @@ auto waybar::modules::Clock::update() -> void { ALabel::update(); } -bool waybar::modules::Clock::handleToggle(GdkEventButton* const& e) { - const std::map, void (waybar::modules::Clock::*)()>::const_iterator& - rec{eventMap_.find(std::pair(e->button, e->type))}; - - const auto callMethod{(rec != eventMap_.cend()) ? rec->second : nullptr}; - - if (callMethod) { - (this->*callMethod)(); +auto waybar::modules::Clock::doAction(const std::string& name) -> void { + if ((actionMap_[name])) { + (this->*actionMap_[name])(); + update(); } else - return ALabel::handleToggle(e); - - update(); - return true; -} - -bool waybar::modules::Clock::handleScroll(GdkEventScroll* e) { - // defer to user commands if set - if (config_["on-scroll-up"].isString() || config_["on-scroll-down"].isString()) { - return AModule::handleScroll(e); - } - - auto dir = AModule::getScrollDir(e); - - // Shift calendar date - if (cldShift_.count() != 0) { - if (dir == SCROLL_DIR::UP) - cldCurrShift_ += ((cldMode_ == CldMode::YEAR) ? 12 : 1) * cldShift_; - else - cldCurrShift_ -= ((cldMode_ == CldMode::YEAR) ? 12 : 1) * cldShift_; - } else { - // Change time zone - if (dir != SCROLL_DIR::UP && dir != SCROLL_DIR::DOWN) { - return true; - } - if (time_zones_.size() == 1) { - return true; - } - - auto nr_zones = time_zones_.size(); - if (dir == SCROLL_DIR::UP) { - size_t new_idx = current_time_zone_idx_ + 1; - current_time_zone_idx_ = new_idx == nr_zones ? 0 : new_idx; - } else { - current_time_zone_idx_ = - current_time_zone_idx_ == 0 ? nr_zones - 1 : current_time_zone_idx_ - 1; - } - } - - update(); - return true; + spdlog::error("Clock. Unsupported action \"{0}\"", name); } // The number of weeks in calendar month layout plus 1 more for calendar titles @@ -461,9 +407,31 @@ auto waybar::modules::Clock::get_calendar(const date::zoned_seconds& now, return os.str(); } +/*Clock actions*/ void waybar::modules::Clock::cldModeSwitch() { cldMode_ = (cldMode_ == CldMode::YEAR) ? CldMode::MONTH : CldMode::YEAR; } +void waybar::modules::Clock::cldShift_up() { + cldCurrShift_ += ((cldMode_ == CldMode::YEAR) ? 12 : 1) * cldShift_; +} +void waybar::modules::Clock::cldShift_down() { + cldCurrShift_ -= ((cldMode_ == CldMode::YEAR) ? 12 : 1) * cldShift_; +} +void waybar::modules::Clock::tz_up() { + auto nr_zones = time_zones_.size(); + + if (nr_zones == 1) return; + + size_t new_idx = current_time_zone_idx_ + 1; + current_time_zone_idx_ = new_idx == nr_zones ? 0 : new_idx; +} +void waybar::modules::Clock::tz_down() { + auto nr_zones = time_zones_.size(); + + if (nr_zones == 1) return; + + current_time_zone_idx_ = current_time_zone_idx_ == 0 ? nr_zones - 1 : current_time_zone_idx_ - 1; +} auto waybar::modules::Clock::timezones_text(std::chrono::system_clock::time_point* now) -> std::string {