1// Aseprite
2// Copyright (C) 2018-2022 Igara Studio S.A.
3// Copyright (C) 2001-2018 David Capello
4//
5// This program is distributed under the terms of
6// the End-User License Agreement for Aseprite.
7
8#ifndef APP_CONTEXT_H_INCLUDED
9#define APP_CONTEXT_H_INCLUDED
10#pragma once
11
12#include "app/commands/params.h"
13#include "app/context_flags.h"
14#include "app/context_observer.h"
15#include "app/docs.h"
16#include "app/docs_observer.h"
17#include "base/disable_copying.h"
18#include "base/exception.h"
19#include "doc/frame.h"
20#include "obs/observable.h"
21#include "obs/signal.h"
22
23#include <memory>
24#include <vector>
25
26namespace doc {
27 class Layer;
28 class PalettePicks;
29}
30
31namespace app {
32 class ActiveSiteHandler;
33 class Clipboard;
34 class Command;
35 class Doc;
36 class DocRange;
37 class DocView;
38 class Preferences;
39
40 class CommandResult {
41 public:
42 enum Type {
43 kOk,
44 // Exception throw (e.g. cannot lock sprite)
45 kError,
46 // Canceled by user.
47 kCanceled,
48 };
49
50 CommandResult(Type type = Type::kOk) : m_type(type) { }
51 Type type() const { return m_type; }
52 void reset() { m_type = Type::kOk; }
53
54 private:
55 Type m_type;
56 };
57
58 class CommandPreconditionException : public base::Exception {
59 public:
60 CommandPreconditionException() throw()
61 : base::Exception("Cannot execute the command because its pre-conditions are false.") { }
62 };
63
64 class CommandExecutionEvent {
65 public:
66 CommandExecutionEvent(Command* command)
67 : m_command(command), m_canceled(false) {
68 }
69
70 Command* command() const { return m_command; }
71
72 // True if the command was canceled or simulated by an
73 // observer/signal slot.
74 bool isCanceled() const { return m_canceled; }
75 void cancel() {
76 m_canceled = true;
77 }
78
79 private:
80 Command* m_command;
81 bool m_canceled;
82 };
83
84 class Context : public obs::observable<ContextObserver>,
85 public DocsObserver {
86 public:
87 Context();
88 virtual ~Context();
89
90 const Docs& documents() const { return m_docs; }
91 Docs& documents() { return m_docs; }
92
93 Preferences& preferences() const;
94 Clipboard* clipboard() const;
95
96 virtual bool isUIAvailable() const { return false; }
97 virtual bool isRecordingMacro() const { return false; }
98 virtual bool isExecutingMacro() const { return false; }
99 virtual bool isExecutingScript() const { return false; }
100
101 bool checkFlags(uint32_t flags) const { return m_flags.check(flags); }
102 void updateFlags() { m_flags.update(this); }
103
104 void sendDocumentToTop(Doc* doc);
105 void closeDocument(Doc* doc);
106
107 Site activeSite() const;
108 Doc* activeDocument() const;
109 void setActiveDocument(Doc* document);
110 void setActiveLayer(doc::Layer* layer);
111 void setActiveFrame(doc::frame_t frame);
112 void setRange(const DocRange& range);
113 void setSelectedColors(const doc::PalettePicks& picks);
114 void setSelectedTiles(const doc::PalettePicks& picks);
115 bool hasModifiedDocuments() const;
116 void notifyActiveSiteChanged();
117
118 void executeCommandFromMenuOrShortcut(Command* command, const Params& params = Params());
119 virtual void executeCommand(Command* command, const Params& params = Params());
120
121 void setCommandResult(const CommandResult& result);
122 const CommandResult& commandResult() { return m_result; }
123
124 virtual DocView* getFirstDocView(Doc* document) const {
125 return nullptr;
126 }
127
128 obs::signal<void (CommandExecutionEvent&)> BeforeCommandExecution;
129 obs::signal<void (CommandExecutionEvent&)> AfterCommandExecution;
130
131 protected:
132 // DocsObserver impl
133 void onAddDocument(Doc* doc) override;
134 void onRemoveDocument(Doc* doc) override;
135
136 virtual void onGetActiveSite(Site* site) const;
137 virtual void onSetActiveDocument(Doc* doc, bool notify);
138 virtual void onSetActiveLayer(doc::Layer* layer);
139 virtual void onSetActiveFrame(const doc::frame_t frame);
140 virtual void onSetRange(const DocRange& range);
141 virtual void onSetSelectedColors(const doc::PalettePicks& picks);
142 virtual void onSetSelectedTiles(const doc::PalettePicks& picks);
143 virtual void onCloseDocument(Doc* doc);
144
145 Doc* lastSelectedDoc() { return m_lastSelectedDoc; }
146
147 private:
148 ActiveSiteHandler* activeSiteHandler() const;
149
150 // This must be defined before m_docs because ActiveSiteHandler
151 // will be an observer of all documents.
152 mutable std::unique_ptr<ActiveSiteHandler> m_activeSiteHandler;
153 mutable Docs m_docs;
154 ContextFlags m_flags; // Last updated flags.
155 Doc* m_lastSelectedDoc;
156 mutable std::unique_ptr<Preferences> m_preferences;
157
158 // Result of the execution of a command.
159 CommandResult m_result;
160
161 DISABLE_COPYING(Context);
162 };
163
164} // namespace app
165
166#endif
167