Compare commits

..

12 Commits

Author SHA1 Message Date
David Capello 49b01c2565
Merge 2c9a2998df into 6c7544a132 2025-10-06 21:28:00 +00:00
David Capello 2c9a2998df Fix TextEdit::caretFromPosition() when lines have different heights 2025-10-06 18:27:34 -03:00
David Capello c089bb87ff Invalidate all blobs after changing theme
We've moved the InitTheme code from the InitTheme.connect() signal to
the onInitTheme() member function.
2025-10-06 16:40:50 -03:00
David Capello f9abfbe87b Implement "selection by words" after double-clicking
This is the same behavior as in ui::Entry widget.
2025-10-06 16:30:03 -03:00
David Capello 0068819580 Improve caret/char selection with the mouse 2025-10-06 15:46:44 -03:00
David Capello 73fbf16d31 Fix caret position when a line has multiple runs (e.g. there's an emoji present) 2025-10-06 15:32:45 -03:00
David Capello c1327bf798 Jump between words correctly with Ctrl+Left/Right 2025-10-06 14:42:49 -03:00
David Capello 1a70e8a289 Change size_t to int for position/line numbers 2025-10-06 14:39:51 -03:00
David Capello 31557a9e7b Fix End key to go to EOL and added Ctrl+Home/End to go to BOF/EOF 2025-10-06 12:37:31 -03:00
David Capello c7868641fb Enter from the numeric keypad can be used for new lines too 2025-10-06 12:28:46 -03:00
David Capello 7ca4cb8129 We cannot bypass onSetText() as ui::Entry requires this
Without this fix, "Run Command" will crash.
2025-10-06 12:26:05 -03:00
Christian Kaiser e24fabb38b User data with multiple lines of text (new TextEdit widget) (#3130, #3131, #4743, #4968) 2025-10-06 11:54:37 -03:00
11 changed files with 30 additions and 35 deletions

2
laf

@ -1 +1 @@
Subproject commit 29aa044517059df87158c9e5f26c92572effb103
Subproject commit 39706c11063fb53cf4c8e865102c6f71e2606906

View File

@ -34,6 +34,7 @@ namespace app { namespace script {
template<>
void push_value_to_lua(lua_State* L, const std::nullptr_t&)
{
TRACEARGS("push_value_to_lua nullptr_t");
lua_pushnil(L);
}

View File

@ -1296,22 +1296,12 @@ int SkinTheme::getScrollbarSize()
return dimensions.scrollbarSize();
}
gfx::Size SkinTheme::getCaretSize(Widget* widget)
gfx::Size SkinTheme::getEntryCaretSize(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(), caretHeight);
return gfx::Size(2 * guiscale(), widget->textHeight());
else
return gfx::Size(2 * guiscale(), caretHeight + 2 * guiscale());
return gfx::Size(2 * guiscale(), widget->textHeight() + 2 * guiscale());
}
void SkinTheme::paintEntry(PaintEvent& ev)
@ -1876,7 +1866,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 = getCaretSize(widget);
gfx::Size caretSize = getEntryCaretSize(widget);
for (int u = x; u < x + caretSize.w; ++u)
g->drawVLine(color, u, y + textHeight / 2 - caretSize.h / 2, caretSize.h);

View File

@ -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 getCaretSize(ui::Widget* widget) override;
gfx::Size getEntryCaretSize(ui::Widget* widget) override;
void paintEntry(ui::PaintEvent& ev) override;
void paintListBox(ui::PaintEvent& ev) override;

View File

@ -1,5 +1,5 @@
// Aseprite
// Copyright (C) 2019-2025 Igara Studio S.A.
// Copyright (C) 2019-2023 Igara Studio S.A.
//
// This program is distributed under the terms of
// the End-User License Agreement for Aseprite.
@ -50,8 +50,10 @@ TaskWidget::TaskWidget(const Type type, base::task::func_t&& func)
}
else if (m_progressBar.parent()) {
float v = m_task.progress();
if (v > 0.0f)
if (v > 0.0f) {
TRACEARGS("progressBar setValue", int(std::clamp(v * 100.0f, 0.0f, 100.0f)));
m_progressBar.setValue(int(std::clamp(v * 100.0f, 0.0f, 100.0f)));
}
}
});
m_monitorTimer.start();

View File

