1 // Aseprite
2 // Copyright (C) 2018 David Capello
3 //
4 // This program is distributed under the terms of
5 // the End-User License Agreement for Aseprite.
6
7 #ifdef HAVE_CONFIG_H
8 #include "config.h"
9 #endif
10
11 #include "app/app.h"
12 #include "app/cmd/set_cel_opacity.h"
13 #include "app/commands/command.h"
14 #include "app/commands/params.h"
15 #include "app/context.h"
16 #include "app/context_access.h"
17 #include "app/i18n/strings.h"
18 #include "app/modules/gui.h"
19 #include "app/transaction.h"
20 #include "app/ui/timeline/timeline.h"
21 #include "doc/cel.h"
22 #include "doc/cels_range.h"
23 #include "doc/sprite.h"
24 #include "fmt/format.h"
25
26 #include <string>
27
28 namespace app {
29
30 class CelOpacityCommand : public Command {
31 public:
32 CelOpacityCommand();
33
34 protected:
onNeedsParams() const35 bool onNeedsParams() const override { return true; }
36 void onLoadParams(const Params& params) override;
37 bool onEnabled(Context* context) override;
38 void onExecute(Context* context) override;
39 std::string onGetFriendlyName() const override;
40
41 private:
42 int m_opacity;
43 };
44
CelOpacityCommand()45 CelOpacityCommand::CelOpacityCommand()
46 : Command(CommandId::CelOpacity(), CmdUIOnlyFlag)
47 {
48 m_opacity = 255;
49 }
50
onLoadParams(const Params & params)51 void CelOpacityCommand::onLoadParams(const Params& params)
52 {
53 m_opacity = params.get_as<int>("opacity");
54 m_opacity = MID(0, m_opacity, 255);
55 }
56
onEnabled(Context * context)57 bool CelOpacityCommand::onEnabled(Context* context)
58 {
59 return context->checkFlags(ContextFlags::ActiveDocumentIsWritable |
60 ContextFlags::HasActiveCel);
61 }
62
onExecute(Context * context)63 void CelOpacityCommand::onExecute(Context* context)
64 {
65 ContextWriter writer(context);
66 Layer* layer = writer.layer();
67 Cel* cel = writer.cel();
68 if (!cel ||
69 layer->isBackground() ||
70 !layer->isEditable() ||
71 cel->opacity() == m_opacity)
72 return;
73
74 {
75 Transaction transaction(writer.context(), "Set Cel Opacity");
76
77 // TODO the range of selected cels should be in app::Site.
78 DocRange range = App::instance()->timeline()->range();
79 if (!range.enabled()) {
80 range.startRange(layer, cel->frame(), DocRange::kCels);
81 range.endRange(layer, cel->frame());
82 }
83
84 for (Cel* cel : cel->sprite()->uniqueCels(range.selectedFrames())) {
85 if (range.contains(cel->layer())) {
86 if (!cel->layer()->isBackground() &&
87 cel->layer()->isEditable() &&
88 m_opacity != cel->opacity()) {
89 transaction.execute(new cmd::SetCelOpacity(cel, m_opacity));
90 }
91 }
92 }
93
94 transaction.commit();
95 }
96
97 update_screen_for_document(writer.document());
98 }
99
onGetFriendlyName() const100 std::string CelOpacityCommand::onGetFriendlyName() const
101 {
102 return fmt::format(getBaseFriendlyName(),
103 m_opacity,
104 int(100.0 * m_opacity / 255.0));
105 }
106
createCelOpacityCommand()107 Command* CommandFactory::createCelOpacityCommand()
108 {
109 return new CelOpacityCommand;
110 }
111
112 } // namespace app
113