Merge pull request #5156 from Alexays/refactor/generic-tooltip
refactor(ALabel): generic label+tooltip helper to remove per-module duplication
This commit is contained in:
@@ -1,10 +1,14 @@
|
||||
#pragma once
|
||||
|
||||
#include <fmt/args.h>
|
||||
#include <fmt/format.h>
|
||||
#include <glibmm/markup.h>
|
||||
#include <gtkmm/label.h>
|
||||
#include <json/json.h>
|
||||
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include "AModule.hpp"
|
||||
|
||||
@@ -30,6 +34,50 @@ class ALabel : public AModule {
|
||||
bool setLabelMarkup(const Glib::ustring& markup);
|
||||
bool setTooltipMarkup(const Glib::ustring& markup);
|
||||
|
||||
// resolveTooltipFormat() / resolveFormat() are inherited from AModule.
|
||||
|
||||
// Combined label + tooltip helper. Builds a single fmt argument store from
|
||||
// `args`, renders `labelFormat` into the label and the resolved tooltip format
|
||||
// into the tooltip, both through the dedup-aware setters. Honors the `tooltip`
|
||||
// toggle. This replaces the label/tooltip formatting boilerplate that modules
|
||||
// used to duplicate. `state` selects `tooltip-format-<state>` when non-empty.
|
||||
template <typename... Args>
|
||||
void updateLabelAndTooltipForState(const std::string& state, const std::string& labelFormat,
|
||||
const std::string& tooltipDefault, Args&&... args) {
|
||||
fmt::dynamic_format_arg_store<fmt::format_context> store;
|
||||
(store.push_back(std::forward<Args>(args)), ...);
|
||||
setLabelMarkup(fmt::vformat(labelFormat, store));
|
||||
if (tooltipEnabled()) {
|
||||
setTooltipMarkup(fmt::vformat(resolveTooltipFormat(tooltipDefault, state), store));
|
||||
}
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
void updateLabelAndTooltip(const std::string& labelFormat, const std::string& tooltipDefault,
|
||||
Args&&... args) {
|
||||
updateLabelAndTooltipForState("", labelFormat, tooltipDefault, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
// Overloads accepting a pre-built argument store, for modules that must
|
||||
// assemble a dynamic set of format arguments (e.g. per-core CPU stats) that
|
||||
// cannot be expressed through a fixed variadic call.
|
||||
// A non-const reference is used so this overload is preferred over the
|
||||
// variadic template above (which would otherwise bind the store as a single
|
||||
// forwarded argument).
|
||||
void updateLabelAndTooltipForState(const std::string& state, const std::string& labelFormat,
|
||||
const std::string& tooltipDefault,
|
||||
fmt::dynamic_format_arg_store<fmt::format_context>& store) {
|
||||
setLabelMarkup(fmt::vformat(labelFormat, store));
|
||||
if (tooltipEnabled()) {
|
||||
setTooltipMarkup(fmt::vformat(resolveTooltipFormat(tooltipDefault, state), store));
|
||||
}
|
||||
}
|
||||
|
||||
void updateLabelAndTooltip(const std::string& labelFormat, const std::string& tooltipDefault,
|
||||
fmt::dynamic_format_arg_store<fmt::format_context>& store) {
|
||||
updateLabelAndTooltipForState("", labelFormat, tooltipDefault, store);
|
||||
}
|
||||
|
||||
bool handleToggle(GdkEventButton* const& e) override;
|
||||
void copyToClipboard(const std::string&);
|
||||
virtual std::string getState(uint8_t value, bool lesser = false);
|
||||
|
||||
@@ -1,11 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#include <fmt/args.h>
|
||||
#include <fmt/format.h>
|
||||
#include <glibmm/dispatcher.h>
|
||||
#include <glibmm/markup.h>
|
||||
#include <gtkmm.h>
|
||||
#include <gtkmm/eventbox.h>
|
||||
#include <json/json.h>
|
||||
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include "IModule.hpp"
|
||||
|
||||
namespace waybar {
|
||||
@@ -40,6 +45,40 @@ class AModule : public IModule {
|
||||
SCROLL_DIR getScrollDir(GdkEventScroll* e);
|
||||
bool tooltipEnabled() const;
|
||||
|
||||
// --- Generic format/tooltip resolution (config-only, usable by any module,
|
||||
// ALabel-derived or not). Prefers `<key>-<state>`, then `<key>`, then default.
|
||||
std::string resolveFormat(const std::string& defaultFormat, const std::string& state = "") const {
|
||||
if (!state.empty() && config_["format-" + state].isString()) {
|
||||
return config_["format-" + state].asString();
|
||||
}
|
||||
if (config_["format"].isString()) {
|
||||
return config_["format"].asString();
|
||||
}
|
||||
return defaultFormat;
|
||||
}
|
||||
std::string resolveTooltipFormat(const std::string& defaultFormat,
|
||||
const std::string& state = "") const {
|
||||
if (!state.empty() && config_["tooltip-format-" + state].isString()) {
|
||||
return config_["tooltip-format-" + state].asString();
|
||||
}
|
||||
if (config_["tooltip-format"].isString()) {
|
||||
return config_["tooltip-format"].asString();
|
||||
}
|
||||
return defaultFormat;
|
||||
}
|
||||
|
||||
// Generic tooltip for any widget: honors the `tooltip` toggle and
|
||||
// `tooltip-format`, formats with the given args and applies it. Lets modules
|
||||
// that are not ALabel-derived (e.g. gamemode) reuse the shared logic.
|
||||
template <typename... Args>
|
||||
void updateTooltip(Gtk::Widget& widget, const std::string& defaultFormat, Args&&... args) {
|
||||
if (!tooltipEnabled()) {
|
||||
return;
|
||||
}
|
||||
widget.set_tooltip_markup(
|
||||
fmt::format(fmt::runtime(resolveTooltipFormat(defaultFormat)), std::forward<Args>(args)...));
|
||||
}
|
||||
|
||||
std::vector<int> pid_children_;
|
||||
const std::string name_;
|
||||
const Json::Value& config_;
|
||||
|
||||
Reference in New Issue
Block a user