diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/ui/click_detector.cpp | 7 | ||||
-rw-r--r-- | src/ui/control.cpp | 19 | ||||
-rw-r--r-- | src/ui/controls/button.cpp | 84 | ||||
-rw-r--r-- | src/ui/controls/flex_layout.cpp | 5 | ||||
-rw-r--r-- | src/ui/controls/text_block.cpp | 1 | ||||
-rw-r--r-- | src/ui/render/border_render_object.cpp | 2 | ||||
-rw-r--r-- | src/ui/render/flex_layout_render_object.cpp | 2 | ||||
-rw-r--r-- | src/ui/render/window_render_object.cpp | 2 | ||||
-rw-r--r-- | src/ui/window.cpp | 8 | ||||
-rw-r--r-- | src/win/native/native_window.cpp | 9 |
10 files changed, 105 insertions, 34 deletions
diff --git a/src/ui/click_detector.cpp b/src/ui/click_detector.cpp index 1442b885..b335f3b5 100644 --- a/src/ui/click_detector.cpp +++ b/src/ui/click_detector.cpp @@ -12,8 +12,9 @@ ClickDetector::ClickDetector(Control* control) { EventRevokerGuard(control->MouseDownEvent()->Direct()->AddHandler( [this, control](event::MouseButtonEventArgs& args) { if (!control->CaptureMouse()) return; // capture failed - FromButton(args.GetMouseButton()) = - args.GetPoint(); // save mouse down point + const auto button = args.GetMouseButton(); + FromButton(button) = args.GetPoint(); // save mouse down point + begin_event_.Raise(button); }))); event_rovoker_guards_.push_front( @@ -25,8 +26,10 @@ ClickDetector::ClickDetector(Control* control) { if (down_point.has_value()) { event_.Raise(ClickEventArgs(control, down_point.value(), args.GetPoint(), button)); + end_event_.Raise(button); down_point = std::nullopt; } + control->ReleaseMouse(); }))); } } // namespace cru::ui diff --git a/src/ui/control.cpp b/src/ui/control.cpp index d529b687..7bd33d84 100644 --- a/src/ui/control.cpp +++ b/src/ui/control.cpp @@ -54,6 +54,7 @@ void Control::_TraverseDescendants( predicate(control); for (auto c : control->GetChildren()) _TraverseDescendants(c, predicate); } + bool Control::RequestFocus() { auto window = GetWindow(); if (window == nullptr) return false; @@ -68,15 +69,21 @@ bool Control::HasFocus() { return window->GetFocusControl() == this; } -void Control::OnParentChanged(Control* old_parent, Control* new_parent) {} +bool Control::CaptureMouse() { + return GetWindow()->CaptureMouseFor(this); +} -void Control::OnAttachToWindow(Window* window) {} +bool Control::ReleaseMouse() { + return GetWindow()->CaptureMouseFor(nullptr); +} -void Control::OnDetachToWindow(Window* window) {} +bool Control::IsMouseCaptured() { + return GetWindow()->GetMouseCaptureControl() == this; +} -void Control::OnMouseClickBegin(platform::native::MouseButton button) {} +void Control::OnParentChanged(Control* old_parent, Control* new_parent) {} -void Control::OnMouseClickEnd(platform::native::MouseButton button) {} +void Control::OnAttachToWindow(Window* window) {} -void Control::OnMouseClickCancel(platform::native::MouseButton button) {} +void Control::OnDetachToWindow(Window* window) {} } // namespace cru::ui diff --git a/src/ui/controls/button.cpp b/src/ui/controls/button.cpp index 618371fb..42a08e33 100644 --- a/src/ui/controls/button.cpp +++ b/src/ui/controls/button.cpp @@ -1,17 +1,60 @@ #include "cru/ui/controls/button.hpp" +#include <memory> +#include "cru/platform/graph/brush.hpp" +#include "cru/platform/graph/graph_factory.hpp" +#include "cru/platform/native/native_window.hpp" #include "cru/ui/render/border_render_object.hpp" #include "cru/ui/ui_manager.hpp" +#include "cru/ui/window.hpp" namespace cru::ui::controls { -Button::Button() { - const auto predefined_resource = - UiManager::GetInstance()->GetPredefineResources(); - render_object_.reset(new render::BorderRenderObject( - predefined_resource->button_normal_border_brush)); +Button::Button() : click_detector_(this) { + // const auto predefined_resource = + // UiManager::GetInstance()->GetPredefineResources(); + + const auto factory = platform::graph::GraphFactory::GetInstance(); + border_style_.normal.brush = std::shared_ptr<platform::graph::Brush>( + factory->CreateSolidColorBrush(Color::FromHex(0x00bfff))); + border_style_.hover.brush = std::shared_ptr<platform::graph::Brush>( + factory->CreateSolidColorBrush(Color::FromHex(0x47d1ff))); + border_style_.press.brush = std::shared_ptr<platform::graph::Brush>( + factory->CreateSolidColorBrush(Color::FromHex(0x91e4ff))); + + border_style_.normal.thickness = border_style_.hover.thickness = + border_style_.press.thickness = Thickness{3}; + + border_style_.normal.corner_radius = border_style_.hover.corner_radius = + border_style_.press.corner_radius = render::CornerRadius{Point{10, 5}}; + + render_object_.reset( + new render::BorderRenderObject(border_style_.normal.brush)); + render_object_->SetAttachedControl(this); render_object_->SetEnabled(true); - render_object_->SetBorderWidth(Thickness{3}); - render_object_->SetCornerRadius(render::CornerRadius{Point{10, 5}}); + render_object_->SetStyle(border_style_.normal); + + MouseEnterEvent()->Direct()->AddHandler([this](event::MouseEventArgs& args) { + if (click_detector_.GetPressingButton() & trigger_button_) { + SetState(ButtonState::Press); + } else { + SetState(ButtonState::Hover); + } + }); + + MouseLeaveEvent()->Direct()->AddHandler( + [this](event::MouseEventArgs& args) { SetState(ButtonState::Normal); }); + + click_detector_.ClickBeginEvent()->AddHandler([this](MouseButton button) { + if (button & trigger_button_) { + SetState(ButtonState::Press); + } + }); + + click_detector_.ClickEndEvent()->AddHandler([this](MouseButton button) { + if (button & trigger_button_) { + SetState(ButtonState::Normal); + } + }); } render::RenderObject* Button::GetRenderObject() const { @@ -24,21 +67,18 @@ void Button::OnChildChanged(Control* old_child, Control* new_child) { render_object_->AddChild(new_child->GetRenderObject(), 0); } -void Button::OnMouseClickBegin(platform::native::MouseButton button) { - if (button & trigger_button_) { - SetState(ButtonState::Press); - //TODO! - } -} - -void Button::OnMouseClickEnd(platform::native::MouseButton button) { - if (button & trigger_button_) { - SetState(ButtonState::Normal); - //TODO! - } -} - void Button::OnStateChange(ButtonState oldState, ButtonState newState) { - + switch (newState) { + case ButtonState::Normal: + render_object_->SetStyle(border_style_.normal); + break; + case ButtonState::Hover: + render_object_->SetStyle(border_style_.hover); + break; + case ButtonState::Press: + render_object_->SetStyle(border_style_.press); + break; + } + GetWindow()->GetNativeWindow()->Repaint(); } } // namespace cru::ui::controls diff --git a/src/ui/controls/flex_layout.cpp b/src/ui/controls/flex_layout.cpp index 3b70c98c..340710cc 100644 --- a/src/ui/controls/flex_layout.cpp +++ b/src/ui/controls/flex_layout.cpp @@ -5,7 +5,10 @@ namespace cru::ui::controls { using render::FlexLayoutRenderObject; -FlexLayout::FlexLayout() { render_object_.reset(new FlexLayoutRenderObject()); } +FlexLayout::FlexLayout() { + render_object_.reset(new FlexLayoutRenderObject()); + render_object_->SetAttachedControl(this); +} render::RenderObject* FlexLayout::GetRenderObject() const { return render_object_.get(); diff --git a/src/ui/controls/text_block.cpp b/src/ui/controls/text_block.cpp index 55d83acc..71903981 100644 --- a/src/ui/controls/text_block.cpp +++ b/src/ui/controls/text_block.cpp @@ -13,6 +13,7 @@ TextBlock::TextBlock() { new TextRenderObject(predefined_resources->text_block_text_brush, predefined_resources->text_block_font, predefined_resources->text_block_selection_brush)); + render_object_->SetAttachedControl(this); } render::RenderObject* TextBlock::GetRenderObject() const { diff --git a/src/ui/render/border_render_object.cpp b/src/ui/render/border_render_object.cpp index 1bec3e0b..4b61e511 100644 --- a/src/ui/render/border_render_object.cpp +++ b/src/ui/render/border_render_object.cpp @@ -30,7 +30,7 @@ RenderObject* BorderRenderObject::HitTest(const Point& point) { if (const auto child = GetChild()) { auto offset = child->GetOffset(); Point p{point.x - offset.x, point.y - offset.y}; - const auto result = child->HitTest(point); + const auto result = child->HitTest(p); if (result != nullptr) { return result; } diff --git a/src/ui/render/flex_layout_render_object.cpp b/src/ui/render/flex_layout_render_object.cpp index 8ce2db0a..5e313e49 100644 --- a/src/ui/render/flex_layout_render_object.cpp +++ b/src/ui/render/flex_layout_render_object.cpp @@ -29,7 +29,7 @@ RenderObject* FlexLayoutRenderObject::HitTest(const Point& point) { for (auto i = children.crbegin(); i != children.crend(); ++i) { auto offset = (*i)->GetOffset(); Point p{point.x - offset.x, point.y - offset.y}; - const auto result = (*i)->HitTest(point); + const auto result = (*i)->HitTest(p); if (result != nullptr) { return result; } diff --git a/src/ui/render/window_render_object.cpp b/src/ui/render/window_render_object.cpp index 89bb0beb..18faeee8 100644 --- a/src/ui/render/window_render_object.cpp +++ b/src/ui/render/window_render_object.cpp @@ -27,7 +27,7 @@ RenderObject* WindowRenderObject::HitTest(const Point& point) { if (const auto child = GetChild()) { auto offset = child->GetOffset(); Point p{point.x - offset.x, point.y - offset.y}; - const auto result = child->HitTest(point); + const auto result = child->HitTest(p); if (result != nullptr) { return result; } diff --git a/src/ui/window.cpp b/src/ui/window.cpp index 47509749..1ec34c1d 100644 --- a/src/ui/window.cpp +++ b/src/ui/window.cpp @@ -7,6 +7,7 @@ #include "routed_event_dispatch.hpp" #include <cassert> +#include <list> namespace cru::ui { namespace { @@ -54,6 +55,7 @@ Control* FindLowestCommonAncestor(Control* left, Control* right, *find_result = in_right; return result; } + ++right_i; } return result; } @@ -64,6 +66,7 @@ Control* FindLowestCommonAncestor(Control* left, Control* right, *find_result = in_left; return result; } + ++left_i; } return result; } @@ -75,13 +78,16 @@ Control* FindLowestCommonAncestor(Control* left, Control* right, *find_result = in_right; return result; } + ++right_i; } while (left_i != left_list.cend()) { if (*left_i == find_control) { *find_result = in_left; return result; } + ++left_i; } + return result; } ++left_i; ++right_i; @@ -107,9 +113,11 @@ Window::Window(tag_overlapped_constructor) : mouse_hover_control_(nullptr), focus_control_(this), mouse_captured_control_(nullptr) { + window_ = this; native_window_ = platform::native::UiApplication::GetInstance()->CreateWindow(nullptr); render_object_.reset(new render::WindowRenderObject(this)); + render_object_->SetAttachedControl(this); BindNativeEvent(this, native_window_->DestroyEvent(), &Window::OnNativeDestroy, event_revoker_guards_); diff --git a/src/win/native/native_window.cpp b/src/win/native/native_window.cpp index 5da121cf..f301f955 100644 --- a/src/win/native/native_window.cpp +++ b/src/win/native/native_window.cpp @@ -147,6 +147,15 @@ bool WinNativeWindow::ReleaseMouse() { return false; } +void WinNativeWindow::Repaint() { + if (IsValid()) { + if (!::InvalidateRect(hwnd_, nullptr, FALSE)) + throw Win32Error(::GetLastError(), "Failed to invalidate window."); + if (!::UpdateWindow(hwnd_)) + throw Win32Error(::GetLastError(), "Failed to update window."); + } +} + graph::Painter* WinNativeWindow::BeginPaint() { return new WindowD2DPainter(this); } |