Move action_context into separate file
This commit is contained in:
parent
7a9f301830
commit
c4fbf0023e
@ -10,7 +10,7 @@
|
||||
#include "events/signal_fwd.hpp"
|
||||
#include "events/signal_receiver.hpp"
|
||||
#include "settings.hpp"
|
||||
#include "tags/context.hpp"
|
||||
#include "tags/action_context.hpp"
|
||||
#include "utils/math.hpp"
|
||||
#include "x11/types.hpp"
|
||||
#include "x11/window.hpp"
|
||||
|
@ -2,6 +2,7 @@
|
||||
#include <map>
|
||||
|
||||
#include "common.hpp"
|
||||
#include "tags/action_context.hpp"
|
||||
#include "tags/context.hpp"
|
||||
POLYBAR_NS
|
||||
|
||||
|
114
include/tags/action_context.hpp
Normal file
114
include/tags/action_context.hpp
Normal file
@ -0,0 +1,114 @@
|
||||
#pragma once
|
||||
|
||||
#include <map>
|
||||
|
||||
#include "common.hpp"
|
||||
#include "components/types.hpp"
|
||||
|
||||
POLYBAR_NS
|
||||
|
||||
namespace tags {
|
||||
/**
|
||||
* An identifier for an action block.
|
||||
*
|
||||
* A value of NO_ACTION denotes an undefined identifier and is guaranteed to
|
||||
* be smaller (<) than any valid identifier.
|
||||
*
|
||||
* If two action blocks overlap, the action with the higher identifier will
|
||||
* be above.
|
||||
*
|
||||
* Except for NO_ACTION, negative values are not allowed
|
||||
*/
|
||||
using action_t = int;
|
||||
|
||||
static constexpr action_t NO_ACTION = -1;
|
||||
|
||||
/**
|
||||
* Defines a clickable (or scrollable) action block.
|
||||
*
|
||||
* An action block is an area on the bar that executes some command when clicked.
|
||||
*/
|
||||
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;
|
||||
/**
|
||||
* Start position of the action block (inclusive), relative to the alignment.
|
||||
*/
|
||||
double start_x{0};
|
||||
|
||||
/**
|
||||
* End position of the action block (exclusive), relative to the alignment.
|
||||
*/
|
||||
double end_x{0};
|
||||
mousebtn button;
|
||||
alignment align;
|
||||
/**
|
||||
* Tracks whether this block is still open or whether it already has a
|
||||
* corresponding closing tag.
|
||||
*
|
||||
* After rendering, all action blocks should be closed.
|
||||
*/
|
||||
bool is_open;
|
||||
|
||||
unsigned int width() const {
|
||||
return static_cast<unsigned int>(end_x - start_x + 0.5);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests whether a given point is inside this block.
|
||||
*
|
||||
* This additionally needs the position of the start of the alignment
|
||||
* because the given point is relative to the bar window.
|
||||
*/
|
||||
bool test(double align_start, int point) const {
|
||||
return static_cast<int>(start_x + align_start) <= point && static_cast<int>(end_x + align_start) > point;
|
||||
}
|
||||
};
|
||||
|
||||
class action_context {
|
||||
public:
|
||||
void reset();
|
||||
|
||||
action_t action_open(mousebtn btn, const string&& cmd, alignment align, double x);
|
||||
std::pair<action_t, mousebtn> action_close(mousebtn btn, alignment align, double x);
|
||||
|
||||
void set_alignmnent_start(const alignment a, const 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;
|
||||
size_t num_unclosed() const;
|
||||
|
||||
const std::vector<action_block>& get_blocks() const;
|
||||
|
||||
protected:
|
||||
void set_start(action_t id, double x);
|
||||
void set_end(action_t id, double x);
|
||||
|
||||
/**
|
||||
* Stores all currently known action blocks.
|
||||
*
|
||||
* The action_t type is an index into this vector.
|
||||
*/
|
||||
std::vector<action_block> m_action_blocks;
|
||||
|
||||
/**
|
||||
* Stores the x-coordinate for the start of all the alignment blocks.
|
||||
*
|
||||
* This is needed because the action block coordinates are relative to the
|
||||
* alignment blocks and thus need the alignment block coordinates for
|
||||
* intersection tests.
|
||||
*/
|
||||
std::map<alignment, double> m_align_start{
|
||||
{alignment::NONE, 0}, {alignment::LEFT, 0}, {alignment::CENTER, 0}, {alignment::RIGHT, 0}};
|
||||
};
|
||||
|
||||
} // namespace tags
|
||||
|
||||
POLYBAR_NS_END
|
@ -1,7 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include <map>
|
||||
|
||||
#include "common.hpp"
|
||||
#include "components/types.hpp"
|
||||
#include "tags/types.hpp"
|
||||
@ -82,108 +80,6 @@ namespace tags {
|
||||
private:
|
||||
const bar_settings& m_settings;
|
||||
};
|
||||
|
||||
/**
|
||||
* An identifier for an action block.
|
||||
*
|
||||
* A value of NO_ACTION denotes an undefined identifier and is guaranteed to
|
||||
* be smaller (<) than any valid identifier.
|
||||
*
|
||||
* If two action blocks overlap, the action with the higher identifier will
|
||||
* be above.
|
||||
*
|
||||
* Except for NO_ACTION, negative values are not allowed
|
||||
*/
|
||||
using action_t = int;
|
||||
|
||||
static constexpr action_t NO_ACTION = -1;
|
||||
|
||||
/**
|
||||
* Defines a clickable (or scrollable) action block.
|
||||
*
|
||||
* An action block is an area on the bar that executes some command when clicked.
|
||||
*/
|
||||
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;
|
||||
/**
|
||||
* Start position of the action block (inclusive), relative to the alignment.
|
||||
*/
|
||||
double start_x{0};
|
||||
|
||||
/**
|
||||
* End position of the action block (exclusive), relative to the alignment.
|
||||
*/
|
||||
double end_x{0};
|
||||
mousebtn button;
|
||||
alignment align;
|
||||
/**
|
||||
* Tracks whether this block is still open or whether it already has a
|
||||
* corresponding closing tag.
|
||||
*
|
||||
* After rendering, all action blocks should be closed.
|
||||
*/
|
||||
bool is_open;
|
||||
|
||||
unsigned int width() const {
|
||||
return static_cast<unsigned int>(end_x - start_x + 0.5);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests whether a given point is inside this block.
|
||||
*
|
||||
* This additionally needs the position of the start of the alignment
|
||||
* because the given point is relative to the bar window.
|
||||
*/
|
||||
bool test(double align_start, int point) const {
|
||||
return static_cast<int>(start_x + align_start) <= point && static_cast<int>(end_x + align_start) > point;
|
||||
}
|
||||
};
|
||||
|
||||
class action_context {
|
||||
public:
|
||||
void reset();
|
||||
|
||||
action_t action_open(mousebtn btn, const string&& cmd, alignment align, double x);
|
||||
std::pair<action_t, mousebtn> action_close(mousebtn btn, alignment align, double x);
|
||||
|
||||
void set_alignmnent_start(const alignment a, const 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;
|
||||
size_t num_unclosed() const;
|
||||
|
||||
const std::vector<action_block>& get_blocks() const;
|
||||
|
||||
protected:
|
||||
void set_start(action_t id, double x);
|
||||
void set_end(action_t id, double x);
|
||||
|
||||
/**
|
||||
* Stores all currently known action blocks.
|
||||
*
|
||||
* The action_t type is an index into this vector.
|
||||
*/
|
||||
std::vector<action_block> m_action_blocks;
|
||||
|
||||
/**
|
||||
* Stores the x-coordinate for the start of all the alignment blocks.
|
||||
*
|
||||
* This is needed because the action block coordinates are relative to the
|
||||
* alignment blocks and thus need the alignment block coordinates for
|
||||
* intersection tests.
|
||||
*/
|
||||
std::map<alignment, double> m_align_start{
|
||||
{alignment::NONE, 0}, {alignment::LEFT, 0}, {alignment::CENTER, 0}, {alignment::RIGHT, 0}};
|
||||
};
|
||||
|
||||
} // namespace tags
|
||||
|
||||
POLYBAR_NS_END
|
||||
|
@ -96,6 +96,7 @@ if(BUILD_LIBPOLY)
|
||||
${src_dir}/modules/xwindow.cpp
|
||||
${src_dir}/modules/xworkspaces.cpp
|
||||
|
||||
${src_dir}/tags/action_context.cpp
|
||||
${src_dir}/tags/context.cpp
|
||||
${src_dir}/tags/dispatch.cpp
|
||||
${src_dir}/tags/parser.cpp
|
||||
|
110
src/tags/action_context.cpp
Normal file
110
src/tags/action_context.cpp
Normal file
@ -0,0 +1,110 @@
|
||||
#include "tags/action_context.hpp"
|
||||
|
||||
#include <cassert>
|
||||
|
||||
POLYBAR_NS
|
||||
|
||||
namespace tags {
|
||||
|
||||
void action_context::reset() {
|
||||
m_action_blocks.clear();
|
||||
}
|
||||
|
||||
action_t action_context::action_open(mousebtn btn, const string&& cmd, alignment align, double x) {
|
||||
action_t id = m_action_blocks.size();
|
||||
m_action_blocks.emplace_back(std::move(cmd), btn, align, true);
|
||||
set_start(id, x);
|
||||
return id;
|
||||
}
|
||||
|
||||
std::pair<action_t, mousebtn> action_context::action_close(mousebtn btn, alignment align, double x) {
|
||||
for (auto it = m_action_blocks.rbegin(); it != m_action_blocks.rend(); it++) {
|
||||
if (it->is_open && it->align == align && (btn == mousebtn::NONE || it->button == btn)) {
|
||||
it->is_open = false;
|
||||
|
||||
// Converts a reverse iterator into an index
|
||||
action_t id = std::distance(m_action_blocks.begin(), it.base()) - 1;
|
||||
set_end(id, x);
|
||||
return {id, it->button};
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
void action_context::set_alignmnent_start(const alignment a, const double x) {
|
||||
m_align_start[a] = 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(m_align_start.at(action.align), 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());
|
||||
|
||||
return m_action_blocks[id].cmd;
|
||||
}
|
||||
|
||||
bool action_context::has_double_click() const {
|
||||
for (auto&& a : m_action_blocks) {
|
||||
if (a.button == mousebtn::DOUBLE_LEFT || a.button == mousebtn::DOUBLE_MIDDLE ||
|
||||
a.button == mousebtn::DOUBLE_RIGHT) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t action_context::num_actions() const {
|
||||
return m_action_blocks.size();
|
||||
}
|
||||
|
||||
size_t action_context::num_unclosed() const {
|
||||
size_t num = 0;
|
||||
|
||||
for (const auto& a : m_action_blocks) {
|
||||
if (a.is_open) {
|
||||
num++;
|
||||
}
|
||||
}
|
||||
|
||||
return num;
|
||||
}
|
||||
|
||||
const std::vector<action_block>& action_context::get_blocks() const {
|
||||
return m_action_blocks;
|
||||
}
|
||||
} // namespace tags
|
||||
|
||||
POLYBAR_NS_END
|
@ -1,7 +1,5 @@
|
||||
#include "tags/context.hpp"
|
||||
|
||||
#include <cassert>
|
||||
|
||||
POLYBAR_NS
|
||||
|
||||
namespace tags {
|
||||
@ -113,107 +111,6 @@ namespace tags {
|
||||
alignment context::get_alignment() const {
|
||||
return m_align;
|
||||
}
|
||||
|
||||
void action_context::reset() {
|
||||
m_action_blocks.clear();
|
||||
}
|
||||
|
||||
action_t action_context::action_open(mousebtn btn, const string&& cmd, alignment align, double x) {
|
||||
action_t id = m_action_blocks.size();
|
||||
m_action_blocks.emplace_back(std::move(cmd), btn, align, true);
|
||||
set_start(id, x);
|
||||
return id;
|
||||
}
|
||||
|
||||
std::pair<action_t, mousebtn> action_context::action_close(mousebtn btn, alignment align, double x) {
|
||||
for (auto it = m_action_blocks.rbegin(); it != m_action_blocks.rend(); it++) {
|
||||
if (it->is_open && it->align == align && (btn == mousebtn::NONE || it->button == btn)) {
|
||||
it->is_open = false;
|
||||
|
||||
// Converts a reverse iterator into an index
|
||||
action_t id = std::distance(m_action_blocks.begin(), it.base()) - 1;
|
||||
set_end(id, x);
|
||||
return {id, it->button};
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
void action_context::set_alignmnent_start(const alignment a, const double x) {
|
||||
m_align_start[a] = 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(m_align_start.at(action.align), 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());
|
||||
|
||||
return m_action_blocks[id].cmd;
|
||||
}
|
||||
|
||||
bool action_context::has_double_click() const {
|
||||
for (auto&& a : m_action_blocks) {
|
||||
if (a.button == mousebtn::DOUBLE_LEFT || a.button == mousebtn::DOUBLE_MIDDLE ||
|
||||
a.button == mousebtn::DOUBLE_RIGHT) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t action_context::num_actions() const {
|
||||
return m_action_blocks.size();
|
||||
}
|
||||
|
||||
size_t action_context::num_unclosed() const {
|
||||
size_t num = 0;
|
||||
|
||||
for (const auto& a : m_action_blocks) {
|
||||
if (a.is_open) {
|
||||
num++;
|
||||
}
|
||||
}
|
||||
|
||||
return num;
|
||||
}
|
||||
|
||||
const std::vector<action_block>& action_context::get_blocks() const {
|
||||
return m_action_blocks;
|
||||
}
|
||||
|
||||
} // namespace tags
|
||||
|
||||
POLYBAR_NS_END
|
||||
|
@ -1,6 +1,7 @@
|
||||
#include "tags/action_context.hpp"
|
||||
|
||||
#include "common/test.hpp"
|
||||
#include "components/logger.hpp"
|
||||
#include "tags/context.hpp"
|
||||
|
||||
using namespace polybar;
|
||||
using namespace std;
|
||||
|
Loading…
Reference in New Issue
Block a user