Merge branch 'editor-functions-refactor' into beta

This commit is contained in:
David Capello 2021-05-20 15:50:34 -03:00
commit b3e80c49a1
4 changed files with 140 additions and 65 deletions

View File

@ -147,6 +147,7 @@ Editor::Editor(Doc* document, EditorFlags flags)
, m_layer(m_sprite->root()->firstLayer())
, m_frame(frame_t(0))
, m_docPref(Preferences::instance().document(document))
, m_tiledModeHelper(app::TiledModeHelper(m_docPref.tiled.mode(), m_sprite))
, m_brushPreview(this)
, m_toolLoopModifiers(tools::ToolLoopModifiers::kNone)
, m_padding(0, 0)
@ -2222,6 +2223,8 @@ void Editor::onTiledModeChange()
screenPos = editorToScreen(spritePos);
centerInSpritePoint(spritePos);
m_tiledModeHelper.mode(m_docPref.tiled.mode());
}
void Editor::onShowExtrasChange()
@ -2810,77 +2813,23 @@ gfx::Point Editor::calcExtraPadding(const Projection& proj)
gfx::Size Editor::canvasSize() const
{
gfx::Size sz(m_sprite->width(),
m_sprite->height());
if (int(m_docPref.tiled.mode()) & int(filters::TiledMode::X_AXIS)) {
sz.w += sz.w*2;
}
if (int(m_docPref.tiled.mode()) & int(filters::TiledMode::Y_AXIS)) {
sz.h += sz.h*2;
}
return sz;
return m_tiledModeHelper.canvasSize();
}
gfx::Point Editor::mainTilePosition() const
{
gfx::Point pt(0, 0);
if (int(m_docPref.tiled.mode()) & int(filters::TiledMode::X_AXIS)) {
pt.x += m_sprite->width();
}
if (int(m_docPref.tiled.mode()) & int(filters::TiledMode::Y_AXIS)) {
pt.y += m_sprite->height();
}
return pt;
return m_tiledModeHelper.mainTilePosition();
}
void Editor::expandRegionByTiledMode(gfx::Region& rgn,
const bool withProj) const
{
gfx::Region tile = rgn;
const bool xTiled = (int(m_docPref.tiled.mode()) & int(filters::TiledMode::X_AXIS));
const bool yTiled = (int(m_docPref.tiled.mode()) & int(filters::TiledMode::Y_AXIS));
int w = m_sprite->width();
int h = m_sprite->height();
if (withProj) {
w = m_proj.applyX(w);
h = m_proj.applyY(h);
}
if (xTiled) {
tile.offset(w, 0); rgn |= tile;
tile.offset(w, 0); rgn |= tile;
tile.offset(-2*w, 0);
}
if (yTiled) {
tile.offset(0, h); rgn |= tile;
tile.offset(0, h); rgn |= tile;
tile.offset(0, -2*h);
}
if (xTiled && yTiled) {
tile.offset(w, h); rgn |= tile;
tile.offset(w, 0); rgn |= tile;
tile.offset(-w, h); rgn |= tile;
tile.offset(w, 0); rgn |= tile;
}
m_tiledModeHelper.expandRegionByTiledMode(rgn, withProj ? &m_proj : nullptr);
}
void Editor::collapseRegionByTiledMode(gfx::Region& rgn) const
{
auto canvasSize = this->canvasSize();
rgn &= gfx::Region(gfx::Rect(canvasSize));
const int sprW = m_sprite->width();
const int sprH = m_sprite->height();
gfx::Region newRgn;
for (int v=0; v<canvasSize.h; v+=sprH) {
for (int u=0; u<canvasSize.w; u+=sprW) {
gfx::Region tmp(gfx::Rect(u, v, sprW, sprH));
tmp &= rgn;
tmp.offset(-u, -v);
newRgn |= tmp;
}
}
rgn = newRgn;
m_tiledModeHelper.collapseRegionByTiledMode(rgn);
}
bool Editor::isMovingPixels() const

View File

