Merge branch 'main' into beta

This commit is contained in:
David Capello 2022-08-31 11:56:19 -03:00
commit ddafa5083e
7 changed files with 113 additions and 32 deletions

View File

@ -1142,6 +1142,7 @@ octree = Octree
title = Notice
description = Do you want to load the following files as an animation?
repeat = Do the same for other files
duration = Duration
agree = &Agree
skip = &Skip

View File

@ -8,6 +8,10 @@
<view expansive="true" id="view" minwidth="128" minheight="64">
<listbox id="files" multiselect="true" />
</view>
<hbox>
<label text="@.duration" />
<expr text="0" id="duration" suffix="ms" />
</hbox>
<separator horizontal="true" />
<check id="repeat" text="@.repeat" />
<check id="dont_show" text="@general.dont_show" />

View File

@ -874,32 +874,36 @@ static void read_rle4_compressed_image(FILE *f, Image *image, const BITMAPINFOHE
}
}
static uint32_t calc_shift(const uint32_t channelMask, int& channelBits)
{
uint32_t channelShift = 0;
uint32_t mask = 0;
if (channelMask) {
mask = ~channelMask;
while (mask & 1) {
++channelShift;
mask >>= 1;
}
if (mask) {
mask = ~mask;
while (mask & 1) {
channelBits++;
mask >>= 1;
}
}
else
channelBits = 32 - channelShift;
}
else
channelBits = 8;
return channelShift;
}
static int read_bitfields_image(FILE *f, Image *image, BITMAPINFOHEADER *infoheader,
uint32_t rmask, uint32_t gmask, uint32_t bmask,
uint32_t amask, bool& withAlpha)
{
#define CALC_SHIFT(c) \
c##shift = 0; \
if (c##mask) { \
mask = ~c##mask; \
while (mask & 1) { \
++c##shift; \
mask >>= 1; \
} \
if (mask) { \
mask = ~mask; \
while (mask & 1) { \
c##bits++; \
mask >>= 1; \
} \
} \
else \
c##bits = 32 - c##shift; \
} \
else \
c##bits = 8; \
uint32_t buffer, mask, rshift, gshift, bshift, ashift;
uint32_t buffer, rshift, gshift, bshift, ashift;
int rbits = 0, gbits = 0, bbits = 0, abits = 0;
int i, j, k, line, height, dir, r, g, b, a;
int bits_per_pixel;
@ -911,10 +915,10 @@ static int read_bitfields_image(FILE *f, Image *image, BITMAPINFOHEADER *infohea
height = ABS(height);
/* calculate shifts */
CALC_SHIFT(r);
CALC_SHIFT(g);
CALC_SHIFT(b);
CALC_SHIFT(a);
rshift = calc_shift(rmask, rbits);
gshift = calc_shift(gmask, gbits);
bshift = calc_shift(bmask, bbits);
ashift = calc_shift(amask, abits);
/* calculate bits-per-pixel and bytes-per-pixel */
bits_per_pixel = infoheader->biBitCount;

View File

@ -388,6 +388,18 @@ FileOp* FileOp::createLoadDocumentOperation(Context* context,
window.files()->getSelectedChild() != nullptr);
});
window.duration()->setTextf("%d", fop->m_seq.duration);
window.duration()->Change.connect(
[&]() {
fop->m_seq.duration = window.duration()->textInt();
// If the animation duration is changed we'll prefer to
// agree on loading the sequence if the user press Enter.
//
// TODO maybe the "Agree" button should be the default
// focus magnet in this dialog
window.agree()->setFocusMagnet(true);
});
window.openWindowInForeground();
// Don't show this alert again.
@ -836,6 +848,8 @@ void FileOp::operate(IFileOpProgress* progress)
#endif
}
m_document->sprite()->setFrameDuration(frame, m_seq.duration);
++frame;
m_seq.progress_offset += m_seq.progress_fraction;
}
@ -1422,6 +1436,7 @@ FileOp::FileOp(FileOpType type,
m_seq.frame = frame_t(0);
m_seq.layer = nullptr;
m_seq.last_cel = nullptr;
m_seq.duration = 100;
m_seq.flags = 0;
}

View File

@ -314,6 +314,7 @@ namespace app {
bool has_alpha;
LayerImage* layer;
Cel* last_cel;
int duration;
// Flags after the user choose what to do with the sequence.
int flags;
} m_seq;

View File

@ -10,6 +10,6 @@
// Increment this value if the scripting API is modified between two
// released Aseprite versions.
#define API_VERSION 19
#define API_VERSION 20
#endif

View File

