[lua] Add app.command.ImportSpriteSheet()

Feature request: https://community.aseprite.org/t/8482
This commit is contained in:
David Capello 2021-04-09 17:28:20 -03:00
parent 3769d91125
commit 2df3cd8a80
4 changed files with 94 additions and 41 deletions

View File

@ -1,5 +1,5 @@
# Aseprite # Aseprite
# Copyright (C) 2018-2020 Igara Studio S.A. # Copyright (C) 2018-2021 Igara Studio S.A.
# Copyright (C) 2001-2018 David Capello # Copyright (C) 2001-2018 David Capello
# Generate a ui::Widget for each widget in a XML file # Generate a ui::Widget for each widget in a XML file
@ -231,7 +231,6 @@ if(ENABLE_UI)
commands/cmd_goto_tab.cpp commands/cmd_goto_tab.cpp
commands/cmd_grid.cpp commands/cmd_grid.cpp
commands/cmd_home.cpp commands/cmd_home.cpp
commands/cmd_import_sprite_sheet.cpp
commands/cmd_invert_mask.cpp commands/cmd_invert_mask.cpp
commands/cmd_keyboard_shortcuts.cpp commands/cmd_keyboard_shortcuts.cpp
commands/cmd_launch.cpp commands/cmd_launch.cpp
@ -503,6 +502,7 @@ add_library(app-lib
commands/cmd_export_sprite_sheet.cpp commands/cmd_export_sprite_sheet.cpp
commands/cmd_flatten_layers.cpp commands/cmd_flatten_layers.cpp
commands/cmd_flip.cpp commands/cmd_flip.cpp
commands/cmd_import_sprite_sheet.cpp
commands/cmd_layer_from_background.cpp commands/cmd_layer_from_background.cpp
commands/cmd_load_palette.cpp commands/cmd_load_palette.cpp
commands/cmd_merge_down_layer.cpp commands/cmd_merge_down_layer.cpp

View File

@ -1,5 +1,5 @@
// Aseprite // Aseprite
// Copyright (C) 2019-2020 Igara Studio S.A. // Copyright (C) 2019-2021 Igara Studio S.A.
// Copyright (C) 2001-2018 David Capello // Copyright (C) 2001-2018 David Capello
// //
// This program is distributed under the terms of // This program is distributed under the terms of
@ -12,7 +12,7 @@
#include "app/app.h" #include "app/app.h"
#include "app/commands/command.h" #include "app/commands/command.h"
#include "app/commands/commands.h" #include "app/commands/commands.h"
#include "app/commands/params.h" #include "app/commands/new_params.h"
#include "app/context.h" #include "app/context.h"
#include "app/context_access.h" #include "app/context_access.h"
#include "app/doc_access.h" #include "app/doc_access.h"
@ -44,6 +44,14 @@ namespace app {
using namespace ui; using namespace ui;
struct ImportSpriteSheetParams : public NewParams {
Param<bool> ui { this, true, "ui" };
Param<app::SpriteSheetType> type { this, app::SpriteSheetType::None, "type" };
Param<gfx::Rect> frameBounds { this, gfx::Rect(0, 0, 0, 0), "frameBounds" };
Param<gfx::Size> padding { this, gfx::Size(0, 0), "padding" };
Param<bool> partialTiles { this, false, "partialTiles" };
};
class ImportSpriteSheetWindow : public app::gen::ImportSpriteSheet class ImportSpriteSheetWindow : public app::gen::ImportSpriteSheet
, public SelectBoxDelegate { , public SelectBoxDelegate {
public: public:
@ -127,6 +135,17 @@ public:
return m_padding; return m_padding;
} }
void updateParams(ImportSpriteSheetParams& params) {
params.type(sheetTypeValue());
params.frameBounds(frameBounds());
params.partialTiles(partialTilesValue());
if (paddingEnabledValue())
params.padding(paddingThickness());
else
params.padding(gfx::Size(0, 0));
}
protected: protected:
void onSheetTypeChange() { void onSheetTypeChange() {
@ -372,7 +391,7 @@ private:
DocumentPreferences* m_docPref; DocumentPreferences* m_docPref;
}; };
class ImportSpriteSheetCommand : public Command { class ImportSpriteSheetCommand : public CommandWithNewParams<ImportSpriteSheetParams> {
public: public:
ImportSpriteSheetCommand(); ImportSpriteSheetCommand();
@ -381,29 +400,44 @@ protected:
}; };
ImportSpriteSheetCommand::ImportSpriteSheetCommand() ImportSpriteSheetCommand::ImportSpriteSheetCommand()
: Command(CommandId::ImportSpriteSheet(), CmdRecordableFlag) : CommandWithNewParams(CommandId::ImportSpriteSheet(), CmdRecordableFlag)
{ {
} }
void ImportSpriteSheetCommand::onExecute(Context* context) void ImportSpriteSheetCommand::onExecute(Context* context)
{ {
ImportSpriteSheetWindow window(context); Doc* document;
auto& params = this->params();
window.openWindowInForeground(); #ifdef ENABLE_UI
if (!window.ok()) if (context->isUIAvailable() && params.ui()) {
return; // TODO use params as input values for the ImportSpriteSheetWindow
Doc* document = window.document(); ImportSpriteSheetWindow window(context);
DocumentPreferences* docPref = window.docPref(); window.openWindowInForeground();
gfx::Rect frameBounds = window.frameBounds(); if (!window.ok())
gfx::Size padThickness = window.paddingThickness(); return;
bool partialTiles = window.partialTilesValue();
bool paddingEnable = window.paddingEnabledValue();
auto sheetType = window.sheetTypeValue();
ASSERT(document); document = window.document();
if (!document) if (!document)
return; return;
window.updateParams(params);
DocumentPreferences* docPref = window.docPref();
docPref->importSpriteSheet.type(params.type());
docPref->importSpriteSheet.bounds(params.frameBounds());
docPref->importSpriteSheet.partialTiles(params.partialTiles());
docPref->importSpriteSheet.paddingBounds(params.padding());
docPref->importSpriteSheet.paddingEnabled(window.paddingEnabledValue());
}
else // We import the sprite sheet from the active document if there is no UI
#endif
{
document = context->activeDocument();
if (!document)
return;
}
// The list of frames imported from the sheet // The list of frames imported from the sheet
std::vector<ImageRef> animation; std::vector<ImageRef> animation;
@ -411,39 +445,44 @@ void ImportSpriteSheetCommand::onExecute(Context* context)
try { try {
Sprite* sprite = document->sprite(); Sprite* sprite = document->sprite();
frame_t currentFrame = context->activeSite().frame(); frame_t currentFrame = context->activeSite().frame();
gfx::Rect frameBounds = params.frameBounds();
const gfx::Size padding = params.padding();
render::Render render; render::Render render;
render.setNewBlend(Preferences::instance().experimental.newBlend()); render.setNewBlend(Preferences::instance().experimental.newBlend());
if (frameBounds.isEmpty())
frameBounds = sprite->bounds();
// Each sprite in the sheet // Each sprite in the sheet
std::vector<gfx::Rect> tileRects; std::vector<gfx::Rect> tileRects;
int widthStop = sprite->width(); int widthStop = sprite->width();
int heightStop = sprite->height(); int heightStop = sprite->height();
if (partialTiles) { if (params.partialTiles()) {
widthStop += frameBounds.w-1; widthStop += frameBounds.w-1;
heightStop += frameBounds.h-1; heightStop += frameBounds.h-1;
} }
switch (sheetType) { switch (params.type()) {
case app::SpriteSheetType::Horizontal: case app::SpriteSheetType::Horizontal:
for (int x=frameBounds.x; x+frameBounds.w<=widthStop; x+=frameBounds.w+padThickness.w) { for (int x=frameBounds.x; x+frameBounds.w<=widthStop; x+=frameBounds.w+padding.w) {
tileRects.push_back(gfx::Rect(x, frameBounds.y, frameBounds.w, frameBounds.h)); tileRects.push_back(gfx::Rect(x, frameBounds.y, frameBounds.w, frameBounds.h));
} }
break; break;
case app::SpriteSheetType::Vertical: case app::SpriteSheetType::Vertical:
for (int y=frameBounds.y; y+frameBounds.h<=heightStop; y+=frameBounds.h+padThickness.h) { for (int y=frameBounds.y; y+frameBounds.h<=heightStop; y+=frameBounds.h+padding.h) {
tileRects.push_back(gfx::Rect(frameBounds.x, y, frameBounds.w, frameBounds.h)); tileRects.push_back(gfx::Rect(frameBounds.x, y, frameBounds.w, frameBounds.h));
} }
break; break;
case app::SpriteSheetType::Rows: case app::SpriteSheetType::Rows:
for (int y=frameBounds.y; y+frameBounds.h<=heightStop; y+=frameBounds.h+padThickness.h) { for (int y=frameBounds.y; y+frameBounds.h<=heightStop; y+=frameBounds.h+padding.h) {
for (int x=frameBounds.x; x+frameBounds.w<=widthStop; x+=frameBounds.w+padThickness.w) { for (int x=frameBounds.x; x+frameBounds.w<=widthStop; x+=frameBounds.w+padding.w) {
tileRects.push_back(gfx::Rect(x, y, frameBounds.w, frameBounds.h)); tileRects.push_back(gfx::Rect(x, y, frameBounds.w, frameBounds.h));
} }
} }
break; break;
case app::SpriteSheetType::Columns: case app::SpriteSheetType::Columns:
for (int x=frameBounds.x; x+frameBounds.w<=widthStop; x+=frameBounds.w+padThickness.w) { for (int x=frameBounds.x; x+frameBounds.w<=widthStop; x+=frameBounds.w+padding.w) {
for (int y=frameBounds.y; y+frameBounds.h<=heightStop; y+=frameBounds.h+padThickness.h) { for (int y=frameBounds.y; y+frameBounds.h<=heightStop; y+=frameBounds.h+padding.h) {
tileRects.push_back(gfx::Rect(x, y, frameBounds.w, frameBounds.h)); tileRects.push_back(gfx::Rect(x, y, frameBounds.w, frameBounds.h));
} }
} }
@ -504,21 +543,15 @@ void ImportSpriteSheetCommand::onExecute(Context* context)
api.setSpriteSize(sprite, frameBounds.w, frameBounds.h); api.setSpriteSize(sprite, frameBounds.w, frameBounds.h);
tx.commit(); tx.commit();
ASSERT(docPref);
if (docPref) {
docPref->importSpriteSheet.type(sheetType);
docPref->importSpriteSheet.bounds(frameBounds);
docPref->importSpriteSheet.partialTiles(partialTiles);
docPref->importSpriteSheet.paddingBounds(padThickness);
docPref->importSpriteSheet.paddingEnabled(paddingEnable);
}
} }
catch (...) { catch (...) {
throw; throw;
} }
update_screen_for_document(document); #ifdef ENABLE_UI
if (context->isUIAvailable())
update_screen_for_document(document);
#endif
} }
Command* CommandFactory::createImportSpriteSheetCommand() Command* CommandFactory::createImportSpriteSheetCommand()

View File

@ -1,5 +1,5 @@
// Aseprite // Aseprite
// Copyright (C) 2018-2020 Igara Studio S.A. // Copyright (C) 2018-2021 Igara Studio S.A.
// Copyright (C) 2001-2018 David Capello // Copyright (C) 2001-2018 David Capello
// //
// This program is distributed under the terms of // This program is distributed under the terms of
@ -22,6 +22,7 @@ FOR_EACH_COMMAND(ExportSpriteSheet)
FOR_EACH_COMMAND(FlattenLayers) FOR_EACH_COMMAND(FlattenLayers)
FOR_EACH_COMMAND(Flip) FOR_EACH_COMMAND(Flip)
FOR_EACH_COMMAND(HueSaturation) FOR_EACH_COMMAND(HueSaturation)
FOR_EACH_COMMAND(ImportSpriteSheet)
FOR_EACH_COMMAND(InvertColor) FOR_EACH_COMMAND(InvertColor)
FOR_EACH_COMMAND(LayerFromBackground) FOR_EACH_COMMAND(LayerFromBackground)
FOR_EACH_COMMAND(LoadPalette) FOR_EACH_COMMAND(LoadPalette)
@ -86,7 +87,6 @@ FOR_EACH_COMMAND(GotoPreviousLayer)
FOR_EACH_COMMAND(GotoPreviousTab) FOR_EACH_COMMAND(GotoPreviousTab)
FOR_EACH_COMMAND(GridSettings) FOR_EACH_COMMAND(GridSettings)
FOR_EACH_COMMAND(Home) FOR_EACH_COMMAND(Home)
FOR_EACH_COMMAND(ImportSpriteSheet)
FOR_EACH_COMMAND(InvertMask) FOR_EACH_COMMAND(InvertMask)
FOR_EACH_COMMAND(KeyboardShortcuts) FOR_EACH_COMMAND(KeyboardShortcuts)
FOR_EACH_COMMAND(Launch) FOR_EACH_COMMAND(Launch)

View File

@ -1,5 +1,5 @@
// Aseprite // Aseprite
// Copyright (C) 2019-2020 Igara Studio S.A. // Copyright (C) 2019-2021 Igara Studio S.A.
// //
// This program is distributed under the terms of // This program is distributed under the terms of
// the End-User License Agreement for Aseprite. // the End-User License Agreement for Aseprite.
@ -24,6 +24,7 @@
#include "filters/outline_filter.h" #include "filters/outline_filter.h"
#include "filters/tiled_mode.h" #include "filters/tiled_mode.h"
#include "gfx/rect.h" #include "gfx/rect.h"
#include "gfx/size.h"
#ifdef ENABLE_SCRIPTING #ifdef ENABLE_SCRIPTING
#include "app/script/engine.h" #include "app/script/engine.h"
@ -61,6 +62,19 @@ void Param<std::string>::fromString(const std::string& value)
setValue(value); setValue(value);
} }
template<>
void Param<gfx::Size>::fromString(const std::string& value)
{
gfx::Size size;
std::vector<std::string> parts;
base::split_string(value, parts, ",");
if (parts.size() == 2) {
size.w = base::convert_to<int>(parts[0]);
size.h = base::convert_to<int>(parts[1]);
}
setValue(size);
}
template<> template<>
void Param<gfx::Rect>::fromString(const std::string& value) void Param<gfx::Rect>::fromString(const std::string& value)
{ {
@ -241,6 +255,12 @@ void Param<std::string>::fromLua(lua_State* L, int index)
setValue(std::string()); setValue(std::string());
} }
template<>
void Param<gfx::Size>::fromLua(lua_State* L, int index)
{
setValue(script::convert_args_into_size(L, index));
}
template<> template<>
void Param<gfx::Rect>::fromLua(lua_State* L, int index) void Param<gfx::Rect>::fromLua(lua_State* L, int index)
{ {