From 93265251d56c91b05f160423077ce95339786f87 Mon Sep 17 00:00:00 2001 From: crupest Date: Fri, 30 Oct 2020 13:14:34 +0800 Subject: ... --- src/ui/host/LayoutPaintCycler.cpp | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 src/ui/host/LayoutPaintCycler.cpp (limited to 'src/ui/host/LayoutPaintCycler.cpp') diff --git a/src/ui/host/LayoutPaintCycler.cpp b/src/ui/host/LayoutPaintCycler.cpp new file mode 100644 index 00000000..9b319da4 --- /dev/null +++ b/src/ui/host/LayoutPaintCycler.cpp @@ -0,0 +1,35 @@ +#include "cru/ui/host/LayoutPaintCycler.hpp" +#include + +#include "../Helper.hpp" +#include "cru/ui/Base.hpp" +#include "cru/ui/host/WindowHost.hpp" + +namespace cru::ui::host { +LayoutPaintCycler::LayoutPaintCycler(WindowHost* host) : host_(host) { + timer_canceler_ = GetUiApplication()->SetInterval( + std::chrono::duration_cast( + this->cycle_threshold_), + [this] { OnCycle(); }); +} + +LayoutPaintCycler::~LayoutPaintCycler() = default; + +void LayoutPaintCycler::InvalidateLayout() { layout_dirty_ = true; } + +void LayoutPaintCycler::InvalidatePaint() { paint_dirty_ = true; } + +void LayoutPaintCycler::OnCycle() { + last_cycle_time_ = std::chrono::steady_clock::now(); + if (layout_dirty_) { + host_->Relayout(); + host_->Repaint(); + } else { + if (paint_dirty_) { + host_->Repaint(); + } + } + layout_dirty_ = true; + paint_dirty_ = true; +} +} // namespace cru::ui::host -- cgit v1.2.3 From 2d4a5df468f8bc13fbb657e010c393365ef79bda Mon Sep 17 00:00:00 2001 From: crupest Date: Tue, 10 Nov 2020 15:52:15 +0800 Subject: ... --- include/cru/platform/GraphBase.hpp | 6 ++++++ include/cru/platform/gui/InputMethod.hpp | 3 ++- include/cru/ui/DebugFlags.hpp | 2 +- src/ui/controls/TextBox.cpp | 2 -- src/ui/controls/TextControlService.hpp | 26 +++++++++++++++++++++++++- src/ui/host/LayoutPaintCycler.cpp | 4 ++-- src/win/gui/InputMethod.cpp | 2 +- 7 files changed, 37 insertions(+), 8 deletions(-) (limited to 'src/ui/host/LayoutPaintCycler.cpp') diff --git a/include/cru/platform/GraphBase.hpp b/include/cru/platform/GraphBase.hpp index 6700765e..2b40898e 100644 --- a/include/cru/platform/GraphBase.hpp +++ b/include/cru/platform/GraphBase.hpp @@ -22,6 +22,12 @@ struct Point final { return fmt::format(u"({}, {})", ToUtf16String(x), ToUtf16String(y)); } + constexpr Point& operator+=(const Point& other) { + this->x += other.x; + this->y += other.y; + return *this; + } + float x = 0; float y = 0; }; diff --git a/include/cru/platform/gui/InputMethod.hpp b/include/cru/platform/gui/InputMethod.hpp index 53a8d671..9d090eab 100644 --- a/include/cru/platform/gui/InputMethod.hpp +++ b/include/cru/platform/gui/InputMethod.hpp @@ -37,7 +37,8 @@ struct IInputMethodContext : virtual INativeResource { virtual CompositionText GetCompositionText() = 0; - // Set the candidate window lefttop. Use this method to prepare typing. + // Set the candidate window lefttop. Relative to window lefttop. Use this + // method to prepare typing. virtual void SetCandidateWindowPosition(const Point& point) = 0; // Triggered when user starts composition. diff --git a/include/cru/ui/DebugFlags.hpp b/include/cru/ui/DebugFlags.hpp index fceef081..7c600d48 100644 --- a/include/cru/ui/DebugFlags.hpp +++ b/include/cru/ui/DebugFlags.hpp @@ -4,5 +4,5 @@ namespace cru::ui::debug_flags { constexpr bool routed_event = false; constexpr bool layout = false; constexpr bool shortcut = false; -constexpr bool text_service = false; +constexpr bool text_service = true; } // namespace cru::ui::debug_flags diff --git a/src/ui/controls/TextBox.cpp b/src/ui/controls/TextBox.cpp index 4a8d6658..6ba6ecb2 100644 --- a/src/ui/controls/TextBox.cpp +++ b/src/ui/controls/TextBox.cpp @@ -10,9 +10,7 @@ namespace cru::ui::controls { using render::BorderRenderObject; -using render::CanvasRenderObject; using render::ScrollRenderObject; -using render::StackLayoutRenderObject; using render::TextRenderObject; TextBox::TextBox() diff --git a/src/ui/controls/TextControlService.hpp b/src/ui/controls/TextControlService.hpp index 92a66f5e..d50621ea 100644 --- a/src/ui/controls/TextControlService.hpp +++ b/src/ui/controls/TextControlService.hpp @@ -298,6 +298,24 @@ class TextControlService : public Object { selection.GetStart(), selection.GetEnd()); } + void UpdateInputMethodPosition() { + if (auto input_method_context = this->GetInputMethodContext()) { + Point right_bottom = + this->GetTextRenderObject()->GetTotalOffset() + + this->GetTextRenderObject()->GetCaretRect().GetRightBottom(); + right_bottom.x += 5; + right_bottom.y += 5; + + if constexpr (debug_flags::text_service) { + log::TagDebug(log_tag, + u"Calculate input method candidate window position: {}.", + right_bottom.ToDebugString()); + } + + input_method_context->SetCandidateWindowPosition(right_bottom); + } + } + template void SetupOneHandler(event::RoutedEvent* (Control::*event)(), void (TextControlService::*handler)( @@ -449,6 +467,12 @@ class TextControlService : public Object { if (text == u"\b") return; this->ReplaceSelectedText(text); }); + + host::WindowHost* window_host = control_->GetWindowHost(); + if (window_host) + input_method_context_event_guard_ += + window_host->AfterLayoutEvent()->AddHandler( + [this](auto) { this->UpdateInputMethodPosition(); }); } } @@ -481,5 +505,5 @@ class TextControlService : public Object { // nullopt means not selecting std::optional select_down_button_; -}; // namespace cru::ui::controls +}; } // namespace cru::ui::controls diff --git a/src/ui/host/LayoutPaintCycler.cpp b/src/ui/host/LayoutPaintCycler.cpp index 9b319da4..fd581e00 100644 --- a/src/ui/host/LayoutPaintCycler.cpp +++ b/src/ui/host/LayoutPaintCycler.cpp @@ -29,7 +29,7 @@ void LayoutPaintCycler::OnCycle() { host_->Repaint(); } } - layout_dirty_ = true; - paint_dirty_ = true; + layout_dirty_ = false; + paint_dirty_ = false; } } // namespace cru::ui::host diff --git a/src/win/gui/InputMethod.cpp b/src/win/gui/InputMethod.cpp index 492f1c2f..0ef9a403 100644 --- a/src/win/gui/InputMethod.cpp +++ b/src/win/gui/InputMethod.cpp @@ -198,7 +198,7 @@ void WinInputMethodContext::SetCandidateWindowPosition(const Point& point) { auto himc = GetHIMC(); ::CANDIDATEFORM form; - form.dwIndex = 1; + form.dwIndex = 0; form.dwStyle = CFS_CANDIDATEPOS; form.ptCurrentPos = native_window_->DipToPixel(point); -- cgit v1.2.3