diff options
author | crupest <crupest@outlook.com> | 2021-11-21 20:42:54 +0800 |
---|---|---|
committer | crupest <crupest@outlook.com> | 2021-11-21 20:42:54 +0800 |
commit | 3f8e493423b7cfe96ab53531078b803da7beccbe (patch) | |
tree | a0a998c6b2b696eaf4f58870224fef31e65e3dbd /src | |
parent | 73b90d4fe6c93a288ca6514432fe1e83ddcf4928 (diff) | |
download | cru-3f8e493423b7cfe96ab53531078b803da7beccbe.tar.gz cru-3f8e493423b7cfe96ab53531078b803da7beccbe.tar.bz2 cru-3f8e493423b7cfe96ab53531078b803da7beccbe.zip |
...
Diffstat (limited to 'src')
-rw-r--r-- | src/osx/graphics/quartz/TextLayout.cpp | 71 | ||||
-rw-r--r-- | src/osx/gui/InputMethod.mm | 4 | ||||
-rw-r--r-- | src/osx/gui/Window.mm | 22 | ||||
-rw-r--r-- | src/platform/graphics/CMakeLists.txt | 9 | ||||
-rw-r--r-- | src/platform/graphics/NullPainter.cpp | 1 | ||||
-rw-r--r-- | src/ui/controls/RootControl.cpp | 2 | ||||
-rw-r--r-- | src/ui/controls/TextHostControlService.cpp | 4 | ||||
-rw-r--r-- | src/ui/render/TextRenderObject.cpp | 10 |
8 files changed, 83 insertions, 40 deletions
diff --git a/src/osx/graphics/quartz/TextLayout.cpp b/src/osx/graphics/quartz/TextLayout.cpp index 8e5022a9..de14816d 100644 --- a/src/osx/graphics/quartz/TextLayout.cpp +++ b/src/osx/graphics/quartz/TextLayout.cpp @@ -112,6 +112,30 @@ void OsxCTTextLayout::SetEditMode(bool enable) { RecreateFrame(); } +Index OsxCTTextLayout::GetLineIndexFromCharIndex(Index char_index) { + if (char_index < 0 || char_index >= text_.size()) { + return -1; + } + + auto line_index = 0; + for (Index i = 0; i < char_index; ++i) { + if (text_[i] == u'\n') { + line_index++; + } + } + + return line_index; +} + +Index OsxCTTextLayout::GetLineCount() { return line_count_; } + +float OsxCTTextLayout::GetLineHeight(Index line_index) { + if (line_index < 0 || line_index >= line_count_) { + return 0.0f; + } + return line_heights_[line_index]; +} + Rect OsxCTTextLayout::GetTextBounds(bool includingTrailingSpace) { if (text_.empty() && edit_mode_) return Rect(0, 0, 0, font_->GetFontSize()); @@ -123,8 +147,10 @@ std::vector<Rect> OsxCTTextLayout::TextRangeRect(const TextRange& text_range) { if (text_.empty()) return {}; auto tr = text_range; - text_range.CoerceInto(head_empty_line_count_, - text_.size() - tail_empty_line_count_); + tr = text_range.CoerceInto(head_empty_line_count_, + text_.size() - tail_empty_line_count_); + tr.position -= head_empty_line_count_; + std::vector<CGRect> results = DoTextRangeRect(tr); std::vector<Rect> r; @@ -162,9 +188,9 @@ TextHitTestResult OsxCTTextLayout::HitTest(const Point& point) { if (point.y < 0) { return {0, false, false}; } else { - for (int i = 0; i < head_empty_line_count_; ++i) { + for (int i = 1; i <= head_empty_line_count_; ++i) { if (point.y < i * font_->GetFontSize()) { - return {i, false, false}; + return {i - 1, false, false}; } } } @@ -175,11 +201,12 @@ TextHitTestResult OsxCTTextLayout::HitTest(const Point& point) { auto text_height = static_cast<float>(text_bounds.size.height); auto th = text_height + head_empty_line_count_ * font_->GetFontSize(); if (point.y >= th) { - for (int i = 0; i < tail_empty_line_count_; ++i) { + for (int i = 1; i <= tail_empty_line_count_; ++i) { if (point.y < th + i * font_->GetFontSize()) { - return {text_.size() - i, false, false}; + return {text_.size() - (tail_empty_line_count_ - i), false, false}; } } + return {text_.size(), false, false}; } auto p = point; @@ -209,27 +236,33 @@ TextHitTestResult OsxCTTextLayout::HitTest(const Point& point) { if (p.y >= bounds.origin.y || force_inside) { auto pp = p; pp.y = bounds.origin.y; + Index po; + bool inside_text; if (pp.x < bounds.origin.x) { - return TextHitTestResult{ - actual_text_.IndexFromCodePointToCodeUnit(range.location) + - head_empty_line_count_, - false, false}; + po = actual_text_.IndexFromCodePointToCodeUnit(range.location); + inside_text = false; } else if (pp.x > bounds.origin.x + bounds.size.width) { - auto po = actual_text_.IndexFromCodePointToCodeUnit(range.location + - range.length); - if (po != actual_text_.size()) { - Utf16PreviousCodePoint(text_, po, &po); - } - return TextHitTestResult{po + head_empty_line_count_, false, false}; + po = actual_text_.IndexFromCodePointToCodeUnit(range.location + + range.length); + inside_text = false; } else { int position = CTLineGetStringIndexForPosition( line, CGPointMake(pp.x - line_origins_[i].x, pp.y - line_origins_[i].y)); - return TextHitTestResult{text_.IndexFromCodePointToCodeUnit(position) + - head_empty_line_count_, - false, true}; + + po = actual_text_.IndexFromCodePointToCodeUnit(position); + inside_text = true; + } + + if (po != 0 && + po == actual_text_.IndexFromCodePointToCodeUnit(range.location + + range.length) && + actual_text_[po - 1] == u'\n') { + --po; } + + return {po + head_empty_line_count_, false, inside_text}; } } diff --git a/src/osx/gui/InputMethod.mm b/src/osx/gui/InputMethod.mm index 56ac2c56..45b50318 100644 --- a/src/osx/gui/InputMethod.mm +++ b/src/osx/gui/InputMethod.mm @@ -47,12 +47,12 @@ OsxInputMethodContext::OsxInputMethodContext(OsxWindow* window) OsxInputMethodContext::~OsxInputMethodContext() {} void OsxInputMethodContext::EnableIME() { - log::Debug(u"Enable IME."); + // log::Debug(u"Enable IME."); p_->Activate(); } void OsxInputMethodContext::DisableIME() { - log::Debug(u"Disable IME."); + // log::Debug(u"Disable IME."); p_->Deactivate(); } diff --git a/src/osx/gui/Window.mm b/src/osx/gui/Window.mm index 6e4c8497..fcbc5cb5 100644 --- a/src/osx/gui/Window.mm +++ b/src/osx/gui/Window.mm @@ -14,18 +14,11 @@ #include "cru/osx/gui/Resource.hpp" #include "cru/osx/gui/UiApplication.hpp" #include "cru/platform/Check.hpp" -#include "cru/platform/gui/Base.hpp" -#include "cru/platform/gui/Cursor.hpp" -#include "cru/platform/gui/InputMethod.hpp" -#include "cru/platform/gui/Keyboard.hpp" +#include "cru/platform/graphics/NullPainter.hpp" #include "cru/platform/gui/TimerHelper.hpp" -#include "cru/platform/gui/Window.hpp" -#include <AppKit/NSGraphicsContext.h> -#include <AppKit/NSTextInputContext.h> -#include <AppKit/NSWindow.h> -#include <Foundation/NSAttributedString.h> -#include <Foundation/NSString.h> +#include <AppKit/AppKit.h> +#include <Foundation/Foundation.h> #include <limits> #include <memory> @@ -89,7 +82,7 @@ void OsxWindowPrivate::OnWindowDidResize() { void OsxWindowPrivate::OnBecomeKeyWindow() { focus_event_.Raise(FocusChangeType::Gain); } -void OsxWindowPrivate::OnResignKeyWindow() { focus_event_.Raise(FocusChangeType::Lost); } +void OsxWindowPrivate::OnResignKeyWindow() { focus_event_.Raise(FocusChangeType::Lose); } void OsxWindowPrivate::OnMouseEnterLeave(MouseEnterLeaveType type) { mouse_enter_leave_event_.Raise(type); @@ -234,6 +227,7 @@ void OsxWindow::SetStyleFlag(WindowStyleFlag flag) { WindowVisibilityType OsxWindow::GetVisibility() { if (!p_->window_) return WindowVisibilityType::Hide; + if ([p_->window_ isMiniaturized]) return WindowVisibilityType::Minimize; return [p_->window_ isVisible] ? WindowVisibilityType::Show : WindowVisibilityType::Hide; } @@ -242,9 +236,11 @@ void OsxWindow::SetVisibility(WindowVisibilityType visibility) { if (visibility == WindowVisibilityType::Show) { [p_->window_ orderFront:nil]; p_->visibility_change_event_.Raise(WindowVisibilityType::Show); - } else { + } else if (visibility == WindowVisibilityType::Hide) { [p_->window_ orderOut:nil]; p_->visibility_change_event_.Raise(WindowVisibilityType::Hide); + } else if (visibility == WindowVisibilityType::Minimize) { + [p_->window_ miniaturize:nil]; } } else { if (visibility == WindowVisibilityType::Show) { @@ -307,7 +303,7 @@ void OsxWindow::RequestRepaint() { std::unique_ptr<graphics::IPainter> OsxWindow::BeginPaint() { if (!p_->window_) { - p_->CreateWindow(); + return std::make_unique<graphics::NullPainter>(); } CGContextRef cg_context = CGLayerGetContext(p_->draw_layer_); diff --git a/src/platform/graphics/CMakeLists.txt b/src/platform/graphics/CMakeLists.txt index 5f841267..7d86db40 100644 --- a/src/platform/graphics/CMakeLists.txt +++ b/src/platform/graphics/CMakeLists.txt @@ -1,14 +1,17 @@ set(CRU_PLATFORM_GRAPHICS_INCLUDE_DIR ${CRU_INCLUDE_DIR}/cru/platform/graphics) -add_library(cru_platform_graphics INTERFACE) -target_sources(cru_platform_graphics INTERFACE +add_library(cru_platform_graphics SHARED + NullPainter.cpp +) +target_sources(cru_platform_graphics PUBLIC ${CRU_PLATFORM_GRAPHICS_INCLUDE_DIR}/Base.hpp ${CRU_PLATFORM_GRAPHICS_INCLUDE_DIR}/Brush.hpp ${CRU_PLATFORM_GRAPHICS_INCLUDE_DIR}/Font.hpp ${CRU_PLATFORM_GRAPHICS_INCLUDE_DIR}/Geometry.hpp + ${CRU_PLATFORM_GRAPHICS_INCLUDE_DIR}/NullPainter.hpp ${CRU_PLATFORM_GRAPHICS_INCLUDE_DIR}/Factory.hpp ${CRU_PLATFORM_GRAPHICS_INCLUDE_DIR}/Resource.hpp ${CRU_PLATFORM_GRAPHICS_INCLUDE_DIR}/Painter.hpp ${CRU_PLATFORM_GRAPHICS_INCLUDE_DIR}/TextLayout.hpp ${CRU_PLATFORM_GRAPHICS_INCLUDE_DIR}/util/Painter.hpp ) -target_link_libraries(cru_platform_graphics INTERFACE cru_platform_base) +target_link_libraries(cru_platform_graphics PUBLIC cru_platform_base) diff --git a/src/platform/graphics/NullPainter.cpp b/src/platform/graphics/NullPainter.cpp new file mode 100644 index 00000000..1b02ea07 --- /dev/null +++ b/src/platform/graphics/NullPainter.cpp @@ -0,0 +1 @@ +#include "cru/platform/graphics/NullPainter.hpp" diff --git a/src/ui/controls/RootControl.cpp b/src/ui/controls/RootControl.cpp index d89982c5..278649de 100644 --- a/src/ui/controls/RootControl.cpp +++ b/src/ui/controls/RootControl.cpp @@ -41,7 +41,7 @@ void RootControl::SetGainFocusOnCreateAndDestroyWhenLoseFocus(bool value) { gain_focus_on_create_and_destroy_when_lose_focus_event_guard_ += native_window->FocusEvent()->AddHandler( [native_window](platform::gui::FocusChangeType type) { - if (type == platform::gui::FocusChangeType::Lost) { + if (type == platform::gui::FocusChangeType::Lose) { native_window->Close(); } }); diff --git a/src/ui/controls/TextHostControlService.cpp b/src/ui/controls/TextHostControlService.cpp index 46c02f50..870d643f 100644 --- a/src/ui/controls/TextHostControlService.cpp +++ b/src/ui/controls/TextHostControlService.cpp @@ -55,7 +55,7 @@ TextControlMovePattern TextControlMovePattern::kUp( gsl::index current_position) { auto text_render_object = service->GetTextRenderObject(); auto rect = text_render_object->TextSinglePoint(current_position, false); - rect.top -= text_render_object->GetFont()->GetFontSize(); + rect.top -= 1.f; auto result = text_render_object->TextHitTest(rect.GetLeftTop()); return result.trailing ? result.position + 1 : result.position; }); @@ -65,7 +65,7 @@ TextControlMovePattern TextControlMovePattern::kDown( gsl::index current_position) { auto text_render_object = service->GetTextRenderObject(); auto rect = text_render_object->TextSinglePoint(current_position, false); - rect.top += text_render_object->GetFont()->GetFontSize(); + rect.top += rect.height + 0.1f; auto result = text_render_object->TextHitTest(rect.GetLeftTop()); return result.trailing ? result.position + 1 : result.position; }); diff --git a/src/ui/render/TextRenderObject.cpp b/src/ui/render/TextRenderObject.cpp index e1036072..0e65da92 100644 --- a/src/ui/render/TextRenderObject.cpp +++ b/src/ui/render/TextRenderObject.cpp @@ -64,6 +64,16 @@ void TextRenderObject::SetEditMode(bool enable) { text_layout_->SetEditMode(enable); } +Index TextRenderObject::GetLineCount() { return text_layout_->GetLineCount(); } + +Index TextRenderObject::GetLineIndexFromCharIndex(Index char_index) { + return text_layout_->GetLineIndexFromCharIndex(char_index); +} + +float TextRenderObject::GetLineHeight(Index line_index) { + return text_layout_->GetLineHeight(line_index); +} + std::vector<Rect> TextRenderObject::TextRangeRect(const TextRange& text_range) { return text_layout_->TextRangeRect(text_range); } |