1 | // Aseprite |
2 | // Copyright (C) 2018-2021 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_UI_COLOR_BAR_H_INCLUDED |
9 | #define APP_UI_COLOR_BAR_H_INCLUDED |
10 | #pragma once |
11 | |
12 | #include "app/color.h" |
13 | #include "app/context_observer.h" |
14 | #include "app/doc_observer.h" |
15 | #include "app/docs_observer.h" |
16 | #include "app/tilemap_mode.h" |
17 | #include "app/tileset_mode.h" |
18 | #include "app/ui/button_set.h" |
19 | #include "app/ui/color_button.h" |
20 | #include "app/ui/input_chain_element.h" |
21 | #include "app/ui/palette_view.h" |
22 | #include "app/ui/tile_button.h" |
23 | #include "doc/object_id.h" |
24 | #include "doc/palette_gradient_type.h" |
25 | #include "doc/pixel_format.h" |
26 | #include "doc/sort_palette.h" |
27 | #include "doc/tileset.h" |
28 | #include "obs/connection.h" |
29 | #include "obs/signal.h" |
30 | #include "ui/box.h" |
31 | #include "ui/button.h" |
32 | #include "ui/splitter.h" |
33 | #include "ui/view.h" |
34 | |
35 | namespace ui { |
36 | class TooltipManager; |
37 | } |
38 | |
39 | namespace app { |
40 | class ColorButton; |
41 | class ColorSpectrum; |
42 | class ColorTintShadeTone; |
43 | class ColorWheel; |
44 | class CommandExecutionEvent; |
45 | class PaletteIndexChangeEvent; |
46 | class ; |
47 | class PalettesLoader; |
48 | |
49 | class ColorBar : public ui::Box |
50 | , public PaletteViewDelegate |
51 | , public ContextObserver |
52 | , public DocObserver |
53 | , public InputChainElement { |
54 | static ColorBar* m_instance; |
55 | public: |
56 | enum class ColorSelector { |
57 | NONE, |
58 | SPECTRUM, |
59 | RGB_WHEEL, |
60 | RYB_WHEEL, |
61 | TINT_SHADE_TONE, |
62 | NORMAL_MAP_WHEEL, |
63 | }; |
64 | |
65 | static ColorBar* instance() { return m_instance; } |
66 | |
67 | ColorBar(int align, ui::TooltipManager* tooltipManager); |
68 | ~ColorBar(); |
69 | |
70 | void setPixelFormat(PixelFormat pixelFormat); |
71 | |
72 | app::Color getFgColor() const; |
73 | app::Color getBgColor() const; |
74 | void setFgColor(const app::Color& color); |
75 | void setBgColor(const app::Color& color); |
76 | |
77 | doc::tile_index getFgTile() const; |
78 | doc::tile_index getBgTile() const; |
79 | void setFgTile(doc::tile_t tile); |
80 | void setBgTile(doc::tile_t tile); |
81 | |
82 | PaletteView* getPaletteView() { return &m_paletteView; } |
83 | PaletteView* getTilesView() { return &m_tilesView; } |
84 | |
85 | ColorSelector getColorSelector() const; |
86 | void setColorSelector(ColorSelector selector); |
87 | |
88 | // Used by the Palette Editor command to change the status of button |
89 | // when the visibility of the dialog changes. |
90 | bool inEditMode() const; |
91 | void setEditMode(bool state); |
92 | |
93 | TilemapMode tilemapMode() const; |
94 | void setTilemapMode(TilemapMode mode); |
95 | |
96 | TilesetMode tilesetMode() const; |
97 | void setTilesetMode(const TilesetMode mode); |
98 | |
99 | ColorButton* fgColorButton() { return &m_fgColor; } |
100 | ColorButton* bgColorButton() { return &m_bgColor; } |
101 | |
102 | // ContextObserver impl |
103 | void onActiveSiteChange(const Site& site) override; |
104 | |
105 | // DocObserver impl |
106 | void onGeneralUpdate(DocEvent& ev) override; |
107 | void onTilesetChanged(DocEvent& ev) override; |
108 | |
109 | // InputChainElement impl |
110 | void onNewInputPriority(InputChainElement* element, |
111 | const ui::Message* msg) override; |
112 | bool onCanCut(Context* ctx) override; |
113 | bool onCanCopy(Context* ctx) override; |
114 | bool onCanPaste(Context* ctx) override; |
115 | bool onCanClear(Context* ctx) override; |
116 | bool onCut(Context* ctx) override; |
117 | bool onCopy(Context* ctx) override; |
118 | bool onPaste(Context* ctx) override; |
119 | bool onClear(Context* ctx) override; |
120 | void onCancel(Context* ctx) override; |
121 | |
122 | obs::signal<void()> ChangeSelection; |
123 | |
124 | protected: |
125 | void onSizeHint(ui::SizeHintEvent& ev) override; |
126 | void onAppPaletteChange(); |
127 | void onFocusPaletteView(ui::Message* msg); |
128 | void onFocusTilesView(ui::Message* msg); |
129 | void onBeforeExecuteCommand(CommandExecutionEvent& ev); |
130 | void onAfterExecuteCommand(CommandExecutionEvent& ev); |
131 | void onSwitchPalEditMode(); |
132 | void onPaletteButtonClick(); |
133 | void onTilesButtonClick(); |
134 | void onTilesButtonRightClick(); |
135 | void onTilesetModeButtonClick(); |
136 | void onTilesetOptionsClick(); |
137 | void onRemapPalButtonClick(); |
138 | void onRemapTilesButtonClick(); |
139 | void onPaletteIndexChange(PaletteIndexChangeEvent& ev); |
140 | void onFgColorChangeFromPreferences(); |
141 | void onBgColorChangeFromPreferences(); |
142 | void onFgTileChangeFromPreferences(); |
143 | void onBgTileChangeFromPreferences(); |
144 | void onFgColorButtonBeforeChange(app::Color& color); |
145 | void onFgColorButtonChange(const app::Color& color); |
146 | void onBgColorButtonChange(const app::Color& color); |
147 | void onColorButtonChange(const app::Color& color); |
148 | void onFgTileButtonChange(doc::tile_t tile); |
149 | void onBgTileButtonChange(doc::tile_t tile); |
150 | void onPickSpectrum(const app::Color& color, ui::MouseButton button); |
151 | void onReverseColors(); |
152 | void onSortBy(doc::SortPaletteBy channel); |
153 | void onGradient(GradientType gradientType); |
154 | void onFixWarningClick(ColorButton* colorButton, ui::Button* warningIcon); |
155 | void onTimerTick(); |
156 | void setAscending(bool ascending); |
157 | |
158 | // PaletteViewDelegate impl |
159 | bool onIsPaletteViewActive(PaletteView* paletteView) const override; |
160 | void onPaletteViewIndexChange(int index, ui::MouseButton button) override; |
161 | void onPaletteViewModification(const doc::Palette* newPalette, PaletteViewModification mod) override; |
162 | void onPaletteViewChangeSize(PaletteView* paletteView, int boxsize) override; |
163 | void onPaletteViewPasteColors(const Palette* fromPal, const doc::PalettePicks& from, const doc::PalettePicks& to) override; |
164 | app::Color onPaletteViewGetForegroundIndex() override; |
165 | app::Color onPaletteViewGetBackgroundIndex() override; |
166 | doc::tile_index onPaletteViewGetForegroundTile() override; |
167 | doc::tile_index onPaletteViewGetBackgroundTile() override; |
168 | void onTilesViewClearTiles(const doc::PalettePicks& picks) override; |
169 | void onTilesViewResize(const int newSize) override; |
170 | void onTilesViewDragAndDrop(doc::Tileset* tileset, |
171 | doc::PalettePicks& picks, |
172 | int& currentEntry, |
173 | const int beforeIndex, |
174 | const bool isCopy) override; |
175 | void onTilesViewIndexChange(int index, ui::MouseButton button) override; |
176 | |
177 | private: |
178 | void showRemapPal(); |
179 | void showRemapTiles(); |
180 | void hideRemapPal(); |
181 | void hideRemapTiles(); |
182 | void setPalette(const doc::Palette* newPalette, const std::string& actionText); |
183 | void setTransparentIndex(int index); |
184 | void updateWarningIcon(const app::Color& color, ui::Button* warningIcon); |
185 | int setPaletteEntry(const app::Color& color); |
186 | void updateCurrentSpritePalette(const char* operationName); |
187 | void setupTooltips(ui::TooltipManager* tooltipManager); |
188 | void registerCommands(); |
189 | void showPaletteSortOptions(); |
190 | void showPalettePresets(); |
191 | void showPaletteOptions(); |
192 | bool canEditTiles() const; |
193 | void updateFromTilemapMode(); |
194 | static void fixColorIndex(ColorButton& color); |
195 | |
196 | class ScrollableView : public ui::View { |
197 | public: |
198 | ScrollableView(); |
199 | protected: |
200 | void onInitTheme(ui::InitThemeEvent& ev) override; |
201 | }; |
202 | |
203 | class WarningIcon; |
204 | |
205 | ui::HBox m_palHBox; |
206 | ui::HBox m_tilesHBox; |
207 | ButtonSet m_editPal; |
208 | ButtonSet m_buttons; |
209 | ButtonSet m_tilesButton; |
210 | ButtonSet m_tilesetModeButtons; |
211 | std::unique_ptr<PalettePopup> ; |
212 | ui::Splitter m_splitter; |
213 | ui::VBox m_palettePlaceholder; |
214 | ui::VBox m_selectorPlaceholder; |
215 | ui::Splitter m_splitterPalTil; |
216 | ScrollableView m_scrollablePalView; |
217 | ScrollableView m_scrollableTilesView; |
218 | PaletteView m_paletteView; |
219 | PaletteView m_tilesView; |
220 | ui::Button m_remapPalButton; |
221 | ui::Button m_remapTilesButton; |
222 | ui::VBox m_colorHelpers; |
223 | ui::HBox m_tilesHelpers; |
224 | ColorSelector m_selector; |
225 | ColorTintShadeTone* m_tintShadeTone; |
226 | ColorSpectrum* m_spectrum; |
227 | ColorWheel* m_wheel; |
228 | ColorButton m_fgColor; |
229 | ColorButton m_bgColor; |
230 | WarningIcon* m_fgWarningIcon; |
231 | WarningIcon* m_bgWarningIcon; |
232 | TileButton m_fgTile; |
233 | TileButton m_bgTile; |
234 | |
235 | // True when the user clicks the PaletteView so we're changing the |
236 | // color from the palette view. |
237 | bool m_fromPalView; |
238 | |
239 | // If m_syncingWithPref is true it means that the eyedropper was |
240 | // used to change the color. |
241 | bool m_fromPref; |
242 | |
243 | bool m_fromFgButton; |
244 | bool m_fromBgButton; |
245 | |
246 | std::unique_ptr<doc::Palette> m_oldPalette; |
247 | std::unique_ptr<doc::Tileset> m_oldTileset; |
248 | Doc* m_lastDocument; |
249 | doc::ObjectId m_lastTilesetId; |
250 | bool m_ascending; |
251 | obs::scoped_connection m_beforeCmdConn; |
252 | obs::scoped_connection m_afterCmdConn; |
253 | obs::scoped_connection m_fgConn; |
254 | obs::scoped_connection m_bgConn; |
255 | obs::scoped_connection m_fgTileConn; |
256 | obs::scoped_connection m_bgTileConn; |
257 | obs::scoped_connection m_sepConn; |
258 | obs::scoped_connection m_appPalChangeConn; |
259 | ui::MouseButton m_lastButton; |
260 | |
261 | // True if the editing mode is on. |
262 | bool m_editMode; |
263 | |
264 | // True if we should be putting/setting tiles. |
265 | TilemapMode m_tilemapMode; |
266 | TilesetMode m_tilesetMode; |
267 | |
268 | // Timer to redraw editors after a palette change. |
269 | ui::Timer m_redrawTimer; |
270 | bool m_redrawAll; |
271 | |
272 | // True if a palette change must be implant in the UndoHistory |
273 | // (e.g. when two or more changes in the palette are made in a |
274 | // very short time). |
275 | bool m_implantChange; |
276 | |
277 | // True if the App::PaletteChange signal is generated by this same |
278 | // ColorBar. |
279 | bool m_selfPalChange; |
280 | |
281 | double m_splitterPalTilPos; |
282 | }; |
283 | |
284 | class DisableColorBarEditMode { |
285 | public: |
286 | DisableColorBarEditMode() |
287 | : m_colorBar(ColorBar::instance()) |
288 | , m_oldMode(m_colorBar->inEditMode()) { |
289 | if (m_oldMode) |
290 | m_colorBar->setEditMode(false); |
291 | } |
292 | ~DisableColorBarEditMode() { |
293 | if (m_oldMode) |
294 | m_colorBar->setEditMode(true); |
295 | } |
296 | private: |
297 | ColorBar* m_colorBar; |
298 | bool m_oldMode; |
299 | }; |
300 | |
301 | } // namespace app |
302 | |
303 | #endif |
304 | |