@ -1,5 +1,5 @@
// Aseprite Steam Wrapper
// Copyright (c) 2020-2025 Igara Studio S.A.
// Copyright (c) 2020-2024 Igara Studio S.A.
// Copyright (c) 2016 David Capello
//
// This file is released under the terms of the MIT license.
@ -153,6 +153,8 @@ public:
CallbackMsg_t msg;
if (SteamAPI_ManualDispatch_GetNextCallback(m_pipe, &msg)) {
// TRACEARGS("SteamAPI_ManualDispatch_GetNextCallback", msg.callback);
bool disconnected = false;
switch (msg.callback) {
case kSteamServersDisconnected:

View File

@ -139,7 +139,7 @@ gfx::Point Entry::caretPosOnScreen() const
void Entry::setCaretPos(const int pos)
{
gfx::Size caretSize = theme()->getCaretSize(this);
gfx::Size caretSize = theme()->getEntryCaretSize(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()->getCaretSize(entry).w +
int w = font->textLength(text) + +2 * entry->theme()->getEntryCaretSize(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()->getCaretSize(this).w);
trailing = std::max(trailing, 2 * theme()->getEntryCaretSize(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()->getCaretSize(this).w;
box.width = theme()->getEntryCaretSize(this).w;
m_boxes.push_back(box);
}

View File

@ -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()->getCaretSize(this).w);
trailing = std::max(trailing, 2 * theme()->getEntryCaretSize(this).w);
int min_w = font->textLength(m_slider->convertValueToText(m_min));
int max_w = font->textLength(m_slider->convertValueToText(m_max)) + trailing;

View File

@ -364,8 +364,8 @@ void TextEdit::onPaint(PaintEvent& ev)
gfx::PointF point(border().left(), border().top());
point -= scroll;
m_caretRect = gfx::Rect(gfx::Point(border().left() - scroll.x, border().top() - scroll.y),
theme()->getCaretSize(this));
m_caretRect =
gfx::Rect(border().left() - scroll.x, border().top() - scroll.y, 2, font()->lineHeight());
const gfx::Rect clipBounds = g->getClipBounds();
@ -403,9 +403,8 @@ void TextEdit::onPaint(PaintEvent& ev)
m_caretRect.x += line.getBounds(m_caret.pos()).x;
}
// 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;
m_caretRect.y = point.y;
m_caretRect.h = line.height; // Ensure the caret height corresponds with the tallest glyph
}
point.y += line.height;
@ -799,6 +798,7 @@ struct Utf8RangeBuilder : public text::TextBlob::RunHandler {
void commitRunBuffer(TextBlob::RunInfo& info) override
{
ASSERT(info.clusters == nullptr || *info.clusters == 0);
for (int i = 0; i < info.glyphCount; ++i) {
ranges.push_back(info.getGlyphUtf8Range(i));
}
@ -843,7 +843,7 @@ void TextEdit::Line::insertText(int pos, const std::string& str)
text.insert(utfSize[pos - 1].end, str);
}
gfx::RectF TextEdit::Line::getBounds(const int glyph) const
gfx::Rect TextEdit::Line::getBounds(const int glyph) const
{
int advance = 0;
gfx::Rect result;
@ -857,10 +857,10 @@ gfx::RectF TextEdit::Line::getBounds(const int glyph) const
return result;
}
gfx::RectF TextEdit::Line::getBounds(const int startGlyph, const int endGlyph) const
gfx::Rect TextEdit::Line::getBounds(int startGlyph, int endGlyph) const
{
if (startGlyph == endGlyph)
return {};
return getBounds(startGlyph);
ASSERT(endGlyph > startGlyph);

View File

@ -62,10 +62,10 @@ private:
// Insert text into this line based on a caret position, taking into account utf8 size.
void insertText(int pos, const std::string& str);
gfx::RectF getBounds(int glyph) const;
gfx::Rect getBounds(int glyph) const;
// Get the screen size between the start and end glyph positions.
gfx::RectF getBounds(int startGlyph, int endGlyph) const;
gfx::Rect getBounds(int startGlyph, int endGlyph) const;
};
struct Caret {

View File

@ -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 getCaretSize(Widget* widget) { return gfx::Size(kDefaultFontHeight, 1); }
virtual gfx::Size getEntryCaretSize(Widget* widget) { return gfx::Size(kDefaultFontHeight, 1); }
virtual void paintEntry(PaintEvent& ev) {}
virtual void paintTextEdit(PaintEvent& ev) {}