@ -22,6 +22,7 @@
#include "app/ui/editor/editor_state.h"
#include "app/ui/editor/editor_states_history.h"
#include "app/ui/tile_source.h"
#include "app/util/tiled_mode.h"
#include "doc/algorithm/flip_type.h"
#include "doc/frame.h"
#include "doc/image_buffer.h"
@ -403,6 +404,8 @@ namespace app {
frame_t m_frame; // Active frame in the editor
render::Projection m_proj; // Zoom/pixel ratio in the editor
DocumentPreferences& m_docPref;
// Helper functions affected by the current Tiled Mode.
app::TiledModeHelper m_tiledModeHelper;
// Brush preview
BrushPreview m_brushPreview;

View File

@ -473,6 +473,7 @@ class ToolLoopImpl : public ToolLoopBase,
std::unique_ptr<ExpandCelCanvas> m_expandCelCanvas;
Image* m_floodfillSrcImage;
bool m_saveLastPoint;
app::TiledModeHelper m_tiledModeHelper;
public:
ToolLoopImpl(Editor* editor,
@ -493,6 +494,7 @@ public:
ModifyDocument))
, m_floodfillSrcImage(nullptr)
, m_saveLastPoint(saveLastPoint)
, m_tiledModeHelper(m_docPref.tiled.mode(), m_sprite)
{
if (m_pointShape->isFloodFill()) {
if (m_tilesMode) {
@ -766,7 +768,7 @@ public:
getPointShape()->getModifiedArea(this, pos.x, pos.y, r);
gfx::Region rgn(r);
m_editor->collapseRegionByTiledMode(rgn);
m_tiledModeHelper.collapseRegionByTiledMode(rgn);
for (auto a : rgn) {
ImageRef i(Image::create(getSrcImage()->pixelFormat(), a.w, a.h));
@ -830,16 +832,28 @@ private:
void wrapPositionOnTiledMode(const tools::Stroke::Pt& pt, tools::Stroke::Pt& result) {
result = pt;
if (getTiledMode() == TiledMode::NONE)
return;
if (int(getTiledMode()) & int(TiledMode::X_AXIS)) {
result.x %= m_editor->canvasSize().w;
if (result.x < 0)
result.x += m_editor->canvasSize().w;
result.x %= m_tiledModeHelper.canvasSize().w;
}
if (int(getTiledMode()) & int(TiledMode::Y_AXIS)) {
result.y %= m_editor->canvasSize().h;
if (result.y < 0)
result.y += m_editor->canvasSize().h;
result.y %= m_tiledModeHelper.canvasSize().h;
}
gfx::Rect r;
getPointShape()->getModifiedArea(this, result.x, result.y, r);
if (r.x < 0)
result.x += m_sprite->width();
else if (r.x2() > m_tiledModeHelper.canvasSize().w)
result.x -= m_sprite->width();
if (r.y < 0)
result.y += m_sprite->height();
else if (r.y2() > m_tiledModeHelper.canvasSize().h)
result.y -= m_sprite->height();
}
};

109
src/app/util/tiled_mode.h Normal file
View File

@ -0,0 +1,109 @@
// Aseprite
// Copyright (C) 2001-2015 David Capello
//
// This program is distributed under the terms of
// the End-User License Agreement for Aseprite.
#ifndef APP_TILED_MODE_H_INCLUDED
#define APP_TILED_MODE_H_INCLUDED
#pragma once
#include "filters/tiled_mode.h"
#include "app/doc.h"
#include "gfx/region.h"
#include "render/projection.h"
namespace app {
class TiledModeHelper {
public:
TiledModeHelper(const filters::TiledMode mode, const doc::Sprite* canvas) :
m_mode(mode),
m_canvas(canvas) {
}
~TiledModeHelper() {}
void mode(const filters::TiledMode mode) {
m_mode = mode;
}
gfx::Size canvasSize() const {
gfx::Size sz(m_canvas->width(),
m_canvas->height());
if (int(m_mode) & int(filters::TiledMode::X_AXIS)) {
sz.w += sz.w * 2;
}
if (int(m_mode) & int(filters::TiledMode::Y_AXIS)) {
sz.h += sz.h * 2;
}
return sz;
}
gfx::Point mainTilePosition() const {
gfx::Point pt(0, 0);
if (int(m_mode) & int(filters::TiledMode::X_AXIS)) {
pt.x += m_canvas->width();
}
if (int(m_mode) & int(filters::TiledMode::Y_AXIS)) {
pt.y += m_canvas->height();
}
return pt;
}
void expandRegionByTiledMode(gfx::Region& rgn,
const render::Projection* proj = nullptr) const {
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));
int w = m_canvas->width();
int h = m_canvas->height();
if (proj) {
w = proj->applyX(w);
h = proj->applyY(h);
}
if (xTiled) {
tile.offset(w, 0); rgn |= tile;
tile.offset(w, 0); rgn |= tile;
tile.offset(-2 * w, 0);
}
if (yTiled) {
tile.offset(0, h); rgn |= tile;
tile.offset(0, h); rgn |= tile;
tile.offset(0, -2 * h);
}
if (xTiled && yTiled) {
tile.offset(w, h); rgn |= tile;
tile.offset(w, 0); rgn |= tile;
tile.offset(-w, h); rgn |= tile;
tile.offset(w, 0); rgn |= tile;
}
}
void collapseRegionByTiledMode(gfx::Region& rgn) const {
auto canvasSize = this->canvasSize();
rgn &= gfx::Region(gfx::Rect(canvasSize));
const int sprW = m_canvas->width();
const int sprH = m_canvas->height();
gfx::Region newRgn;
for (int v = 0; v < canvasSize.h; v += sprH) {
for (int u = 0; u < canvasSize.w; u += sprW) {
gfx::Region tmp(gfx::Rect(u, v, sprW, sprH));
tmp &= rgn;
tmp.offset(-u, -v);
newRgn |= tmp;
}
}
rgn = newRgn;
}
private:
filters::TiledMode m_mode;
const doc::Sprite* m_canvas;
};
} // namespace app
#endif