@ -1,5 +1,5 @@
// Aseprite
// Copyright (C) 2018-2021 Igara Studio S.A.
// Copyright (C) 2018-2022 Igara Studio S.A.
//
// This program is distributed under the terms of
// the End-User License Agreement for Aseprite.
@ -11,14 +11,18 @@
#include "app/app.h"
#include "app/context.h"
#include "app/doc_range.h"
#include "app/modules/editors.h"
#include "app/script/docobj.h"
#include "app/script/engine.h"
#include "app/script/luacpp.h"
#include "app/site.h"
#include "app/ui/editor/editor.h"
#include "app/util/range_utils.h"
#include "doc/cel.h"
#include "doc/layer.h"
#include "doc/object_ids.h"
#include "doc/slice.h"
#include "doc/slices.h"
#include "doc/sprite.h"
#include "doc/tile.h"
@ -33,9 +37,10 @@ namespace {
struct RangeObj { // This is like DocRange but referencing objects with IDs
DocRange::Type type;
ObjectId spriteId;
std::set<ObjectId> layers;
doc::SelectedObjects layers;
std::vector<frame_t> frames;
std::set<ObjectId> cels;
doc::SelectedObjects cels;
doc::SelectedObjects slices;
std::vector<color_t> colors;
std::vector<tile_index> tiles;
@ -88,18 +93,23 @@ struct RangeObj { // This is like DocRange but referencing objects with IDs
if (site.selectedTiles().picks() > 0)
tiles = site.selectedTiles().toVectorOfIndexes();
slices = site.selectedSlices();
}
Sprite* sprite(lua_State* L) { return check_docobj(L, doc::get<Sprite>(spriteId)); }
bool contains(const Layer* layer) const {
return layers.find(layer->id()) != layers.end();
return layers.contains(layer->id());
}
bool contains(const frame_t frame) const {
return std::find(frames.begin(), frames.end(), frame) != frames.end();
}
bool contains(const Cel* cel) const {
return cels.find(cel->id()) != cels.end();
return cels.contains(cel->id());
}
bool contains(const Slice* slice) const {
return slices.contains(slice->id());
}
bool containsColor(const color_t color) const {
return (std::find(colors.begin(), colors.end(), color) != colors.end());
@ -139,6 +149,9 @@ int Range_contains(lua_State* L)
else if (Cel* cel = may_get_docobj<Cel>(L, 2)) {
result = obj->contains(cel);
}
else if (Slice* slice = may_get_docobj<Slice>(L, 2)) {
result = obj->contains(slice);
}
else {
frame_t frame = get_frame_number_from_arg(L, 2);
result = obj->contains(frame);
@ -176,6 +189,13 @@ int Range_clear(lua_State* L)
doc::PalettePicks picks;
ctx->setSelectedColors(picks);
#ifdef ENABLE_UI
// Empty selected slices in the current editor
// TODO add a new function to Context class for this
if (current_editor)
current_editor->clearSlicesSelection();
#endif
obj->updateFromSite(ctx->activeSite());
return 0;
}
@ -275,6 +295,18 @@ int Range_get_tiles(lua_State* L)
return 1;
}
int Range_get_slices(lua_State* L)
{
auto obj = get_obj<RangeObj>(L, 1);
lua_newtable(L);
int j = 1;
for (auto sliceId : obj->slices) {
push_docobj<Slice>(L, sliceId);
lua_rawseti(L, -2, j++);
}
return 1;
}
int Range_set_layers(lua_State* L)
{
auto obj = get_obj<RangeObj>(L, 1);
@ -355,6 +387,29 @@ int Range_set_tiles(lua_State* L)
}
}
ctx->setSelectedTiles(picks);
obj->updateFromSite(ctx->activeSite());
return 0;
}
int Range_set_slices(lua_State* L)
{
auto obj = get_obj<RangeObj>(L, 1);
app::Context* ctx = App::instance()->context();
// TODO we should add support to CLI scripts
#ifdef ENABLE_UI
if (current_editor) {
current_editor->clearSlicesSelection();
const int len = luaL_len(L, 2);
for (int i = 1; i <= len; i++) {
if (lua_geti(L, 2, i) != LUA_TNIL)
current_editor->selectSlice(get_docobj<Slice>(L, -1));
lua_pop(L, 1);
}
}
#endif
obj->updateFromSite(ctx->activeSite());
return 0;
}
@ -378,6 +433,7 @@ const Property Range_properties[] = {
{ "editableImages", Range_get_editableImages, nullptr },
{ "colors", Range_get_colors, Range_set_colors },
{ "tiles", Range_get_tiles, Range_set_tiles },
{ "slices", Range_get_slices, Range_set_slices },
{ nullptr, nullptr, nullptr }
};