1 #pragma once
2 
3 #ifndef TPALETTE_H
4 #define TPALETTE_H
5 
6 // TnzCore includes
7 #include "tpersist.h"
8 #include "timage.h"
9 #include "tfilepath.h"
10 #include "tpixel.h"
11 #include "tcolorstyles.h"
12 
13 // Qt includes
14 #include <QMutex>
15 
16 #undef DVAPI
17 #undef DVVAR
18 #ifdef TVRENDER_EXPORTS
19 #define DVAPI DV_EXPORT_API
20 #define DVVAR DV_EXPORT_VAR
21 #else
22 #define DVAPI DV_IMPORT_API
23 #define DVVAR DV_IMPORT_VAR
24 #endif
25 
26 #ifdef _MSC_VER
27 #pragma warning(push)
28 #pragma warning(disable : 4251)
29 #endif
30 
31 //=========================================================
32 
33 //    Forward declarations
34 
35 class TPixelRGBM32;
36 
37 typedef TSmartPointerT<TPalette> TPaletteP;
38 
39 //=========================================================
40 
41 //*****************************************************************************************
42 //    TPalette  declaration
43 //*****************************************************************************************
44 
45 /*!
46   \brief    The class representing a Toonz palette object.
47 
48   \par Rationale
49     A palette is a collection of <I>color styles</I> that adds a level of
50 indirection
51     on color selections when drawing certain graphical objects.
52 \n
53     Palette-based objects store <I>style identifiers</I> into an associated
54 palette object,
55     rather than the colors directly. When a color needs to be accessed, the
56 palette
57     objects is queried for a <I>style id</I>, and the associated \a style is
58 returned.
59 \n
60     A TColorStyle instance generalizes the notion of \a color, providing the
61 ability to
62     reduce a style instance to a color, \a and specialized drawing functions for
63     <I>vector graphics</I> objects.
64 
65   \par Reserved colors
66     A palette object has two fixed \a reserved styles - which <I>cannot be
67 removed</I> - at
68     indexes \p 0 and \p1. Index \p 0 is reserved for the \b transparent color.
69 Index \p 1
70     is reserved for the \b ink color, initialized by default to black.
71 
72   \par Syntax
73     A palette is supposedly created <B>on the heap</B>, to the point that, <I>in
74 current
75     implementation</I>, copy and assignment are \a forbidden. This behavior is
76 somewhat
77     inconsitent since a palette \b is currently \a clonable and \a assignable
78 with the
79     appropriate functions. Normalization to common C++ syntax should be enforced
80 ASAP.
81 
82 \sa The TColorStyle class.
83 */
84 
85 class DVAPI TPalette final : public TPersist, public TSmartObject {
86   DECLARE_CLASS_CODE
87   PERSIST_DECLARATION(TPalette);
88 
89 public:
90   /*!
91           \brief A palette page is a restricted view of a palette instance.
92   */
93 
94   class DVAPI Page {
95     friend class TPalette;
96 
97   private:
98     std::wstring m_name;  //!< Name of the page to be displayed.
99     int m_index;  //!< Index of the page in the palette's pages collection.
100     TPalette *m_palette;  //!< (\p not \p owned)  Palette the page refers to.
101     std::vector<int> m_styleIds;  //!< Palette style ids contained in the page.
102 
103   public:
104     Page(std::wstring name);
105 
getName()106     std::wstring getName() const {
107       return m_name;
108     }  //!< Returns the name of the page.
setName(std::wstring name)109     void setName(std::wstring name) {
110       m_name = name;
111     }  //!< Sets the name of the page.
112 
getPalette()113     TPalette *getPalette() const {
114       return m_palette;
115     }  //!< Returns a pointer to the palette that contains this page.
116 
getIndex()117     int getIndex() const {
118       return m_index;
119     }  //!< Returns the page index in the palette.
120 
getStyleCount()121     int getStyleCount() const {
122       return (int)m_styleIds.size();
123     }  //!< Returns the number of the styles contained in the page.
124 
125     int getStyleId(int indexInPage) const;  //!< Returns the \a index-th style
126                                             //! id in the page, or \p -1 if not
127     //! found.
128     TColorStyle *getStyle(int indexInPage) const;  //!< Returns the \a index-th
129     //! style in the page, or \p 0
130     //! if not found.
131 
132     //! \return The insertion index in the page, or \p -1 on failure
133     int addStyle(int styleId);  //!< Adds the specified style Id to the page (at
134                                 //! the \a back
135                                 //!  of the page).
136                                 /*!
137                             \warning  The supplied style must have been allocated with \a new.
138                             \warning  Style ownership is surrendered to the palette.
139                             \return   The insertion index in the page, or \p -1 on failure.
140                                 In case of failure, the supplied style is \a deleted.
141                             */
142     int addStyle(TColorStyle *style);  //!< Adds the specified style to the
143                                        //! palette, and assigns it
144     //!  to this page.
145     //! \return The insertion index in the page, or \p -1 on failure
146     int addStyle(TPixel32 color);  //!< Add a solid color style to the palette,
147                                    //! and assigns it
148     //!  to this page.
149 
150     void insertStyle(int indexInPage, int styleId);  //!< Inserts the supplied
151                                                      //! style id at the
152     //! specified position
153     //!  in the page.
154     //! \sa The specifics of addStyle(TColorStyle*) apply here.
155     void insertStyle(int indexInPage, TColorStyle *style);  //!< Inserts the
156     //! supplied style in
157     //! the palette, and
158     //! assigns its
159     //!  id at the specified position in the page.
160     void insertStyle(int indexInPage, TPixel32 color);  //!< Inserts a solid
161                                                         //! color style in the
162     //! palette, and assigns
163     //! its
164     //!  id at the specified position in the page.
165 
166     void removeStyle(int indexInPage);  //!< Removes the style at the specified
167                                         //! position from this page.
168     int search(int styleId)
169         const;  //!< Returns the page position of the specified style id,
170                 //!  or \p -1 if it cannot be found on the page.
171     int search(TColorStyle *style)
172         const;  //!< Returns the page position of the specified style,
173                 //!  or \p -1 if it cannot be found on the page.
174   };
175 
176 private:
177   typedef std::map<int, TColorStyleP>
178       StyleAnimation;  //!< Style keyframes list.
179   typedef std::map<int, StyleAnimation>
180       StyleAnimationTable;  //!< Style keyframes list per style id.
181 
182   friend class Page;
183 
184 private:
185   std::wstring m_globalName;   //!< Palette \a global name.
186   std::wstring m_paletteName;  //!< Palette name.
187 
188   int m_version;                //!< Palette version number.
189   std::vector<Page *> m_pages;  //!< Pages list.
190   std::vector<std::pair<Page *, TColorStyleP>> m_styles;  //!< Styles container.
191   std::map<int, int> m_shortcuts;
192   StyleAnimationTable
193       m_styleAnimationTable;  //!< Table of style animations (per style).
194   int m_currentFrame;         //!< Palette's current frame in style animations.
195   bool m_isCleanupPalette;    //!< Whether the palette is used for cleanup
196                               //! purposes.
197 
198   TImageP m_refImg;
199   TFilePath m_refImgPath;
200   std::vector<TFrameId> m_refLevelFids;
201 
202   bool m_dirtyFlag;  //!< Whether the palette changed and needs to be refreshed.
203   QMutex m_mutex;    //!< Synchronization mutex for multithreading purposes.
204 
205   bool m_isLocked;          //!< Whether the palette is locked.
206   bool m_askOverwriteFlag;  //!< This variable is quite unique. This flag is to
207                             //! acheive following beghavior:
208   //! When saving the level with the palette being edited, ask whether the
209   //! palette
210   //! should be overwitten ONLY ONCE AT THE FIRST TIME.
211   //! The confirmation dialog will not be opened unless the palette is edited
212   //! again,
213   //! even if the palette's dirtyflag is true.
214 
215   int m_shortcutScopeIndex;
216 
217   int m_currentStyleId;
218 
219   bool m_areRefLevelFidsSpecified = false;
220 
221 public:
222   TPalette();
223   ~TPalette();
224 
225   TPalette *clone()
226       const;  //!< Allocates a \a new copy of this palette instance.
227 
228   static void setRootDir(const TFilePath &fp);  //!< It must be specified to
229                                                 //! save textures in \e
230   //! fp/textures.
231   static TFilePath getRootDir();
232 
getGlobalName()233   std::wstring getGlobalName() const {
234     return m_globalName;
235   }  //!< Returns the name of the palette object.
setGlobalName(std::wstring name)236   void setGlobalName(std::wstring name) {
237     m_globalName = name;
238   }  //!< Assigns the name of the palette.
239 
setDirtyFlag(bool dirtyFlag)240   void setDirtyFlag(bool dirtyFlag)  //!< Declares the palette \a changed with
241                                      //! respect to the last <I>saved state</I>.
242   {
243     m_dirtyFlag = dirtyFlag;
244     // synchronize with the dirty flag
245     m_askOverwriteFlag = dirtyFlag;
246   }
getDirtyFlag()247   bool getDirtyFlag() {
248     return m_dirtyFlag;
249   }  //!< Returns whether the palette changed with respect to the last <I>saved
250      //! state</I>.
251 
252   TColorStyle *getStyle(int styleId)
253       const;  //!< Returns a pointer to the color style with the specified id,
254               //!  or \p 0 if said id is not stored in the palette.
getStyleCount()255   int getStyleCount() const {
256     return (int)m_styles.size();
257   }  //!< Returns the number of the color styles in the palette.
258   int getStyleInPagesCount()
259       const;  //!< Returns the number of styles contained in palette pages.
260 
261   int getFirstUnpagedStyle() const;  //!< Returns the styleId of the first style
262                                      //! not in a page (\p -1 if none).
263 
264   /*!
265           \remark   Style ownserhip is \a surrendered to the palette
266           \return   The styleId associated to the inserted style, or \a -1 on
267      failure.
268   */
269   int addStyle(TColorStyle *style);         //!< Adds the specified style to the
270                                             //! palette (but in no page).
271   int addStyle(const TPixelRGBM32 &color);  //!< Adds a solid color style to the
272                                             //! palette (but in no page).
273 
274   /*!
275 \remark     Style ownserhip is \a surrendered to the palette.
276 \remark     Any existing style's animation will be discarded.
277 */
278   void setStyle(
279       int styleId,
280       TColorStyle *style);  //!< Replaces the style with the specified style id.
281   void setStyle(int styleId, const TPixelRGBM32 &color);  //!< Replaces the
282                                                           //! style with the
283   //! specified style id.
284 
285   int getPageCount() const;  //!< Returns the pages count.
286 
287   Page *getPage(int pageIndex);  //!< Returns the \a index-th palette page, or
288                                  //!\p 0 if no such page was found.
289   const Page *getPage(int pageIndex) const;  //!< Const version of getPage(int).
290 
291   /*!
292 \return  A pointer to the newly created page.
293 */
294   Page *addPage(
295       std::wstring name);     //!< Creates a new page with the specified name.
296   void erasePage(int index);  //!< Deletes the \a index-th page.
297 
298   void movePage(Page *page, int dstPageIndex);  //!< Moves the specified page to
299                                                 //! a different page index.
300 
301   Page *getStylePage(int styleId)
302       const;  //!< Returns the page containing the specified \a styleId.
303 
304   /*!
305 \note   The distance between colors is calculated with the usual sphrical norm
306 between RGBA color components.
307 \return The style id of the nearest style, or \p -1 if none was found.
308   */
309   int getClosestStyle(const TPixelRGBM32 &color)
310       const;  //!< Returns the index of the style whose main color
311               //!  is nearest to the requested one.
312 
313   void loadData(TIStream &is) override;  //!< I/O palette save function.
314   void saveData(TOStream &os) override;  //!< I/O palette load function.
315 
getVersion()316   int getVersion() const {
317     return m_version;
318   }  //!< Returns the palette's version number
setVersion(int v)319   void setVersion(int v) {
320     m_version = v;
321   }  //!< Sets the palette's version number
322 
323   void setRefLevelFids(const std::vector<TFrameId> fids,
324                        bool specified);  //!< Associates the
325                                          //! list of frames \e
326   //! fids to this palette.
327   //! When specified == true fids were specified by user on loading.
328   std::vector<TFrameId> getRefLevelFids();  //!< Returns the list of frames
329                                             //! associated to this palette.
330 
331   //! \deprecated  Should be substituted by operator=(const TPalette&).
332   void assign(const TPalette *src,
333               bool isFromStudioPalette = false);  //!< Copies src's page, color
334                                                   //! styles an animation table
335   //! to the
336   //!  correspondig features of the palette.
337   //!  if the palette is copied from studio palette, this function will modify
338   //!  the original names.
339   void merge(const TPalette *src,
340              bool isFromStudioPalette =
341                  false);  //!< Adds src's styles and pages to the palette.
342   //!  if the palette is merged from studio palette, this function will modify
343   //!  the original names.
344 
setAskOverwriteFlag(bool askOverwriteFlag)345   void setAskOverwriteFlag(
346       bool askOverwriteFlag) {  //!< Sets the ask-overwrite flag.
347     m_askOverwriteFlag = askOverwriteFlag;
348   }
getAskOverwriteFlag()349   bool getAskOverwriteFlag() {
350     return m_askOverwriteFlag;
351   }  //!< Returns the ask-overwrite flag.
352 
353   void setIsCleanupPalette(
354       bool on);  //!< Sets the palette's identity as a cleanup palette.
isCleanupPalette()355   bool isCleanupPalette() const {
356     return m_isCleanupPalette;
357   }  //!< Returns whether this is a cleanup palette.
358 
getRefImg()359   const TImageP &getRefImg() const {
360     return m_refImg;
361   }  //!< Returns an image that represents the frame image associated to this
362      //! palette.
363   void setRefImg(const TImageP &img);  //!< Associates an image to this palette,
364                                        //! that is an image in the frame
365   //!  builded or modified using this palette.
366 
getRefImgPath()367   const TFilePath getRefImgPath() const {
368     return m_refImgPath;
369   }  //!< Returns the file path of the reference image.
370   void setRefImgPath(
371       const TFilePath &fp);  //!< Sets the path filename of the reference image.
372 
373   bool isAnimated() const;  //!< Returns whether this palette is animated
374                             //!(styles change through time).
375 
376   int getFrame() const;      //!< Returns the index of the current frame.
377   void setFrame(int frame);  //!< Sets the index of the current frame.
378 
379   bool isKeyframe(int styleId, int frame) const;  //!< Returns whether the
380                                                   //! specified frame is a \a
381   //! keyframe in styleId's
382   //! animation
383   int getKeyframeCount(int styleId)
384       const;  //!< Returns the keyframes count in styleId's animation.
385 
386   int getKeyframe(int styleId, int index)
387       const;  //!< Returns the \a index-th frame in styleId's animation,
388               //!  or \p -1 if it couldn't be found.
389   void setKeyframe(int styleId, int frame);  //!< Sets a keyframe at the
390                                              //! specified frame of styleId's
391   //! animation.
392   void clearKeyframe(int styleId, int frame);  //!< Deletes the keyframe at the
393                                                //! specified frame of styleId's
394   //! animation.
395 
396   /*!
397 \note   Key is an integer between 0 and 9 included.
398 */
399   int getShortcutValue(
400       int key) const;  //!< Returns the style id \a shortcut associated to key,
401                        //!  or \p -1 if it couldn't be found.
402   /*!
403 
404   */
405   int getStyleShortcut(
406       int styleId) const;  //!< Returns the shortcut associated to styleId, or
407                            //!  or \p -1 if it couldn't be found.
408   void setShortcutValue(
409       int key, int styleId);  //!< Associates the specified key to a styleId.
410 
setPaletteName(std::wstring name)411   void setPaletteName(std::wstring name) {
412     m_paletteName = name;
413   }  //!< Sets the name of the palette.
getPaletteName()414   std::wstring getPaletteName() const {
415     return m_paletteName;
416   }  //!< Returns the name of the palette.
417 
mutex()418   QMutex *mutex() { return &m_mutex; }  //!< Returns the palette's mutex
419 
isLocked()420   bool isLocked() const {
421     return m_isLocked;
422   }                            //!< Returns whether the palette is locked.
setIsLocked(bool lock)423   void setIsLocked(bool lock)  //!< Sets lock/unlock to the palette.
424   {
425     m_isLocked = lock;
426   }
427 
428   bool hasPickedPosStyle();  // Returns true if there is at least one style with
429                              // picked pos value
430 
431   void nextShortcutScope(bool invert);
432 
setCurrentStyleId(int id)433   void setCurrentStyleId(int id) { m_currentStyleId = id; }
getCurrentStyleId()434   int getCurrentStyleId() const { return m_currentStyleId; }
435 
436 public:
437   // Deprecated functions
438 
439   //! \deprecated  Used only once throughout Toonz, should be verified.
440   bool getFxRects(const TRect &rect, TRect &rectIn, TRect &rectOut);
441 
442 private:
443   // Not copyable
444   TPalette(const TPalette &);             //!< Not implemented
445   TPalette &operator=(const TPalette &);  //!< Not implemented
446 };
447 
448 //-------------------------------------------------------------------
449 
450 #ifdef _WIN32
451 template class DVAPI TSmartPointerT<TPalette>;
452 #endif
453 
454 //-------------------------------------------------------------------
455 
456 #ifdef _MSC_VER
457 #pragma warning(pop)
458 #endif
459 
460 #endif  // TPALETTE_H
461