2019-07-01 06:43:29 +08:00
|
|
|
#include <iostream>
|
2019-01-07 00:10:35 +08:00
|
|
|
#include "ftxui/component/event.hpp"
|
2019-06-23 23:47:33 +08:00
|
|
|
#include "ftxui/screen/string.hpp"
|
2018-10-19 04:58:38 +08:00
|
|
|
|
2019-01-12 22:00:08 +08:00
|
|
|
namespace ftxui {
|
2018-10-19 04:58:38 +08:00
|
|
|
|
2019-06-23 23:47:33 +08:00
|
|
|
// static
|
|
|
|
Event Event::Character(const std::string& input) {
|
|
|
|
Event event;
|
|
|
|
event.input_ = input;
|
|
|
|
event.is_character_ = true;
|
|
|
|
event.character_ = to_wstring(input)[0];
|
|
|
|
return event;
|
|
|
|
}
|
|
|
|
|
|
|
|
// static
|
|
|
|
Event Event::Character(char c) {
|
|
|
|
return Character(wchar_t(c));
|
|
|
|
}
|
|
|
|
|
|
|
|
// static
|
|
|
|
Event Event::Character(wchar_t c) {
|
|
|
|
Event event;
|
|
|
|
event.input_ = {(char)c};
|
|
|
|
event.is_character_ = true;
|
|
|
|
event.character_ = c;
|
|
|
|
return event;
|
|
|
|
}
|
|
|
|
|
|
|
|
// static
|
|
|
|
Event Event::Special(const std::string& input) {
|
|
|
|
Event event;
|
|
|
|
event.input_ = std::move(input);
|
|
|
|
return event;
|
|
|
|
}
|
|
|
|
|
|
|
|
Event ParseUTF8(std::function<char()>& getchar, std::string& input) {
|
|
|
|
if ((input[0] & 0b11000000) == 0b11000000)
|
|
|
|
input += getchar();
|
|
|
|
if ((input[0] & 0b11100000) == 0b11100000)
|
|
|
|
input += getchar();
|
|
|
|
if ((input[0] & 0b11110000) == 0b11110000)
|
|
|
|
input += getchar();
|
|
|
|
return Event::Character(input);
|
|
|
|
}
|
|
|
|
|
|
|
|
Event ParseCSI(std::function<char()> getchar, std::string& input) {
|
|
|
|
while (1) {
|
|
|
|
char c = getchar();
|
|
|
|
input += c;
|
|
|
|
|
2019-07-01 06:43:29 +08:00
|
|
|
if (c >= '0' && c<= '9')
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (c == ';')
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (c >= ' ' && c <= '~')
|
2019-06-23 23:47:33 +08:00
|
|
|
return Event::Special(input);
|
|
|
|
|
|
|
|
// Invalid ESC in CSI.
|
2020-02-12 04:44:55 +08:00
|
|
|
if (c == '\x1B')
|
2019-06-23 23:47:33 +08:00
|
|
|
return Event::Special(input);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Event ParseDCS(std::function<char()> getchar, std::string& input) {
|
|
|
|
// Parse until the string terminator ST.
|
|
|
|
while (1) {
|
|
|
|
input += getchar();
|
2020-02-12 04:44:55 +08:00
|
|
|
if (input.back() != '\x1B')
|
2019-06-23 23:47:33 +08:00
|
|
|
continue;
|
|
|
|
input += getchar();
|
|
|
|
if (input.back() != '\\')
|
|
|
|
continue;
|
|
|
|
return Event::Special(input);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Event ParseOSC(std::function<char()> getchar, std::string& input) {
|
|
|
|
// Parse until the string terminator ST.
|
|
|
|
while (1) {
|
|
|
|
input += getchar();
|
2020-02-12 04:44:55 +08:00
|
|
|
if (input.back() != '\x1B')
|
2019-06-23 23:47:33 +08:00
|
|
|
continue;
|
|
|
|
input += getchar();
|
|
|
|
if (input.back() != '\\')
|
|
|
|
continue;
|
|
|
|
return Event::Special(input);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Event ParseESC(std::function<char()> getchar, std::string& input) {
|
|
|
|
input += getchar();
|
|
|
|
switch (input.back()) {
|
2019-07-01 06:43:29 +08:00
|
|
|
case 'P': return ParseDCS(getchar, input);
|
|
|
|
case '[': return ParseCSI(getchar, input);
|
|
|
|
case ']': return ParseOSC(getchar, input);
|
2019-06-23 23:47:33 +08:00
|
|
|
default:
|
|
|
|
input += getchar();
|
|
|
|
return Event::Special(input);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// static
|
|
|
|
Event Event::GetEvent(std::function<char()> getchar) {
|
|
|
|
std::string input;
|
|
|
|
input += getchar();
|
|
|
|
|
2020-02-12 06:43:26 +08:00
|
|
|
unsigned char head = input[0];
|
|
|
|
switch (head) {
|
2019-06-23 23:47:33 +08:00
|
|
|
case 24: // CAN
|
|
|
|
case 26: // SUB
|
|
|
|
return Event(); // Ignored.
|
|
|
|
|
|
|
|
case 'P':
|
|
|
|
return ParseDCS(getchar, input);
|
|
|
|
|
2020-02-12 04:44:55 +08:00
|
|
|
case '\x1B':
|
2019-06-23 23:47:33 +08:00
|
|
|
return ParseESC(getchar, input);
|
|
|
|
}
|
|
|
|
|
2020-02-12 06:43:26 +08:00
|
|
|
if (head < 32) // C0
|
2019-06-23 23:47:33 +08:00
|
|
|
return Event::Special(input);
|
|
|
|
|
2020-02-12 06:43:26 +08:00
|
|
|
if (head == 127) // Delete
|
2019-07-03 05:09:20 +08:00
|
|
|
return Event::Special(input);
|
|
|
|
|
2019-06-23 23:47:33 +08:00
|
|
|
return ParseUTF8(getchar, input);
|
2018-10-19 04:58:38 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// --- Arrow ---
|
2020-02-12 04:44:55 +08:00
|
|
|
Event Event::ArrowLeft = Event::Special("\x1B[D");
|
|
|
|
Event Event::ArrowRight = Event::Special("\x1B[C");
|
|
|
|
Event Event::ArrowUp = Event::Special("\x1B[A");
|
|
|
|
Event Event::ArrowDown = Event::Special("\x1B[B");
|
2019-06-23 23:47:33 +08:00
|
|
|
Event Event::Backspace = Event::Special({127});
|
2020-02-12 04:44:55 +08:00
|
|
|
Event Event::Delete = Event::Special("\x1B[3~");
|
|
|
|
Event Event::Escape = Event::Special("\x1B");
|
2019-06-23 23:47:33 +08:00
|
|
|
Event Event::Return = Event::Special({10});
|
2019-11-02 02:52:41 +08:00
|
|
|
Event Event::Tab = Event::Special({9});
|
|
|
|
Event Event::TabReverse = Event::Special({27, 91, 90});
|
2020-02-12 04:44:55 +08:00
|
|
|
Event Event::F1 = Event::Special("\x1B[OP");
|
|
|
|
Event Event::F2 = Event::Special("\x1B[OQ");
|
|
|
|
Event Event::F3 = Event::Special("\x1B[OR");
|
|
|
|
Event Event::F4 = Event::Special("\x1B[OS");
|
|
|
|
Event Event::F5 = Event::Special("\x1B[15~");
|
|
|
|
Event Event::F6 = Event::Special("\x1B[17~");
|
|
|
|
Event Event::F7 = Event::Special("\x1B[18~");
|
|
|
|
Event Event::F8 = Event::Special("\x1B[19~");
|
|
|
|
Event Event::F9 = Event::Special("\x1B[20~");
|
|
|
|
Event Event::F10 = Event::Special("\x1B[21~");
|
|
|
|
Event Event::F11 = Event::Special("\x1B[21~"); // Doesn't exist
|
|
|
|
Event Event::F12 = Event::Special("\x1B[24~");
|
2019-06-23 23:47:33 +08:00
|
|
|
Event Event::Custom = Event::Special({0});
|
|
|
|
|
|
|
|
} // namespace ftxui
|