mirror of
https://github.com/aseprite/aseprite.git
synced 2025-02-18 21:40:46 +00:00
Merge branch 'main' into beta
This commit is contained in:
commit
ae904428fa
@ -96,8 +96,8 @@ void FlipCommand::onExecute(Context* ctx)
|
||||
cels = get_unlocked_unique_cels(site.sprite(), range);
|
||||
}
|
||||
else if (site.cel() &&
|
||||
site.layer() &&
|
||||
site.layer()->isEditable()) {
|
||||
site.layer() &&
|
||||
site.layer()->canEditPixels()) {
|
||||
cels.push_back(site.cel());
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
@ -217,7 +217,7 @@ void RotateCommand::onExecute(Context* context)
|
||||
cels = get_unlocked_unique_cels(site.sprite(), range);
|
||||
else if (site.cel() &&
|
||||
site.layer() &&
|
||||
site.layer()->isEditable()) {
|
||||
site.layer()->canEditPixels()) {
|
||||
cels.push_back(site.cel());
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
@ -281,8 +281,7 @@ void FilterManagerImpl::applyToTarget()
|
||||
}
|
||||
else if (m_site.cel() &&
|
||||
m_site.layer() &&
|
||||
m_site.layer()->isEditable() &&
|
||||
!m_site.layer()->isReference()) {
|
||||
m_site.layer()->canEditPixels()) {
|
||||
cels.push_back(m_site.cel());
|
||||
}
|
||||
break;
|
||||
@ -290,8 +289,7 @@ void FilterManagerImpl::applyToTarget()
|
||||
|
||||
case CelsTarget::All: {
|
||||
for (Cel* cel : m_site.sprite()->uniqueCels()) {
|
||||
if (cel->layer()->isEditable() &&
|
||||
!cel->layer()->isReference())
|
||||
if (cel->layer()->canEditPixels())
|
||||
cels.push_back(cel);
|
||||
}
|
||||
break;
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2018-2019 Igara Studio S.A.
|
||||
// Copyright (C) 2018-2021 Igara Studio S.A.
|
||||
// Copyright (C) 2001-2016 David Capello
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
@ -81,7 +81,7 @@ ConfigModule::ConfigModule()
|
||||
#elif !defined(_WIN32)
|
||||
|
||||
// On Linux we migrate the old configuration file name
|
||||
// (.asepriterc -> ~/.config/aseprite/aseprite.ini)
|
||||
// (~/.asepriterc -> ~/.config/aseprite/aseprite.ini)
|
||||
{
|
||||
ResourceFinder old_rf;
|
||||
old_rf.includeHomeDir(".asepriterc");
|
||||
|
@ -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
|
||||
@ -191,6 +191,10 @@ DocumentPreferences& Preferences::document(const Doc* doc)
|
||||
|
||||
void Preferences::resetToolPreferences(tools::Tool* tool)
|
||||
{
|
||||
if (tool->prefAlreadyResetFromScript())
|
||||
return;
|
||||
tool->markPrefAlreadyResetFromScript();
|
||||
|
||||
auto it = m_tools.find(tool->getId());
|
||||
if (it != m_tools.end())
|
||||
m_tools.erase(it);
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2019-2020 Igara Studio S.A.
|
||||
// Copyright (C) 2019-2021 Igara Studio S.A.
|
||||
// Copyright (C) 2001-2016 David Capello
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
@ -105,8 +105,8 @@ void ResourceFinder::includeDataDir(const char* filename)
|
||||
#else
|
||||
|
||||
// $HOME/.config/aseprite/filename
|
||||
sprintf(buf, ".config/aseprite/data/%s", filename);
|
||||
includeHomeDir(buf);
|
||||
sprintf(buf, "aseprite/data/%s", filename);
|
||||
includeHomeConfigDir(buf);
|
||||
|
||||
// $BINDIR/data/filename
|
||||
sprintf(buf, "data/%s", filename);
|
||||
@ -150,6 +150,24 @@ void ResourceFinder::includeHomeDir(const char* filename)
|
||||
#endif
|
||||
}
|
||||
|
||||
#if !defined(_WIN32) && !defined(__APPLE__)
|
||||
|
||||
// For Linux: It's $XDG_CONFIG_HOME or $HOME/.config
|
||||
void ResourceFinder::includeHomeConfigDir(const char* filename)
|
||||
{
|
||||
char* configHome = std::getenv("XDG_CONFIG_HOME");
|
||||
if (configHome && *configHome) {
|
||||
// $XDG_CONFIG_HOME/filename
|
||||
addPath(base::join_path(configHome, filename));
|
||||
}
|
||||
else {
|
||||
// $HOME/.config/filename
|
||||
includeHomeDir(base::join_path(std::string(".config"), filename).c_str());
|
||||
}
|
||||
}
|
||||
|
||||
#endif // !defined(_WIN32) && !defined(__APPLE__)
|
||||
|
||||
void ResourceFinder::includeUserDir(const char* filename)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
@ -185,7 +203,7 @@ void ResourceFinder::includeUserDir(const char* filename)
|
||||
#else // !__APPLE__
|
||||
|
||||
// $HOME/.config/aseprite/filename
|
||||
includeHomeDir((std::string(".config/aseprite/") + filename).c_str());
|
||||
includeHomeConfigDir((std::string("aseprite/") + filename).c_str());
|
||||
|
||||
#endif
|
||||
}
|
||||
|
@ -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
|
||||
@ -42,6 +42,11 @@ namespace app {
|
||||
void includeDataDir(const char* filename);
|
||||
void includeHomeDir(const char* filename);
|
||||
|
||||
#if !defined(_WIN32) && !defined(__APPLE__)
|
||||
// For Linux: It's $XDG_CONFIG_HOME or $HOME/.config
|
||||
void includeHomeConfigDir(const char* filename);
|
||||
#endif
|
||||
|
||||
// Tries to add the given filename in these locations:
|
||||
// For Windows:
|
||||
// - If ASEPRITE_USER_FOLDER environment variable is defined, it
|
||||
|
@ -1,4 +1,5 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2021 Igara Studio S.A.
|
||||
// Copyright (C) 2001-2018 David Capello
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
@ -61,6 +62,9 @@ namespace app {
|
||||
void setIntertwine(int button, Intertwine* intertwine) { m_button[button].m_intertwine = intertwine; }
|
||||
void setTracePolicy(int button, TracePolicy trace_policy) { m_button[button].m_trace_policy = trace_policy; }
|
||||
|
||||
bool prefAlreadyResetFromScript() const { return m_prefAlreadyResetFromScript; }
|
||||
void markPrefAlreadyResetFromScript() { m_prefAlreadyResetFromScript = true; }
|
||||
|
||||
private:
|
||||
ToolGroup* m_group;
|
||||
std::string m_id;
|
||||
@ -68,6 +72,13 @@ namespace app {
|
||||
std::string m_tips;
|
||||
int m_default_brush_size;
|
||||
|
||||
// Flag used to indicate that the preferences of this tool were
|
||||
// already reset from scripts when they are executed in CLI mode
|
||||
// (without GUI). This is needed to reset the preferences only
|
||||
// once, but if the script then modifies the preferences, they
|
||||
// are not reset again.
|
||||
bool m_prefAlreadyResetFromScript = false;
|
||||
|
||||
struct {
|
||||
Fill m_fill;
|
||||
Ink* m_ink;
|
||||
|
@ -409,6 +409,7 @@ void Editor::getSite(Site* site) const
|
||||
// TODO we should not access timeline directly here
|
||||
Timeline* timeline = App::instance()->timeline();
|
||||
if (timeline &&
|
||||
timeline->isVisible() &&
|
||||
timeline->range().enabled()) {
|
||||
site->range(timeline->range());
|
||||
}
|
||||
|
@ -47,8 +47,10 @@ MovingCelCollect::MovingCelCollect(Editor* editor, Layer* layer)
|
||||
if (layer && layer->isImage())
|
||||
m_mainCel = layer->cel(editor->frame());
|
||||
|
||||
DocRange range = App::instance()->timeline()->range();
|
||||
if (!range.enabled()) {
|
||||
Timeline* timeline = App::instance()->timeline();
|
||||
DocRange range = timeline->range();
|
||||
if (!range.enabled() ||
|
||||
!timeline->isVisible()) {
|
||||
range.startRange(editor->layer(), editor->frame(), DocRange::kCels);
|
||||
range.endRange(editor->layer(), editor->frame());
|
||||
}
|
||||
@ -86,8 +88,6 @@ MovingCelState::MovingCelState(Editor* editor,
|
||||
, m_celList(collect.celList())
|
||||
, m_celOffset(0.0, 0.0)
|
||||
, m_celScale(1.0, 1.0)
|
||||
, m_hasReference(false)
|
||||
, m_scaled(false)
|
||||
, m_handle(handle)
|
||||
, m_editor(editor)
|
||||
{
|
||||
@ -188,6 +188,13 @@ bool MovingCelState::onMouseUp(Editor* editor, MouseMessage* msg)
|
||||
// like to update all the editors.
|
||||
document->notifyGeneralUpdate();
|
||||
}
|
||||
// Just a click in the current layer
|
||||
else if (!m_moved & !m_scaled) {
|
||||
// Deselect the whole range if we are in "Auto Select Layer"
|
||||
if (editor->isAutoSelectLayer()) {
|
||||
App::instance()->timeline()->clearAndInvalidateRange();
|
||||
}
|
||||
}
|
||||
|
||||
// Restore the mask visibility.
|
||||
if (m_maskVisible) {
|
||||
@ -218,6 +225,8 @@ bool MovingCelState::onMouseMove(Editor* editor, MouseMessage* msg)
|
||||
m_celOffset.y = 0;
|
||||
}
|
||||
}
|
||||
if (!m_moved && intCelOffset() != gfx::Point(0, 0))
|
||||
m_moved = true;
|
||||
break;
|
||||
|
||||
case ScaleSEHandle: {
|
||||
@ -246,6 +255,7 @@ bool MovingCelState::onMouseMove(Editor* editor, MouseMessage* msg)
|
||||
if (cel->layer()->isReference()) {
|
||||
celBounds.x += m_celOffset.x;
|
||||
celBounds.y += m_celOffset.y;
|
||||
m_moved = true;
|
||||
if (m_scaled) {
|
||||
celBounds.w *= m_celScale.w;
|
||||
celBounds.h *= m_celScale.h;
|
||||
|
@ -68,8 +68,9 @@ namespace app {
|
||||
gfx::SizeF m_celMainSize;
|
||||
gfx::SizeF m_celScale;
|
||||
bool m_maskVisible;
|
||||
bool m_hasReference;
|
||||
bool m_scaled;
|
||||
bool m_hasReference = false;
|
||||
bool m_moved = false;
|
||||
bool m_scaled = false;
|
||||
HandleType m_handle;
|
||||
Editor* m_editor;
|
||||
|
||||
|
@ -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
|
||||
@ -36,6 +36,7 @@
|
||||
#include "app/ui/keyboard_shortcuts.h"
|
||||
#include "app/ui/main_window.h"
|
||||
#include "app/ui/status_bar.h"
|
||||
#include "app/ui/timeline/timeline.h"
|
||||
#include "app/ui_context.h"
|
||||
#include "app/util/clipboard.h"
|
||||
#include "app/util/layer_utils.h"
|
||||
@ -114,10 +115,14 @@ MovingPixelsState::MovingPixelsState(Editor* editor, MouseMessage* msg, PixelsMo
|
||||
ContextBar* contextBar = App::instance()->contextBar();
|
||||
contextBar->updateForMovingPixels(getTransformation(editor));
|
||||
contextBar->add_observer(this);
|
||||
|
||||
App::instance()->mainWindow()->getTimeline()->add_observer(this);
|
||||
}
|
||||
|
||||
MovingPixelsState::~MovingPixelsState()
|
||||
{
|
||||
App::instance()->mainWindow()->getTimeline()->remove_observer(this);
|
||||
|
||||
ContextBar* contextBar = App::instance()->contextBar();
|
||||
contextBar->remove_observer(this);
|
||||
contextBar->updateForActiveTool();
|
||||
@ -723,6 +728,15 @@ void MovingPixelsState::onBeforeLayerChanged(Editor* editor)
|
||||
dropPixels();
|
||||
}
|
||||
|
||||
void MovingPixelsState::onBeforeRangeChanged(Timeline* timeline)
|
||||
{
|
||||
if (!isActiveDocument())
|
||||
return;
|
||||
|
||||
if (m_pixelsMovement)
|
||||
dropPixels();
|
||||
}
|
||||
|
||||
void MovingPixelsState::onTransparentColorChange()
|
||||
{
|
||||
ASSERT(m_pixelsMovement);
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2019-2020 Igara Studio S.A.
|
||||
// Copyright (C) 2019-2021 Igara Studio S.A.
|
||||
// Copyright (C) 2001-2017 David Capello
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
@ -15,6 +15,7 @@
|
||||
#include "app/ui/editor/pixels_movement.h"
|
||||
#include "app/ui/editor/standby_state.h"
|
||||
#include "app/ui/status_bar.h"
|
||||
#include "app/ui/timeline/timeline_observer.h"
|
||||
#include "obs/connection.h"
|
||||
#include "ui/timer.h"
|
||||
|
||||
@ -29,6 +30,7 @@ namespace app {
|
||||
class MovingPixelsState
|
||||
: public StandbyState
|
||||
, EditorObserver
|
||||
, TimelineObserver
|
||||
, ContextBarObserver
|
||||
, PixelsMovementDelegate {
|
||||
public:
|
||||
@ -66,6 +68,9 @@ namespace app {
|
||||
virtual void onBeforeFrameChanged(Editor* editor) override;
|
||||
virtual void onBeforeLayerChanged(Editor* editor) override;
|
||||
|
||||
// TimelineObserver
|
||||
virtual void onBeforeRangeChanged(Timeline* timeline) override;
|
||||
|
||||
// ContextBarObserver
|
||||
virtual void onDropPixels(ContextBarObserver::DropAction action) override;
|
||||
|
||||
|
@ -1293,16 +1293,32 @@ CelList PixelsMovement::getEditableCels()
|
||||
// TODO This case is used in paste too, where the cel() can be
|
||||
// nullptr (e.g. we paste the clipboard image into an empty
|
||||
// cel).
|
||||
if (m_site.layer() && m_site.layer()->isEditableHierarchy())
|
||||
if (m_site.layer() &&
|
||||
m_site.layer()->canEditPixels()) {
|
||||
cels.push_back(m_site.cel());
|
||||
}
|
||||
return cels;
|
||||
}
|
||||
|
||||
// Current cel (m_site.cel()) can be nullptr when we paste in an
|
||||
// empty cel (Ctrl+V) and cut (Ctrl+X) the floating pixels.
|
||||
if (m_site.cel() &&
|
||||
m_site.cel()->layer()->isEditableHierarchy()) {
|
||||
auto it = std::find(cels.begin(), cels.end(), m_site.cel());
|
||||
m_site.cel()->layer()->canEditPixels()) {
|
||||
CelList::iterator it;
|
||||
|
||||
// If we are in a linked cel, remove the cel that matches the
|
||||
// linked cel. In this way we avoid having two Cel in cels
|
||||
// pointing to the same CelData.
|
||||
if (Cel* link = m_site.cel()->link()) {
|
||||
it = std::find_if(cels.begin(), cels.end(),
|
||||
[link](const Cel* cel){
|
||||
return (cel == link ||
|
||||
cel->link() == link);
|
||||
});
|
||||
}
|
||||
else {
|
||||
it = std::find(cels.begin(), cels.end(), m_site.cel());
|
||||
}
|
||||
if (it != cels.end())
|
||||
cels.erase(it);
|
||||
cels.insert(cels.begin(), m_site.cel());
|
||||
|
@ -4051,6 +4051,8 @@ void Timeline::invalidateRange()
|
||||
void Timeline::clearAndInvalidateRange()
|
||||
{
|
||||
if (m_range.enabled()) {
|
||||
notify_observers(&TimelineObserver::onBeforeRangeChanged, this);
|
||||
|
||||
invalidateRange();
|
||||
m_range.clearRange();
|
||||
}
|
||||
|
@ -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
|
||||
@ -17,6 +17,7 @@
|
||||
#include "app/ui/editor/editor_observer.h"
|
||||
#include "app/ui/input_chain_element.h"
|
||||
#include "app/ui/timeline/ani_controls.h"
|
||||
#include "app/ui/timeline/timeline_observer.h"
|
||||
#include "base/debug.h"
|
||||
#include "doc/frame.h"
|
||||
#include "doc/layer.h"
|
||||
@ -26,6 +27,7 @@
|
||||
#include "doc/tag.h"
|
||||
#include "gfx/color.h"
|
||||
#include "obs/connection.h"
|
||||
#include "obs/observable.h"
|
||||
#include "ui/scroll_bar.h"
|
||||
#include "ui/timer.h"
|
||||
#include "ui/widget.h"
|
||||
@ -60,6 +62,7 @@ namespace app {
|
||||
|
||||
class Timeline : public ui::Widget,
|
||||
public ui::ScrollableViewDelegate,
|
||||
public obs::observable<TimelineObserver>,
|
||||
public ContextObserver,
|
||||
public DocsObserver,
|
||||
public DocObserver,
|
||||
|
24
src/app/ui/timeline/timeline_observer.h
Normal file
24
src/app/ui/timeline/timeline_observer.h
Normal file
@ -0,0 +1,24 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2021 Igara Studio S.A.
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
// the End-User License Agreement for Aseprite.
|
||||
|
||||
#ifndef APP_UI_TIMELINE_TIMELINE_OBSERVER_H_INCLUDED
|
||||
#define APP_UI_TIMELINE_TIMELINE_OBSERVER_H_INCLUDED
|
||||
#pragma once
|
||||
|
||||
namespace app {
|
||||
class Timeline;
|
||||
|
||||
class TimelineObserver {
|
||||
public:
|
||||
virtual ~TimelineObserver() { }
|
||||
|
||||
// Called when the current timeline range is going to change.
|
||||
virtual void onBeforeRangeChanged(Timeline* timeline) { }
|
||||
};
|
||||
|
||||
} // namespace app
|
||||
|
||||
#endif
|
@ -338,9 +338,14 @@ void UIContext::onGetActiveSite(Site* site) const
|
||||
view->getSite(site);
|
||||
|
||||
if (site->sprite()) {
|
||||
// Selected range in the timeline
|
||||
// Selected range in the timeline. We use it only if the
|
||||
// timeline is visible. A common scenario might be
|
||||
// undoing/redoing actions where the range is re-selected, that
|
||||
// could enable the range even if the timeline is hidden. In
|
||||
// this way we avoid using the timeline selection unexpectedly.
|
||||
Timeline* timeline = App::instance()->timeline();
|
||||
if (timeline &&
|
||||
timeline->isVisible() &&
|
||||
timeline->range().enabled()) {
|
||||
site->range(timeline->range());
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2020 Igara Studio S.A.
|
||||
// Copyright (C) 2020-2021 Igara Studio S.A.
|
||||
// Copyright (C) 2001-2018 David Capello
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
@ -25,6 +25,7 @@ namespace app {
|
||||
using namespace doc;
|
||||
|
||||
// TODO the DocRange should be "iteratable" to replace this function
|
||||
// or we can wait to C++20 coroutines and co_yield
|
||||
static CelList get_cels_templ(const Sprite* sprite,
|
||||
DocRange range,
|
||||
const bool onlyUniqueCels,
|
||||
@ -39,8 +40,9 @@ static CelList get_cels_templ(const Sprite* sprite,
|
||||
for (Layer* layer : range.selectedLayers()) {
|
||||
if (!layer ||
|
||||
!layer->isImage() ||
|
||||
(onlyUnlockedCel && !layer->isEditableHierarchy()))
|
||||
(onlyUnlockedCel && !layer->canEditPixels())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
LayerImage* layerImage = static_cast<LayerImage*>(layer);
|
||||
for (frame_t frame : range.selectedFrames()) {
|
||||
|
@ -1,4 +1,4 @@
|
||||
Copyright (c) 2018-2020 Igara Studio S.A.
|
||||
Copyright (c) 2018-2021 Igara Studio S.A.
|
||||
Copyright (c) 2001-2018 David Capello
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Aseprite Document Library
|
||||
// Copyright (C) 2019-2020 Igara Studio S.A.
|
||||
// Copyright (C) 2019-2021 Igara Studio S.A.
|
||||
// Copyright (C) 2001-2018 David Capello
|
||||
//
|
||||
// This file is released under the terms of the MIT license.
|
||||
@ -180,6 +180,24 @@ bool Layer::isEditableHierarchy() const
|
||||
return true;
|
||||
}
|
||||
|
||||
// It's like isVisibleHierarchy + isEditableHierarchy. Returns true if
|
||||
// the whole layer hierarchy is unlocked and visible, so the user can
|
||||
// edit its pixels without unexpected side-effects (e.g. editing
|
||||
// hidden layers).
|
||||
bool Layer::canEditPixels() const
|
||||
{
|
||||
const Layer* layer = this;
|
||||
while (layer) {
|
||||
if (!layer->isVisible() ||
|
||||
!layer->isEditable() ||
|
||||
layer->isReference()) { // Cannot edit pixels from reference layers
|
||||
return false;
|
||||
}
|
||||
layer = layer->parent();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Layer::hasAncestor(const Layer* ancestor) const
|
||||
{
|
||||
Layer* it = parent();
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Aseprite Document Library
|
||||
// Copyright (C) 2019-2020 Igara Studio S.A.
|
||||
// Copyright (C) 2019-2021 Igara Studio S.A.
|
||||
// Copyright (C) 2001-2018 David Capello
|
||||
//
|
||||
// This file is released under the terms of the MIT license.
|
||||
@ -92,6 +92,7 @@ namespace doc {
|
||||
|
||||
bool isVisibleHierarchy() const;
|
||||
bool isEditableHierarchy() const;
|
||||
bool canEditPixels() const;
|
||||
bool hasAncestor(const Layer* ancestor) const;
|
||||
|
||||
void setBackground(bool state) { switchFlags(LayerFlags::Background, state); }
|
||||
|
2
src/flic
2
src/flic
@ -1 +1 @@
|
||||
Subproject commit 1e0630d310b55abf7d16d3d89feeb13936d540f8
|
||||
Subproject commit 876ef60df5fec606f8eb0638ee893e4967db4673
|
2
src/tga
2
src/tga
@ -1 +1 @@
|
||||
Subproject commit ea8005303f42925fa1180d1f6e973a816c0b80af
|
||||
Subproject commit 16b8bb25e34bfb0193609012257502be62539d35
|
Loading…
x
Reference in New Issue
Block a user