From 354f6a15fa4dfe6d118a301572036895793c5693 Mon Sep 17 00:00:00 2001 From: David Capello Date: Thu, 2 Feb 2012 20:05:26 -0300 Subject: [PATCH] Add context listeners. --- src/CMakeLists.txt | 1 + src/context.cpp | 20 +++++++++- src/context.h | 9 +++++ src/context_listener.h | 36 ++++++++++++++++++ src/context_listener_list.cpp | 70 +++++++++++++++++++++++++++++++++++ src/context_listener_list.h | 48 ++++++++++++++++++++++++ 6 files changed, 183 insertions(+), 1 deletion(-) create mode 100644 src/context_listener.h create mode 100644 src/context_listener_list.cpp create mode 100644 src/context_listener_list.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 6e873e2ae..b69a70855 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -97,6 +97,7 @@ add_library(aseprite-library console.cpp context.cpp context_flags.cpp + context_listener_list.cpp document.cpp documents.cpp drop_files.cpp diff --git a/src/context.cpp b/src/context.cpp index e7ed1b781..0d2d8feaf 100644 --- a/src/context.cpp +++ b/src/context.cpp @@ -103,9 +103,13 @@ Document* Context::getActiveDocument() const void Context::setActiveDocument(Document* document) { + m_listeners.notifyActiveDocumentBeforeChange(this); + m_activeDocument = document; onSetActiveDocument(document); + + m_listeners.notifyActiveDocumentAfterChange(this); } void Context::executeCommand(Command* command, Params* params) @@ -115,6 +119,7 @@ void Context::executeCommand(Command* command, Params* params) ASSERT(command != NULL); PRINTF("Executing '%s' command.\n", command->short_name()); + m_listeners.notifyCommandBeforeExecution(this); try { m_flags.update(this); @@ -122,8 +127,11 @@ void Context::executeCommand(Command* command, Params* params) if (params) command->loadParams(params); - if (command->isEnabled(this)) + if (command->isEnabled(this)) { command->execute(this); + + m_listeners.notifyCommandAfterExecution(this); + } } catch (base::Exception& e) { PRINTF("Exception caught executing '%s' command\n%s\n", @@ -151,6 +159,16 @@ void Context::executeCommand(Command* command, Params* params) #endif } +void Context::addListener(ContextListener* listener) +{ + m_listeners.add(listener); +} + +void Context::removeListener(ContextListener* listener) +{ + m_listeners.remove(listener); +} + void Context::onAddDocument(Document* document) { // do nothing diff --git a/src/context.h b/src/context.h index 8bcc6af86..bbb464a8f 100644 --- a/src/context.h +++ b/src/context.h @@ -22,9 +22,13 @@ #include "base/disable_copying.h" #include "base/exception.h" #include "context_flags.h" +#include "context_listener.h" +#include "context_listener_list.h" #include "documents.h" #include "settings/settings.h" +#include + class Command; class Document; class Params; @@ -65,6 +69,9 @@ public: virtual void executeCommand(Command* command, Params* params = NULL); + void addListener(ContextListener* listener); + void removeListener(ContextListener* listener); + protected: // The "settings" are deleted automatically in the ~Context destructor @@ -91,6 +98,8 @@ private: // Last updated flags. ContextFlags m_flags; + ContextListenerList m_listeners; + DISABLE_COPYING(Context); }; diff --git a/src/context_listener.h b/src/context_listener.h new file mode 100644 index 000000000..1b8b2edb6 --- /dev/null +++ b/src/context_listener.h @@ -0,0 +1,36 @@ +/* ASEPRITE + * Copyright (C) 2001-2012 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 CONTEXT_LISTENER_H_INCLUDED +#define CONTEXT_LISTENER_H_INCLUDED + +class Context; + +// Listener of context events. The default implementation does nothing +// in each handler, so you can override the required events. +class ContextListener +{ +public: + virtual ~ContextListener() { } + virtual void onActiveDocumentBeforeChange(Context* context) { } + virtual void onActiveDocumentAfterChange(Context* context) { } + virtual void onCommandBeforeExecution(Context* context) { } + virtual void onCommandAfterExecution(Context* context) { } +}; + +#endif diff --git a/src/context_listener_list.cpp b/src/context_listener_list.cpp new file mode 100644 index 000000000..ae3c9e389 --- /dev/null +++ b/src/context_listener_list.cpp @@ -0,0 +1,70 @@ +/* ASEPRITE + * Copyright (C) 2001-2012 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 + */ + +#include "config.h" + +#include "context_listener_list.h" + +#include "context_listener.h" + +#include +#include + +ContextListenerList::ContextListenerList() +{ +} + +void ContextListenerList::add(ContextListener* listener) +{ + m_listener.push_back(listener); +} + +void ContextListenerList::remove(ContextListener* listener) +{ + iterator it = std::find(m_listener.begin(), m_listener.end(), listener); + ASSERT(it != m_listener.end()); + m_listener.erase(it); +} + +void ContextListenerList::notifyActiveDocumentBeforeChange(Context* context) +{ + list_type copy = m_listener; + std::for_each(copy.begin(), copy.end(), + std::bind2nd(std::mem_fun(&ContextListener::onActiveDocumentBeforeChange), context)); +} + +void ContextListenerList::notifyActiveDocumentAfterChange(Context* context) +{ + list_type copy = m_listener; + std::for_each(copy.begin(), copy.end(), + std::bind2nd(std::mem_fun(&ContextListener::onActiveDocumentAfterChange), context)); +} + +void ContextListenerList::notifyCommandBeforeExecution(Context* context) +{ + list_type copy = m_listener; + std::for_each(copy.begin(), copy.end(), + std::bind2nd(std::mem_fun(&ContextListener::onCommandBeforeExecution), context)); +} + +void ContextListenerList::notifyCommandAfterExecution(Context* context) +{ + list_type copy = m_listener; + std::for_each(copy.begin(), copy.end(), + std::bind2nd(std::mem_fun(&ContextListener::onCommandAfterExecution), context)); +} diff --git a/src/context_listener_list.h b/src/context_listener_list.h new file mode 100644 index 000000000..0935db4a2 --- /dev/null +++ b/src/context_listener_list.h @@ -0,0 +1,48 @@ +/* ASEPRITE + * Copyright (C) 2001-2012 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 CONTEXT_LISTENER_LIST_H_INCLUDED +#define CONTEXT_LISTENER_LIST_H_INCLUDED + +#include + +class Context; +class ContextListener; + +class ContextListenerList +{ +public: + typedef std::vector list_type; + typedef std::vector::iterator iterator; + typedef std::vector::const_iterator const_iterator; + + ContextListenerList(); + + void add(ContextListener* listener); + void remove(ContextListener* listener); + + void notifyActiveDocumentBeforeChange(Context* context); + void notifyActiveDocumentAfterChange(Context* context); + void notifyCommandBeforeExecution(Context* context); + void notifyCommandAfterExecution(Context* context); + +private: + list_type m_listener; +}; + +#endif