Refactor: Create doc::Context and move some logic from app::Document to doc::Document

The objective of these changes is to create a more testable doc/logic API.

Included changes:
- Added doc::Context, doc::Documents (the old app::Documents),
  and doc::Sprites (and observers for each)
- Added raster::Sprite::createBasicSprite()
- Added doc::ColorMode (equal to raster::PixelFormat)
- Added some methods to doc::Document: context(), sprites(), sprite()
  (to replace app::Document::getSprite()), width/height(), colorMode(),
  name(), and close()
- Moved app::DocumentObserver/Event to doc::DocumentObserver/Event
- Replaced app::ContextObserver with doc::DocumentsObserver and a couple
  of signals.
- Renamed app::Context::getActiveDocument() with
  doc::Context::activeDocument()
- Renamed app::Context::getActiveLocation() with
  app::Context::activeLocation()
- Removed app::ContextObserverList
- Removed app::DocumentId (now we can use doc::ObjectId)
- Removed app::Context::getSettings()
This commit is contained in:
David Capello 2014-07-29 00:53:24 -03:00
parent a20bb2d4d7
commit 81ffb0c5bd
114 changed files with 1401 additions and 1074 deletions

View File

@ -286,6 +286,7 @@ endfunction()
find_tests(base base-lib ${sys_libs})
find_tests(gfx gfx-lib base-lib ${sys_libs})
find_tests(raster raster-lib gfx-lib base-lib ${libs3rdparty} ${sys_libs})
find_tests(doc doc-lib raster-lib gfx-lib base-lib ${libs3rdparty} ${sys_libs})
find_tests(css css-lib gfx-lib base-lib ${libs3rdparty} ${sys_libs})
find_tests(ui ui-lib she gfx-lib base-lib ${libs3rdparty} ${sys_libs})
find_tests(app/file ${all_libs})

View File

