aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcrupest <crupest@outlook.com>2020-10-27 22:52:34 +0800
committercrupest <crupest@outlook.com>2020-10-27 22:52:34 +0800
commit37e43bbff36dd7f21d0a483eda62509b9bd7aebf (patch)
treed9c29a6d2c60279f1605931daac3f52d0c7ea064
parentf90650efb7175957892d18097954ffd3aa59dc95 (diff)
downloadcru-37e43bbff36dd7f21d0a483eda62509b9bd7aebf.tar.gz
cru-37e43bbff36dd7f21d0a483eda62509b9bd7aebf.tar.bz2
cru-37e43bbff36dd7f21d0a483eda62509b9bd7aebf.zip
...
-rw-r--r--include/cru/ui/Base.hpp3
-rw-r--r--include/cru/ui/DebugFlags.hpp6
-rw-r--r--include/cru/ui/ShortcutHub.hpp78
-rw-r--r--src/ui/CMakeLists.txt3
-rw-r--r--src/ui/ShortcutHub.cpp5
-rw-r--r--src/ui/render/RenderObject.cpp27
6 files changed, 106 insertions, 16 deletions
diff --git a/include/cru/ui/Base.hpp b/include/cru/ui/Base.hpp
index 0c0a4783..6be359ab 100644
--- a/include/cru/ui/Base.hpp
+++ b/include/cru/ui/Base.hpp
@@ -8,9 +8,6 @@
#include <optional>
#include <vector>
-// Change 0 to 1 to enable debug layout log.
-#define CRUUI_DEBUG_LAYOUT 0
-
namespace cru::ui {
//-------------------- region: import --------------------
using cru::platform::Color;
diff --git a/include/cru/ui/DebugFlags.hpp b/include/cru/ui/DebugFlags.hpp
new file mode 100644
index 00000000..a0003e9d
--- /dev/null
+++ b/include/cru/ui/DebugFlags.hpp
@@ -0,0 +1,6 @@
+#pragma once
+
+namespace cru::ui::debug_flags {
+constexpr bool layout = false;
+constexpr bool shortcut = true;
+} // namespace cru::ui::debug_flags
diff --git a/include/cru/ui/ShortcutHub.hpp b/include/cru/ui/ShortcutHub.hpp
new file mode 100644
index 00000000..9995a4e1
--- /dev/null
+++ b/include/cru/ui/ShortcutHub.hpp
@@ -0,0 +1,78 @@
+#pragma once
+#include "Base.hpp"
+
+#include "cru/platform/native/Keyboard.hpp"
+
+#include <functional>
+#include <optional>
+#include <string>
+#include <string_view>
+#include <vector>
+
+namespace cru::ui {
+
+class ShortcutKeyBind {
+ public:
+ ShortcutKeyBind(platform::native::KeyCode key,
+ platform::native::KeyModifier modifier)
+ : key_(key), modifier_(modifier) {}
+
+ CRU_DEFAULT_COPY(ShortcutKeyBind)
+ CRU_DEFAULT_MOVE(ShortcutKeyBind)
+
+ ~ShortcutKeyBind() = default;
+
+ platform::native::KeyCode GetKey() const { return key_; }
+ platform::native::KeyModifier GetModifier() const { return modifier_; }
+
+ bool Is(platform::native::KeyCode key,
+ platform::native::KeyModifier modifier) const {
+ return key == key_ && modifier == modifier_;
+ }
+
+ bool operator==(const ShortcutKeyBind& other) const {
+ return this->key_ == other.key_ && this->modifier_ == other.modifier_;
+ }
+
+ bool operator!=(const ShortcutKeyBind& other) const {
+ return !this->operator==(other);
+ }
+
+ private:
+ platform::native::KeyCode key_;
+ platform::native::KeyModifier modifier_;
+};
+
+struct ShortcutInfo {
+ std::u16string name;
+ ShortcutKeyBind key_bind;
+ std::function<bool()> handler;
+};
+
+class ShortcutHub : public Object {
+ public:
+ ShortcutHub();
+
+ CRU_DELETE_COPY(ShortcutHub)
+ CRU_DELETE_MOVE(ShortcutHub)
+
+ ~ShortcutHub() override;
+
+ // Handler return true if it consumes the shortcut. Or return false if it does
+ // not handle the shortcut. Name is just for debug.
+ int RegisterShortcut(std::u16string name, ShortcutKeyBind bind,
+ std::function<bool()> handler);
+
+ void UnregisterShortcut(int id);
+
+ std::vector<ShortcutInfo> GetAllShortcuts() const;
+ std::optional<ShortcutInfo> GetShortcut(int id) const;
+ std::vector<ShortcutInfo> GetShortcutByKeyBind(
+ const ShortcutKeyBind& key_bind) const;
+
+ void Install(Control* control);
+ void Uninstall();
+
+ private:
+};
+} // namespace cru::ui
diff --git a/src/ui/CMakeLists.txt b/src/ui/CMakeLists.txt
index 6c50ec57..a83ab1d7 100644
--- a/src/ui/CMakeLists.txt
+++ b/src/ui/CMakeLists.txt
@@ -10,6 +10,7 @@ add_library(cru_ui STATIC
Helper.cpp
LayoutControl.cpp
NoChildControl.cpp
+ ShortcutHub.cpp
UiEvent.cpp
UiHost.cpp
UiManager.cpp
@@ -36,8 +37,10 @@ target_sources(cru_ui PUBLIC
${CRU_UI_INCLUDE_DIR}/ClickDetector.hpp
${CRU_UI_INCLUDE_DIR}/ContentControl.hpp
${CRU_UI_INCLUDE_DIR}/Control.hpp
+ ${CRU_UI_INCLUDE_DIR}/DebugFlags.hpp
${CRU_UI_INCLUDE_DIR}/LayoutControl.hpp
${CRU_UI_INCLUDE_DIR}/NoChildControl.hpp
+ ${CRU_UI_INCLUDE_DIR}/ShortcutHub.hpp
${CRU_UI_INCLUDE_DIR}/UiEvent.hpp
${CRU_UI_INCLUDE_DIR}/UiHost.hpp
${CRU_UI_INCLUDE_DIR}/UiManager.hpp
diff --git a/src/ui/ShortcutHub.cpp b/src/ui/ShortcutHub.cpp
new file mode 100644
index 00000000..2246b6eb
--- /dev/null
+++ b/src/ui/ShortcutHub.cpp
@@ -0,0 +1,5 @@
+#include "cru/ui/ShortcutHub.hpp"
+
+namespace cru::ui {
+
+}
diff --git a/src/ui/render/RenderObject.cpp b/src/ui/render/RenderObject.cpp
index 57116f93..c85f8080 100644
--- a/src/ui/render/RenderObject.cpp
+++ b/src/ui/render/RenderObject.cpp
@@ -2,6 +2,7 @@
#include "cru/common/Logger.hpp"
#include "cru/platform/graph/util/Painter.hpp"
+#include "cru/ui/DebugFlags.hpp"
#include "cru/ui/UiHost.hpp"
#include <algorithm>
@@ -69,18 +70,18 @@ void RenderObject::Measure(const MeasureRequirement& requirement,
MeasureSize merged_preferred_size =
preferred_size.OverrideBy(preferred_size_);
-#if CRUUI_DEBUG_LAYOUT
- log::Debug(u"{} Measure begins :\nrequirement: {}\npreferred size: {}",
- this->GetDebugPathInTree(), requirement.ToDebugString(),
- preferred_size.ToDebugString());
-#endif
+ if constexpr (cru::ui::debug_flags::layout) {
+ log::Debug(u"{} Measure begins :\nrequirement: {}\npreferred size: {}",
+ this->GetDebugPathInTree(), requirement.ToDebugString(),
+ preferred_size.ToDebugString());
+ }
size_ = OnMeasureCore(merged_requirement, merged_preferred_size);
-#if CRUUI_DEBUG_LAYOUT
- log::Debug(u"{} Measure ends :\nresult size: {}", this->GetDebugPathInTree(),
- size_.ToDebugString());
-#endif
+ if constexpr (cru::ui::debug_flags::layout) {
+ log::Debug(u"{} Measure ends :\nresult size: {}",
+ this->GetDebugPathInTree(), size_.ToDebugString());
+ }
Ensures(size_.width >= 0);
Ensures(size_.height >= 0);
@@ -88,10 +89,10 @@ void RenderObject::Measure(const MeasureRequirement& requirement,
}
void RenderObject::Layout(const Point& offset) {
-#if CRUUI_DEBUG_LAYOUT
- log::Debug(u"{} Layout :\noffset: {}", this->GetDebugPathInTree(),
- offset.ToDebugString());
-#endif
+ if constexpr (cru::ui::debug_flags::layout) {
+ log::Debug(u"{} Layout :\noffset: {}", this->GetDebugPathInTree(),
+ offset.ToDebugString());
+ }
offset_ = offset;
OnLayoutCore();
}