Merge branch 'main' into beta

This commit is contained in:
David Capello 2022-09-29 17:23:11 -03:00
commit ba3452b059
8 changed files with 108 additions and 43 deletions

2
laf

@ -1 +1 @@
Subproject commit b4ca9e2a0946c2ecb1efdf3ecb01888f350e3e26
Subproject commit 81622fcbb9e4a0edc14a02250c387bd6fa878708

View File

@ -201,8 +201,8 @@ Doc* generate_sprite_sheet_from_params(
int i = sprite->allLayersCount();
for (const Layer* layer : sprite->allLayers()) {
i--;
if (layer->name() == layerName && layerIndex == -1 ||
layer->name() == layerName && layerIndex == i) {
if (layer->name() == layerName && (layerIndex == -1 ||
layerIndex == i)) {
selLayers.insert(const_cast<Layer*>(layer));
break;
}

View File

@ -100,32 +100,36 @@ bool DocUndo::canRedo() const
void DocUndo::undo()
{
const undo::UndoState* state = nextUndo();
ASSERT(state);
const Cmd* cmd = STATE_CMD(state);
size_t oldSize = m_totalUndoSize;
m_totalUndoSize -= cmd->memSize();
const size_t oldSize = m_totalUndoSize;
{
const undo::UndoState* state = nextUndo();
ASSERT(state);
const Cmd* cmd = STATE_CMD(state);
m_totalUndoSize -= cmd->memSize();
m_undoHistory.undo();
notify_observers(&DocUndoObserver::onCurrentUndoStateChange, this);
m_totalUndoSize += cmd->memSize();
}
m_totalUndoSize += cmd->memSize();
// This notification could execute a script that modifies the sprite
// again (e.g. a script that is listening the "change" event, check
// the SpriteEvents class). If the sprite is modified, the "cmd" is
// not valid anymore.
notify_observers(&DocUndoObserver::onCurrentUndoStateChange, this);
if (m_totalUndoSize != oldSize)
notify_observers(&DocUndoObserver::onTotalUndoSizeChange, this);
}
void DocUndo::redo()
{
const undo::UndoState* state = nextRedo();
ASSERT(state);
const Cmd* cmd = STATE_CMD(state);
size_t oldSize = m_totalUndoSize;
m_totalUndoSize -= cmd->memSize();
const size_t oldSize = m_totalUndoSize;
{
const undo::UndoState* state = nextRedo();
ASSERT(state);
const Cmd* cmd = STATE_CMD(state);
m_totalUndoSize -= cmd->memSize();
m_undoHistory.redo();
notify_observers(&DocUndoObserver::onCurrentUndoStateChange, this);
m_totalUndoSize += cmd->memSize();
}
m_totalUndoSize += cmd->memSize();
notify_observers(&DocUndoObserver::onCurrentUndoStateChange, this);
if (m_totalUndoSize != oldSize)
notify_observers(&DocUndoObserver::onTotalUndoSizeChange, this);
}
@ -222,6 +226,10 @@ Cmd* DocUndo::lastExecutedCmd() const
void DocUndo::moveToState(const undo::UndoState* state)
{
m_undoHistory.moveTo(state);
// After onCurrentUndoStateChange don't use the "state" argument, it
// might be deleted because some script might have modified the
// sprite on its "change" event.
notify_observers(&DocUndoObserver::onCurrentUndoStateChange, this);
// Recalculate the total undo size

View File

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

View File

@ -18,11 +18,14 @@
#include "app/script/docobj.h"
#include "app/script/engine.h"
#include "app/script/luacpp.h"
#include "app/script/values.h"
#include "doc/document.h"
#include "doc/sprite.h"
#include "ui/app_state.h"
#include <any>
#include <cstring>
#include <initializer_list>
#include <map>
#include <memory>
@ -92,7 +95,8 @@ public:
}
protected:
void call(EventType eventType) {
void call(EventType eventType,
const std::initializer_list<std::pair<const std::string, std::any>>& args = {}) {
if (eventType >= m_listeners.size())
return;
@ -101,8 +105,20 @@ protected:
try {
for (EventListener callbackRef : m_listeners[eventType]) {
// Get user-defined callback function
lua_rawgeti(L, LUA_REGISTRYINDEX, callbackRef);
if (lua_pcall(L, 0, 0, 0)) {
int callbackArgs = 0;
if (args.size() > 0) {
++callbackArgs;
lua_newtable(L); // Create "ev" argument with fields about the event
for (const auto& kv : args) {
push_value_to_lua(L, kv.second);
lua_setfield(L, -2, kv.first.c_str());
}
}
if (lua_pcall(L, callbackArgs, 0, 0)) {
if (const char* s = lua_tostring(L, -1))
engine->consolePrint(s);
}
@ -233,11 +249,17 @@ public:
}
}
void onFileNameChanged(Doc* doc) override { call(FilenameChange); }
void onFileNameChanged(Doc* doc) override {
call(FilenameChange);
}
// DocUndoObserver impl
void onAddUndoState(DocUndo* history) override { call(Change); }
void onCurrentUndoStateChange(DocUndo* history) override { call(Change); }
void onAddUndoState(DocUndo* history) override {
call(Change);
}
void onCurrentUndoStateChange(DocUndo* history) override {
call(Change, { { "fromUndo", true } });
}
private:

View File

@ -14,6 +14,8 @@
#include "app/script/engine.h"
#include "app/script/luacpp.h"
#include <any>
namespace app {
namespace script {
@ -74,6 +76,25 @@ std::string get_value_from_lua(lua_State* L, int index) {
return std::string();
}
// ----------------------------------------------------------------------
// std::any
template<>
void push_value_to_lua(lua_State* L, const std::any& value) {
if (!value.has_value())
lua_pushnil(L);
else if (const bool* v = std::any_cast<bool>(&value))
push_value_to_lua(L, *v);
else if (const int* v = std::any_cast<int>(&value))
push_value_to_lua(L, *v);
else if (const std::string* v = std::any_cast<std::string>(&value))
push_value_to_lua(L, *v);
else {
ASSERT(false);
throw std::runtime_error("Cannot convert type inside std::any");
}
}
// ----------------------------------------------------------------------
// Color

View File

@ -117,20 +117,39 @@ public:
color_t b = m_primaryColor;
const float t = pt.gradient;
const float ti = 1.0f - pt.gradient;
auto rgbaGradient = [t, ti](color_t a, color_t b) -> color_t {
if (rgba_geta(a) == 0)
return doc::rgba(rgba_getr(b),
rgba_getg(b),
rgba_getb(b),
int(t*rgba_geta(b)));
else if (rgba_geta(b) == 0)
return doc::rgba(rgba_getr(a),
rgba_getg(a),
rgba_getb(a),
int(ti*rgba_geta(a)));
else
return doc::rgba(int(ti*rgba_getr(a) + t*rgba_getr(b)),
int(ti*rgba_getg(a) + t*rgba_getg(b)),
int(ti*rgba_getb(a) + t*rgba_getb(b)),
int(ti*rgba_geta(a) + t*rgba_geta(b)));
};
switch (loop->sprite()->pixelFormat()) {
case IMAGE_RGB:
if (rgba_geta(a) == 0) a = b;
else if (rgba_geta(b) == 0) b = a;
a = doc::rgba(int(ti*rgba_getr(a) + t*rgba_getr(b)),
int(ti*rgba_getg(a) + t*rgba_getg(b)),
int(ti*rgba_getb(a) + t*rgba_getb(b)),
int(ti*rgba_geta(a) + t*rgba_geta(b)));
a = rgbaGradient(a, b);
break;
case IMAGE_GRAYSCALE:
if (graya_geta(a) == 0) a = b;
else if (graya_geta(b) == 0) b = a;
a = doc::graya(int(ti*graya_getv(a) + t*graya_getv(b)),
int(ti*graya_geta(a) + t*graya_geta(b)));
if (graya_geta(a) == 0)
a = doc::graya(graya_getv(b),
int(t*graya_geta(b)));
else if (graya_geta(b) == 0)
a = doc::graya(graya_getv(a),
int(ti*graya_geta(a)));
else
a = doc::graya(int(ti*graya_getv(a) + t*graya_getv(b)),
int(ti*graya_geta(a) + t*graya_geta(b)));
break;
case IMAGE_INDEXED: {
int maskIndex = (loop->getLayer()->isBackground() ? -1: loop->sprite()->transparentColor());
@ -140,12 +159,7 @@ public:
if (b == maskIndex) b = 0;
else b = loop->getPalette()->getEntry(b);
// Same as in RGBA gradient
if (rgba_geta(a) == 0) a = b;
else if (rgba_geta(b) == 0) b = a;
a = doc::rgba(int(ti*rgba_getr(a) + t*rgba_getr(b)),
int(ti*rgba_getg(a) + t*rgba_getg(b)),
int(ti*rgba_getb(a) + t*rgba_getb(b)),
int(ti*rgba_geta(a) + t*rgba_geta(b)));
a = rgbaGradient(a, b);
// Convert RGBA to index
a = loop->getRgbMap()->mapColor(rgba_getr(a),
rgba_getg(a),

View File

@ -105,8 +105,8 @@ void fill_layers_combobox(const doc::Sprite* sprite, ui::ComboBox* layers, const
for (auto it=layersList.rbegin(), end=layersList.rend(); it!=end; ++it) {
doc::Layer* layer = *it;
i = layers->addItem(new LayerListItem(layer));
if (defLayer == layer->name() && defLayerIndex == -1 ||
defLayer == layer->name() && defLayerIndex == i-kLayersComboboxExtraInitialItems)
if (defLayer == layer->name() && (defLayerIndex == -1 ||
defLayerIndex == i-kLayersComboboxExtraInitialItems))
layers->setSelectedItemIndex(i);
}
}
@ -165,8 +165,8 @@ void calculate_visible_layers(const Site& site,
// TODO add a getLayerByName
for (doc::Layer* layer : site.sprite()->allLayers()) {
i--;
if (layer->name() == layersValue && layersIndex == -1 ||
layer->name() == layersValue && layersIndex == i) {
if (layer->name() == layersValue && (layersIndex == -1 ||
layersIndex == i)) {
layersVisibility.showLayer(layer);
break;
}