mirror of
https://github.com/aseprite/aseprite.git
synced 2025-01-28 18:32:50 +00:00
Add CommandWithNewParams to load command parameters from Lua tables directly
With these new classes (Param/NewParams/CommandWithNewParams(Base)) we can load parameters for commands from a Lua table directly without converting to a string. So instead of Lua value -> string -> C++ param type We can do Lua value -> C++ param type directly.
This commit is contained in:
parent
496d15c428
commit
4335f0c728
@ -194,7 +194,6 @@ if(ENABLE_UI)
|
||||
commands/cmd_add_color.cpp
|
||||
commands/cmd_advanced_mode.cpp
|
||||
commands/cmd_cancel.cpp
|
||||
commands/cmd_canvas_size.cpp
|
||||
commands/cmd_cel_properties.cpp
|
||||
commands/cmd_change_brush.cpp
|
||||
commands/cmd_change_color.cpp
|
||||
@ -213,7 +212,6 @@ if(ENABLE_UI)
|
||||
commands/cmd_duplicate_sprite.cpp
|
||||
commands/cmd_duplicate_view.cpp
|
||||
commands/cmd_exit.cpp
|
||||
commands/cmd_export_sprite_sheet.cpp
|
||||
commands/cmd_eyedropper.cpp
|
||||
commands/cmd_fill_and_stroke.cpp
|
||||
commands/cmd_fit_screen.cpp
|
||||
@ -506,9 +504,11 @@ add_library(app-lib
|
||||
color_spaces.cpp
|
||||
color_utils.cpp
|
||||
commands/cmd_background_from_layer.cpp
|
||||
commands/cmd_canvas_size.cpp
|
||||
commands/cmd_cel_opacity.cpp
|
||||
commands/cmd_change_pixel_format.cpp
|
||||
commands/cmd_crop.cpp
|
||||
commands/cmd_export_sprite_sheet.cpp
|
||||
commands/cmd_flatten_layers.cpp
|
||||
commands/cmd_layer_from_background.cpp
|
||||
commands/cmd_load_palette.cpp
|
||||
@ -523,6 +523,7 @@ add_library(app-lib
|
||||
commands/command.cpp
|
||||
commands/commands.cpp
|
||||
commands/move_thing.cpp
|
||||
commands/new_params.cpp
|
||||
commands/quick_command.cpp
|
||||
console.cpp
|
||||
context.cpp
|
||||
|
@ -1,4 +1,5 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2019 Igara Studio S.A.
|
||||
// Copyright (C) 2001-2018 David Capello
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
@ -9,7 +10,7 @@
|
||||
#endif
|
||||
|
||||
#include "app/app.h"
|
||||
#include "app/commands/command.h"
|
||||
#include "app/commands/new_params.h"
|
||||
#include "app/context.h"
|
||||
#include "app/context_access.h"
|
||||
#include "app/doc.h"
|
||||
@ -581,43 +582,26 @@ private:
|
||||
bool m_dataFilenameAskOverwrite;
|
||||
};
|
||||
|
||||
class ExportSpriteSheetCommand : public Command {
|
||||
struct ExportSpriteSheetParams : public NewParams {
|
||||
Param<bool> ui { this, true, "ui" };
|
||||
Param<bool> askOverwrite { this, true, { "askOverwrite", "ask-overwrite" } };
|
||||
};
|
||||
|
||||
class ExportSpriteSheetCommand : public CommandWithNewParams<ExportSpriteSheetParams> {
|
||||
public:
|
||||
ExportSpriteSheetCommand();
|
||||
Command* clone() const override { return new ExportSpriteSheetCommand(*this); }
|
||||
|
||||
void setUseUI(bool useUI) { m_useUI = useUI; }
|
||||
|
||||
protected:
|
||||
void onLoadParams(const Params& params) override;
|
||||
bool onEnabled(Context* context) override;
|
||||
void onExecute(Context* context) override;
|
||||
|
||||
private:
|
||||
bool m_useUI;
|
||||
bool m_askOverwrite;
|
||||
};
|
||||
|
||||
ExportSpriteSheetCommand::ExportSpriteSheetCommand()
|
||||
: Command(CommandId::ExportSpriteSheet(), CmdRecordableFlag)
|
||||
, m_useUI(true)
|
||||
, m_askOverwrite(true)
|
||||
: CommandWithNewParams(CommandId::ExportSpriteSheet(), CmdRecordableFlag)
|
||||
{
|
||||
}
|
||||
|
||||
void ExportSpriteSheetCommand::onLoadParams(const Params& params)
|
||||
{
|
||||
if (params.has_param("ui"))
|
||||
m_useUI = params.get_as<bool>("ui");
|
||||
else
|
||||
m_useUI = true;
|
||||
|
||||
if (params.has_param("ask-overwrite"))
|
||||
m_askOverwrite = params.get_as<bool>("ask-overwrite");
|
||||
else
|
||||
m_askOverwrite = true;
|
||||
}
|
||||
|
||||
bool ExportSpriteSheetCommand::onEnabled(Context* context)
|
||||
{
|
||||
return context->checkFlags(ContextFlags::ActiveDocumentIsWritable);
|
||||
@ -629,9 +613,10 @@ void ExportSpriteSheetCommand::onExecute(Context* context)
|
||||
Doc* document = site.document();
|
||||
Sprite* sprite = site.sprite();
|
||||
DocumentPreferences& docPref(Preferences::instance().document(document));
|
||||
bool askOverwrite = m_askOverwrite;
|
||||
|
||||
if (m_useUI && context->isUIAvailable()) {
|
||||
#ifdef ENABLE_UI
|
||||
bool askOverwrite = params().askOverwrite();
|
||||
if (params().ui() && context->isUIAvailable()) {
|
||||
ExportSpriteSheetWindow window(site, docPref);
|
||||
window.openWindowInForeground();
|
||||
if (!window.ok())
|
||||
@ -670,6 +655,7 @@ void ExportSpriteSheetCommand::onExecute(Context* context)
|
||||
|
||||
askOverwrite = false; // Already asked in the ExportSpriteSheetWindow
|
||||
}
|
||||
#endif // ENABLE_UI
|
||||
|
||||
app::SpriteSheetType type = docPref.spriteSheet.type();
|
||||
int columns = docPref.spriteSheet.columns();
|
||||
@ -693,11 +679,13 @@ void ExportSpriteSheetCommand::onExecute(Context* context)
|
||||
const bool listFrameTags = docPref.spriteSheet.listFrameTags();
|
||||
const bool listSlices = docPref.spriteSheet.listSlices();
|
||||
|
||||
#ifdef ENABLE_UI
|
||||
if (context->isUIAvailable() && askOverwrite) {
|
||||
if (!ask_overwrite(true, filename,
|
||||
true, dataFilename))
|
||||
return; // Do not overwrite
|
||||
}
|
||||
#endif
|
||||
|
||||
SelectedFrames selFrames;
|
||||
FrameTag* frameTag =
|
||||
@ -781,9 +769,13 @@ void ExportSpriteSheetCommand::onExecute(Context* context)
|
||||
if (!newDocument)
|
||||
return;
|
||||
|
||||
StatusBar* statusbar = StatusBar::instance();
|
||||
if (statusbar)
|
||||
statusbar->showTip(1000, "Sprite Sheet Generated");
|
||||
#ifdef ENABLE_UI
|
||||
if (context->isUIAvailable()) {
|
||||
StatusBar* statusbar = StatusBar::instance();
|
||||
if (statusbar)
|
||||
statusbar->showTip(1000, "Sprite Sheet Generated");
|
||||
}
|
||||
#endif
|
||||
|
||||
// Copy background and grid preferences
|
||||
{
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2018 Igara Studio S.A.
|
||||
// Copyright (C) 2018-2019 Igara Studio S.A.
|
||||
// Copyright (C) 2001-2018 David Capello
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
@ -11,6 +11,7 @@ FOR_EACH_COMMAND(CanvasSize)
|
||||
FOR_EACH_COMMAND(CelOpacity)
|
||||
FOR_EACH_COMMAND(ChangePixelFormat)
|
||||
FOR_EACH_COMMAND(CropSprite)
|
||||
FOR_EACH_COMMAND(ExportSpriteSheet)
|
||||
FOR_EACH_COMMAND(FlattenLayers)
|
||||
FOR_EACH_COMMAND(LayerFromBackground)
|
||||
FOR_EACH_COMMAND(LoadPalette)
|
||||
@ -54,7 +55,6 @@ FOR_EACH_COMMAND(DuplicateLayer)
|
||||
FOR_EACH_COMMAND(DuplicateSprite)
|
||||
FOR_EACH_COMMAND(DuplicateView)
|
||||
FOR_EACH_COMMAND(Exit)
|
||||
FOR_EACH_COMMAND(ExportSpriteSheet)
|
||||
FOR_EACH_COMMAND(Eyedropper)
|
||||
FOR_EACH_COMMAND(Fill)
|
||||
FOR_EACH_COMMAND(FitScreen)
|
||||
|
62
src/app/commands/new_params.cpp
Normal file
62
src/app/commands/new_params.cpp
Normal file
@ -0,0 +1,62 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2019 Igara Studio S.A.
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
// the End-User License Agreement for Aseprite.
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "app/commands/new_params.h"
|
||||
|
||||
#include "app/script/luacpp.h"
|
||||
|
||||
namespace app {
|
||||
|
||||
template<>
|
||||
void Param<bool>::fromString(const std::string& value)
|
||||
{
|
||||
m_value = (value == "1" || value == "true");
|
||||
}
|
||||
|
||||
#ifdef ENABLE_SCRIPTING
|
||||
|
||||
template<>
|
||||
void Param<bool>::fromLua(lua_State* L, int index)
|
||||
{
|
||||
m_value = lua_toboolean(L, index);
|
||||
}
|
||||
|
||||
void CommandWithNewParamsBase::onLoadParams(const Params& params)
|
||||
{
|
||||
if (m_skipLoadParams) {
|
||||
m_skipLoadParams = false;
|
||||
return;
|
||||
}
|
||||
onResetValues();
|
||||
for (const auto& pair : params) {
|
||||
if (ParamBase* p = onGetParam(pair.first))
|
||||
p->fromString(pair.second);
|
||||
}
|
||||
}
|
||||
|
||||
void CommandWithNewParamsBase::loadParamsFromLuaTable(lua_State* L, int index)
|
||||
{
|
||||
onResetValues();
|
||||
if (lua_istable(L, index)) {
|
||||
lua_pushnil(L);
|
||||
while (lua_next(L, index) != 0) {
|
||||
if (const char* k = lua_tostring(L, -2)) {
|
||||
if (ParamBase* p = onGetParam(k))
|
||||
p->fromLua(L, -1);
|
||||
}
|
||||
lua_pop(L, 1); // Pop the value, leave the key
|
||||
}
|
||||
}
|
||||
m_skipLoadParams = true;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace app
|
145
src/app/commands/new_params.h
Normal file
145
src/app/commands/new_params.h
Normal file
@ -0,0 +1,145 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2019 Igara Studio S.A.
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
// the End-User License Agreement for Aseprite.
|
||||
|
||||
#ifndef APP_COMMANDS_NEW_PARAMS_H
|
||||
#define APP_COMMANDS_NEW_PARAMS_H
|
||||
|
||||
#include "app/commands/command.h"
|
||||
#include "app/commands/params.h"
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#ifdef ENABLE_SCRIPTING
|
||||
extern "C" struct lua_State;
|
||||
#endif
|
||||
|
||||
namespace app {
|
||||
|
||||
class ParamBase {
|
||||
public:
|
||||
virtual ~ParamBase() { }
|
||||
virtual void resetValue() = 0;
|
||||
virtual void fromString(const std::string& value) = 0;
|
||||
#ifdef ENABLE_SCRIPTING
|
||||
virtual void fromLua(lua_State* L, int index) = 0;
|
||||
#endif
|
||||
};
|
||||
|
||||
class NewParams {
|
||||
public:
|
||||
void addParam(const char* id, ParamBase* param) {
|
||||
m_params[id] = param;
|
||||
}
|
||||
|
||||
void resetValues() {
|
||||
for (auto& pair : m_params)
|
||||
pair.second->resetValue();
|
||||
}
|
||||
|
||||
ParamBase* getParam(const std::string& id) {
|
||||
auto it = m_params.find(id);
|
||||
if (it != m_params.end())
|
||||
return it->second;
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
private:
|
||||
std::map<std::string, ParamBase*> m_params;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class Param : public ParamBase {
|
||||
public:
|
||||
Param(NewParams* params,
|
||||
const T& defaultValue,
|
||||
const char* id)
|
||||
: m_defaultValue(defaultValue)
|
||||
, m_value(defaultValue) {
|
||||
if (id)
|
||||
params->addParam(id, this);
|
||||
}
|
||||
|
||||
Param(NewParams* params,
|
||||
const T& defaultValue,
|
||||
const std::initializer_list<const char*> ids)
|
||||
: Param(params, defaultValue, nullptr) {
|
||||
for (const auto& id : ids)
|
||||
params->addParam(id, this);
|
||||
}
|
||||
|
||||
void resetValue() override {
|
||||
m_value = m_defaultValue;
|
||||
}
|
||||
|
||||
void fromString(const std::string& value) override;
|
||||
#ifdef ENABLE_SCRIPTING
|
||||
void fromLua(lua_State* L, int index) override;
|
||||
#endif
|
||||
|
||||
const T& operator()() const {
|
||||
return m_value;
|
||||
}
|
||||
|
||||
void operator()(const T& value) {
|
||||
m_value = value;
|
||||
}
|
||||
|
||||
private:
|
||||
T m_defaultValue;
|
||||
T m_value;
|
||||
};
|
||||
|
||||
class CommandWithNewParamsBase : public Command {
|
||||
public:
|
||||
template<typename...Args>
|
||||
CommandWithNewParamsBase(Args&&...args)
|
||||
: Command(std::forward<Args>(args)...) { }
|
||||
|
||||
#ifdef ENABLE_SCRIPTING
|
||||
void loadParamsFromLuaTable(lua_State* L, int index);
|
||||
#endif
|
||||
|
||||
protected:
|
||||
void onLoadParams(const Params& params) override;
|
||||
|
||||
virtual void onResetValues() = 0;
|
||||
virtual ParamBase* onGetParam(const std::string& k) = 0;
|
||||
|
||||
private:
|
||||
#ifdef ENABLE_SCRIPTING
|
||||
bool m_skipLoadParams = false;
|
||||
#endif
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class CommandWithNewParams : public CommandWithNewParamsBase {
|
||||
public:
|
||||
template<typename...Args>
|
||||
CommandWithNewParams(Args&&...args)
|
||||
: CommandWithNewParamsBase(std::forward<Args>(args)...) { }
|
||||
|
||||
T& params() {
|
||||
return m_params;
|
||||
}
|
||||
|
||||
private:
|
||||
void onResetValues() override {
|
||||
m_params.resetValues();
|
||||
}
|
||||
|
||||
ParamBase* onGetParam(const std::string& k) override {
|
||||
return m_params.getParam(k);
|
||||
}
|
||||
|
||||
T m_params;
|
||||
};
|
||||
|
||||
} // namespace app
|
||||
|
||||
#endif
|
@ -1,4 +1,5 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2019 Igara Studio S.A.
|
||||
// Copyright (C) 2018 David Capello
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
@ -11,6 +12,7 @@
|
||||
#include "app/app.h"
|
||||
#include "app/commands/command.h"
|
||||
#include "app/commands/commands.h"
|
||||
#include "app/commands/new_params.h"
|
||||
#include "app/commands/params.h"
|
||||
#include "app/context.h"
|
||||
#include "app/script/luacpp.h"
|
||||
@ -31,18 +33,21 @@ int Command_call(lua_State* L)
|
||||
auto command = get_ptr<Command>(L, 1);
|
||||
Params params;
|
||||
|
||||
if (lua_istable(L, 2)) {
|
||||
lua_pushnil(L);
|
||||
while (lua_next(L, 2) != 0) {
|
||||
const char* k = lua_tostring(L, -2);
|
||||
if (k) {
|
||||
const char* v = luaL_tolstring(L, -1, nullptr);
|
||||
if (v) {
|
||||
params.set(k, v);
|
||||
if (auto commandLua = dynamic_cast<CommandWithNewParamsBase*>(command)) {
|
||||
commandLua->loadParamsFromLuaTable(L, 2);
|
||||
}
|
||||
else {
|
||||
if (lua_istable(L, 2)) {
|
||||
lua_pushnil(L);
|
||||
while (lua_next(L, 2) != 0) {
|
||||
if (const char* k = lua_tostring(L, -2)) {
|
||||
const char* v = luaL_tolstring(L, -1, nullptr);
|
||||
if (v)
|
||||
params.set(k, v);
|
||||
lua_pop(L, 1); // pop the value generated by luaL_tolstring()
|
||||
}
|
||||
lua_pop(L, 1);
|
||||
lua_pop(L, 1); // pop the value lua_next(), leave the key in the stack
|
||||
}
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user