aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/cru/platform/native/Keyboard.hpp5
-rw-r--r--include/cru/ui/ShortcutHub.hpp12
-rw-r--r--src/platform/native/CMakeLists.txt1
-rw-r--r--src/platform/native/Keyboard.cpp142
-rw-r--r--src/ui/ShortcutHub.cpp62
5 files changed, 222 insertions, 0 deletions
diff --git a/include/cru/platform/native/Keyboard.hpp b/include/cru/platform/native/Keyboard.hpp
index 83c61bcc..8f53c5d6 100644
--- a/include/cru/platform/native/Keyboard.hpp
+++ b/include/cru/platform/native/Keyboard.hpp
@@ -1,4 +1,5 @@
#pragma once
+#include <string_view>
#include "cru/common/Bitmask.hpp"
namespace cru::platform::native {
@@ -117,4 +118,8 @@ struct KeyModifiers {
static constexpr KeyModifier ctrl{0b10};
static constexpr KeyModifier alt{0b100};
};
+
+std::u16string_view ToString(KeyCode key_code);
+std::u16string ToString(KeyModifier key_modifier,
+ std::u16string_view separator = u"+");
} // namespace cru::platform::native
diff --git a/include/cru/ui/ShortcutHub.hpp b/include/cru/ui/ShortcutHub.hpp
index 7557b758..a1dfcb7d 100644
--- a/include/cru/ui/ShortcutHub.hpp
+++ b/include/cru/ui/ShortcutHub.hpp
@@ -4,6 +4,7 @@
#include "cru/common/Base.hpp"
#include "cru/common/Event.hpp"
#include "cru/platform/native/Keyboard.hpp"
+#include "cru/ui/UiEvent.hpp"
#include <cstddef>
#include <functional>
@@ -43,6 +44,14 @@ class ShortcutKeyBind {
return !this->operator==(other);
}
+ std::u16string ToString() {
+ std::u16string result = u"(";
+ result += platform::native::ToString(modifier_);
+ result += u")";
+ result += platform::native::ToString(key_);
+ return result;
+ }
+
private:
platform::native::KeyCode key_;
platform::native::KeyModifier modifier_;
@@ -95,6 +104,9 @@ class ShortcutHub : public Object {
void Uninstall();
private:
+ void OnKeyDown(event::KeyEventArgs& event);
+
+ private:
std::unordered_map<ShortcutKeyBind, std::vector<ShortcutInfo>> map_;
const std::vector<ShortcutInfo> empty_list_;
diff --git a/src/platform/native/CMakeLists.txt b/src/platform/native/CMakeLists.txt
index c68a0958..3fe4370a 100644
--- a/src/platform/native/CMakeLists.txt
+++ b/src/platform/native/CMakeLists.txt
@@ -1,5 +1,6 @@
set(CRU_PLATFORM_NATIVE_INCLUDE_DIR ${CRU_INCLUDE_DIR}/cru/platform/native)
add_library(cru_platform_native STATIC
+ Keyboard.cpp
UiApplication.cpp
)
target_sources(cru_platform_native PUBLIC
diff --git a/src/platform/native/Keyboard.cpp b/src/platform/native/Keyboard.cpp
new file mode 100644
index 00000000..dd0e8f23
--- /dev/null
+++ b/src/platform/native/Keyboard.cpp
@@ -0,0 +1,142 @@
+#include "cru/platform/native/Keyboard.hpp"
+
+#include <array>
+#include <string>
+#include <string_view>
+
+namespace cru::platform::native {
+constexpr std::array<std::u16string_view,
+ static_cast<int>(KeyCode::NumPad9) + 1>
+ key_code_string_list{u"Unknown",
+ u"LeftButton",
+ u"MiddleButton",
+ u"RightButton",
+ u"Escape",
+ u"F1",
+ u"F2",
+ u"F3",
+ u"F4",
+ u"F5",
+ u"F6",
+ u"F7",
+ u"F8",
+ u"F9",
+ u"F10",
+ u"F11",
+ u"F12",
+ u"N0",
+ u"N1",
+ u"N2",
+ u"N3",
+ u"N4",
+ u"N5",
+ u"N6",
+ u"N7",
+ u"N8",
+ u"N9",
+ u"A",
+ u"B",
+ u"C",
+ u"D",
+ u"E",
+ u"F",
+ u"G",
+ u"H",
+ u"I",
+ u"J",
+ u"K",
+ u"L",
+ u"M",
+ u"N",
+ u"O",
+ u"P",
+ u"Q",
+ u"R",
+ u"S",
+ u"T",
+ u"U",
+ u"V",
+ u"W",
+ u"X",
+ u"Y",
+ u"Z",
+ u"GraveAccent",
+ u"Tab",
+ u"CapsLock",
+ u"LeftShift",
+ u"LeftCtrl",
+ u"LeftSuper",
+ u"LeftAlt",
+ u"Minus",
+ u"Equal",
+ u"Backspace",
+ u"LeftSquareBracket",
+ u"RightSquareBracket",
+ u"BackSlash",
+ u"Semicolon",
+ u"Quote",
+ u"Comma",
+ u"Period",
+ u"Slash",
+ u"RightShift",
+ u"RightCtrl",
+ u"RightSuper",
+ u"RightAlt",
+ u"Insert",
+ u"Delete",
+ u"Home",
+ u"End",
+ u"PageUp",
+ u"PageDown",
+ u"Up",
+ u"Left",
+ u"Down",
+ u"Right",
+ u"PrintScreen",
+ u"ScrollLock",
+ u"Pause",
+ u"NumPad0",
+ u"NumPad1",
+ u"NumPad2",
+ u"NumPad3",
+ u"NumPad4",
+ u"NumPad5",
+ u"NumPad6",
+ u"NumPad7",
+ u"NumPad8",
+ u"NumPad9"};
+
+std::u16string_view ToString(KeyCode key_code) {
+ if (static_cast<int>(key_code) < 0 ||
+ static_cast<int>(key_code) >=
+ static_cast<int>(key_code_string_list.size()))
+ return u"UNKNOWN_KEYCODENAME";
+
+ return key_code_string_list[static_cast<int>(key_code)];
+}
+
+std::u16string ToString(KeyModifier key_modifier,
+ std::u16string_view separator) {
+ std::vector<std::u16string> list;
+ if (key_modifier & KeyModifiers::shift) {
+ list.push_back(u"Shift");
+ }
+
+ if (key_modifier & KeyModifiers::ctrl) {
+ list.push_back(u"Ctrl");
+ }
+
+ if (key_modifier & KeyModifiers::alt) {
+ list.push_back(u"Shift");
+ }
+
+ if (list.empty()) return u"";
+ std::u16string result = list.front();
+ for (auto iter = list.cbegin() + 1; iter != list.cend(); ++iter) {
+ result += separator;
+ result += *iter;
+ }
+
+ return result;
+}
+} // namespace cru::platform::native
diff --git a/src/ui/ShortcutHub.cpp b/src/ui/ShortcutHub.cpp
index e5847f8c..145cfa87 100644
--- a/src/ui/ShortcutHub.cpp
+++ b/src/ui/ShortcutHub.cpp
@@ -1,5 +1,11 @@
#include "cru/ui/ShortcutHub.hpp"
+
+#include "cru/common/Logger.hpp"
+#include "cru/ui/Control.hpp"
+#include "cru/ui/DebugFlags.hpp"
+
#include <algorithm>
+#include <functional>
#include <iterator>
#include <optional>
@@ -55,4 +61,60 @@ const std::vector<ShortcutInfo>& ShortcutHub::GetShortcutByKeyBind(
if (result != map_.cend()) return result->second;
return empty_list_;
}
+
+void ShortcutHub::Install(Control* control) {
+ if (!event_guard_.IsEmpty()) {
+ log::Error(u"Shortcut hub is already installed. Failed to install.");
+ return;
+ }
+
+ event_guard_ += control->KeyDownEvent()->Bubble()->AddHandler(
+ std::bind(&ShortcutHub::OnKeyDown, this, std::placeholders::_1));
+}
+
+void ShortcutHub::Uninstall() {
+ if (event_guard_.IsEmpty()) {
+ log::Warn(u"Shortcut hub is not installed. Failed to uninstall.");
+ return;
+ }
+
+ event_guard_.Clear();
+}
+
+void ShortcutHub::OnKeyDown(event::KeyEventArgs& event) {
+ ShortcutKeyBind key_bind(event.GetKeyCode(), event.GetKeyModifier());
+ const auto& shortcut_list = this->GetShortcutByKeyBind(key_bind);
+
+ if constexpr (debug_flags::shortcut) {
+ if (shortcut_list.empty()) {
+ log::Debug(u"No shortcut for key bind {}.", key_bind.ToString());
+ }
+ log::Debug(u"Begin to handle shortcut for key bind {}.",
+ key_bind.ToString());
+ }
+
+ for (const auto& shortcut : shortcut_list) {
+ auto is_handled = shortcut.handler();
+ if (is_handled) {
+ if constexpr (debug_flags::shortcut) {
+ log::Debug(u"Handle {} handled it.", shortcut.name);
+ }
+
+ event.SetHandled();
+
+ break;
+ } else {
+ if constexpr (debug_flags::shortcut) {
+ log::Debug(u"Handle {} disdn't handle it.", shortcut.name);
+ }
+ }
+ }
+
+ if constexpr (debug_flags::shortcut) {
+ if (!shortcut_list.empty()) {
+ log::Debug(u"End handling shortcut for key bind {}.",
+ key_bind.ToString());
+ }
+ }
+}
} // namespace cru::ui