@ -1,7 +1,7 @@
# Aseprite Source Code
If you are here is because you want to learn about Aseprite source
code. I'll try to write in these `README.md` files a summary of each
code. We'll try to write in these `README.md` files a summary of each
module/library.
# Modules & Libraries
@ -15,7 +15,7 @@ because they don't depend on any other component.
* [allegro](allegro/): Modified version of [Allegro](http://alleg.sourceforge.net/) library, used for keyboard/mouse input, and drawing 2D graphics on screen.
* [base](base/): Core/basic stuff, multithreading, utf8, sha1, file system, memory, etc.
* [css](css/): Style sheet library.
* [css](css/): Pseudo-style sheet library.
* [gfx](gfx/): Abstract graphics structures like point, size, rectangle, region, color, etc.
* [scripting](scripting/): JavaScript engine ([V8](https://code.google.com/p/v8/)).
* [undo](undo/): Generic library to manage undo history of undoable actions.
@ -23,7 +23,6 @@ because they don't depend on any other component.
## Level 1
* [cfg](cfg/) (base, allegro): Library to handle configuration/settings/user preferences.
* [doc](doc/) (base, gfx): Document model library (business layer, replacement of `raster` library).
* [gen](gen/) (base): Helper utility to generate C++ files from different XMLs.
* [net](net/) (base): Networking library to send HTTP requests.
* [raster](raster/) (base, gfx): Library to handle graphics entities like sprites, images, frames.
@ -32,15 +31,19 @@ because they don't depend on any other component.
## Level 2
* [doc](doc/) (raster, base, gfx): Document model library.
* [filters](filters/) (base, gfx, raster): FX for raster images.
* [iff](iff/) (base, doc): Image File Formats library (load/save documents).
* [ui](ui/) (base, gfx, she): Portable UI library (buttons, windows, text fields, etc.)
* [updater](updater/) (base, net): Component to check for updates.
## Level 3
* [app](app/) (allegro, base, doc, filters, gfx, iff, raster, scripting, she, ui, undo, updater, webserver)
* [iff](iff/) (base, doc): Image File Formats library (load/save documents).
## Level 4
* [app](app/) (allegro, base, doc, filters, gfx, iff, raster, scripting, she, ui, undo, updater, webserver)
## Level 5
* [main](main/) (app, base, she, ui)

View File

@ -100,14 +100,12 @@ add_library(app-lib
console.cpp
context.cpp
context_flags.cpp
context_observer_list.cpp
data_recovery.cpp
document.cpp
document_api.cpp
document_exporter.cpp
document_location.cpp
document_undo.cpp
documents.cpp
file/ase_format.cpp
file/bmp_format.cpp
file/file.cpp

View File

@ -31,7 +31,6 @@
#include "app/data_recovery.h"
#include "app/document_exporter.h"
#include "app/document_location.h"
#include "app/document_observer.h"
#include "app/file/file.h"
#include "app/file/file_formats_manager.h"
#include "app/file_system.h"
@ -61,6 +60,7 @@
#include "app/webserver.h"
#include "base/exception.h"
#include "base/unique_ptr.h"
#include "doc/document_observer.h"
#include "raster/image.h"
#include "raster/layer.h"
#include "raster/palette.h"
@ -220,9 +220,6 @@ int App::run()
console.printf("Error loading file \"%s\"\n", it->c_str());
}
else {
// Mount and select the sprite
context->addDocument(document);
// Add the given file in the argument as a "recent file" only
// if we are running in GUI mode. If the program is executed
// in batch mode this is not desirable.
@ -262,9 +259,9 @@ int App::run()
gui_run();
// Destroy all documents in the UIContext.
const Documents& docs = m_modules->m_ui_context.getDocuments();
const doc::Documents& docs = m_modules->m_ui_context.documents();
while (!docs.empty())
m_modules->m_ui_context.removeDocument(docs.back());
delete docs.back();
// Destroy the window.
m_mainWindow.reset(NULL);
@ -344,7 +341,7 @@ void app_refresh_screen()
Context* context = UIContext::instance();
ASSERT(context != NULL);
DocumentLocation location = context->getActiveLocation();
DocumentLocation location = context->activeLocation();
if (Palette* pal = location.palette())
set_current_palette(pal, false);
@ -365,9 +362,9 @@ PixelFormat app_get_current_pixel_format()
Context* context = UIContext::instance();
ASSERT(context != NULL);
Document* document = context->getActiveDocument();
Document* document = context->activeDocument();
if (document != NULL)
return document->getSprite()->getPixelFormat();
return document->sprite()->getPixelFormat();
else if (screen != NULL && bitmap_color_depth(screen) == 8)
return IMAGE_INDEXED;
else

View File

@ -70,7 +70,7 @@ void BackgroundFromLayerCommand::onExecute(Context* context)
raster::color_t bgcolor =
color_utils::color_for_target(
context->getSettings()->getBgColor(),
context->settings()->getBgColor(),
ColorTarget(
ColorTarget::BackgroundLayer,
sprite->getPixelFormat(),

View File

@ -213,7 +213,7 @@ void CanvasSizeCommand::onExecute(Context* context)
UndoTransaction undoTransaction(writer.context(), "Canvas Size");
DocumentApi api = document->getApi();
raster::color_t bgcolor = color_utils::color_for_target(
context->getSettings()->getBgColor(),
context->settings()->getBgColor(),
ColorTarget(
ColorTarget::BackgroundLayer,
sprite->getPixelFormat(),

View File

@ -69,8 +69,8 @@ void ChangeBrushCommand::onLoadParams(Params* params)
void ChangeBrushCommand::onExecute(Context* context)
{
tools::Tool* current_tool = context->getSettings()->getCurrentTool();
IToolSettings* tool_settings = context->getSettings()->getToolSettings(current_tool);
tools::Tool* current_tool = context->settings()->getCurrentTool();
IToolSettings* tool_settings = context->settings()->getToolSettings(current_tool);
IBrushSettings* brush = tool_settings->getBrush();
switch (m_change) {

View File

@ -31,7 +31,6 @@
#include "app/ui/status_bar.h"
#include "app/ui/workspace.h"
#include "app/ui_context.h"
#include "base/path.h"
#include "raster/sprite.h"
#include "ui/ui.h"
@ -67,11 +66,11 @@ protected:
{
Workspace* workspace = App::instance()->getMainWindow()->getWorkspace();
if (workspace->getActiveView() == NULL)
if (workspace->activeView() == NULL)
return;
if (DocumentView* docView =
dynamic_cast<DocumentView*>(workspace->getActiveView())) {
dynamic_cast<DocumentView*>(workspace->activeView())) {
Document* document = docView->getDocument();
if (static_cast<UIContext*>(context)->countViewsOf(document) == 1) {
// If we have only one view for this document, close the file.
@ -81,7 +80,7 @@ protected:
}
// Close the active view.
WorkspaceView* view = workspace->getActiveView();
WorkspaceView* view = workspace->activeView();
workspace->removeView(view);
delete view;
}
@ -105,13 +104,13 @@ protected:
bool onEnabled(Context* context)
{
return !context->getDocuments().empty();
return !context->documents().empty();
}
void onExecute(Context* context)
{
while (true) {
if (context->getActiveDocument() != NULL) {
if (context->activeDocument() != NULL) {
if (!close_active_document(context))
break;
}
@ -143,7 +142,7 @@ static bool close_active_document(Context* context)
while (document->isModified()) {
// ask what want to do the user with the changes in the sprite
int ret = Alert::show("Warning<<Saving changes in:<<%s||&Save||Do&n't Save||&Cancel",
base::get_file_name(document->getFilename()).c_str());
document->name().c_str());
if (ret == 1) {
// "save": save the changes
@ -178,7 +177,7 @@ static bool close_active_document(Context* context)
DocumentDestroyer document(context, closedDocument);
StatusBar::instance()
->setStatusText(0, "Sprite '%s' closed.",
base::get_file_name(document->getFilename()).c_str());
document->name().c_str());
document.destroyDocument();
}

View File

@ -95,7 +95,7 @@ ConfigureTools::ConfigureTools()
void ConfigureTools::onExecute(Context* context)
{
m_settings = UIContext::instance()->getSettings();
m_settings = UIContext::instance()->settings();
m_docSettings = m_settings->getDocumentSettings(NULL);
Button* set_grid;

View File

@ -24,7 +24,6 @@
#include "app/commands/command.h"
#include "app/context.h"
#include "app/document.h"
#include "app/documents.h"
#include "app/ui/devconsole_view.h"
#include "app/ui/main_window.h"
#include "app/ui/workspace.h"

View File

@ -1,5 +1,5 @@
/* Aseprite
* Copyright (C) 2001-2013 David Capello
* Copyright (C) 2001-2014 David Capello
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -73,9 +73,10 @@ void DuplicateSpriteCommand::onExecute(Context* context)
dst_name = window->findChild("dst_name");
flatten = window->findChild("flatten");
std::string fn = document->getFilename();
std::string fn = document->filename();
std::string ext = base::get_file_extension(fn);
src_name->setText(base::get_file_name(fn));
dst_name->setText(base::get_file_title(fn) + " Copy." + base::get_file_extension(fn));
dst_name->setText(base::get_file_title(fn) + " Copy" + (!ext.empty() ? "." + ext: ""));
if (get_config_bool("DuplicateSprite", "Flatten", false))
flatten->setSelected(true);
@ -94,8 +95,7 @@ void DuplicateSpriteCommand::onExecute(Context* context)
docCopy = document->duplicate(DuplicateExactCopy);
docCopy->setFilename(dst_name->getText().c_str());
context->addDocument(docCopy);
docCopy->setContext(context);
}
}

View File

@ -47,11 +47,11 @@ ExitCommand::ExitCommand()
void ExitCommand::onExecute(Context* context)
{
const Documents& docs = context->getDocuments();
const doc::Documents& docs = context->documents();
bool modifiedFiles = false;
for (Documents::const_iterator it=docs.begin(), end=docs.end(); it!=end; ++it) {
const Document* document = *it;
for (doc::Documents::const_iterator it=docs.begin(), end=docs.end(); it!=end; ++it) {
const Document* document = static_cast<Document*>(*it);
if (document->isModified()) {
modifiedFiles = true;
break;

View File

@ -188,8 +188,8 @@ void ExportSpriteSheetCommand::onExecute(Context* context)
setColumns(window->columns());
}
Document* document(context->getActiveDocument());
Sprite* sprite = document->getSprite();
Document* document(context->activeDocument());
Sprite* sprite = document->sprite();
FrameNumber nframes = sprite->getTotalFrames();
int columns;

View File

@ -53,14 +53,14 @@ public:
protected:
bool onChecked(Context* context)
{
IDocumentSettings* docSettings = context->getSettings()->getDocumentSettings(context->getActiveDocument());
IDocumentSettings* docSettings = context->settings()->getDocumentSettings(context->activeDocument());
return docSettings->getGridVisible();
}
void onExecute(Context* context)
{
IDocumentSettings* docSettings = context->getSettings()->getDocumentSettings(context->getActiveDocument());
IDocumentSettings* docSettings = context->settings()->getDocumentSettings(context->activeDocument());
docSettings->setGridVisible(docSettings->getGridVisible() ? false: true);
}
@ -80,14 +80,14 @@ public:
protected:
bool onChecked(Context* context)
{
IDocumentSettings* docSettings = context->getSettings()->getDocumentSettings(context->getActiveDocument());
IDocumentSettings* docSettings = context->settings()->getDocumentSettings(context->activeDocument());
return docSettings->getSnapToGrid();
}
void onExecute(Context* context)
{
IDocumentSettings* docSettings = context->getSettings()->getDocumentSettings(context->getActiveDocument());
IDocumentSettings* docSettings = context->settings()->getDocumentSettings(context->activeDocument());
char buf[512];
docSettings->setSnapToGrid(docSettings->getSnapToGrid() ? false: true);
@ -130,7 +130,7 @@ void GridSettingsCommand::onExecute(Context* context)
Widget* grid_w = app::find_widget<Widget>(window, "grid_w");
Widget* grid_h = app::find_widget<Widget>(window, "grid_h");
IDocumentSettings* docSettings = context->getSettings()->getDocumentSettings(context->getActiveDocument());
IDocumentSettings* docSettings = context->settings()->getDocumentSettings(context->activeDocument());
Rect bounds = docSettings->getGridBounds();
grid_x->setTextf("%d", bounds.x);

View File

@ -114,7 +114,7 @@ protected:
void onSelectFile()
{
Document* oldActiveDocument = m_context->getActiveDocument();
Document* oldActiveDocument = m_context->activeDocument();
Command* openFile = CommandsModule::instance()->getCommandByName(CommandId::OpenFile);
Params params;
params.set("filename", "");
@ -122,7 +122,7 @@ protected:
openFile->execute(m_context);
// The user have selected another document.
if (oldActiveDocument != m_context->getActiveDocument()) {
if (oldActiveDocument != m_context->activeDocument()) {
selectActiveDocument();
m_fileOpened = true;
}
@ -161,8 +161,8 @@ protected:
std::vector<Image*> animation;
try {
Sprite* sprite = m_document->getSprite();
FrameNumber currentFrame = m_context->getActiveLocation().frame();
Sprite* sprite = m_document->sprite();
FrameNumber currentFrame = m_context->activeLocation().frame();
// As first step, we cut each tile and add them into "animation" list.
for (int y=m_rect.y; y<sprite->getHeight(); y += m_rect.h) {
@ -293,7 +293,7 @@ private:
void selectActiveDocument()
{
Document* oldDocument = m_document;
m_document = m_context->getActiveDocument();
m_document = m_context->activeDocument();
// If the user already have selected a file, we have to destroy
// that file in order to select the new one.

View File

@ -169,21 +169,15 @@ void NewFileCommand::onExecute(Context* context)
ASSERT(format == IMAGE_RGB || format == IMAGE_GRAYSCALE || format == IMAGE_INDEXED);
ASSERT(w > 0 && h > 0);
base::UniquePtr<Document> document(
Document::createBasicDocument(format, w, h,
(format == IMAGE_INDEXED ? ncolors: 256)));
Sprite* sprite(document->getSprite());
base::UniquePtr<Sprite> sprite(Sprite::createBasicSprite(format, w, h,
(format == IMAGE_INDEXED ? ncolors: 256)));
if (sprite->getPixelFormat() != IMAGE_GRAYSCALE)
get_default_palette()->copyColorsTo(sprite->getPalette(FrameNumber(0)));
usprintf(buf, "Sprite-%04d", ++_sprite_counter);
document->setFilename(buf);
// If the background color isn't transparent, we have to
// convert the `Layer 1' in a `Background'
if (color.getType() != app::Color::MaskType) {
Sprite* sprite = document->getSprite();
Layer* layer = sprite->getFolder()->getFirstLayer();
if (layer && layer->isImage()) {
@ -201,7 +195,12 @@ void NewFileCommand::onExecute(Context* context)
}
// Show the sprite to the user
context->addDocument(document.release());
base::UniquePtr<Document> doc(new Document(sprite));
sprite.release();
usprintf(buf, "Sprite-%04d", ++_sprite_counter);
doc->setFilename(buf);
doc->setContext(context);
doc.release();
}
}
}

View File

@ -77,7 +77,7 @@ void NewFrameCommand::onExecute(Context* context)
StatusBar::instance()
->showTip(1000, "New frame %d/%d",
(int)context->getActiveLocation().frame()+1,
(int)context->activeLocation().frame()+1,
(int)sprite->getTotalFrames());
App::instance()->getMainWindow()->popTimeline();

View File

@ -46,14 +46,14 @@ public:
protected:
bool onChecked(Context* context)
{
IDocumentSettings* docSettings = context->getSettings()->getDocumentSettings(context->getActiveDocument());
IDocumentSettings* docSettings = context->settings()->getDocumentSettings(context->activeDocument());
return docSettings->getUseOnionskin();
}
void onExecute(Context* context)
{
IDocumentSettings* docSettings = context->getSettings()->getDocumentSettings(context->getActiveDocument());
IDocumentSettings* docSettings = context->settings()->getDocumentSettings(context->activeDocument());
docSettings->setUseOnionskin(docSettings->getUseOnionskin() ? false: true);
}

View File

@ -147,10 +147,8 @@ void OpenFileCommand::onExecute(Context* context)
Document* document = fop->document;
if (document) {
UIContext* context = UIContext::instance();
App::instance()->getRecentFiles()->addRecentFile(fop->filename.c_str());
context->addDocument(document);
document->setContext(context);
}
else if (!fop_is_stop(fop))
unrecent = true;

View File

@ -56,7 +56,7 @@ bool OpenInFolderCommand::onEnabled(Context* context)
void OpenInFolderCommand::onExecute(Context* context)
{
launcher::open_folder(context->getActiveDocument()->getFilename());
launcher::open_folder(context->activeDocument()->filename());
}
Command* CommandFactory::createOpenInFolderCommand()

View File

@ -56,7 +56,7 @@ bool OpenWithAppCommand::onEnabled(Context* context)
void OpenWithAppCommand::onExecute(Context* context)
{
launcher::open_file(context->getActiveDocument()->getFilename());
launcher::open_file(context->activeDocument()->filename());
}
Command* CommandFactory::createOpenWithAppCommand()

View File

@ -229,8 +229,8 @@ void PaletteEditorCommand::onExecute(Context* context)
// Show the specified target color
{
app::Color color =
(m_background ? context->getSettings()->getBgColor():
context->getSettings()->getFgColor());
(m_background ? context->settings()->getBgColor():
context->settings()->getFgColor());
g_window->setColor(color);
}
@ -733,8 +733,8 @@ void PaletteEntryEditor::setNewPalette(Palette* palette, const char* operationNa
void PaletteEntryEditor::updateCurrentSpritePalette(const char* operationName)
{
if (UIContext::instance()->getActiveDocument() &&
UIContext::instance()->getActiveDocument()->getSprite()) {
if (UIContext::instance()->activeDocument() &&
UIContext::instance()->activeDocument()->sprite()) {
try {
ContextWriter writer(UIContext::instance());
Document* document(writer.document());

View File

@ -85,7 +85,7 @@ void PlayAnimationCommand::onExecute(Context* context)
Sprite* sprite(writer.sprite());
int msecs;
bool done = false;
IDocumentSettings* docSettings = context->getSettings()->getDocumentSettings(document);
IDocumentSettings* docSettings = context->settings()->getDocumentSettings(document);
bool onionskin_state = docSettings->getUseOnionskin();
Palette *oldpal, *newpal;
bool pingPongForward = true;

View File

@ -93,7 +93,7 @@ void PreviewCommand::onExecute(Context* context)
View* view = View::getView(editor);
int u, v, x, y;
int index_bg_color = -1;
IDocumentSettings* docSettings = context->getSettings()->getDocumentSettings(document);
IDocumentSettings* docSettings = context->settings()->getDocumentSettings(document);
filters::TiledMode tiled = docSettings->getTiledMode();
// Free mouse

View File

@ -103,13 +103,13 @@ static void save_document_in_background(Context* context, Document* document, bo
document->impossibleToBackToSavedState();
}
else {
App::instance()->getRecentFiles()->addRecentFile(document->getFilename().c_str());
App::instance()->getRecentFiles()->addRecentFile(document->filename().c_str());
if (mark_as_saved)
document->markAsSaved();
StatusBar::instance()
->setStatusText(2000, "File %s, saved.",
base::get_file_name(document->getFilename()).c_str());
document->name().c_str());
}
}
@ -141,7 +141,7 @@ protected:
filename = m_filename;
}
else {
filename = document->getFilename();
filename = document->filename();
char exts[4096];
get_writable_extensions(exts, sizeof(exts));
@ -185,7 +185,7 @@ protected:
{
ContextWriter writer(reader);
Document* documentWriter = writer.document();
std::string oldFilename = documentWriter->getFilename();
std::string oldFilename = documentWriter->filename();
// Change the document file name
documentWriter->setFilename(filename.c_str());
@ -248,7 +248,7 @@ void SaveFileCommand::onExecute(Context* context)
ContextWriter writer(reader);
Document* documentWriter = writer.document();
if (!confirmReadonly(documentWriter->getFilename()))
if (!confirmReadonly(documentWriter->filename()))
return;
save_document_in_background(context, documentWriter, true);
@ -300,7 +300,7 @@ void SaveFileCopyAsCommand::onExecute(Context* context)
{
const ContextReader reader(context);
const Document* document(reader.document());
std::string old_filename = document->getFilename();
std::string old_filename = document->filename();
// show "Save As" dialog
saveAsDialog(reader, "Save Copy As", false);

View File

@ -96,7 +96,7 @@ bool ScrollCommand::onEnabled(Context* context)
void ScrollCommand::onExecute(Context* context)
{
IDocumentSettings* docSettings = context->getSettings()->getDocumentSettings(context->getActiveDocument());
IDocumentSettings* docSettings = context->settings()->getDocumentSettings(context->activeDocument());
ui::View* view = ui::View::getView(current_editor);
gfx::Rect vp = view->getViewportBounds();
gfx::Point scroll = view->getViewScroll();

View File

@ -47,8 +47,8 @@ MakeUniqueEditorCommand::MakeUniqueEditorCommand()
void MakeUniqueEditorCommand::onExecute(Context* context)
{
Workspace* workspace = App::instance()->getMainWindow()->getWorkspace();
if (workspace->getActiveView() != NULL)
workspace->makeUnique(workspace->getActiveView());
if (workspace->activeView() != NULL)
workspace->makeUnique(workspace->activeView());
}
class SplitEditorHorizontallyCommand : public Command {
@ -70,8 +70,8 @@ SplitEditorHorizontallyCommand::SplitEditorHorizontallyCommand()
void SplitEditorHorizontallyCommand::onExecute(Context* context)
{
Workspace* workspace = App::instance()->getMainWindow()->getWorkspace();
if (workspace->getActiveView() != NULL)
workspace->splitView(workspace->getActiveView(), JI_HORIZONTAL);
if (workspace->activeView() != NULL)
workspace->splitView(workspace->activeView(), JI_HORIZONTAL);
}
class SplitEditorVerticallyCommand : public Command {
@ -93,8 +93,8 @@ SplitEditorVerticallyCommand::SplitEditorVerticallyCommand()
void SplitEditorVerticallyCommand::onExecute(Context* context)
{
Workspace* workspace = App::instance()->getMainWindow()->getWorkspace();
if (workspace->getActiveView() != NULL)
workspace->splitView(workspace->getActiveView(), JI_VERTICAL);
if (workspace->activeView() != NULL)
workspace->splitView(workspace->activeView(), JI_VERTICAL);
}
Command* CommandFactory::createMakeUniqueEditorCommand()

View File

@ -107,7 +107,7 @@ void SpritePropertiesCommand::onExecute(Context* context)
}
// Filename
name->setText(document->getFilename());
name->setText(document->filename());
// Color mode
type->setText(imgtype_text.c_str());

View File

@ -74,7 +74,7 @@ void UndoCommand::onExecute(Context* context)
ContextWriter writer(context);
Document* document(writer.document());
DocumentUndo* undo = document->getUndo();
Sprite* sprite = document->getSprite();
Sprite* sprite = document->sprite();
if (get_config_bool("Options", "UndoGotoModified", true)) {
SpritePosition spritePosition;

View File

@ -187,7 +187,7 @@ void ConvolutionMatrixCommand::onExecute(Context* context)
// Create the filter and setup initial settings
ConvolutionMatrixFilter filter;
IDocumentSettings* docSettings = context->getSettings()->getDocumentSettings(context->getActiveDocument());
IDocumentSettings* docSettings = context->settings()->getDocumentSettings(context->activeDocument());
filter.setTiledMode(docSettings->getTiledMode());
if (matrix != 0)
filter.setMatrix(matrix);

View File

@ -116,7 +116,7 @@ bool DespeckleCommand::onEnabled(Context* context)
void DespeckleCommand::onExecute(Context* context)
{
IDocumentSettings* docSettings = context->getSettings()->getDocumentSettings(context->getActiveDocument());
IDocumentSettings* docSettings = context->settings()->getDocumentSettings(context->activeDocument());
MedianFilter filter;
filter.setTiledMode(docSettings->getTiledMode());

View File

@ -143,7 +143,7 @@ bool ReplaceColorCommand::onEnabled(Context* context)
void ReplaceColorCommand::onExecute(Context* context)
{
DocumentLocation location = context->getActiveLocation();
DocumentLocation location = context->activeLocation();
ReplaceColorFilterWrapper filter(location.layer());
filter.setFrom(get_config_color(ConfigSection, "Color1", ColorBar::instance()->getFgColor()));

View File

@ -50,7 +50,7 @@ using namespace ui;
FilterManagerImpl::FilterManagerImpl(Context* context, Filter* filter)
: m_context(context)
, m_location(context->getActiveLocation())
, m_location(context->activeLocation())
, m_filter(filter)
, m_progressDelegate(NULL)
, m_dst(NULL)

View File

@ -44,53 +44,26 @@ Context::Context(ISettings* settings)
Context::~Context()
{
// The context must be empty at this point.
ASSERT(m_documents.empty());
delete m_settings;
m_settings = NULL;
}
const Documents& Context::getDocuments() const
{
return m_documents;
}
void Context::addDocument(Document* document)
void Context::sendDocumentToTop(doc::Document* document)
{
ASSERT(document != NULL);
m_documents.addDocument(document);
// Generate onAddDocument event
onAddDocument(document);
documents().move(document, 0);
}
void Context::removeDocument(Document* document)
{
ASSERT(document != NULL);
// Remove the item from the documents list.
m_documents.removeDocument(document);
// generate onRemoveDocument event
onRemoveDocument(document);
}
void Context::sendDocumentToTop(Document* document)
{
ASSERT(document != NULL);
m_documents.moveDocument(document, 0);
}
Document* Context::getActiveDocument() const
app::Document* Context::activeDocument() const
{
DocumentLocation location;
onGetActiveLocation(&location);
ASSERT(location.document() == doc::Context::activeDocument());
return location.document();
}
DocumentLocation Context::getActiveLocation() const
DocumentLocation Context::activeLocation() const
{
DocumentLocation location;
onGetActiveLocation(&location);
@ -104,7 +77,7 @@ void Context::executeCommand(Command* command, Params* params)
ASSERT(command != NULL);
PRINTF("Executing '%s' command.\n", command->short_name());
m_observers.notifyCommandBeforeExecution(this);
BeforeCommandExecution();
try {
m_flags.update(this);
@ -115,7 +88,7 @@ void Context::executeCommand(Command* command, Params* params)
if (command->isEnabled(this)) {
command->execute(this);
m_observers.notifyCommandAfterExecution(this);
AfterCommandExecution();
}
}
catch (base::Exception& e) {
@ -144,24 +117,9 @@ void Context::executeCommand(Command* command, Params* params)
#endif
}
void Context::addObserver(ContextObserver* observer)
void Context::onCreateDocument(doc::CreateDocumentArgs* args)
{
m_observers.addObserver(observer);
}
void Context::removeObserver(ContextObserver* observer)
{
m_observers.removeObserver(observer);
}
void Context::onAddDocument(Document* document)
{
m_observers.notifyAddDocument(this, document);
}
void Context::onRemoveDocument(Document* document)
{
m_observers.notifyRemoveDocument(this, document);
args->setDocument(new app::Document(NULL));
}
void Context::onGetActiveLocation(DocumentLocation* location) const

View File

@ -21,11 +21,10 @@
#pragma once
#include "app/context_flags.h"
#include "app/context_observer.h"
#include "app/context_observer_list.h"
#include "app/documents.h"
#include "base/disable_copying.h"
#include "base/exception.h"
#include "base/signal.h"
#include "doc/context.h"
#include <vector>
@ -42,7 +41,7 @@ namespace app {
: base::Exception("Cannot execute the command because its pre-conditions are false.") { }
};
class Context {
class Context : public doc::Context {
public:
Context();
// The "settings" are deleted automatically in the ~Context destructor
@ -54,49 +53,33 @@ namespace app {
virtual bool isExecutingMacro() const { return false; }
virtual bool isExecutingScript() const { return false; }
// TODO Refactor codebase to use ISettings::settings() instead
ISettings* getSettings() {
return settings();
}
ISettings* settings() { return m_settings; }
const Documents& getDocuments() const;
bool checkFlags(uint32_t flags) const { return m_flags.check(flags); }
void updateFlags() { m_flags.update(this); }
// Appends the document to the context's documents' list.
void addDocument(Document* document);
void removeDocument(Document* document);
void sendDocumentToTop(Document* document);
void sendDocumentToTop(doc::Document* document);
Document* getActiveDocument() const;
DocumentLocation getActiveLocation() const;
app::Document* activeDocument() const;
DocumentLocation activeLocation() const;
virtual void executeCommand(Command* command, Params* params = NULL);
void addObserver(ContextObserver* observer);
void removeObserver(ContextObserver* observer);
Signal0<void> BeforeCommandExecution;
Signal0<void> AfterCommandExecution;
protected:
virtual void onAddDocument(Document* document);
virtual void onRemoveDocument(Document* document);
virtual void onCreateDocument(doc::CreateDocumentArgs* args) OVERRIDE;
virtual void onGetActiveLocation(DocumentLocation* location) const;
private:
// List of all documents.
Documents m_documents;
// Settings in this context.
ISettings* m_settings;
// Last updated flags.
ContextFlags m_flags;
ContextObserverList m_observers;
DISABLE_COPYING(Context);
};
} // namespace app

View File

@ -58,8 +58,8 @@ namespace app {
protected:
ContextAccess(const Context* context)
: m_context(context)
, m_document(context->getActiveDocument())
, m_location(context->getActiveLocation())
, m_document(context->activeDocument())
, m_location(context->activeLocation())
{
}
@ -67,7 +67,7 @@ namespace app {
ContextAccess(const Context* context, const DocumentReaderT& documentReader)
: m_context(context)
, m_document(documentReader)
, m_location(context->getActiveLocation())
, m_location(context->activeLocation())
{
}

View File

@ -39,7 +39,7 @@ ContextFlags::ContextFlags()
void ContextFlags::update(Context* context)
{
DocumentLocation location = context->getActiveLocation();
DocumentLocation location = context->activeLocation();
Document* document = location.document();
m_flags = 0;

View File

@ -1,76 +0,0 @@
/* Aseprite
* Copyright (C) 2001-2013 David Capello
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "app/context_observer_list.h"
#include "app/context_observer.h"
#include <algorithm>
#include <functional>
namespace app {
ContextObserverList::ContextObserverList()
{
}
void ContextObserverList::addObserver(ContextObserver* observer)
{
m_observer.push_back(observer);
}
void ContextObserverList::removeObserver(ContextObserver* observer)
{
iterator it = std::find(m_observer.begin(), m_observer.end(), observer);
ASSERT(it != m_observer.end());
m_observer.erase(it);
}
void ContextObserverList::notifyCommandBeforeExecution(Context* context)
{
list_type copy = m_observer;
std::for_each(copy.begin(), copy.end(),
std::bind2nd(std::mem_fun(&ContextObserver::onCommandBeforeExecution), context));
}
void ContextObserverList::notifyCommandAfterExecution(Context* context)
{
list_type copy = m_observer;
std::for_each(copy.begin(), copy.end(),
std::bind2nd(std::mem_fun(&ContextObserver::onCommandAfterExecution), context));
}
void ContextObserverList::notifyAddDocument(Context* context, Document* document)
{
list_type copy = m_observer;
for (iterator it=copy.begin(), end=copy.end(); it!=end; ++it)
(*it)->onAddDocument(context, document);
}
void ContextObserverList::notifyRemoveDocument(Context* context, Document* document)
{
list_type copy = m_observer;
for (iterator it=copy.begin(), end=copy.end(); it!=end; ++it)
(*it)->onRemoveDocument(context, document);
}
} // namespace app

View File

@ -1,52 +0,0 @@
/* Aseprite
* Copyright (C) 2001-2013 David Capello
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef APP_CONTEXT_OBSERVER_LIST_H_INCLUDED
#define APP_CONTEXT_OBSERVER_LIST_H_INCLUDED
#pragma once
#include <vector>
namespace app {
class Context;
class ContextObserver;
class Document;
class ContextObserverList {
public:
typedef std::vector<ContextObserver*> list_type;
typedef std::vector<ContextObserver*>::iterator iterator;
typedef std::vector<ContextObserver*>::const_iterator const_iterator;
ContextObserverList();
void addObserver(ContextObserver* observer);
void removeObserver(ContextObserver* observer);
void notifyCommandBeforeExecution(Context* context);
void notifyCommandAfterExecution(Context* context);
void notifyAddDocument(Context* context, Document* document);
void notifyRemoveDocument(Context* context, Document* document);
private:
list_type m_observer;
};
} // namespace app
#endif

View File

@ -33,7 +33,7 @@
namespace app {
DataRecovery::DataRecovery(Context* context)
DataRecovery::DataRecovery(doc::Context* context)
: m_tempDir(NULL)
, m_backup(NULL)
, m_context(context)
@ -57,10 +57,12 @@ DataRecovery::DataRecovery(Context* context)
}
m_context->addObserver(this);
m_context->documents().addObserver(this);
}
DataRecovery::~DataRecovery()
{
m_context->documents().removeObserver(this);
m_context->removeObserver(this);
delete m_backup;
@ -71,12 +73,12 @@ DataRecovery::~DataRecovery()
}
}
void DataRecovery::onAddDocument(Context* context, Document* document)
void DataRecovery::onAddDocument(doc::Document* document)
{
document->addObserver(this);
}
void DataRecovery::onRemoveDocument(Context* context, Document* document)
void DataRecovery::onRemoveDocument(doc::Document* document)
{
document->removeObserver(this);
}

View File

@ -20,22 +20,29 @@
#define APP_DATA_RECOVERY_H_INCLUDED
#pragma once
#include "app/context_observer.h"
#include "app/document_observer.h"
#include "app/documents.h"
#include "base/compiler_specific.h"
#include "base/disable_copying.h"
#include "base/slot.h"
#include "doc/context_observer.h"
#include "doc/document_observer.h"
#include "doc/documents_observer.h"
namespace base { class TempDir; }
namespace base {
class TempDir;
}
namespace doc {
class Context;
}
namespace app {
class Backup;
class DataRecovery : public ContextObserver
, public DocumentObserver {
class DataRecovery : public doc::ContextObserver
, public doc::DocumentsObserver
, public doc::DocumentObserver {
public:
DataRecovery(Context* context);
DataRecovery(doc::Context* context);
~DataRecovery();
// Returns a backup if there are data to be restored from a
@ -44,12 +51,12 @@ namespace app {
Backup* getBackup() { return m_backup; }
private:
void onAddDocument(Context* context, Document* document) OVERRIDE;
void onRemoveDocument(Context* context, Document* document) OVERRIDE;
virtual void onAddDocument(doc::Document* document) OVERRIDE;
virtual void onRemoveDocument(doc::Document* document) OVERRIDE;
base::TempDir* m_tempDir;
Backup* m_backup;
Context* m_context;
doc::Context* m_context;
DISABLE_COPYING(DataRecovery);
};

View File

@ -23,8 +23,6 @@
#include "app/document.h"
#include "app/document_api.h"
#include "app/document_event.h"
#include "app/document_observer.h"
#include "app/document_undo.h"
#include "app/file/format_options.h"
#include "app/flatten.h"
@ -36,6 +34,8 @@
#include "base/mutex.h"
#include "base/scoped_lock.h"
#include "base/unique_ptr.h"
#include "doc/document_event.h"
#include "doc/document_observer.h"
#include "raster/cel.h"
#include "raster/layer.h"
#include "raster/mask.h"
@ -49,8 +49,7 @@ using namespace base;
using namespace raster;
Document::Document(Sprite* sprite)
: m_sprite(sprite)
, m_undo(new DocumentUndo)
: m_undo(new DocumentUndo)
, m_associated_to_file(false)
, m_mutex(new mutex)
, m_write_lock(false)
@ -64,19 +63,18 @@ Document::Document(Sprite* sprite)
, m_mask(new Mask())
, m_maskVisible(true)
{
m_document.setFilename("Sprite");
setFilename("Sprite");
// Boundary stuff
m_bound.nseg = 0;
m_bound.seg = NULL;
if (sprite)
sprites().add(sprite);
}
Document::~Document()
{
DocumentEvent ev(this);
ev.sprite(m_sprite);
notifyObservers<DocumentEvent&>(&DocumentObserver::onRemoveSprite, ev);
if (m_bound.seg)
base_free(m_bound.seg);
@ -88,110 +86,49 @@ DocumentApi Document::getApi(undo::UndoersCollector* undoers)
return DocumentApi(this, undoers ? undoers: m_undo->getDefaultUndoersCollector());
}
Document* Document::createBasicDocument(PixelFormat format, int width, int height, int ncolors)
{
// Create the sprite.
base::UniquePtr<Sprite> sprite(new Sprite(format, width, height, ncolors));
sprite->setTotalFrames(FrameNumber(1));
// Create the main image.
int indexInStock;
{
base::UniquePtr<Image> image(Image::create(format, width, height));
// Clear the image with mask color.
clear_image(image, 0);
// Add image in the sprite's stock.
indexInStock = sprite->getStock()->addImage(image);
image.release(); // Release the image because it is in the sprite's stock.
}
// Create the first transparent layer.
{
base::UniquePtr<LayerImage> layer(new LayerImage(sprite));
layer->setName("Layer 1");
// Create the cel.
{
base::UniquePtr<Cel> cel(new Cel(FrameNumber(0), indexInStock));
cel->setPosition(0, 0);
// Add the cel in the layer.
layer->addCel(cel);
cel.release(); // Release the cel because it is in the layer
}
// Add the layer in the sprite.
sprite->getFolder()->addLayer(layer.release()); // Release the layer because it's owned by the sprite
}
// Create the document with the new sprite.
base::UniquePtr<Document> document(new Document(sprite));
sprite.release(); // Release the sprite because it is in the document.
document->setFilename("Sprite");
return document.release(); // Release the document (it does not throw) returning the raw pointer
}
void Document::addSprite(Sprite* sprite)
{
ASSERT(m_sprite == NULL); // TODO add support for more sprites in the future (e.g. for .ico files)
m_sprite.reset(sprite);
DocumentEvent ev(this);
ev.sprite(m_sprite);
notifyObservers<DocumentEvent&>(&DocumentObserver::onAddSprite, ev);
}
void Document::notifyGeneralUpdate()
{
DocumentEvent ev(this);
notifyObservers<DocumentEvent&>(&DocumentObserver::onGeneralUpdate, ev);
doc::DocumentEvent ev(this);
notifyObservers<doc::DocumentEvent&>(&doc::DocumentObserver::onGeneralUpdate, ev);
}
void Document::notifySpritePixelsModified(Sprite* sprite, const gfx::Region& region)
{
DocumentEvent ev(this);
doc::DocumentEvent ev(this);
ev.sprite(sprite);
ev.region(region);
notifyObservers<DocumentEvent&>(&DocumentObserver::onSpritePixelsModified, ev);
notifyObservers<doc::DocumentEvent&>(&doc::DocumentObserver::onSpritePixelsModified, ev);
}
void Document::notifyLayerMergedDown(Layer* srcLayer, Layer* targetLayer)
{
DocumentEvent ev(this);
doc::DocumentEvent ev(this);
ev.sprite(srcLayer->getSprite());
ev.layer(srcLayer);
ev.targetLayer(targetLayer);
notifyObservers<DocumentEvent&>(&DocumentObserver::onLayerMergedDown, ev);
notifyObservers<doc::DocumentEvent&>(&doc::DocumentObserver::onLayerMergedDown, ev);
}
void Document::notifyCelMoved(Layer* fromLayer, FrameNumber fromFrame, Layer* toLayer, FrameNumber toFrame)
{
DocumentEvent ev(this);
doc::DocumentEvent ev(this);
ev.sprite(fromLayer->getSprite());
ev.layer(fromLayer);
ev.frame(fromFrame);
ev.targetLayer(toLayer);
ev.targetFrame(toFrame);
notifyObservers<DocumentEvent&>(&DocumentObserver::onCelMoved, ev);
notifyObservers<doc::DocumentEvent&>(&doc::DocumentObserver::onCelMoved, ev);
}
void Document::notifyCelCopied(Layer* fromLayer, FrameNumber fromFrame, Layer* toLayer, FrameNumber toFrame)
{
DocumentEvent ev(this);
doc::DocumentEvent ev(this);
ev.sprite(fromLayer->getSprite());
ev.layer(fromLayer);
ev.frame(fromFrame);
ev.targetLayer(toLayer);
ev.targetFrame(toFrame);
notifyObservers<DocumentEvent&>(&DocumentObserver::onCelCopied, ev);
}
void Document::setFilename(const std::string& filename)
{
m_document.setFilename(filename);
notifyObservers<doc::DocumentEvent&>(&doc::DocumentObserver::onCelCopied, ev);
}
bool Document::isModified() const
@ -281,7 +218,7 @@ void Document::destroyExtraCel()
void Document::prepareExtraCel(int x, int y, int w, int h, int opacity)
{
ASSERT(getSprite() != NULL);
ASSERT(sprite() != NULL);
if (!m_extraCel)
m_extraCel = new Cel(FrameNumber(0), 0); // Ignored fields for this cell (frame, and image index)
@ -290,11 +227,11 @@ void Document::prepareExtraCel(int x, int y, int w, int h, int opacity)
m_extraCel->setOpacity(opacity);
if (!m_extraImage ||
m_extraImage->getPixelFormat() != getSprite()->getPixelFormat() ||
m_extraImage->getPixelFormat() != sprite()->getPixelFormat() ||
m_extraImage->getWidth() != w ||
m_extraImage->getHeight() != h) {
delete m_extraImage; // image
m_extraImage = Image::create(getSprite()->getPixelFormat(), w, h);
m_extraImage = Image::create(sprite()->getPixelFormat(), w, h);
}
}
@ -434,11 +371,13 @@ void Document::copyLayerContent(const Layer* sourceLayer0, Document* destDoc, La
Document* Document::duplicate(DuplicateType type) const
{
const Sprite* sourceSprite = getSprite();
base::UniquePtr<Sprite> spriteCopyPtr(new Sprite(sourceSprite->getPixelFormat(),
sourceSprite->getWidth(),
sourceSprite->getHeight(),
sourceSprite->getPalette(FrameNumber(0))->size()));
const Sprite* sourceSprite = sprite();
base::UniquePtr<Sprite> spriteCopyPtr(new Sprite(
sourceSprite->getPixelFormat(),
sourceSprite->getWidth(),
sourceSprite->getHeight(),
sourceSprite->getPalette(FrameNumber(0))->size()));
base::UniquePtr<Document> documentCopy(new Document(spriteCopyPtr));
Sprite* spriteCopy = spriteCopyPtr.release();
@ -462,7 +401,7 @@ Document* Document::duplicate(DuplicateType type) const
case DuplicateExactCopy:
// Copy the layer folder
copyLayerContent(getSprite()->getFolder(), documentCopy, spriteCopy->getFolder());
copyLayerContent(sprite()->getFolder(), documentCopy, spriteCopy->getFolder());
break;
case DuplicateWithFlattenLayers:

View File

@ -20,7 +20,6 @@
#define APP_DOCUMENT_H_INCLUDED
#pragma once
#include "app/document_id.h"
#include "base/disable_copying.h"
#include "base/observable.h"
#include "base/shared_ptr.h"
@ -54,7 +53,6 @@ namespace undo {
namespace app {
class DocumentApi;
class DocumentObserver;
class DocumentUndo;
class FormatOptions;
struct BoundSeg;
@ -68,18 +66,13 @@ namespace app {
// An application document. It is the class used to contain one file
// opened and being edited by the user (a sprite).
class Document : public base::Observable<DocumentObserver> {
class Document : public doc::Document {
public:
enum LockType {
ReadLock,
WriteLock
};
// Creates a document with one sprite, with one transparent layer,
// and one frame.
static Document* createBasicDocument(PixelFormat format, int width, int height, int ncolors);
Document(Sprite* sprite);
~Document();
@ -89,28 +82,9 @@ namespace app {
//////////////////////////////////////////////////////////////////////
// Main properties
DocumentId getId() const { return m_document.id(); }
void setId(DocumentId id) { m_document.setId(id); }
const Sprite* getSprite() const { return m_sprite; }
const DocumentUndo* getUndo() const { return m_undo; }
Sprite* getSprite() { return m_sprite; }
DocumentUndo* getUndo() { return m_undo; }
void addSprite(Sprite* sprite);
//////////////////////////////////////////////////////////////////////
// Export data
doc::ExportDataPtr exportData() const {
return m_document.exportData();
}
void setExportData(const doc::ExportDataPtr& data) {
return m_document.setExportData(data);
}
//////////////////////////////////////////////////////////////////////
// Notifications
@ -123,9 +97,6 @@ namespace app {
//////////////////////////////////////////////////////////////////////
// File related properties
const std::string& getFilename() const { return m_document.filename(); }
void setFilename(const std::string& filename);
bool isModified() const;
bool isAssociatedToFile() const;
void markAsSaved();
@ -211,11 +182,6 @@ namespace app {
void unlock();
private:
doc::Document m_document;
// The main sprite.
base::UniquePtr<Sprite> m_sprite;
// Undo and redo information about the document.
base::UniquePtr<DocumentUndo> m_undo;

View File

@ -217,7 +217,7 @@ namespace app {
{
ASSERT(m_document != NULL);
m_context->removeDocument(m_document);
m_document->close();
unlockWriter();
delete m_document;

View File

@ -23,8 +23,6 @@
#include "app/document_api.h"
#include "app/document.h"
#include "app/document_event.h"
#include "app/document_observer.h"
#include "app/document_undo.h"
#include "app/undoers/add_cel.h"
#include "app/undoers/add_frame.h"
@ -58,6 +56,8 @@
#include "app/undoers/set_sprite_transparent_color.h"
#include "app/undoers/set_total_frames.h"
#include "base/unique_ptr.h"
#include "doc/document_event.h"
#include "doc/document_observer.h"
#include "raster/algorithm/flip_image.h"
#include "raster/algorithm/shrink_bounds.h"
#include "raster/blend.h"
@ -72,6 +72,7 @@
#include "raster/sprite.h"
#include "raster/stock.h"
namespace app {
DocumentApi::DocumentApi(Document* document, undo::UndoersCollector* undoers)
@ -95,9 +96,9 @@ void DocumentApi::setSpriteSize(Sprite* sprite, int w, int h)
sprite->setSize(w, h);
DocumentEvent ev(m_document);
doc::DocumentEvent ev(m_document);
ev.sprite(sprite);
m_document->notifyObservers<DocumentEvent&>(&DocumentObserver::onSpriteSizeChanged, ev);
m_document->notifyObservers<doc::DocumentEvent&>(&doc::DocumentObserver::onSpriteSizeChanged, ev);
}
void DocumentApi::setSpriteTransparentColor(Sprite* sprite, color_t maskColor)
@ -107,9 +108,9 @@ void DocumentApi::setSpriteTransparentColor(Sprite* sprite, color_t maskColor)
sprite->setTransparentColor(maskColor);
DocumentEvent ev(m_document);
doc::DocumentEvent ev(m_document);
ev.sprite(sprite);
m_document->notifyObservers<DocumentEvent&>(&DocumentObserver::onSpriteTransparentColorChanged, ev);
m_document->notifyObservers<doc::DocumentEvent&>(&doc::DocumentObserver::onSpriteTransparentColorChanged, ev);
}
void DocumentApi::cropSprite(Sprite* sprite, const gfx::Rect& bounds, color_t bgcolor)
@ -246,10 +247,10 @@ void DocumentApi::copyFrame(Sprite* sprite, FrameNumber fromFrame, FrameNumber n
copyFrameForLayer(sprite->getFolder(), fromFrame, newFrame);
// Notify observers about the new frame.
DocumentEvent ev(m_document);
doc::DocumentEvent ev(m_document);
ev.sprite(sprite);
ev.frame(newFrame);
m_document->notifyObservers<DocumentEvent&>(&DocumentObserver::onAddFrame, ev);
m_document->notifyObservers<doc::DocumentEvent&>(&doc::DocumentObserver::onAddFrame, ev);
}
void DocumentApi::copyFrameForLayer(Layer* layer, FrameNumber fromFrame, FrameNumber frame)
@ -308,10 +309,10 @@ void DocumentApi::removeFrame(Sprite* sprite, FrameNumber frame)
sprite->removeFrame(frame);
// Notify observers.
DocumentEvent ev(m_document);
doc::DocumentEvent ev(m_document);
ev.sprite(sprite);
ev.frame(frame);
m_document->notifyObservers<DocumentEvent&>(&DocumentObserver::onRemoveFrame, ev);
m_document->notifyObservers<doc::DocumentEvent&>(&doc::DocumentObserver::onRemoveFrame, ev);
}
// Does the hard part of removing a frame: Removes all cels located in
@ -360,10 +361,10 @@ void DocumentApi::setTotalFrames(Sprite* sprite, FrameNumber frames)
sprite->setTotalFrames(frames);
// Notify observers.
DocumentEvent ev(m_document);
doc::DocumentEvent ev(m_document);
ev.sprite(sprite);
ev.frame(frames);
m_document->notifyObservers<DocumentEvent&>(&DocumentObserver::onTotalFramesChanged, ev);
m_document->notifyObservers<doc::DocumentEvent&>(&doc::DocumentObserver::onTotalFramesChanged, ev);
}
void DocumentApi::setFrameDuration(Sprite* sprite, FrameNumber frame, int msecs)
@ -377,10 +378,10 @@ void DocumentApi::setFrameDuration(Sprite* sprite, FrameNumber frame, int msecs)
sprite->setFrameDuration(frame, msecs);
// Notify observers.
DocumentEvent ev(m_document);
doc::DocumentEvent ev(m_document);
ev.sprite(sprite);
ev.frame(frame);
m_document->notifyObservers<DocumentEvent&>(&DocumentObserver::onFrameDurationChanged, ev);
m_document->notifyObservers<doc::DocumentEvent&>(&doc::DocumentObserver::onFrameDurationChanged, ev);
}
void DocumentApi::setFrameRangeDuration(Sprite* sprite, FrameNumber from, FrameNumber to, int msecs)
@ -499,11 +500,11 @@ void DocumentApi::addCel(LayerImage* layer, Cel* cel)
layer->addCel(cel);
DocumentEvent ev(m_document);
doc::DocumentEvent ev(m_document);
ev.sprite(layer->getSprite());
ev.layer(layer);
ev.cel(cel);
m_document->notifyObservers<DocumentEvent&>(&DocumentObserver::onAddCel, ev);
m_document->notifyObservers<doc::DocumentEvent&>(&doc::DocumentObserver::onAddCel, ev);
}
void DocumentApi::removeCel(LayerImage* layer, Cel* cel)
@ -513,11 +514,11 @@ void DocumentApi::removeCel(LayerImage* layer, Cel* cel)
Sprite* sprite = layer->getSprite();
DocumentEvent ev(m_document);
doc::DocumentEvent ev(m_document);
ev.sprite(sprite);
ev.layer(layer);
ev.cel(cel);
m_document->notifyObservers<DocumentEvent&>(&DocumentObserver::onRemoveCel, ev);
m_document->notifyObservers<doc::DocumentEvent&>(&doc::DocumentObserver::onRemoveCel, ev);
// Find if the image that use this cel we are going to remove, is
// used by other cels.
@ -549,12 +550,12 @@ void DocumentApi::setCelFramePosition(LayerImage* layer, Cel* cel, FrameNumber f
layer->moveCel(cel, frame);
DocumentEvent ev(m_document);
doc::DocumentEvent ev(m_document);
ev.sprite(layer->getSprite());
ev.layer(layer);
ev.cel(cel);
ev.frame(frame);
m_document->notifyObservers<DocumentEvent&>(&DocumentObserver::onCelFrameChanged, ev);
m_document->notifyObservers<doc::DocumentEvent&>(&doc::DocumentObserver::onCelFrameChanged, ev);
}
void DocumentApi::setCelPosition(Sprite* sprite, Cel* cel, int x, int y)
@ -566,10 +567,10 @@ void DocumentApi::setCelPosition(Sprite* sprite, Cel* cel, int x, int y)
cel->setPosition(x, y);
DocumentEvent ev(m_document);
doc::DocumentEvent ev(m_document);
ev.sprite(sprite);
ev.cel(cel);
m_document->notifyObservers<DocumentEvent&>(&DocumentObserver::onCelPositionChanged, ev);
m_document->notifyObservers<doc::DocumentEvent&>(&doc::DocumentObserver::onCelPositionChanged, ev);
}
void DocumentApi::setCelOpacity(Sprite* sprite, Cel* cel, int newOpacity)
@ -581,10 +582,10 @@ void DocumentApi::setCelOpacity(Sprite* sprite, Cel* cel, int newOpacity)
cel->setOpacity(newOpacity);
DocumentEvent ev(m_document);
doc::DocumentEvent ev(m_document);
ev.sprite(sprite);
ev.cel(cel);
m_document->notifyObservers<DocumentEvent&>(&DocumentObserver::onCelOpacityChanged, ev);
m_document->notifyObservers<doc::DocumentEvent&>(&doc::DocumentObserver::onCelOpacityChanged, ev);
}
void DocumentApi::cropCel(Sprite* sprite, Cel* cel, int x, int y, int w, int h, color_t bgcolor)
@ -761,10 +762,10 @@ void DocumentApi::addLayer(LayerFolder* folder, Layer* newLayer, Layer* afterThi
folder->stackLayer(newLayer, afterThis);
// Notify observers.
DocumentEvent ev(m_document);
doc::DocumentEvent ev(m_document);
ev.sprite(folder->getSprite());
ev.layer(newLayer);
m_document->notifyObservers<DocumentEvent&>(&DocumentObserver::onAddLayer, ev);
m_document->notifyObservers<doc::DocumentEvent&>(&doc::DocumentObserver::onAddLayer, ev);
}
void DocumentApi::removeLayer(Layer* layer)
@ -773,10 +774,10 @@ void DocumentApi::removeLayer(Layer* layer)
// Notify observers that a layer will be removed (e.g. an Editor can
// select another layer if the removed layer is the active one).
DocumentEvent ev(m_document);
doc::DocumentEvent ev(m_document);
ev.sprite(layer->getSprite());
ev.layer(layer);
m_document->notifyObservers<DocumentEvent&>(&DocumentObserver::onBeforeRemoveLayer, ev);
m_document->notifyObservers<doc::DocumentEvent&>(&doc::DocumentObserver::onBeforeRemoveLayer, ev);
// Add undoers.
if (undoEnabled())
@ -785,7 +786,7 @@ void DocumentApi::removeLayer(Layer* layer)
// Do the action.
layer->getParent()->removeLayer(layer);
m_document->notifyObservers<DocumentEvent&>(&DocumentObserver::onAfterRemoveLayer, ev);
m_document->notifyObservers<doc::DocumentEvent&>(&doc::DocumentObserver::onAfterRemoveLayer, ev);
delete layer;
}
@ -810,10 +811,10 @@ void DocumentApi::restackLayerAfter(Layer* layer, Layer* afterThis)
layer->getParent()->stackLayer(layer, afterThis);
DocumentEvent ev(m_document);
doc::DocumentEvent ev(m_document);
ev.sprite(layer->getSprite());
ev.layer(layer);
m_document->notifyObservers<DocumentEvent&>(&DocumentObserver::onLayerRestacked, ev);
m_document->notifyObservers<doc::DocumentEvent&>(&doc::DocumentObserver::onLayerRestacked, ev);
}
void DocumentApi::cropLayer(Layer* layer, int x, int y, int w, int h, color_t bgcolor)

View File

@ -166,7 +166,7 @@ void DocumentExporter::exportSheet()
base::UniquePtr<Document> textureDocument(
createEmptyTexture(samples));
Sprite* texture = textureDocument->getSprite();
Sprite* texture = textureDocument->sprite();
Image* textureImage = texture->getStock()->getImage(
static_cast<LayerImage*>(texture->getFolder()->getFirstLayer())
->getCel(FrameNumber(0))->getImage());
@ -191,11 +191,11 @@ void DocumentExporter::captureSamples(Samples& samples)
it = m_documents.begin(),
end = m_documents.end(); it != end; ++it) {
Document* document = *it;
Sprite* sprite = document->getSprite();
Sprite* sprite = document->sprite();
for (FrameNumber frame=FrameNumber(0);
frame<sprite->getTotalFrames(); ++frame) {
std::string filename = document->getFilename();
std::string filename = document->filename();
if (sprite->getTotalFrames() > FrameNumber(1)) {
int frameNumWidth =
@ -246,11 +246,14 @@ Document* DocumentExporter::createEmptyTexture(const Samples& samples)
fullTextureBounds = fullTextureBounds.createUnion(it->inTextureBounds());
}
base::UniquePtr<Document> document(Document::createBasicDocument(pixelFormat,
fullTextureBounds.w, fullTextureBounds.h, maxColors));
base::UniquePtr<Sprite> sprite(Sprite::createBasicSprite(
pixelFormat, fullTextureBounds.w, fullTextureBounds.h, maxColors));
if (palette != NULL)
document->getSprite()->setPalette(palette, false);
sprite->setPalette(palette, false);
base::UniquePtr<Document> document(new Document(sprite));
sprite.release();
return document.release();
}

View File

@ -1,31 +0,0 @@
/* Aseprite
* Copyright (C) 2001-2013 David Capello
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef APP_DOCUMENT_ID_H_INCLUDED
#define APP_DOCUMENT_ID_H_INCLUDED
#pragma once
#include "doc/object_id.h"
namespace app {
typedef doc::ObjectId DocumentId;
}
#endif

View File

@ -1,88 +0,0 @@
/* Aseprite
* Copyright (C) 2001-2013 David Capello
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "app/documents.h"
#include "app/document.h"
#include "base/mutex.h"
#include "raster/sprite.h"
#include "undo/undo_history.h"
#include <algorithm>
namespace app {
Documents::Documents()
{
m_idCounter = 0;
}
Documents::~Documents()
{
deleteAll();
}
void Documents::addDocument(Document* document)
{
ASSERT(document != NULL);
ASSERT(document->getId() == doc::NullId);
m_documents.insert(begin(), document);
document->setId(++m_idCounter);
}
void Documents::removeDocument(Document* document)
{
iterator it = std::find(begin(), end(), document);
ASSERT(it != end());
if (it != end())
m_documents.erase(it);
}
void Documents::moveDocument(Document* document, int index)
{
removeDocument(document);
m_documents.insert(begin()+index, document);
}
void Documents::deleteAll()
{
for (iterator it = begin(), end = this->end(); it != end; ++it) {
Document* document = *it;
delete document;
}
m_documents.clear();
}
Document* Documents::getById(DocumentId id) const
{
for (const_iterator it = begin(), end = this->end(); it != end; ++it) {
if ((*it)->getId() == id)
return *it;
}
return NULL;
}
} // namespace app

View File

@ -1,78 +0,0 @@
/* Aseprite
* Copyright (C) 2001-2013 David Capello
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef APP_DOCUMENTS_H_INCLUDED
#define APP_DOCUMENTS_H_INCLUDED
#pragma once
#include "base/disable_copying.h"
#include "app/document_id.h"
#include <vector>
namespace app {
class Document;
class Documents {
public:
typedef std::vector<Document*>::iterator iterator;
typedef std::vector<Document*>::const_iterator const_iterator;
Documents();
~Documents();
iterator begin() { return m_documents.begin(); }
iterator end() { return m_documents.end(); }
const_iterator begin() const { return m_documents.begin(); }
const_iterator end() const { return m_documents.end(); }
Document* front() const { return m_documents.front(); }
Document* back() const { return m_documents.back(); }
int size() const { return m_documents.size(); }
bool empty() const { return m_documents.empty(); }
// Adds a new document to the list. If the destructor is called the
// document is deleted automatically.
void addDocument(Document* document);
// Removes a document from the list without deleting it. You must to
// delete the document after removing it.
void removeDocument(Document* document);
// Moves the document to the given location in the same
// list. E.g. It is used to reorder documents when they are selected
// as active.
void moveDocument(Document* document, int index);
Document* getByIndex(int index) const { return m_documents[index]; }
Document* getById(DocumentId id) const;
private:
// Deletes all documents in the list (calling "delete" operation).
void deleteAll();
std::vector<Document*> m_documents;
DocumentId m_idCounter;
DISABLE_COPYING(Documents);
};
} // namespace app
#endif

View File

@ -164,13 +164,9 @@ bool AseFormat::onLoad(FileOp* fop)
}
// Create the new sprite
Sprite* sprite = new Sprite(header.depth == 32 ? IMAGE_RGB:
header.depth == 16 ? IMAGE_GRAYSCALE: IMAGE_INDEXED,
header.width, header.height, header.ncolors);
if (!sprite) {
fop_error(fop, "Error creating sprite with file spec\n");
return false;
}
UniquePtr<Sprite> sprite(new Sprite(header.depth == 32 ? IMAGE_RGB:
header.depth == 16 ? IMAGE_GRAYSCALE: IMAGE_INDEXED,
header.width, header.height, header.ncolors));
// Set frames and speed
sprite->setTotalFrames(FrameNumber(header.frames));
@ -290,7 +286,8 @@ bool AseFormat::onLoad(FileOp* fop)
break;
}
fop->document = new Document(sprite);
fop->createDocument(sprite);
sprite.release();
if (ferror(f)) {
fop_error(fop, "Error reading file.\n");
@ -304,7 +301,7 @@ bool AseFormat::onLoad(FileOp* fop)
#ifdef ENABLE_SAVE
bool AseFormat::onSave(FileOp* fop)
{
Sprite* sprite = fop->document->getSprite();
Sprite* sprite = fop->document->sprite();
FileHandle f(open_file_with_exception(fop->filename, "wb"));
// Write the header

View File

@ -1,5 +1,5 @@
/* Aseprite
* Copyright (C) 2001-2013 David Capello
* Copyright (C) 2001-2014 David Capello
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -113,13 +113,18 @@ Document* load_document(Context* context, const char* filename)
document = fop->document;
fop_free(fop);
if (context)
document->setContext(context);
return document;
}
int save_document(Context* context, Document* document)
int save_document(Context* context, doc::Document* document)
{
ASSERT(dynamic_cast<app::Document*>(document));
int ret;
FileOp* fop = fop_to_save_document(context, document);
FileOp* fop = fop_to_save_document(context, static_cast<app::Document*>(document));
if (!fop)
return -1;
@ -199,7 +204,7 @@ FileOp* fop_to_load_document(Context* context, const char* filename, int flags)
}
/* TODO add a better dialog to edit file-names */
if ((flags & FILE_LOAD_SEQUENCE_ASK) && context->isUiAvailable()) {
if ((flags & FILE_LOAD_SEQUENCE_ASK) && context && context->isUiAvailable()) {
/* really want load all files? */
if ((fop->seq.filename_list.size() > 1) &&
(ui::Alert::show("Notice"
@ -243,16 +248,15 @@ FileOp* fop_to_save_document(Context* context, Document* document)
fop->document = document;
// Get the extension of the filename (in lower case)
std::string extension = base::string_to_lower(base::get_file_extension(fop->document->getFilename()));
std::string extension = base::string_to_lower(base::get_file_extension(fop->document->filename()));
PRINTF("Saving document \"%s\" (%s)\n",
fop->document->getFilename().c_str(), extension.c_str());
PRINTF("Saving document \"%s\" (%s)\n", fop->document->filename().c_str(), extension.c_str());
/* get the format through the extension of the filename */
fop->format = get_fileformat(extension.c_str());
if (!fop->format ||
!fop->format->support(FILE_SUPPORT_SAVE)) {
fop_error(fop, "ASEPRITE can't save \"%s\" files\n", extension.c_str());
fop_error(fop, "ASEPRITE can't save \"%s\" files\n", extension.c_str());
return fop;
}
@ -261,7 +265,7 @@ FileOp* fop_to_save_document(Context* context, Document* document)
fatal = false;
/* check image type support */
switch (fop->document->getSprite()->getPixelFormat()) {
switch (fop->document->sprite()->getPixelFormat()) {
case IMAGE_RGB:
if (!(fop->format->support(FILE_SUPPORT_RGB))) {
@ -270,7 +274,7 @@ FileOp* fop_to_save_document(Context* context, Document* document)
}
if (!(fop->format->support(FILE_SUPPORT_RGBA)) &&
fop->document->getSprite()->needAlpha()) {
fop->document->sprite()->needAlpha()) {
warnings += "<<- Alpha channel";
}
@ -282,7 +286,7 @@ FileOp* fop_to_save_document(Context* context, Document* document)
fatal = true;
}
if (!(fop->format->support(FILE_SUPPORT_GRAYA)) &&
fop->document->getSprite()->needAlpha()) {
fop->document->sprite()->needAlpha()) {
warnings += "<<- Alpha channel";
}
@ -297,7 +301,7 @@ FileOp* fop_to_save_document(Context* context, Document* document)
}
// check frames support
if (fop->document->getSprite()->getTotalFrames() > 1) {
if (fop->document->sprite()->getTotalFrames() > 1) {
if (!fop->format->support(FILE_SUPPORT_FRAMES) &&
!fop->format->support(FILE_SUPPORT_SEQUENCES)) {
warnings += "<<- Frames";
@ -305,14 +309,14 @@ FileOp* fop_to_save_document(Context* context, Document* document)
}
// layers support
if (fop->document->getSprite()->getFolder()->getLayersCount() > 1) {
if (fop->document->sprite()->getFolder()->getLayersCount() > 1) {
if (!(fop->format->support(FILE_SUPPORT_LAYERS))) {
warnings += "<<- Layers";
}
}
// Palettes support.
if (fop->document->getSprite()->getPalettes().size() > 1) {
if (fop->document->sprite()->getPalettes().size() > 1) {
if (!fop->format->support(FILE_SUPPORT_PALETTES) &&
!fop->format->support(FILE_SUPPORT_SEQUENCES)) {
warnings += "<<- Palette changes between frames";
@ -322,7 +326,7 @@ FileOp* fop_to_save_document(Context* context, Document* document)
// Show the confirmation alert
if (!warnings.empty()) {
// Interative
if (context->isUiAvailable()) {
if (context && context->isUiAvailable()) {
int ret;
if (fatal)
@ -354,24 +358,24 @@ FileOp* fop_to_save_document(Context* context, Document* document)
fop_prepare_for_sequence(fop);
// To save one frame
if (fop->document->getSprite()->getTotalFrames() == 1) {
fop->seq.filename_list.push_back(fop->document->getFilename());
if (fop->document->sprite()->getTotalFrames() == 1) {
fop->seq.filename_list.push_back(fop->document->filename());
}
// To save more frames
else {
char left[256], right[256];
int width, start_from;
start_from = split_filename(fop->document->getFilename().c_str(), left, right, &width);
start_from = split_filename(fop->document->filename().c_str(), left, right, &width);
if (start_from < 0) {
start_from = 0;
width =
(fop->document->getSprite()->getTotalFrames() < 10)? 1:
(fop->document->getSprite()->getTotalFrames() < 100)? 2:
(fop->document->getSprite()->getTotalFrames() < 1000)? 3: 4;
(fop->document->sprite()->getTotalFrames() < 10)? 1:
(fop->document->sprite()->getTotalFrames() < 100)? 2:
(fop->document->sprite()->getTotalFrames() < 1000)? 3: 4;
}
for (FrameNumber frame(0); frame<fop->document->getSprite()->getTotalFrames(); ++frame) {
for (FrameNumber frame(0); frame<fop->document->sprite()->getTotalFrames(); ++frame) {
// Get the name for this frame
char buf[4096];
sprintf(buf, "%s%0*d%s", left, width, start_from+frame, right);
@ -380,7 +384,7 @@ FileOp* fop_to_save_document(Context* context, Document* document)
}
}
else
fop->filename = fop->document->getFilename();
fop->filename = fop->document->filename();
// Configure output format?
if (fop->format->support(FILE_SUPPORT_GET_FORMAT_OPTIONS)) {
@ -430,16 +434,16 @@ void fop_operate(FileOp *fop, IFileOpProgress* progress)
#define SEQUENCE_IMAGE() \
do { \
image_index = fop->document \
->getSprite() \
->sprite() \
->getStock()->addImage(fop->seq.image); \
\
fop->seq.last_cel->setImage(image_index); \
fop->seq.layer->addCel(fop->seq.last_cel); \
\
if (fop->document->getSprite()->getPalette(frame) \
if (fop->document->sprite()->getPalette(frame) \
->countDiff(fop->seq.palette, NULL, NULL) > 0) { \
fop->seq.palette->setFrame(frame); \
fop->document->getSprite()->setPalette(fop->seq.palette, true); \
fop->document->sprite()->setPalette(fop->seq.palette, true); \
} \
\
old_image = fop->seq.image; \
@ -526,7 +530,7 @@ void fop_operate(FileOp *fop, IFileOpProgress* progress)
fop->seq.layer->configureAsBackground();
// Set the frames range
fop->document->getSprite()->setTotalFrames(frame);
fop->document->sprite()->setTotalFrames(frame);
// Sets special options from the specific format (e.g. BMP
// file can contain the number of bits per pixel).
@ -550,7 +554,7 @@ void fop_operate(FileOp *fop, IFileOpProgress* progress)
if (fop->is_sequence()) {
ASSERT(fop->format->support(FILE_SUPPORT_SEQUENCES));
Sprite* sprite = fop->document->getSprite();
Sprite* sprite = fop->document->sprite();
// Create a temporary bitmap
fop->seq.image = Image::create(sprite->getPixelFormat(),
@ -631,6 +635,14 @@ FileOp::~FileOp()
delete this->mutex;
}
void FileOp::createDocument(Sprite* spr)
{
// spr can be NULL if the sprite is set in onPostLoad() then
ASSERT(this->document == NULL);
this->document = new Document(spr);
}
void fop_free(FileOp *fop)
{
delete fop;
@ -656,18 +668,18 @@ void fop_post_load(FileOp* fop)
return;
}
if (fop->document->getSprite() != NULL) {
if (fop->document->sprite() != NULL) {
// Creates a suitable palette for RGB images
if (fop->document->getSprite()->getPixelFormat() == IMAGE_RGB &&
fop->document->getSprite()->getPalettes().size() <= 1 &&
fop->document->getSprite()->getPalette(FrameNumber(0))->isBlack()) {
if (fop->document->sprite()->getPixelFormat() == IMAGE_RGB &&
fop->document->sprite()->getPalettes().size() <= 1 &&
fop->document->sprite()->getPalette(FrameNumber(0))->isBlack()) {
SharedPtr<Palette> palette
(quantization::create_palette_from_rgb(
fop->document->getSprite(),
fop->document->sprite(),
FrameNumber(0), NULL));
fop->document->getSprite()->resetPalettes();
fop->document->getSprite()->setPalette(palette, false);
fop->document->sprite()->resetPalettes();
fop->document->sprite()->setPalette(palette, false);
}
}
@ -708,7 +720,7 @@ Image* fop_sequence_image(FileOp* fop, PixelFormat pixelFormat, int w, int h)
sprite->getFolder()->addLayer(layer);
// Done
fop->document = new Document(sprite);
fop->createDocument(sprite);
fop->seq.layer = layer;
}
catch (...) {
@ -717,7 +729,7 @@ Image* fop_sequence_image(FileOp* fop, PixelFormat pixelFormat, int w, int h)
}
}
else {
sprite = fop->document->getSprite();
sprite = fop->document->sprite();
if (sprite->getPixelFormat() != pixelFormat)
return NULL;

View File

@ -1,5 +1,5 @@
/* Aseprite
* Copyright (C) 2001-2013 David Capello
* Copyright (C) 2001-2014 David Capello
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -37,12 +37,17 @@ namespace base {
class mutex;
}
namespace doc {
class Document;
}
namespace raster {
class Cel;
class Image;
class Layer;
class LayerImage;
class Palette;
class Sprite;
}
namespace app {
@ -112,6 +117,7 @@ namespace app {
return !this->seq.filename_list.empty();
}
void createDocument(Sprite* spr);
};
// Available extensions for each load/save operation.
@ -121,8 +127,8 @@ namespace app {
// High-level routines to load/save documents.
Document* load_document(Context* context, const char* filename);
int save_document(Context* context, Document* document);
app::Document* load_document(Context* context, const char* filename);
int save_document(Context* context, doc::Document* document);
// Low-level routines to load/save documents.

View File

@ -38,7 +38,7 @@ TEST(File, SeveralSizes)
// Register all possible image formats.
FileFormatsManager::instance().registerAllFormats();
std::vector<char> fn(256);
app::Context context;
app::Context ctx;
for (int w=10; w<=10+503*2; w+=503) {
for (int h=10; h<=10+503*2; h+=503) {
@ -46,13 +46,13 @@ TEST(File, SeveralSizes)
std::sprintf(&fn[0], "test.ase");
{
base::UniquePtr<Document> doc(Document::createBasicDocument(IMAGE_INDEXED, w, h, 256));
base::UniquePtr<Document> doc(ctx.documents().add(w, h, doc::ColorMode_INDEXED, 256));
doc->setFilename(&fn[0]);
// Random pixels
LayerImage* layer = dynamic_cast<LayerImage*>(doc->getSprite()->getFolder()->getFirstLayer());
LayerImage* layer = dynamic_cast<LayerImage*>(doc->sprite()->getFolder()->getFirstLayer());
ASSERT_TRUE(layer != NULL);
Image* image = doc->getSprite()->getStock()->getImage(layer->getCel(FrameNumber(0))->getImage());
Image* image = doc->sprite()->getStock()->getImage(layer->getCel(FrameNumber(0))->getImage());
std::srand(w*h);
int c = std::rand()%256;
for (int y=0; y<h; y++) {
@ -63,18 +63,18 @@ TEST(File, SeveralSizes)
}
}
save_document(&context, doc);
save_document(&ctx, doc);
}
{
base::UniquePtr<Document> doc(load_document(&context, &fn[0]));
ASSERT_EQ(w, doc->getSprite()->getWidth());
ASSERT_EQ(h, doc->getSprite()->getHeight());
base::UniquePtr<Document> doc(load_document(&ctx, &fn[0]));
ASSERT_EQ(w, doc->sprite()->getWidth());
ASSERT_EQ(h, doc->sprite()->getHeight());
// Same random pixels (see the seed)
LayerImage* layer = dynamic_cast<LayerImage*>(doc->getSprite()->getFolder()->getFirstLayer());
LayerImage* layer = dynamic_cast<LayerImage*>(doc->sprite()->getFolder()->getFirstLayer());
ASSERT_TRUE(layer != NULL);
Image* image = doc->getSprite()->getStock()->getImage(layer->getCel(FrameNumber(0))->getImage());
Image* image = doc->sprite()->getStock()->getImage(layer->getCel(FrameNumber(0))->getImage());
std::srand(w*h);
int c = std::rand()%256;
for (int y=0; y<h; y++) {

View File

@ -177,14 +177,14 @@ bool FliFormat::onLoad(FileOp* fop)
// Update number of frames
sprite->setTotalFrames(frpos_out.next());
fop->document = new Document(sprite);
fop->createDocument(sprite);
return true;
}
#ifdef ENABLE_SAVE
bool FliFormat::onSave(FileOp* fop)
{
Sprite* sprite = fop->document->getSprite();
Sprite* sprite = fop->document->sprite();
unsigned char cmap[768];
unsigned char omap[768];
s_fli_header fli_header;

View File

@ -312,7 +312,7 @@ bool GifFormat::onLoad(FileOp* fop)
break;
} while (record_type != TERMINATE_RECORD_TYPE);
fop->document = new Document(NULL);
fop->createDocument(NULL); // The sprite is set in onPostLoad()
return true;
}
@ -371,7 +371,7 @@ bool GifFormat::onPostLoad(FileOp* fop)
"<<" PACKAGE " cannot handle this kind of GIF correctly in Indexed format."
"<<What would you like to do?"
"||Convert to &RGBA||Keep &Indexed||&Cancel",
fop->document->getFilename().c_str());
fop->document->name().c_str());
if (result == 1)
pixelFormat = IMAGE_RGB;
@ -507,7 +507,7 @@ bool GifFormat::onPostLoad(FileOp* fop)
copy_image(previous_image, current_image, 0, 0);
}
fop->document->addSprite(sprite);
fop->document->sprites().add(sprite);
sprite.release(); // Now the sprite is owned by fop->document
return true;
@ -539,7 +539,7 @@ bool GifFormat::onSave(FileOp* fop)
throw Exception("Error creating GIF file.\n");
SharedPtr<GifOptions> gif_options = fop->seq.format_options;
Sprite* sprite = fop->document->getSprite();
Sprite* sprite = fop->document->sprite();
int sprite_w = sprite->getWidth();
int sprite_h = sprite->getHeight();
PixelFormat sprite_format = sprite->getPixelFormat();
@ -785,7 +785,7 @@ SharedPtr<FormatOptions> GifFormat::onGetFormatOptions(FileOp* fop)
gif_options.reset(new GifOptions);
// Non-interactive mode
if (!fop->context->isUiAvailable())
if (!fop->context || !fop->context->isUiAvailable())
return gif_options;
try {
@ -797,7 +797,7 @@ SharedPtr<FormatOptions> GifFormat::onGetFormatOptions(FileOp* fop)
// Load the window to ask to the user the GIF options he wants.
app::gen::GifOptions win;
win.rgbOptions()->setVisible(fop->document->getSprite()->getPixelFormat() != IMAGE_INDEXED);
win.rgbOptions()->setVisible(fop->document->sprite()->getPixelFormat() != IMAGE_INDEXED);
switch (gif_options->quantize()) {
case GifOptions::NoQuantize: win.noQuantize()->setSelected(true); break;

View File

@ -23,6 +23,7 @@
#include "app/file/file.h"
#include "app/file/file_formats_manager.h"
#include "app/file/gif_options.h"
#include "app/test_context.h"
#include "raster/raster.h"
#include "she/scoped_handle.h"
#include "she/system.h"
@ -38,7 +39,7 @@ public:
}
protected:
app::Context m_context;
app::TestContext m_ctx;
she::ScopedHandle<she::System> m_system;
};
@ -47,8 +48,8 @@ TEST_F(GifFormat, Dimensions)
const char* fn = "test.gif";
{
DocumentPtr doc(Document::createBasicDocument(IMAGE_INDEXED, 31, 29, 14));
Sprite* sprite = doc->getSprite();
doc::Document* doc = m_ctx.documents().add(31, 29, doc::ColorMode_INDEXED, 14);
Sprite* sprite = doc->sprite();
doc->setFilename(fn);
sprite->setTransparentColor(3);
@ -56,14 +57,14 @@ TEST_F(GifFormat, Dimensions)
ASSERT_NE((LayerImage*)NULL, layer);
Image* image = sprite->getStock()->getImage(layer->getCel(FrameNumber(0))->getImage());
clear_image(image, doc->getSprite()->getTransparentColor());
clear_image(image, doc->sprite()->getTransparentColor());
save_document(&m_context, doc);
save_document(&m_ctx, doc);
}
{
DocumentPtr doc(load_document(&m_context, fn));
Sprite* sprite = doc->getSprite();
Document* doc = load_document(&m_ctx, fn);
Sprite* sprite = doc->sprite();
EXPECT_EQ(31, sprite->getWidth());
EXPECT_EQ(29, sprite->getHeight());
@ -79,8 +80,8 @@ TEST_F(GifFormat, OpaqueIndexed)
const char* fn = "test.gif";
{
DocumentPtr doc(Document::createBasicDocument(IMAGE_INDEXED, 2, 2, 4));
Sprite* sprite = doc->getSprite();
doc::Document* doc = m_ctx.documents().add(2, 2, doc::ColorMode_INDEXED, 4);
Sprite* sprite = doc->sprite();
doc->setFilename(fn);
Palette* pal = sprite->getPalette(FrameNumber(0));
@ -99,12 +100,12 @@ TEST_F(GifFormat, OpaqueIndexed)
image->putPixel(1, 0, 2);
image->putPixel(1, 1, 3);
save_document(&m_context, doc);
save_document(&m_ctx, doc);
}
{
DocumentPtr doc(load_document(&m_context, fn));
Sprite* sprite = doc->getSprite();
Document* doc = load_document(&m_ctx, fn);
Sprite* sprite = doc->sprite();
LayerImage* layer = dynamic_cast<LayerImage*>(sprite->getFolder()->getFirstLayer());
ASSERT_NE((LayerImage*)NULL, layer);
@ -130,8 +131,8 @@ TEST_F(GifFormat, TransparentIndexed)
const char* fn = "test.gif";
{
DocumentPtr doc(Document::createBasicDocument(IMAGE_INDEXED, 2, 2, 4));
Sprite* sprite = doc->getSprite();
doc::Document* doc = m_ctx.documents().add(2, 2, doc::ColorMode_INDEXED, 4);
Sprite* sprite = doc->sprite();
doc->setFilename(fn);
Palette* pal = sprite->getPalette(FrameNumber(0));
@ -149,12 +150,12 @@ TEST_F(GifFormat, TransparentIndexed)
image->putPixel(1, 0, 2);
image->putPixel(1, 1, 3);
save_document(&m_context, doc);
save_document(&m_ctx, doc);
}
{
DocumentPtr doc(load_document(&m_context, fn));
Sprite* sprite = doc->getSprite();
Document* doc = load_document(&m_ctx, fn);
Sprite* sprite = doc->sprite();
LayerImage* layer = dynamic_cast<LayerImage*>(sprite->getFolder()->getFirstLayer());
ASSERT_NE((LayerImage*)NULL, layer);
@ -180,8 +181,8 @@ TEST_F(GifFormat, TransparentRgbQuantization)
const char* fn = "test.gif";
{
DocumentPtr doc(Document::createBasicDocument(IMAGE_RGB, 2, 2, 256));
Sprite* sprite = doc->getSprite();
doc::Document* doc = m_ctx.documents().add(2, 2, doc::ColorMode_RGB, 256);
Sprite* sprite = doc->sprite();
doc->setFilename(fn);
LayerImage* layer = dynamic_cast<LayerImage*>(sprite->getFolder()->getFirstLayer());
@ -193,12 +194,12 @@ TEST_F(GifFormat, TransparentRgbQuantization)
image->putPixel(1, 0, rgb(0, 255, 0));
image->putPixel(1, 1, rgb(0, 0, 255));
save_document(&m_context, doc);
save_document(&m_ctx, doc);
}
{
DocumentPtr doc(load_document(&m_context, fn));
Sprite* sprite = doc->getSprite();
Document* doc = load_document(&m_ctx, fn);
Sprite* sprite = doc->sprite();
LayerImage* layer = dynamic_cast<LayerImage*>(sprite->getFolder()->getFirstLayer());
ASSERT_NE((LayerImage*)NULL, layer);
@ -218,8 +219,8 @@ TEST_F(GifFormat, OpaqueRgbQuantization)
const char* fn = "test.gif";
{
DocumentPtr doc(Document::createBasicDocument(IMAGE_RGB, 2, 2, 256));
Sprite* sprite = doc->getSprite();
doc::Document* doc = m_ctx.documents().add(2, 2, doc::ColorMode_RGB, 256);
Sprite* sprite = doc->sprite();
doc->setFilename(fn);
LayerImage* layer = dynamic_cast<LayerImage*>(sprite->getFolder()->getFirstLayer());
@ -233,12 +234,12 @@ TEST_F(GifFormat, OpaqueRgbQuantization)
image->putPixel(1, 0, rgb(0, 255, 0));
image->putPixel(1, 1, rgb(0, 0, 255));
save_document(&m_context, doc);
save_document(&m_ctx, doc);
}
{
DocumentPtr doc(load_document(&m_context, fn));
Sprite* sprite = doc->getSprite();
Document* doc = load_document(&m_ctx, fn);
Sprite* sprite = doc->sprite();
LayerImage* layer = dynamic_cast<LayerImage*>(sprite->getFolder()->getFirstLayer());
ASSERT_NE((LayerImage*)NULL, layer);
@ -260,8 +261,8 @@ TEST_F(GifFormat, OpaqueRgbQuantizationTwoLayers)
const char* fn = "test.gif";
{
DocumentPtr doc(Document::createBasicDocument(IMAGE_RGB, 2, 2, 256));
Sprite* sprite = doc->getSprite();
Document* doc(static_cast<Document*>(m_ctx.documents().add(2, 2, doc::ColorMode_RGB, 256)));
Sprite* sprite = doc->sprite();
doc->setFilename(fn);
LayerImage* layer1 = dynamic_cast<LayerImage*>(sprite->getFolder()->getFirstLayer());
@ -286,12 +287,12 @@ TEST_F(GifFormat, OpaqueRgbQuantizationTwoLayers)
// Do not modify palettes
doc->setFormatOptions(SharedPtr<FormatOptions>(new GifOptions(GifOptions::NoQuantize)));
save_document(&m_context, doc);
save_document(&m_ctx, doc);
}
{
DocumentPtr doc(load_document(&m_context, fn));
Sprite* sprite = doc->getSprite();
DocumentPtr doc(load_document(&m_ctx, fn));
Sprite* sprite = doc->sprite();
LayerImage* layer = dynamic_cast<LayerImage*>(sprite->getFolder()->getFirstLayer());
ASSERT_NE((LayerImage*)NULL, layer);

View File

@ -232,14 +232,14 @@ bool IcoFormat::onLoad(FileOp* fop)
}
}
fop->document = new Document(sprite);
fop->createDocument(sprite);
return true;
}
#ifdef ENABLE_SAVE
bool IcoFormat::onSave(FileOp* fop)
{
Sprite* sprite = fop->document->getSprite();
Sprite* sprite = fop->document->sprite();
int bpp, bw, bitsw;
int size, offset, i;
int c, x, y, b, m, v;

View File

@ -368,7 +368,7 @@ SharedPtr<FormatOptions> JpegFormat::onGetFormatOptions(FileOp* fop)
jpeg_options.reset(new JpegOptions);
// Non-interactive mode
if (!fop->context->isUiAvailable())
if (!fop->context || !fop->context->isUiAvailable())
return jpeg_options;
try {

View File

@ -232,10 +232,10 @@ bool PngFormat::onLoad(FileOp* fop)
// Set the transparent color to the first transparent entry found
if (mask_entry >= 0)
fop->document->getSprite()->setTransparentColor(mask_entry);
fop->document->sprite()->setTransparentColor(mask_entry);
}
mask_entry = fop->document->getSprite()->getTransparentColor();
mask_entry = fop->document->sprite()->getTransparentColor();
/* Allocate the memory to hold the image using the fields of info_ptr. */
@ -388,12 +388,12 @@ bool PngFormat::onSave(FileOp* fop)
switch (image->getPixelFormat()) {
case IMAGE_RGB:
color_type = fop->document->getSprite()->needAlpha() ?
color_type = fop->document->sprite()->needAlpha() ?
PNG_COLOR_TYPE_RGB_ALPHA:
PNG_COLOR_TYPE_RGB;
break;
case IMAGE_GRAYSCALE:
color_type = fop->document->getSprite()->needAlpha() ?
color_type = fop->document->sprite()->needAlpha() ?
PNG_COLOR_TYPE_GRAY_ALPHA:
PNG_COLOR_TYPE_GRAY;
break;
@ -426,8 +426,8 @@ bool PngFormat::onSave(FileOp* fop)
// If the sprite does not have a background layer, we include the
// alpha information of palette entries to indicate which is the
// transparent color.
if (fop->document->getSprite()->getBackgroundLayer() == NULL) {
int mask_entry = fop->document->getSprite()->getTransparentColor();
if (fop->document->sprite()->getBackgroundLayer() == NULL) {
int mask_entry = fop->document->sprite()->getTransparentColor();
int num_trans = mask_entry+1;
png_bytep trans = (png_bytep)png_malloc(png_ptr, num_trans);

View File

@ -791,7 +791,7 @@ bool CustomizedGuiManager::onProcessMessage(Message* msg)
switch (shortcut->type) {
case Shortcut_ChangeTool: {
tools::Tool* current_tool = UIContext::instance()->getSettings()->getCurrentTool();
tools::Tool* current_tool = UIContext::instance()->settings()->getCurrentTool();
tools::Tool* select_this_tool = shortcut->tool;
tools::ToolBox* toolbox = App::instance()->getToolBox();
std::vector<tools::Tool*> possibles;

View File

@ -1,5 +1,5 @@
/* Aseprite
* Copyright (C) 2001-2013 David Capello
* Copyright (C) 2001-2014 David Capello
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -16,25 +16,32 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef APP_CONTEXT_OBSERVER_H_INCLUDED
#define APP_CONTEXT_OBSERVER_H_INCLUDED
#ifndef APP_TEST_CONTEXT_H_INCLUDED
#define APP_TEST_CONTEXT_H_INCLUDED
#pragma once
#include "app/document_location.h"
#include "raster/layer.h"
namespace app {
class Context;
class Document;
class TestContext : public app::Context {
public:
TestContext() : app::Context(NULL) {
}
// Observer of context events. The default implementation does nothing
// in each handler, so you can override the required events.
class ContextObserver {
public:
virtual ~ContextObserver() { }
virtual void onCommandBeforeExecution(Context* context) { }
virtual void onCommandAfterExecution(Context* context) { }
virtual void onAddDocument(Context* context, Document* document) { }
virtual void onRemoveDocument(Context* context, Document* document) { }
};
protected:
void onGetActiveLocation(DocumentLocation* location) const OVERRIDE {
Document* doc = activeDocument();
if (!doc)
return;
location->document(doc);
location->sprite(doc->sprite());
location->layer(doc->sprite()->getFolder()->getFirstLayer());
location->frame(FrameNumber(0));
}
};
} // namespace app

View File

@ -23,7 +23,6 @@
#include "app/thumbnail_generator.h"
#include "app/app.h"
#include "app/context.h"
#include "app/document.h"
#include "app/file/file.h"
#include "app/file_system.h"
@ -73,8 +72,9 @@ private:
fop_post_load(m_fop);
// Convert the loaded document into the she::Surface.
const Sprite* sprite = (m_fop->document && m_fop->document->getSprite()) ? m_fop->document->getSprite():
NULL;
const Sprite* sprite = (m_fop->document && m_fop->document->sprite()) ?
m_fop->document->sprite(): NULL;
if (!fop_is_stop(m_fop) && sprite) {
// The palette to convert the Image
m_palette.reset(new Palette(*sprite->getPalette(FrameNumber(0))));
@ -103,6 +103,7 @@ private:
image_scale(m_thumbnail, image, 0, 0, thumb_w, thumb_h);
}
// Close file
delete m_fop->document;
// Set the thumbnail of the file-item.
@ -191,8 +192,7 @@ void ThumbnailGenerator::addWorkerToGenerateThumbnail(IFileItem* fileitem)
getWorkerStatus(fileitem, progress) != WithoutWorker)
return;
Context tmpContext;
FileOp* fop = fop_to_load_document(&tmpContext,
FileOp* fop = fop_to_load_document(NULL,
fileitem->getFileName().c_str(),
FILE_LOAD_SEQUENCE_NONE |
FILE_LOAD_ONE_FRAME);

View File

@ -58,8 +58,8 @@ public:
case WithBg:
{
int color = color_utils::color_for_layer(m_type == WithFg ?
loop->getSettings()->getFgColor():
loop->getSettings()->getBgColor(),
loop->settings()->getFgColor():
loop->settings()->getBgColor(),
loop->getLayer());
loop->setPrimaryColor(color);
loop->setSecondaryColor(color);
@ -189,18 +189,18 @@ public:
case ReplaceFgWithBg:
m_proc = ink_processing[INK_REPLACE][MID(0, loop->getSprite()->getPixelFormat(), 2)];
loop->setPrimaryColor(color_utils::color_for_layer(loop->getSettings()->getFgColor(),
loop->setPrimaryColor(color_utils::color_for_layer(loop->settings()->getFgColor(),
loop->getLayer()));
loop->setSecondaryColor(color_utils::color_for_layer(loop->getSettings()->getBgColor(),
loop->setSecondaryColor(color_utils::color_for_layer(loop->settings()->getBgColor(),
loop->getLayer()));
break;
case ReplaceBgWithFg:
m_proc = ink_processing[INK_REPLACE][MID(0, loop->getSprite()->getPixelFormat(), 2)];
loop->setPrimaryColor(color_utils::color_for_layer(loop->getSettings()->getBgColor(),
loop->setPrimaryColor(color_utils::color_for_layer(loop->settings()->getBgColor(),
loop->getLayer()));
loop->setSecondaryColor(color_utils::color_for_layer(loop->getSettings()->getFgColor(),
loop->setSecondaryColor(color_utils::color_for_layer(loop->settings()->getFgColor(),
loop->getLayer()));
break;
}

View File

@ -131,7 +131,7 @@ namespace app {
// foreground/background color (certain tools needs to know the
// exact foreground/background color, they cannot used the
// primary/secondary).
virtual ISettings* getSettings() = 0;
virtual ISettings* settings() = 0;
// Returns the document settings (tiled mode, grid bounds, etc.).
// It's used to know the preferred "tiled" mode of the document.

View File

@ -80,11 +80,11 @@ ConfigureTimelinePopup::ConfigureTimelinePopup()
IDocumentSettings* ConfigureTimelinePopup::docSettings()
{
Context* context = UIContext::instance();
Document* document = context->getActiveDocument();
Document* document = context->activeDocument();
if (!document)
return NULL;
return context->getSettings()->getDocumentSettings(document);
return context->settings()->getDocumentSettings(document);
}
void ConfigureTimelinePopup::updateWidgetsFromCurrentSettings()

View File

@ -190,7 +190,7 @@ private:
void onBrushTypeChange() {
m_brushType = (BrushType)m_brushTypeButton->getSelectedItem();
ISettings* settings = UIContext::instance()->getSettings();
ISettings* settings = UIContext::instance()->settings();
Tool* currentTool = settings->getCurrentTool();
IBrushSettings* brushSettings = settings->getToolSettings(currentTool)->getBrush();
brushSettings->setType(m_brushType);
@ -215,7 +215,7 @@ private:
void onValueChange() OVERRIDE {
IntEntry::onValueChange();
ISettings* settings = UIContext::instance()->getSettings();
ISettings* settings = UIContext::instance()->settings();
Tool* currentTool = settings->getCurrentTool();
settings->getToolSettings(currentTool)
->getBrush()
@ -236,7 +236,7 @@ protected:
void onValueChange() OVERRIDE {
IntEntry::onValueChange();
ISettings* settings = UIContext::instance()->getSettings();
ISettings* settings = UIContext::instance()->settings();
Tool* currentTool = settings->getCurrentTool();
settings->getToolSettings(currentTool)
->getBrush()
@ -261,7 +261,7 @@ protected:
void onValueChange() OVERRIDE {
IntEntry::onValueChange();
ISettings* settings = UIContext::instance()->getSettings();
ISettings* settings = UIContext::instance()->settings();
Tool* currentTool = settings->getCurrentTool();
settings->getToolSettings(currentTool)
->setTolerance(getValue());
@ -319,7 +319,7 @@ protected:
case 2: inkType = kLockAlphaInk; break;
}
ISettings* settings = UIContext::instance()->getSettings();
ISettings* settings = UIContext::instance()->settings();
Tool* currentTool = settings->getCurrentTool();
settings->getToolSettings(currentTool)->setInkType(inkType);
}
@ -341,7 +341,7 @@ protected:
void onValueChange() OVERRIDE {
IntEntry::onValueChange();
ISettings* settings = UIContext::instance()->getSettings();
ISettings* settings = UIContext::instance()->settings();
Tool* currentTool = settings->getCurrentTool();
settings->getToolSettings(currentTool)
->setOpacity(getValue());
@ -358,7 +358,7 @@ protected:
void onValueChange() OVERRIDE {
IntEntry::onValueChange();
ISettings* settings = UIContext::instance()->getSettings();
ISettings* settings = UIContext::instance()->settings();
Tool* currentTool = settings->getCurrentTool();
settings->getToolSettings(currentTool)
->setSprayWidth(getValue());
@ -375,7 +375,7 @@ protected:
void onValueChange() OVERRIDE {
IntEntry::onValueChange();
ISettings* settings = UIContext::instance()->getSettings();
ISettings* settings = UIContext::instance()->settings();
Tool* currentTool = settings->getCurrentTool();
settings->getToolSettings(currentTool)
->setSpraySpeed(getValue());
@ -571,7 +571,7 @@ private:
setFreehandAlgorithm(
(FreehandAlgorithm)m_freehandAlgoButton->getSelectedItem());
ISettings* settings = UIContext::instance()->getSettings();
ISettings* settings = UIContext::instance()->settings();
Tool* currentTool = settings->getCurrentTool();
settings->getToolSettings(currentTool)
->setFreehandAlgorithm(m_freehandAlgo);
@ -616,7 +616,7 @@ protected:
void onClick(Event& ev) OVERRIDE {
CheckBox::onClick(ev);
ISettings* settings = UIContext::instance()->getSettings();
ISettings* settings = UIContext::instance()->settings();
Tool* currentTool = settings->getCurrentTool();
settings->getToolSettings(currentTool)
->setFreehandAlgorithm(isSelected() ?
@ -801,7 +801,7 @@ void ContextBar::onSetOpacity(int newOpacity)
void ContextBar::onBrushSizeChange()
{
ISettings* settings = UIContext::instance()->getSettings();
ISettings* settings = UIContext::instance()->settings();
Tool* currentTool = settings->getCurrentTool();
IToolSettings* toolSettings = settings->getToolSettings(currentTool);
IBrushSettings* brushSettings = toolSettings->getBrush();
@ -812,7 +812,7 @@ void ContextBar::onBrushSizeChange()
void ContextBar::onBrushAngleChange()
{
ISettings* settings = UIContext::instance()->getSettings();
ISettings* settings = UIContext::instance()->settings();
Tool* currentTool = settings->getCurrentTool();
IToolSettings* toolSettings = settings->getToolSettings(currentTool);
IBrushSettings* brushSettings = toolSettings->getBrush();
@ -823,7 +823,7 @@ void ContextBar::onBrushAngleChange()
void ContextBar::onCurrentToolChange()
{
ISettings* settings = UIContext::instance()->getSettings();
ISettings* settings = UIContext::instance()->settings();
updateFromTool(settings->getCurrentTool());
}
@ -834,7 +834,7 @@ void ContextBar::onDropPixels(ContextBarObserver::DropAction action)
void ContextBar::updateFromTool(tools::Tool* tool)
{
ISettings* settings = UIContext::instance()->getSettings();
ISettings* settings = UIContext::instance()->settings();
IToolSettings* toolSettings = settings->getToolSettings(tool);
IBrushSettings* brushSettings = toolSettings->getBrush();

View File

@ -23,7 +23,6 @@
#include "app/ui/document_view.h"
#include "app/app.h"
#include "app/document_event.h"
#include "app/modules/editors.h"
#include "app/modules/gui.h"
#include "app/modules/palettes.h"
@ -34,6 +33,7 @@
#include "app/ui/mini_editor.h"
#include "app/ui/workspace.h"
#include "base/path.h"
#include "doc/document_event.h"
#include "raster/layer.h"
#include "raster/sprite.h"
#include "ui/accelerator.h"
@ -160,7 +160,7 @@ void DocumentView::getDocumentLocation(DocumentLocation* location) const
std::string DocumentView::getTabText()
{
std::string str = base::get_file_name(m_document->getFilename());
std::string str = m_document->name();
// Add an asterisk if the document is modified.
if (m_document->isModified())
@ -202,24 +202,24 @@ bool DocumentView::onProcessMessage(Message* msg)
return Box::onProcessMessage(msg);
}
void DocumentView::onGeneralUpdate(DocumentEvent& ev)
void DocumentView::onGeneralUpdate(doc::DocumentEvent& ev)
{
if (m_editor->isVisible())
m_editor->updateEditor();
}
void DocumentView::onSpritePixelsModified(DocumentEvent& ev)
void DocumentView::onSpritePixelsModified(doc::DocumentEvent& ev)
{
if (m_editor->isVisible())
m_editor->drawSpriteClipped(ev.region());
}
void DocumentView::onLayerMergedDown(DocumentEvent& ev)
void DocumentView::onLayerMergedDown(doc::DocumentEvent& ev)
{
m_editor->setLayer(ev.targetLayer());
}
void DocumentView::onAddLayer(DocumentEvent& ev)
void DocumentView::onAddLayer(doc::DocumentEvent& ev)
{
if (current_editor == m_editor) {
ASSERT(ev.layer() != NULL);
@ -227,7 +227,7 @@ void DocumentView::onAddLayer(DocumentEvent& ev)
}
}
void DocumentView::onBeforeRemoveLayer(DocumentEvent& ev)
void DocumentView::onBeforeRemoveLayer(doc::DocumentEvent& ev)
{
Sprite* sprite = ev.sprite();
Layer* layer = ev.layer();
@ -250,7 +250,7 @@ void DocumentView::onBeforeRemoveLayer(DocumentEvent& ev)
}
}
void DocumentView::onAddFrame(DocumentEvent& ev)
void DocumentView::onAddFrame(doc::DocumentEvent& ev)
{
if (current_editor == m_editor)
m_editor->setFrame(ev.frame());
@ -258,7 +258,7 @@ void DocumentView::onAddFrame(DocumentEvent& ev)
m_editor->setFrame(m_editor->getFrame().next());
}
void DocumentView::onRemoveFrame(DocumentEvent& ev)
void DocumentView::onRemoveFrame(doc::DocumentEvent& ev)
{
// Adjust current frame of all editors that are in a frame more
// advanced that the removed one.
@ -273,14 +273,14 @@ void DocumentView::onRemoveFrame(DocumentEvent& ev)
}
}
void DocumentView::onTotalFramesChanged(DocumentEvent& ev)
void DocumentView::onTotalFramesChanged(doc::DocumentEvent& ev)
{
if (m_editor->getFrame() >= m_editor->getSprite()->getTotalFrames()) {
m_editor->setFrame(m_editor->getSprite()->getLastFrame());
}
}
void DocumentView::onLayerRestacked(DocumentEvent& ev)
void DocumentView::onLayerRestacked(doc::DocumentEvent& ev)
{
m_editor->invalidate();
}

View File

@ -20,10 +20,10 @@
#define APP_UI_DOCUMENT_VIEW_H_INCLUDED
#pragma once
#include "app/document_observer.h"
#include "app/ui/tabs.h"
#include "app/ui/workspace_view.h"
#include "base/compiler_specific.h"
#include "doc/document_observer.h"
#include "ui/box.h"
namespace ui {
@ -37,7 +37,7 @@ namespace app {
class DocumentView : public ui::Box
, public TabView
, public DocumentObserver
, public doc::DocumentObserver
, public WorkspaceView {
public:
enum Type {
@ -62,15 +62,15 @@ namespace app {
void onClonedFrom(WorkspaceView* from) OVERRIDE;
// DocumentObserver implementation
void onGeneralUpdate(DocumentEvent& ev) OVERRIDE;
void onSpritePixelsModified(DocumentEvent& ev) OVERRIDE;
void onLayerMergedDown(DocumentEvent& ev) OVERRIDE;
void onAddLayer(DocumentEvent& ev) OVERRIDE;
void onBeforeRemoveLayer(DocumentEvent& ev) OVERRIDE;
void onAddFrame(DocumentEvent& ev) OVERRIDE;
void onRemoveFrame(DocumentEvent& ev) OVERRIDE;
void onTotalFramesChanged(DocumentEvent& ev) OVERRIDE;
void onLayerRestacked(DocumentEvent& ev) OVERRIDE;
void onGeneralUpdate(doc::DocumentEvent& ev) OVERRIDE;
void onSpritePixelsModified(doc::DocumentEvent& ev) OVERRIDE;
void onLayerMergedDown(doc::DocumentEvent& ev) OVERRIDE;
void onAddLayer(doc::DocumentEvent& ev) OVERRIDE;
void onBeforeRemoveLayer(doc::DocumentEvent& ev) OVERRIDE;
void onAddFrame(doc::DocumentEvent& ev) OVERRIDE;
void onRemoveFrame(doc::DocumentEvent& ev) OVERRIDE;
void onTotalFramesChanged(doc::DocumentEvent& ev) OVERRIDE;
void onLayerRestacked(doc::DocumentEvent& ev) OVERRIDE;
protected:
bool onProcessMessage(ui::Message* msg) OVERRIDE;

View File

@ -160,11 +160,11 @@ static Brush* editor_get_current_brush()
{
// Create the current brush from settings
tools::Tool* current_tool = UIContext::instance()
->getSettings()
->settings()
->getCurrentTool();
IBrushSettings* brush_settings = UIContext::instance()
->getSettings()
->settings()
->getToolSettings(current_tool)
->getBrush();
@ -236,7 +236,7 @@ void Editor::drawBrushPreview(int x, int y, bool refresh)
// Get the current tool
tools::Tool* current_tool = UIContext::instance()
->getSettings()
->settings()
->getCurrentTool();
// Setup the cursor type debrushding of several factors (current tool,
@ -267,7 +267,7 @@ void Editor::drawBrushPreview(int x, int y, bool refresh)
// Draw pixel/brush preview
if (cursor_type & CURSOR_THINCROSS && m_state->requireBrushPreview()) {
IToolSettings* tool_settings = UIContext::instance()
->getSettings()
->settings()
->getToolSettings(current_tool);
Brush* brush = editor_get_current_brush();
@ -427,13 +427,13 @@ bool Editor::doesBrushPreviewNeedSubpixel()
static void generate_cursor_boundaries()
{
tools::Tool* current_tool = UIContext::instance()
->getSettings()
->settings()
->getCurrentTool();
IBrushSettings* brush_settings = NULL;
if (current_tool)
brush_settings = UIContext::instance()
->getSettings()
->settings()
->getToolSettings(current_tool)
->getBrush();
@ -649,7 +649,7 @@ static void clearpixel(ui::Graphics* g, int x, int y, gfx::Color color)
static color_t get_brush_color(Sprite* sprite, Layer* layer)
{
app::Color c = UIContext::instance()->getSettings()->getFgColor();
app::Color c = UIContext::instance()->settings()->getFgColor();
ASSERT(sprite != NULL);
// Avoid using invalid colors

View File

@ -135,7 +135,7 @@ Editor::Editor(Document* document, EditorFlags flags)
, m_state(new StandbyState())
, m_decorator(NULL)
, m_document(document)
, m_sprite(m_document->getSprite())
, m_sprite(m_document->sprite())
, m_layer(m_sprite->getFolder()->getFirstLayer())
, m_frame(FrameNumber(0))
, m_zoom(0)
@ -167,14 +167,14 @@ Editor::Editor(Document* document, EditorFlags flags)
m_fgColorChangeConn =
ColorBar::instance()->FgColorChange.connect(Bind<void>(&Editor::onFgColorChange, this));
UIContext::instance()->getSettings()
UIContext::instance()->settings()
->getDocumentSettings(m_document)
->addObserver(this);
}
Editor::~Editor()
{
UIContext::instance()->getSettings()
UIContext::instance()->settings()
->getDocumentSettings(m_document)
->removeObserver(this);
@ -422,7 +422,7 @@ void Editor::drawSpriteUnclippedRect(ui::Graphics* g, const gfx::Rect& rc)
// Document settings
IDocumentSettings* docSettings =
UIContext::instance()->getSettings()->getDocumentSettings(m_document);
UIContext::instance()->settings()->getDocumentSettings(m_document);
if (docSettings->getTiledMode() & filters::TILED_X_AXIS) {
drawOneSpriteUnclippedRect(g, rc, -spriteRect.w, 0);
@ -730,7 +730,7 @@ tools::Tool* Editor::getCurrentEditorTool()
return m_quicktool;
else {
UIContext* context = UIContext::instance();
return context->getSettings()->getCurrentTool();
return context->settings()->getCurrentTool();
}
}
@ -871,7 +871,7 @@ void Editor::editor_update_quicktool()
{
if (m_customizationDelegate) {
UIContext* context = UIContext::instance();
tools::Tool* current_tool = context->getSettings()->getCurrentTool();
tools::Tool* current_tool = context->settings()->getCurrentTool();
tools::Tool* old_quicktool = m_quicktool;
m_quicktool = m_customizationDelegate->getQuickTool(current_tool);

View File

@ -80,12 +80,13 @@ MovingPixelsState::MovingPixelsState(Editor* editor, MouseMessage* msg, PixelsMo
// Setup mask color
setTransparentColor(context->settings()->selection()->getMoveTransparentColor());
// Add this class as:
// - observer of the UI context: so we know if the user wants to
// execute other command, so we can drop pixels.
// - observer of SelectionSettings to be informed of changes to Transparent Color
// changes from Context Bar.
context->addObserver(this);
// Hook BeforeCommandExecution signal so we know if the user wants
// to execute other command, so we can drop pixels.
m_ctxConn =
context->BeforeCommandExecution.connect(&MovingPixelsState::onBeforeCommandExecution, this);
// Observe SelectionSettings to be informed of changes to
// Transparent Color from Context Bar.
context->settings()->selection()->addObserver(this);
// Add the current editor as filter for key message of the manager
@ -105,7 +106,7 @@ MovingPixelsState::~MovingPixelsState()
contextBar->removeObserver(this);
contextBar->updateFromTool(UIContext::instance()->settings()->getCurrentTool());
UIContext::instance()->removeObserver(this);
m_ctxConn.disconnect();
UIContext::instance()->settings()->selection()->removeObserver(this);
m_pixelsMovement.reset(NULL);
@ -324,7 +325,7 @@ bool MovingPixelsState::onKeyDown(Editor* editor, KeyMessage* msg)
gfx::Point origin;
base::UniquePtr<Image> floatingImage(m_pixelsMovement->getDraggedImageCopy(origin));
clipboard::copy_image(floatingImage.get(),
document->getSprite()->getPalette(editor->getFrame()),
document->sprite()->getPalette(editor->getFrame()),
origin);
}
@ -386,7 +387,7 @@ bool MovingPixelsState::onUpdateStatusBar(Editor* editor)
}
// Before executing any command, we drop the pixels (go back to standby).
void MovingPixelsState::onCommandBeforeExecution(Context* context)
void MovingPixelsState::onBeforeCommandExecution()
{
if (m_pixelsMovement)
dropPixels(m_currentEditor);

View File

@ -20,7 +20,6 @@
#define APP_UI_EDITOR_MOVING_PIXELS_STATE_H_INCLUDED
#pragma once
#include "app/context_observer.h"
#include "app/settings/settings_observers.h"
#include "app/ui/context_bar_observer.h"
#include "app/ui/editor/handle_type.h"
@ -28,6 +27,7 @@
#include "app/ui/editor/standby_state.h"
#include "app/ui/status_bar.h"
#include "base/compiler_specific.h"
#include "base/connection.h"
namespace raster {
class Image;
@ -38,7 +38,6 @@ namespace app {
class MovingPixelsState
: public StandbyState
, ContextObserver
, SelectionSettingsObserver
, ContextBarObserver {
public:
@ -55,9 +54,6 @@ namespace app {
virtual bool onKeyDown(Editor* editor, ui::KeyMessage* msg) OVERRIDE;
virtual bool onKeyUp(Editor* editor, ui::KeyMessage* msg) OVERRIDE;
virtual bool onUpdateStatusBar(Editor* editor) OVERRIDE;
// ContextObserver
virtual void onCommandBeforeExecution(Context* context) OVERRIDE;
// SettingsObserver
virtual void onSetMoveTransparentColor(app::Color newColor) OVERRIDE;
@ -68,6 +64,9 @@ namespace app {
virtual gfx::Transformation getTransformation(Editor* editor) OVERRIDE;
private:
// ContextObserver
void onBeforeCommandExecution();
void setTransparentColor(const app::Color& color);
void dropPixels(Editor* editor);
@ -78,6 +77,8 @@ namespace app {
// True if the image was discarded (e.g. when a "Cut" command was
// used to remove the dragged image).
bool m_discarded;
Connection m_ctxConn;
};
} // namespace app

View File

@ -74,12 +74,12 @@ PixelsMovement::PixelsMovement(Context* context,
m_initialMask = new Mask(*m_document->getMask());
m_currentMask = new Mask(*m_document->getMask());
UIContext::instance()->getSettings()->selection()->addObserver(this);
UIContext::instance()->settings()->selection()->addObserver(this);
}
PixelsMovement::~PixelsMovement()
{
UIContext::instance()->getSettings()->selection()->removeObserver(this);
UIContext::instance()->settings()->selection()->removeObserver(this);
delete m_originalImage;
delete m_initialMask;
@ -219,7 +219,7 @@ void PixelsMovement::moveImage(int x, int y, MoveModifier moveModifier)
if ((moveModifier & SnapToGridMovement) == SnapToGridMovement) {
// Snap the x1,y1 point to the grid.
gfx::Point gridOffset(x1, y1);
UIContext::instance()->getSettings()
UIContext::instance()->settings()
->getDocumentSettings(m_document)->snapToGrid(gridOffset);
// Now we calculate the difference from x1,y1 point and we can
@ -617,7 +617,7 @@ void PixelsMovement::drawParallelogram(raster::Image* dst, raster::Image* src,
const gfx::Transformation::Corners& corners,
const gfx::Point& leftTop)
{
switch (UIContext::instance()->getSettings()->selection()->getRotationAlgorithm()) {
switch (UIContext::instance()->settings()->selection()->getRotationAlgorithm()) {
case kFastRotationAlgorithm:
image_parallelogram(dst, src,

View File

@ -104,7 +104,7 @@ public:
, m_layer(editor->getLayer())
, m_frame(editor->getFrame())
, m_canceled(false)
, m_settings(m_context->getSettings())
, m_settings(m_context->settings())
, m_docSettings(m_settings->getDocumentSettings(m_document))
, m_toolSettings(m_settings->getToolSettings(m_tool))
, m_button(button)
@ -225,7 +225,7 @@ public:
int getOpacity() OVERRIDE { return m_opacity; }
int getTolerance() OVERRIDE { return m_tolerance; }
SelectionMode getSelectionMode() OVERRIDE { return m_selectionMode; }
ISettings* getSettings() OVERRIDE { return m_settings; }
ISettings* settings() OVERRIDE { return m_settings; }
IDocumentSettings* getDocumentSettings() OVERRIDE { return m_docSettings; }
bool getFilled() OVERRIDE { return m_filled; }
bool getPreviewFilled() OVERRIDE { return m_previewFilled; }
@ -333,7 +333,7 @@ private:
tools::ToolLoop* create_tool_loop(Editor* editor, Context* context, MouseMessage* msg)
{
tools::Tool* current_tool = context->getSettings()->getCurrentTool();
tools::Tool* current_tool = context->settings()->getCurrentTool();
if (!current_tool)
return NULL;

View File

@ -253,11 +253,11 @@ void MainWindow::onSaveLayout(SaveLayoutEvent& ev)
// inform to the UIContext that the current view has changed.
void MainWindow::onActiveViewChange()
{
if (DocumentView* docView = dynamic_cast<DocumentView*>(m_workspace->getActiveView())) {
if (DocumentView* docView = dynamic_cast<DocumentView*>(m_workspace->activeView())) {
UIContext::instance()->setActiveView(docView);
m_contextBar->updateFromTool(UIContext::instance()
->getSettings()->getCurrentTool());
->settings()->getCurrentTool());
if (m_mode != EditorOnlyMode)
m_contextBar->setVisible(true);
@ -277,7 +277,7 @@ void MainWindow::clickTab(Tabs* tabs, TabView* tabView, ui::MouseButtons buttons
return;
WorkspaceView* workspaceView = dynamic_cast<WorkspaceView*>(tabView);
if (m_workspace->getActiveView() != workspaceView)
if (m_workspace->activeView() != workspaceView)
m_workspace->setActiveView(workspaceView);
DocumentView* docView = dynamic_cast<DocumentView*>(workspaceView);
@ -310,7 +310,7 @@ void MainWindow::mouseOverTab(Tabs* tabs, TabView* tabView)
if (DocumentView* docView = dynamic_cast<DocumentView*>(tabView)) {
Document* document = docView->getDocument();
m_statusBar->setStatusText(250, "%s",
document->getFilename().c_str());
document->filename().c_str());
}
else {
m_statusBar->clearText();

View File

@ -264,7 +264,7 @@ void MiniEditorWindow::onPlaybackTick()
if (!document || !sprite)
return;
ISettings* settings = UIContext::instance()->getSettings();
ISettings* settings = UIContext::instance()->settings();
IDocumentSettings* docSettings = settings->getDocumentSettings(document);
if (!docSettings)
return;

View File

@ -62,7 +62,7 @@ void PalettePopup::showPopup(const gfx::Rect& bounds)
m_load->setEnabled(false);
m_paletteListBox.selectChild(NULL);
if (!UIContext::instance()->getActiveDocument())
if (!UIContext::instance()->activeDocument())
m_load->setText("Set as Default");
else
m_load->setText("Load");

View File

@ -266,7 +266,7 @@ StatusBar::~StatusBar()
void StatusBar::onCurrentToolChange()
{
if (isVisible()) {
tools::Tool* currentTool = UIContext::instance()->getSettings()->getCurrentTool();
tools::Tool* currentTool = UIContext::instance()->settings()->getCurrentTool();
if (currentTool) {
showTool(500, currentTool);
setTextf("%s Selected", currentTool->getText().c_str());
@ -431,7 +431,7 @@ bool StatusBar::onProcessMessage(Message* msg)
case kMouseEnterMessage: {
updateSubwidgetsVisibility();
const Document* document = UIContext::instance()->getActiveDocument();
const Document* document = UIContext::instance()->activeDocument();
if (document != NULL)
updateCurrentFrame();
break;
@ -630,7 +630,7 @@ void StatusBar::updateFromLayer()
void StatusBar::updateCurrentFrame()
{
DocumentLocation location = UIContext::instance()->getActiveLocation();
DocumentLocation location = UIContext::instance()->activeLocation();
if (location.sprite())
m_currentFrame->setTextf("%d", location.frame()+1);
}
@ -644,7 +644,7 @@ void StatusBar::newFrame()
void StatusBar::updateSubwidgetsVisibility()
{
const Document* document = UIContext::instance()->getActiveDocument();
const Document* document = UIContext::instance()->activeDocument();
bool commandsVisible = (document != NULL && hasMouse());
bool notificationsVisible = (document == NULL);

View File

@ -31,7 +31,6 @@
#include "app/context_access.h"
#include "app/document.h"
#include "app/document_api.h"
#include "app/document_event.h"
#include "app/document_undo.h"
#include "app/modules/editors.h"
#include "app/modules/gfx.h"
@ -47,6 +46,7 @@
#include "app/undo_transaction.h"
#include "base/compiler_specific.h"
#include "base/memory.h"
#include "doc/document_event.h"
#include "gfx/point.h"
#include "gfx/rect.h"
#include "raster/raster.h"
@ -166,7 +166,8 @@ Timeline::Timeline()
, m_separator_w(1)
, m_confPopup(NULL)
{
m_context->addObserver(this);
m_ctxConn = m_context->AfterCommandExecution.connect(&Timeline::onAfterCommandExecution, this);
m_context->documents().addObserver(this);
setDoubleBuffered(true);
}
@ -174,9 +175,7 @@ Timeline::Timeline()
Timeline::~Timeline()
{
detachDocument();
m_context->removeObserver(this);
m_context->documents().removeObserver(this);
delete m_confPopup;
}
@ -308,14 +307,14 @@ bool Timeline::onProcessMessage(Message* msg)
m_state = STATE_MOVING_SEPARATOR;
break;
case A_PART_HEADER_ONIONSKIN_RANGE_LEFT: {
ISettings* settings = UIContext::instance()->getSettings();
ISettings* settings = UIContext::instance()->settings();
IDocumentSettings* docSettings = settings->getDocumentSettings(m_document);
m_state = STATE_MOVING_ONIONSKIN_RANGE_LEFT;
m_origFrames = docSettings->getOnionskinPrevFrames();
break;
}
case A_PART_HEADER_ONIONSKIN_RANGE_RIGHT: {
ISettings* settings = UIContext::instance()->getSettings();
ISettings* settings = UIContext::instance()->settings();
IDocumentSettings* docSettings = settings->getDocumentSettings(m_document);
m_state = STATE_MOVING_ONIONSKIN_RANGE_RIGHT;
m_origFrames = docSettings->getOnionskinNextFrames();
@ -362,7 +361,7 @@ bool Timeline::onProcessMessage(Message* msg)
break;
case A_PART_CEL: {
const DocumentReader document(const_cast<Document*>(m_document));
const Sprite* sprite = document->getSprite();
const Sprite* sprite = document->sprite();
LayerIndex old_layer = getLayerIndex(m_layer);
bool selectCel = (mouseMsg->left()
|| !isLayerActive(m_clk_layer)
@ -426,7 +425,7 @@ bool Timeline::onProcessMessage(Message* msg)
}
case STATE_MOVING_ONIONSKIN_RANGE_LEFT: {
ISettings* settings = UIContext::instance()->getSettings();
ISettings* settings = UIContext::instance()->settings();
IDocumentSettings* docSettings = settings->getDocumentSettings(m_document);
int newValue = m_origFrames + (m_clk_frame - hot_frame);
docSettings->setOnionskinPrevFrames(MAX(0, newValue));
@ -435,7 +434,7 @@ bool Timeline::onProcessMessage(Message* msg)
}
case STATE_MOVING_ONIONSKIN_RANGE_RIGHT:
ISettings* settings = UIContext::instance()->getSettings();
ISettings* settings = UIContext::instance()->settings();
IDocumentSettings* docSettings = settings->getDocumentSettings(m_document);
int newValue = m_origFrames - (m_clk_frame - hot_frame);
docSettings->setOnionskinNextFrames(MAX(0, newValue));
@ -631,7 +630,7 @@ bool Timeline::onProcessMessage(Message* msg)
}
case A_PART_HEADER_ONIONSKIN: {
ISettings* settings = UIContext::instance()->getSettings();
ISettings* settings = UIContext::instance()->settings();
IDocumentSettings* docSettings = settings->getDocumentSettings(m_document);
if (docSettings)
docSettings->setUseOnionskin(!docSettings->getUseOnionskin());
@ -926,7 +925,7 @@ paintNoDoc:;
drawPart(g, getClientBounds(), NULL, m_timelinePaddingStyle);
}
void Timeline::onCommandAfterExecution(Context* context)
void Timeline::onAfterCommandExecution()
{
if (!m_document)
return;
@ -936,13 +935,13 @@ void Timeline::onCommandAfterExecution(Context* context)
invalidate();
}
void Timeline::onRemoveDocument(Context* context, Document* document)
void Timeline::onRemoveDocument(doc::Document* document)
{
if (document == m_document)
detachDocument();
}
void Timeline::onAddLayer(DocumentEvent& ev)
void Timeline::onAddLayer(doc::DocumentEvent& ev)
{
ASSERT(ev.layer() != NULL);
@ -953,7 +952,7 @@ void Timeline::onAddLayer(DocumentEvent& ev)
invalidate();
}
void Timeline::onAfterRemoveLayer(DocumentEvent& ev)
void Timeline::onAfterRemoveLayer(doc::DocumentEvent& ev)
{
Sprite* sprite = ev.sprite();
Layer* layer = ev.layer();
@ -980,7 +979,7 @@ void Timeline::onAfterRemoveLayer(DocumentEvent& ev)
invalidate();
}
void Timeline::onAddFrame(DocumentEvent& ev)
void Timeline::onAddFrame(doc::DocumentEvent& ev)
{
setFrame(ev.frame());
@ -988,7 +987,7 @@ void Timeline::onAddFrame(DocumentEvent& ev)
invalidate();
}
void Timeline::onRemoveFrame(DocumentEvent& ev)
void Timeline::onRemoveFrame(doc::DocumentEvent& ev)
{
// Adjust current frame of all editors that are in a frame more
// advanced that the removed one.
@ -1103,7 +1102,7 @@ void Timeline::drawPart(ui::Graphics* g, const gfx::Rect& bounds,
void Timeline::drawHeader(ui::Graphics* g)
{
ISettings* settings = UIContext::instance()->getSettings();
ISettings* settings = UIContext::instance()->settings();
IDocumentSettings* docSettings = settings->getDocumentSettings(m_document);
bool allInvisible = allLayersInvisible();
bool allLocked = allLayersLocked();
@ -1255,7 +1254,7 @@ void Timeline::drawCel(ui::Graphics* g, LayerIndex layerIndex, FrameNumber frame
void Timeline::drawLoopRange(ui::Graphics* g)
{
ISettings* settings = UIContext::instance()->getSettings();
ISettings* settings = UIContext::instance()->settings();
IDocumentSettings* docSettings = settings->getDocumentSettings(m_document);
if (!docSettings->getLoopAnimation())
return;
@ -1393,7 +1392,7 @@ gfx::Rect Timeline::getFrameHeadersBounds() const
gfx::Rect Timeline::getOnionskinFramesBounds() const
{
ISettings* settings = UIContext::instance()->getSettings();
ISettings* settings = UIContext::instance()->settings();
IDocumentSettings* docSettings = settings->getDocumentSettings(m_document);
if (docSettings->getUseOnionskin()) {
FrameNumber firstFrame = m_frame.previous(docSettings->getOnionskinPrevFrames());
@ -1641,7 +1640,7 @@ void Timeline::updateStatusBar(ui::Message* msg)
switch (m_hot_part) {
case A_PART_HEADER_ONIONSKIN: {
ISettings* settings = UIContext::instance()->getSettings();
ISettings* settings = UIContext::instance()->settings();
IDocumentSettings* docSettings = settings->getDocumentSettings(m_document);
if (docSettings) {
sb->setStatusText(0, "Onionskin is %s",

View File

@ -20,11 +20,12 @@
#define APP_UI_TIMELINE_H_INCLUDED
#pragma once
#include "app/context_observer.h"
#include "app/document_observer.h"
#include "app/ui/editor/editor_observer.h"
#include "app/ui/skin/style.h"
#include "base/compiler_specific.h"
#include "base/connection.h"
#include "doc/document_observer.h"
#include "doc/documents_observer.h"
#include "raster/frame_number.h"
#include "raster/layer_index.h"
#include "raster/sprite.h"
@ -52,9 +53,9 @@ namespace app {
class Editor;
class Timeline : public ui::Widget
, public ContextObserver
, public DocumentObserver
, public EditorObserver {
, public doc::DocumentsObserver
, public doc::DocumentObserver
, public app::EditorObserver {
public:
enum State {
STATE_STANDBY,
@ -137,14 +138,16 @@ namespace app {
void onPaint(ui::PaintEvent& ev) OVERRIDE;
// DocumentObserver impl.
void onAddLayer(DocumentEvent& ev) OVERRIDE;
void onAfterRemoveLayer(DocumentEvent& ev) OVERRIDE;
void onAddFrame(DocumentEvent& ev) OVERRIDE;
void onRemoveFrame(DocumentEvent& ev) OVERRIDE;
void onAddLayer(doc::DocumentEvent& ev) OVERRIDE;
void onAfterRemoveLayer(doc::DocumentEvent& ev) OVERRIDE;
void onAddFrame(doc::DocumentEvent& ev) OVERRIDE;
void onRemoveFrame(doc::DocumentEvent& ev) OVERRIDE;
// ContextObserver impl.
void onCommandAfterExecution(Context* context) OVERRIDE;
void onRemoveDocument(Context* context, Document* document) OVERRIDE;
// app::Context slots.
void onAfterCommandExecution();
// DocumentsObserver impl.
void onRemoveDocument(doc::Document* document) OVERRIDE;
// EditorObserver impl.
void dispose() OVERRIDE { }
@ -281,6 +284,7 @@ namespace app {
gfx::Point m_oldPos;
// Configure timeline
ConfigureTimelinePopup* m_confPopup;
ScopedConnection m_ctxConn;
};
} // namespace app

View File

@ -333,7 +333,7 @@ void ToolBar::onPaint(ui::PaintEvent& ev)
gfx::Color face;
int nw;
if (UIContext::instance()->getSettings()->getCurrentTool() == tool ||
if (UIContext::instance()->settings()->getCurrentTool() == tool ||
m_hotIndex == c) {
nw = PART_TOOLBUTTON_HOT_NW;
face = hotFace;
@ -599,7 +599,7 @@ void ToolBar::selectTool(Tool* tool)
m_selectedInGroup[tool->getGroup()] = tool;
UIContext::instance()->getSettings()->setCurrentTool(tool);
UIContext::instance()->settings()->setCurrentTool(tool);
if (m_currentStrip)
m_currentStrip->invalidate();
@ -744,7 +744,7 @@ void ToolBar::ToolStrip::onPaint(PaintEvent& ev)
gfx::Color face;
int nw;
if (UIContext::instance()->getSettings()->getCurrentTool() == tool ||
if (UIContext::instance()->settings()->getCurrentTool() == tool ||
m_hotTool == tool) {
nw = PART_TOOLBUTTON_HOT_NW;
face = theme->getColor(ThemeColor::ButtonHotFace);

View File

@ -89,10 +89,10 @@ void Workspace::removeView(WorkspaceView* view)
ActiveViewChanged(); // Fire ActiveViewChanged event
}
WorkspaceView* Workspace::getActiveView()
WorkspaceView* Workspace::activeView()
{
ASSERT(m_activePart != NULL);
return m_activePart->getActiveView();
return m_activePart->activeView();
}
void Workspace::setActiveView(WorkspaceView* view)
@ -192,8 +192,8 @@ void Workspace::makeUnique(WorkspaceView* view)
for (WorkspaceParts::iterator it=parts.begin(), end=parts.end(); it != end; ++it) {
WorkspacePart* part = *it;
if (part->getParent() != this) {
while (part->getActiveView())
part->removeView(part->getActiveView());
while (part->activeView())
part->removeView(part->activeView());
}
}

View File

@ -41,7 +41,7 @@ namespace app {
void addView(WorkspaceView* view);
void removeView(WorkspaceView* view);
WorkspaceView* getActiveView();
WorkspaceView* activeView();
void setActiveView(WorkspaceView* view);
void splitView(WorkspaceView* view, int orientation);

View File

@ -36,7 +36,7 @@ namespace app {
void addView(WorkspaceView* view);
void removeView(WorkspaceView* view);
WorkspaceView* getActiveView() { return m_activeView; }
WorkspaceView* activeView() { return m_activeView; }
void setActiveView(WorkspaceView* view);
bool hasView(WorkspaceView* view);

View File

@ -34,7 +34,6 @@
#include "app/ui/workspace.h"
#include "app/ui_context.h"
#include "base/mutex.h"
#include "base/path.h"
#include "raster/sprite.h"
#include "undo/undo_history.h"
@ -56,12 +55,17 @@ UIContext::~UIContext()
{
ASSERT(m_instance == this);
m_instance = NULL;
// The context must be empty at this point. (It's to check if the UI
// is working correctly, i.e. closing all files when the user can
// take any action about it.)
ASSERT(documents().empty());
}
DocumentView* UIContext::getActiveView() const
DocumentView* UIContext::activeView() const
{
Workspace* workspace = App::instance()->getMainWindow()->getWorkspace();
WorkspaceView* view = workspace->getActiveView();
WorkspaceView* view = workspace->activeView();
if (DocumentView* docView = dynamic_cast<DocumentView*>(view))
return docView;
else
@ -70,10 +74,12 @@ DocumentView* UIContext::getActiveView() const
void UIContext::setActiveView(DocumentView* docView)
{
setActiveDocument(docView ? docView->getDocument(): NULL);
if (docView != NULL) {
App::instance()->getMainWindow()->getTabsBar()->selectTab(docView);
if (App::instance()->getMainWindow()->getWorkspace()->getActiveView() != docView)
if (App::instance()->getMainWindow()->getWorkspace()->activeView() != docView)
App::instance()->getMainWindow()->getWorkspace()->setActiveView(docView);
}
@ -96,9 +102,10 @@ void UIContext::setActiveView(DocumentView* docView)
std::string title;
if (docView) {
// Prepend the document's filename.
title += base::get_file_name(docView->getDocument()->getFilename());
title += docView->getDocument()->name();
title += " - ";
}
title += defaultTitle;
set_window_title(title.c_str());
}
@ -120,26 +127,25 @@ size_t UIContext::countViewsOf(Document* document) const
return counter;
}
Editor* UIContext::getActiveEditor()
Editor* UIContext::activeEditor()
{
DocumentView* activeView = getActiveView();
if (activeView)
return activeView->getEditor();
DocumentView* view = activeView();
if (view)
return view->getEditor();
else
return NULL;
}
void UIContext::onAddDocument(Document* document)
void UIContext::onAddDocument(doc::Document* doc)
{
// base method
Context::onAddDocument(document);
Context::onAddDocument(doc);
// We don't create views in batch mode.
if (!App::instance()->isGui())
return;
// Add a new view for this document
DocumentView* view = new DocumentView(document, DocumentView::Normal);
DocumentView* view = new DocumentView(static_cast<app::Document*>(doc), DocumentView::Normal);
// Add a tab with the new view for the document
App::instance()->getMainWindow()->getWorkspace()->addView(view);
@ -148,9 +154,9 @@ void UIContext::onAddDocument(Document* document)
view->getEditor()->setDefaultScroll();
}
void UIContext::onRemoveDocument(Document* document)
void UIContext::onRemoveDocument(doc::Document* doc)
{
Context::onRemoveDocument(document);
Context::onRemoveDocument(doc);
Workspace* workspace = App::instance()->getMainWindow()->getWorkspace();
DocumentViews docViews;
@ -159,7 +165,7 @@ void UIContext::onRemoveDocument(Document* document)
for (Workspace::iterator it=workspace->begin(); it != workspace->end(); ++it) {
WorkspaceView* view = *it;
if (DocumentView* docView = dynamic_cast<DocumentView*>(view)) {
if (docView->getDocument() == document) {
if (docView->getDocument() == doc) {
docViews.push_back(docView);
}
}
@ -174,9 +180,9 @@ void UIContext::onRemoveDocument(Document* document)
void UIContext::onGetActiveLocation(DocumentLocation* location) const
{
DocumentView* activeView = getActiveView();
if (activeView)
activeView->getDocumentLocation(location);
DocumentView* view = activeView();
if (view)
view->getDocumentLocation(location);
}
} // namespace app

View File

@ -20,8 +20,9 @@
#define APP_UI_CONTEXT_H_INCLUDED
#pragma once
#include "base/compiler_specific.h"
#include "app/context.h"
#include "base/compiler_specific.h"
#include "doc/documents_observer.h"
namespace app {
class DocumentView;
@ -29,7 +30,7 @@ namespace app {
typedef std::vector<DocumentView*> DocumentViews;
class UIContext : public Context {
class UIContext : public app::Context {
public:
static UIContext* instance() { return m_instance; }
@ -38,22 +39,22 @@ namespace app {
virtual bool isUiAvailable() const { return true; }
DocumentView* getActiveView() const;
DocumentView* activeView() const;
void setActiveView(DocumentView* documentView);
// Returns the number of views that the given document has.
size_t countViewsOf(Document* document) const;
// Returns the current editor. It can be null.
Editor* getActiveEditor();
Editor* activeEditor();
// Returns the active editor for the given document, or creates a
// new one if it's necessary.
Editor* getEditorFor(Document* document);
protected:
virtual void onAddDocument(Document* document) OVERRIDE;
virtual void onRemoveDocument(Document* document) OVERRIDE;
virtual void onAddDocument(doc::Document* doc) OVERRIDE;
virtual void onRemoveDocument(doc::Document* doc) OVERRIDE;
virtual void onGetActiveLocation(DocumentLocation* location) const OVERRIDE;
private:

View File

@ -39,7 +39,7 @@ UndoTransaction::UndoTransaction(Context* context, const char* label, undo::Modi
{
ASSERT(label != NULL);
DocumentLocation location = m_context->getActiveLocation();
DocumentLocation location = m_context->activeLocation();
m_document = location.document();
m_sprite = location.sprite();
@ -83,7 +83,7 @@ void UndoTransaction::closeUndoGroup()
ASSERT(!m_closed);
if (isEnabled()) {
DocumentLocation location = m_context->getActiveLocation();
DocumentLocation location = m_context->activeLocation();
SpritePosition position(m_sprite->layerToIndex(location.layer()),
location.frame());

View File

@ -23,9 +23,9 @@
#include "app/undoers/add_frame.h"
#include "app/document.h"
#include "app/document_event.h"
#include "app/document_observer.h"
#include "app/undoers/remove_frame.h"
#include "doc/document_event.h"
#include "doc/document_observer.h"
#include "raster/sprite.h"
#include "undo/objects_container.h"
#include "undo/undoers_collector.h"
@ -59,10 +59,10 @@ void AddFrame::revert(ObjectsContainer* objects, UndoersCollector* redoers)
sprite->removeFrame(m_frame);
// Notify observers.
DocumentEvent ev(document);
doc::DocumentEvent ev(document);
ev.sprite(sprite);
ev.frame(m_frame);
document->notifyObservers<DocumentEvent&>(&DocumentObserver::onRemoveFrame, ev);
document->notifyObservers<doc::DocumentEvent&>(&doc::DocumentObserver::onRemoveFrame, ev);
}
} // namespace undoers

View File

@ -23,9 +23,9 @@
#include "app/undoers/remove_frame.h"
#include "app/document.h"
#include "app/document_event.h"
#include "app/document_observer.h"
#include "app/undoers/add_frame.h"
#include "doc/document_event.h"
#include "doc/document_observer.h"
#include "raster/sprite.h"
#include "undo/objects_container.h"
#include "undo/undoers_collector.h"
@ -62,10 +62,10 @@ void RemoveFrame::revert(ObjectsContainer* objects, UndoersCollector* redoers)
sprite->setFrameDuration(m_frame, m_frameDuration);
// Notify observers.
DocumentEvent ev(document);
doc::DocumentEvent ev(document);
ev.sprite(sprite);
ev.frame(m_frame);
document->notifyObservers<DocumentEvent&>(&DocumentObserver::onAddFrame, ev);
document->notifyObservers<doc::DocumentEvent&>(&doc::DocumentObserver::onAddFrame, ev);
}
} // namespace undoers

View File

@ -109,7 +109,7 @@ static bool copy_from_document(const DocumentLocation& location)
clipboard_x = document->getMask()->getBounds().x;
clipboard_y = document->getMask()->getBounds().y;
const Palette* pal = document->getSprite()->getPalette(location.frame());
const Palette* pal = document->sprite()->getPalette(location.frame());
set_clipboard(image, pal ? new Palette(*pal): NULL, true);
return true;
}
@ -185,7 +185,7 @@ void clipboard::paste()
}
#endif
Sprite* dst_sprite = editor->getDocument()->getSprite();
Sprite* dst_sprite = editor->getDocument()->sprite();
if (clipboard_image == NULL)
return;

View File

@ -75,7 +75,7 @@ ExpandCelCanvas::ExpandCelCanvas(Context* context, TiledMode tiledMode, UndoTran
{
create_buffers();
DocumentLocation location = context->getActiveLocation();
DocumentLocation location = context->activeLocation();
m_document = location.document();
m_sprite = location.sprite();
m_layer = location.layer();

View File

@ -426,7 +426,7 @@ Image* RenderEngine::renderSprite(int source_x, int source_y,
// Onion-skin feature: Draw previous/next frames with different
// opacity (<255) (it is the onion-skinning)
IDocumentSettings* docSettings = UIContext::instance()
->getSettings()->getDocumentSettings(m_document);
->settings()->getDocumentSettings(m_document);
if (enable_onionskin & docSettings->getUseOnionskin()) {
int prevs = docSettings->getOnionskinPrevFrames();

View File

@ -31,10 +31,6 @@ public:
typedef Slot0<R> SlotType;
typedef std::vector<SlotType*> SlotList;
protected:
SlotList m_slots;
public:
Signal0_base() { }
~Signal0_base() { }
@ -57,6 +53,9 @@ public:
base::remove_from_container(m_slots, static_cast<SlotType*>(slot));
}
protected:
SlotList m_slots;
private:
DISABLE_COPYING(Signal0_base);
};
@ -65,15 +64,19 @@ private:
template<typename R>
class Signal0 : public Signal0_base<R> {
public:
// GCC needs redefinitions
typedef Signal0_base<R> Base;
typedef Slot0<R> SlotType;
typedef typename Base::SlotList SlotList;
Signal0() {
}
R operator()(R default_result = R()) {
R result(default_result);
typename Signal0_base<R>::SlotList::iterator end = Signal0_base<R>::m_slots.end();
for (typename Signal0_base<R>::SlotList::iterator
it = Signal0_base<R>::m_slots.begin(); it != end; ++it) {
typename Signal0_base<R>::SlotType* slot = *it;
SlotList copy = Base::m_slots;
for (typename SlotList::iterator it = copy.begin(), end = copy.end(); it != end; ++it) {
SlotType* slot = *it;
result = (*slot)();
}
return result;
@ -83,10 +86,9 @@ public:
R operator()(R default_result, const Merger& m) {
R result(default_result);
Merger merger(m);
typename Signal0_base<R>::SlotList::iterator end = Signal0_base<R>::m_slots.end();
for (typename Signal0_base<R>::SlotList::iterator
it = Signal0_base<R>::m_slots.begin(); it != end; ++it) {
typename Signal0_base<R>::SlotType* slot = *it;
SlotList copy = Base::m_slots;
for (typename SlotList::iterator it = copy.begin(), end = copy.end(); it != end; ++it) {
SlotType* slot = *it;
result = merger(result, (*slot)());
}
return result;
@ -98,12 +100,16 @@ public:
template<>
class Signal0<void> : public Signal0_base<void> {
public:
// GCC needs redefinitions
typedef Signal0_base<void> Base;
typedef Slot0<void> SlotType;
typedef Base::SlotList SlotList;
Signal0() { }
void operator()() {
SlotList::iterator end = m_slots.end();
for (SlotList::iterator
it = m_slots.begin(); it != end; ++it) {
SlotList copy = Base::m_slots;
for (SlotList::iterator it = copy.begin(), end = copy.end(); it != end; ++it) {
SlotType* slot = *it;
(*slot)();
}
@ -120,10 +126,6 @@ public:
typedef Slot1<R, A1> SlotType;
typedef std::vector<SlotType*> SlotList;
protected:
SlotList m_slots;
public:
Signal1_base() { }
~Signal1_base() { }
@ -146,6 +148,9 @@ public:
base::remove_from_container(m_slots, static_cast<SlotType*>(slot));
}
protected:
SlotList m_slots;
private:
DISABLE_COPYING(Signal1_base);
};
@ -155,14 +160,18 @@ template<typename R, typename A1>
class Signal1 : public Signal1_base<R, A1>
{
public:
// GCC needs redefinitions
typedef Signal1_base<R, A1> Base;
typedef Slot1<R, A1> SlotType;
typedef typename Base::SlotList SlotList;
Signal1() { }
R operator()(A1 a1, R default_result = R()) {
R result(default_result);
typename Signal1_base<R, A1>::SlotList::iterator end = Signal1_base<R, A1>::m_slots.end();
for (typename Signal1_base<R, A1>::SlotList::iterator
it = Signal1_base<R, A1>::m_slots.begin(); it != end; ++it) {
typename Signal1_base<R, A1>::SlotType* slot = *it;
SlotList copy = Base::m_slots;
for (typename SlotList::iterator it = copy.begin(), end = copy.end(); it != end; ++it) {
SlotType* slot = *it;
result = (*slot)(a1);
}
return result;
@ -172,10 +181,9 @@ public:
R operator()(A1 a1, R default_result, const Merger& m) {
R result(default_result);
Merger merger(m);
typename Signal1_base<R, A1>::SlotList::iterator end = Signal1_base<R, A1>::m_slots.end();
for (typename Signal1_base<R, A1>::SlotList::iterator
it = Signal1_base<R, A1>::m_slots.begin(); it != end; ++it) {
typename Signal1_base<R, A1>::SlotType* slot = *it;
SlotList copy = Base::m_slots;
for (typename SlotList::iterator it = copy.begin(), end = copy.end(); it != end; ++it) {
SlotType* slot = *it;
result = merger(result, (*slot)(a1));
}
return result;
@ -188,13 +196,17 @@ template<typename A1>
class Signal1<void, A1> : public Signal1_base<void, A1>
{
public:
// GCC needs redefinitions
typedef Signal1_base<void, A1> Base;
typedef Slot1<void, A1> SlotType;
typedef typename Base::SlotList SlotList;
Signal1() { }
void operator()(A1 a1) {
typename Signal1_base<void, A1>::SlotList::iterator end = Signal1_base<void, A1>::m_slots.end();
for (typename Signal1_base<void, A1>::SlotList::iterator
it = Signal1_base<void, A1>::m_slots.begin(); it != end; ++it) {
typename Signal1_base<void, A1>::SlotType* slot = *it;
SlotList copy = Base::m_slots;
for (typename SlotList::iterator it = copy.begin(), end = copy.end(); it != end; ++it) {
SlotType* slot = *it;
(*slot)(a1);
}
}
@ -210,10 +222,6 @@ public:
typedef Slot2<R, A1, A2> SlotType;
typedef std::vector<SlotType*> SlotList;
protected:
SlotList m_slots;
public:
Signal2_base() { }
~Signal2_base() { }
@ -236,6 +244,9 @@ public:
base::remove_from_container(m_slots, static_cast<SlotType*>(slot));
}
protected:
SlotList m_slots;
private:
DISABLE_COPYING(Signal2_base);
};
@ -244,15 +255,19 @@ private:
template<typename R, typename A1, typename A2>
class Signal2 : public Signal2_base<R, A1, A2> {
public:
// GCC needs redefinitions
typedef Signal2_base<R, A1, A2> Base;
typedef Slot2<R, A1, A2> SlotType;
typedef typename Base::SlotList SlotList;
Signal2() {
}
R operator()(A1 a1, A2 a2, R default_result = R()) {
R result(default_result);
typename Signal2_base<R, A1, A2>::SlotList::iterator end = Signal2_base<R, A1, A2>::m_slots.end();
for (typename Signal2_base<R, A1, A2>::SlotList::iterator
it = Signal2_base<R, A1, A2>::m_slots.begin(); it != end; ++it) {
typename Signal2_base<R, A1, A2>::SlotType* slot = *it;
SlotList copy = Base::m_slots;
for (typename SlotList::iterator it = copy.begin(), end = copy.end(); it != end; ++it) {
SlotType* slot = *it;
result = (*slot)(a1, a2);
}
return result;
@ -262,10 +277,9 @@ public:
R operator()(A1 a1, A2 a2, R default_result, const Merger& m) {
R result(default_result);
Merger merger(m);
typename Signal2_base<R, A1, A2>::SlotList::iterator end = Signal2_base<R, A1, A2>::m_slots.end();
for (typename Signal2_base<R, A1, A2>::SlotList::iterator
it = Signal2_base<R, A1, A2>::m_slots.begin(); it != end; ++it) {
typename Signal2_base<R, A1, A2>::SlotType* slot = *it;
SlotList copy = Base::m_slots;
for (typename SlotList::iterator it = copy.begin(), end = copy.end(); it != end; ++it) {
SlotType* slot = *it;
result = merger(result, (*slot)(a1, a2));
}
return result;
@ -277,14 +291,18 @@ public:
template<typename A1, typename A2>
class Signal2<void, A1, A2> : public Signal2_base<void, A1, A2> {
public:
// GCC needs redefinitions
typedef Signal2_base<void, A1, A2> Base;
typedef Slot2<void, A1, A2> SlotType;
typedef typename Base::SlotList SlotList;
Signal2() {
}
void operator()(A1 a1, A2 a2) {
typename Signal2_base<void, A1, A2>::SlotList::iterator end = Signal2_base<void, A1, A2>::m_slots.end();
for (typename Signal2_base<void, A1, A2>::SlotList::iterator
it = Signal2_base<void, A1, A2>::m_slots.begin(); it != end; ++it) {
typename Signal2_base<void, A1, A2>::SlotType* slot = *it;
SlotList copy = Base::m_slots;
for (typename SlotList::iterator it = copy.begin(), end = copy.end(); it != end; ++it) {
SlotType* slot = *it;
(*slot)(a1, a2);
}
}

View File

@ -2,5 +2,8 @@
# Copyright (C) 2014 David Capello
add_library(doc-lib
context.cpp
document.cpp
object.cpp)
documents.cpp
object.cpp
sprites.cpp)

22
src/doc/color_mode.h Normal file
View File

@ -0,0 +1,22 @@
// Aseprite Document Library
// Copyright (c) 2014 David Capello
//
// This file is released under the terms of the MIT license.
// Read LICENSE.txt for more information.
#ifndef DOC_COLOR_MODE_H_INCLUDED
#define DOC_COLOR_MODE_H_INCLUDED
#pragma once
namespace doc {
enum ColorMode {
ColorMode_RGB,
ColorMode_GRAYSCALE,
ColorMode_INDEXED,
ColorMode_BITMAP
};
} // namespace doc
#endif

52
src/doc/context.cpp Normal file
View File

@ -0,0 +1,52 @@
// Aseprite Document Library
// Copyright (c) 2014 David Capello
//
// This file is released under the terms of the MIT license.
// Read LICENSE.txt for more information.
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "doc/context.h"
#include <algorithm>
namespace doc {
Context::Context()
: m_docs(this)
, m_activeDoc(NULL)
{
m_docs.addObserver(this);
}
Context::~Context()
{
setActiveDocument(NULL);
m_docs.removeObserver(this);
}
Document* Context::activeDocument() const
{
return m_activeDoc;
}
void Context::setActiveDocument(Document* doc)
{
m_activeDoc = doc;
notifyObservers(&ContextObserver::onSetActiveDocument, doc);
}
void Context::onAddDocument(Document* doc)
{
m_activeDoc = doc;
}
void Context::onRemoveDocument(Document* doc)
{
if (m_activeDoc == doc)
setActiveDocument(!m_docs.empty() ? m_docs.back() : NULL);
}
} // namespace doc

47
src/doc/context.h Normal file
View File

@ -0,0 +1,47 @@
// Aseprite Document Library
// Copyright (c) 2014 David Capello
//
// This file is released under the terms of the MIT license.
// Read LICENSE.txt for more information.
#ifndef DOC_CONTEXT_H_INCLUDED
#define DOC_CONTEXT_H_INCLUDED
#pragma once
#include "base/compiler_specific.h"
#include "base/disable_copying.h"
#include "base/observable.h"
#include "doc/context_observer.h"
#include "doc/documents.h"
#include "doc/documents_observer.h"
namespace doc {
class Command;
class Document;
class Context : public base::Observable<ContextObserver>
, public DocumentsObserver {
public:
Context();
virtual ~Context();
const Documents& documents() const { return m_docs; }
Documents& documents() { return m_docs; }
Document* activeDocument() const;
void setActiveDocument(Document* doc);
// DocumentsObserver impl
virtual void onAddDocument(Document* doc) OVERRIDE;
virtual void onRemoveDocument(Document* doc) OVERRIDE;
private:
Documents m_docs;
Document* m_activeDoc;
DISABLE_COPYING(Context);
};
} // namespace doc
#endif

View File

@ -0,0 +1,23 @@
// Aseprite Document Library
// Copyright (c) 2014 David Capello
//
// This file is released under the terms of the MIT license.
// Read LICENSE.txt for more information.
#ifndef DOC_CONTEXT_OBSERVER_H_INCLUDED
#define DOC_CONTEXT_OBSERVER_H_INCLUDED
#pragma once
namespace doc {
class Document;
class ContextObserver {
public:
virtual ~ContextObserver() { }
virtual void onSetActiveDocument(Document* document) { }
};
} // namespace doc
#endif

86
src/doc/context_tests.cpp Normal file
View File

@ -0,0 +1,86 @@
// Aseprite Document Library
// Copyright (c) 2014 David Capello
//
// This file is released under the terms of the MIT license.
// Read LICENSE.txt for more information.
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <gtest/gtest.h>
#include "doc/context.h"
#include "doc/document.h"
using namespace doc;
TEST(Context, AddDocument)
{
Context ctx;
Document* doc = ctx.documents().add(32, 28);
ASSERT_TRUE(doc != NULL);
EXPECT_EQ(32, doc->width());
EXPECT_EQ(28, doc->height());
EXPECT_EQ(ColorMode_RGB, doc->colorMode()); // Default color mode is RGB
}
TEST(Context, DeleteDocuments)
{
Context ctx;
Document* doc1 = ctx.documents().add(2, 2);
Document* doc2 = ctx.documents().add(4, 4);
EXPECT_EQ(2, ctx.documents().size());
delete doc1;
delete doc2;
EXPECT_EQ(0, ctx.documents().size());
}
TEST(Context, CloseAndDeleteDocuments)
{
Context ctx;
EXPECT_EQ(0, ctx.documents().size());
Document* doc1 = ctx.documents().add(2, 2);
Document* doc2 = ctx.documents().add(4, 4);
EXPECT_EQ(2, ctx.documents().size());
doc1->close();
EXPECT_EQ(1, ctx.documents().size());
delete doc1;
delete doc2;
EXPECT_EQ(0, ctx.documents().size());
}
TEST(Context, SwitchContext)
{
Context ctx1, ctx2;
Document* doc1 = new Document();
Document* doc2 = new Document();
doc1->setContext(&ctx1);
doc2->setContext(&ctx2);
EXPECT_EQ(&ctx1, doc1->context());
EXPECT_EQ(&ctx2, doc2->context());
doc1->setContext(&ctx2);
doc2->setContext(&ctx1);
EXPECT_EQ(&ctx2, doc1->context());
EXPECT_EQ(&ctx1, doc2->context());
ctx2.documents().remove(doc1);
ctx1.documents().remove(doc2);
ctx1.documents().add(doc1);
ctx2.documents().add(doc2);
EXPECT_EQ(&ctx1, doc1->context());
EXPECT_EQ(&ctx2, doc2->context());
}
int main(int argc, char** argv)
{
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}

View File

@ -10,17 +10,60 @@
#include "doc/document.h"
#include "base/path.h"
#include "doc/context.h"
#include "doc/export_data.h"
#include "doc/sprite.h"
namespace doc {
Document::Document()
: m_ctx(NULL)
, m_sprites(this)
{
}
Document::~Document()
{
removeFromContext();
}
void Document::setContext(Context* ctx)
{
if (ctx == m_ctx)
return;
removeFromContext();
m_ctx = ctx;
if (ctx)
ctx->documents().add(this);
}
int Document::width() const
{
return sprite()->getWidth();
}
int Document::height() const
{
return sprite()->getHeight();
}
ColorMode Document::colorMode() const
{
return (ColorMode)sprite()->getPixelFormat();
}
std::string Document::name() const
{
return base::get_file_name(m_filename);
}
void Document::setFilename(const std::string& filename)
{
m_filename = filename;
notifyObservers(&DocumentObserver::onFileNameChanged, this);
}
void Document::setExportData(const ExportDataPtr& data)
@ -28,4 +71,17 @@ void Document::setExportData(const ExportDataPtr& data)
m_exportData = data;
}
void Document::close()
{
removeFromContext();
}
void Document::removeFromContext()
{
if (m_ctx) {
m_ctx->documents().remove(this);
m_ctx = NULL;
}
}
} // namespace doc

Some files were not shown because too many files have changed in this diff Show More