Skip to content

Fix tiled mode when moving pixels #5369

Merged
dacap merged 7 commits into
aseprite:betafrom
martincapello:loop-selection-into-tiled-area
Nov 19, 2025
Merged

Fix tiled mode when moving pixels #5369
dacap merged 7 commits into
aseprite:betafrom
martincapello:loop-selection-into-tiled-area

Conversation

@martincapello

@martincapello martincapello commented Aug 19, 2025

Copy link
Copy Markdown
Member

Fix #1457

This PR doesn't include changes to make the fix work with tilemaps. Should this be addressed? If so, IMO it would be better to do it in a separate issue.

@aseprite-bot aseprite-bot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

clang-tidy made some suggestions


auto corners = transformation.transformedCorners();
gfx::Rect bounds = corners.bounds(transformation.cornerThick());
gfx::Rect unexpandedBounds = bounds;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: variable 'unexpandedBounds' of type 'gfx::Rect' (aka 'RectT') can be declared 'const' [misc-const-correctness]

Suggested change
gfx::Rect unexpandedBounds = bounds;
gfx::Rect const unexpandedBounds = bounds;

Comment thread src/app/ui/editor/pixels_movement.cpp Outdated

// Temporal image. Used for copying several times the pixels being transformed by the user
// when tile mode is active.
doc::ImageRef tmp;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: variable 'tmp' of type 'doc::ImageRef' (aka 'shared_ptr') can be declared 'const' [misc-const-correctness]

Suggested change
doc::ImageRef tmp;
doc::ImageRef const tmp;

@aseprite-bot aseprite-bot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

clang-tidy made some suggestions

Comment thread src/app/util/tiled_mode.h Outdated
if (int(m_mode) & int(filters::TiledMode::X_AXIS))
rgn.offset(m_canvas->width() * (1 - (rgn.bounds().x / m_canvas->width())), 0);
if (int(m_mode) & int(filters::TiledMode::X_AXIS)) {
int w = rgn.bounds().origin().x < 0 ? (rgn.bounds().w - m_canvas->width()) : 0;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: variable 'w' of type 'int' can be declared 'const' [misc-const-correctness]

Suggested change
int w = rgn.bounds().origin().x < 0 ? (rgn.bounds().w - m_canvas->width()) : 0;
int const w = rgn.bounds().origin().x < 0 ? (rgn.bounds().w - m_canvas->width()) : 0;

Comment thread src/app/util/tiled_mode.h Outdated
}

