diff options
author | crupest <crupest@outlook.com> | 2018-11-05 23:25:57 +0800 |
---|---|---|
committer | crupest <crupest@outlook.com> | 2018-11-05 23:25:57 +0800 |
commit | fb1b16cd0ab189d61efe6237b2c2b1f7f72f90de (patch) | |
tree | e537823b914b407dc9ce5b5a69f91dc93d834426 /src | |
parent | a908cff41ce987f4adc597f9e5ad4105e56e6ff4 (diff) | |
download | cru-fb1b16cd0ab189d61efe6237b2c2b1f7f72f90de.tar.gz cru-fb1b16cd0ab189d61efe6237b2c2b1f7f72f90de.tar.bz2 cru-fb1b16cd0ab189d61efe6237b2c2b1f7f72f90de.zip |
Develop cursor.
Diffstat (limited to 'src')
-rw-r--r-- | src/application.cpp | 8 | ||||
-rw-r--r-- | src/ui/control.cpp | 8 | ||||
-rw-r--r-- | src/ui/control.h | 8 | ||||
-rw-r--r-- | src/ui/controls/button.cpp | 2 | ||||
-rw-r--r-- | src/ui/cursor.cpp | 7 | ||||
-rw-r--r-- | src/ui/cursor.h | 16 | ||||
-rw-r--r-- | src/ui/window.cpp | 39 | ||||
-rw-r--r-- | src/ui/window.h | 13 |
8 files changed, 85 insertions, 16 deletions
diff --git a/src/application.cpp b/src/application.cpp index 7be56f56..79aaf38d 100644 --- a/src/application.cpp +++ b/src/application.cpp @@ -103,9 +103,9 @@ namespace cru { void LoadSystemCursor(HINSTANCE h_instance) { - ui::cursors[ui::cursor_arrow_key] = std::make_shared<ui::Cursor>(::LoadCursorW(h_instance, MAKEINTRESOURCEW(IDC_ARROW)), false); - ui::cursors[ui::cursor_hand_key] = std::make_shared<ui::Cursor>(::LoadCursorW(h_instance, MAKEINTRESOURCEW(IDC_HAND)), false); - ui::cursors[ui::cursor_i_beam_key] = std::make_shared<ui::Cursor>(::LoadCursorW(h_instance, MAKEINTRESOURCEW(IDC_IBEAM)), false); + ui::cursors::arrow = std::make_shared<ui::Cursor>(::LoadCursorW(nullptr, MAKEINTRESOURCEW(IDC_ARROW)), false); + ui::cursors::hand = std::make_shared<ui::Cursor>(::LoadCursorW(nullptr, MAKEINTRESOURCEW(IDC_HAND)), false); + ui::cursors::i_beam = std::make_shared<ui::Cursor>(::LoadCursorW(nullptr, MAKEINTRESOURCEW(IDC_IBEAM)), false); } } @@ -137,8 +137,6 @@ namespace cru { Application::~Application() { - ui::cursors.clear(); - animation_manager_.reset(); instance_ = nullptr; } diff --git a/src/ui/control.cpp b/src/ui/control.cpp index d080ebb0..5215c107 100644 --- a/src/ui/control.cpp +++ b/src/ui/control.cpp @@ -322,6 +322,14 @@ namespace cru { } } + void Control::SetCursor(const Cursor::Ptr& cursor) + { + cursor_ = cursor; + const auto window = GetWindow(); + if (window && window->GetMouseHoverControl() == this) + window->UpdateCursor(); + } + void Control::OnAddChild(Control* child) { if (auto window = GetWindow()) diff --git a/src/ui/control.h b/src/ui/control.h index a9dbc7a4..db89b3b6 100644 --- a/src/ui/control.h +++ b/src/ui/control.h @@ -226,8 +226,9 @@ namespace cru //*************** region: cursor *************** - //TODO! - /* + // If cursor is set to null, then it uses parent's cursor. + // Window's cursor can't be null. + Cursor::Ptr GetCursor() const { return cursor_; @@ -235,9 +236,6 @@ namespace cru void SetCursor(const Cursor::Ptr& cursor); - Cursor::Ptr GetCursorInherit(); - */ - //*************** region: events *************** //Raised when mouse enter the control. diff --git a/src/ui/controls/button.cpp b/src/ui/controls/button.cpp index 6c1024c4..11f8e31b 100644 --- a/src/ui/controls/button.cpp +++ b/src/ui/controls/button.cpp @@ -20,6 +20,8 @@ namespace cru::ui::controls SetBordered(true); GetBorderProperty() = normal_border_; + + SetCursor(cursors::hand); } StringView Button::GetControlType() const diff --git a/src/ui/cursor.cpp b/src/ui/cursor.cpp index e0bd1814..e1f0e5ef 100644 --- a/src/ui/cursor.cpp +++ b/src/ui/cursor.cpp @@ -16,5 +16,10 @@ namespace cru::ui ::DestroyCursor(handle_); } - std::unordered_map<String, Cursor::Ptr> cursors; + namespace cursors + { + Cursor::Ptr arrow{}; + Cursor::Ptr hand{}; + Cursor::Ptr i_beam{}; + } } diff --git a/src/ui/cursor.h b/src/ui/cursor.h index b57db9b7..3c09b35e 100644 --- a/src/ui/cursor.h +++ b/src/ui/cursor.h @@ -20,14 +20,20 @@ namespace cru::ui Cursor& operator=(Cursor&& other) = delete; ~Cursor() override; + HCURSOR GetHandle() const + { + return handle_; + } + private: HCURSOR handle_; bool auto_release_; }; - - extern std::unordered_map<String, Cursor::Ptr> cursors; - constexpr auto cursor_arrow_key = L"System_Arrow"; - constexpr auto cursor_hand_key = L"System_Hand"; - constexpr auto cursor_i_beam_key = L"System_IBeam"; + namespace cursors + { + extern Cursor::Ptr arrow; + extern Cursor::Ptr hand; + extern Cursor::Ptr i_beam; + } } diff --git a/src/ui/window.cpp b/src/ui/window.cpp index 947516e0..50959c91 100644 --- a/src/ui/window.cpp +++ b/src/ui/window.cpp @@ -3,6 +3,7 @@ #include "application.h" #include "graph/graph.h" #include "exception.h" +#include "cursor.h" namespace cru { @@ -91,6 +92,21 @@ namespace cru ); } + namespace + { + Cursor::Ptr GetCursorInherit(Control* control) + { + while (control != nullptr) + { + const auto cursor = control->GetCursor(); + if (cursor != nullptr) + return cursor; + control = control->GetParent(); + } + return cursors::arrow; + } + } + Window::Window() : Control(WindowConstructorTag{}, this), control_list_({ this }) { const auto app = Application::GetInstance(); hwnd_ = CreateWindowEx(0, @@ -106,6 +122,8 @@ namespace cru app->GetWindowManager()->RegisterWindow(hwnd_, this); render_target_ = app->GetGraphManager()->CreateWindowRenderTarget(hwnd_); + + SetCursor(cursors::arrow); } Window::~Window() { @@ -442,6 +460,14 @@ namespace cru } } + void Window::UpdateCursor() + { + if (IsWindowValid() && mouse_hover_control_ != nullptr) + { + SetCursorInternal(GetCursorInherit(mouse_hover_control_)->GetHandle()); + } + } + #ifdef CRU_DEBUG_LAYOUT void Window::SetDebugLayout(const bool value) { @@ -465,6 +491,16 @@ namespace cru return ::PeekMessageW(&msg, hwnd_, message, message, PM_NOREMOVE) != 0; } + void Window::SetCursorInternal(HCURSOR cursor) + { + if (IsWindowValid()) + { + ::SetClassLongPtrW(GetWindowHandle(), GCLP_HCURSOR, reinterpret_cast<LONG_PTR>(cursor)); + if (mouse_hover_control_ != nullptr) + ::SetCursor(cursor); + } + } + Size Window::OnMeasureContent(const Size& available_size) { for (auto control: GetChildren()) @@ -618,7 +654,10 @@ namespace cru if (old_control != nullptr) // if last mouse-hover-on control exists DispatchEvent(old_control, &Control::RaiseMouseLeaveEvent, lowest_common_ancestor); // dispatch mouse leave event. if (new_control != nullptr) + { DispatchEvent(new_control, &Control::RaiseMouseEnterEvent, lowest_common_ancestor, point); // dispatch mouse enter event. + UpdateCursor(); + } } } } diff --git a/src/ui/window.h b/src/ui/window.h index d6560c0f..1d188a05 100644 --- a/src/ui/window.h +++ b/src/ui/window.h @@ -143,8 +143,15 @@ namespace cru { //Return false if the message is not handled. bool HandleWindowMessage(HWND hwnd, int msg, WPARAM w_param, LPARAM l_param, LRESULT& result); + //*************** region: mouse *************** + Point GetMousePosition(); + Control* GetMouseHoverControl() const + { + return mouse_hover_control_; + } + //*************** region: position and size *************** //Always return (0, 0) for a window. @@ -187,6 +194,10 @@ namespace cru { Control* CaptureMouseFor(Control* control); Control* ReleaseCurrentMouseCapture(); + + //*************** region: cursor *************** + void UpdateCursor(); + //*************** region: debug *************** #ifdef CRU_DEBUG_LAYOUT bool IsDebugLayout() const @@ -212,6 +223,8 @@ namespace cru { bool IsMessageInQueue(UINT message); + void SetCursorInternal(HCURSOR cursor); + //*************** region: layout *************** |