From d3a55867c29d05db34746ac95f43e06eeaf88a43 Mon Sep 17 00:00:00 2001 From: David Capello Date: Tue, 27 Aug 2024 16:01:32 -0300 Subject: [PATCH] Resize text box when more space is needed (more text or bigger font) --- src/app/ui/editor/writing_text_state.cpp | 76 +++++++++++++++++------- src/app/util/render_text.cpp | 30 ++++++---- src/app/util/render_text.h | 5 ++ 3 files changed, 81 insertions(+), 30 deletions(-) diff --git a/src/app/ui/editor/writing_text_state.cpp b/src/app/ui/editor/writing_text_state.cpp index a3a77b274..c4e9409dc 100644 --- a/src/app/ui/editor/writing_text_state.cpp +++ b/src/app/ui/editor/writing_text_state.cpp @@ -60,25 +60,7 @@ public: setPersistSelection(true); - // TODO move this opacity() to Site class - int t, opacity = (site.layer()->isImage() ? - static_cast(site.layer())->opacity(): 255); - Cel* cel = site.cel(); - if (cel) opacity = MUL_UN8(opacity, cel->opacity(), t); - - m_extraCel->create( - site.tilemapMode(), - site.sprite(), - bounds, - bounds.size(), - site.frame(), - 255); - - m_extraCel->setType(render::ExtraType::PATCH); - m_extraCel->setBlendMode(site.layer()->isImage() ? - static_cast(site.layer())->blendMode(): - doc::BlendMode::NORMAL); - + createExtraCel(site, bounds); renderExtraCelBase(); FontInfo fontInfo = App::instance()->contextBar()->fontInfo(); @@ -100,12 +82,36 @@ public: } void setExtraCelBounds(const gfx::Rect& bounds) { - m_extraCel->cel()->setBounds(bounds); + if (bounds.w != m_extraCel->image()->width() || + bounds.h != m_extraCel->image()->height()) { + createExtraCel(m_editor->getSite(), bounds); + } + else { + m_extraCel->cel()->setBounds(bounds); + } renderExtraCelBase(); renderExtraCelText(true); } + obs::signal NewRequiredBounds; + private: + void createExtraCel(const Site& site, + const gfx::Rect& bounds) { + m_extraCel->create( + site.tilemapMode(), + site.sprite(), + bounds, + bounds.size(), + site.frame(), + 255); + + m_extraCel->setType(render::ExtraType::PATCH); + m_extraCel->setBlendMode(site.layer()->isImage() ? + static_cast(site.layer())->blendMode(): + doc::BlendMode::NORMAL); + } + bool onProcessMessage(Message* msg) override { switch (msg->type()) { case kMouseDownMessage: @@ -132,6 +138,26 @@ private: setBgColor(gfx::ColorNone); } + void onSetText() override { + Entry::onSetText(); + onNewTextBlob(); + } + + void onSetFont() override { + Entry::onSetFont(); + onNewTextBlob(); + } + + void onNewTextBlob() { + text::TextBlobRef blob = textBlob(); + if (!blob) + return; + + // Notify that we could make the text editor bigger to show this + // text blob. + NewRequiredBounds(get_text_blob_required_size(blob)); + } + void onPaint(PaintEvent& ev) override { Graphics* g = ev.graphics(); @@ -256,6 +282,16 @@ WritingTextState::WritingTextState(Editor* editor, App::instance()->contextBar()->FontChange.connect( &WritingTextState::onFontChange, this); + m_entry->NewRequiredBounds.connect([this](const gfx::Size& blobSize) { + if (m_bounds.w < blobSize.w || + m_bounds.h < blobSize.h) { + m_bounds.w = std::max(m_bounds.w, blobSize.w); + m_bounds.h = std::max(m_bounds.h, blobSize.h); + m_entry->setExtraCelBounds(m_bounds); + m_entry->setBounds(calcEntryBounds()); + } + }); + onEditorResize(editor); } diff --git a/src/app/util/render_text.cpp b/src/app/util/render_text.cpp index 8c941556b..e064ac1e8 100644 --- a/src/app/util/render_text.cpp +++ b/src/app/util/render_text.cpp @@ -116,6 +116,24 @@ text::TextBlobRef create_text_blob( return text::TextBlob::MakeWithShaper(fontMgr, font, text); } +gfx::Size get_text_blob_required_size( + const text::TextBlobRef& blob) +{ + ASSERT(blob != nullptr); + + gfx::RectF bounds(0, 0, 1, 1); + blob->visitRuns([&bounds](text::TextBlob::RunInfo& run) { + for (int i=0; imetrics(nullptr)); + } + }); + if (bounds.w < 1) bounds.w = 1; + if (bounds.h < 1) bounds.h = 1; + return gfx::Size(std::ceil(bounds.w), + std::ceil(bounds.h)); +} + doc::ImageRef render_text_blob( const text::TextBlobRef& blob, gfx::Color color) @@ -127,18 +145,10 @@ doc::ImageRef render_text_blob( paint.style(os::Paint::Fill); paint.color(color); - gfx::RectF bounds(0, 0, 1, 1); - blob->visitRuns([&bounds](text::TextBlob::RunInfo& run){ - for (int i=0; imetrics(nullptr)); - } - }); - if (bounds.w < 1) bounds.w = 1; - if (bounds.h < 1) bounds.h = 1; + gfx::Size blobSize = get_text_blob_required_size(blob); doc::ImageRef image( - doc::Image::create(doc::IMAGE_RGB, bounds.w, bounds.h)); + doc::Image::create(doc::IMAGE_RGB, blobSize.w, blobSize.h)); #ifdef LAF_SKIA sk_sp skSurface = wrap_docimage_in_sksurface(image.get()); diff --git a/src/app/util/render_text.h b/src/app/util/render_text.h index 5c276bd61..2d818a580 100644 --- a/src/app/util/render_text.h +++ b/src/app/util/render_text.h @@ -28,6 +28,11 @@ namespace app { const FontInfo& fontInfo, const std::string& text); + // Returns the exact bounds that are required to draw this TextBlob, + // i.e. the image size that will be required in render_text_blob(). + gfx::Size get_text_blob_required_size( + const text::TextBlobRef& blob); + doc::ImageRef render_text_blob( const text::TextBlobRef& blob, gfx::Color color);