if (int(m_mode) & int(filters::TiledMode::Y_AXIS)) {
int h = rgn.bounds().origin().y < 0 ? (rgn.bounds().h - m_canvas->height()) : 0;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: variable 'h' of type 'int' can be declared 'const' [misc-const-correctness]

Suggested change
int h = rgn.bounds().origin().y < 0 ? (rgn.bounds().h - m_canvas->height()) : 0;
int const h = rgn.bounds().origin().y < 0 ? (rgn.bounds().h - m_canvas->height()) : 0;

Comment thread src/app/util/tiled_mode.h Outdated
// When Y axis tiled mode is enable, the analog algorithm is used for the Y coordinates.
void wrapTransformation(Transformation* transformation) const
{
gfx::Rect bounds = transformation->transformedBounds();

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: variable 'bounds' of type 'gfx::Rect' (aka 'RectT') can be declared 'const' [misc-const-correctness]

Suggested change
gfx::Rect bounds = transformation->transformedBounds();
gfx::Rect const bounds = transformation->transformedBounds();

Comment thread src/app/util/tiled_mode.h Outdated
doc::ImageRef tmp;
Mask tmpMask;
tmpMask.freeze();
int x = (hasModeFlag(TiledMode::X_AXIS) ? m_canvas->width() : 0);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: variable 'x' of type 'int' can be declared 'const' [misc-const-correctness]

Suggested change
int x = (hasModeFlag(TiledMode::X_AXIS) ? m_canvas->width() : 0);
int const x = (hasModeFlag(TiledMode::X_AXIS) ? m_canvas->width() : 0);

Comment thread src/app/util/tiled_mode.h Outdated
Mask tmpMask;
tmpMask.freeze();
int x = (hasModeFlag(TiledMode::X_AXIS) ? m_canvas->width() : 0);
int y = (hasModeFlag(TiledMode::Y_AXIS) ? m_canvas->height() : 0);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: variable 'y' of type 'int' can be declared 'const' [misc-const-correctness]

Suggested change
int y = (hasModeFlag(TiledMode::Y_AXIS) ? m_canvas->height() : 0);
int const y = (hasModeFlag(TiledMode::Y_AXIS) ? m_canvas->height() : 0);

Comment thread src/app/util/tiled_mode.h Outdated
tmpMask.freeze();
int x = (hasModeFlag(TiledMode::X_AXIS) ? m_canvas->width() : 0);
int y = (hasModeFlag(TiledMode::Y_AXIS) ? m_canvas->height() : 0);
int w = dst->width() - 2 * x;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: variable 'w' of type 'int' can be declared 'const' [misc-const-correctness]

Suggested change
int w = dst->width() - 2 * x;
int const w = dst->width() - 2 * x;

Comment thread src/app/util/tiled_mode.h Outdated
int x = (hasModeFlag(TiledMode::X_AXIS) ? m_canvas->width() : 0);
int y = (hasModeFlag(TiledMode::Y_AXIS) ? m_canvas->height() : 0);
int w = dst->width() - 2 * x;
int h = dst->height() - 2 * y;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: variable 'h' of type 'int' can be declared 'const' [misc-const-correctness]

Suggested change
int h = dst->height() - 2 * y;
int const h = dst->height() - 2 * y;

@martincapello martincapello marked this pull request as ready for review August 20, 2025 21:09
@martincapello martincapello requested a review from dacap as a code owner August 20, 2025 21:09
@Gasparoken

Gasparoken commented Aug 27, 2025

Copy link
Copy Markdown
Member

Works great! A minor observation: Perhaps it would be better to use the new hasModeFlag() function in more places instead the expression ((int(m_mode) & int(filters::TiledMode::SOME_MODE))).

Throughout testing, I discovered that the pivot point isn't positioned correctly in tiled mode, but that's a different issue (#2316); I'll look into a fix for this in another PR.

@martincapello martincapello assigned dacap and unassigned martincapello Aug 27, 2025
@dacap dacap linked an issue Oct 15, 2025 that may be closed by this pull request
@dacap

dacap commented Oct 15, 2025

Copy link
Copy Markdown
Member

It works great 👍 it would be nice to move the whole TiledModeHelper impl in its own .cpp file. Adjusting the required #includes (e.g. #include "doc/algorithm/rotate.h" can be moved to the .cpp)

@dacap dacap assigned martincapello and unassigned dacap Oct 15, 2025
@martincapello martincapello force-pushed the loop-selection-into-tiled-area branch from 9df632b to ea70862 Compare October 17, 2025 13:50
@martincapello martincapello assigned dacap and unassigned martincapello Oct 17, 2025

@aseprite-bot aseprite-bot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

clang-tidy made some suggestions

const render::Projection* proj) const
{
gfx::Region tile = rgn;
const bool xTiled = (int(m_mode) & int(filters::TiledMode::X_AXIS));

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: implicit conversion 'int' -> 'bool' [readability-implicit-bool-conversion]

Suggested change
const bool xTiled = (int(m_mode) & int(filters::TiledMode::X_AXIS));
const bool xTiled = (int(m_mode) & int(filters::TiledMode::X_AXIS)) != 0;

{
gfx::Region tile = rgn;
const bool xTiled = (int(m_mode) & int(filters::TiledMode::X_AXIS));
const bool yTiled = (int(m_mode) & int(filters::TiledMode::Y_AXIS));

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: implicit conversion 'int' -> 'bool' [readability-implicit-bool-conversion]

Suggested change
const bool yTiled = (int(m_mode) & int(filters::TiledMode::Y_AXIS));
const bool yTiled = (int(m_mode) & int(filters::TiledMode::Y_AXIS)) != 0;

return;

if (int(m_mode) & int(filters::TiledMode::X_AXIS)) {
int w = rgn.bounds().origin().x < 0 ? (rgn.bounds().w - m_canvas->width()) : 0;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: variable 'w' of type 'int' can be declared 'const' [misc-const-correctness]

Suggested change
int w = rgn.bounds().origin().x < 0 ? (rgn.bounds().w - m_canvas->width()) : 0;
int const w = rgn.bounds().origin().x < 0 ? (rgn.bounds().w - m_canvas->width()) : 0;

}

if (int(m_mode) & int(filters::TiledMode::Y_AXIS)) {
int h = rgn.bounds().origin().y < 0 ? (rgn.bounds().h - m_canvas->height()) : 0;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: variable 'h' of type 'int' can be declared 'const' [misc-const-correctness]

Suggested change
int h = rgn.bounds().origin().y < 0 ? (rgn.bounds().h - m_canvas->height()) : 0;
int const h = rgn.bounds().origin().y < 0 ? (rgn.bounds().h - m_canvas->height()) : 0;

// including its pivot.
void TiledModeHelper::wrapTransformation(Transformation* transformation) const
{
gfx::Rect bounds = transformation->transformedBounds();

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: variable 'bounds' of type 'gfx::Rect' (aka 'RectT') can be declared 'const' [misc-const-correctness]

Suggested change
gfx::Rect bounds = transformation->transformedBounds();
gfx::Rect const bounds = transformation->transformedBounds();

doc::ImageRef tmp;
Mask tmpMask;
tmpMask.freeze();
int x = (hasModeFlag(TiledMode::X_AXIS) ? m_canvas->width() : 0);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: variable 'x' of type 'int' can be declared 'const' [misc-const-correctness]

Suggested change
int x = (hasModeFlag(TiledMode::X_AXIS) ? m_canvas->width() : 0);
int const x = (hasModeFlag(TiledMode::X_AXIS) ? m_canvas->width() : 0);

Mask tmpMask;
tmpMask.freeze();
int x = (hasModeFlag(TiledMode::X_AXIS) ? m_canvas->width() : 0);
int y = (hasModeFlag(TiledMode::Y_AXIS) ? m_canvas->height() : 0);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: variable 'y' of type 'int' can be declared 'const' [misc-const-correctness]

Suggested change
int y = (hasModeFlag(TiledMode::Y_AXIS) ? m_canvas->height() : 0);
int const y = (hasModeFlag(TiledMode::Y_AXIS) ? m_canvas->height() : 0);

tmpMask.freeze();
int x = (hasModeFlag(TiledMode::X_AXIS) ? m_canvas->width() : 0);
int y = (hasModeFlag(TiledMode::Y_AXIS) ? m_canvas->height() : 0);
int w = dst->width() - 2 * x;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: variable 'w' of type 'int' can be declared 'const' [misc-const-correctness]

Suggested change
int w = dst->width() - 2 * x;
int const w = dst->width() - 2 * x;

int x = (hasModeFlag(TiledMode::X_AXIS) ? m_canvas->width() : 0);
int y = (hasModeFlag(TiledMode::Y_AXIS) ? m_canvas->height() : 0);
int w = dst->width() - 2 * x;
int h = dst->height() - 2 * y;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: variable 'h' of type 'int' can be declared 'const' [misc-const-correctness]

Suggested change
int h = dst->height() - 2 * y;
int const h = dst->height() - 2 * y;

@dacap

dacap commented Nov 19, 2025

Copy link
Copy Markdown
Member

LGTM! 👍

@dacap dacap merged commit a0749d4 into aseprite:beta Nov 19, 2025
12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Ability to "loop" when moving selection into tiled area

4 participants