mirror of
https://github.com/ArthurSonzogni/FTXUI.git
synced 2024-11-29 14:45:53 +08:00
Parse mouse events.
This commit is contained in:
parent
476b9deaf8
commit
cbd13499ae
@ -23,10 +23,35 @@ class DrawKey : public Component {
|
|||||||
code += L" " + std::to_wstring((unsigned int)it);
|
code += L" " + std::to_wstring((unsigned int)it);
|
||||||
|
|
||||||
code = L"(" + code + L" ) -> ";
|
code = L"(" + code + L" ) -> ";
|
||||||
if (keys[i].is_character())
|
if (keys[i].is_character()) {
|
||||||
code += keys[i].character();
|
code += std::wstring(L"character(") + keys[i].character() + L")";
|
||||||
else
|
} else if (keys[i].is_mouse_move()) {
|
||||||
|
code += L"mouse_move(" + //
|
||||||
|
std::to_wstring(keys[i].mouse_x()) + L"," +
|
||||||
|
std::to_wstring(keys[i].mouse_y()) + L")";
|
||||||
|
} else if (keys[i].is_mouse_up()) {
|
||||||
|
code += L"mouse_up(" + //
|
||||||
|
std::to_wstring(keys[i].mouse_x()) + L"," +
|
||||||
|
std::to_wstring(keys[i].mouse_y()) + L")";
|
||||||
|
} else if (keys[i].is_mouse_left_down()) {
|
||||||
|
code += L"mouse_left_down(" + //
|
||||||
|
std::to_wstring(keys[i].mouse_x()) + L"," +
|
||||||
|
std::to_wstring(keys[i].mouse_y()) + L")";
|
||||||
|
} else if (keys[i].is_mouse_left_move()) {
|
||||||
|
code += L"mouse_left_move(" + //
|
||||||
|
std::to_wstring(keys[i].mouse_x()) + L"," +
|
||||||
|
std::to_wstring(keys[i].mouse_y()) + L")";
|
||||||
|
} else if (keys[i].is_mouse_right_down()) {
|
||||||
|
code += L"mouse_right_down(" + //
|
||||||
|
std::to_wstring(keys[i].mouse_x()) + L"," +
|
||||||
|
std::to_wstring(keys[i].mouse_y()) + L")";
|
||||||
|
} else if (keys[i].is_mouse_right_move()) {
|
||||||
|
code += L"mouse_right_move(" + //
|
||||||
|
std::to_wstring(keys[i].mouse_x()) + L"," +
|
||||||
|
std::to_wstring(keys[i].mouse_y()) + L")";
|
||||||
|
} else {
|
||||||
code += L"(special)";
|
code += L"(special)";
|
||||||
|
}
|
||||||
children.push_back(text(code));
|
children.push_back(text(code));
|
||||||
}
|
}
|
||||||
return window(text(L"keys"), vbox(std::move(children)));
|
return window(text(L"keys"), vbox(std::move(children)));
|
||||||
|
@ -26,8 +26,14 @@ struct Event {
|
|||||||
static Event Character(char);
|
static Event Character(char);
|
||||||
static Event Character(wchar_t);
|
static Event Character(wchar_t);
|
||||||
|
|
||||||
static Event Character(const std::string&);
|
static Event Character(std::string);
|
||||||
static Event Special(const std::string&);
|
static Event Special(std::string);
|
||||||
|
static Event MouseMove(std::string, int x, int y);
|
||||||
|
static Event MouseUp(std::string, int x, int y);
|
||||||
|
static Event MouseLeftMove(std::string, int x, int y);
|
||||||
|
static Event MouseLeftDown(std::string, int x, int y);
|
||||||
|
static Event MouseRightMove(std::string, int x, int y);
|
||||||
|
static Event MouseRightDown(std::string, int x, int y);
|
||||||
|
|
||||||
// --- Arrow ---
|
// --- Arrow ---
|
||||||
static const Event ArrowLeft;
|
static const Event ArrowLeft;
|
||||||
@ -48,17 +54,47 @@ struct Event {
|
|||||||
static Event Custom;
|
static Event Custom;
|
||||||
|
|
||||||
//--- Method section ---------------------------------------------------------
|
//--- Method section ---------------------------------------------------------
|
||||||
bool is_character() const { return is_character_; }
|
bool is_character() const { return type_ == Type::Character;}
|
||||||
wchar_t character() const { return character_; }
|
wchar_t character() const { return character_; }
|
||||||
|
|
||||||
|
bool is_mouse_left_down() const { return type_ == Type::MouseLeftDown; }
|
||||||
|
bool is_mouse_left_move() const { return type_ == Type::MouseLeftMove; }
|
||||||
|
bool is_mouse_right_down() const { return type_ == Type::MouseRightDown; }
|
||||||
|
bool is_mouse_right_move() const { return type_ == Type::MouseRightMove; }
|
||||||
|
bool is_mouse_up() const { return type_ == Type::MouseUp; }
|
||||||
|
bool is_mouse_move() const { return type_ == Type::MouseMove; }
|
||||||
|
int mouse_x() const { return mouse_.x; }
|
||||||
|
int mouse_y() const { return mouse_.y; }
|
||||||
|
|
||||||
const std::string& input() const { return input_; }
|
const std::string& input() const { return input_; }
|
||||||
|
|
||||||
bool operator==(const Event& other) const { return input_ == other.input_; }
|
bool operator==(const Event& other) const { return input_ == other.input_; }
|
||||||
|
|
||||||
//--- State section ----------------------------------------------------------
|
//--- State section ----------------------------------------------------------
|
||||||
private:
|
private:
|
||||||
std::string input_;
|
enum class Type {
|
||||||
bool is_character_ = false;
|
Unknown,
|
||||||
|
Character,
|
||||||
|
MouseMove,
|
||||||
|
MouseUp,
|
||||||
|
MouseLeftDown,
|
||||||
|
MouseLeftMove,
|
||||||
|
MouseRightDown,
|
||||||
|
MouseRightMove,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Mouse {
|
||||||
|
int x;
|
||||||
|
int y;
|
||||||
|
};
|
||||||
|
|
||||||
|
Type type_ = Type::Unknown;
|
||||||
|
|
||||||
|
union {
|
||||||
wchar_t character_ = U'?';
|
wchar_t character_ = U'?';
|
||||||
|
Mouse mouse_;
|
||||||
|
};
|
||||||
|
std::string input_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -6,11 +6,11 @@
|
|||||||
namespace ftxui {
|
namespace ftxui {
|
||||||
|
|
||||||
// static
|
// static
|
||||||
Event Event::Character(const std::string& input) {
|
Event Event::Character(std::string input) {
|
||||||
Event event;
|
Event event;
|
||||||
event.input_ = input;
|
|
||||||
event.is_character_ = true;
|
|
||||||
event.character_ = to_wstring(input)[0];
|
event.character_ = to_wstring(input)[0];
|
||||||
|
event.input_ = std::move(input);
|
||||||
|
event.type_ = Type::Character;
|
||||||
return event;
|
return event;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -23,13 +23,67 @@ Event Event::Character(char c) {
|
|||||||
Event Event::Character(wchar_t c) {
|
Event Event::Character(wchar_t c) {
|
||||||
Event event;
|
Event event;
|
||||||
event.input_ = {(char)c};
|
event.input_ = {(char)c};
|
||||||
event.is_character_ = true;
|
event.type_ = Type::Character;
|
||||||
event.character_ = c;
|
event.character_ = c;
|
||||||
return event;
|
return event;
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
Event Event::Special(const std::string& input) {
|
Event Event::MouseMove(std::string input, int x, int y) {
|
||||||
|
Event event;
|
||||||
|
event.input_ = std::move(input);
|
||||||
|
event.type_ = Type::MouseMove;
|
||||||
|
event.mouse_ = {x, y};
|
||||||
|
return event;
|
||||||
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
Event Event::MouseUp(std::string input, int x, int y) {
|
||||||
|
Event event;
|
||||||
|
event.input_ = std::move(input);
|
||||||
|
event.type_ = Type::MouseUp;
|
||||||
|
event.mouse_ = {x, y};
|
||||||
|
return event;
|
||||||
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
Event Event::MouseLeftDown(std::string input, int x, int y) {
|
||||||
|
Event event;
|
||||||
|
event.input_ = std::move(input);
|
||||||
|
event.type_ = Type::MouseLeftDown;
|
||||||
|
event.mouse_ = {x, y};
|
||||||
|
return event;
|
||||||
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
Event Event::MouseLeftMove(std::string input, int x, int y) {
|
||||||
|
Event event;
|
||||||
|
event.input_ = std::move(input);
|
||||||
|
event.type_ = Type::MouseLeftMove;
|
||||||
|
event.mouse_ = {x, y};
|
||||||
|
return event;
|
||||||
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
Event Event::MouseRightDown(std::string input, int x, int y) {
|
||||||
|
Event event;
|
||||||
|
event.input_ = std::move(input);
|
||||||
|
event.type_ = Type::MouseRightDown;
|
||||||
|
event.mouse_ = {x, y};
|
||||||
|
return event;
|
||||||
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
Event Event::MouseRightMove(std::string input, int x, int y) {
|
||||||
|
Event event;
|
||||||
|
event.input_ = std::move(input);
|
||||||
|
event.type_ = Type::MouseRightMove;
|
||||||
|
event.mouse_ = {x, y};
|
||||||
|
return event;
|
||||||
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
Event Event::Special(std::string input) {
|
||||||
Event event;
|
Event event;
|
||||||
event.input_ = std::move(input);
|
event.input_ = std::move(input);
|
||||||
return event;
|
return event;
|
||||||
|
@ -155,8 +155,8 @@ static const char DISABLE_LINE_WRAP[] = "\x1B[7l";
|
|||||||
static const char USE_ALTERNATIVE_SCREEN[] = "\x1B[?1049h";
|
static const char USE_ALTERNATIVE_SCREEN[] = "\x1B[?1049h";
|
||||||
static const char USE_NORMAL_SCREEN[] = "\x1B[?1049l";
|
static const char USE_NORMAL_SCREEN[] = "\x1B[?1049l";
|
||||||
|
|
||||||
static const char ENABLE_MOUSE[] = "\x1B[?1000;1006;1015h";
|
static const char ENABLE_MOUSE[] = "\x1B[?1000;1003;1006;1015h";
|
||||||
static const char DISABLE_MOUSE[] = "\x1B[?1000;10006;1015l";
|
static const char DISABLE_MOUSE[] = "\x1B[?1000;1003;10006;1015l";
|
||||||
|
|
||||||
using SignalHandler = void(int);
|
using SignalHandler = void(int);
|
||||||
std::stack<std::function<void()>> on_exit_functions;
|
std::stack<std::function<void()>> on_exit_functions;
|
||||||
|
@ -30,28 +30,56 @@ bool TerminalInputParser::Eat() {
|
|||||||
return position_ < (int)pending_.size();
|
return position_ < (int)pending_.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TerminalInputParser::Send(TerminalInputParser::Type type) {
|
void TerminalInputParser::Send(TerminalInputParser::Output output) {
|
||||||
switch (type) {
|
switch (output.type) {
|
||||||
case UNCOMPLETED:
|
case UNCOMPLETED:
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case DROP:
|
case DROP:
|
||||||
pending_.clear();
|
break;
|
||||||
return;
|
|
||||||
|
|
||||||
case CHARACTER:
|
case CHARACTER:
|
||||||
out_->Send(Event::Character(std::move(pending_)));
|
out_->Send(Event::Character(std::move(pending_)));
|
||||||
pending_.clear();
|
break;
|
||||||
return;
|
|
||||||
|
|
||||||
case SPECIAL:
|
case SPECIAL:
|
||||||
out_->Send(Event::Special(std::move(pending_)));
|
out_->Send(Event::Special(std::move(pending_)));
|
||||||
pending_.clear();
|
break;
|
||||||
return;
|
|
||||||
|
case MOUSE_MOVE:
|
||||||
|
out_->Send(
|
||||||
|
Event::MouseMove(std::move(pending_), output.mouse.x, output.mouse.y));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MOUSE_UP:
|
||||||
|
out_->Send(
|
||||||
|
Event::MouseUp(std::move(pending_), output.mouse.x, output.mouse.y));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MOUSE_LEFT_DOWN:
|
||||||
|
out_->Send(Event::MouseLeftDown(std::move(pending_), output.mouse.x,
|
||||||
|
output.mouse.y));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MOUSE_LEFT_MOVE:
|
||||||
|
out_->Send(Event::MouseLeftMove(std::move(pending_), output.mouse.x,
|
||||||
|
output.mouse.y));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MOUSE_RIGHT_DOWN:
|
||||||
|
out_->Send(Event::MouseRightDown(std::move(pending_), output.mouse.x,
|
||||||
|
output.mouse.y));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MOUSE_RIGHT_MOVE:
|
||||||
|
out_->Send(Event::MouseRightMove(std::move(pending_), output.mouse.x,
|
||||||
|
output.mouse.y));
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
pending_.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
TerminalInputParser::Type TerminalInputParser::Parse() {
|
TerminalInputParser::Output TerminalInputParser::Parse() {
|
||||||
if (!Eat())
|
if (!Eat())
|
||||||
return UNCOMPLETED;
|
return UNCOMPLETED;
|
||||||
|
|
||||||
@ -75,7 +103,7 @@ TerminalInputParser::Type TerminalInputParser::Parse() {
|
|||||||
return ParseUTF8();
|
return ParseUTF8();
|
||||||
}
|
}
|
||||||
|
|
||||||
TerminalInputParser::Type TerminalInputParser::ParseUTF8() {
|
TerminalInputParser::Output TerminalInputParser::ParseUTF8() {
|
||||||
unsigned char head = static_cast<unsigned char>(Current());
|
unsigned char head = static_cast<unsigned char>(Current());
|
||||||
for (int i = 0; i < 3; ++i, head <<= 1) {
|
for (int i = 0; i < 3; ++i, head <<= 1) {
|
||||||
if ((head & 0b11000000) != 0b11000000)
|
if ((head & 0b11000000) != 0b11000000)
|
||||||
@ -86,7 +114,7 @@ TerminalInputParser::Type TerminalInputParser::ParseUTF8() {
|
|||||||
return CHARACTER;
|
return CHARACTER;
|
||||||
}
|
}
|
||||||
|
|
||||||
TerminalInputParser::Type TerminalInputParser::ParseESC() {
|
TerminalInputParser::Output TerminalInputParser::ParseESC() {
|
||||||
if (!Eat())
|
if (!Eat())
|
||||||
return UNCOMPLETED;
|
return UNCOMPLETED;
|
||||||
switch (Current()) {
|
switch (Current()) {
|
||||||
@ -103,7 +131,7 @@ TerminalInputParser::Type TerminalInputParser::ParseESC() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TerminalInputParser::Type TerminalInputParser::ParseDCS() {
|
TerminalInputParser::Output TerminalInputParser::ParseDCS() {
|
||||||
// Parse until the string terminator ST.
|
// Parse until the string terminator ST.
|
||||||
while (1) {
|
while (1) {
|
||||||
if (!Eat())
|
if (!Eat())
|
||||||
@ -122,19 +150,35 @@ TerminalInputParser::Type TerminalInputParser::ParseDCS() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TerminalInputParser::Type TerminalInputParser::ParseCSI() {
|
TerminalInputParser::Output TerminalInputParser::ParseCSI() {
|
||||||
|
int argument;
|
||||||
|
std::vector<int> arguments;
|
||||||
while (true) {
|
while (true) {
|
||||||
if (!Eat())
|
if (!Eat())
|
||||||
return UNCOMPLETED;
|
return UNCOMPLETED;
|
||||||
|
|
||||||
if (Current() >= '0' && Current() <= '9')
|
if (Current() >= '0' && Current() <= '9') {
|
||||||
|
argument *= 10;
|
||||||
|
argument += int(Current() - '0');
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (Current() == ';')
|
if (Current() == ';') {
|
||||||
|
arguments.push_back(argument);
|
||||||
|
argument = 0;
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (Current() >= ' ' && Current() <= '~')
|
if (Current() >= ' ' && Current() <= '~') {
|
||||||
|
arguments.push_back(argument);
|
||||||
|
argument = 0;
|
||||||
|
switch (Current()) {
|
||||||
|
case 'M':
|
||||||
|
return ParseMouse(std::move(arguments));
|
||||||
|
default:
|
||||||
return SPECIAL;
|
return SPECIAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Invalid ESC in CSI.
|
// Invalid ESC in CSI.
|
||||||
if (Current() == '\x1B')
|
if (Current() == '\x1B')
|
||||||
@ -142,7 +186,7 @@ TerminalInputParser::Type TerminalInputParser::ParseCSI() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TerminalInputParser::Type TerminalInputParser::ParseOSC() {
|
TerminalInputParser::Output TerminalInputParser::ParseOSC() {
|
||||||
// Parse until the string terminator ST.
|
// Parse until the string terminator ST.
|
||||||
while (true) {
|
while (true) {
|
||||||
if (!Eat())
|
if (!Eat())
|
||||||
@ -156,4 +200,28 @@ TerminalInputParser::Type TerminalInputParser::ParseOSC() {
|
|||||||
return SPECIAL;
|
return SPECIAL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TerminalInputParser::Output TerminalInputParser::ParseMouse(
|
||||||
|
std::vector<int> arguments) {
|
||||||
|
if (arguments.size() != 3)
|
||||||
|
return SPECIAL;
|
||||||
|
switch(arguments[0]) {
|
||||||
|
case 32:
|
||||||
|
return Output(MOUSE_LEFT_DOWN, arguments[1], arguments[2]);
|
||||||
|
case 64:
|
||||||
|
return Output(MOUSE_LEFT_MOVE, arguments[1], arguments[2]);
|
||||||
|
|
||||||
|
case 34:
|
||||||
|
return Output(MOUSE_RIGHT_DOWN, arguments[1], arguments[2]);
|
||||||
|
case 66:
|
||||||
|
return Output(MOUSE_RIGHT_MOVE, arguments[1], arguments[2]);
|
||||||
|
|
||||||
|
case 35:
|
||||||
|
return Output(MOUSE_UP, arguments[1], arguments[2]);
|
||||||
|
case 67:
|
||||||
|
return Output(MOUSE_MOVE, arguments[1], arguments[2]);
|
||||||
|
}
|
||||||
|
return SPECIAL;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace ftxui
|
} // namespace ftxui
|
||||||
|
@ -20,18 +20,42 @@ class TerminalInputParser {
|
|||||||
bool Eat();
|
bool Eat();
|
||||||
|
|
||||||
enum Type {
|
enum Type {
|
||||||
UNCOMPLETED = 0,
|
UNCOMPLETED,
|
||||||
DROP = 1,
|
DROP,
|
||||||
CHARACTER = 2,
|
CHARACTER,
|
||||||
SPECIAL = 3,
|
SPECIAL,
|
||||||
|
MOUSE_UP,
|
||||||
|
MOUSE_MOVE,
|
||||||
|
MOUSE_LEFT_DOWN,
|
||||||
|
MOUSE_LEFT_MOVE,
|
||||||
|
MOUSE_RIGHT_DOWN,
|
||||||
|
MOUSE_RIGHT_MOVE,
|
||||||
};
|
};
|
||||||
void Send(Type type);
|
|
||||||
Type Parse();
|
struct Mouse {
|
||||||
Type ParseUTF8();
|
int x;
|
||||||
Type ParseESC();
|
int y;
|
||||||
Type ParseDCS();
|
Mouse(int x, int y) : x(x), y(y) {}
|
||||||
Type ParseCSI();
|
};
|
||||||
Type ParseOSC();
|
|
||||||
|
struct Output {
|
||||||
|
Type type;
|
||||||
|
union {
|
||||||
|
Mouse mouse;
|
||||||
|
};
|
||||||
|
|
||||||
|
Output(Type type) : type(type) {}
|
||||||
|
Output(Type type, int x, int y) : type(type), mouse(x, y) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
void Send(Output type);
|
||||||
|
Output Parse();
|
||||||
|
Output ParseUTF8();
|
||||||
|
Output ParseESC();
|
||||||
|
Output ParseDCS();
|
||||||
|
Output ParseCSI();
|
||||||
|
Output ParseOSC();
|
||||||
|
Output ParseMouse(std::vector<int> arguments);
|
||||||
|
|
||||||
Sender<Event> out_;
|
Sender<Event> out_;
|
||||||
int position_ = -1;
|
int position_ = -1;
|
||||||
|
Loading…
Reference in New Issue
Block a user