mirror of https://github.com/aseprite/aseprite.git
Merge branch 'main' into beta
This commit is contained in:
commit
6c9abed00f
2
laf
2
laf
|
@ -1 +1 @@
|
||||||
Subproject commit 0d8396ea41cf4432f07b31d9002c80ef52e0565a
|
Subproject commit c90b81aec001293bdf7d19eb7feb22509716705e
|
|
@ -54,6 +54,7 @@ AppOptions::AppOptions(int argc, const char* argv[])
|
||||||
, m_allLayers(m_po.add("all-layers").description("Make all layers visible\nBy default hidden layers will be ignored"))
|
, m_allLayers(m_po.add("all-layers").description("Make all layers visible\nBy default hidden layers will be ignored"))
|
||||||
, m_ignoreLayer(m_po.add("ignore-layer").requiresValue("<name>").description("Exclude the given layer in the sheet\nor save as operation"))
|
, m_ignoreLayer(m_po.add("ignore-layer").requiresValue("<name>").description("Exclude the given layer in the sheet\nor save as operation"))
|
||||||
, m_tag(m_po.add("tag").alias("frame-tag").requiresValue("<name>").description("Include tagged frames in the sheet"))
|
, m_tag(m_po.add("tag").alias("frame-tag").requiresValue("<name>").description("Include tagged frames in the sheet"))
|
||||||
|
, m_playSubtags(m_po.add("play-subtags").description("Play subtags and repeats when saving the frames of an animated sprite"))
|
||||||
, m_frameRange(m_po.add("frame-range").requiresValue("from,to").description("Only export frames in the [from,to] range"))
|
, m_frameRange(m_po.add("frame-range").requiresValue("from,to").description("Only export frames in the [from,to] range"))
|
||||||
, m_ignoreEmpty(m_po.add("ignore-empty").description("Do not export empty frames/cels"))
|
, m_ignoreEmpty(m_po.add("ignore-empty").description("Do not export empty frames/cels"))
|
||||||
, m_mergeDuplicates(m_po.add("merge-duplicates").description("Merge all duplicate frames into one in the sprite sheet"))
|
, m_mergeDuplicates(m_po.add("merge-duplicates").description("Merge all duplicate frames into one in the sprite sheet"))
|
||||||
|
|
|
@ -70,6 +70,7 @@ public:
|
||||||
const Option& allLayers() const { return m_allLayers; }
|
const Option& allLayers() const { return m_allLayers; }
|
||||||
const Option& ignoreLayer() const { return m_ignoreLayer; }
|
const Option& ignoreLayer() const { return m_ignoreLayer; }
|
||||||
const Option& tag() const { return m_tag; }
|
const Option& tag() const { return m_tag; }
|
||||||
|
const Option& playSubtags() const { return m_playSubtags; }
|
||||||
const Option& frameRange() const { return m_frameRange; }
|
const Option& frameRange() const { return m_frameRange; }
|
||||||
const Option& ignoreEmpty() const { return m_ignoreEmpty; }
|
const Option& ignoreEmpty() const { return m_ignoreEmpty; }
|
||||||
const Option& mergeDuplicates() const { return m_mergeDuplicates; }
|
const Option& mergeDuplicates() const { return m_mergeDuplicates; }
|
||||||
|
@ -143,6 +144,7 @@ private:
|
||||||
Option& m_allLayers;
|
Option& m_allLayers;
|
||||||
Option& m_ignoreLayer;
|
Option& m_ignoreLayer;
|
||||||
Option& m_tag;
|
Option& m_tag;
|
||||||
|
Option& m_playSubtags;
|
||||||
Option& m_frameRange;
|
Option& m_frameRange;
|
||||||
Option& m_ignoreEmpty;
|
Option& m_ignoreEmpty;
|
||||||
Option& m_mergeDuplicates;
|
Option& m_mergeDuplicates;
|
||||||
|
|
|
@ -44,6 +44,7 @@ namespace app {
|
||||||
bool trimByGrid = false;
|
bool trimByGrid = false;
|
||||||
bool oneFrame = false;
|
bool oneFrame = false;
|
||||||
bool exportTileset = false;
|
bool exportTileset = false;
|
||||||
|
bool playSubtags = false;
|
||||||
gfx::Rect crop;
|
gfx::Rect crop;
|
||||||
|
|
||||||
bool hasTag() const {
|
bool hasTag() const {
|
||||||
|
|
|
@ -303,6 +303,10 @@ int CliProcessor::process(Context* ctx)
|
||||||
else if (opt == &m_options.tag()) {
|
else if (opt == &m_options.tag()) {
|
||||||
cof.tag = value.value();
|
cof.tag = value.value();
|
||||||
}
|
}
|
||||||
|
// --play-subtags
|
||||||
|
else if (opt == &m_options.playSubtags()) {
|
||||||
|
cof.playSubtags = true;
|
||||||
|
}
|
||||||
// --frame-range from,to
|
// --frame-range from,to
|
||||||
else if (opt == &m_options.frameRange()) {
|
else if (opt == &m_options.frameRange()) {
|
||||||
std::vector<std::string> splitRange;
|
std::vector<std::string> splitRange;
|
||||||
|
|
|
@ -88,6 +88,9 @@ void DefaultCliDelegate::saveFile(Context* ctx, const CliOpenFile& cof)
|
||||||
if (cof.hasTag()) {
|
if (cof.hasTag()) {
|
||||||
params.set("frame-tag", cof.tag.c_str());
|
params.set("frame-tag", cof.tag.c_str());
|
||||||
}
|
}
|
||||||
|
if (cof.playSubtags) {
|
||||||
|
params.set("playSubtags", "true");
|
||||||
|
}
|
||||||
if (cof.hasFrameRange()) {
|
if (cof.hasFrameRange()) {
|
||||||
params.set("from-frame", base::convert_to<std::string>(cof.fromFrame).c_str());
|
params.set("from-frame", base::convert_to<std::string>(cof.fromFrame).c_str());
|
||||||
params.set("to-frame", base::convert_to<std::string>(cof.toFrame).c_str());
|
params.set("to-frame", base::convert_to<std::string>(cof.toFrame).c_str());
|
||||||
|
|
|
@ -121,6 +121,10 @@ void PreviewCliDelegate::saveFile(Context* ctx, const CliOpenFile& cof)
|
||||||
std::cout << " - Tag: '" << cof.tag << "'\n";
|
std::cout << " - Tag: '" << cof.tag << "'\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (cof.playSubtags) {
|
||||||
|
std::cout << " - Play subtags & repeats\n";
|
||||||
|
}
|
||||||
|
|
||||||
if (cof.hasSlice()) {
|
if (cof.hasSlice()) {
|
||||||
std::cout << " - Slice: '" << cof.slice << "'\n";
|
std::cout << " - Slice: '" << cof.slice << "'\n";
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
// Aseprite
|
// Aseprite
|
||||||
|
// Copyright (C) 2024 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
|
||||||
|
@ -35,6 +36,8 @@ protected:
|
||||||
|
|
||||||
bool onEnabled(Context* context) override {
|
bool onEnabled(Context* context) override {
|
||||||
Workspace* workspace = App::instance()->workspace();
|
Workspace* workspace = App::instance()->workspace();
|
||||||
|
if (!workspace) // Workspace (main window) can be null if we are in --batch mode
|
||||||
|
return false;
|
||||||
WorkspaceView* view = workspace->activeView();
|
WorkspaceView* view = workspace->activeView();
|
||||||
return (view != nullptr);
|
return (view != nullptr);
|
||||||
}
|
}
|
||||||
|
@ -62,6 +65,8 @@ protected:
|
||||||
|
|
||||||
void onExecute(Context* context) override {
|
void onExecute(Context* context) override {
|
||||||
Workspace* workspace = App::instance()->workspace();
|
Workspace* workspace = App::instance()->workspace();
|
||||||
|
if (!workspace) // Workspace (main window) can be null if we are in --batch mode
|
||||||
|
return;
|
||||||
|
|
||||||
// Collect all document views
|
// Collect all document views
|
||||||
DocViews docViews;
|
DocViews docViews;
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
// Aseprite
|
// Aseprite
|
||||||
|
// Copyright (C) 2024 Igara Studio S.A.
|
||||||
// Copyright (C) 2001-2017 David Capello
|
// Copyright (C) 2001-2017 David Capello
|
||||||
//
|
//
|
||||||
// This program is distributed under the terms of
|
// This program is distributed under the terms of
|
||||||
|
@ -35,6 +36,8 @@ DuplicateViewCommand::DuplicateViewCommand()
|
||||||
bool DuplicateViewCommand::onEnabled(Context* context)
|
bool DuplicateViewCommand::onEnabled(Context* context)
|
||||||
{
|
{
|
||||||
Workspace* workspace = App::instance()->workspace();
|
Workspace* workspace = App::instance()->workspace();
|
||||||
|
if (!workspace) // Workspace (main window) can be null if we are in --batch mode
|
||||||
|
return false;
|
||||||
WorkspaceView* view = workspace->activeView();
|
WorkspaceView* view = workspace->activeView();
|
||||||
return (view != nullptr);
|
return (view != nullptr);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
// Aseprite
|
// Aseprite
|
||||||
|
// Copyright (C) 2024 Igara Studio S.A.
|
||||||
// Copyright (C) 2001-2017 David Capello
|
// Copyright (C) 2001-2017 David Capello
|
||||||
//
|
//
|
||||||
// This program is distributed under the terms of
|
// This program is distributed under the terms of
|
||||||
|
@ -30,7 +31,10 @@ GotoNextTabCommand::GotoNextTabCommand()
|
||||||
|
|
||||||
bool GotoNextTabCommand::onEnabled(Context* context)
|
bool GotoNextTabCommand::onEnabled(Context* context)
|
||||||
{
|
{
|
||||||
return App::instance()->workspace()->canSelectOtherTab();
|
Workspace* workspace = App::instance()->workspace();
|
||||||
|
if (!workspace) // Workspace (main window) can be null if we are in --batch mode
|
||||||
|
return false;
|
||||||
|
return workspace->canSelectOtherTab();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GotoNextTabCommand::onExecute(Context* context)
|
void GotoNextTabCommand::onExecute(Context* context)
|
||||||
|
@ -54,7 +58,10 @@ GotoPreviousTabCommand::GotoPreviousTabCommand()
|
||||||
|
|
||||||
bool GotoPreviousTabCommand::onEnabled(Context* context)
|
bool GotoPreviousTabCommand::onEnabled(Context* context)
|
||||||
{
|
{
|
||||||
return App::instance()->workspace()->canSelectOtherTab();
|
Workspace* workspace = App::instance()->workspace();
|
||||||
|
if (!workspace) // Workspace (main window) can be null if we are in --batch mode
|
||||||
|
return false;
|
||||||
|
return workspace->canSelectOtherTab();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GotoPreviousTabCommand::onExecute(Context* context)
|
void GotoPreviousTabCommand::onExecute(Context* context)
|
||||||
|
|
|
@ -494,29 +494,28 @@ void SaveFileCopyAsCommand::onExecute(Context* context)
|
||||||
|
|
||||||
{
|
{
|
||||||
RestoreVisibleLayers layersVisibility;
|
RestoreVisibleLayers layersVisibility;
|
||||||
|
Site site = context->activeSite();
|
||||||
if (context->isUIAvailable()) {
|
if (context->isUIAvailable()) {
|
||||||
Site site = context->activeSite();
|
|
||||||
|
|
||||||
// Selected layers to export
|
// Selected layers to export
|
||||||
calculate_visible_layers(site,
|
calculate_visible_layers(site,
|
||||||
layers,
|
layers,
|
||||||
layersIndex,
|
layersIndex,
|
||||||
layersVisibility);
|
layersVisibility);
|
||||||
|
|
||||||
// m_selFrames is not empty if fromFrame/toFrame parameters are
|
|
||||||
// specified.
|
|
||||||
if (m_framesSeq.empty()) {
|
|
||||||
// Frames sequence to export
|
|
||||||
FramesSequence framesSeq;
|
|
||||||
Tag* tag = calculate_frames_sequence(
|
|
||||||
site, frames, framesSeq, isPlaySubtags, aniDirValue);
|
|
||||||
if (tag)
|
|
||||||
params().tag(tag->name());
|
|
||||||
m_framesSeq = framesSeq;
|
|
||||||
}
|
|
||||||
m_adjustFramesByTag = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// m_selFrames is not empty if fromFrame/toFrame parameters are
|
||||||
|
// specified.
|
||||||
|
if (m_framesSeq.empty()) {
|
||||||
|
// Frames sequence to export
|
||||||
|
FramesSequence framesSeq;
|
||||||
|
Tag* tag = calculate_frames_sequence(
|
||||||
|
site, frames, framesSeq, isPlaySubtags, aniDirValue);
|
||||||
|
if (tag)
|
||||||
|
params().tag(tag->name());
|
||||||
|
m_framesSeq = framesSeq;
|
||||||
|
}
|
||||||
|
m_adjustFramesByTag = false;
|
||||||
|
|
||||||
// Set other parameters
|
// Set other parameters
|
||||||
params().aniDir(aniDirValue);
|
params().aniDir(aniDirValue);
|
||||||
if (!bounds.isEmpty())
|
if (!bounds.isEmpty())
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
#include "app/doc_range_ops.h"
|
#include "app/doc_range_ops.h"
|
||||||
#include "app/doc_undo.h"
|
#include "app/doc_undo.h"
|
||||||
#include "app/i18n/strings.h"
|
#include "app/i18n/strings.h"
|
||||||
|
#include "app/inline_command_execution.h"
|
||||||
#include "app/loop_tag.h"
|
#include "app/loop_tag.h"
|
||||||
#include "app/modules/gfx.h"
|
#include "app/modules/gfx.h"
|
||||||
#include "app/modules/gui.h"
|
#include "app/modules/gui.h"
|
||||||
|
@ -1390,6 +1391,7 @@ bool Timeline::onProcessMessage(Message* msg)
|
||||||
if ((m_state == STATE_RESIZING_TAG_LEFT && tag->fromFrame() != m_resizeTagData.from) ||
|
if ((m_state == STATE_RESIZING_TAG_LEFT && tag->fromFrame() != m_resizeTagData.from) ||
|
||||||
(m_state == STATE_RESIZING_TAG_RIGHT && tag->toFrame() != m_resizeTagData.to)) {
|
(m_state == STATE_RESIZING_TAG_RIGHT && tag->toFrame() != m_resizeTagData.to)) {
|
||||||
try {
|
try {
|
||||||
|
InlineCommandExecution inlineCmd(m_context);
|
||||||
ContextWriter writer(m_context);
|
ContextWriter writer(m_context);
|
||||||
Tx tx(writer, Strings::commands_FrameTagProperties());
|
Tx tx(writer, Strings::commands_FrameTagProperties());
|
||||||
tx(new cmd::SetTagRange(
|
tx(new cmd::SetTagRange(
|
||||||
|
|
|
@ -407,3 +407,28 @@ assert(d3.bounds == Rectangle(0, 0, 6, 4))
|
||||||
assert(d4.bounds == Rectangle(0, 0, 8, 4))
|
assert(d4.bounds == Rectangle(0, 0, 8, 4))
|
||||||
EOF
|
EOF
|
||||||
$ASEPRITE -b -script "$d/compare.lua" || exit 1
|
$ASEPRITE -b -script "$d/compare.lua" || exit 1
|
||||||
|
|
||||||
|
# --play-subtags --save-as
|
||||||
|
d=$t/save-as-play-subtags
|
||||||
|
$ASEPRITE -b sprites/tags3x123reps.aseprite --play-subtags --save-as $d/image{frame01}.png || exit 1
|
||||||
|
expect "image01.png
|
||||||
|
image02.png
|
||||||
|
image03.png
|
||||||
|
image04.png
|
||||||
|
image05.png
|
||||||
|
image06.png
|
||||||
|
image07.png
|
||||||
|
image08.png
|
||||||
|
image09.png
|
||||||
|
image10.png
|
||||||
|
image11.png" "list_files $d"
|
||||||
|
cat >$d/compare.lua <<EOF
|
||||||
|
local src = app.open("sprites/tags3x123reps.aseprite")
|
||||||
|
src:flatten()
|
||||||
|
local res = app.open("$d/image01.png")
|
||||||
|
local frames = {1,2,3,6,5,4,7,8,9,8,7}
|
||||||
|
for i = 1,#frames do
|
||||||
|
assert(src.layers[1]:cel(frames[i]).image:isEqual(res.layers[1]:cel(i).image))
|
||||||
|
end
|
||||||
|
EOF
|
||||||
|
$ASEPRITE -b -script "$d/compare.lua" || exit 1
|
||||||
|
|
Binary file not shown.
|
@ -11,7 +11,7 @@ endif(MSVC)
|
||||||
if(NOT USE_SHARED_ZLIB)
|
if(NOT USE_SHARED_ZLIB)
|
||||||
set(SKIP_INSTALL_ALL on)
|
set(SKIP_INSTALL_ALL on)
|
||||||
# Don't build zlib tests
|
# Don't build zlib tests
|
||||||
set(ZLIB_TESTS OFF CACHE BOOL "Build zlib tests")
|
set(ZLIB_BUILD_EXAMPLES OFF CACHE BOOL "Enable Zlib Examples")
|
||||||
add_subdirectory(zlib)
|
add_subdirectory(zlib)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
@ -123,6 +123,9 @@ endif()
|
||||||
add_subdirectory(json11)
|
add_subdirectory(json11)
|
||||||
|
|
||||||
# libarchive
|
# libarchive
|
||||||
|
set(HAVE_WCSCPY 1)
|
||||||
|
set(HAVE_WCSLEN 1)
|
||||||
|
|
||||||
set(ENABLE_WERROR OFF CACHE BOOL "Treat warnings as errors - default is ON for Debug, OFF otherwise.")
|
set(ENABLE_WERROR OFF CACHE BOOL "Treat warnings as errors - default is ON for Debug, OFF otherwise.")
|
||||||
set(ENABLE_TEST OFF CACHE BOOL "Enable unit and regression tests")
|
set(ENABLE_TEST OFF CACHE BOOL "Enable unit and regression tests")
|
||||||
set(ENABLE_COVERAGE OFF CACHE BOOL "Enable code coverage (GCC only, automatically sets ENABLE_TEST to ON)")
|
set(ENABLE_COVERAGE OFF CACHE BOOL "Enable code coverage (GCC only, automatically sets ENABLE_TEST to ON)")
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit fc3ecad5d50b59945ffd3f44c78472c3ecc70b87
|
Subproject commit 51b7f2abdade71cd9bb0e7a373ef2610ec6f9daf
|
Loading…
Reference in New Issue