|
|
@@ -10,37 +10,125 @@ namespace lumacs {
|
|
|
// Key Implementation
|
|
|
// ============================================================================
|
|
|
|
|
|
-Key::Key(const std::string& key_name) {
|
|
|
- *this = parse(key_name);
|
|
|
+namespace {
|
|
|
+ // Helper to convert string to BaseKey
|
|
|
+ BaseKey string_to_base_key(const std::string& s) {
|
|
|
+ if (s.length() == 1) {
|
|
|
+ char c = s[0];
|
|
|
+ if (c >= 'a' && c <= 'z') return static_cast<BaseKey>(static_cast<int>(BaseKey::A) + (c - 'a'));
|
|
|
+ if (c >= 'A' && c <= 'Z') return static_cast<BaseKey>(static_cast<int>(BaseKey::A) + (c - 'A'));
|
|
|
+ if (c >= '0' && c <= '9') return static_cast<BaseKey>(static_cast<int>(BaseKey::D0) + (c - '0'));
|
|
|
+ }
|
|
|
+ if (s == "Space") return BaseKey::Space;
|
|
|
+ if (s == "Return") return BaseKey::Return;
|
|
|
+ if (s == "Tab") return BaseKey::Tab;
|
|
|
+ if (s == "Escape") return BaseKey::Escape;
|
|
|
+ if (s == "Backspace") return BaseKey::Backspace;
|
|
|
+ if (s == "Delete") return BaseKey::Delete;
|
|
|
+ if (s == "ArrowUp") return BaseKey::ArrowUp;
|
|
|
+ if (s == "ArrowDown") return BaseKey::ArrowDown;
|
|
|
+ if (s == "ArrowLeft") return BaseKey::ArrowLeft;
|
|
|
+ if (s == "ArrowRight") return BaseKey::ArrowRight;
|
|
|
+ if (s == "Home") return BaseKey::Home;
|
|
|
+ if (s == "End") return BaseKey::End;
|
|
|
+ if (s == "PageUp") return BaseKey::PageUp;
|
|
|
+ if (s == "PageDown") return BaseKey::PageDown;
|
|
|
+ if (s == "Insert") return BaseKey::Insert;
|
|
|
+ if (s == ";") return BaseKey::Semicolon;
|
|
|
+ if (s == "=") return BaseKey::Equal;
|
|
|
+ if (s == ",") return BaseKey::Comma;
|
|
|
+ if (s == "-") return BaseKey::Minus;
|
|
|
+ if (s == ".") return BaseKey::Period;
|
|
|
+ if (s == "/") return BaseKey::Slash;
|
|
|
+ if (s == "`") return BaseKey::Backtick;
|
|
|
+ if (s == "[") return BaseKey::LeftBracket;
|
|
|
+ if (s == "\\") return BaseKey::Backslash;
|
|
|
+ if (s == "]") return BaseKey::RightBracket;
|
|
|
+ if (s == "'") return BaseKey::Quote;
|
|
|
+ // Add more keys as needed
|
|
|
+ return BaseKey::Unknown;
|
|
|
+ }
|
|
|
+
|
|
|
+ // Helper to convert BaseKey to string
|
|
|
+ std::string base_key_to_string(BaseKey bk) {
|
|
|
+ if (bk >= BaseKey::A && bk <= BaseKey::Z) return std::string(1, static_cast<char>(static_cast<int>(bk) - static_cast<int>(BaseKey::A) + 'a'));
|
|
|
+ if (bk >= BaseKey::D0 && bk <= BaseKey::D9) return std::string(1, static_cast<char>(static_cast<int>(bk) - static_cast<int>(BaseKey::D0) + '0'));
|
|
|
+
|
|
|
+ switch (bk) {
|
|
|
+ case BaseKey::Space: return "Space";
|
|
|
+ case BaseKey::Return: return "Return";
|
|
|
+ case BaseKey::Tab: return "Tab";
|
|
|
+ case BaseKey::Escape: return "Escape";
|
|
|
+ case BaseKey::Backspace: return "Backspace";
|
|
|
+ case BaseKey::Delete: return "Delete";
|
|
|
+ case BaseKey::ArrowUp: return "ArrowUp";
|
|
|
+ case BaseKey::ArrowDown: return "ArrowDown";
|
|
|
+ case BaseKey::ArrowLeft: return "ArrowLeft";
|
|
|
+ case BaseKey::ArrowRight: return "ArrowRight";
|
|
|
+ case BaseKey::Home: return "Home";
|
|
|
+ case BaseKey::End: return "End";
|
|
|
+ case BaseKey::PageUp: return "PageUp";
|
|
|
+ case BaseKey::PageDown: return "PageDown";
|
|
|
+ case BaseKey::Insert: return "Insert";
|
|
|
+ case BaseKey::F1: return "F1"; // Handle F keys properly
|
|
|
+ case BaseKey::F2: return "F2";
|
|
|
+ case BaseKey::F3: return "F3";
|
|
|
+ case BaseKey::F4: return "F4";
|
|
|
+ case BaseKey::F5: return "F5";
|
|
|
+ case BaseKey::F6: return "F6";
|
|
|
+ case BaseKey::F7: return "F7";
|
|
|
+ case BaseKey::F8: return "F8";
|
|
|
+ case BaseKey::F9: return "F9";
|
|
|
+ case BaseKey::F10: return "F10";
|
|
|
+ case BaseKey::F11: return "F11";
|
|
|
+ case BaseKey::F12: return "F12";
|
|
|
+ case BaseKey::Semicolon: return ";";
|
|
|
+ case BaseKey::Equal: return "=";
|
|
|
+ case BaseKey::Comma: return ",";
|
|
|
+ case BaseKey::Minus: return "-";
|
|
|
+ case BaseKey::Period: return ".";
|
|
|
+ case BaseKey::Slash: return "/";
|
|
|
+ case BaseKey::Backtick: return "`";
|
|
|
+ case BaseKey::LeftBracket: return "[";
|
|
|
+ case BaseKey::Backslash: return "\\";
|
|
|
+ case BaseKey::RightBracket: return "]";
|
|
|
+ case BaseKey::Quote: return "'";
|
|
|
+ default: return "Unknown";
|
|
|
+ }
|
|
|
+ }
|
|
|
+} // anonymous namespace
|
|
|
+
|
|
|
+
|
|
|
+Key::Key(const std::string& key_name_str) {
|
|
|
+ *this = parse(key_name_str);
|
|
|
}
|
|
|
|
|
|
Key Key::parse(const std::string& key_str) {
|
|
|
Key key;
|
|
|
-
|
|
|
- if (key_str.empty()) {
|
|
|
- return key;
|
|
|
- }
|
|
|
-
|
|
|
std::string remaining = key_str;
|
|
|
|
|
|
// Parse modifiers
|
|
|
while (true) {
|
|
|
if (remaining.length() >= 2 && remaining.substr(0, 2) == "C-") {
|
|
|
- key.ctrl = true;
|
|
|
+ key.modifiers = static_cast<Modifier>(static_cast<uint16_t>(key.modifiers) | static_cast<uint16_t>(Modifier::Control));
|
|
|
remaining = remaining.substr(2);
|
|
|
} else if (remaining.length() >= 2 && (remaining.substr(0, 2) == "M-" || remaining.substr(0, 2) == "A-")) {
|
|
|
- key.meta = true;
|
|
|
+ key.modifiers = static_cast<Modifier>(static_cast<uint16_t>(key.modifiers) | static_cast<uint16_t>(Modifier::Meta));
|
|
|
remaining = remaining.substr(2);
|
|
|
} else if (remaining.length() >= 2 && remaining.substr(0, 2) == "S-") {
|
|
|
- key.shift = true;
|
|
|
+ key.modifiers = static_cast<Modifier>(static_cast<uint16_t>(key.modifiers) | static_cast<uint16_t>(Modifier::Shift));
|
|
|
remaining = remaining.substr(2);
|
|
|
} else {
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- // The rest is the key name
|
|
|
- key.name = remaining;
|
|
|
+ key.base_key = string_to_base_key(remaining);
|
|
|
+
|
|
|
+ // If Shift is pressed and the base key is a letter, convert base_key to uppercase if necessary,
|
|
|
+ // but the BaseKey enum already handles 'a' through 'z' as lowercase by default for simplicity
|
|
|
+ // If the original input was 'S-a', string_to_base_key("a") gives BaseKey::A.
|
|
|
+ // So the explicit shift modifier should be enough.
|
|
|
|
|
|
return key;
|
|
|
}
|
|
|
@@ -48,27 +136,22 @@ Key Key::parse(const std::string& key_str) {
|
|
|
std::string Key::to_string() const {
|
|
|
std::string result;
|
|
|
|
|
|
- if (ctrl) result += "C-";
|
|
|
- if (meta) result += "M-";
|
|
|
- if (shift) result += "S-";
|
|
|
+ if (static_cast<uint16_t>(modifiers) & static_cast<uint16_t>(Modifier::Control)) result += "C-";
|
|
|
+ if (static_cast<uint16_t>(modifiers) & static_cast<uint16_t>(Modifier::Meta)) result += "M-";
|
|
|
+ if (static_cast<uint16_t>(modifiers) & static_cast<uint16_t>(Modifier::Shift)) result += "S-";
|
|
|
|
|
|
- result += name;
|
|
|
+ result += base_key_to_string(base_key);
|
|
|
|
|
|
return result;
|
|
|
}
|
|
|
|
|
|
bool Key::operator==(const Key& other) const {
|
|
|
- return name == other.name &&
|
|
|
- ctrl == other.ctrl &&
|
|
|
- meta == other.meta &&
|
|
|
- shift == other.shift;
|
|
|
+ return base_key == other.base_key && modifiers == other.modifiers;
|
|
|
}
|
|
|
|
|
|
bool Key::operator<(const Key& other) const {
|
|
|
- if (name != other.name) return name < other.name;
|
|
|
- if (ctrl != other.ctrl) return ctrl < other.ctrl;
|
|
|
- if (meta != other.meta) return meta < other.meta;
|
|
|
- return shift < other.shift;
|
|
|
+ if (base_key != other.base_key) return base_key < other.base_key;
|
|
|
+ return modifiers < other.modifiers;
|
|
|
}
|
|
|
|
|
|
// ============================================================================
|