Store all action info in action_context
The renderer is responsible for setting the start and end positions while dispatch does the rest
This commit is contained in:
parent
f359540b5d
commit
464bedb33c
@ -36,10 +36,10 @@ class renderer : public renderer_interface,
|
||||
public signal_receiver<SIGN_PRIORITY_RENDERER, signals::ui::request_snapshot> {
|
||||
public:
|
||||
using make_type = unique_ptr<renderer>;
|
||||
static make_type make(const bar_settings& bar);
|
||||
static make_type make(const bar_settings& bar, tags::action_context& action_ctxt);
|
||||
|
||||
explicit renderer(connection& conn, signal_emitter& sig, const config&, const logger& logger, const bar_settings& bar,
|
||||
background_manager& background_manager);
|
||||
background_manager& background_manager, tags::action_context& action_ctxt);
|
||||
~renderer();
|
||||
|
||||
xcb_window_t window() const;
|
||||
@ -56,9 +56,6 @@ class renderer : public renderer_interface,
|
||||
void action_open(const tags::context& ctxt, mousebtn btn, tags::action_t id) override;
|
||||
void action_close(const tags::context& ctxt, tags::action_t id) override;
|
||||
|
||||
std::map<mousebtn, tags::action_t> get_actions(int x) override;
|
||||
tags::action_t get_action(mousebtn btn, int x) override;
|
||||
|
||||
protected:
|
||||
void fill_background();
|
||||
void fill_overline(rgba color, double x, double w);
|
||||
@ -114,7 +111,6 @@ class renderer : public renderer_interface,
|
||||
bool m_pseudo_transparency{false};
|
||||
|
||||
alignment m_align;
|
||||
std::unordered_map<tags::action_t, action_block> m_actions;
|
||||
|
||||
bool m_fixedcenter;
|
||||
string m_snapshot_dst;
|
||||
|
@ -7,6 +7,8 @@ POLYBAR_NS
|
||||
|
||||
class renderer_interface {
|
||||
public:
|
||||
renderer_interface(tags::action_context& action_ctxt) : m_action_ctxt(action_ctxt){};
|
||||
|
||||
virtual void render_offset(const tags::context& ctxt, int pixels) = 0;
|
||||
virtual void render_text(const tags::context& ctxt, const string&& str) = 0;
|
||||
virtual void change_alignment(const tags::context& ctxt) = 0;
|
||||
@ -14,8 +16,14 @@ class renderer_interface {
|
||||
virtual void action_open(const tags::context& ctxt, mousebtn btn, tags::action_t id) = 0;
|
||||
virtual void action_close(const tags::context& ctxt, tags::action_t id) = 0;
|
||||
|
||||
virtual std::map<mousebtn, tags::action_t> get_actions(int x) = 0;
|
||||
virtual tags::action_t get_action(mousebtn btn, int x) = 0;
|
||||
protected:
|
||||
/**
|
||||
* Stores information about actions in the current action cycle.
|
||||
*
|
||||
* The renderer is only responsible for updating the start and end positions
|
||||
* of each action block.
|
||||
*/
|
||||
tags::action_context& m_action_ctxt;
|
||||
};
|
||||
|
||||
POLYBAR_NS_END
|
||||
|
@ -109,21 +109,6 @@ struct action {
|
||||
string command{};
|
||||
};
|
||||
|
||||
struct action_block {
|
||||
mousebtn button{mousebtn::NONE};
|
||||
alignment align{alignment::NONE};
|
||||
double start_x{0.0};
|
||||
double end_x{0.0};
|
||||
|
||||
unsigned int width() const {
|
||||
return static_cast<unsigned int>(end_x - start_x + 0.5);
|
||||
}
|
||||
|
||||
bool test(int point) const {
|
||||
return static_cast<int>(start_x) <= point && static_cast<int>(end_x) > point;
|
||||
}
|
||||
};
|
||||
|
||||
struct bar_settings {
|
||||
explicit bar_settings() = default;
|
||||
bar_settings(const bar_settings& other) = default;
|
||||
|
@ -1,5 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <map>
|
||||
|
||||
#include "common.hpp"
|
||||
#include "components/types.hpp"
|
||||
#include "tags/types.hpp"
|
||||
@ -96,6 +98,26 @@ namespace tags {
|
||||
|
||||
static constexpr action_t NO_ACTION = -1;
|
||||
|
||||
struct action_block {
|
||||
action_block(const string&& cmd, mousebtn button, alignment align, bool is_open)
|
||||
: cmd(std::move(cmd)), button(button), align(align), is_open(is_open){};
|
||||
|
||||
string cmd;
|
||||
double start_x{0};
|
||||
double end_x{0};
|
||||
mousebtn button;
|
||||
alignment align;
|
||||
bool is_open;
|
||||
|
||||
unsigned int width() const {
|
||||
return static_cast<unsigned int>(end_x - start_x + 0.5);
|
||||
}
|
||||
|
||||
bool test(int point) const {
|
||||
return static_cast<int>(start_x) <= point && static_cast<int>(end_x) > point;
|
||||
}
|
||||
};
|
||||
|
||||
class action_context {
|
||||
public:
|
||||
void reset();
|
||||
@ -103,22 +125,20 @@ namespace tags {
|
||||
action_t action_open(mousebtn btn, const string&& cmd, alignment align);
|
||||
std::pair<action_t, mousebtn> action_close(mousebtn btn, alignment align);
|
||||
|
||||
void set_start(action_t id, double x);
|
||||
void set_end(action_t id, double x);
|
||||
|
||||
std::map<mousebtn, tags::action_t> get_actions(int x) const;
|
||||
action_t has_action(mousebtn btn, int x) const;
|
||||
|
||||
string get_action(action_t id) const;
|
||||
bool has_double_click() const;
|
||||
|
||||
size_t num_actions() const;
|
||||
|
||||
std::vector<action_block>& get_blocks();
|
||||
|
||||
protected:
|
||||
struct action_block {
|
||||
action_block(const string&& cmd, mousebtn button, alignment align, bool is_open)
|
||||
: cmd(std::move(cmd)), button(button), align(align), is_open(is_open){};
|
||||
|
||||
string cmd;
|
||||
mousebtn button;
|
||||
alignment align;
|
||||
bool is_open;
|
||||
};
|
||||
|
||||
/**
|
||||
* Stores all currently known action blocks.
|
||||
*
|
||||
|
@ -649,10 +649,9 @@ void bar::handle(const evt::motion_notify& evt) {
|
||||
// scroll cursor is less important than click cursor, so we shouldn't return until we are sure there is no click
|
||||
// action
|
||||
bool found_scroll = false;
|
||||
const auto& actions = m_renderer->get_actions(m_motion_pos);
|
||||
const auto has_action = [&](const vector<mousebtn>& buttons) -> bool {
|
||||
for (auto btn : buttons) {
|
||||
if (actions.at(btn) != tags::NO_ACTION) {
|
||||
if (m_action_ctxt->has_action(btn, m_motion_pos) != tags::NO_ACTION) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -741,7 +740,8 @@ void bar::handle(const evt::button_press& evt) {
|
||||
m_buttonpress_pos = evt->event_x;
|
||||
|
||||
const auto deferred_fn = [&](size_t) {
|
||||
tags::action_t action = m_renderer->get_action(m_buttonpress_btn, m_buttonpress_pos);
|
||||
tags::action_t action = m_action_ctxt->has_action(m_buttonpress_btn, m_buttonpress_pos);
|
||||
;
|
||||
|
||||
if (action != tags::NO_ACTION) {
|
||||
m_log.trace("Found matching input area");
|
||||
@ -830,7 +830,7 @@ void bar::handle(const evt::configure_notify&) {
|
||||
|
||||
bool bar::on(const signals::eventqueue::start&) {
|
||||
m_log.trace("bar: Create renderer");
|
||||
m_renderer = renderer::make(m_opts);
|
||||
m_renderer = renderer::make(m_opts, *m_action_ctxt);
|
||||
m_opts.window = m_renderer->window();
|
||||
|
||||
// Subscribe to window enter and leave events
|
||||
|
@ -21,7 +21,7 @@ static constexpr double BLOCK_GAP{20.0};
|
||||
/**
|
||||
* Create instance
|
||||
*/
|
||||
renderer::make_type renderer::make(const bar_settings& bar) {
|
||||
renderer::make_type renderer::make(const bar_settings& bar, tags::action_context& action_ctxt) {
|
||||
// clang-format off
|
||||
return factory_util::unique<renderer>(
|
||||
connection::make(),
|
||||
@ -29,7 +29,8 @@ renderer::make_type renderer::make(const bar_settings& bar) {
|
||||
config::make(),
|
||||
logger::make(),
|
||||
forward<decltype(bar)>(bar),
|
||||
background_manager::make());
|
||||
background_manager::make(),
|
||||
action_ctxt);
|
||||
// clang-format on
|
||||
}
|
||||
|
||||
@ -37,8 +38,9 @@ renderer::make_type renderer::make(const bar_settings& bar) {
|
||||
* Construct renderer instance
|
||||
*/
|
||||
renderer::renderer(connection& conn, signal_emitter& sig, const config& conf, const logger& logger,
|
||||
const bar_settings& bar, background_manager& background)
|
||||
: m_connection(conn)
|
||||
const bar_settings& bar, background_manager& background, tags::action_context& action_ctxt)
|
||||
: renderer_interface(action_ctxt)
|
||||
, m_connection(conn)
|
||||
, m_sig(sig)
|
||||
, m_conf(conf)
|
||||
, m_log(logger)
|
||||
@ -203,7 +205,6 @@ void renderer::begin(xcb_rectangle_t rect) {
|
||||
|
||||
// Reset state
|
||||
m_rect = rect;
|
||||
m_actions.clear();
|
||||
m_align = alignment::NONE;
|
||||
|
||||
// Clear canvas
|
||||
@ -250,8 +251,7 @@ void renderer::begin(xcb_rectangle_t rect) {
|
||||
void renderer::end() {
|
||||
m_log.trace_x("renderer: end");
|
||||
|
||||
for (auto& entry : m_actions) {
|
||||
auto& a = entry.second;
|
||||
for (auto& a : m_action_ctxt.get_blocks()) {
|
||||
a.start_x += block_x(a.align) + m_rect.x;
|
||||
a.end_x += block_x(a.align) + m_rect.x;
|
||||
}
|
||||
@ -700,43 +700,11 @@ void renderer::change_alignment(const tags::context& ctxt) {
|
||||
|
||||
void renderer::action_open(const tags::context&, mousebtn btn, tags::action_t id) {
|
||||
assert(btn != mousebtn::NONE);
|
||||
action_block block;
|
||||
block.align = m_align;
|
||||
block.button = btn;
|
||||
block.start_x = m_blocks.at(block.align).x;
|
||||
m_actions[id] = block;
|
||||
m_action_ctxt.set_start(id, m_blocks.at(m_align).x);
|
||||
}
|
||||
|
||||
void renderer::action_close(const tags::context&, tags::action_t id) {
|
||||
auto& block = m_actions[id];
|
||||
block.end_x = m_blocks.at(block.align).x;
|
||||
}
|
||||
|
||||
std::map<mousebtn, tags::action_t> renderer::get_actions(int x) {
|
||||
std::map<mousebtn, tags::action_t> buttons;
|
||||
|
||||
for (int i = static_cast<int>(mousebtn::NONE); i < static_cast<int>(mousebtn::BTN_COUNT); i++) {
|
||||
buttons[static_cast<mousebtn>(i)] = tags::NO_ACTION;
|
||||
}
|
||||
|
||||
for (auto&& entry : m_actions) {
|
||||
tags::action_t id;
|
||||
action_block action;
|
||||
std::tie(id, action) = entry;
|
||||
|
||||
mousebtn btn = action.button;
|
||||
|
||||
// Higher IDs are higher in the action stack.
|
||||
if (id > buttons[btn] && action.test(x)) {
|
||||
buttons[action.button] = id;
|
||||
}
|
||||
}
|
||||
|
||||
return buttons;
|
||||
}
|
||||
|
||||
tags::action_t renderer::get_action(mousebtn btn, int x) {
|
||||
return get_actions(x)[btn];
|
||||
m_action_ctxt.set_end(id, m_blocks.at(m_align).x);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -745,8 +713,7 @@ tags::action_t renderer::get_action(mousebtn btn, int x) {
|
||||
void renderer::highlight_clickable_areas() {
|
||||
#ifdef DEBUG_HINTS
|
||||
map<alignment, int> hint_num{};
|
||||
for (auto&& entry : m_actions) {
|
||||
auto&& action = entry.second;
|
||||
for (auto&& action : m_action_ctxt.get_blocks()) {
|
||||
int n = hint_num.find(action.align)->second++;
|
||||
double x = action.start_x;
|
||||
double y = m_rect.y;
|
||||
|
@ -137,6 +137,39 @@ namespace tags {
|
||||
return {NO_ACTION, mousebtn::NONE};
|
||||
}
|
||||
|
||||
void action_context::set_start(action_t id, double x) {
|
||||
m_action_blocks[id].start_x = x;
|
||||
}
|
||||
|
||||
void action_context::set_end(action_t id, double x) {
|
||||
m_action_blocks[id].end_x = x;
|
||||
}
|
||||
|
||||
std::map<mousebtn, tags::action_t> action_context::get_actions(int x) const {
|
||||
std::map<mousebtn, tags::action_t> buttons;
|
||||
|
||||
for (int i = static_cast<int>(mousebtn::NONE); i < static_cast<int>(mousebtn::BTN_COUNT); i++) {
|
||||
buttons[static_cast<mousebtn>(i)] = tags::NO_ACTION;
|
||||
}
|
||||
|
||||
for (action_t id = 0; (unsigned)id < m_action_blocks.size(); id++) {
|
||||
auto action = m_action_blocks[id];
|
||||
mousebtn btn = action.button;
|
||||
|
||||
// Higher IDs are higher in the action stack.
|
||||
if (id > buttons[btn] && action.test(x)) {
|
||||
buttons[action.button] = id;
|
||||
}
|
||||
}
|
||||
|
||||
return buttons;
|
||||
}
|
||||
|
||||
action_t action_context::has_action(mousebtn btn, int x) const {
|
||||
// TODO optimize
|
||||
return get_actions(x)[btn];
|
||||
}
|
||||
|
||||
string action_context::get_action(action_t id) const {
|
||||
assert(id >= 0 && (unsigned)id < num_actions());
|
||||
|
||||
@ -158,6 +191,10 @@ namespace tags {
|
||||
return m_action_blocks.size();
|
||||
}
|
||||
|
||||
std::vector<action_block>& action_context::get_blocks() {
|
||||
return m_action_blocks;
|
||||
}
|
||||
|
||||
} // namespace tags
|
||||
|
||||
POLYBAR_NS_END
|
||||
|
Loading…
Reference in New Issue
Block a user