mirror of
https://github.com/aseprite/aseprite.git
synced 2025-01-30 15:32:38 +00:00
Merge branch 'main' into beta
This commit is contained in:
commit
a012dac020
@ -121,6 +121,11 @@
|
||||
<value id="HSV" value="1" />
|
||||
<value id="HSL" value="2" />
|
||||
</enum>
|
||||
<enum id="SequenceDecision">
|
||||
<value id="ASK" value="0" />
|
||||
<value id="YES" value="1" />
|
||||
<value id="NO" value="2" />
|
||||
</enum>
|
||||
</types>
|
||||
|
||||
<global>
|
||||
@ -183,6 +188,9 @@
|
||||
<section id="tags">
|
||||
<option id="user_data_visibility" type="bool" default="false" />
|
||||
</section>
|
||||
<section id="timeline">
|
||||
<option id="keep_selection" type="bool" default="false" />
|
||||
</section>
|
||||
<section id="cursor">
|
||||
<option id="use_native_cursor" type="bool" default="false" />
|
||||
<option id="cursor_scale" type="int" default="1" />
|
||||
@ -330,6 +338,9 @@
|
||||
<section id="advanced_mode">
|
||||
<option id="show_alert" type="bool" default="true" />
|
||||
</section>
|
||||
<section id="open_file">
|
||||
<option id="open_sequence" type="SequenceDecision" default="SequenceDecision::ASK" />
|
||||
</section>
|
||||
<section id="save_file">
|
||||
<option id="show_file_format_doesnt_support_alert" type="bool" default="true" />
|
||||
<option id="show_export_animation_in_sequence_alert" type="bool" default="true" />
|
||||
|
@ -1244,6 +1244,11 @@ rewind_on_stop_tooltip = <<<END
|
||||
The 'Stop' button should rewind the animation
|
||||
where it was started.
|
||||
END
|
||||
keep_timeline_selection = Keep selection
|
||||
keep_timeline_selection_tooltip = <<<END
|
||||
Keep the selected range of layers/frames/cels
|
||||
when we edit the canvas.
|
||||
END
|
||||
default_first_frame = Default First Frame:
|
||||
ui_mouse_cursor = UI Mouse Cursor
|
||||
native_cursor = Use native mouse cursors
|
||||
@ -1297,6 +1302,10 @@ the current frame & layer will be modified
|
||||
to focus the undid/redid change.
|
||||
END
|
||||
undo_allow_nonlinear_history = Allow non-linear history
|
||||
open_sequence_alert = Open a sequence of static files as an animation
|
||||
open_sequence_alert_ask = Ask
|
||||
open_sequence_alert_no = No
|
||||
open_sequence_alert_yes = Yes
|
||||
file_format_doesnt_support_alert = Show warning when saving a file with unsupported features
|
||||
export_animation_in_sequence_alert = Show warning when saving an animation as a sequence of static images
|
||||
overwrite_files_on_export_alert = Show warning when overwriting files on File > Export
|
||||
|
@ -1,4 +1,5 @@
|
||||
<!-- Aseprite -->
|
||||
<!-- Copyright (C) 2021 by Igara Studio S.A. -->
|
||||
<!-- Copyright (C) 2016 by David Capello -->
|
||||
<gui>
|
||||
<window id="open_sequence" text="@.title">
|
||||
@ -9,6 +10,7 @@
|
||||
</view>
|
||||
<separator horizontal="true" />
|
||||
<check id="repeat" text="@.repeat" />
|
||||
<check id="dont_show" text="@general.dont_show" />
|
||||
<hbox>
|
||||
<boxfiller />
|
||||
<hbox homogeneous="true">
|
||||
|
@ -258,6 +258,8 @@
|
||||
pref="general.autoshow_timeline" />
|
||||
<check text="@.rewind_on_stop" id="rewind_on_stop" tooltip="@.rewind_on_stop_tooltip"
|
||||
pref="general.rewind_on_stop" />
|
||||
<check text="@.keep_timeline_selection" id="keep_selection" tooltip="@.keep_timeline_selection_tooltip"
|
||||
pref="timeline.keep_selection" />
|
||||
<hbox>
|
||||
<label text="@.default_first_frame" />
|
||||
<expr id="first_frame" />
|
||||
@ -424,6 +426,14 @@
|
||||
<!-- Alerts -->
|
||||
<vbox id="section_alerts">
|
||||
<separator text="@.section_alerts" horizontal="true" />
|
||||
<hbox>
|
||||
<label text="@.open_sequence_alert" />
|
||||
<combobox id="open_sequence">
|
||||
<listitem text="@.open_sequence_alert_ask" value="0" />
|
||||
<listitem text="@.open_sequence_alert_yes" value="1" />
|
||||
<listitem text="@.open_sequence_alert_no" value="2" />
|
||||
</combobox>
|
||||
</hbox>
|
||||
<check id="file_format_doesnt_support_alert" text="@.file_format_doesnt_support_alert"
|
||||
pref="save_file.show_file_format_doesnt_support_alert" />
|
||||
<check id="export_animation_in_sequence_alert" text="@.export_animation_in_sequence_alert"
|
||||
|
@ -235,7 +235,6 @@ if(ENABLE_UI)
|
||||
commands/cmd_goto_tab.cpp
|
||||
commands/cmd_grid.cpp
|
||||
commands/cmd_home.cpp
|
||||
commands/cmd_import_sprite_sheet.cpp
|
||||
commands/cmd_invert_mask.cpp
|
||||
commands/cmd_keyboard_shortcuts.cpp
|
||||
commands/cmd_launch.cpp
|
||||
@ -521,6 +520,7 @@ add_library(app-lib
|
||||
commands/cmd_export_sprite_sheet.cpp
|
||||
commands/cmd_flatten_layers.cpp
|
||||
commands/cmd_flip.cpp
|
||||
commands/cmd_import_sprite_sheet.cpp
|
||||
commands/cmd_layer_from_background.cpp
|
||||
commands/cmd_load_palette.cpp
|
||||
commands/cmd_merge_down_layer.cpp
|
||||
|
@ -12,7 +12,7 @@
|
||||
#include "app/app.h"
|
||||
#include "app/commands/command.h"
|
||||
#include "app/commands/commands.h"
|
||||
#include "app/commands/params.h"
|
||||
#include "app/commands/new_params.h"
|
||||
#include "app/context.h"
|
||||
#include "app/context_access.h"
|
||||
#include "app/doc_access.h"
|
||||
@ -44,6 +44,14 @@ namespace app {
|
||||
|
||||
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
|
||||
, public SelectBoxDelegate {
|
||||
public:
|
||||
@ -127,6 +135,17 @@ public:
|
||||
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:
|
||||
|
||||
void onSheetTypeChange() {
|
||||
@ -370,7 +389,7 @@ private:
|
||||
DocumentPreferences* m_docPref;
|
||||
};
|
||||
|
||||
class ImportSpriteSheetCommand : public Command {
|
||||
class ImportSpriteSheetCommand : public CommandWithNewParams<ImportSpriteSheetParams> {
|
||||
public:
|
||||
ImportSpriteSheetCommand();
|
||||
|
||||
@ -379,29 +398,44 @@ protected:
|
||||
};
|
||||
|
||||
ImportSpriteSheetCommand::ImportSpriteSheetCommand()
|
||||
: Command(CommandId::ImportSpriteSheet(), CmdRecordableFlag)
|
||||
: CommandWithNewParams(CommandId::ImportSpriteSheet(), CmdRecordableFlag)
|
||||
{
|
||||
}
|
||||
|
||||
void ImportSpriteSheetCommand::onExecute(Context* context)
|
||||
{
|
||||
ImportSpriteSheetWindow window(context);
|
||||
Doc* document;
|
||||
auto& params = this->params();
|
||||
|
||||
window.openWindowInForeground();
|
||||
if (!window.ok())
|
||||
return;
|
||||
#ifdef ENABLE_UI
|
||||
if (context->isUIAvailable() && params.ui()) {
|
||||
// TODO use params as input values for the ImportSpriteSheetWindow
|
||||
|
||||
Doc* document = window.document();
|
||||
DocumentPreferences* docPref = window.docPref();
|
||||
gfx::Rect frameBounds = window.frameBounds();
|
||||
gfx::Size padThickness = window.paddingThickness();
|
||||
bool partialTiles = window.partialTilesValue();
|
||||
bool paddingEnable = window.paddingEnabledValue();
|
||||
auto sheetType = window.sheetTypeValue();
|
||||
ImportSpriteSheetWindow window(context);
|
||||
window.openWindowInForeground();
|
||||
if (!window.ok())
|
||||
return;
|
||||
|
||||
ASSERT(document);
|
||||
if (!document)
|
||||
return;
|
||||
document = window.document();
|
||||
if (!document)
|
||||
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
|
||||
std::vector<ImageRef> animation;
|
||||
@ -409,39 +443,44 @@ void ImportSpriteSheetCommand::onExecute(Context* context)
|
||||
try {
|
||||
Sprite* sprite = document->sprite();
|
||||
frame_t currentFrame = context->activeSite().frame();
|
||||
gfx::Rect frameBounds = params.frameBounds();
|
||||
const gfx::Size padding = params.padding();
|
||||
render::Render render;
|
||||
render.setNewBlend(Preferences::instance().experimental.newBlend());
|
||||
|
||||
if (frameBounds.isEmpty())
|
||||
frameBounds = sprite->bounds();
|
||||
|
||||
// Each sprite in the sheet
|
||||
std::vector<gfx::Rect> tileRects;
|
||||
int widthStop = sprite->width();
|
||||
int heightStop = sprite->height();
|
||||
if (partialTiles) {
|
||||
if (params.partialTiles()) {
|
||||
widthStop += frameBounds.w-1;
|
||||
heightStop += frameBounds.h-1;
|
||||
}
|
||||
|
||||
switch (sheetType) {
|
||||
switch (params.type()) {
|
||||
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));
|
||||
}
|
||||
break;
|
||||
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));
|
||||
}
|
||||
break;
|
||||
case app::SpriteSheetType::Rows:
|
||||
for (int y=frameBounds.y; y+frameBounds.h<=heightStop; y+=frameBounds.h+padThickness.h) {
|
||||
for (int x=frameBounds.x; x+frameBounds.w<=widthStop; x+=frameBounds.w+padThickness.w) {
|
||||
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+padding.w) {
|
||||
tileRects.push_back(gfx::Rect(x, y, frameBounds.w, frameBounds.h));
|
||||
}
|
||||
}
|
||||
break;
|
||||
case app::SpriteSheetType::Columns:
|
||||
for (int x=frameBounds.x; x+frameBounds.w<=widthStop; x+=frameBounds.w+padThickness.w) {
|
||||
for (int y=frameBounds.y; y+frameBounds.h<=heightStop; y+=frameBounds.h+padThickness.h) {
|
||||
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+padding.h) {
|
||||
tileRects.push_back(gfx::Rect(x, y, frameBounds.w, frameBounds.h));
|
||||
}
|
||||
}
|
||||
@ -502,21 +541,15 @@ void ImportSpriteSheetCommand::onExecute(Context* context)
|
||||
api.setSpriteSize(sprite, frameBounds.w, frameBounds.h);
|
||||
|
||||
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 (...) {
|
||||
throw;
|
||||
}
|
||||
|
||||
update_screen_for_document(document);
|
||||
#ifdef ENABLE_UI
|
||||
if (context->isUIAvailable())
|
||||
update_screen_for_document(document);
|
||||
#endif
|
||||
}
|
||||
|
||||
Command* CommandFactory::createImportSpriteSheetCommand()
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2019-2020 Igara Studio S.A.
|
||||
// Copyright (C) 2019-2021 Igara Studio S.A.
|
||||
// Copyright (C) 2001-2018 David Capello
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
@ -78,7 +78,7 @@ OpenFileCommand::OpenFileCommand()
|
||||
: Command(CommandId::OpenFile(), CmdRecordableFlag)
|
||||
, m_repeatCheckbox(false)
|
||||
, m_oneFrame(false)
|
||||
, m_seqDecision(SequenceDecision::Ask)
|
||||
, m_seqDecision(gen::SequenceDecision::ASK)
|
||||
{
|
||||
}
|
||||
|
||||
@ -90,12 +90,18 @@ void OpenFileCommand::onLoadParams(const Params& params)
|
||||
m_oneFrame = params.get_as<bool>("oneframe");
|
||||
|
||||
std::string sequence = params.get("sequence");
|
||||
if (m_oneFrame || sequence == "skip")
|
||||
m_seqDecision = SequenceDecision::Skip;
|
||||
else if (sequence == "agree")
|
||||
m_seqDecision = SequenceDecision::Agree;
|
||||
else
|
||||
m_seqDecision = SequenceDecision::Ask;
|
||||
if (m_oneFrame ||
|
||||
sequence == "skip" ||
|
||||
sequence == "no") {
|
||||
m_seqDecision = gen::SequenceDecision::NO;
|
||||
}
|
||||
else if (sequence == "agree" ||
|
||||
sequence == "yes") {
|
||||
m_seqDecision = gen::SequenceDecision::YES;
|
||||
}
|
||||
else {
|
||||
m_seqDecision = gen::SequenceDecision::ASK;
|
||||
}
|
||||
}
|
||||
|
||||
void OpenFileCommand::onExecute(Context* context)
|
||||
@ -143,14 +149,25 @@ void OpenFileCommand::onExecute(Context* context)
|
||||
FILE_LOAD_CREATE_PALETTE |
|
||||
(m_repeatCheckbox ? FILE_LOAD_SEQUENCE_ASK_CHECKBOX: 0);
|
||||
|
||||
if (context->isUIAvailable() &&
|
||||
m_seqDecision == gen::SequenceDecision::ASK) {
|
||||
if (Preferences::instance().openFile.openSequence() == gen::SequenceDecision::ASK) {
|
||||
// Do nothing (ask by default, or whatever the command params
|
||||
// specified)
|
||||
}
|
||||
else {
|
||||
m_seqDecision = Preferences::instance().openFile.openSequence();
|
||||
}
|
||||
}
|
||||
|
||||
switch (m_seqDecision) {
|
||||
case SequenceDecision::Ask:
|
||||
case gen::SequenceDecision::ASK:
|
||||
flags |= FILE_LOAD_SEQUENCE_ASK;
|
||||
break;
|
||||
case SequenceDecision::Agree:
|
||||
case gen::SequenceDecision::YES:
|
||||
flags |= FILE_LOAD_SEQUENCE_YES;
|
||||
break;
|
||||
case SequenceDecision::Skip:
|
||||
case gen::SequenceDecision::NO:
|
||||
flags |= FILE_LOAD_SEQUENCE_NONE;
|
||||
break;
|
||||
}
|
||||
@ -179,12 +196,12 @@ void OpenFileCommand::onExecute(Context* context)
|
||||
else {
|
||||
if (fop->isSequence()) {
|
||||
if (fop->sequenceFlags() & FILE_LOAD_SEQUENCE_YES) {
|
||||
m_seqDecision = SequenceDecision::Agree;
|
||||
m_seqDecision = gen::SequenceDecision::YES;
|
||||
flags &= ~FILE_LOAD_SEQUENCE_ASK;
|
||||
flags |= FILE_LOAD_SEQUENCE_YES;
|
||||
}
|
||||
else if (fop->sequenceFlags() & FILE_LOAD_SEQUENCE_NONE) {
|
||||
m_seqDecision = SequenceDecision::Skip;
|
||||
m_seqDecision = gen::SequenceDecision::NO;
|
||||
flags &= ~FILE_LOAD_SEQUENCE_ASK;
|
||||
flags |= FILE_LOAD_SEQUENCE_NONE;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2020 Igara Studio S.A.
|
||||
// Copyright (C) 2020-2021 Igara Studio S.A.
|
||||
// Copyright (C) 2016-2018 David Capello
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
@ -10,6 +10,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "app/commands/command.h"
|
||||
#include "app/pref/preferences.h"
|
||||
#include "base/paths.h"
|
||||
|
||||
#include <string>
|
||||
@ -18,17 +19,13 @@ namespace app {
|
||||
|
||||
class OpenFileCommand : public Command {
|
||||
public:
|
||||
enum class SequenceDecision {
|
||||
Ask, Agree, Skip,
|
||||
};
|
||||
|
||||
OpenFileCommand();
|
||||
|
||||
const base::paths& usedFiles() const {
|
||||
return m_usedFiles;
|
||||
}
|
||||
|
||||
SequenceDecision seqDecision() const {
|
||||
gen::SequenceDecision seqDecision() const {
|
||||
return m_seqDecision;
|
||||
}
|
||||
|
||||
@ -42,7 +39,7 @@ namespace app {
|
||||
bool m_repeatCheckbox;
|
||||
bool m_oneFrame;
|
||||
base::paths m_usedFiles;
|
||||
SequenceDecision m_seqDecision;
|
||||
gen::SequenceDecision m_seqDecision;
|
||||
};
|
||||
|
||||
} // namespace app
|
||||
|
@ -236,6 +236,7 @@ public:
|
||||
}
|
||||
|
||||
// Alerts
|
||||
openSequence()->setSelectedItemIndex(int(m_pref.openFile.openSequence()));
|
||||
resetAlerts()->Click.connect([this]{ onResetAlerts(); });
|
||||
|
||||
// Cursor
|
||||
@ -686,6 +687,9 @@ public:
|
||||
m_curPref->bg.color1(checkedBgColor1()->getColor());
|
||||
m_curPref->bg.color2(checkedBgColor2()->getColor());
|
||||
|
||||
// Alerts preferences
|
||||
m_pref.openFile.openSequence(gen::SequenceDecision(openSequence()->getSelectedItemIndex()));
|
||||
|
||||
int undo_size_limit_value;
|
||||
undo_size_limit_value = undoSizeLimit()->textInt();
|
||||
undo_size_limit_value = base::clamp(undo_size_limit_value, 0, 999999);
|
||||
|
@ -24,6 +24,7 @@ FOR_EACH_COMMAND(ExportSpriteSheet)
|
||||
FOR_EACH_COMMAND(FlattenLayers)
|
||||
FOR_EACH_COMMAND(Flip)
|
||||
FOR_EACH_COMMAND(HueSaturation)
|
||||
FOR_EACH_COMMAND(ImportSpriteSheet)
|
||||
FOR_EACH_COMMAND(InvertColor)
|
||||
FOR_EACH_COMMAND(LayerFromBackground)
|
||||
FOR_EACH_COMMAND(LoadPalette)
|
||||
@ -90,7 +91,6 @@ FOR_EACH_COMMAND(GotoPreviousLayer)
|
||||
FOR_EACH_COMMAND(GotoPreviousTab)
|
||||
FOR_EACH_COMMAND(GridSettings)
|
||||
FOR_EACH_COMMAND(Home)
|
||||
FOR_EACH_COMMAND(ImportSpriteSheet)
|
||||
FOR_EACH_COMMAND(InvertMask)
|
||||
FOR_EACH_COMMAND(KeyboardShortcuts)
|
||||
FOR_EACH_COMMAND(Launch)
|
||||
|
@ -1,5 +1,5 @@
|
||||
// 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
|
||||
// the End-User License Agreement for Aseprite.
|
||||
@ -25,6 +25,7 @@
|
||||
#include "filters/outline_filter.h"
|
||||
#include "filters/tiled_mode.h"
|
||||
#include "gfx/rect.h"
|
||||
#include "gfx/size.h"
|
||||
|
||||
#ifdef ENABLE_SCRIPTING
|
||||
#include "app/script/engine.h"
|
||||
@ -62,6 +63,19 @@ void Param<std::string>::fromString(const std::string& 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<>
|
||||
void Param<gfx::Rect>::fromString(const std::string& value)
|
||||
{
|
||||
@ -253,6 +267,12 @@ void Param<std::string>::fromLua(lua_State* L, int index)
|
||||
setValue(std::string());
|
||||
}
|
||||
|
||||
template<>
|
||||
void Param<gfx::Size>::fromLua(lua_State* L, int index)
|
||||
{
|
||||
setValue(script::convert_args_into_size(L, index));
|
||||
}
|
||||
|
||||
template<>
|
||||
void Param<gfx::Rect>::fromLua(lua_State* L, int index)
|
||||
{
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2018-2020 Igara Studio S.A.
|
||||
// Copyright (C) 2018-2021 Igara Studio S.A.
|
||||
// Copyright (C) 2001-2018 David Capello
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
@ -261,10 +261,19 @@ FileOp* FileOp::createLoadDocumentOperation(Context* context,
|
||||
|
||||
window.openWindowInForeground();
|
||||
|
||||
// Don't show this alert again.
|
||||
if (window.dontShow()->isSelected()) {
|
||||
Preferences::instance().openFile.openSequence(
|
||||
window.closer() == window.agree() ?
|
||||
gen::SequenceDecision::YES:
|
||||
gen::SequenceDecision::NO);
|
||||
}
|
||||
|
||||
// If the user selected the "do the same for other files"
|
||||
// checkbox, we've to save what the user want to do for the
|
||||
// following files.
|
||||
if (window.repeat()->isSelected()) {
|
||||
if (window.repeat()->isSelected() ||
|
||||
window.dontShow()->isSelected()) {
|
||||
if (window.closer() == window.agree())
|
||||
fop->m_seq.flags = FILE_LOAD_SEQUENCE_YES;
|
||||
else
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2019-2020 Igara Studio S.A.
|
||||
// Copyright (C) 2019-2021 Igara Studio S.A.
|
||||
// Copyright (C) 2001-2018 David Capello
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
@ -52,7 +52,8 @@ class TgaFormat : public FileFormat {
|
||||
FILE_SUPPORT_GRAY |
|
||||
FILE_SUPPORT_INDEXED |
|
||||
FILE_SUPPORT_SEQUENCES |
|
||||
FILE_SUPPORT_GET_FORMAT_OPTIONS;
|
||||
FILE_SUPPORT_GET_FORMAT_OPTIONS |
|
||||
FILE_SUPPORT_PALETTE_WITH_ALPHA;
|
||||
}
|
||||
|
||||
bool onLoad(FileOp* fop) override;
|
||||
@ -148,8 +149,10 @@ bool TgaFormat::onLoad(FileOp* fop)
|
||||
tga::getr(c),
|
||||
tga::getg(c),
|
||||
tga::getb(c));
|
||||
if (tga::geta(c) < 255)
|
||||
if (tga::geta(c) < 255) {
|
||||
fop->sequenceSetAlpha(i, tga::geta(c));
|
||||
fop->sequenceSetHasAlpha(true); // Is a transparent sprite
|
||||
}
|
||||
}
|
||||
}
|
||||
// Generate grayscale palette
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2018-2020 Igara Studio S.A.
|
||||
// Copyright (C) 2018-2021 Igara Studio S.A.
|
||||
// Copyright (C) 2015-2018 David Capello
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
@ -21,6 +21,7 @@
|
||||
#include "app/cmd/remove_tag.h"
|
||||
#include "app/cmd/set_grid_bounds.h"
|
||||
#include "app/cmd/set_mask.h"
|
||||
#include "app/cmd/set_pixel_ratio.h"
|
||||
#include "app/cmd/set_sprite_size.h"
|
||||
#include "app/cmd/set_transparent_color.h"
|
||||
#include "app/color_spaces.h"
|
||||
@ -782,6 +783,23 @@ int Sprite_set_gridBounds(lua_State* L)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Sprite_get_pixelRatio(lua_State* L)
|
||||
{
|
||||
const auto sprite = get_docobj<Sprite>(L, 1);
|
||||
push_obj<gfx::Size>(L, sprite->pixelRatio());
|
||||
return 1;
|
||||
}
|
||||
|
||||
int Sprite_set_pixelRatio(lua_State* L)
|
||||
{
|
||||
auto sprite = get_docobj<Sprite>(L, 1);
|
||||
const gfx::Size pixelRatio = convert_args_into_size(L, 2);
|
||||
Tx tx;
|
||||
tx(new cmd::SetPixelRatio(sprite, pixelRatio));
|
||||
tx.commit();
|
||||
return 0;
|
||||
}
|
||||
|
||||
const luaL_Reg Sprite_methods[] = {
|
||||
{ "__eq", Sprite_eq },
|
||||
{ "resize", Sprite_resize },
|
||||
@ -835,6 +853,7 @@ const Property Sprite_properties[] = {
|
||||
{ "gridBounds", Sprite_get_gridBounds, Sprite_set_gridBounds },
|
||||
{ "color", UserData_get_color<Sprite>, UserData_set_color<Sprite> },
|
||||
{ "data", UserData_get_text<Sprite>, UserData_set_text<Sprite> },
|
||||
{ "pixelRatio", Sprite_get_pixelRatio, Sprite_set_pixelRatio },
|
||||
{ nullptr, nullptr, nullptr }
|
||||
};
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
// 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
|
||||
// the End-User License Agreement for Aseprite.
|
||||
@ -187,11 +187,12 @@ FOR_ENUM(app::gen::PivotPosition)
|
||||
FOR_ENUM(app::gen::PixelConnectivity)
|
||||
FOR_ENUM(app::gen::RightClickMode)
|
||||
FOR_ENUM(app::gen::SelectionMode)
|
||||
FOR_ENUM(app::gen::SequenceDecision)
|
||||
FOR_ENUM(app::gen::StopAtGrid)
|
||||
FOR_ENUM(app::gen::SymmetryMode)
|
||||
FOR_ENUM(app::gen::TimelinePosition)
|
||||
FOR_ENUM(app::gen::WindowColorProfile)
|
||||
FOR_ENUM(app::gen::ToGrayAlgorithm)
|
||||
FOR_ENUM(app::gen::WindowColorProfile)
|
||||
FOR_ENUM(app::tools::FreehandAlgorithm)
|
||||
FOR_ENUM(app::tools::RotationAlgorithm)
|
||||
FOR_ENUM(doc::AniDir)
|
||||
|
@ -288,9 +288,8 @@ public:
|
||||
RgbMap* getRgbMap() override {
|
||||
if (!m_rgbMap) {
|
||||
Sprite::RgbMapFor forLayer =
|
||||
((!m_layer ||
|
||||
m_layer->isBackground() ||
|
||||
m_sprite->pixelFormat() == IMAGE_RGB) ?
|
||||
(((m_layer && m_layer->isBackground()) ||
|
||||
(m_sprite->pixelFormat() == IMAGE_RGB)) ?
|
||||
Sprite::RgbMapFor::OpaqueLayer:
|
||||
Sprite::RgbMapFor::TransparentLayer);
|
||||
m_rgbMap = m_sprite->rgbMap(m_frame, forLayer);
|
||||
|
@ -325,18 +325,24 @@ void Timeline::updateUsingEditor(Editor* editor)
|
||||
|
||||
m_aniControls.updateUsingEditor(editor);
|
||||
|
||||
DocRange oldRange;
|
||||
if (editor != m_editor) {
|
||||
// Save active m_tagFocusBand into the old focused editor
|
||||
if (m_editor)
|
||||
m_editor->setTagFocusBand(m_tagFocusBand);
|
||||
m_tagFocusBand = -1;
|
||||
}
|
||||
else {
|
||||
oldRange = m_range;
|
||||
}
|
||||
|
||||
detachDocument();
|
||||
|
||||
if (m_range.enabled() &&
|
||||
m_rangeLocks == 0) {
|
||||
m_range.clearRange();
|
||||
if (Preferences::instance().timeline.keepSelection())
|
||||
m_range = oldRange;
|
||||
else {
|
||||
// The range is reset in detachDocument()
|
||||
ASSERT(!m_range.enabled());
|
||||
}
|
||||
|
||||
// We always update the editor. In this way the timeline keeps in
|
||||
@ -2990,14 +2996,17 @@ gfx::Rect Timeline::getRangeBounds(const Range& range) const
|
||||
}
|
||||
break;
|
||||
case Range::kFrames: {
|
||||
for (auto frame : range.selectedFrames())
|
||||
for (auto frame : range.selectedFrames()) {
|
||||
rc |= getPartBounds(Hit(PART_HEADER_FRAME, 0, frame));
|
||||
rc |= getPartBounds(Hit(PART_CEL, 0, frame));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Range::kLayers:
|
||||
for (auto layer : range.selectedLayers()) {
|
||||
layer_t layerIdx = getLayerIndex(layer);
|
||||
rc |= getPartBounds(Hit(PART_ROW_TEXT, layerIdx));
|
||||
rc |= getPartBounds(Hit(PART_CEL, layerIdx, m_sprite->lastFrame()));
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -3006,11 +3015,28 @@ gfx::Rect Timeline::getRangeBounds(const Range& range) const
|
||||
|
||||
gfx::Rect Timeline::getRangeClipBounds(const Range& range) const
|
||||
{
|
||||
gfx::Rect clipBounds;
|
||||
gfx::Rect celBounds = getCelsBounds();
|
||||
gfx::Rect clipBounds, unionBounds;
|
||||
switch (range.type()) {
|
||||
case Range::kCels: clipBounds = getCelsBounds(); break;
|
||||
case Range::kFrames: clipBounds = getFrameHeadersBounds(); break;
|
||||
case Range::kLayers: clipBounds = getLayerHeadersBounds(); break;
|
||||
case Range::kCels:
|
||||
clipBounds = celBounds;
|
||||
break;
|
||||
case Range::kFrames: {
|
||||
clipBounds = getFrameHeadersBounds();
|
||||
|
||||
unionBounds = (clipBounds | celBounds);
|
||||
clipBounds.y = unionBounds.y;
|
||||
clipBounds.h = unionBounds.h;
|
||||
break;
|
||||
}
|
||||
case Range::kLayers: {
|
||||
clipBounds = getLayerHeadersBounds();
|
||||
|
||||
unionBounds = (clipBounds | celBounds);
|
||||
clipBounds.x = unionBounds.x;
|
||||
clipBounds.w = unionBounds.w;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return clipBounds;
|
||||
}
|
||||
@ -3940,6 +3966,8 @@ void Timeline::setViewScroll(const gfx::Point& pt)
|
||||
gfx::Rect rc;
|
||||
if (m_tagBands > 0)
|
||||
rc |= getPartBounds(Hit(PART_TAG_BAND));
|
||||
if (m_range.enabled())
|
||||
rc |= getRangeBounds(m_range).enlarge(outlineWidth());
|
||||
rc |= getFrameHeadersBounds();
|
||||
rc |= getCelsBounds();
|
||||
rc.offset(origin());
|
||||
@ -4153,8 +4181,10 @@ void Timeline::onNewInputPriority(InputChainElement* element,
|
||||
return;
|
||||
|
||||
if (element != this && m_rangeLocks == 0) {
|
||||
m_range.clearRange();
|
||||
invalidate();
|
||||
if (!Preferences::instance().timeline.keepSelection()) {
|
||||
m_range.clearRange();
|
||||
invalidate();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2020 Igara Studio S.A.
|
||||
// Copyright (C) 2020-2021 Igara Studio S.A.
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
// the End-User License Agreement for Aseprite.
|
||||
@ -29,14 +29,14 @@ namespace app {
|
||||
params.set("oneframe", "true");
|
||||
else {
|
||||
switch (m_lastDecision) {
|
||||
case OpenFileCommand::SequenceDecision::Ask:
|
||||
case gen::SequenceDecision::ASK:
|
||||
params.set("sequence", "ask");
|
||||
params.set("repeat_checkbox", "true");
|
||||
break;
|
||||
case OpenFileCommand::SequenceDecision::Skip:
|
||||
case gen::SequenceDecision::NO:
|
||||
params.set("sequence", "skip");
|
||||
break;
|
||||
case OpenFileCommand::SequenceDecision::Agree:
|
||||
case gen::SequenceDecision::YES:
|
||||
params.set("sequence", "agree");
|
||||
break;
|
||||
}
|
||||
@ -49,7 +49,7 @@ namespace app {
|
||||
|
||||
// Future decision for other files in the CLI
|
||||
auto d = m_cmd.seqDecision();
|
||||
if (d != OpenFileCommand::SequenceDecision::Ask)
|
||||
if (d != gen::SequenceDecision::ASK)
|
||||
m_lastDecision = d;
|
||||
}
|
||||
|
||||
@ -59,7 +59,7 @@ namespace app {
|
||||
|
||||
private:
|
||||
OpenFileCommand m_cmd;
|
||||
OpenFileCommand::SequenceDecision m_lastDecision = OpenFileCommand::SequenceDecision::Ask;
|
||||
gen::SequenceDecision m_lastDecision = gen::SequenceDecision::ASK;
|
||||
};
|
||||
|
||||
} // namespace app
|
||||
|
Loading…
x
Reference in New Issue
Block a user