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