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_fwd.hpp"
|
||||||
#include "events/signal_receiver.hpp"
|
#include "events/signal_receiver.hpp"
|
||||||
#include "settings.hpp"
|
#include "settings.hpp"
|
||||||
#include "tags/context.hpp"
|
#include "tags/action_context.hpp"
|
||||||
#include "utils/math.hpp"
|
#include "utils/math.hpp"
|
||||||
#include "x11/types.hpp"
|
#include "x11/types.hpp"
|
||||||
#include "x11/window.hpp"
|
#include "x11/window.hpp"
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
#include "common.hpp"
|
#include "common.hpp"
|
||||||
|
#include "tags/action_context.hpp"
|
||||||
#include "tags/context.hpp"
|
#include "tags/context.hpp"
|
||||||
POLYBAR_NS
|
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
|
#pragma once
|
||||||
|
|
||||||
#include <map>
|
|
||||||
|
|
||||||
#include "common.hpp"
|
#include "common.hpp"
|
||||||
#include "components/types.hpp"
|
#include "components/types.hpp"
|
||||||
#include "tags/types.hpp"
|
#include "tags/types.hpp"
|
||||||
@ -82,108 +80,6 @@ namespace tags {
|
|||||||
private:
|
private:
|
||||||
const bar_settings& m_settings;
|
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
|
} // namespace tags
|
||||||
|
|
||||||
POLYBAR_NS_END
|
POLYBAR_NS_END
|
||||||
|
@ -96,6 +96,7 @@ if(BUILD_LIBPOLY)
|
|||||||
${src_dir}/modules/xwindow.cpp
|
${src_dir}/modules/xwindow.cpp
|
||||||
${src_dir}/modules/xworkspaces.cpp
|
${src_dir}/modules/xworkspaces.cpp
|
||||||
|
|
||||||
|
${src_dir}/tags/action_context.cpp
|
||||||
${src_dir}/tags/context.cpp
|
${src_dir}/tags/context.cpp
|
||||||
${src_dir}/tags/dispatch.cpp
|
${src_dir}/tags/dispatch.cpp
|
||||||
${src_dir}/tags/parser.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 "tags/context.hpp"
|
||||||
|
|
||||||
#include <cassert>
|
|
||||||
|
|
||||||
POLYBAR_NS
|
POLYBAR_NS
|
||||||
|
|
||||||
namespace tags {
|
namespace tags {
|
||||||
@ -113,107 +111,6 @@ namespace tags {
|
|||||||
alignment context::get_alignment() const {
|
alignment context::get_alignment() const {
|
||||||
return m_align;
|
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
|
} // namespace tags
|
||||||
|
|
||||||
POLYBAR_NS_END
|
POLYBAR_NS_END
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
|
#include "tags/action_context.hpp"
|
||||||
|
|
||||||
#include "common/test.hpp"
|
#include "common/test.hpp"
|
||||||
#include "components/logger.hpp"
|
#include "components/logger.hpp"
|
||||||
#include "tags/context.hpp"
|
|
||||||
|
|
||||||
using namespace polybar;
|
using namespace polybar;
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
Loading…
Reference in New Issue
Block a user