Waybar/src/group.cpp

142 lines
4.3 KiB
C++
Raw Normal View History

2021-10-31 22:55:13 +00:00
#include "group.hpp"
2022-04-06 06:37:19 +00:00
2021-10-31 22:55:13 +00:00
#include <fmt/format.h>
2022-04-06 06:37:19 +00:00
2021-10-31 22:55:13 +00:00
#include <util/command.hpp>
#include "gtkmm/enums.h"
2023-10-14 20:17:19 +00:00
#include "gtkmm/widget.h"
2021-10-31 22:55:13 +00:00
namespace waybar {
2024-08-03 03:30:56 +00:00
Gtk::RevealerTransitionType getPreferredTransitionType(bool is_vertical) {
/* The transition direction of a drawer is not actually determined by the transition type,
* but rather by the order of 'box' and 'revealer_box':
* 'REVEALER_TRANSITION_TYPE_SLIDE_LEFT' and 'REVEALER_TRANSITION_TYPE_SLIDE_RIGHT'
* will result in the same thing.
* However: we still need to differentiate between vertical and horizontal transition types.
*/
2023-10-14 21:03:27 +00:00
if (is_vertical) {
return Gtk::RevealerTransitionType::REVEALER_TRANSITION_TYPE_SLIDE_UP;
2023-10-14 21:03:27 +00:00
}
2024-07-02 15:12:41 +00:00
return Gtk::RevealerTransitionType::REVEALER_TRANSITION_TYPE_SLIDE_LEFT;
2023-10-14 21:03:27 +00:00
}
Group::Group(const std::string& name, const std::string& id, const Json::Value& config,
bool vertical)
2023-10-14 20:17:19 +00:00
: 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);
}
// default orientation: orthogonal to parent
auto orientation =
config_["orientation"].empty() ? "orthogonal" : config_["orientation"].asString();
if (orientation == "inherit") {
// keep orientation passed
} else if (orientation == "orthogonal") {
box.set_orientation(vertical ? Gtk::ORIENTATION_HORIZONTAL : Gtk::ORIENTATION_VERTICAL);
} else if (orientation == "vertical") {
box.set_orientation(Gtk::ORIENTATION_VERTICAL);
} else if (orientation == "horizontal") {
box.set_orientation(Gtk::ORIENTATION_HORIZONTAL);
} else {
throw std::runtime_error("Invalid orientation value: " + orientation);
}
2023-10-14 20:17:19 +00:00
2023-10-14 21:03:27 +00:00
if (config_["drawer"].isObject()) {
2023-10-14 20:17:19 +00:00
is_drawer = true;
2023-10-14 21:03:27 +00:00
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);
2024-07-07 20:08:45 +00:00
click_to_reveal = drawer_config["click-to-reveal"].asBool();
2023-10-14 21:03:27 +00:00
auto transition_type = getPreferredTransitionType(vertical);
2023-10-14 21:03:27 +00:00
revealer.set_transition_type(transition_type);
revealer.set_transition_duration(transition_duration);
2023-10-14 20:17:19 +00:00
revealer.set_reveal_child(false);
revealer.get_style_context()->add_class("drawer");
revealer.add(revealer_box);
if (left_to_right) {
box.pack_end(revealer);
} else {
box.pack_start(revealer);
}
2023-10-14 20:17:19 +00:00
}
event_box_.add(box);
}
2023-10-14 20:17:19 +00:00
2024-07-07 20:08:45 +00:00
void Group::show_group() {
box.set_state_flags(Gtk::StateFlags::STATE_FLAG_PRELIGHT);
revealer.set_reveal_child(true);
}
2021-10-31 22:55:13 +00:00
2024-07-07 20:08:45 +00:00
void Group::hide_group() {
box.unset_state_flags(Gtk::StateFlags::STATE_FLAG_PRELIGHT);
revealer.set_reveal_child(false);
2024-07-07 20:08:45 +00:00
}
bool Group::handleMouseEnter(GdkEventCrossing* const& e) {
if (!click_to_reveal) {
show_group();
}
return false;
}
2024-07-07 20:08:45 +00:00
bool Group::handleMouseLeave(GdkEventCrossing* const& e) {
if (!click_to_reveal && e->detail != GDK_NOTIFY_INFERIOR) {
2024-07-07 20:08:45 +00:00
hide_group();
}
return false;
}
bool Group::handleToggle(GdkEventButton* const& e) {
if (!click_to_reveal || e->button != 1) {
return false;
}
2024-08-03 03:30:56 +00:00
if ((box.get_state_flags() & Gtk::StateFlags::STATE_FLAG_PRELIGHT) != 0U) {
2024-07-07 20:08:45 +00:00
hide_group();
} else {
show_group();
}
return true;
}
2021-10-31 22:55:13 +00:00
auto Group::update() -> void {
// noop
}
2023-10-14 20:17:19 +00:00
Gtk::Box& Group::getBox() { return is_drawer ? (is_first_widget ? box : revealer_box) : box; }
void Group::addWidget(Gtk::Widget& widget) {
2023-10-14 21:39:42 +00:00
getBox().pack_start(widget, false, false);
2023-10-14 21:03:27 +00:00
if (is_drawer && !is_first_widget) {
widget.get_style_context()->add_class(add_class_to_drawer_children);
2023-10-14 20:17:19 +00:00
}
2023-10-14 21:03:27 +00:00
2023-10-14 20:17:19 +00:00
is_first_widget = false;
}
Group::operator Gtk::Widget&() { return event_box_; }
2021-10-31 22:55:13 +00:00
} // namespace waybar