From c781d82cf6961d1010459b1fbae6b903c72e4ccc Mon Sep 17 00:00:00 2001 From: David Capello Date: Tue, 7 Oct 2025 11:08:41 -0300 Subject: [PATCH] Match text caret size with Entry widget --- src/app/ui/skin/skin_theme.cpp | 18 ++++++++++++++---- src/app/ui/skin/skin_theme.h | 2 +- src/ui/entry.cpp | 8 ++++---- src/ui/int_entry.cpp | 2 +- src/ui/textedit.cpp | 9 +++++---- src/ui/theme.h | 2 +- 6 files changed, 26 insertions(+), 15 deletions(-) diff --git a/src/app/ui/skin/skin_theme.cpp b/src/app/ui/skin/skin_theme.cpp index bd0d599bd..3655eefe5 100644 --- a/src/app/ui/skin/skin_theme.cpp +++ b/src/app/ui/skin/skin_theme.cpp @@ -1296,12 +1296,22 @@ int SkinTheme::getScrollbarSize() return dimensions.scrollbarSize(); } -gfx::Size SkinTheme::getEntryCaretSize(Widget* widget) +gfx::Size SkinTheme::getCaretSize(Widget* widget) { + int caretHeight; + if (widget->type() == kTextEditWidget) { + // We cannot use the height of the widget text, because it + // includes the line height of every single line in the widget. + caretHeight = widget->font()->lineHeight(); + } + else { + caretHeight = widget->textHeight(); + } + if (widget->font()->type() == text::FontType::FreeType) - return gfx::Size(2 * guiscale(), widget->textHeight()); + return gfx::Size(2 * guiscale(), caretHeight); else - return gfx::Size(2 * guiscale(), widget->textHeight() + 2 * guiscale()); + return gfx::Size(2 * guiscale(), caretHeight + 2 * guiscale()); } void SkinTheme::paintEntry(PaintEvent& ev) @@ -1866,7 +1876,7 @@ void SkinTheme::drawEntryCaret(ui::Graphics* g, Entry* widget, int x, int y) { gfx::Color color = colors.text(); int textHeight = widget->textHeight(); - gfx::Size caretSize = getEntryCaretSize(widget); + gfx::Size caretSize = getCaretSize(widget); for (int u = x; u < x + caretSize.w; ++u) g->drawVLine(color, u, y + textHeight / 2 - caretSize.h / 2, caretSize.h); diff --git a/src/app/ui/skin/skin_theme.h b/src/app/ui/skin/skin_theme.h index 8a70711ab..f7dcb75a5 100644 --- a/src/app/ui/skin/skin_theme.h +++ b/src/app/ui/skin/skin_theme.h @@ -80,7 +80,7 @@ public: void initWidget(ui::Widget* widget) override; void getWindowMask(ui::Widget* widget, gfx::Region& region) override; int getScrollbarSize() override; - gfx::Size getEntryCaretSize(ui::Widget* widget) override; + gfx::Size getCaretSize(ui::Widget* widget) override; void paintEntry(ui::PaintEvent& ev) override; void paintListBox(ui::PaintEvent& ev) override; diff --git a/src/ui/entry.cpp b/src/ui/entry.cpp index 04daf2541..3fe1970ef 100644 --- a/src/ui/entry.cpp +++ b/src/ui/entry.cpp @@ -139,7 +139,7 @@ gfx::Point Entry::caretPosOnScreen() const void Entry::setCaretPos(const int pos) { - gfx::Size caretSize = theme()->getEntryCaretSize(this); + gfx::Size caretSize = theme()->getCaretSize(this); int textlen = lastCaretPos(); m_caret = std::clamp(pos, 0, textlen); m_scroll = std::clamp(m_scroll, 0, textlen); @@ -521,7 +521,7 @@ gfx::Size Entry::sizeHintWithText(Entry* entry, const std::string& text) { const auto& font = entry->font(); - int w = font->textLength(text) + +2 * entry->theme()->getEntryCaretSize(entry).w + + int w = font->textLength(text) + +2 * entry->theme()->getCaretSize(entry).w + entry->border().width(); w = std::min(w, guiscale() * kMaxWidthHintForEntry); @@ -546,7 +546,7 @@ void Entry::onSizeHint(SizeHintEvent& ev) const auto& font = this->font(); int trailing = font->textLength(getSuffix()); - trailing = std::max(trailing, 2 * theme()->getEntryCaretSize(this).w); + trailing = std::max(trailing, 2 * theme()->getCaretSize(this).w); int w = font->textLength("w") * std::min(m_maxsize, 6) + +trailing + border().width(); @@ -1012,7 +1012,7 @@ void Entry::recalcCharBoxes(const std::string& text) box.codepoint = 0; box.from = box.to = lastTextIndex; box.x = lastX; - box.width = theme()->getEntryCaretSize(this).w; + box.width = theme()->getCaretSize(this).w; m_boxes.push_back(box); } diff --git a/src/ui/int_entry.cpp b/src/ui/int_entry.cpp index 90d0d53d2..fa43b5b02 100644 --- a/src/ui/int_entry.cpp +++ b/src/ui/int_entry.cpp @@ -141,7 +141,7 @@ void IntEntry::onSizeHint(SizeHintEvent& ev) { const text::FontRef& font = this->font(); int trailing = font->textLength(getSuffix()); - trailing = std::max(trailing, 2 * theme()->getEntryCaretSize(this).w); + trailing = std::max(trailing, 2 * theme()->getCaretSize(this).w); int min_w = font->textLength(m_slider->convertValueToText(m_min)); int max_w = font->textLength(m_slider->convertValueToText(m_max)) + trailing; diff --git a/src/ui/textedit.cpp b/src/ui/textedit.cpp index 21af66c8a..9b91af5fb 100644 --- a/src/ui/textedit.cpp +++ b/src/ui/textedit.cpp @@ -364,8 +364,8 @@ void TextEdit::onPaint(PaintEvent& ev) gfx::PointF point(border().left(), border().top()); point -= scroll; - m_caretRect = - gfx::Rect(border().left() - scroll.x, border().top() - scroll.y, 2, font()->lineHeight()); + m_caretRect = gfx::Rect(gfx::Point(border().left() - scroll.x, border().top() - scroll.y), + theme()->getCaretSize(this)); const gfx::Rect clipBounds = g->getClipBounds(); @@ -403,8 +403,9 @@ void TextEdit::onPaint(PaintEvent& ev) m_caretRect.x += line.getBounds(m_caret.pos()).x; } - m_caretRect.y = point.y; - m_caretRect.h = line.height; // Ensure the caret height corresponds with the tallest glyph + // Ensure the caret height corresponds with the tallest glyph + m_caretRect.h = std::max(m_caretRect.h, line.height); + m_caretRect.y = point.y + line.height / 2 - m_caretRect.h / 2; } point.y += line.height; diff --git a/src/ui/theme.h b/src/ui/theme.h index 708546a92..148034dcf 100644 --- a/src/ui/theme.h +++ b/src/ui/theme.h @@ -74,7 +74,7 @@ public: virtual void getWindowMask(Widget* widget, gfx::Region& region) {} virtual void setDecorativeWidgetBounds(Widget* widget); virtual int getScrollbarSize() { return kDefaultFontHeight; } - virtual gfx::Size getEntryCaretSize(Widget* widget) { return gfx::Size(kDefaultFontHeight, 1); } + virtual gfx::Size getCaretSize(Widget* widget) { return gfx::Size(kDefaultFontHeight, 1); } virtual void paintEntry(PaintEvent& ev) {} virtual void paintTextEdit(PaintEvent& ev) {}