mirror of
https://github.com/aseprite/aseprite.git
synced 2025-03-31 07:20:30 +00:00
Convert SaveFileBaseCommand to CommandWithNewParams
With this patch we fixed some use cases: * We can show the ui with a default filename { filename=..., ui=true } * We can specify fromFrame/toFrame for SaveFileCopyAs
This commit is contained in:
parent
d160fb8b91
commit
ddc1b76214
@ -86,24 +86,18 @@ private:
|
|||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
SaveFileBaseCommand::SaveFileBaseCommand(const char* id, CommandFlags flags)
|
SaveFileBaseCommand::SaveFileBaseCommand(const char* id, CommandFlags flags)
|
||||||
: Command(id, flags)
|
: CommandWithNewParams<SaveFileParams>(id, flags)
|
||||||
{
|
{
|
||||||
m_useUI = true;
|
|
||||||
m_ignoreEmpty = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SaveFileBaseCommand::onLoadParams(const Params& params)
|
void SaveFileBaseCommand::onLoadParams(const Params& params)
|
||||||
{
|
{
|
||||||
m_filename = params.get("filename");
|
CommandWithNewParams<SaveFileParams>::onLoadParams(params);
|
||||||
m_filenameFormat = params.get("filename-format");
|
|
||||||
m_tag = params.get("frame-tag");
|
|
||||||
m_aniDir = params.get("ani-dir");
|
|
||||||
m_slice = params.get("slice");
|
|
||||||
|
|
||||||
if (params.has_param("from-frame") ||
|
if (this->params().fromFrame.isSet() ||
|
||||||
params.has_param("to-frame")) {
|
this->params().toFrame.isSet()) {
|
||||||
doc::frame_t fromFrame = params.get_as<doc::frame_t>("from-frame");
|
doc::frame_t fromFrame = this->params().fromFrame();
|
||||||
doc::frame_t toFrame = params.get_as<doc::frame_t>("to-frame");
|
doc::frame_t toFrame = this->params().toFrame();
|
||||||
m_selFrames.insert(fromFrame, toFrame);
|
m_selFrames.insert(fromFrame, toFrame);
|
||||||
m_adjustFramesByTag = true;
|
m_adjustFramesByTag = true;
|
||||||
}
|
}
|
||||||
@ -111,11 +105,6 @@ void SaveFileBaseCommand::onLoadParams(const Params& params)
|
|||||||
m_selFrames.clear();
|
m_selFrames.clear();
|
||||||
m_adjustFramesByTag = false;
|
m_adjustFramesByTag = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string useUI = params.get("useUI");
|
|
||||||
m_useUI = (useUI.empty() || (useUI == "true"));
|
|
||||||
|
|
||||||
m_ignoreEmpty = params.get_as<bool>("ignoreEmpty");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns true if there is a current sprite to save.
|
// Returns true if there is a current sprite to save.
|
||||||
@ -141,19 +130,15 @@ std::string SaveFileBaseCommand::saveAsDialog(
|
|||||||
// preferences.
|
// preferences.
|
||||||
Preferences::instance().save();
|
Preferences::instance().save();
|
||||||
|
|
||||||
std::string filename;
|
std::string filename = params().filename();
|
||||||
|
if (filename.empty() || params().ui()) {
|
||||||
if (!m_filename.empty()) {
|
|
||||||
filename = m_filename;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
base::paths exts = get_writable_extensions();
|
base::paths exts = get_writable_extensions();
|
||||||
filename = initialFilename;
|
filename = initialFilename;
|
||||||
|
|
||||||
#ifdef ENABLE_UI
|
#ifdef ENABLE_UI
|
||||||
again:;
|
again:;
|
||||||
base::paths newfilename;
|
base::paths newfilename;
|
||||||
if (!m_useUI ||
|
if (!params().ui() ||
|
||||||
!app::show_file_selector(
|
!app::show_file_selector(
|
||||||
dlgTitle, filename, exts,
|
dlgTitle, filename, exts,
|
||||||
FileSelectorType::Save,
|
FileSelectorType::Save,
|
||||||
@ -200,8 +185,8 @@ void SaveFileBaseCommand::saveDocumentInBackground(
|
|||||||
const std::string& filename,
|
const std::string& filename,
|
||||||
const MarkAsSaved markAsSaved)
|
const MarkAsSaved markAsSaved)
|
||||||
{
|
{
|
||||||
if (!m_aniDir.empty()) {
|
if (params().aniDir.isSet()) {
|
||||||
switch (convert_string_to_anidir(m_aniDir)) {
|
switch (params().aniDir()) {
|
||||||
case AniDir::REVERSE:
|
case AniDir::REVERSE:
|
||||||
m_selFrames = m_selFrames.makeReverse();
|
m_selFrames = m_selFrames.makeReverse();
|
||||||
break;
|
break;
|
||||||
@ -211,7 +196,7 @@ void SaveFileBaseCommand::saveDocumentInBackground(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FileOpROI roi(document, m_slice, m_tag,
|
FileOpROI roi(document, params().slice(), params().tag(),
|
||||||
m_selFrames, m_adjustFramesByTag);
|
m_selFrames, m_adjustFramesByTag);
|
||||||
|
|
||||||
std::unique_ptr<FileOp> fop(
|
std::unique_ptr<FileOp> fop(
|
||||||
@ -219,8 +204,8 @@ void SaveFileBaseCommand::saveDocumentInBackground(
|
|||||||
context,
|
context,
|
||||||
roi,
|
roi,
|
||||||
filename,
|
filename,
|
||||||
m_filenameFormat,
|
params().filenameFormat(),
|
||||||
m_ignoreEmpty));
|
params().ignoreEmpty()));
|
||||||
if (!fop)
|
if (!fop)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -283,7 +268,8 @@ void SaveFileCommand::onExecute(Context* context)
|
|||||||
|
|
||||||
saveDocumentInBackground(
|
saveDocumentInBackground(
|
||||||
context, document,
|
context, document,
|
||||||
documentReader->filename(),
|
(params().filename.isSet() ? params().filename():
|
||||||
|
documentReader->filename()),
|
||||||
MarkAsSaved::On);
|
MarkAsSaved::On);
|
||||||
}
|
}
|
||||||
// If the document isn't associated to a file, we must to show the
|
// If the document isn't associated to a file, we must to show the
|
||||||
@ -291,7 +277,8 @@ void SaveFileCommand::onExecute(Context* context)
|
|||||||
// for this document.
|
// for this document.
|
||||||
else {
|
else {
|
||||||
saveAsDialog(context, "Save File",
|
saveAsDialog(context, "Save File",
|
||||||
document->filename(),
|
(params().filename.isSet() ? params().filename():
|
||||||
|
document->filename()),
|
||||||
MarkAsSaved::On);
|
MarkAsSaved::On);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -313,7 +300,8 @@ void SaveFileAsCommand::onExecute(Context* context)
|
|||||||
{
|
{
|
||||||
Doc* document = context->activeDocument();
|
Doc* document = context->activeDocument();
|
||||||
saveAsDialog(context, "Save As",
|
saveAsDialog(context, "Save As",
|
||||||
document->filename(),
|
(params().filename.isSet() ? params().filename():
|
||||||
|
document->filename()),
|
||||||
MarkAsSaved::On);
|
MarkAsSaved::On);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -337,17 +325,17 @@ SaveFileCopyAsCommand::SaveFileCopyAsCommand()
|
|||||||
void SaveFileCopyAsCommand::onExecute(Context* context)
|
void SaveFileCopyAsCommand::onExecute(Context* context)
|
||||||
{
|
{
|
||||||
Doc* doc = context->activeDocument();
|
Doc* doc = context->activeDocument();
|
||||||
std::string outputFilename = m_filename;
|
std::string outputFilename = params().filename();
|
||||||
std::string layers = kAllLayers;
|
std::string layers = kAllLayers;
|
||||||
std::string frames = kAllFrames;
|
std::string frames = kAllFrames;
|
||||||
double xscale = 1.0;
|
double xscale = 1.0;
|
||||||
double yscale = 1.0;
|
double yscale = 1.0;
|
||||||
bool applyPixelRatio = false;
|
bool applyPixelRatio = false;
|
||||||
doc::AniDir aniDirValue = convert_string_to_anidir(m_aniDir);
|
doc::AniDir aniDirValue = params().aniDir();
|
||||||
bool isForTwitter = false;
|
bool isForTwitter = false;
|
||||||
|
|
||||||
#if ENABLE_UI
|
#if ENABLE_UI
|
||||||
if (m_useUI && context->isUIAvailable()) {
|
if (params().ui() && context->isUIAvailable()) {
|
||||||
ExportFileWindow win(doc);
|
ExportFileWindow win(doc);
|
||||||
bool askOverwrite = true;
|
bool askOverwrite = true;
|
||||||
|
|
||||||
@ -367,6 +355,8 @@ void SaveFileCopyAsCommand::onExecute(Context* context)
|
|||||||
return result;
|
return result;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
win.setAniDir(aniDirValue);
|
||||||
|
|
||||||
win.remapWindow();
|
win.remapWindow();
|
||||||
load_window_pos(&win, "ExportFile");
|
load_window_pos(&win, "ExportFile");
|
||||||
again:;
|
again:;
|
||||||
@ -446,20 +436,22 @@ void SaveFileCopyAsCommand::onExecute(Context* context)
|
|||||||
layers,
|
layers,
|
||||||
layersVisibility);
|
layersVisibility);
|
||||||
|
|
||||||
// Selected frames to export
|
// m_selFrames is not empty if fromFrame/toFrame parameters are
|
||||||
SelectedFrames selFrames;
|
// specified.
|
||||||
Tag* tag = calculate_selected_frames(
|
if (m_selFrames.empty()) {
|
||||||
site, frames, selFrames);
|
// Selected frames to export
|
||||||
if (tag)
|
SelectedFrames selFrames;
|
||||||
m_tag = tag->name();
|
Tag* tag = calculate_selected_frames(
|
||||||
m_selFrames = selFrames;
|
site, frames, selFrames);
|
||||||
|
if (tag)
|
||||||
|
params().tag(tag->name());
|
||||||
|
m_selFrames = selFrames;
|
||||||
|
}
|
||||||
m_adjustFramesByTag = false;
|
m_adjustFramesByTag = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
base::ScopedValue<std::string> restoreAniDir(
|
// Set ani dir
|
||||||
m_aniDir,
|
params().aniDir(aniDirValue);
|
||||||
convert_anidir_to_string(aniDirValue), // New value
|
|
||||||
m_aniDir); // Restore old value
|
|
||||||
|
|
||||||
// TODO This should be set as options for the specific encoder
|
// TODO This should be set as options for the specific encoder
|
||||||
GifEncoderDurationFix fixGif(isForTwitter);
|
GifEncoderDurationFix fixGif(isForTwitter);
|
||||||
|
@ -10,6 +10,8 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "app/commands/command.h"
|
#include "app/commands/command.h"
|
||||||
|
#include "app/commands/new_params.h"
|
||||||
|
#include "doc/anidir.h"
|
||||||
#include "doc/selected_frames.h"
|
#include "doc/selected_frames.h"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
@ -17,7 +19,19 @@
|
|||||||
namespace app {
|
namespace app {
|
||||||
class Doc;
|
class Doc;
|
||||||
|
|
||||||
class SaveFileBaseCommand : public Command {
|
struct SaveFileParams : public NewParams {
|
||||||
|
Param<bool> ui { this, true, { "ui", "useUI" } };
|
||||||
|
Param<std::string> filename { this, std::string(), "filename" };
|
||||||
|
Param<std::string> filenameFormat { this, std::string(), { "filenameFormat", "filename-format" } };
|
||||||
|
Param<std::string> tag { this, std::string(), { "tag", "frame-tag" } };
|
||||||
|
Param<doc::AniDir> aniDir { this, doc::AniDir::FORWARD, { "aniDir", "ani-dir" } };
|
||||||
|
Param<std::string> slice { this, std::string(), "slice" };
|
||||||
|
Param<doc::frame_t> fromFrame { this, 0, { "fromFrame", "from-frame" } };
|
||||||
|
Param<doc::frame_t> toFrame { this, 0, { "toFrame", "to-frame" } };
|
||||||
|
Param<bool> ignoreEmpty { this, false, "ignoreEmpty" };
|
||||||
|
};
|
||||||
|
|
||||||
|
class SaveFileBaseCommand : public CommandWithNewParams<SaveFileParams> {
|
||||||
public:
|
public:
|
||||||
enum class MarkAsSaved { Off, On };
|
enum class MarkAsSaved { Off, On };
|
||||||
enum class SaveInBackground { Off, On };
|
enum class SaveInBackground { Off, On };
|
||||||
@ -41,15 +55,8 @@ namespace app {
|
|||||||
const std::string& filename,
|
const std::string& filename,
|
||||||
const MarkAsSaved markAsSaved);
|
const MarkAsSaved markAsSaved);
|
||||||
|
|
||||||
std::string m_filename;
|
|
||||||
std::string m_filenameFormat;
|
|
||||||
std::string m_tag;
|
|
||||||
std::string m_aniDir;
|
|
||||||
std::string m_slice;
|
|
||||||
doc::SelectedFrames m_selFrames;
|
doc::SelectedFrames m_selFrames;
|
||||||
bool m_adjustFramesByTag;
|
bool m_adjustFramesByTag;
|
||||||
bool m_useUI;
|
|
||||||
bool m_ignoreEmpty;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace app
|
} // namespace app
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
// Copyright (C) 2019-2021 Igara Studio S.A.
|
// Copyright (C) 2019-2022 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.
|
||||||
@ -18,6 +18,7 @@
|
|||||||
#include "base/split_string.h"
|
#include "base/split_string.h"
|
||||||
#include "base/string.h"
|
#include "base/string.h"
|
||||||
#include "doc/algorithm/resize_image.h"
|
#include "doc/algorithm/resize_image.h"
|
||||||
|
#include "doc/anidir.h"
|
||||||
#include "doc/color_mode.h"
|
#include "doc/color_mode.h"
|
||||||
#include "filters/color_curve.h"
|
#include "filters/color_curve.h"
|
||||||
#include "filters/hue_saturation_filter.h"
|
#include "filters/hue_saturation_filter.h"
|
||||||
@ -144,6 +145,12 @@ void Param<doc::ColorMode>::fromString(const std::string& value)
|
|||||||
setValue(doc::ColorMode::RGB);
|
setValue(doc::ColorMode::RGB);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
void Param<doc::AniDir>::fromString(const std::string& value)
|
||||||
|
{
|
||||||
|
setValue(convert_string_to_anidir(value));
|
||||||
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void Param<app::Color>::fromString(const std::string& value)
|
void Param<app::Color>::fromString(const std::string& value)
|
||||||
{
|
{
|
||||||
@ -303,6 +310,15 @@ void Param<doc::ColorMode>::fromLua(lua_State* L, int index)
|
|||||||
setValue((doc::ColorMode)lua_tointeger(L, index));
|
setValue((doc::ColorMode)lua_tointeger(L, index));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
void Param<doc::AniDir>::fromLua(lua_State* L, int index)
|
||||||
|
{
|
||||||
|
if (lua_type(L, index) == LUA_TSTRING)
|
||||||
|
fromString(lua_tostring(L, index));
|
||||||
|
else
|
||||||
|
setValue((doc::AniDir)lua_tointeger(L, index));
|
||||||
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void Param<app::Color>::fromLua(lua_State* L, int index)
|
void Param<app::Color>::fromLua(lua_State* L, int index)
|
||||||
{
|
{
|
||||||
|
@ -10,6 +10,6 @@
|
|||||||
|
|
||||||
// Increment this value if the scripting API is modified between two
|
// Increment this value if the scripting API is modified between two
|
||||||
// released Aseprite versions.
|
// released Aseprite versions.
|
||||||
#define API_VERSION 18
|
#define API_VERSION 19
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
// Copyright (C) 2019-2020 Igara Studio S.A.
|
// Copyright (C) 2019-2022 Igara Studio S.A.
|
||||||
// Copyright (C) 2018 David Capello
|
// Copyright (C) 2018 David Capello
|
||||||
//
|
//
|
||||||
// This program is distributed under the terms of
|
// This program is distributed under the terms of
|
||||||
@ -141,6 +141,11 @@ bool ExportFileWindow::isForTwitter() const
|
|||||||
return forTwitter()->isSelected();
|
return forTwitter()->isSelected();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ExportFileWindow::setAniDir(const doc::AniDir aniDir)
|
||||||
|
{
|
||||||
|
anidir()->setSelectedItemIndex(int(aniDir));
|
||||||
|
}
|
||||||
|
|
||||||
void ExportFileWindow::setOutputFilename(const std::string& pathAndFilename)
|
void ExportFileWindow::setOutputFilename(const std::string& pathAndFilename)
|
||||||
{
|
{
|
||||||
m_outputPath = base::get_file_path(pathAndFilename);
|
m_outputPath = base::get_file_path(pathAndFilename);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
// Copyright (C) 2020 Igara Studio S.A.
|
// Copyright (C) 2020-2022 Igara Studio S.A.
|
||||||
// Copyright (C) 2018 David Capello
|
// Copyright (C) 2018 David Capello
|
||||||
//
|
//
|
||||||
// This program is distributed under the terms of
|
// This program is distributed under the terms of
|
||||||
@ -34,6 +34,8 @@ namespace app {
|
|||||||
bool applyPixelRatio() const;
|
bool applyPixelRatio() const;
|
||||||
bool isForTwitter() const;
|
bool isForTwitter() const;
|
||||||
|
|
||||||
|
void setAniDir(const doc::AniDir aniDir);
|
||||||
|
|
||||||
obs::signal<std::string()> SelectOutputFile;
|
obs::signal<std::string()> SelectOutputFile;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user