aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/cru/platform/native/Base.hpp11
-rw-r--r--include/cru/platform/native/Cursor.hpp1
-rw-r--r--include/cru/platform/native/InputMethod.hpp6
-rw-r--r--include/cru/platform/native/Keyboard.hpp4
-rw-r--r--include/cru/platform/native/UiApplication.hpp6
-rw-r--r--include/cru/platform/native/Window.hpp16
-rw-r--r--include/cru/ui/WindowHost.hpp24
-rw-r--r--include/cru/win/native/Base.hpp4
-rw-r--r--include/cru/win/native/InputMethod.hpp21
-rw-r--r--include/cru/win/native/UiApplication.hpp6
-rw-r--r--include/cru/win/native/Window.hpp35
-rw-r--r--src/win/native/InputMethod.cpp65
-rw-r--r--src/win/native/UiApplication.cpp8
-rw-r--r--src/win/native/Window.cpp26
14 files changed, 48 insertions, 185 deletions
diff --git a/include/cru/platform/native/Base.hpp b/include/cru/platform/native/Base.hpp
index bba7b960..c3e87439 100644
--- a/include/cru/platform/native/Base.hpp
+++ b/include/cru/platform/native/Base.hpp
@@ -1,23 +1,18 @@
#pragma once
+#include "Keyboard.hpp"
#include "cru/common/Base.hpp"
#include "cru/common/Bitmask.hpp"
#include "cru/platform/graph/Base.hpp"
-#include "Keyboard.hpp"
+
+#include "../Resource.hpp"
namespace cru::platform::native {
struct ICursor;
struct ICursorManager;
struct IUiApplication;
struct INativeWindow;
-struct INativeWindowResolver;
-struct IInputMethodManager;
struct IInputMethodContext;
-struct Dpi {
- float x;
- float y;
-};
-
namespace details {
struct TagMouseButton {};
} // namespace details
diff --git a/include/cru/platform/native/Cursor.hpp b/include/cru/platform/native/Cursor.hpp
index 6c8f8068..447cd694 100644
--- a/include/cru/platform/native/Cursor.hpp
+++ b/include/cru/platform/native/Cursor.hpp
@@ -1,5 +1,4 @@
#pragma once
-#include "../Resource.hpp"
#include "Base.hpp"
#include <memory>
diff --git a/include/cru/platform/native/InputMethod.hpp b/include/cru/platform/native/InputMethod.hpp
index 6f222a43..de752417 100644
--- a/include/cru/platform/native/InputMethod.hpp
+++ b/include/cru/platform/native/InputMethod.hpp
@@ -1,5 +1,4 @@
#pragma once
-#include "../Resource.hpp"
#include "Base.hpp"
#include "cru/common/Event.hpp"
@@ -52,11 +51,6 @@ struct IInputMethodContext : virtual INativeResource {
virtual IEvent<std::u16string_view>* TextEvent() = 0;
};
-
-struct IInputMethodManager : virtual INativeResource {
- virtual std::unique_ptr<IInputMethodContext> GetContext(
- INativeWindow* window) = 0;
-};
} // namespace cru::platform::native
template <>
diff --git a/include/cru/platform/native/Keyboard.hpp b/include/cru/platform/native/Keyboard.hpp
index 8f53c5d6..67a35c8a 100644
--- a/include/cru/platform/native/Keyboard.hpp
+++ b/include/cru/platform/native/Keyboard.hpp
@@ -1,7 +1,9 @@
#pragma once
-#include <string_view>
#include "cru/common/Bitmask.hpp"
+#include <string>
+#include <string_view>
+
namespace cru::platform::native {
// Because of the complexity of keyboard layout, I only add code in US keyboard
// layout, the most widely used layout in China. We should try to make it easy
diff --git a/include/cru/platform/native/UiApplication.hpp b/include/cru/platform/native/UiApplication.hpp
index 4c1b3456..2b1b047a 100644
--- a/include/cru/platform/native/UiApplication.hpp
+++ b/include/cru/platform/native/UiApplication.hpp
@@ -1,7 +1,5 @@
#pragma once
-#include "../Resource.hpp"
#include "Base.hpp"
-#include "cru/common/Base.hpp"
#include <chrono>
#include <functional>
@@ -45,13 +43,11 @@ struct IUiApplication : public virtual INativeResource {
virtual void CancelTimer(long long id) = 0;
virtual std::vector<INativeWindow*> GetAllWindow() = 0;
- virtual std::shared_ptr<INativeWindowResolver> CreateWindow(
- INativeWindow* parent) = 0;
+ virtual INativeWindow* CreateWindow(INativeWindow* parent) = 0;
virtual cru::platform::graph::IGraphFactory* GetGraphFactory() = 0;
virtual ICursorManager* GetCursorManager() = 0;
- virtual IInputMethodManager* GetInputMethodManager() = 0;
};
class TimerAutoCanceler {
diff --git a/include/cru/platform/native/Window.hpp b/include/cru/platform/native/Window.hpp
index 1fcac1fc..c8abdeac 100644
--- a/include/cru/platform/native/Window.hpp
+++ b/include/cru/platform/native/Window.hpp
@@ -1,6 +1,6 @@
#pragma once
-#include "../Resource.hpp"
#include "Base.hpp"
+
#include "cru/common/Event.hpp"
#include <string_view>
@@ -8,14 +8,7 @@
namespace cru::platform::native {
// Represents a native window, which exposes some low-level events and
// operations.
-//
-// Usually you save an INativeWindowResolver after creating a window. Because
-// window may be destroyed when user do certain actions like click the close
-// button. Then the INativeWindow instance is destroyed and
-// INativeWindowResolver::Resolve return nullptr to indicate the fact.
struct INativeWindow : virtual INativeResource {
- virtual std::shared_ptr<INativeWindowResolver> GetResolver() = 0;
-
virtual void Close() = 0;
virtual INativeWindow* GetParent() = 0;
@@ -47,6 +40,7 @@ struct INativeWindow : virtual INativeResource {
// Remember to call EndDraw on return value and destroy it.
virtual std::unique_ptr<graph::IPainter> BeginPaint() = 0;
+ // Don't use this instance after receive this event.
virtual IEvent<std::nullptr_t>* DestroyEvent() = 0;
virtual IEvent<std::nullptr_t>* PaintEvent() = 0;
virtual IEvent<Size>* ResizeEvent() = 0;
@@ -57,11 +51,7 @@ struct INativeWindow : virtual INativeResource {
virtual IEvent<NativeMouseButtonEventArgs>* MouseUpEvent() = 0;
virtual IEvent<NativeKeyEventArgs>* KeyDownEvent() = 0;
virtual IEvent<NativeKeyEventArgs>* KeyUpEvent() = 0;
-};
-// See INativeWindow for more info.
-struct INativeWindowResolver : virtual INativeResource {
- // Think twice before you save the return value.
- virtual INativeWindow* Resolve() = 0;
+ virtual IInputMethodContext* GetInputMethodContext() = 0;
};
} // namespace cru::platform::native
diff --git a/include/cru/ui/WindowHost.hpp b/include/cru/ui/WindowHost.hpp
index 64116590..83ef2f64 100644
--- a/include/cru/ui/WindowHost.hpp
+++ b/include/cru/ui/WindowHost.hpp
@@ -8,30 +8,6 @@
namespace cru::ui {
struct AfterLayoutEventArgs {};
-
-// The host of all controls and render objects.
-//
-// 3 situations on destroy:
-// 1. Native window destroyed, IsRetainAfterDestroy: false:
-// OnNativeDestroy(set native_window_destroyed_ to true, call ~Window due to
-// deleting_ is false and IsRetainAfterDestroy is false) -> ~Window ->
-// ~WindowHost(not destroy native window repeatedly due to native_window_destroyed_
-// is true)
-// 2. Native window destroyed, IsRetainAfterDestroy: true:
-// OnNativeDestroy(set native_window_destroyed_ to true, not call ~Window
-// because deleting_ is false and IsRetainAfterDestroy is true)
-// then, ~Window -> ~WindowHost(not destroy native window repeatedly due to
-// native_window_destroyed_ is true)
-// 3. Native window not destroyed, ~Window is called:
-// ~Window -> ~WindowHost(set deleting_ to true, destroy native window
-// due to native_window_destroyed is false) -> OnNativeDestroy(not call ~Window
-// due to deleting_ is true and IsRetainAfterDestroy is whatever)
-// In conclusion:
-// 1. Set native_window_destroyed_ to true at the beginning of OnNativeDestroy.
-// 2. Set deleting_ to true at the beginning of ~WindowHost.
-// 3. Destroy native window when native_window_destroy_ is false in ~Window.
-// 4. Delete Window when deleting_ is false and IsRetainAfterDestroy is false in
-// OnNativeDestroy.
class WindowHost : public Object, public SelfResolvable<WindowHost> {
CRU_DEFINE_CLASS_LOG_TAG(u"cru::ui::WindowHost")
diff --git a/include/cru/win/native/Base.hpp b/include/cru/win/native/Base.hpp
index 7ddc6b54..881dd8b1 100644
--- a/include/cru/win/native/Base.hpp
+++ b/include/cru/win/native/Base.hpp
@@ -11,8 +11,6 @@ class WinCursorManager;
class WindowClass;
class WindowManager;
class WinNativeWindow;
-class WinNativeWindowResolver;
class WinUiApplication;
-class WinInputMethodManager;
-class WinInputMethodContextRef;
+class WinInputMethodContext;
} // namespace cru::platform::native::win
diff --git a/include/cru/win/native/InputMethod.hpp b/include/cru/win/native/InputMethod.hpp
index 113f460d..f3dc15c0 100644
--- a/include/cru/win/native/InputMethod.hpp
+++ b/include/cru/win/native/InputMethod.hpp
@@ -72,31 +72,16 @@ class WinInputMethodContext : public WinNativeResource,
std::u16string GetResultString();
- std::optional<AutoHIMC> TryGetHIMC();
+ AutoHIMC GetHIMC();
private:
- std::shared_ptr<INativeWindowResolver> native_window_resolver_;
+ WinNativeWindow* native_window_;
- std::vector<EventRevokerGuard> event_revoker_guards_;
+ EventRevokerListGuard event_guard_;
Event<std::nullptr_t> composition_start_event_;
Event<std::nullptr_t> composition_end_event_;
Event<std::nullptr_t> composition_event_;
Event<std::u16string_view> text_event_;
};
-
-class WinInputMethodManager : public WinNativeResource,
- public virtual IInputMethodManager {
- public:
- WinInputMethodManager(WinUiApplication* application);
-
- CRU_DELETE_COPY(WinInputMethodManager)
- CRU_DELETE_MOVE(WinInputMethodManager)
-
- ~WinInputMethodManager() override;
-
- public:
- std::unique_ptr<IInputMethodContext> GetContext(
- INativeWindow* window) override;
-};
} // namespace cru::platform::native::win
diff --git a/include/cru/win/native/UiApplication.hpp b/include/cru/win/native/UiApplication.hpp
index 328a6b84..170be532 100644
--- a/include/cru/win/native/UiApplication.hpp
+++ b/include/cru/win/native/UiApplication.hpp
@@ -1,6 +1,7 @@
#pragma once
#include "Resource.hpp"
+#include "cru/platform/native/Base.hpp"
#include "cru/platform/native/UiApplication.hpp"
#include <memory>
@@ -40,8 +41,7 @@ class WinUiApplication : public WinNativeResource,
void CancelTimer(long long id) override;
std::vector<INativeWindow*> GetAllWindow() override;
- std::shared_ptr<INativeWindowResolver> CreateWindow(
- INativeWindow* parent) override;
+ INativeWindow* CreateWindow(INativeWindow* parent) override;
cru::platform::graph::IGraphFactory* GetGraphFactory() override;
@@ -50,7 +50,6 @@ class WinUiApplication : public WinNativeResource,
}
ICursorManager* GetCursorManager() override;
- IInputMethodManager* GetInputMethodManager() override;
HINSTANCE GetInstanceHandle() const { return instance_handle_; }
@@ -69,7 +68,6 @@ class WinUiApplication : public WinNativeResource,
std::unique_ptr<WindowManager> window_manager_;
std::unique_ptr<WinCursorManager> cursor_manager_;
- std::unique_ptr<WinInputMethodManager> input_method_manager_;
std::vector<std::function<void()>> quit_handlers_;
};
diff --git a/include/cru/win/native/Window.hpp b/include/cru/win/native/Window.hpp
index ecc0dd04..6bf71601 100644
--- a/include/cru/win/native/Window.hpp
+++ b/include/cru/win/native/Window.hpp
@@ -3,6 +3,7 @@
#include "WindowNativeMessageEventArgs.hpp"
#include "cru/platform/GraphBase.hpp"
+#include "cru/platform/native/Base.hpp"
#include "cru/platform/native/Window.hpp"
#include "cru/win/graph/direct/WindowRenderTarget.hpp"
@@ -22,10 +23,6 @@ class WinNativeWindow : public WinNativeResource, public virtual INativeWindow {
~WinNativeWindow() override;
public:
- std::shared_ptr<INativeWindowResolver> GetResolver() override {
- return std::static_pointer_cast<INativeWindowResolver>(resolver_);
- }
-
void Close() override;
WinNativeWindow* GetParent() override { return parent_window_; }
@@ -81,6 +78,8 @@ class WinNativeWindow : public WinNativeResource, public virtual INativeWindow {
return &native_message_event_;
}
+ IInputMethodContext* GetInputMethodContext() override;
+
// Get the handle of the window. Return null if window is invalid.
HWND GetWindowHandle() const { return hwnd_; }
@@ -148,8 +147,6 @@ class WinNativeWindow : public WinNativeResource, public virtual INativeWindow {
// again.
bool sync_flag_ = false;
- std::shared_ptr<WinNativeWindowResolver> resolver_;
-
HWND hwnd_;
WinNativeWindow* parent_window_;
@@ -163,6 +160,8 @@ class WinNativeWindow : public WinNativeResource, public virtual INativeWindow {
std::shared_ptr<WinCursor> cursor_;
+ std::unique_ptr<WinInputMethodContext> input_method_context_;
+
Event<std::nullptr_t> destroy_event_;
Event<std::nullptr_t> paint_event_;
Event<Size> resize_event_;
@@ -176,28 +175,4 @@ class WinNativeWindow : public WinNativeResource, public virtual INativeWindow {
Event<WindowNativeMessageEventArgs&> native_message_event_;
};
-
-class WinNativeWindowResolver : public WinNativeResource,
- public virtual INativeWindowResolver {
- friend WinNativeWindow::~WinNativeWindow();
-
- public:
- WinNativeWindowResolver(WinNativeWindow* window) : window_(window) {}
-
- CRU_DELETE_COPY(WinNativeWindowResolver)
- CRU_DELETE_MOVE(WinNativeWindowResolver)
-
- ~WinNativeWindowResolver() override = default;
-
- public:
- INativeWindow* Resolve() override { return window_; }
-
- private:
- void Reset();
-
- private:
- WinNativeWindow* window_;
-};
-
-WinNativeWindow* Resolve(gsl::not_null<INativeWindowResolver*> resolver);
} // namespace cru::platform::native::win
diff --git a/src/win/native/InputMethod.cpp b/src/win/native/InputMethod.cpp
index d976a8ba..45c5f8da 100644
--- a/src/win/native/InputMethod.cpp
+++ b/src/win/native/InputMethod.cpp
@@ -145,30 +145,23 @@ CompositionText GetCompositionInfo(HIMC imm_context) {
WinInputMethodContext::WinInputMethodContext(
gsl::not_null<WinNativeWindow*> window)
- : native_window_resolver_(window->GetResolver()) {
- event_revoker_guards_.push_back(
- EventRevokerGuard(window->NativeMessageEvent()->AddHandler(
- std::bind(&WinInputMethodContext::OnWindowNativeMessage, this,
- std::placeholders::_1))));
+ : native_window_(window) {
+ event_guard_ += window->NativeMessageEvent()->AddHandler(
+ std::bind(&WinInputMethodContext::OnWindowNativeMessage, this,
+ std::placeholders::_1));
}
WinInputMethodContext::~WinInputMethodContext() {}
void WinInputMethodContext::EnableIME() {
- const auto native_window = Resolve(native_window_resolver_.get());
- if (native_window == nullptr) return;
- const auto hwnd = native_window->GetWindowHandle();
-
+ const auto hwnd = native_window_->GetWindowHandle();
if (::ImmAssociateContextEx(hwnd, nullptr, IACE_DEFAULT) == FALSE) {
log::TagWarn(log_tag, u"Failed to enable ime.");
}
}
void WinInputMethodContext::DisableIME() {
- const auto native_window = Resolve(native_window_resolver_.get());
- if (native_window == nullptr) return;
- const auto hwnd = native_window->GetWindowHandle();
-
+ const auto hwnd = native_window_->GetWindowHandle();
AutoHIMC himc{hwnd};
if (!::ImmNotifyIME(himc.Get(), NI_COMPOSITIONSTR, CPS_COMPLETE, 0)) {
@@ -182,46 +175,32 @@ void WinInputMethodContext::DisableIME() {
}
void WinInputMethodContext::CompleteComposition() {
- auto optional_himc = TryGetHIMC();
- if (!optional_himc.has_value()) return;
- auto himc = *std::move(optional_himc);
-
+ auto himc = GetHIMC();
if (!::ImmNotifyIME(himc.Get(), NI_COMPOSITIONSTR, CPS_COMPLETE, 0)) {
log::TagWarn(log_tag, u"Failed to complete composition.");
}
}
void WinInputMethodContext::CancelComposition() {
- auto optional_himc = TryGetHIMC();
- if (!optional_himc.has_value()) return;
- auto himc = *std::move(optional_himc);
-
+ auto himc = GetHIMC();
if (!::ImmNotifyIME(himc.Get(), NI_COMPOSITIONSTR, CPS_CANCEL, 0)) {
log::TagWarn(log_tag, u"Failed to complete composition.");
}
}
CompositionText WinInputMethodContext::GetCompositionText() {
- auto optional_himc = TryGetHIMC();
- if (!optional_himc.has_value()) return CompositionText{};
- auto himc = *std::move(optional_himc);
-
+ auto himc = GetHIMC();
return GetCompositionInfo(himc.Get());
}
void WinInputMethodContext::SetCandidateWindowPosition(const Point& point) {
- auto optional_himc = TryGetHIMC();
- if (!optional_himc.has_value()) return;
- auto himc = *std::move(optional_himc);
+ auto himc = GetHIMC();
::CANDIDATEFORM form;
form.dwIndex = 1;
form.dwStyle = CFS_CANDIDATEPOS;
- auto window =
- dynamic_cast<WinNativeWindow*>(this->native_window_resolver_->Resolve());
- form.ptCurrentPos =
- window == nullptr ? POINT{0, 0} : window->DipToPixel(point);
+ form.ptCurrentPos = native_window_->DipToPixel(point);
if (!::ImmSetCandidateWindow(himc.Get(), &form))
log::TagDebug(log_tag,
@@ -287,29 +266,13 @@ void WinInputMethodContext::OnWindowNativeMessage(
}
std::u16string WinInputMethodContext::GetResultString() {
- auto optional_himc = TryGetHIMC();
- if (!optional_himc.has_value()) return u"";
- auto himc = *std::move(optional_himc);
-
+ auto himc = GetHIMC();
auto result = win::GetResultString(himc.Get());
return result;
}
-std::optional<AutoHIMC> WinInputMethodContext::TryGetHIMC() {
- const auto native_window = Resolve(native_window_resolver_.get());
- if (native_window == nullptr) return std::nullopt;
- const auto hwnd = native_window->GetWindowHandle();
+AutoHIMC WinInputMethodContext::GetHIMC() {
+ const auto hwnd = native_window_->GetWindowHandle();
return AutoHIMC{hwnd};
}
-
-WinInputMethodManager::WinInputMethodManager(WinUiApplication*) {}
-
-WinInputMethodManager::~WinInputMethodManager() {}
-
-std::unique_ptr<IInputMethodContext> WinInputMethodManager::GetContext(
- INativeWindow* window) {
- Expects(window);
- const auto w = CheckPlatform<WinNativeWindow>(window, GetPlatformId());
- return std::make_unique<WinInputMethodContext>(w);
-}
} // namespace cru::platform::native::win
diff --git a/src/win/native/UiApplication.cpp b/src/win/native/UiApplication.cpp
index 3f7a0cf5..60ff8e8c 100644
--- a/src/win/native/UiApplication.cpp
+++ b/src/win/native/UiApplication.cpp
@@ -100,15 +100,13 @@ std::vector<INativeWindow*> WinUiApplication::GetAllWindow() {
return result;
}
-std::shared_ptr<INativeWindowResolver> WinUiApplication::CreateWindow(
- INativeWindow* parent) {
+INativeWindow* WinUiApplication::CreateWindow(INativeWindow* parent) {
WinNativeWindow* p = nullptr;
if (parent != nullptr) {
p = CheckPlatform<WinNativeWindow>(parent, GetPlatformId());
}
- return (new WinNativeWindow(this, window_manager_->GetGeneralWindowClass(),
- WS_OVERLAPPEDWINDOW, p))
- ->GetResolver();
+ return new WinNativeWindow(this, window_manager_->GetGeneralWindowClass(),
+ WS_OVERLAPPEDWINDOW, p);
}
cru::platform::graph::IGraphFactory* WinUiApplication::GetGraphFactory() {
diff --git a/src/win/native/Window.cpp b/src/win/native/Window.cpp
index 735221ca..d9237c4f 100644
--- a/src/win/native/Window.cpp
+++ b/src/win/native/Window.cpp
@@ -3,23 +3,24 @@
#include "WindowManager.hpp"
#include "cru/common/Logger.hpp"
#include "cru/platform/Check.hpp"
+#include "cru/platform/native/Base.hpp"
#include "cru/win/graph/direct/WindowPainter.hpp"
#include "cru/win/native/Cursor.hpp"
#include "cru/win/native/Exception.hpp"
+#include "cru/win/native/InputMethod.hpp"
#include "cru/win/native/Keyboard.hpp"
#include "cru/win/native/UiApplication.hpp"
#include "cru/win/native/WindowClass.hpp"
#include <imm.h>
#include <windowsx.h>
+#include <memory>
namespace cru::platform::native::win {
WinNativeWindow::WinNativeWindow(WinUiApplication* application,
WindowClass* window_class, DWORD window_style,
WinNativeWindow* parent)
- : application_(application),
- resolver_(std::make_shared<WinNativeWindowResolver>(this)),
- parent_window_(parent) {
+ : application_(application), parent_window_(parent) {
Expects(application); // application can't be null.
if (parent != nullptr) {
@@ -52,6 +53,8 @@ WinNativeWindow::WinNativeWindow(WinUiApplication* application,
std::make_unique<graph::win::direct::D2DWindowRenderTarget>(
application->GetDirectFactory(), hwnd_);
window_render_target_->SetDpi(dpi_, dpi_);
+
+ input_method_context_ = std::make_unique<WinInputMethodContext>(this);
}
WinNativeWindow::~WinNativeWindow() {
@@ -59,7 +62,6 @@ WinNativeWindow::~WinNativeWindow() {
sync_flag_ = true;
Close();
}
- resolver_->Reset();
}
void WinNativeWindow::Close() { ::DestroyWindow(hwnd_); }
@@ -197,6 +199,10 @@ void WinNativeWindow::SetCursor(std::shared_ptr<ICursor> cursor) {
}
}
+IInputMethodContext* WinNativeWindow::GetInputMethodContext() {
+ return static_cast<IInputMethodContext*>(input_method_context_.get());
+}
+
bool WinNativeWindow::HandleNativeWindowMessage(HWND hwnd, UINT msg,
WPARAM w_param, LPARAM l_param,
LRESULT* result) {
@@ -443,16 +449,4 @@ void WinNativeWindow::OnKeyUpInternal(int virtual_code) {
void WinNativeWindow::OnActivatedInternal() {}
void WinNativeWindow::OnDeactivatedInternal() {}
-
-void WinNativeWindowResolver::Reset() {
- Expects(window_); // already reset, can't reset again
- window_ = nullptr;
-}
-
-WinNativeWindow* Resolve(gsl::not_null<INativeWindowResolver*> resolver) {
- const auto window = resolver->Resolve();
- return window == nullptr ? nullptr
- : CheckPlatform<WinNativeWindow>(
- window, WinNativeResource::k_platform_id);
-} // namespace cru::platform::native::win
} // namespace cru::platform::native::win