aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/cru/common/event.hpp56
-rw-r--r--include/cru/platform/native_window.hpp8
-rw-r--r--include/cru/platform/painter.hpp1
-rw-r--r--include/cru/platform/win/win_native_window.hpp16
-rw-r--r--include/cru/platform/win/win_painter.hpp1
-rw-r--r--include/cru/ui/window.hpp23
-rw-r--r--src/platform_win/win_native_window.cpp6
-rw-r--r--src/platform_win/win_painter.cpp5
-rw-r--r--src/ui/window.cpp146
9 files changed, 117 insertions, 145 deletions
diff --git a/include/cru/common/event.hpp b/include/cru/common/event.hpp
index ce014fb8..52d75a7b 100644
--- a/include/cru/common/event.hpp
+++ b/include/cru/common/event.hpp
@@ -3,33 +3,65 @@
#include <functional>
#include <map>
+#include <memory>
#include <utility>
namespace cru {
+using EventHandlerRevoker = std::function<void()>;
+
// A non-copyable non-movable Event class.
// It stores a list of event handlers.
template <typename... TArgs>
class Event {
+ private:
+ using EventResolver = std::function<Event*()>;
+ class EventHandlerRevokerImpl {
+ public:
+ EventHandlerRevokerImpl(const std::shared_ptr<EventResolver>& resolver,
+ long token)
+ : resolver_(resolver), token_(token) {}
+ EventHandlerRevokerImpl(const EventHandlerRevokerImpl& other) = default;
+ EventHandlerRevokerImpl(EventHandlerRevokerImpl&& other) = default;
+ EventHandlerRevokerImpl& operator=(EventHandlerRevokerImpl&& other) =
+ default;
+ EventHandlerRevokerImpl& operator=(EventHandlerRevokerImpl&& other) =
+ default;
+ ~EventHandlerRevokerImpl() = default;
+
+ void operator()() {
+ const auto true_resolver = resolver_.lock();
+ if (true_resolver) {
+ true_resolver()->RemoveHandler(token_);
+ }
+ }
+
+ private:
+ std::weak_ptr<EventResolver> resolver_;
+ long token_;
+ };
+
public:
using EventHandler = std::function<void(TArgs...)>;
- using EventHandlerToken = long;
- Event() = default;
+ Event()
+ : event_resolver_(new std::function<Event*()>([this] { return this; })) {}
Event(const Event&) = delete;
Event& operator=(const Event&) = delete;
Event(Event&&) = delete;
Event& operator=(Event&&) = delete;
~Event() = default;
- EventHandlerToken AddHandler(const EventHandler& handler) {
+ EventHandlerRevoker AddHandler(const EventHandler& handler) {
const auto token = current_token_++;
handlers_.emplace(token, handler);
- return token;
+ return EventHandlerRevoker(EventHandlerRevokerImpl(event_resolver_, token));
}
- void RemoveHandler(const EventHandlerToken token) {
- auto find_result = handlers_.find(token);
- if (find_result != handlers_.cend()) handlers_.erase(find_result);
+ template <typename... Args>
+ EventHandlerRevoker AddHandler(Args&& args...) {
+ const auto token = current_token_++;
+ handlers_.emplace(token, EventHandler(std::forward<Args>(args)...));
+ return EventHandlerRevoker(EventHandlerRevokerImpl(event_resolver_, token));
}
template <typename... Args>
@@ -39,8 +71,14 @@ class Event {
}
private:
- std::map<EventHandlerToken, EventHandler> handlers_;
+ void RemoveHandler(const long token) {
+ auto find_result = handlers_.find(token);
+ if (find_result != handlers_.cend()) handlers_.erase(find_result);
+ }
- EventHandlerToken current_token_ = 0;
+ private:
+ std::map<long, EventHandler> handlers_{};
+ long current_token_ = 0;
+ std::shared_ptr<EventResolver> event_resolver_;
};
} // namespace cru
diff --git a/include/cru/platform/native_window.hpp b/include/cru/platform/native_window.hpp
index 2daf4870..f68fd3a4 100644
--- a/include/cru/platform/native_window.hpp
+++ b/include/cru/platform/native_window.hpp
@@ -35,13 +35,13 @@ struct NativeWindow : public virtual Interface {
virtual Painter* BeginPaint() = 0;
virtual Event<>* DestroyEvent() = 0;
- virtual Event<ui::Size>* ResizeEvent() = 0;
+ virtual Event<const ui::Size&>* ResizeEvent() = 0;
virtual Event<>* PaintEvent() = 0;
virtual Event<bool>* FocusEvent() = 0;
virtual Event<bool>* MouseEnterLeaveEvent() = 0;
- virtual Event<ui::Point>* MouseMoveEvent() = 0;
- virtual Event<MouseButton, ui::Point>* MouseDownEvent() = 0;
- virtual Event<MouseButton, ui::Point>* MouseUpEvent() = 0;
+ virtual Event<const ui::Point&>* MouseMoveEvent() = 0;
+ virtual Event<MouseButton, const ui::Point&>* MouseDownEvent() = 0;
+ virtual Event<MouseButton, const ui::Point&>* MouseUpEvent() = 0;
virtual Event<int>* KeyDownEvent() = 0;
virtual Event<int>* KeyUpEvent() = 0;
};
diff --git a/include/cru/platform/painter.hpp b/include/cru/platform/painter.hpp
index 7310bc5c..eaaf61f9 100644
--- a/include/cru/platform/painter.hpp
+++ b/include/cru/platform/painter.hpp
@@ -12,6 +12,7 @@ struct TextLayout;
struct Painter : virtual Interface {
virtual Matrix GetTransform() = 0;
virtual void SetTransform(const Matrix& matrix) = 0;
+ virtual void Clear(const ui::Color& color) = 0;
virtual void StrokeRectangle(const ui::Rect& rectangle, Brush* brush,
float width) = 0;
virtual void FillRectangle(const ui::Rect& rectangle, Brush* brush) = 0;
diff --git a/include/cru/platform/win/win_native_window.hpp b/include/cru/platform/win/win_native_window.hpp
index ae19c9f3..7b93fd5c 100644
--- a/include/cru/platform/win/win_native_window.hpp
+++ b/include/cru/platform/win/win_native_window.hpp
@@ -47,17 +47,17 @@ class WinNativeWindow : public Object, public virtual NativeWindow {
Painter* BeginPaint() override;
Event<>* DestroyEvent() override { return &destroy_event_; }
- Event<ui::Size>* ResizeEvent() override { return &resize_event_; }
+ Event<const ui::Size&>* ResizeEvent() override { return &resize_event_; }
Event<>* PaintEvent() override { return &paint_event_; }
Event<bool>* FocusEvent() override { return &focus_event_; }
Event<bool>* MouseEnterLeaveEvent() override {
return &mouse_enter_leave_event_;
}
- Event<ui::Point>* MouseMoveEvent() override { return &mouse_move_event_; }
- Event<MouseButton, ui::Point>* MouseDownEvent() override {
+ Event<const ui::Point&>* MouseMoveEvent() override { return &mouse_move_event_; }
+ Event<MouseButton, const ui::Point&>* MouseDownEvent() override {
return &mouse_down_event_;
}
- Event<MouseButton, ui::Point>* MouseUpEvent() override {
+ Event<MouseButton, const ui::Point&>* MouseUpEvent() override {
return &mouse_up_event_;
}
Event<int>* KeyDownEvent() override { return &key_down_event_; }
@@ -117,13 +117,13 @@ class WinNativeWindow : public Object, public virtual NativeWindow {
std::shared_ptr<WindowRenderTarget> window_render_target_;
Event<> destroy_event_;
- Event<ui::Size> resize_event_;
+ Event<const ui::Size&> resize_event_;
Event<> paint_event_;
Event<bool> focus_event_;
Event<bool> mouse_enter_leave_event_;
- Event<ui::Point> mouse_move_event_;
- Event<MouseButton, ui::Point> mouse_down_event_;
- Event<MouseButton, ui::Point> mouse_up_event_;
+ Event<const ui::Point&> mouse_move_event_;
+ Event<MouseButton, const ui::Point&> mouse_down_event_;
+ Event<MouseButton, const ui::Point&> mouse_up_event_;
Event<int> key_down_event_;
Event<int> key_up_event_;
diff --git a/include/cru/platform/win/win_painter.hpp b/include/cru/platform/win/win_painter.hpp
index dfb981d5..3c37ccb2 100644
--- a/include/cru/platform/win/win_painter.hpp
+++ b/include/cru/platform/win/win_painter.hpp
@@ -17,6 +17,7 @@ class WinPainter : public Object, public virtual Painter {
Matrix GetTransform() override;
void SetTransform(const Matrix& matrix) override;
+ void Clear(const ui::Color& color) override;
void StrokeRectangle(const ui::Rect& rectangle, Brush* brush,
float width) override;
void FillRectangle(const ui::Rect& rectangle, Brush* brush) override;
diff --git a/include/cru/ui/window.hpp b/include/cru/ui/window.hpp
index 043aae35..f0c790be 100644
--- a/include/cru/ui/window.hpp
+++ b/include/cru/ui/window.hpp
@@ -60,23 +60,18 @@ class Window final : public ContentControl {
void OnNativeDestroy();
void OnNativePaint();
- void OnNativeResize(float new_width, float new_height);
+ void OnNativeResize(const Size& size);
- void OnSetFocusInternal();
- void OnKillFocusInternal();
+ void OnNativeFocus(bool focus);
- void OnMouseMoveInternal(POINT point);
- void OnMouseLeaveInternal();
- void OnMouseDownInternal(MouseButton button, POINT point);
- void OnMouseUpInternal(MouseButton button, POINT point);
+ void OnNativeMouseMove(const Point& point);
+ void OnNativeMouseLeave();
+ void OnNativeMouseDown(platform::MouseButton button, const Point& point);
+ void OnNativeMouseUp(platform::MouseButton button, const Point& point);
- void OnMouseWheelInternal(short delta, POINT point);
- void OnKeyDownInternal(int virtual_code);
- void OnKeyUpInternal(int virtual_code);
- void OnCharInternal(wchar_t c);
+ void OnNativeKeyDown(int virtual_code);
+ void OnNativeKeyUp(int virtual_code);
- void OnActivatedInternal();
- void OnDeactivatedInternal();
//*************** region: event dispatcher helper ***************
@@ -86,7 +81,7 @@ class Window final : public ContentControl {
private:
platform::NativeWindow* native_window_;
- std::vector<EventHandlerToken> revoke_tokens_;
+ std::vector<EventHandlerRevoker> event_revokers_;
std::shared_ptr<render::WindowRenderObject> render_object_;
diff --git a/src/platform_win/win_native_window.cpp b/src/platform_win/win_native_window.cpp
index ae740205..12c25674 100644
--- a/src/platform_win/win_native_window.cpp
+++ b/src/platform_win/win_native_window.cpp
@@ -4,6 +4,7 @@
#include "cru/platform/win/win_application.hpp"
#include "cru/platform/win/win_painter.hpp"
#include "cru/platform/win/window_class.hpp"
+#include "cru/platform/win/window_render_target.hpp"
#include "dpi_util.hpp"
#include "window_manager.hpp"
@@ -258,10 +259,11 @@ void WinNativeWindow::OnPaintInternal() {
void WinNativeWindow::OnResizeInternal(const int new_width,
const int new_height) {
- // render_target_->ResizeBuffer(new_width, new_height);
- if (!(new_width == 0 && new_height == 0))
+ if (!(new_width == 0 && new_height == 0)) {
+ window_render_target_->ResizeBuffer(new_width, new_height);
resize_event_.Raise(
ui::Size{PixelToDipX(new_width), PixelToDipY(new_height)});
+ }
}
void WinNativeWindow::OnSetFocusInternal() {
diff --git a/src/platform_win/win_painter.cpp b/src/platform_win/win_painter.cpp
index b648f97d..6ce5f4de 100644
--- a/src/platform_win/win_painter.cpp
+++ b/src/platform_win/win_painter.cpp
@@ -40,6 +40,11 @@ void WinPainter::SetTransform(const Matrix& matrix) {
render_target_->SetTransform(util::Convert(matrix));
}
+void WinPainter::Clear(const ui::Color& color) {
+ assert(!IsDisposed());
+ render_target_->Clear(util::Convert(color));
+}
+
void WinPainter::StrokeRectangle(const ui::Rect& rectangle, Brush* brush,
float width) {
assert(!IsDisposed());
diff --git a/src/ui/window.cpp b/src/ui/window.cpp
index 1065a3fb..bad704ae 100644
--- a/src/ui/window.cpp
+++ b/src/ui/window.cpp
@@ -1,8 +1,9 @@
#include "cru/ui/window.hpp"
-#include "cru/ui/render/window_render_object.hpp"
-#include "cru/platform/ui_applicaition.hpp"
#include "cru/platform/native_window.hpp"
+#include "cru/platform/painter.hpp"
+#include "cru/platform/ui_applicaition.hpp"
+#include "cru/ui/render/window_render_object.hpp"
#include <cassert>
@@ -97,10 +98,16 @@ Window* Window::CreateOverlapped() {
return new Window(tag_overlapped_constructor{});
}
-
Window::Window(tag_overlapped_constructor) {
- native_window_ = platform::UiApplication::GetInstance()->CreateWindow(nullptr);
+ native_window_ =
+ platform::UiApplication::GetInstance()->CreateWindow(nullptr);
render_object_.reset(new render::WindowRenderObject(this));
+
+ event_revokers_.push_back(native_window_->DestroyEvent()->AddHandler(
+ this, Window::OnNativeDestroy));
+ event_revokers_.push_back(
+ native_window_->PaintEvent()->AddHandler(this, Window::OnNativePaint));
+ //TODO
}
Window::~Window() {
@@ -143,135 +150,58 @@ Control* Window::HitTest(const Point& point) {
void Window::OnNativeDestroy() { delete this; }
void Window::OnNativePaint() {
- render_target_->SetAsTarget();
-
- auto device_context =
- render_target_->GetGraphManager()->GetD2D1DeviceContext();
- device_context->BeginDraw();
- // Clear the background.
- device_context->Clear(D2D1::ColorF(D2D1::ColorF::White));
- render_object_->Draw(device_context);
- ThrowIfFailed(device_context->EndDraw(), "Failed to draw window.");
- render_target_->Present();
-
- ValidateRect(hwnd_, nullptr);
-}
-
-void Window::OnResizeInternal(const int new_width, const int new_height) {
- render_target_->ResizeBuffer(new_width, new_height);
- if (!(new_width == 0 && new_height == 0)) render_object_->MeasureAndLayout();
+ const auto painter =
+ std::make_unique<platform::Painter>(native_window_->BeginPaint());
+ render_object_->Draw(painter.get());
+ painter->EndDraw();
}
-void Window::OnSetFocusInternal() {
- window_focus_ = true;
- DispatchEvent(focus_control_, &Control::GainFocusEvent, nullptr, true);
+void Window::OnNativeResize(const Size& size) {
+ render_object_->MeasureAndLayout();
}
-void Window::OnKillFocusInternal() {
- window_focus_ = false;
- DispatchEvent(focus_control_, &Control::LoseFocusEvent, nullptr, true);
+void Window::OnNativeFocus(bool focus) {
+ focus
+ ? DispatchEvent(focus_control_, &Control::GainFocusEvent, nullptr, true)
+ : DispatchEvent(focus_control_, &Control::LoseFocusEvent, nullptr, true);
}
-void Window::OnMouseMoveInternal(const POINT point) {
- const auto dip_point = PiToDip(point);
-
- // when mouse was previous outside the window
- if (mouse_hover_control_ == nullptr) {
- // invoke TrackMouseEvent to have WM_MOUSELEAVE sent.
- TRACKMOUSEEVENT tme;
- tme.cbSize = sizeof tme;
- tme.dwFlags = TME_LEAVE;
- tme.hwndTrack = hwnd_;
-
- TrackMouseEvent(&tme);
- }
-
+void Window::OnNativeMouseMove(const Point& point) {
// Find the first control that hit test succeed.
- const auto new_control_mouse_hover = HitTest(dip_point);
+ const auto new_control_mouse_hover = HitTest(point);
const auto old_control_mouse_hover = mouse_hover_control_;
mouse_hover_control_ = new_control_mouse_hover;
- if (mouse_capture_control_) // if mouse is captured
- {
- DispatchEvent(mouse_capture_control_, &Control::MouseMoveEvent, nullptr,
- dip_point);
- } else {
- DispatchMouseHoverControlChangeEvent(old_control_mouse_hover,
- new_control_mouse_hover, dip_point);
- DispatchEvent(new_control_mouse_hover, &Control::MouseMoveEvent, nullptr,
- dip_point);
- }
+ DispatchMouseHoverControlChangeEvent(old_control_mouse_hover,
+ new_control_mouse_hover, point);
+ DispatchEvent(new_control_mouse_hover, &Control::MouseMoveEvent, nullptr,
+ point);
}
-void Window::OnMouseLeaveInternal() {
+void Window::OnNativeMouseLeave() {
DispatchEvent(mouse_hover_control_, &Control::MouseLeaveEvent, nullptr);
mouse_hover_control_ = nullptr;
}
-void Window::OnMouseDownInternal(MouseButton button, POINT point) {
- const auto dip_point = PiToDip(point);
-
- Control* control;
-
- if (mouse_capture_control_)
- control = mouse_capture_control_;
- else
- control = HitTest(dip_point);
-
- DispatchEvent(control, &Control::MouseDownEvent, nullptr, dip_point,
- button);
+void Window::OnNativeMouseDown(platform::MouseButton button,
+ const Point& point) {
+ Control* control = HitTest(point);
+ DispatchEvent(control, &Control::MouseDownEvent, nullptr, point, button);
}
-void Window::OnMouseUpInternal(MouseButton button, POINT point) {
- const auto dip_point = PiToDip(point);
-
- Control* control;
-
- if (mouse_capture_control_)
- control = mouse_capture_control_;
- else
- control = HitTest(dip_point);
-
- DispatchEvent(control, &Control::MouseUpEvent, nullptr, dip_point, button);
+void Window::OnNativeMouseUp(platform::MouseButton button, const Point& point) {
+ Control* control = HitTest(point);
+ DispatchEvent(control, &Control::MouseUpEvent, nullptr, point, button);
}
-void Window::OnMouseWheelInternal(short delta, POINT point) {
- const auto dip_point = PiToDip(point);
-
- Control* control;
-
- if (mouse_capture_control_)
- control = mouse_capture_control_;
- else
- control = HitTest(dip_point);
-
- DispatchEvent(control, &Control::MouseWheelEvent, nullptr, dip_point,
- static_cast<float>(delta));
+void Window::OnNativeKeyDown(int virtual_code) {
+ DispatchEvent(focus_control_, &Control::KeyDownEvent, nullptr, virtual_code);
}
-void Window::OnKeyDownInternal(int virtual_code) {
- DispatchEvent(focus_control_, &Control::KeyDownEvent, nullptr,
- virtual_code);
-}
-
-void Window::OnKeyUpInternal(int virtual_code) {
+void Window::OnNativeKeyUp(int virtual_code) {
DispatchEvent(focus_control_, &Control::KeyUpEvent, nullptr, virtual_code);
}
-void Window::OnCharInternal(wchar_t c) {
- DispatchEvent(focus_control_, &Control::CharEvent, nullptr, c);
-}
-
-void Window::OnActivatedInternal() {
- events::UiEventArgs args(this, this);
- activated_event_.Raise(args);
-}
-
-void Window::OnDeactivatedInternal() {
- events::UiEventArgs args(this, this);
- deactivated_event_.Raise(args);
-}
-
void Window::DispatchMouseHoverControlChangeEvent(Control* old_control,
Control* new_control,
const Point& point) {