mirror of
https://github.com/aseprite/aseprite.git
synced 2025-02-05 00:39:50 +00:00
Add 'x' and 'y' as input parameters to app.command.Paste()
This commit is contained in:
parent
de1fc581f2
commit
e70bbbd369
@ -1,4 +1,5 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2024 Igara Studio S.A.
|
||||
// Copyright (C) 2001-2017 David Capello
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
@ -10,6 +11,7 @@
|
||||
|
||||
#include "app/app.h"
|
||||
#include "app/commands/command.h"
|
||||
#include "app/commands/params.h"
|
||||
#include "app/ui/input_chain.h"
|
||||
|
||||
namespace app {
|
||||
@ -19,8 +21,11 @@ public:
|
||||
PasteCommand();
|
||||
|
||||
protected:
|
||||
void onLoadParams(const Params& params) override;
|
||||
bool onEnabled(Context* ctx) override;
|
||||
void onExecute(Context* ctx) override;
|
||||
private:
|
||||
std::shared_ptr<gfx::Point> m_position;
|
||||
};
|
||||
|
||||
PasteCommand::PasteCommand()
|
||||
@ -28,6 +33,16 @@ PasteCommand::PasteCommand()
|
||||
{
|
||||
}
|
||||
|
||||
void PasteCommand::onLoadParams(const Params& params)
|
||||
{
|
||||
m_position.reset();
|
||||
if (params.has_param("x") || params.has_param("y")) {
|
||||
m_position.reset(new gfx::Point);
|
||||
m_position->x = params.get_as<int>("x");
|
||||
m_position->y = params.get_as<int>("y");
|
||||
}
|
||||
}
|
||||
|
||||
bool PasteCommand::onEnabled(Context* ctx)
|
||||
{
|
||||
return App::instance()->inputChain().canPaste(ctx);
|
||||
@ -35,7 +50,7 @@ bool PasteCommand::onEnabled(Context* ctx)
|
||||
|
||||
void PasteCommand::onExecute(Context* ctx)
|
||||
{
|
||||
App::instance()->inputChain().paste(ctx);
|
||||
App::instance()->inputChain().paste(ctx, m_position.get());
|
||||
}
|
||||
|
||||
Command* CommandFactory::createPasteCommand()
|
||||
|
@ -84,13 +84,14 @@ bool ScriptInputChain::onCopy(Context* ctx)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ScriptInputChain::onPaste(Context* ctx)
|
||||
bool ScriptInputChain::onPaste(Context* ctx,
|
||||
const gfx::Point* position)
|
||||
{
|
||||
Clipboard* clipboard = ctx->clipboard();
|
||||
if (!clipboard)
|
||||
return false;
|
||||
if (clipboard->format() == ClipboardFormat::Image) {
|
||||
clipboard->paste(ctx, false);
|
||||
clipboard->paste(ctx, false, position);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -27,7 +27,8 @@ namespace app {
|
||||
bool onCanClear(Context* ctx) override;
|
||||
bool onCut(Context* ctx) override;
|
||||
bool onCopy(Context* ctx) override;
|
||||
bool onPaste(Context* ctx) override;
|
||||
bool onPaste(Context* ctx,
|
||||
const gfx::Point* position) override;
|
||||
bool onClear(Context* ctx) override;
|
||||
void onCancel(Context* ctx) override;
|
||||
};
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2018-2023 Igara Studio S.A.
|
||||
// Copyright (C) 2018-2024 Igara Studio S.A.
|
||||
// Copyright (C) 2001-2018 David Capello
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
@ -1692,7 +1692,8 @@ bool ColorBar::onCopy(Context* ctx)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ColorBar::onPaste(Context* ctx)
|
||||
bool ColorBar::onPaste(Context* ctx,
|
||||
const gfx::Point* position)
|
||||
{
|
||||
if (m_tilemapMode == TilemapMode::Tiles) {
|
||||
showRemapTiles();
|
||||
|
@ -119,7 +119,8 @@ namespace app {
|
||||
bool onCanClear(Context* ctx) override;
|
||||
bool onCut(Context* ctx) override;
|
||||
bool onCopy(Context* ctx) override;
|
||||
bool onPaste(Context* ctx) override;
|
||||
bool onPaste(Context* ctx,
|
||||
const gfx::Point* position) override;
|
||||
bool onClear(Context* ctx) override;
|
||||
void onCancel(Context* ctx) override;
|
||||
|
||||
|
@ -589,12 +589,13 @@ bool DocView::onCopy(Context* ctx)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool DocView::onPaste(Context* ctx)
|
||||
bool DocView::onPaste(Context* ctx,
|
||||
const gfx::Point* position)
|
||||
{
|
||||
auto clipboard = ctx->clipboard();
|
||||
if (clipboard->format() == ClipboardFormat::Image ||
|
||||
clipboard->format() == ClipboardFormat::Tilemap) {
|
||||
clipboard->paste(ctx, true);
|
||||
clipboard->paste(ctx, true, position);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
|
@ -102,7 +102,8 @@ namespace app {
|
||||
bool onCanClear(Context* ctx) override;
|
||||
bool onCut(Context* ctx) override;
|
||||
bool onCopy(Context* ctx) override;
|
||||
bool onPaste(Context* ctx) override;
|
||||
bool onPaste(Context* ctx,
|
||||
const gfx::Point* position) override;
|
||||
bool onClear(Context* ctx) override;
|
||||
void onCancel(Context* ctx) override;
|
||||
|
||||
|
@ -2654,7 +2654,9 @@ void Editor::setZoomAndCenterInMouse(const Zoom& zoom,
|
||||
}
|
||||
}
|
||||
|
||||
void Editor::pasteImage(const Image* image, const Mask* mask)
|
||||
void Editor::pasteImage(const Image* image,
|
||||
const Mask* mask,
|
||||
const gfx::Point* position)
|
||||
{
|
||||
ASSERT(image);
|
||||
|
||||
@ -2686,11 +2688,14 @@ void Editor::pasteImage(const Image* image, const Mask* mask)
|
||||
Sprite* sprite = this->sprite();
|
||||
|
||||
// Check bounds where the image will be pasted.
|
||||
int x = mask->bounds().x;
|
||||
int y = mask->bounds().y;
|
||||
int x = (position ? position->x : mask->bounds().x);
|
||||
int y = (position ? position->y : mask->bounds().y);
|
||||
{
|
||||
const Rect visibleBounds = getViewportBounds();
|
||||
const Point maskCenter = mask->bounds().center();
|
||||
const Point maskCenter = mask->bounds().center() +
|
||||
(position ? gfx::Point(position->x - mask->bounds().x,
|
||||
position->y - mask->bounds().y)
|
||||
: gfx::Point());
|
||||
|
||||
// If the pasted image original location center point isn't
|
||||
// visible, we center the image in the editor's visible bounds.
|
||||
@ -2743,7 +2748,8 @@ void Editor::pasteImage(const Image* image, const Mask* mask)
|
||||
m_brushPreview.hide();
|
||||
|
||||
Mask mask2(*mask);
|
||||
mask2.setOrigin(x, y);
|
||||
position ? mask2.setOrigin(position->x, position->y)
|
||||
: mask2.setOrigin(x, y);
|
||||
|
||||
PixelsMovementPtr pixelsMovement(
|
||||
new PixelsMovement(UIContext::instance(), site,
|
||||
|
@ -252,7 +252,9 @@ namespace app {
|
||||
void setZoomAndCenterInMouse(const render::Zoom& zoom,
|
||||
const gfx::Point& mousePos, ZoomBehavior zoomBehavior);
|
||||
|
||||
void pasteImage(const Image* image, const Mask* mask = nullptr);
|
||||
void pasteImage(const Image* image,
|
||||
const Mask* mask = nullptr,
|
||||
const gfx::Point* position = nullptr);
|
||||
|
||||
void startSelectionTransformation(const gfx::Point& move, double angle);
|
||||
void startFlipTransformation(doc::algorithm::FlipType flipType);
|
||||
|
@ -230,7 +230,8 @@ bool HomeView::onCopy(Context* ctx)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool HomeView::onPaste(Context* ctx)
|
||||
bool HomeView::onPaste(Context* ctx,
|
||||
const gfx::Point* position)
|
||||
{
|
||||
auto clipboard = ctx->clipboard();
|
||||
if (clipboard->format() == ClipboardFormat::Image) {
|
||||
|
@ -74,7 +74,8 @@ namespace app {
|
||||
bool onCanClear(Context* ctx) override;
|
||||
bool onCut(Context* ctx) override;
|
||||
bool onCopy(Context* ctx) override;
|
||||
bool onPaste(Context* ctx) override;
|
||||
bool onPaste(Context* ctx,
|
||||
const gfx::Point* position) override;
|
||||
bool onClear(Context* ctx) override;
|
||||
void onCancel(Context* ctx) override;
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2024 Igara Studio S.A.
|
||||
// Copyright (C) 2001-2018 David Capello
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
@ -87,10 +88,11 @@ void InputChain::copy(Context* ctx)
|
||||
}
|
||||
}
|
||||
|
||||
void InputChain::paste(Context* ctx)
|
||||
void InputChain::paste(Context* ctx,
|
||||
const gfx::Point* position)
|
||||
{
|
||||
for (auto e : m_elements) {
|
||||
if (e->onCanPaste(ctx) && e->onPaste(ctx))
|
||||
if (e->onCanPaste(ctx) && e->onPaste(ctx, position))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2024 Igara Studio S.A.
|
||||
// Copyright (C) 2001-2018 David Capello
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
@ -8,6 +9,8 @@
|
||||
#define APP_INPUT_CHAIN_H_INCLUDED
|
||||
#pragma once
|
||||
|
||||
#include "gfx/point.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace ui {
|
||||
@ -35,7 +38,8 @@ namespace app {
|
||||
|
||||
void cut(Context* ctx);
|
||||
void copy(Context* ctx);
|
||||
void paste(Context* ctx);
|
||||
void paste(Context* ctx,
|
||||
const gfx::Point* position);
|
||||
void clear(Context* ctx);
|
||||
void cancel(Context* ctx);
|
||||
|
||||
|
@ -9,6 +9,8 @@
|
||||
#define APP_INPUT_CHAIN_ELEMENT_H_INCLUDED
|
||||
#pragma once
|
||||
|
||||
#include "gfx/point.h"
|
||||
|
||||
namespace ui {
|
||||
class Message;
|
||||
}
|
||||
@ -34,7 +36,8 @@ namespace app {
|
||||
// which catch any exception that is thrown.
|
||||
virtual bool onCut(Context* ctx) = 0;
|
||||
virtual bool onCopy(Context* ctx) = 0;
|
||||
virtual bool onPaste(Context* ctx) = 0;
|
||||
virtual bool onPaste(Context* ctx,
|
||||
const gfx::Point* position) = 0;
|
||||
virtual bool onClear(Context* ctx) = 0;
|
||||
virtual void onCancel(Context* ctx) = 0;
|
||||
};
|
||||
|
@ -4398,7 +4398,8 @@ bool Timeline::onCopy(Context* ctx)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Timeline::onPaste(Context* ctx)
|
||||
bool Timeline::onPaste(Context* ctx,
|
||||
const gfx::Point* position)
|
||||
{
|
||||
auto clipboard = ctx->clipboard();
|
||||
if (clipboard->format() == ClipboardFormat::DocRange) {
|
||||
|
@ -190,7 +190,8 @@ namespace app {
|
||||
bool onCanClear(Context* ctx) override;
|
||||
bool onCut(Context* ctx) override;
|
||||
bool onCopy(Context* ctx) override;
|
||||
bool onPaste(Context* ctx) override;
|
||||
bool onPaste(Context* ctx,
|
||||
const gfx::Point* position) override;
|
||||
bool onClear(Context* ctx) override;
|
||||
void onCancel(Context* ctx) override;
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2018-2022 Igara Studio S.A.
|
||||
// Copyright (C) 2018-2024 Igara Studio S.A.
|
||||
// Copyright (C) 2001-2018 David Capello
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
@ -381,12 +381,13 @@ bool Workspace::onCopy(Context* ctx)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Workspace::onPaste(Context* ctx)
|
||||
bool Workspace::onPaste(Context* ctx,
|
||||
const gfx::Point* position)
|
||||
{
|
||||
WorkspaceView* view = activeView();
|
||||
InputChainElement* activeElement = (view ? view->onGetInputChainElement(): nullptr);
|
||||
if (activeElement)
|
||||
return activeElement->onPaste(ctx);
|
||||
return activeElement->onPaste(ctx, position);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2022 Igara Studio S.A.
|
||||
// Copyright (C) 2022-2024 Igara Studio S.A.
|
||||
// Copyright (C) 2001-2018 David Capello
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
@ -71,7 +71,8 @@ namespace app {
|
||||
bool onCanClear(Context* ctx) override;
|
||||
bool onCut(Context* ctx) override;
|
||||
bool onCopy(Context* ctx) override;
|
||||
bool onPaste(Context* ctx) override;
|
||||
bool onPaste(Context* ctx,
|
||||
const gfx::Point* position) override;
|
||||
bool onClear(Context* ctx) override;
|
||||
void onCancel(Context* ctx) override;
|
||||
|
||||
|
@ -34,6 +34,8 @@
|
||||
#include "app/util/new_image_from_mask.h"
|
||||
#include "app/util/range_utils.h"
|
||||
#include "clip/clip.h"
|
||||
#include "doc/algorithm/shrink_bounds.h"
|
||||
#include "doc/blend_image.h"
|
||||
#include "doc/doc.h"
|
||||
#include "render/dithering.h"
|
||||
#include "render/ordered_dither.h"
|
||||
@ -425,7 +427,7 @@ void Clipboard::copyImage(const Image* image,
|
||||
(mask ? new Mask(*mask): nullptr),
|
||||
(pal ? new Palette(*pal): nullptr),
|
||||
nullptr,
|
||||
true, false);
|
||||
App::instance()->isGui(), false);
|
||||
}
|
||||
|
||||
void Clipboard::copyTilemap(const Image* image,
|
||||
@ -463,7 +465,8 @@ void Clipboard::copyPalette(const Palette* palette,
|
||||
}
|
||||
|
||||
void Clipboard::paste(Context* ctx,
|
||||
const bool interactive)
|
||||
const bool interactive,
|
||||
const gfx::Point* position)
|
||||
{
|
||||
const Site site = ctx->activeSite();
|
||||
Doc* dstDoc = site.document();
|
||||
@ -518,38 +521,94 @@ void Clipboard::paste(Context* ctx,
|
||||
|
||||
// Change to MovingPixelsState
|
||||
editor->pasteImage(src_image.get(),
|
||||
m_data->mask.get());
|
||||
m_data->mask.get(),
|
||||
position);
|
||||
}
|
||||
else {
|
||||
// Non-interactive version (just copy the image to the cel)
|
||||
// CLI version:
|
||||
// Paste the image according the position param.
|
||||
// If there are no parameters, we assume the origin
|
||||
// of the pasted image mask is the position.
|
||||
// If there is no mask, x=0, y=0 is taken as position.
|
||||
// TODO Support 'paste' command between images
|
||||
// that do not match their pixel format.
|
||||
Layer* dstLayer = site.layer();
|
||||
ASSERT(dstLayer);
|
||||
if (!dstLayer || !dstLayer->isImage())
|
||||
if (!dstLayer ||
|
||||
!dstLayer->isImage() ||
|
||||
(src_image->pixelFormat() != dstSpr->pixelFormat()))
|
||||
return;
|
||||
|
||||
ImageRef result;
|
||||
// resultBounds starts with the same bounds as source image,
|
||||
// but it'll be merged with the active cel bounds (if any).
|
||||
gfx::Rect resultBounds =
|
||||
gfx::Rect(position ? *position
|
||||
: (m_data->mask ? m_data->mask->origin()
|
||||
: gfx::Point()),
|
||||
src_image->size());
|
||||
const bool isAnImageOnDstCel =
|
||||
ctx->activeSite().cel() && ctx->activeSite().cel()->image();
|
||||
ASSERT(!ctx->activeSite().cel() || ctx->activeSite().cel()->image());
|
||||
if (isAnImageOnDstCel) {
|
||||
Cel* cel = ctx->activeSite().cel();
|
||||
resultBounds = cel->bounds().createUnion(resultBounds);
|
||||
// Create a new image (result) as a blend of the active cel image +
|
||||
// the source image (clipboard image).
|
||||
result.reset(Image::create(dstSpr->pixelFormat(), resultBounds.w, resultBounds.h));
|
||||
doc::blend_image(result.get(), cel->image(),
|
||||
gfx::Clip(cel->bounds().origin() - resultBounds.origin(),
|
||||
cel->image()->bounds()),
|
||||
site.palette(),
|
||||
255, BlendMode::NORMAL);
|
||||
doc::blend_image(result.get(), src_image.get(),
|
||||
gfx::Clip(*position - resultBounds.origin(),
|
||||
src_image->bounds()),
|
||||
site.palette(),
|
||||
255, BlendMode::NORMAL);
|
||||
}
|
||||
|
||||
ContextWriter writer(ctx);
|
||||
Tx tx(writer, "Paste Image");
|
||||
DocApi api = dstDoc->getApi(tx);
|
||||
Cel* dstCel = api.addCel(
|
||||
static_cast<LayerImage*>(dstLayer), site.frame(),
|
||||
ImageRef(Image::createCopy(src_image.get())));
|
||||
Cel* dstCel;
|
||||
if (isAnImageOnDstCel)
|
||||
api.clearCel(ctx->activeSite().cel());
|
||||
else
|
||||
result.reset(Image::createCopy(src_image.get()));
|
||||
|
||||
// Adjust bounds
|
||||
// Calculate the active image + pasted image bounds
|
||||
const gfx::Rect startBounds(gfx::Point(), result->size());
|
||||
const gfx::Point startOrigin(resultBounds.origin());
|
||||
doc::algorithm::shrink_bounds(result.get(),
|
||||
result->maskColor(),
|
||||
dstLayer,
|
||||
startBounds,
|
||||
resultBounds);
|
||||
// Cropped image according the shrink bounds
|
||||
result.reset(crop_image(result.get(),
|
||||
resultBounds,
|
||||
result->maskColor()));
|
||||
resultBounds.x = startOrigin.x + resultBounds.x;
|
||||
resultBounds.y = startOrigin.y + resultBounds.y;
|
||||
|
||||
// Set image on the new Cel
|
||||
dstCel = api.addCel(static_cast<LayerImage*>(dstLayer),
|
||||
site.frame(),
|
||||
result);
|
||||
// Set cel bounds
|
||||
if (dstCel) {
|
||||
if (m_data->mask) {
|
||||
if (dstLayer->isReference()) {
|
||||
dstCel->setBounds(dstSpr->bounds());
|
||||
|
||||
Mask emptyMask;
|
||||
tx(new cmd::SetMask(dstDoc, &emptyMask));
|
||||
}
|
||||
else {
|
||||
dstCel->setBounds(m_data->mask->bounds());
|
||||
tx(new cmd::SetMask(dstDoc, m_data->mask.get()));
|
||||
}
|
||||
const Mask emptyMask;
|
||||
if (dstLayer->isReference()) {
|
||||
dstCel->setBounds(dstSpr->bounds());
|
||||
tx(new cmd::SetMask(dstDoc, &emptyMask));
|
||||
}
|
||||
else {
|
||||
dstCel->setBounds(resultBounds);
|
||||
tx(new cmd::SetMask(dstDoc, m_data->mask ? m_data->mask.get()
|
||||
: &emptyMask));
|
||||
}
|
||||
}
|
||||
|
||||
tx.commit();
|
||||
}
|
||||
break;
|
||||
@ -562,7 +621,8 @@ void Clipboard::paste(Context* ctx,
|
||||
|
||||
// Change to MovingTilemapState
|
||||
editor->pasteImage(m_data->tilemap.get(),
|
||||
m_data->mask.get());
|
||||
m_data->mask.get(),
|
||||
position);
|
||||
}
|
||||
else {
|
||||
// TODO non-interactive version (for scripts)
|
||||
|
@ -75,7 +75,8 @@ namespace app {
|
||||
void copyPalette(const doc::Palette* palette,
|
||||
const doc::PalettePicks& picks);
|
||||
void paste(Context* ctx,
|
||||
const bool interactive);
|
||||
const bool interactive,
|
||||
const gfx::Point* position = nullptr);
|
||||
|
||||
doc::ImageRef getImage(doc::Palette* palette);
|
||||
|
||||
|
@ -28,19 +28,10 @@ do
|
||||
{ 2, 2,
|
||||
2, 2 })
|
||||
|
||||
-- TO DO: Fix this difference between running this script with
|
||||
-- 'UI Available' versus 'UI Not Available'
|
||||
app.layer = sprite.layers[3]
|
||||
if (app.isUIAvailable) then
|
||||
assert(app.cel.position == Point(1, 1))
|
||||
expect_img(app.activeImage,
|
||||
{ 1, 1 })
|
||||
else
|
||||
assert(app.cel.position == Point(0, 1))
|
||||
expect_img(app.activeImage,
|
||||
{ 0, 1, 1, 0, 0 })
|
||||
end
|
||||
|
||||
assert(app.cel.position == Point(1, 1))
|
||||
expect_img(app.activeImage,
|
||||
{ 1, 1 })
|
||||
app.command.FlattenLayers()
|
||||
assert(app.cel.position == Point(1, 1))
|
||||
expect_img(app.activeImage,
|
||||
@ -53,6 +44,18 @@ do
|
||||
app.undo() -- New Layer
|
||||
app.undo() -- Cut
|
||||
|
||||
app.layer = sprite.layers[1]
|
||||
assert(app.cel.position == Point(1, 1))
|
||||
expect_img(app.activeImage,
|
||||
{ 1, 1,
|
||||
1, 1 })
|
||||
app.layer = sprite.layers[2]
|
||||
assert(app.cel.position == Point(2, 2))
|
||||
expect_img(app.activeImage,
|
||||
{ 2, 2,
|
||||
2, 2 })
|
||||
assert(#sprite.layers == 2)
|
||||
|
||||
-- Another test
|
||||
app.layer = sprite.layers[1]
|
||||
app.useTool {
|
||||
@ -62,30 +65,21 @@ do
|
||||
}
|
||||
|
||||
app.command.Cut()
|
||||
assert(app.cel.position == Point(1, 1))
|
||||
expect_img(app.activeImage,
|
||||
{ 1, 1,
|
||||
1, 0 })
|
||||
sprite:newLayer()
|
||||
app.command.Paste()
|
||||
|
||||
-- TO DO: Fix this difference between running this script with
|
||||
-- 'UI Available' versus 'UI Not Available'
|
||||
app.layer = sprite.layers[3]
|
||||
if (app.isUIAvailable) then
|
||||
assert(app.cel.position == Point(2, 2))
|
||||
expect_img(app.activeImage,
|
||||
{ 1 })
|
||||
else
|
||||
assert(app.cel.position == Point(2, 2))
|
||||
expect_img(app.activeImage,
|
||||
{ 1, 0, 0 })
|
||||
end
|
||||
assert(app.cel.position == Point(2, 2))
|
||||
expect_img(app.activeImage,
|
||||
{ 1 })
|
||||
|
||||
app.undo() -- Paste
|
||||
app.undo() -- New Layer
|
||||
app.undo() -- Cut
|
||||
app.undo() -- MoveMask
|
||||
-- TO DO: at the moment useTool requires double undo to undo
|
||||
-- the selection action (Just one undo should be enough).
|
||||
app.undo() -- useTool
|
||||
app.undo() -- useTool
|
||||
|
||||
-- Test app.command.Copy
|
||||
app.layer = sprite.layers[1]
|
||||
@ -108,19 +102,10 @@ do
|
||||
expect_img(app.activeImage,
|
||||
{ 2, 2,
|
||||
2, 2 })
|
||||
|
||||
-- TO DO: Fix this difference between running this script with
|
||||
-- 'UI Available' versus 'UI Not Available'
|
||||
app.layer = sprite.layers[3]
|
||||
if (app.isUIAvailable) then
|
||||
assert(app.cel.position == Point(1, 1))
|
||||
expect_img(app.activeImage,
|
||||
{ 1, 1 })
|
||||
else
|
||||
assert(app.cel.position == Point(0, 1))
|
||||
expect_img(app.activeImage,
|
||||
{ 0, 1, 1, 0, 0 })
|
||||
end
|
||||
assert(app.cel.position == Point(1, 1))
|
||||
expect_img(app.activeImage,
|
||||
{ 1, 1 })
|
||||
|
||||
app.command.FlattenLayers()
|
||||
assert(app.cel.position == Point(1, 1))
|
||||
@ -130,6 +115,17 @@ do
|
||||
0, 2, 2 })
|
||||
|
||||
-- Test app.command.Clear()
|
||||
app.useTool {
|
||||
tool = "rectangular_marquee",
|
||||
points = {Point(2,2), Point(4,2)},
|
||||
selection = SelectionMode.REPLACE
|
||||
}
|
||||
app.command.Clear()
|
||||
expect_img(app.activeImage,
|
||||
{ 1, 1, 0,
|
||||
1, 0, 0,
|
||||
0, 2, 2 })
|
||||
|
||||
app.useTool {
|
||||
tool = "rectangular_marquee",
|
||||
points = {Point(0,1), Point(4,2)},
|
||||
@ -141,6 +137,8 @@ do
|
||||
{ 2, 2 })
|
||||
|
||||
app.undo()
|
||||
app.undo()
|
||||
app.undo()
|
||||
|
||||
assert(app.cel.position == Point(1, 1))
|
||||
expect_img(app.activeImage,
|
||||
@ -151,7 +149,7 @@ do
|
||||
-- Test app.command.Cancel()
|
||||
app.useTool {
|
||||
tool = "rectangular_marquee",
|
||||
points = {Point(0,1), Point(4,2)},
|
||||
points = {Point(2,2), Point(4,2)},
|
||||
selection = SelectionMode.REPLACE
|
||||
}
|
||||
app.command.Cancel()
|
||||
@ -161,4 +159,20 @@ do
|
||||
{ 1, 1, 0,
|
||||
1, 2, 2,
|
||||
0, 2, 2 })
|
||||
|
||||
app.useTool {
|
||||
tool = "rectangular_marquee",
|
||||
points = {Point(2,0), Point(4,1)},
|
||||
selection = SelectionMode.REPLACE
|
||||
}
|
||||
app.command.Copy()
|
||||
sprite:newLayer()
|
||||
app.command.Paste { x=3, y=3 }
|
||||
app.command.FlattenLayers()
|
||||
assert(app.cel.position == Point(1, 1))
|
||||
expect_img(app.activeImage,
|
||||
{ 1, 1, 0,
|
||||
1, 2, 2,
|
||||
0, 2, 2,
|
||||
0, 0, 1, })
|
||||
end
|
Loading…
x
Reference in New Issue
Block a user