Merge pull request #2574 from Syndelis/feat/group-drawers

This commit is contained in:
Alexis Rouillard
2023-10-15 21:26:04 +02:00
committed by GitHub
5 changed files with 149 additions and 12 deletions

View File

@ -740,7 +740,7 @@ void waybar::Bar::handleSignal(int signal) {
}
void waybar::Bar::getModules(const Factory& factory, const std::string& pos,
Gtk::Box* group = nullptr) {
waybar::Group* group = nullptr) {
auto module_list = group ? config[pos]["modules"] : config[pos];
if (module_list.isArray()) {
for (const auto& name : module_list) {
@ -753,10 +753,11 @@ void waybar::Bar::getModules(const Factory& factory, const std::string& pos,
auto id_name = ref.substr(6, hash_pos - 6);
auto class_name = hash_pos != std::string::npos ? ref.substr(hash_pos + 1) : "";
auto parent = group ? group : &this->box_;
auto vertical = parent->get_orientation() == Gtk::ORIENTATION_VERTICAL;
auto vertical = (group ? group->getBox().get_orientation() : box_.get_orientation()) ==
Gtk::ORIENTATION_VERTICAL;
auto group_module = new waybar::Group(id_name, class_name, config[ref], vertical);
getModules(factory, ref, &group_module->box);
getModules(factory, ref, group_module);
module = group_module;
} else {
module = factory.makeModule(ref);
@ -765,7 +766,7 @@ void waybar::Bar::getModules(const Factory& factory, const std::string& pos,
std::shared_ptr<AModule> module_sp(module);
modules_all_.emplace_back(module_sp);
if (group) {
group->pack_start(*module, false, false);
group->addWidget(*module);
} else {
if (pos == "modules-left") {
modules_left_.emplace_back(module_sp);

View File

@ -4,12 +4,32 @@
#include <util/command.hpp>
#include "gdkmm/device.h"
#include "gtkmm/widget.h"
namespace waybar {
const Gtk::RevealerTransitionType getPreferredTransitionType(bool is_vertical, bool left_to_right) {
if (is_vertical) {
if (left_to_right) {
return Gtk::RevealerTransitionType::REVEALER_TRANSITION_TYPE_SLIDE_DOWN;
} else {
return Gtk::RevealerTransitionType::REVEALER_TRANSITION_TYPE_SLIDE_UP;
}
} else {
if (left_to_right) {
return Gtk::RevealerTransitionType::REVEALER_TRANSITION_TYPE_SLIDE_RIGHT;
} else {
return Gtk::RevealerTransitionType::REVEALER_TRANSITION_TYPE_SLIDE_LEFT;
}
}
}
Group::Group(const std::string& name, const std::string& id, const Json::Value& config,
bool vertical)
: AModule(config, name, id, false, false),
box{vertical ? Gtk::ORIENTATION_VERTICAL : Gtk::ORIENTATION_HORIZONTAL, 0} {
: AModule(config, name, id, true, true),
box{vertical ? Gtk::ORIENTATION_VERTICAL : Gtk::ORIENTATION_HORIZONTAL, 0},
revealer_box{vertical ? Gtk::ORIENTATION_VERTICAL : Gtk::ORIENTATION_HORIZONTAL, 0} {
box.set_name(name_);
if (!id.empty()) {
box.get_style_context()->add_class(id);
@ -29,12 +49,77 @@ Group::Group(const std::string& name, const std::string& id, const Json::Value&
} else {
throw std::runtime_error("Invalid orientation value: " + orientation);
}
if (config_["drawer"].isObject()) {
is_drawer = true;
const auto& drawer_config = config_["drawer"];
const int transition_duration =
(drawer_config["transition-duration"].isInt() ? drawer_config["transition-duration"].asInt()
: 500);
add_class_to_drawer_children =
(drawer_config["children-class"].isString() ? drawer_config["children-class"].asString()
: "drawer-child");
const bool left_to_right = (drawer_config["transition-left-to-right"].isBool()
? drawer_config["transition-left-to-right"].asBool()
: true);
auto transition_type = getPreferredTransitionType(vertical, left_to_right);
revealer.set_transition_type(transition_type);
revealer.set_transition_duration(transition_duration);
revealer.set_reveal_child(false);
revealer.get_style_context()->add_class("drawer");
revealer.add(revealer_box);
box.pack_start(revealer);
addHoverHandlerTo(revealer);
}
}
bool Group::handleMouseHover(GdkEventCrossing* const& e) {
switch (e->type) {
case GDK_ENTER_NOTIFY:
revealer.set_reveal_child(true);
break;
case GDK_LEAVE_NOTIFY:
revealer.set_reveal_child(false);
break;
default:
break;
}
return true;
}
void Group::addHoverHandlerTo(Gtk::Widget& widget) {
widget.add_events(Gdk::EventMask::ENTER_NOTIFY_MASK | Gdk::EventMask::LEAVE_NOTIFY_MASK);
widget.signal_enter_notify_event().connect(sigc::mem_fun(*this, &Group::handleMouseHover));
widget.signal_leave_notify_event().connect(sigc::mem_fun(*this, &Group::handleMouseHover));
}
auto Group::update() -> void {
// noop
}
Gtk::Box& Group::getBox() { return is_drawer ? (is_first_widget ? box : revealer_box) : box; }
void Group::addWidget(Gtk::Widget& widget) {
getBox().pack_start(widget, false, false);
if (is_drawer) {
// Necessary because of GTK's hitbox detection
addHoverHandlerTo(widget);
if (!is_first_widget) {
widget.get_style_context()->add_class(add_class_to_drawer_children);
}
}
is_first_widget = false;
}
Group::operator Gtk::Widget&() { return box; }
} // namespace waybar