diff --git a/data/extensions/aseprite-theme/dark/sheet.png b/data/extensions/aseprite-theme/dark/sheet.png index 6ab76d140..f716408f5 100644 Binary files a/data/extensions/aseprite-theme/dark/sheet.png and b/data/extensions/aseprite-theme/dark/sheet.png differ diff --git a/data/extensions/aseprite-theme/dark/theme.xml b/data/extensions/aseprite-theme/dark/theme.xml index b763fcb9f..485823f0a 100644 --- a/data/extensions/aseprite-theme/dark/theme.xml +++ b/data/extensions/aseprite-theme/dark/theme.xml @@ -386,6 +386,8 @@ + + @@ -418,7 +420,6 @@ - diff --git a/data/extensions/aseprite-theme/sheet.png b/data/extensions/aseprite-theme/sheet.png index 57752ee8d..c908f2111 100644 Binary files a/data/extensions/aseprite-theme/sheet.png and b/data/extensions/aseprite-theme/sheet.png differ diff --git a/data/extensions/aseprite-theme/theme.xml b/data/extensions/aseprite-theme/theme.xml index 6f95b5f46..c23ca5247 100644 --- a/data/extensions/aseprite-theme/theme.xml +++ b/data/extensions/aseprite-theme/theme.xml @@ -382,6 +382,8 @@ + + @@ -414,7 +416,6 @@ - diff --git a/src/app/app_brushes.cpp b/src/app/app_brushes.cpp index 6a83810b8..f1dbe96b2 100644 --- a/src/app/app_brushes.cpp +++ b/src/app/app_brushes.cpp @@ -1,5 +1,5 @@ // Aseprite -// Copyright (C) 2020-2021 Igara Studio S.A. +// Copyright (C) 2020-2022 Igara Studio S.A. // Copyright (C) 2001-2016 David Capello // // This program is distributed under the terms of @@ -437,9 +437,9 @@ void AppBrushes::save(const std::string& filename) const } if (slot.brush()->type() == kImageBrushType && - slot.brush()->image()) { + slot.brush()->originalImage()) { TiXmlElement elem("image"); - save_xml_image(&elem, slot.brush()->image()); + save_xml_image(&elem, slot.brush()->originalImage()); brushElem.InsertEndChild(elem); if (slot.brush()->maskBitmap()) { diff --git a/src/app/commands/cmd_undo_history.cpp b/src/app/commands/cmd_undo_history.cpp index 24e5bd404..1f752e791 100644 --- a/src/app/commands/cmd_undo_history.cpp +++ b/src/app/commands/cmd_undo_history.cpp @@ -113,7 +113,7 @@ public: [[fallthrough]]; case ui::kMouseMoveMessage: - if (hasCapture()) { + if (hasCapture() && m_undoHistory) { auto mouseMsg = static_cast(msg); const gfx::Rect bounds = this->bounds(); diff --git a/src/app/tools/controllers.h b/src/app/tools/controllers.h index ff32976e3..048f62d6a 100644 --- a/src/app/tools/controllers.h +++ b/src/app/tools/controllers.h @@ -1,5 +1,5 @@ // Aseprite -// Copyright (C) 2019-2020 Igara Studio S.A. +// Copyright (C) 2019-2022 Igara Studio S.A. // Copyright (C) 2001-2018 David Capello // // This program is distributed under the terms of @@ -94,7 +94,7 @@ public: gfx::Point offset = loop->statusBarPositionOffset(); char buf[1024]; - sprintf(buf, ":start: %3d %3d :end: %3d %3d", + sprintf(buf, ":start: %d %d :end: %d %d", stroke.firstPoint().x+offset.x, stroke.firstPoint().y+offset.y, stroke.lastPoint().x+offset.x, @@ -259,7 +259,7 @@ public: gfx::Point offset = loop->statusBarPositionOffset(); char buf[1024]; int gcd = base::gcd(w, h); - sprintf(buf, ":start: %3d %3d :end: %3d %3d :size: %3d %3d :distance: %.1f", + sprintf(buf, ":start: %d %d :end: %d %d :size: %d %d :distance: %.1f", stroke[0].x+offset.x, stroke[0].y+offset.y, stroke[1].x+offset.x, stroke[1].y+offset.y, w, h, std::sqrt(w*w + h*h)); @@ -362,7 +362,7 @@ public: gfx::Point offset = loop->statusBarPositionOffset(); char buf[1024]; - sprintf(buf, ":start: %3d %3d :end: %3d %3d", + sprintf(buf, ":start: %d %d :end: %d %d", stroke.firstPoint().x+offset.x, stroke.firstPoint().y+offset.y, stroke.lastPoint().x+offset.x, @@ -402,7 +402,7 @@ public: gfx::Point offset = loop->statusBarPositionOffset(); char buf[1024]; - sprintf(buf, ":pos: %3d %3d", + sprintf(buf, ":pos: %d %d", stroke[0].x+offset.x, stroke[0].y+offset.y); text = buf; @@ -460,7 +460,7 @@ public: gfx::Point offset = loop->statusBarPositionOffset(); char buf[1024]; - sprintf(buf, ":start: %3d %3d :end: %3d %3d (%3d %3d - %3d %3d)", + sprintf(buf, ":start: %d %d :end: %d %d (%d %d - %d %d)", stroke[0].x+offset.x, stroke[0].y+offset.y, stroke[3].x+offset.x, stroke[3].y+offset.y, stroke[1].x+offset.x, stroke[1].y+offset.y, diff --git a/src/app/ui/brush_popup.cpp b/src/app/ui/brush_popup.cpp index 8b715cd04..dc6fadd8a 100644 --- a/src/app/ui/brush_popup.cpp +++ b/src/app/ui/brush_popup.cpp @@ -81,7 +81,9 @@ public: , m_slot(slot) { if (m_brush.hasBrush()) { SkinPartPtr icon(new SkinPart); - icon->setBitmap(0, BrushPopup::createSurfaceForBrush(m_brush.brush())); + icon->setBitmap(0, BrushPopup::createSurfaceForBrush( + m_brush.brush(), + m_brush.hasFlag(BrushSlot::Flags::ImageColor))); setIcon(icon); } } @@ -453,7 +455,8 @@ void BrushPopup::onBrushChanges() } // static -os::SurfaceRef BrushPopup::createSurfaceForBrush(const BrushRef& origBrush) +os::SurfaceRef BrushPopup::createSurfaceForBrush(const BrushRef& origBrush, + const bool useOriginalImage) { Image* image = nullptr; BrushRef brush = origBrush; @@ -462,7 +465,12 @@ os::SurfaceRef BrushPopup::createSurfaceForBrush(const BrushRef& origBrush) brush.reset(new Brush(*brush)); brush->setSize(10); } - image = brush->image(); + // Show the original image in the popup (without the image colors + // modified if there were some modification). + if (useOriginalImage) + image = brush->originalImage(); + else + image = brush->image(); } os::SurfaceRef surface = os::instance()->makeRgbaSurface( diff --git a/src/app/ui/brush_popup.h b/src/app/ui/brush_popup.h index 34d79f046..5ace89138 100644 --- a/src/app/ui/brush_popup.h +++ b/src/app/ui/brush_popup.h @@ -1,5 +1,5 @@ // Aseprite -// Copyright (C) 2018-2021 Igara Studio S.A. +// Copyright (C) 2018-2022 Igara Studio S.A. // Copyright (C) 2001-2015 David Capello // // This program is distributed under the terms of @@ -24,7 +24,8 @@ namespace app { void regenerate(ui::Display* display, const gfx::Point& pos); - static os::SurfaceRef createSurfaceForBrush(const doc::BrushRef& brush); + static os::SurfaceRef createSurfaceForBrush(const doc::BrushRef& brush, + const bool useOriginalImage = false); private: void onStandardBrush(); diff --git a/src/app/ui/color_button.cpp b/src/app/ui/color_button.cpp index 40284290b..91d87449f 100644 --- a/src/app/ui/color_button.cpp +++ b/src/app/ui/color_button.cpp @@ -142,7 +142,7 @@ bool ColorButton::onProcessMessage(Message* msg) break; case kMouseEnterMessage: - StatusBar::instance()->showColor(0, "", m_color); + StatusBar::instance()->showColor(0, m_color); break; case kMouseLeaveMessage: diff --git a/src/app/ui/color_selector.cpp b/src/app/ui/color_selector.cpp index dba11976c..d703d73cc 100644 --- a/src/app/ui/color_selector.cpp +++ b/src/app/ui/color_selector.cpp @@ -334,7 +334,7 @@ bool ColorSelector::onProcessMessage(ui::Message* msg) if (color != app::Color::fromMask()) { base::ScopedValue switcher(m_lockColor, subColorPicked(), false); - StatusBar::instance()->showColor(0, "", color); + StatusBar::instance()->showColor(0, color); if (hasCapture()) ColorChange(color, mouseMsg->button()); } diff --git a/src/app/ui/context_bar.cpp b/src/app/ui/context_bar.cpp index d451158a2..995cabdda 100644 --- a/src/app/ui/context_bar.cpp +++ b/src/app/ui/context_bar.cpp @@ -2220,6 +2220,11 @@ void ContextBar::setActiveBrushBySlot(tools::Tool* tool, int slot) if (brush.brush()) { if (brush.brush()->type() == doc::kImageBrushType) { + // Reset the colors of the image when we select the brush from + // the slot. + if (brush.hasFlag(BrushSlot::Flags::ImageColor)) + brush.brush()->resetImageColors(); + setActiveBrush(brush.brush()); } else { diff --git a/src/app/ui/editor/editor.cpp b/src/app/ui/editor/editor.cpp index c814fc8f6..57c6ee6f6 100644 --- a/src/app/ui/editor/editor.cpp +++ b/src/app/ui/editor/editor.cpp @@ -2971,6 +2971,7 @@ void Editor::updateAutoCelGuides(ui::Message* msg) if (m_showGuidesThisCel != oldShowGuidesThisCel || m_showAutoCelGuides != oldShowAutoCelGuides) { invalidate(); + updateStatusBar(); } } diff --git a/src/app/ui/editor/editor.h b/src/app/ui/editor/editor.h index 5b8967508..aa35acf7f 100644 --- a/src/app/ui/editor/editor.h +++ b/src/app/ui/editor/editor.h @@ -317,6 +317,9 @@ namespace app { // key is pressed to cancel the active selection. void cancelSelections(); + // Properties to show information in the status bar + bool showAutoCelGuides() const { return m_showAutoCelGuides; } + static void registerCommands(); protected: @@ -389,7 +392,6 @@ namespace app { void invalidateCanvas(); void invalidateIfActive(); - bool showAutoCelGuides(); void updateAutoCelGuides(ui::Message* msg); // Stack of states. The top element in the stack is the current state (m_state). diff --git a/src/app/ui/editor/moving_cel_state.cpp b/src/app/ui/editor/moving_cel_state.cpp index f256e319a..5c81342b7 100644 --- a/src/app/ui/editor/moving_cel_state.cpp +++ b/src/app/ui/editor/moving_cel_state.cpp @@ -97,8 +97,12 @@ MovingCelState::MovingCelState(Editor* editor, ASSERT(!m_celList.empty()); m_cel = collect.mainCel(); - if (m_cel) - m_celMainSize = m_cel->boundsF().size(); + if (m_cel) { + if (m_cel->data()->hasBoundsF()) + m_celMainSize = m_cel->boundsF().size(); + else + m_celMainSize = gfx::SizeF(m_cel->bounds().size()); + } // Record start positions of all cels in selected range for (Cel* cel : m_celList) { @@ -282,6 +286,11 @@ void MovingCelState::onCommitMouseMove(Editor* editor, // Redraw the new cel position. editor->invalidate(); + + // Redraw status bar with the new position of cels (without this the + // previous position before this onCommitMouseMove() is still + // displayed in the screen). + editor->updateStatusBar(); } bool MovingCelState::onKeyDown(Editor* editor, KeyMessage* msg) @@ -297,37 +306,46 @@ bool MovingCelState::onKeyDown(Editor* editor, KeyMessage* msg) bool MovingCelState::onUpdateStatusBar(Editor* editor) { - gfx::PointF pos = m_cursorStart - gfx::PointF(editor->mainTilePosition()); + gfx::PointF pos = m_celOffset + m_cursorStart - gfx::PointF(editor->mainTilePosition()); + gfx::RectF fullBounds = calcFullBounds(); + std::string buf; if (m_hasReference) { + buf = fmt::format(":pos: {:.2f} {:.2f}", pos.x, pos.y); if (m_scaled && m_cel) { - StatusBar::instance()->setStatusText( - 0, - fmt::format( - ":pos: {:.2f} {:.2f} :offset: {:.2f} {:.2f} :size: {:.2f}% {:.2f}%", - pos.x, pos.y, - m_celOffset.x, m_celOffset.y, - 100.0*m_celScale.w*m_celMainSize.w/m_cel->image()->width(), - 100.0*m_celScale.h*m_celMainSize.h/m_cel->image()->height())); + buf += fmt::format( + " :start: {:.2f} {:.2f}" + " :size: {:.2f} {:.2f} [{:.2f}% {:.2f}%]", + m_cel->boundsF().x, + m_cel->boundsF().y, + m_celScale.w*m_celMainSize.w, + m_celScale.h*m_celMainSize.h, + 100.0*m_celScale.w*m_celMainSize.w/m_cel->image()->width(), + 100.0*m_celScale.h*m_celMainSize.h/m_cel->image()->height()); } else { - StatusBar::instance()->setStatusText( - 0, - fmt::format( - ":pos: {:.2f} {:.2f} :offset: {:.2f} {:.2f}", - pos.x, pos.y, - m_celOffset.x, m_celOffset.y)); + buf += fmt::format( + " :start: {:.2f} {:.2f} :size: {:.2f} {:.2f}" + " :delta: {:.2f} {:.2f}", + fullBounds.x, fullBounds.y, + fullBounds.w, fullBounds.h, + m_celOffset.x, m_celOffset.y); } } else { gfx::Point intOffset = intCelOffset(); - StatusBar::instance()->setStatusText( - 0, - fmt::format(":pos: {:3d} {:3d} :offset: {:3d} {:3d}", - int(pos.x), int(pos.y), - intOffset.x, intOffset.y)); + fullBounds.floor(); + buf = fmt::format( + ":pos: {} {}" + " :start: {} {} :size: {} {}" + " :delta: {} {}", + int(pos.x), int(pos.y), + int(fullBounds.x), int(fullBounds.y), + int(fullBounds.w), int(fullBounds.h), + intOffset.x, intOffset.y); } + StatusBar::instance()->setStatusText(0, buf); return true; } @@ -337,6 +355,18 @@ gfx::Point MovingCelState::intCelOffset() const int(std::round(m_celOffset.y))); } +gfx::RectF MovingCelState::calcFullBounds() const +{ + gfx::RectF bounds; + for (Cel* cel : m_celList) { + if (cel->data()->hasBoundsF()) + bounds |= cel->boundsF(); + else + bounds |= gfx::RectF(cel->bounds()).floor(); + } + return bounds; +} + bool MovingCelState::restoreCelStartPosition() const { bool modified = false; diff --git a/src/app/ui/editor/moving_cel_state.h b/src/app/ui/editor/moving_cel_state.h index b3050279f..5bc98f58a 100644 --- a/src/app/ui/editor/moving_cel_state.h +++ b/src/app/ui/editor/moving_cel_state.h @@ -57,6 +57,7 @@ namespace app { private: gfx::Point intCelOffset() const; + gfx::RectF calcFullBounds() const; bool restoreCelStartPosition() const; // ContextObserver void onBeforeCommandExecution(CommandExecutionEvent& ev); diff --git a/src/app/ui/editor/moving_pixels_state.cpp b/src/app/ui/editor/moving_pixels_state.cpp index a5cc9d09d..c10d38ff8 100644 --- a/src/app/ui/editor/moving_pixels_state.cpp +++ b/src/app/ui/editor/moving_pixels_state.cpp @@ -554,7 +554,11 @@ bool MovingPixelsState::onUpdateStatusBar(Editor* editor) StatusBar::instance()->setStatusText( 100, fmt::format( - ":pos: {} {} :size: {:3d} {:3d} :selsize: {} {} [{:.02f}% {:.02f}%] :angle: {:.1f} :aspect_ratio: {}:{}", + ":pos: {} {}" + " :size: {} {}" + " :selsize: {} {} [{:.02f}% {:.02f}%]" + " :angle: {:.1f}" + " :aspect_ratio: {}:{}", int(transform.bounds().x), int(transform.bounds().y), imageSize.w, diff --git a/src/app/ui/editor/moving_selection_state.cpp b/src/app/ui/editor/moving_selection_state.cpp index c3a956ad3..82673c516 100644 --- a/src/app/ui/editor/moving_selection_state.cpp +++ b/src/app/ui/editor/moving_selection_state.cpp @@ -157,7 +157,9 @@ bool MovingSelectionState::onUpdateStatusBar(Editor* editor) StatusBar::instance()->setStatusText( 100, fmt::format( - ":pos: {} {} :size: {:3d} {:3d} :offset: {} {}", + ":pos: {} {}" + " :size: {} {}" + " :delta: {} {}", bounds.x, bounds.y, bounds.w, bounds.h, m_delta.x, m_delta.y)); diff --git a/src/app/ui/editor/standby_state.cpp b/src/app/ui/editor/standby_state.cpp index ad4f46aa5..de348741e 100644 --- a/src/app/ui/editor/standby_state.cpp +++ b/src/app/ui/editor/standby_state.cpp @@ -532,14 +532,15 @@ bool StandbyState::onUpdateStatusBar(Editor* editor) editor->projection(), color, tile); - auto buf = fmt::format(" :pos: {} {}", - int(std::floor(spritePos.x)), - int(std::floor(spritePos.y))); + std::string buf = + fmt::format(" :pos: {} {}", + int(std::floor(spritePos.x)), + int(std::floor(spritePos.y))); if (site.tilemapMode() == TilemapMode::Tiles) - StatusBar::instance()->showTile(0, buf.c_str(), tile); + StatusBar::instance()->showTile(0, tile, buf); else - StatusBar::instance()->showColor(0, buf.c_str(), color); + StatusBar::instance()->showColor(0, color, buf); } else { Site site = editor->getSite(); @@ -547,22 +548,37 @@ bool StandbyState::onUpdateStatusBar(Editor* editor) (editor->document()->isMaskVisible() ? editor->document()->mask(): NULL); - char buf[1024]; - sprintf( - buf, ":pos: %d %d :size: %d %d", - int(std::floor(spritePos.x)), - int(std::floor(spritePos.y)), - sprite->width(), - sprite->height()); + std::string buf = fmt::format( + ":pos: {} {}", + int(std::floor(spritePos.x)), + int(std::floor(spritePos.y))); + + Cel* cel = nullptr; + if (editor->showAutoCelGuides()) { + cel = editor->getSite().cel(); + } + + if (cel) { + buf += fmt::format( + " :start: {} {} :size: {} {}", + cel->bounds().x, cel->bounds().y, + cel->bounds().w, cel->bounds().h); + } + else { + buf += fmt::format( + " :size: {} {}", + sprite->width(), + sprite->height()); + } if (mask) - sprintf(buf+std::strlen(buf), " :selsize: %d %d", - mask->bounds().w, - mask->bounds().h); + buf += fmt::format(" :selsize: {} {}", + mask->bounds().w, + mask->bounds().h); if (sprite->totalFrames() > 1) { - sprintf( - buf+std::strlen(buf), " :frame: %d :clock: %s/%s", + buf += fmt::format( + " :frame: {} :clock: {}/{}", site.frame()+editor->docPref().timeline.firstFrame(), human_readable_time(sprite->frameDuration(site.frame())).c_str(), human_readable_time(sprite->totalAnimationDuration()).c_str()); @@ -573,15 +589,14 @@ bool StandbyState::onUpdateStatusBar(Editor* editor) doc::Grid grid = site.grid(); if (!grid.isEmpty()) { gfx::Point pt = grid.canvasToTile(gfx::Point(spritePos)); - sprintf(buf+std::strlen(buf), " :grid: %d %d", pt.x, pt.y); + buf += fmt::format(" :grid: {} {}", pt.x, pt.y); // Show the tile index of this specific tile if (site.layer() && site.layer()->isTilemap() && site.image()) { if (site.image()->bounds().contains(pt)) { - sprintf(buf+std::strlen(buf), " [%d]", - site.image()->getPixel(pt.x, pt.y)); + buf += fmt::format(" [{}]", site.image()->getPixel(pt.x, pt.y)); } } } @@ -596,14 +611,11 @@ bool StandbyState::onUpdateStatusBar(Editor* editor) int(std::floor(spritePos.x)), int(std::floor(spritePos.y)))) { if (++count == 3) { - sprintf( - buf+std::strlen(buf), " :slice: ..."); + buf += fmt::format(" :slice: ..."); break; } - sprintf( - buf+std::strlen(buf), " :slice: %s", - slice->name().c_str()); + buf += fmt::format(" :slice: {}", slice->name()); } } } diff --git a/src/app/ui/palette_view.cpp b/src/app/ui/palette_view.cpp index 07f98d79b..877cde285 100644 --- a/src/app/ui/palette_view.cpp +++ b/src/app/ui/palette_view.cpp @@ -150,7 +150,7 @@ public: PaletteViewModification::DRAGANDDROP); } void showEntryInStatusBar(StatusBar* statusBar, int index) override { - statusBar->showColor(0, "", app::Color::fromIndex(index)); + statusBar->showColor(0, app::Color::fromIndex(index)); } void showDragInfoInStatusBar(StatusBar* statusBar, bool copy, int destIndex, int newSize) override { statusBar->setStatusText( @@ -281,7 +281,7 @@ public: picks = newPicks; } void showEntryInStatusBar(StatusBar* statusBar, int index) override { - statusBar->showTile(0, "", doc::tile(index, 0)); + statusBar->showTile(0, doc::tile(index, 0)); } void showDragInfoInStatusBar(StatusBar* statusBar, bool copy, int destIndex, int newSize) override { statusBar->setStatusText( diff --git a/src/app/ui/status_bar.cpp b/src/app/ui/status_bar.cpp index 6ae55d318..67f62f0bc 100644 --- a/src/app/ui/status_bar.cpp +++ b/src/app/ui/status_bar.cpp @@ -833,26 +833,28 @@ void StatusBar::showTip(int msecs, const std::string& msg) m_timeout = base::current_tick(); } -void StatusBar::showColor(int msecs, const char* text, const app::Color& color) +void StatusBar::showColor(int msecs, const app::Color& color, + const std::string& text) { if ((base::current_tick() > m_timeout) || (msecs > 0)) { showIndicators(); IndicatorsGeneration gen(m_indicators); gen.add(color); - if (text) - gen.add(text); + if (!text.empty()) + gen.add(text.c_str()); m_timeout = base::current_tick() + msecs; } } -void StatusBar::showTile(int msecs, const char* text, doc::tile_t tile) +void StatusBar::showTile(int msecs, doc::tile_t tile, + const std::string& text) { if ((base::current_tick() > m_timeout) || (msecs > 0)) { IndicatorsGeneration gen(m_indicators); gen.add(tile); - if (text) - gen.add(text); + if (!text.empty()) + gen.add(text.c_str()); m_timeout = base::current_tick() + msecs; } diff --git a/src/app/ui/status_bar.h b/src/app/ui/status_bar.h index 3ffffa4d2..e0c5ca903 100644 --- a/src/app/ui/status_bar.h +++ b/src/app/ui/status_bar.h @@ -1,5 +1,5 @@ // Aseprite -// Copyright (C) 2018-2021 Igara Studio S.A. +// Copyright (C) 2018-2022 Igara Studio S.A. // Copyright (C) 2001-2018 David Capello // // This program is distributed under the terms of @@ -61,8 +61,10 @@ namespace app { bool setStatusText(int msecs, const std::string& text); void showTip(int msecs, const std::string& msg); - void showColor(int msecs, const char* text, const Color& color); - void showTile(int msecs, const char* text, doc::tile_t tile); + void showColor(int msecs, const Color& color, + const std::string& text = std::string()); + void showTile(int msecs, doc::tile_t tile, + const std::string& text = std::string()); void showTool(int msecs, tools::Tool* tool); void showSnapToGridWarning(bool state); diff --git a/src/app/ui/tile_button.cpp b/src/app/ui/tile_button.cpp index 204a9a7a3..d74e2ed5b 100644 --- a/src/app/ui/tile_button.cpp +++ b/src/app/ui/tile_button.cpp @@ -81,7 +81,7 @@ bool TileButton::onProcessMessage(Message* msg) switch (msg->type()) { case kMouseEnterMessage: - StatusBar::instance()->showTile(0, "", m_tile); + StatusBar::instance()->showTile(0, m_tile); break; case kMouseLeaveMessage: diff --git a/src/doc/brush.cpp b/src/doc/brush.cpp index fb935da3d..7d6a724de 100644 --- a/src/doc/brush.cpp +++ b/src/doc/brush.cpp @@ -1,5 +1,5 @@ // Aseprite Document Library -// Copyright (C) 2019-2021 Igara Studio S.A. +// Copyright (C) 2019-2022 Igara Studio S.A. // Copyright (C) 2001-2016 David Capello // // This file is released under the terms of the MIT license. @@ -281,6 +281,12 @@ void Brush::setImageColor(ImageColor imageColor, color_t color) } } +void Brush::resetImageColors() +{ + if (m_backupImage) + m_image.reset(Image::createCopy(m_backupImage.get())); +} + void Brush::setCenter(const gfx::Point& center) { m_center = center; diff --git a/src/doc/brush.h b/src/doc/brush.h index d5bfb804a..98da5f7e1 100644 --- a/src/doc/brush.h +++ b/src/doc/brush.h @@ -1,5 +1,5 @@ // Aseprite Document Library -// Copyright (C) 2019-2020 Igara Studio S.A. +// Copyright (C) 2019-2022 Igara Studio S.A. // Copyright (C) 2001-2018 David Capello // // This file is released under the terms of the MIT license. @@ -52,7 +52,12 @@ namespace doc { void setAngle(int angle); void setImage(const Image* image, const Image* maskBitmap); + + // Special functions to change the colors of the image or restore + // the colors to the original image used to create the brush. void setImageColor(ImageColor imageColor, color_t color); + void resetImageColors(); + void setPattern(BrushPattern pattern) { m_pattern = pattern; } @@ -64,6 +69,15 @@ namespace doc { } void setCenter(const gfx::Point& center); + // Returns the original image used to create the brush before + // calling any setImageColor() + Image* originalImage() const { + if (m_backupImage) + return m_backupImage.get(); + else + return m_image.get(); + } + private: void clean(); void regenerate(); diff --git a/src/ui/int_entry.cpp b/src/ui/int_entry.cpp index 0babcce36..a76915d4d 100644 --- a/src/ui/int_entry.cpp +++ b/src/ui/int_entry.cpp @@ -176,14 +176,14 @@ void IntEntry::openPopup() { m_slider.setValue(getValue()); - m_popupWindow = new TransparentPopupWindow(PopupWindow::ClickBehavior::CloseOnClickInOtherWindow); + m_popupWindow = std::make_unique(PopupWindow::ClickBehavior::CloseOnClickInOtherWindow); m_popupWindow->setAutoRemap(false); m_popupWindow->addChild(&m_slider); m_popupWindow->Close.connect(&IntEntry::onPopupClose, this); fit_bounds( display(), - m_popupWindow, + m_popupWindow.get(), gfx::Rect(0, 0, 128*guiscale(), m_popupWindow->sizeHint().h), [this](const gfx::Rect& workarea, gfx::Rect& rc, @@ -214,8 +214,7 @@ void IntEntry::closePopup() removeSlider(); m_popupWindow->closeWindow(nullptr); - delete m_popupWindow; - m_popupWindow = nullptr; + m_popupWindow.reset(); } } @@ -237,7 +236,7 @@ void IntEntry::onPopupClose(CloseEvent& ev) void IntEntry::removeSlider() { if (m_popupWindow && - m_slider.parent() == m_popupWindow) { + m_slider.parent() == m_popupWindow.get()) { m_popupWindow->removeChild(&m_slider); } } diff --git a/src/ui/int_entry.h b/src/ui/int_entry.h index 31736b9c8..7e64332f3 100644 --- a/src/ui/int_entry.h +++ b/src/ui/int_entry.h @@ -1,4 +1,5 @@ // Aseprite UI Library +// Copyright (C) 2022 Igara Studio S.A. // Copyright (C) 2001-2017 David Capello // // This file is released under the terms of the MIT license. @@ -11,6 +12,8 @@ #include "ui/entry.h" #include "ui/slider.h" +#include + namespace ui { class CloseEvent; @@ -43,7 +46,7 @@ namespace ui { int m_min; int m_max; Slider m_slider; - PopupWindow* m_popupWindow; + std::unique_ptr m_popupWindow; bool m_changeFromSlider; };