1 | // Aseprite |
2 | // Copyright (C) 2019-2020 Igara Studio S.A. |
3 | // Copyright (C) 2016-2018 David Capello |
4 | // |
5 | // This program is distributed under the terms of |
6 | // the End-User License Agreement for Aseprite. |
7 | |
8 | #ifdef HAVE_CONFIG_H |
9 | #include "config.h" |
10 | #endif |
11 | |
12 | #include "app/app.h" |
13 | #include "app/cmd/set_palette.h" |
14 | #include "app/commands/command.h" |
15 | #include "app/commands/new_params.h" |
16 | #include "app/console.h" |
17 | #include "app/context.h" |
18 | #include "app/context_access.h" |
19 | #include "app/i18n/strings.h" |
20 | #include "app/pref/preferences.h" |
21 | #include "app/tx.h" |
22 | #include "doc/palette.h" |
23 | #include "fmt/format.h" |
24 | |
25 | #ifdef ENABLE_SCRIPTING |
26 | #include "app/script/luacpp.h" |
27 | #endif |
28 | |
29 | namespace app { |
30 | |
31 | enum class AddColorSource { Fg, Bg, Color }; |
32 | |
33 | template<> |
34 | void Param<AddColorSource>::fromString(const std::string& value) |
35 | { |
36 | if (value == "fg" || |
37 | value == "foreground" ) |
38 | setValue(AddColorSource::Fg); |
39 | else if (value == "bg" || |
40 | value == "background" ) |
41 | setValue(AddColorSource::Bg); |
42 | else |
43 | setValue(AddColorSource::Color); |
44 | } |
45 | |
46 | #ifdef ENABLE_SCRIPTING |
47 | template<> |
48 | void Param<AddColorSource>::fromLua(lua_State* L, int index) |
49 | { |
50 | fromString(lua_tostring(L, index)); |
51 | } |
52 | #endif // ENABLE_SCRIPTING |
53 | |
54 | struct AddColorParams : public NewParams { |
55 | Param<AddColorSource> source { this, AddColorSource::Color, "source" }; |
56 | Param<app::Color> color { this, app::Color::fromMask(), "color" }; |
57 | }; |
58 | |
59 | class AddColorCommand : public CommandWithNewParams<AddColorParams> { |
60 | public: |
61 | AddColorCommand(); |
62 | protected: |
63 | bool onEnabled(Context* ctx) override; |
64 | void onExecute(Context* ctx) override; |
65 | std::string onGetFriendlyName() const override; |
66 | }; |
67 | |
68 | AddColorCommand::AddColorCommand() |
69 | : CommandWithNewParams<AddColorParams>(CommandId::AddColor(), CmdUIOnlyFlag) |
70 | { |
71 | } |
72 | |
73 | bool AddColorCommand::onEnabled(Context* ctx) |
74 | { |
75 | return ctx->checkFlags(ContextFlags::ActiveDocumentIsWritable); |
76 | } |
77 | |
78 | void AddColorCommand::onExecute(Context* ctx) |
79 | { |
80 | app::Color appColor; |
81 | |
82 | switch (params().source()) { |
83 | case AddColorSource::Fg: |
84 | appColor = Preferences::instance().colorBar.fgColor(); |
85 | break; |
86 | case AddColorSource::Bg: |
87 | appColor = Preferences::instance().colorBar.bgColor(); |
88 | break; |
89 | case AddColorSource::Color: |
90 | appColor = params().color(); |
91 | break; |
92 | } |
93 | |
94 | Palette* pal = ctx->activeSite().palette(); |
95 | ASSERT(pal); |
96 | if (!pal) |
97 | return; |
98 | |
99 | try { |
100 | std::unique_ptr<Palette> newPalette(new Palette(*pal)); |
101 | color_t color = doc::rgba( |
102 | appColor.getRed(), |
103 | appColor.getGreen(), |
104 | appColor.getBlue(), |
105 | appColor.getAlpha()); |
106 | int index = newPalette->findExactMatch( |
107 | appColor.getRed(), |
108 | appColor.getGreen(), |
109 | appColor.getBlue(), |
110 | appColor.getAlpha(), -1); |
111 | |
112 | // It should be -1, because the user has pressed the warning |
113 | // button that is available only when the color isn't in the |
114 | // palette. |
115 | ASSERT(index < 0); |
116 | if (index >= 0) |
117 | return; |
118 | |
119 | ContextWriter writer(ctx); |
120 | Doc* document(writer.document()); |
121 | Sprite* sprite = writer.sprite(); |
122 | if (!document || !sprite) { |
123 | ASSERT(false); |
124 | return; |
125 | } |
126 | |
127 | newPalette->addEntry(color); |
128 | index = newPalette->size()-1; |
129 | |
130 | if (document) { |
131 | frame_t frame = writer.frame(); |
132 | |
133 | Tx tx(writer.context(), friendlyName(), ModifyDocument); |
134 | tx(new cmd::SetPalette(sprite, frame, newPalette.get())); |
135 | tx.commit(); |
136 | } |
137 | } |
138 | catch (base::Exception& e) { |
139 | Console::showException(e); |
140 | } |
141 | } |
142 | |
143 | std::string AddColorCommand::onGetFriendlyName() const |
144 | { |
145 | std::string source; |
146 | switch (params().source()) { |
147 | case AddColorSource::Fg: source = Strings::commands_AddColor_Foreground(); break; |
148 | case AddColorSource::Bg: source = Strings::commands_AddColor_Background(); break; |
149 | case AddColorSource::Color: source = Strings::commands_AddColor_Specific(); break; |
150 | } |
151 | return fmt::format(getBaseFriendlyName(), source); |
152 | } |
153 | |
154 | Command* CommandFactory::createAddColorCommand() |
155 | { |
156 | return new AddColorCommand; |
157 | } |
158 | |
159 | } // namespace app |
160 | |