mirror of
https://github.com/aseprite/aseprite.git
synced 2025-01-30 15:32:38 +00:00
This fixes several problems in MovingPixelsState where hidden layers were transformed anyway when we switched the visibility of a layer in this state. Other fix was tried before in #3254 but we needed the onBefore/After layer visibility change notifications to make this work properly (i.e. drop pixels when the visiblity of a layer is changed). The only drawback at this moment is that changing the visibility of the non-active layer when we are transforming multiple cels/timeline range can be confused because we don't have #2144/#2865 implemented yet. This bug was originally reported here: https://community.aseprite.org/t/20621
This commit is contained in:
parent
a2b294b0fe
commit
e949a5401d
@ -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
|
||||||
@ -8,7 +9,6 @@
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "app/app.h"
|
|
||||||
#include "app/commands/command.h"
|
#include "app/commands/command.h"
|
||||||
#include "app/context_access.h"
|
#include "app/context_access.h"
|
||||||
#include "app/modules/gui.h"
|
#include "app/modules/gui.h"
|
||||||
@ -49,7 +49,7 @@ bool LayerVisibilityCommand::onChecked(Context* context)
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
SelectedLayers selLayers;
|
SelectedLayers selLayers;
|
||||||
auto range = App::instance()->timeline()->range();
|
DocRange range = context->activeSite().range();
|
||||||
if (range.enabled()) {
|
if (range.enabled()) {
|
||||||
selLayers = range.selectedLayers();
|
selLayers = range.selectedLayers();
|
||||||
}
|
}
|
||||||
@ -67,24 +67,25 @@ bool LayerVisibilityCommand::onChecked(Context* context)
|
|||||||
void LayerVisibilityCommand::onExecute(Context* context)
|
void LayerVisibilityCommand::onExecute(Context* context)
|
||||||
{
|
{
|
||||||
ContextWriter writer(context);
|
ContextWriter writer(context);
|
||||||
|
Doc* doc = writer.document();
|
||||||
SelectedLayers selLayers;
|
SelectedLayers selLayers;
|
||||||
auto range = App::instance()->timeline()->range();
|
DocRange range = context->activeSite().range();
|
||||||
if (range.enabled()) {
|
if (range.enabled()) {
|
||||||
selLayers = range.selectedLayers();
|
selLayers = range.selectedLayers();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
selLayers.insert(writer.layer());
|
selLayers.insert(writer.layer());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool anyVisible = false;
|
bool anyVisible = false;
|
||||||
for (auto layer : selLayers) {
|
for (auto layer : selLayers) {
|
||||||
if (layer->isVisible())
|
if (layer->isVisible())
|
||||||
anyVisible = true;
|
anyVisible = true;
|
||||||
}
|
}
|
||||||
for (auto layer : selLayers) {
|
|
||||||
layer->setVisible(!anyVisible);
|
|
||||||
}
|
|
||||||
|
|
||||||
update_screen_for_document(writer.document());
|
const bool newState = !anyVisible;
|
||||||
|
for (auto layer : selLayers)
|
||||||
|
doc->setLayerVisibilityWithNotifications(layer, newState);
|
||||||
}
|
}
|
||||||
|
|
||||||
Command* CommandFactory::createLayerVisibilityCommand()
|
Command* CommandFactory::createLayerVisibilityCommand()
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
// Copyright (C) 2018-2023 Igara Studio S.A.
|
// Copyright (C) 2018-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
|
||||||
@ -193,6 +193,16 @@ color_t Doc::bgColor(Layer* layer) const
|
|||||||
return layer->sprite()->transparentColor();
|
return layer->sprite()->transparentColor();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// Modifications with notifications
|
||||||
|
|
||||||
|
void Doc::setLayerVisibilityWithNotifications(Layer* layer, const bool visible)
|
||||||
|
{
|
||||||
|
notifyBeforeLayerVisibilityChange(layer, visible);
|
||||||
|
layer->setVisible(visible);
|
||||||
|
notifyAfterLayerVisibilityChange(layer);
|
||||||
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
// Notifications
|
// Notifications
|
||||||
|
|
||||||
@ -244,6 +254,20 @@ void Doc::notifyLayerMergedDown(Layer* srcLayer, Layer* targetLayer)
|
|||||||
notify_observers<DocEvent&>(&DocObserver::onLayerMergedDown, ev);
|
notify_observers<DocEvent&>(&DocObserver::onLayerMergedDown, ev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Doc::notifyBeforeLayerVisibilityChange(Layer* layer, bool newState)
|
||||||
|
{
|
||||||
|
DocEvent ev(this);
|
||||||
|
ev.layer(layer);
|
||||||
|
notify_observers<DocEvent&, bool>(&DocObserver::onBeforeLayerVisibilityChange, ev, newState);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Doc::notifyAfterLayerVisibilityChange(Layer* layer)
|
||||||
|
{
|
||||||
|
DocEvent ev(this);
|
||||||
|
ev.layer(layer);
|
||||||
|
notify_observers<DocEvent&>(&DocObserver::onAfterLayerVisibilityChange, ev);
|
||||||
|
}
|
||||||
|
|
||||||
void Doc::notifyCelMoved(Layer* fromLayer, frame_t fromFrame, Layer* toLayer, frame_t toFrame)
|
void Doc::notifyCelMoved(Layer* fromLayer, frame_t fromFrame, Layer* toLayer, frame_t toFrame)
|
||||||
{
|
{
|
||||||
DocEvent ev(this);
|
DocEvent ev(this);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
// Copyright (C) 2018-2023 Igara Studio S.A.
|
// Copyright (C) 2018-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
|
||||||
@ -107,6 +107,14 @@ namespace app {
|
|||||||
|
|
||||||
os::ColorSpaceRef osColorSpace() const { return m_osColorSpace; }
|
os::ColorSpaceRef osColorSpace() const { return m_osColorSpace; }
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// Modifications with notifications
|
||||||
|
|
||||||
|
// Use this function to change the layer visibility and notify all
|
||||||
|
// DocObservers about this change (e.g. so the Editor can be
|
||||||
|
// invalidated/redrawn, MovingPixelsState can drop pixels, etc.)
|
||||||
|
void setLayerVisibilityWithNotifications(Layer* layer, const bool visible);
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
// Notifications
|
// Notifications
|
||||||
|
|
||||||
@ -116,6 +124,8 @@ namespace app {
|
|||||||
void notifySpritePixelsModified(Sprite* sprite, const gfx::Region& region, frame_t frame);
|
void notifySpritePixelsModified(Sprite* sprite, const gfx::Region& region, frame_t frame);
|
||||||
void notifyExposeSpritePixels(Sprite* sprite, const gfx::Region& region);
|
void notifyExposeSpritePixels(Sprite* sprite, const gfx::Region& region);
|
||||||
void notifyLayerMergedDown(Layer* srcLayer, Layer* targetLayer);
|
void notifyLayerMergedDown(Layer* srcLayer, Layer* targetLayer);
|
||||||
|
void notifyBeforeLayerVisibilityChange(Layer* layer, bool newState);
|
||||||
|
void notifyAfterLayerVisibilityChange(Layer* layer);
|
||||||
void notifyCelMoved(Layer* fromLayer, frame_t fromFrame, Layer* toLayer, frame_t toFrame);
|
void notifyCelMoved(Layer* fromLayer, frame_t fromFrame, Layer* toLayer, frame_t toFrame);
|
||||||
void notifyCelCopied(Layer* fromLayer, frame_t fromFrame, Layer* toLayer, frame_t toFrame);
|
void notifyCelCopied(Layer* fromLayer, frame_t fromFrame, Layer* toLayer, frame_t toFrame);
|
||||||
void notifySelectionChanged();
|
void notifySelectionChanged();
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
// Copyright (C) 2018-2023 Igara Studio S.A.
|
// Copyright (C) 2018-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
|
||||||
@ -97,6 +97,10 @@ namespace app {
|
|||||||
// The collapsed/expanded flag of a specific layer changed.
|
// The collapsed/expanded flag of a specific layer changed.
|
||||||
virtual void onLayerCollapsedChanged(DocEvent& ev) { }
|
virtual void onLayerCollapsedChanged(DocEvent& ev) { }
|
||||||
|
|
||||||
|
// The visibility flag of a specific layer is going to change/changed.
|
||||||
|
virtual void onBeforeLayerVisibilityChange(DocEvent& ev, bool newState) { }
|
||||||
|
virtual void onAfterLayerVisibilityChange(DocEvent& ev) { }
|
||||||
|
|
||||||
// The tileset was remapped (e.g. when tiles are re-ordered).
|
// The tileset was remapped (e.g. when tiles are re-ordered).
|
||||||
virtual void onRemapTileset(DocEvent& ev, const doc::Remap& remap) { }
|
virtual void onRemapTileset(DocEvent& ev, const doc::Remap& remap) { }
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
// Copyright (C) 2018-2023 Igara Studio S.A.
|
// Copyright (C) 2018-2024 Igara Studio S.A.
|
||||||
// Copyright (C) 2018 David Capello
|
// Copyright (C) 2018 David Capello
|
||||||
//
|
//
|
||||||
// This program is distributed under the terms of
|
// This program is distributed under the terms of
|
||||||
@ -329,7 +329,9 @@ int Layer_set_isEditable(lua_State* L)
|
|||||||
int Layer_set_isVisible(lua_State* L)
|
int Layer_set_isVisible(lua_State* L)
|
||||||
{
|
{
|
||||||
auto layer = get_docobj<Layer>(L, 1);
|
auto layer = get_docobj<Layer>(L, 1);
|
||||||
layer->setVisible(lua_toboolean(L, 2));
|
const bool newState = lua_toboolean(L, 2);
|
||||||
|
Doc* doc = static_cast<Doc*>(layer->sprite()->document());
|
||||||
|
doc->setLayerVisibilityWithNotifications(layer, newState);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
// Copyright (C) 2018-2023 Igara Studio S.A.
|
// Copyright (C) 2018-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
|
||||||
@ -478,6 +478,15 @@ void DocView::onTotalFramesChanged(DocEvent& ev)
|
|||||||
|
|
||||||
void DocView::onLayerRestacked(DocEvent& ev)
|
void DocView::onLayerRestacked(DocEvent& ev)
|
||||||
{
|
{
|
||||||
|
if (hasContentInActiveFrame(ev.layer()))
|
||||||
|
m_editor->invalidate();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DocView::onAfterLayerVisibilityChange(DocEvent& ev)
|
||||||
|
{
|
||||||
|
// If there is no cel for this layer in the current frame, there is
|
||||||
|
// no need to redraw the editor
|
||||||
|
if (hasContentInActiveFrame(ev.layer()))
|
||||||
m_editor->invalidate();
|
m_editor->invalidate();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -653,4 +662,19 @@ void DocView::onCancel(Context* ctx)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool DocView::hasContentInActiveFrame(const doc::Layer* layer) const
|
||||||
|
{
|
||||||
|
if (!layer)
|
||||||
|
return false;
|
||||||
|
else if (layer->cel(m_editor->frame()))
|
||||||
|
return true;
|
||||||
|
else if (layer->isGroup()) {
|
||||||
|
for (const doc::Layer* child : static_cast<const doc::LayerGroup*>(layer)->layers()) {
|
||||||
|
if (hasContentInActiveFrame(child))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace app
|
} // namespace app
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
// Copyright (C) 2019-2023 Igara Studio S.A.
|
// Copyright (C) 2019-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
|
||||||
@ -15,6 +15,10 @@
|
|||||||
#include "app/ui/workspace_view.h"
|
#include "app/ui/workspace_view.h"
|
||||||
#include "ui/box.h"
|
#include "ui/box.h"
|
||||||
|
|
||||||
|
namespace doc {
|
||||||
|
class Layer;
|
||||||
|
}
|
||||||
|
|
||||||
namespace ui {
|
namespace ui {
|
||||||
class View;
|
class View;
|
||||||
}
|
}
|
||||||
@ -86,6 +90,7 @@ namespace app {
|
|||||||
void onAfterRemoveCel(DocEvent& ev) override;
|
void onAfterRemoveCel(DocEvent& ev) override;
|
||||||
void onTotalFramesChanged(DocEvent& ev) override;
|
void onTotalFramesChanged(DocEvent& ev) override;
|
||||||
void onLayerRestacked(DocEvent& ev) override;
|
void onLayerRestacked(DocEvent& ev) override;
|
||||||
|
void onAfterLayerVisibilityChange(DocEvent& ev) override;
|
||||||
void onTilesetChanged(DocEvent& ev) override;
|
void onTilesetChanged(DocEvent& ev) override;
|
||||||
|
|
||||||
// InputChainElement impl
|
// InputChainElement impl
|
||||||
@ -105,6 +110,8 @@ namespace app {
|
|||||||
bool onProcessMessage(ui::Message* msg) override;
|
bool onProcessMessage(ui::Message* msg) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
bool hasContentInActiveFrame(const doc::Layer* layer) const;
|
||||||
|
|
||||||
Type m_type;
|
Type m_type;
|
||||||
Doc* m_document;
|
Doc* m_document;
|
||||||
ui::View* m_view;
|
ui::View* m_view;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
// Copyright (C) 2018-2023 Igara Studio S.A.
|
// Copyright (C) 2018-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
|
||||||
@ -2438,6 +2438,12 @@ void Editor::onRemoveSlice(DocEvent& ev)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Editor::onBeforeLayerVisibilityChange(DocEvent& ev, bool newState)
|
||||||
|
{
|
||||||
|
if (m_state)
|
||||||
|
m_state->onBeforeLayerVisibilityChange(this, ev.layer(), newState);
|
||||||
|
}
|
||||||
|
|
||||||
void Editor::setCursor(const gfx::Point& mouseDisplayPos)
|
void Editor::setCursor(const gfx::Point& mouseDisplayPos)
|
||||||
{
|
{
|
||||||
Rect vp = View::getView(this)->viewportBounds();
|
Rect vp = View::getView(this)->viewportBounds();
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
// Copyright (C) 2018-2023 Igara Studio S.A.
|
// Copyright (C) 2018-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
|
||||||
@ -351,6 +351,7 @@ namespace app {
|
|||||||
void onAddTag(DocEvent& ev) override;
|
void onAddTag(DocEvent& ev) override;
|
||||||
void onRemoveTag(DocEvent& ev) override;
|
void onRemoveTag(DocEvent& ev) override;
|
||||||
void onRemoveSlice(DocEvent& ev) override;
|
void onRemoveSlice(DocEvent& ev) override;
|
||||||
|
void onBeforeLayerVisibilityChange(DocEvent& ev, bool newState) override;
|
||||||
|
|
||||||
// ActiveToolObserver impl
|
// ActiveToolObserver impl
|
||||||
void onActiveToolChange(tools::Tool* tool) override;
|
void onActiveToolChange(tools::Tool* tool) override;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
// Copyright (C) 2019-2023 Igara Studio S.A.
|
// Copyright (C) 2019-2024 Igara Studio S.A.
|
||||||
// Copyright (C) 2001-2016 David Capello
|
// Copyright (C) 2001-2016 David Capello
|
||||||
//
|
//
|
||||||
// This program is distributed under the terms of
|
// This program is distributed under the terms of
|
||||||
@ -26,6 +26,7 @@ namespace ui {
|
|||||||
}
|
}
|
||||||
|
|
||||||
namespace doc {
|
namespace doc {
|
||||||
|
class Layer;
|
||||||
class Tag;
|
class Tag;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -145,6 +146,11 @@ namespace app {
|
|||||||
// collection.
|
// collection.
|
||||||
virtual void onBeforeRemoveLayer(Editor* editor) { }
|
virtual void onBeforeRemoveLayer(Editor* editor) { }
|
||||||
|
|
||||||
|
// Called when the visibility of a specific layer is changed.
|
||||||
|
virtual void onBeforeLayerVisibilityChange(Editor* editor,
|
||||||
|
doc::Layer* layer,
|
||||||
|
bool newState) { }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DISABLE_COPYING(EditorState);
|
DISABLE_COPYING(EditorState);
|
||||||
};
|
};
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
// Copyright (C) 2019-2023 Igara Studio S.A.
|
// Copyright (C) 2019-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
|
||||||
@ -578,6 +578,25 @@ bool MovingPixelsState::acceptQuickTool(tools::Tool* tool)
|
|||||||
tool->getInk(0)->isZoom());
|
tool->getInk(0)->isZoom());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MovingPixelsState::onBeforeLayerVisibilityChange(Editor* editor,
|
||||||
|
doc::Layer* layer,
|
||||||
|
bool newState)
|
||||||
|
{
|
||||||
|
if (!isActiveDocument())
|
||||||
|
return;
|
||||||
|
|
||||||
|
// If the layer visibility of any selected layer changes, we just
|
||||||
|
// drop the pixels (it's the easiest way to avoid modifying hidden
|
||||||
|
// pixels).
|
||||||
|
if (m_pixelsMovement) {
|
||||||
|
const Site& site = m_pixelsMovement->site();
|
||||||
|
if (site.layer() == layer ||
|
||||||
|
site.range().contains(layer)) {
|
||||||
|
dropPixels();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Before executing any command, we drop the pixels (go back to standby).
|
// Before executing any command, we drop the pixels (go back to standby).
|
||||||
void MovingPixelsState::onBeforeCommandExecution(CommandExecutionEvent& ev)
|
void MovingPixelsState::onBeforeCommandExecution(CommandExecutionEvent& ev)
|
||||||
{
|
{
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
// Copyright (C) 2019-2022 Igara Studio S.A.
|
// Copyright (C) 2019-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
|
||||||
@ -21,7 +21,7 @@
|
|||||||
#include "ui/timer.h"
|
#include "ui/timer.h"
|
||||||
|
|
||||||
namespace doc {
|
namespace doc {
|
||||||
class Image;
|
class Layer;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace app {
|
namespace app {
|
||||||
@ -54,35 +54,37 @@ namespace app {
|
|||||||
void updateTransformation(const Transformation& t);
|
void updateTransformation(const Transformation& t);
|
||||||
|
|
||||||
// EditorState
|
// EditorState
|
||||||
virtual void onEnterState(Editor* editor) override;
|
void onEnterState(Editor* editor) override;
|
||||||
virtual void onEditorGotFocus(Editor* editor) override;
|
void onEditorGotFocus(Editor* editor) override;
|
||||||
virtual LeaveAction onLeaveState(Editor* editor, EditorState* newState) override;
|
LeaveAction onLeaveState(Editor* editor, EditorState* newState) override;
|
||||||
virtual void onActiveToolChange(Editor* editor, tools::Tool* tool) override;
|
void onActiveToolChange(Editor* editor, tools::Tool* tool) override;
|
||||||
virtual bool onMouseDown(Editor* editor, ui::MouseMessage* msg) override;
|
bool onMouseDown(Editor* editor, ui::MouseMessage* msg) override;
|
||||||
virtual bool onMouseUp(Editor* editor, ui::MouseMessage* msg) override;
|
bool onMouseUp(Editor* editor, ui::MouseMessage* msg) override;
|
||||||
virtual bool onMouseMove(Editor* editor, ui::MouseMessage* msg) override;
|
bool onMouseMove(Editor* editor, ui::MouseMessage* msg) override;
|
||||||
virtual bool onSetCursor(Editor* editor, const gfx::Point& mouseScreenPos) override;
|
bool onSetCursor(Editor* editor, const gfx::Point& mouseScreenPos) override;
|
||||||
virtual bool onKeyDown(Editor* editor, ui::KeyMessage* msg) override;
|
bool onKeyDown(Editor* editor, ui::KeyMessage* msg) override;
|
||||||
virtual bool onKeyUp(Editor* editor, ui::KeyMessage* msg) override;
|
bool onKeyUp(Editor* editor, ui::KeyMessage* msg) override;
|
||||||
virtual bool onUpdateStatusBar(Editor* editor) override;
|
bool onUpdateStatusBar(Editor* editor) override;
|
||||||
virtual bool acceptQuickTool(tools::Tool* tool) override;
|
bool acceptQuickTool(tools::Tool* tool) override;
|
||||||
virtual bool requireBrushPreview() override { return false; }
|
bool requireBrushPreview() override { return false; }
|
||||||
|
void onBeforeLayerVisibilityChange(Editor* editor, doc::Layer* layer, bool newState) override;
|
||||||
|
|
||||||
|
|
||||||
// EditorObserver
|
// EditorObserver
|
||||||
virtual void onDestroyEditor(Editor* editor) override;
|
void onDestroyEditor(Editor* editor) override;
|
||||||
virtual void onBeforeFrameChanged(Editor* editor) override;
|
void onBeforeFrameChanged(Editor* editor) override;
|
||||||
virtual void onBeforeLayerChanged(Editor* editor) override;
|
void onBeforeLayerChanged(Editor* editor) override;
|
||||||
|
|
||||||
// TimelineObserver
|
// TimelineObserver
|
||||||
virtual void onBeforeRangeChanged(Timeline* timeline) override;
|
void onBeforeRangeChanged(Timeline* timeline) override;
|
||||||
|
|
||||||
// ContextBarObserver
|
// ContextBarObserver
|
||||||
virtual void onDropPixels(ContextBarObserver::DropAction action) override;
|
void onDropPixels(ContextBarObserver::DropAction action) override;
|
||||||
|
|
||||||
// PixelsMovementDelegate
|
// PixelsMovementDelegate
|
||||||
virtual void onPivotChange() override;
|
void onPivotChange() override;
|
||||||
|
|
||||||
virtual Transformation getTransformation(Editor* editor) override;
|
Transformation getTransformation(Editor* editor) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// DelayedMouseMoveDelegate impl
|
// DelayedMouseMoveDelegate impl
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
// Copyright (C) 2019-2023 Igara Studio S.A.
|
// Copyright (C) 2019-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
|
||||||
@ -787,9 +787,10 @@ void PixelsMovement::stampImage(bool finalStamp)
|
|||||||
cels.push_back(currentCel);
|
cels.push_back(currentCel);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (currentCel && currentCel->layer() &&
|
if (currentCel &&
|
||||||
|
currentCel->layer() &&
|
||||||
currentCel->layer()->isImage() &&
|
currentCel->layer()->isImage() &&
|
||||||
!currentCel->layer()->isEditableHierarchy()) {
|
!currentCel->layer()->canEditPixels()) {
|
||||||
Transformation initialCelPos(gfx::Rect(m_initialMask0->bounds()), m_currentData.cornerThick());
|
Transformation initialCelPos(gfx::Rect(m_initialMask0->bounds()), m_currentData.cornerThick());
|
||||||
redrawExtraImage(&initialCelPos);
|
redrawExtraImage(&initialCelPos);
|
||||||
stampExtraCelImage();
|
stampExtraCelImage();
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
// Copyright (C) 2019-2021 Igara Studio S.A.
|
// Copyright (C) 2019-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
|
||||||
@ -75,6 +75,8 @@ namespace app {
|
|||||||
const Mask* mask,
|
const Mask* mask,
|
||||||
const char* operationName);
|
const char* operationName);
|
||||||
|
|
||||||
|
const Site& site() { return m_site; }
|
||||||
|
|
||||||
HandleType handle() const { return m_handle; }
|
HandleType handle() const { return m_handle; }
|
||||||
bool canHandleFrameChange() const { return m_canHandleFrameChange; }
|
bool canHandleFrameChange() const { return m_canHandleFrameChange; }
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
// Copyright (C) 2018-2023 Igara Studio S.A.
|
// Copyright (C) 2018-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
|
||||||
@ -696,7 +696,9 @@ bool Timeline::onProcessMessage(Message* msg)
|
|||||||
bool newVisibleState = !allLayersVisible();
|
bool newVisibleState = !allLayersVisible();
|
||||||
for (Layer* topLayer : m_sprite->root()->layers()) {
|
for (Layer* topLayer : m_sprite->root()->layers()) {
|
||||||
if (topLayer->isVisible() != newVisibleState) {
|
if (topLayer->isVisible() != newVisibleState) {
|
||||||
topLayer->setVisible(newVisibleState);
|
m_document->setLayerVisibilityWithNotifications(
|
||||||
|
topLayer, newVisibleState);
|
||||||
|
|
||||||
if (topLayer->isGroup())
|
if (topLayer->isGroup())
|
||||||
regenRows = true;
|
regenRows = true;
|
||||||
}
|
}
|
||||||
@ -825,11 +827,11 @@ bool Timeline::onProcessMessage(Message* msg)
|
|||||||
for (Row& row : m_rows) {
|
for (Row& row : m_rows) {
|
||||||
Layer* l = row.layer();
|
Layer* l = row.layer();
|
||||||
if (l->hasFlags(LayerFlags::Internal_WasVisible)) {
|
if (l->hasFlags(LayerFlags::Internal_WasVisible)) {
|
||||||
l->setVisible(true);
|
m_document->setLayerVisibilityWithNotifications(l, true);
|
||||||
l->switchFlags(LayerFlags::Internal_WasVisible, false);
|
l->switchFlags(LayerFlags::Internal_WasVisible, false);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
l->setVisible(false);
|
m_document->setLayerVisibilityWithNotifications(l, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -838,7 +840,7 @@ bool Timeline::onProcessMessage(Message* msg)
|
|||||||
for (Row& row : m_rows) {
|
for (Row& row : m_rows) {
|
||||||
Layer* l = row.layer();
|
Layer* l = row.layer();
|
||||||
l->switchFlags(LayerFlags::Internal_WasVisible, l->isVisible());
|
l->switchFlags(LayerFlags::Internal_WasVisible, l->isVisible());
|
||||||
l->setVisible(false);
|
m_document->setLayerVisibilityWithNotifications(l, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2016,6 +2018,14 @@ void Timeline::onLayerCollapsedChanged(DocEvent& ev)
|
|||||||
invalidate();
|
invalidate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Timeline::onAfterLayerVisibilityChange(DocEvent& ev)
|
||||||
|
{
|
||||||
|
layer_t layerIdx = getLayerIndex(ev.layer());
|
||||||
|
if (layerIdx >= 0)
|
||||||
|
invalidateRect(getPartBounds(Hit(PART_ROW_EYE_ICON, layerIdx))
|
||||||
|
.offset(origin()));
|
||||||
|
}
|
||||||
|
|
||||||
void Timeline::onStateChanged(Editor* editor)
|
void Timeline::onStateChanged(Editor* editor)
|
||||||
{
|
{
|
||||||
m_aniControls.updateUsingEditor(editor);
|
m_aniControls.updateUsingEditor(editor);
|
||||||
@ -4475,12 +4485,10 @@ void Timeline::setLayerVisibleFlag(const layer_t l, const bool state)
|
|||||||
if (!layer)
|
if (!layer)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
bool redrawEditors = false;
|
|
||||||
bool regenRows = false;
|
bool regenRows = false;
|
||||||
|
|
||||||
if (layer->isVisible() != state) {
|
if (layer->isVisible() != state) {
|
||||||
layer->setVisible(state);
|
m_document->setLayerVisibilityWithNotifications(layer, state);
|
||||||
redrawEditors = true;
|
|
||||||
|
|
||||||
// Regenerate rows because might change the flag of the children
|
// Regenerate rows because might change the flag of the children
|
||||||
// (the flag is propagated to the children in m_inheritedFlags).
|
// (the flag is propagated to the children in m_inheritedFlags).
|
||||||
@ -4493,9 +4501,8 @@ void Timeline::setLayerVisibleFlag(const layer_t l, const bool state)
|
|||||||
layer = layer->parent();
|
layer = layer->parent();
|
||||||
while (layer) {
|
while (layer) {
|
||||||
if (!layer->isVisible()) {
|
if (!layer->isVisible()) {
|
||||||
layer->setVisible(true);
|
m_document->setLayerVisibilityWithNotifications(layer, true);
|
||||||
regenRows = true;
|
regenRows = true;
|
||||||
redrawEditors = true;
|
|
||||||
}
|
}
|
||||||
layer = layer->parent();
|
layer = layer->parent();
|
||||||
}
|
}
|
||||||
@ -4506,9 +4513,6 @@ void Timeline::setLayerVisibleFlag(const layer_t l, const bool state)
|
|||||||
regenerateRows();
|
regenerateRows();
|
||||||
invalidate();
|
invalidate();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (redrawEditors)
|
|
||||||
m_document->notifyGeneralUpdate();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Timeline::setLayerEditableFlag(const layer_t l, const bool state)
|
void Timeline::setLayerEditableFlag(const layer_t l, const bool state)
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
// Copyright (C) 2018-2023 Igara Studio S.A.
|
// Copyright (C) 2018-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
|
||||||
@ -163,6 +163,7 @@ namespace app {
|
|||||||
void onTagChange(DocEvent& ev) override;
|
void onTagChange(DocEvent& ev) override;
|
||||||
void onTagRename(DocEvent& ev) override;
|
void onTagRename(DocEvent& ev) override;
|
||||||
void onLayerCollapsedChanged(DocEvent& ev) override;
|
void onLayerCollapsedChanged(DocEvent& ev) override;
|
||||||
|
void onAfterLayerVisibilityChange(DocEvent& ev) override;
|
||||||
|
|
||||||
// app::Context slots.
|
// app::Context slots.
|
||||||
void onBeforeCommandExecution(CommandExecutionEvent& ev);
|
void onBeforeCommandExecution(CommandExecutionEvent& ev);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
// Copyright (C) 2020 Igara Studio S.A.
|
// Copyright (C) 2020-2024 Igara Studio S.A.
|
||||||
//
|
//
|
||||||
// This program is distributed under the terms of
|
// This program is distributed under the terms of
|
||||||
// the End-User License Agreement for Aseprite.
|
// the End-User License Agreement for Aseprite.
|
||||||
@ -45,14 +45,34 @@ Layer* candidate_if_layer_is_deleted(
|
|||||||
bool layer_is_locked(Editor* editor)
|
bool layer_is_locked(Editor* editor)
|
||||||
{
|
{
|
||||||
Layer* layer = editor->layer();
|
Layer* layer = editor->layer();
|
||||||
if (layer && !layer->isEditableHierarchy()) {
|
if (!layer)
|
||||||
|
return false;
|
||||||
|
|
||||||
#ifdef ENABLE_UI
|
#ifdef ENABLE_UI
|
||||||
if (auto statusBar = StatusBar::instance())
|
auto statusBar = StatusBar::instance();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (!layer->isVisibleHierarchy()) {
|
||||||
|
#ifdef ENABLE_UI
|
||||||
|
if (statusBar) {
|
||||||
statusBar->showTip(
|
statusBar->showTip(
|
||||||
1000, fmt::format(Strings::statusbar_tips_layer_locked(), layer->name()));
|
1000, fmt::format(Strings::statusbar_tips_layer_x_is_hidden(),
|
||||||
|
layer->name()));
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!layer->isEditableHierarchy()) {
|
||||||
|
#ifdef ENABLE_UI
|
||||||
|
if (statusBar) {
|
||||||
|
statusBar->showTip(
|
||||||
|
1000, fmt::format(Strings::statusbar_tips_layer_locked(), layer->name()));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user