mirror of
https://github.com/aseprite/aseprite.git
synced 2025-04-10 12:44:53 +00:00
* Moved app::DocRange to view::Range * Moved range_utils to view/cels.cpp * Moved layer_utils to view/layers.cpp * Created more functions in app::Site to access selected cels (they use the functions from view/cels.h)
176 lines
4.2 KiB
C++
176 lines
4.2 KiB
C++
// Aseprite
|
|
// Copyright (C) 2019-2023 Igara Studio S.A.
|
|
//
|
|
// This program is distributed under the terms of
|
|
// the End-User License Agreement for Aseprite.
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
#include "config.h"
|
|
#endif
|
|
|
|
#include "app/active_site_handler.h"
|
|
#include "app/doc.h"
|
|
#include "app/doc_event.h"
|
|
#include "app/site.h"
|
|
#include "doc/layer.h"
|
|
#include "view/layers.h"
|
|
|
|
namespace app {
|
|
|
|
ActiveSiteHandler::ActiveSiteHandler()
|
|
{
|
|
}
|
|
|
|
ActiveSiteHandler::~ActiveSiteHandler()
|
|
{
|
|
}
|
|
|
|
void ActiveSiteHandler::addDoc(Doc* doc)
|
|
{
|
|
Data data;
|
|
data.layer = doc::NullId;
|
|
if (doc->sprite()) { // The sprite can be nullptr in some tests
|
|
if (doc::Layer* layer = doc->sprite()->root()->firstLayer())
|
|
data.layer = layer->id();
|
|
}
|
|
data.frame = 0;
|
|
m_data.insert(std::make_pair(doc, data));
|
|
doc->add_observer(this);
|
|
}
|
|
|
|
void ActiveSiteHandler::removeDoc(Doc* doc)
|
|
{
|
|
auto it = m_data.find(doc);
|
|
if (it == m_data.end())
|
|
return;
|
|
|
|
doc->remove_observer(this);
|
|
m_data.erase(it);
|
|
}
|
|
|
|
ActiveSiteHandler::Data& ActiveSiteHandler::getData(Doc* doc)
|
|
{
|
|
auto it = m_data.find(doc);
|
|
if (it == m_data.end()) {
|
|
addDoc(doc);
|
|
it = m_data.find(doc);
|
|
ASSERT(it != m_data.end());
|
|
}
|
|
return it->second;
|
|
}
|
|
|
|
void ActiveSiteHandler::getActiveSiteForDoc(Doc* doc, Site* site)
|
|
{
|
|
Data& data = getData(doc);
|
|
site->document(doc);
|
|
site->sprite(doc->sprite());
|
|
site->layer(doc::get<doc::Layer>(data.layer));
|
|
site->frame(data.frame);
|
|
site->range(data.range);
|
|
site->selectedColors(data.selectedColors);
|
|
site->selectedTiles(data.selectedTiles);
|
|
}
|
|
|
|
void ActiveSiteHandler::setActiveLayerInDoc(Doc* doc, doc::Layer* layer)
|
|
{
|
|
Data& data = getData(doc);
|
|
data.layer = (layer ? layer->id(): 0);
|
|
}
|
|
|
|
void ActiveSiteHandler::setActiveFrameInDoc(Doc* doc, doc::frame_t frame)
|
|
{
|
|
Data& data = getData(doc);
|
|
data.frame = frame;
|
|
}
|
|
|
|
void ActiveSiteHandler::setRangeInDoc(Doc* doc, const DocRange& range)
|
|
{
|
|
Data& data = getData(doc);
|
|
data.range = range;
|
|
|
|
// Select at least the active layer
|
|
if (data.range.selectedLayers().empty()) {
|
|
if (auto layer = doc::get<Layer>(data.layer)) {
|
|
data.range.selectLayer(layer);
|
|
}
|
|
}
|
|
|
|
// Select at least the active frame
|
|
if (data.range.selectedFrames().empty()) {
|
|
SelectedFrames frames;
|
|
frames.insert(data.frame);
|
|
data.range.setSelectedFrames(frames);
|
|
}
|
|
|
|
data.range.setType(range.type());
|
|
}
|
|
|
|
void ActiveSiteHandler::setSelectedColorsInDoc(Doc* doc, const doc::PalettePicks& picks)
|
|
{
|
|
Data& data = getData(doc);
|
|
data.selectedColors = picks;
|
|
}
|
|
|
|
void ActiveSiteHandler::setSelectedTilesInDoc(Doc* doc, const doc::PalettePicks& picks)
|
|
{
|
|
Data& data = getData(doc);
|
|
data.selectedTiles = picks;
|
|
}
|
|
|
|
void ActiveSiteHandler::onAddLayer(DocEvent& ev)
|
|
{
|
|
Data& data = getData(ev.document());
|
|
data.layer = ev.layer()->id();
|
|
}
|
|
|
|
void ActiveSiteHandler::onAddFrame(DocEvent& ev)
|
|
{
|
|
Data& data = getData(ev.document());
|
|
data.frame = ev.frame();
|
|
}
|
|
|
|
// TODO similar to Timeline::onBeforeRemoveLayer() and Editor::onBeforeRemoveLayer()
|
|
void ActiveSiteHandler::onBeforeRemoveLayer(DocEvent& ev)
|
|
{
|
|
Data& data = getData(ev.document());
|
|
doc::Layer* selectedLayer = (data.layer != doc::NullId ?
|
|
doc::get<doc::Layer>(data.layer):
|
|
nullptr);
|
|
if (!selectedLayer)
|
|
return;
|
|
|
|
// Remove layer from range
|
|
data.range.eraseAndAdjust(ev.layer());
|
|
|
|
// Select other layer as active
|
|
doc::Layer* layerToSelect =
|
|
view::candidate_if_layer_is_deleted(selectedLayer, ev.layer());
|
|
if (selectedLayer != layerToSelect) {
|
|
data.layer = (layerToSelect ? layerToSelect->id():
|
|
doc::NullId);
|
|
}
|
|
}
|
|
|
|
// TODO similar to Timeline::onRemoveFrame()
|
|
void ActiveSiteHandler::onRemoveFrame(DocEvent& ev)
|
|
{
|
|
Data& data = getData(ev.document());
|
|
|
|
// Adjust current frame of the data that are in a frame more
|
|
// advanced that the removed one.
|
|
if (data.frame > ev.frame()) {
|
|
--data.frame;
|
|
}
|
|
// If the data was in the previous "last frame" (current value of
|
|
// totalFrames()), we've to adjust it to the new last frame
|
|
// (lastFrame())
|
|
else if (data.frame >= ev.sprite()->totalFrames()) {
|
|
data.frame = ev.sprite()->lastFrame();
|
|
}
|
|
|
|
if (data.frame < ev.frame())
|
|
--data.frame;
|
|
}
|
|
|
|
} // namespace app
|