mirror of
https://github.com/aseprite/aseprite.git
synced 2025-02-20 18:40:57 +00:00
Merge branch 'main' into beta
This commit is contained in:
commit
ba3452b059
2
laf
2
laf
@ -1 +1 @@
|
||||
Subproject commit b4ca9e2a0946c2ecb1efdf3ecb01888f350e3e26
|
||||
Subproject commit 81622fcbb9e4a0edc14a02250c387bd6fa878708
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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:
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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),
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user