From 73f13dd60f51ff05e31a64fba89fe31ab3ab185d Mon Sep 17 00:00:00 2001 From: 杨宇千 Date: Sun, 15 Sep 2019 00:03:11 +0800 Subject: ... --- include/cru/common/base.hpp | 6 +++ include/cru/platform/native/cursor.hpp | 2 + include/cru/platform/native/ui_applicaition.hpp | 58 ------------------------- include/cru/platform/native/ui_application.hpp | 58 +++++++++++++++++++++++++ include/cru/ui/click_detector.hpp | 2 +- include/cru/ui/controls/button.hpp | 8 +++- include/cru/win/native/ui_application.hpp | 2 +- src/CMakeLists.txt | 36 +-------------- src/main.cpp | 2 +- src/platform/CMakeLists.txt | 14 ++++++ src/platform/graph/CMakeLists.txt | 12 +++++ src/platform/native/CMakeLists.txt | 12 +++++ src/platform/native/cursor.cpp | 10 +++++ src/ui/control.cpp | 2 +- src/ui/controls/button.cpp | 32 +++++++++----- src/ui/ui_manager.cpp | 2 +- src/ui/window.cpp | 2 +- src/win/graph/direct/CMakeLists.txt | 2 +- src/win/native/CMakeLists.txt | 2 +- src/win/native/window_manager.cpp | 2 +- 20 files changed, 152 insertions(+), 114 deletions(-) delete mode 100644 include/cru/platform/native/ui_applicaition.hpp create mode 100644 include/cru/platform/native/ui_application.hpp create mode 100644 src/platform/CMakeLists.txt create mode 100644 src/platform/graph/CMakeLists.txt create mode 100644 src/platform/native/CMakeLists.txt create mode 100644 src/platform/native/cursor.cpp diff --git a/include/cru/common/base.hpp b/include/cru/common/base.hpp index 920fe569..55f43e5c 100644 --- a/include/cru/common/base.hpp +++ b/include/cru/common/base.hpp @@ -1,6 +1,8 @@ #pragma once #include "pre_config.hpp" +#include + #define CRU_DEFAULT_COPY(classname) \ classname(const classname&) = default; \ classname& operator=(const classname&) = default; @@ -36,4 +38,8 @@ struct Interface { Interface& operator=(Interface&& other) = delete; virtual ~Interface() = default; }; + +[[noreturn]] inline void UnreachableCode() { + throw std::runtime_error("Unreachable code."); +} } // namespace cru diff --git a/include/cru/platform/native/cursor.hpp b/include/cru/platform/native/cursor.hpp index b0ff4494..b8604ecb 100644 --- a/include/cru/platform/native/cursor.hpp +++ b/include/cru/platform/native/cursor.hpp @@ -34,4 +34,6 @@ class CursorManager : public NativeResource { //TODO: Add method to create cursor. }; + +std::shared_ptr GetSystemCursor(SystemCursor type); } // namespace cru::platform::native diff --git a/include/cru/platform/native/ui_applicaition.hpp b/include/cru/platform/native/ui_applicaition.hpp deleted file mode 100644 index 923fbaf7..00000000 --- a/include/cru/platform/native/ui_applicaition.hpp +++ /dev/null @@ -1,58 +0,0 @@ -#pragma once -#include "../native_resource.hpp" - -#include "cursor.hpp" - -#include -#include -#include - -namespace cru::platform::native { -class NativeWindow; - -// The entry point of a ui application. -// It will call IGraphFactory::CreateInstance during its creation -// and set graph factory to be auto deleted. If you want to keep -// the graph factory then you should manually set it to false after -// creating the ui application. -class UiApplication : public NativeResource { - public: - // Create a platform-specific instance and save it as the global instance. - // Do not create the instance twice. Implements should assert for that. - // After creating, get the instance by GetInstance. - static UiApplication* CreateInstance(); - - // Get the global instance. If it is not created, then return nullptr. - static UiApplication* GetInstance(); - - protected: - UiApplication() = default; - - public: - UiApplication(const UiApplication& other) = delete; - UiApplication& operator=(const UiApplication& other) = delete; - - UiApplication(UiApplication&& other) = delete; - UiApplication& operator=(UiApplication&& other) = delete; - - ~UiApplication() override = default; - - public: - virtual int Run() = 0; - virtual void Quit(int quite_code) = 0; - - virtual void AddOnQuitHandler(const std::function& handler) = 0; - - virtual void InvokeLater(const std::function& action) = 0; - virtual unsigned long SetTimeout(std::chrono::milliseconds milliseconds, - const std::function& action) = 0; - virtual unsigned long SetInterval(std::chrono::milliseconds milliseconds, - const std::function& action) = 0; - virtual void CancelTimer(unsigned long id) = 0; - - virtual std::vector GetAllWindow() = 0; - virtual NativeWindow* CreateWindow(NativeWindow* parent) = 0; - - virtual CursorManager* GetCursorManager() = 0; -}; -} // namespace cru::platform::native diff --git a/include/cru/platform/native/ui_application.hpp b/include/cru/platform/native/ui_application.hpp new file mode 100644 index 00000000..923fbaf7 --- /dev/null +++ b/include/cru/platform/native/ui_application.hpp @@ -0,0 +1,58 @@ +#pragma once +#include "../native_resource.hpp" + +#include "cursor.hpp" + +#include +#include +#include + +namespace cru::platform::native { +class NativeWindow; + +// The entry point of a ui application. +// It will call IGraphFactory::CreateInstance during its creation +// and set graph factory to be auto deleted. If you want to keep +// the graph factory then you should manually set it to false after +// creating the ui application. +class UiApplication : public NativeResource { + public: + // Create a platform-specific instance and save it as the global instance. + // Do not create the instance twice. Implements should assert for that. + // After creating, get the instance by GetInstance. + static UiApplication* CreateInstance(); + + // Get the global instance. If it is not created, then return nullptr. + static UiApplication* GetInstance(); + + protected: + UiApplication() = default; + + public: + UiApplication(const UiApplication& other) = delete; + UiApplication& operator=(const UiApplication& other) = delete; + + UiApplication(UiApplication&& other) = delete; + UiApplication& operator=(UiApplication&& other) = delete; + + ~UiApplication() override = default; + + public: + virtual int Run() = 0; + virtual void Quit(int quite_code) = 0; + + virtual void AddOnQuitHandler(const std::function& handler) = 0; + + virtual void InvokeLater(const std::function& action) = 0; + virtual unsigned long SetTimeout(std::chrono::milliseconds milliseconds, + const std::function& action) = 0; + virtual unsigned long SetInterval(std::chrono::milliseconds milliseconds, + const std::function& action) = 0; + virtual void CancelTimer(unsigned long id) = 0; + + virtual std::vector GetAllWindow() = 0; + virtual NativeWindow* CreateWindow(NativeWindow* parent) = 0; + + virtual CursorManager* GetCursorManager() = 0; +}; +} // namespace cru::platform::native diff --git a/include/cru/ui/click_detector.hpp b/include/cru/ui/click_detector.hpp index 3806dd82..1a88b8a6 100644 --- a/include/cru/ui/click_detector.hpp +++ b/include/cru/ui/click_detector.hpp @@ -70,7 +70,7 @@ class ClickDetector : public Object { case MouseButton::Right: return click_map_.right; default: - std::abort(); + UnreachableCode(); } } diff --git a/include/cru/ui/controls/button.hpp b/include/cru/ui/controls/button.hpp index ca3dcae9..b5cca7dc 100644 --- a/include/cru/ui/controls/button.hpp +++ b/include/cru/ui/controls/button.hpp @@ -20,6 +20,8 @@ struct ButtonBorderStyle { render::BorderStyle hover; // corresponds to ButtonState::Press render::BorderStyle press; + // corresponds to ButtonState::PressCancel + render::BorderStyle press_cancel; }; enum class ButtonState { @@ -27,8 +29,10 @@ enum class ButtonState { Normal, // mouse is in it and not pressed Hover, - // mouse is pressed in it (click begins) - Press + // mouse is pressed in it + Press, + // mouse is pressed outside button + PressCancel, }; class Button : public ContentControl { diff --git a/include/cru/win/native/ui_application.hpp b/include/cru/win/native/ui_application.hpp index d7da4409..addf2c93 100644 --- a/include/cru/win/native/ui_application.hpp +++ b/include/cru/win/native/ui_application.hpp @@ -1,7 +1,7 @@ #pragma once #include "../win_pre_config.hpp" -#include "cru/platform/native/ui_applicaition.hpp" +#include "cru/platform/native/ui_application.hpp" #include "platform_id.hpp" #include "cursor.hpp" diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 3cff8a24..59ca69d4 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,40 +1,6 @@ add_subdirectory(common) -set(CRU_PLATFORM_BASE_INCLUDE_DIR ${CRU_INCLUDE_DIR}/cru/platform) -add_library(cru_platform_base INTERFACE) -target_sources(cru_platform_base INTERFACE - ${CRU_PLATFORM_BASE_INCLUDE_DIR}/exception.hpp - ${CRU_PLATFORM_BASE_INCLUDE_DIR}/graphic_base.hpp - ${CRU_PLATFORM_BASE_INCLUDE_DIR}/heap_debug.hpp - ${CRU_PLATFORM_BASE_INCLUDE_DIR}/matrix.hpp - ${CRU_PLATFORM_BASE_INCLUDE_DIR}/native_resource.hpp - ${CRU_PLATFORM_BASE_INCLUDE_DIR}/string_util.hpp -) -target_link_libraries(cru_platform_base INTERFACE cru_base) - -set(CRU_PLATFORM_GRAPH_INCLUDE_DIR ${CRU_INCLUDE_DIR}/cru/platform/graph) -add_library(cru_platform_graph INTERFACE) -target_sources(cru_platform_graph INTERFACE - ${CRU_PLATFORM_GRAPH_INCLUDE_DIR}/brush.hpp - ${CRU_PLATFORM_GRAPH_INCLUDE_DIR}/font.hpp - ${CRU_PLATFORM_GRAPH_INCLUDE_DIR}/geometry.hpp - ${CRU_PLATFORM_GRAPH_INCLUDE_DIR}/graph_factory.hpp - ${CRU_PLATFORM_GRAPH_INCLUDE_DIR}/painter.hpp - ${CRU_PLATFORM_GRAPH_INCLUDE_DIR}/text_layout.hpp - ${CRU_PLATFORM_GRAPH_INCLUDE_DIR}/util/painter_util.hpp -) -target_link_libraries(cru_platform_graph INTERFACE cru_platform_base) - -set(CRU_PLATFORM_NATIVE_INCLUDE_DIR ${CRU_INCLUDE_DIR}/cru/platform/native) -add_library(cru_platform_native INTERFACE) -target_sources(cru_platform_native INTERFACE - ${CRU_PLATFORM_NATIVE_INCLUDE_DIR}/basic_types.hpp - ${CRU_PLATFORM_NATIVE_INCLUDE_DIR}/cursor.hpp - ${CRU_PLATFORM_NATIVE_INCLUDE_DIR}/native_event.hpp - ${CRU_PLATFORM_NATIVE_INCLUDE_DIR}/native_window.hpp - ${CRU_PLATFORM_NATIVE_INCLUDE_DIR}/ui_application.hpp -) -target_link_libraries(cru_platform_native INTERFACE cru_platform_graph) +add_subdirectory(platform) if(WIN32) add_subdirectory(win) diff --git a/src/main.cpp b/src/main.cpp index 9336dda7..7fca1fce 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,6 +1,6 @@ #include "cru/platform/heap_debug.hpp" #include "cru/platform/native/native_window.hpp" -#include "cru/platform/native/ui_applicaition.hpp" +#include "cru/platform/native/ui_application.hpp" #include "cru/ui/controls/button.hpp" #include "cru/ui/controls/flex_layout.hpp" #include "cru/ui/controls/text_block.hpp" diff --git a/src/platform/CMakeLists.txt b/src/platform/CMakeLists.txt new file mode 100644 index 00000000..c9eef482 --- /dev/null +++ b/src/platform/CMakeLists.txt @@ -0,0 +1,14 @@ +set(CRU_PLATFORM_BASE_INCLUDE_DIR ${CRU_INCLUDE_DIR}/cru/platform) +add_library(cru_platform_base INTERFACE) +target_sources(cru_platform_base INTERFACE + ${CRU_PLATFORM_BASE_INCLUDE_DIR}/exception.hpp + ${CRU_PLATFORM_BASE_INCLUDE_DIR}/graphic_base.hpp + ${CRU_PLATFORM_BASE_INCLUDE_DIR}/heap_debug.hpp + ${CRU_PLATFORM_BASE_INCLUDE_DIR}/matrix.hpp + ${CRU_PLATFORM_BASE_INCLUDE_DIR}/native_resource.hpp + ${CRU_PLATFORM_BASE_INCLUDE_DIR}/string_util.hpp +) +target_link_libraries(cru_platform_base INTERFACE cru_base) + +add_subdirectory(graph) +add_subdirectory(native) diff --git a/src/platform/graph/CMakeLists.txt b/src/platform/graph/CMakeLists.txt new file mode 100644 index 00000000..da76d296 --- /dev/null +++ b/src/platform/graph/CMakeLists.txt @@ -0,0 +1,12 @@ +set(CRU_PLATFORM_GRAPH_INCLUDE_DIR ${CRU_INCLUDE_DIR}/cru/platform/graph) +add_library(cru_platform_graph INTERFACE) +target_sources(cru_platform_graph INTERFACE + ${CRU_PLATFORM_GRAPH_INCLUDE_DIR}/brush.hpp + ${CRU_PLATFORM_GRAPH_INCLUDE_DIR}/font.hpp + ${CRU_PLATFORM_GRAPH_INCLUDE_DIR}/geometry.hpp + ${CRU_PLATFORM_GRAPH_INCLUDE_DIR}/graph_factory.hpp + ${CRU_PLATFORM_GRAPH_INCLUDE_DIR}/painter.hpp + ${CRU_PLATFORM_GRAPH_INCLUDE_DIR}/text_layout.hpp + ${CRU_PLATFORM_GRAPH_INCLUDE_DIR}/util/painter_util.hpp +) +target_link_libraries(cru_platform_graph INTERFACE cru_platform_base) diff --git a/src/platform/native/CMakeLists.txt b/src/platform/native/CMakeLists.txt new file mode 100644 index 00000000..0e44fd55 --- /dev/null +++ b/src/platform/native/CMakeLists.txt @@ -0,0 +1,12 @@ +set(CRU_PLATFORM_NATIVE_INCLUDE_DIR ${CRU_INCLUDE_DIR}/cru/platform/native) +add_library(cru_platform_native STATIC + cursor.cpp +) +target_sources(cru_platform_native PUBLIC + ${CRU_PLATFORM_NATIVE_INCLUDE_DIR}/basic_types.hpp + ${CRU_PLATFORM_NATIVE_INCLUDE_DIR}/cursor.hpp + ${CRU_PLATFORM_NATIVE_INCLUDE_DIR}/native_event.hpp + ${CRU_PLATFORM_NATIVE_INCLUDE_DIR}/native_window.hpp + ${CRU_PLATFORM_NATIVE_INCLUDE_DIR}/ui_application.hpp +) +target_link_libraries(cru_platform_native PUBLIC cru_platform_graph) diff --git a/src/platform/native/cursor.cpp b/src/platform/native/cursor.cpp new file mode 100644 index 00000000..b12aec40 --- /dev/null +++ b/src/platform/native/cursor.cpp @@ -0,0 +1,10 @@ +#include "cru/platform/native/cursor.hpp" + +#include "cru/platform/native/ui_application.hpp" + +namespace cru::platform::native { +std::shared_ptr GetSystemCursor(SystemCursor type) { + return UiApplication::GetInstance()->GetCursorManager()->GetSystemCursor( + type); +} +} // namespace cru::platform::native diff --git a/src/ui/control.cpp b/src/ui/control.cpp index 50628883..8e8819de 100644 --- a/src/ui/control.cpp +++ b/src/ui/control.cpp @@ -3,7 +3,7 @@ #include "cru/platform/native/basic_types.hpp" #include "cru/platform/native/cursor.hpp" #include "cru/platform/native/native_window.hpp" -#include "cru/platform/native/ui_applicaition.hpp" +#include "cru/platform/native/ui_application.hpp" #include "cru/ui/base.hpp" #include "cru/ui/event/ui_event.hpp" #include "cru/ui/window.hpp" diff --git a/src/ui/controls/button.cpp b/src/ui/controls/button.cpp index 38ce75a8..5e32e064 100644 --- a/src/ui/controls/button.cpp +++ b/src/ui/controls/button.cpp @@ -5,14 +5,14 @@ #include "cru/platform/graph/graph_factory.hpp" #include "cru/platform/native/cursor.hpp" #include "cru/platform/native/native_window.hpp" -#include "cru/platform/native/ui_applicaition.hpp" +#include "cru/platform/native/ui_application.hpp" #include "cru/ui/render/border_render_object.hpp" #include "cru/ui/ui_manager.hpp" #include "cru/ui/window.hpp" namespace cru::ui::controls { +using platform::native::GetSystemCursor; using platform::native::SystemCursor; -using platform::native::UiApplication; Button::Button() : click_detector_(this) { // const auto predefined_resource = @@ -25,12 +25,17 @@ Button::Button() : click_detector_(this) { factory->CreateSolidColorBrush(Color::FromHex(0x47d1ff))); border_style_.press.brush = std::shared_ptr( factory->CreateSolidColorBrush(Color::FromHex(0x91e4ff))); + border_style_.press_cancel.brush = std::shared_ptr( + factory->CreateSolidColorBrush(Color::FromHex(0x91e4ff))); border_style_.normal.thickness = border_style_.hover.thickness = - border_style_.press.thickness = Thickness{3}; + border_style_.press.thickness = border_style_.press_cancel.thickness = + Thickness{3}; border_style_.normal.corner_radius = border_style_.hover.corner_radius = - border_style_.press.corner_radius = render::CornerRadius{Point{10, 5}}; + border_style_.press.corner_radius = + border_style_.press_cancel.corner_radius = + render::CornerRadius{Point{10, 5}}; render_object_.reset( new render::BorderRenderObject(border_style_.normal.brush)); @@ -44,14 +49,14 @@ Button::Button() : click_detector_(this) { } else { SetState(ButtonState::Hover); } - SetCursor(UiApplication::GetInstance()->GetCursorManager()->GetSystemCursor( - SystemCursor::Hand)); }); MouseLeaveEvent()->Direct()->AddHandler([this](event::MouseEventArgs& args) { - SetState(ButtonState::Normal); - SetCursor(UiApplication::GetInstance()->GetCursorManager()->GetSystemCursor( - SystemCursor::Arrow)); + if (click_detector_.GetPressingButton() & trigger_button_) { + SetState(ButtonState::Normal); + } else { + SetState(ButtonState::PressCancel); + } }); click_detector_.ClickBeginEvent()->AddHandler([this](MouseButton button) { @@ -62,7 +67,7 @@ Button::Button() : click_detector_(this) { click_detector_.ClickEndEvent()->AddHandler([this](MouseButton button) { if (button & trigger_button_) { - SetState(ButtonState::Normal); + SetState(ButtonState::Hover); } }); } @@ -81,12 +86,19 @@ void Button::OnStateChange(ButtonState oldState, ButtonState newState) { switch (newState) { case ButtonState::Normal: render_object_->SetStyle(border_style_.normal); + SetCursor(GetSystemCursor(SystemCursor::Arrow)); break; case ButtonState::Hover: render_object_->SetStyle(border_style_.hover); + SetCursor(GetSystemCursor(SystemCursor::Hand)); break; case ButtonState::Press: render_object_->SetStyle(border_style_.press); + SetCursor(GetSystemCursor(SystemCursor::Hand)); + break; + case ButtonState::PressCancel: + render_object_->SetStyle(border_style_.press_cancel); + SetCursor(GetSystemCursor(SystemCursor::Arrow)); break; } GetWindow()->GetNativeWindow()->Repaint(); diff --git a/src/ui/ui_manager.cpp b/src/ui/ui_manager.cpp index 376b1b45..fa3304fb 100644 --- a/src/ui/ui_manager.cpp +++ b/src/ui/ui_manager.cpp @@ -3,7 +3,7 @@ #include "cru/platform/graph/brush.hpp" #include "cru/platform/graph/font.hpp" #include "cru/platform/graph/graph_factory.hpp" -#include "cru/platform/native/ui_applicaition.hpp" +#include "cru/platform/native/ui_application.hpp" namespace cru::ui { using namespace cru::platform::graph; diff --git a/src/ui/window.cpp b/src/ui/window.cpp index af95c3c6..41f440f0 100644 --- a/src/ui/window.cpp +++ b/src/ui/window.cpp @@ -2,7 +2,7 @@ #include "cru/platform/graph/painter.hpp" #include "cru/platform/native/native_window.hpp" -#include "cru/platform/native/ui_applicaition.hpp" +#include "cru/platform/native/ui_application.hpp" #include "cru/ui/render/window_render_object.hpp" #include "routed_event_dispatch.hpp" diff --git a/src/win/graph/direct/CMakeLists.txt b/src/win/graph/direct/CMakeLists.txt index 7228802c..fa5e3a99 100644 --- a/src/win/graph/direct/CMakeLists.txt +++ b/src/win/graph/direct/CMakeLists.txt @@ -21,4 +21,4 @@ target_sources(cru_win_graph_direct PUBLIC ${CRU_WIN_GRAPH_DIRECT_INCLUDE_DIR}/platform_id.hpp ${CRU_WIN_GRAPH_DIRECT_INCLUDE_DIR}/text_layout.hpp ) -target_link_libraries(cru_win_graph_direct PUBLIC D3D11 D2d1 DWrite cru_win_base) +target_link_libraries(cru_win_graph_direct PUBLIC D3D11 D2d1 DWrite cru_win_base cru_platform_graph) diff --git a/src/win/native/CMakeLists.txt b/src/win/native/CMakeLists.txt index 02f3afce..08acc739 100644 --- a/src/win/native/CMakeLists.txt +++ b/src/win/native/CMakeLists.txt @@ -28,4 +28,4 @@ target_sources(cru_win_native PUBLIC ${CRU_WIN_NATIVE_INCLUDE_DIR}/window_native_message_event_args.hpp ${CRU_WIN_NATIVE_INCLUDE_DIR}/window_render_target.hpp ) -target_link_libraries(cru_win_native PUBLIC cru_win_graph_direct) +target_link_libraries(cru_win_native PUBLIC cru_win_graph_direct cru_platform_native) diff --git a/src/win/native/window_manager.cpp b/src/win/native/window_manager.cpp index 7f70d3cc..5699b38a 100644 --- a/src/win/native/window_manager.cpp +++ b/src/win/native/window_manager.cpp @@ -4,7 +4,7 @@ #include "cru/win/native/native_window.hpp" #include "cru/win/native/window_class.hpp" -#include +#include namespace cru::platform::native::win { LRESULT __stdcall GeneralWndProc(HWND hWnd, UINT Msg, WPARAM wParam, -- cgit v1.2.3