1 #pragma once
2 
3 #ifndef FILMSTRIP_H
4 #define FILMSTRIP_H
5 
6 // TnzQt includes
7 #include "toonzqt/dvdialog.h"
8 #include "toonzqt/selection.h"
9 #include "saveloadqsettings.h"
10 
11 // Qt includes
12 #include <QScrollArea>
13 #include <QKeyEvent>
14 
15 // STD includes
16 #include <vector>
17 #include <map>
18 
19 // forward declaration
20 class TFrameId;
21 class TFilmstripSelection;
22 class FilmstripFrameHeadGadget;
23 class TXshSimpleLevel;
24 class QComboBox;
25 class InbetweenDialog;
26 class TXshLevel;
27 class SceneViewer;
28 
29 const int fs_leftMargin       = 2;
30 const int fs_rightMargin      = 3;
31 const int fs_frameSpacing     = 6;
32 const int fs_iconMarginLR     = 5;
33 const int fs_iconMarginTop    = 5;
34 const int fs_iconMarginBottom = 15;
35 
36 //=============================================================================
37 // FilmstripFrames
38 // (inserita dentro Filmstrip : QScrollArea)
39 //-----------------------------------------------------------------------------
40 
41 class FilmstripFrames final : public QFrame, public TSelection::View {
42   Q_OBJECT
43 
44 public:
45 #if QT_VERSION >= 0x050500
46   FilmstripFrames(QScrollArea *parent = 0, Qt::WindowFlags flags = 0);
47 #else
48   FilmstripFrames(QScrollArea *parent = 0, Qt::WFlags flags = 0);
49 #endif
50   ~FilmstripFrames();
51 
52   bool m_isVertical    = true;
53   bool m_showNavigator = true;
54   bool m_showComboBox  = true;
55 
setBGColor(const QColor & color)56   void setBGColor(const QColor &color) { m_bgColor = color; }
getBGColor()57   QColor getBGColor() const { return m_bgColor; }
setLightLineColor(const QColor & color)58   void setLightLineColor(const QColor &color) { m_lightLineColor = color; }
getLightLineColor()59   QColor getLightLineColor() const { return m_lightLineColor; }
setDarkLineColor(const QColor & color)60   void setDarkLineColor(const QColor &color) { m_darkLineColor = color; }
getDarkLineColor()61   QColor getDarkLineColor() const { return m_darkLineColor; }
62 
63   // helper method: get the current level
64   TXshSimpleLevel *getLevel() const;
65 
getIconSize()66   QSize getIconSize() const { return m_iconSize; }
getFrameLabelWidth()67   int getFrameLabelWidth() const { return m_frameLabelWidth; }
68 
69   // convert mouse coordinate y to a frame index and vice versa
70   int y2index(int y) const;
71   int index2y(int index) const;
72 
73   // convert mouse coordinate x to a frame index and vice versa
74   int x2index(int x) const;
75   int index2x(int index) const;
76 
77   // returns the frame id of the provided index if index >= 0
78   // otherwise returns TFrameId()
79   TFrameId index2fid(int index) const;
80 
81   // returns the index if the frame exists, otherwise -1
82   int fid2index(const TFrameId &fid) const;
83 
84   // returns the height of all frames plus a blank one
85   int getFramesHeight() const;
86 
87   // returns the width of all frames plus a blank one
88   int getFramesWidth() const;
89 
90   // aggiorna le dimensioni del QWidget in base al numero di fotogrammi del
91   // livello
92   // la dimensione verticale e' sempre >= minimumHeight. Questo permette di
93   // gestire
94   // lo scroll anche oltre i frame esistenti.
95   // se minimumHeight == -1 viene utilizzato
96   // visibleRegion().boundingRect().bottom()
97   void updateContentHeight(int minimumHeight = -1);
98   void updateContentWidth(int minimumHeight = -1);
99 
100   // makes sure that the indexed frame is visible (scrolling if necessary)
101   void showFrame(int index);
102 
103   // esegue uno scroll di dy pixel. se dy<0 fa scorrere i fotogrammi verso
104   // l'alto
105   // lo scroll e' illimitato verso il basso. aggiorna contentHeight
106   void scroll(int dy);
107 
108   // overriden from TSelection::View
onSelectionChanged()109   void onSelectionChanged() override { update(); }
110 
111   enum SelectionMode {
112     SIMPLE_SELECT,
113     SHIFT_SELECT,
114     CTRL_SELECT,
115     START_DRAG_SELECT,
116     DRAG_SELECT,
117     ONLY_SELECT
118   };
119   void select(int index, SelectionMode mode = SIMPLE_SELECT);
120 
121   int getOneFrameHeight();
122   int getOneFrameWidth();
123   void setOrientation(bool isVertical);
124   void setNavigator(bool showNavigator);
125   void setComboBox(bool showComboBox);
126 
127 signals:
128   void orientationToggledSignal(bool);
129   void comboBoxToggledSignal();
130   void navigatorToggledSignal();
131   void levelSelectedSignal(int);
132 
133 protected:
134   void showEvent(QShowEvent *) override;
135   void hideEvent(QHideEvent *) override;
136   void paintEvent(QPaintEvent *) override;
137 
138   enum {
139     F_NORMAL          = 0,
140     F_INBETWEEN_RANGE = 0x1,
141     F_INBETWEEN_LAST  = 0x2
142   };  // Flags
143   void drawFrameIcon(QPainter &p, const QRect &r, int index,
144                      const TFrameId &fid, int flags);
145 
146   void mousePressEvent(QMouseEvent *event) override;
147   void mouseReleaseEvent(QMouseEvent *event) override;
148   void mouseMoveEvent(QMouseEvent *) override;
149   void enterEvent(QEvent *event) override;
150   void keyPressEvent(QKeyEvent *event) override;
151   void wheelEvent(QWheelEvent *event) override;
152 
153   void startAutoPanning();
154   void stopAutoPanning();
155   void timerEvent(QTimerEvent *) override;
156   TFrameId getCurrentFrameId();
157   void contextMenuEvent(QContextMenuEvent *event) override;
158 
159   void startDragDrop();
160   void createSelectLevelMenu(QMenu *menu);
161   void inbetween();
162 
163   void execNavigatorPan(const QPoint &point);
164   void mouseDoubleClickEvent(QMouseEvent *event) override;
165 
166 protected slots:
167   void onLevelChanged();
168   void onLevelSwitched(TXshLevel *);
169   void onFrameSwitched();
170   void getViewer();
171   void orientationToggled(bool);
172   void comboBoxToggled(bool);
173   void navigatorToggled(bool);
174   void levelSelected(int);
175   void onViewerAboutToBeDestroyed();
176 
177 private:
178   // QSS Properties
179 
180   QColor m_bgColor;
181   QColor m_lightLineColor;
182   QColor m_darkLineColor;
183 
184   Q_PROPERTY(QColor BGColor READ getBGColor WRITE setBGColor)
185   Q_PROPERTY(
186       QColor LightLineColor READ getLightLineColor WRITE setLightLineColor)
187   Q_PROPERTY(QColor DarkLineColor READ getDarkLineColor WRITE setDarkLineColor)
188 
189 private:
190   // Widgets
191 
192   QScrollArea *m_scrollArea;
193   TFilmstripSelection *m_selection;
194   FilmstripFrameHeadGadget *m_frameHeadGadget;
195   InbetweenDialog *m_inbetweenDialog;
196   SceneViewer *m_viewer;
197   bool m_justStartedSelection  = false;
198   int m_indexForResetSelection = -1;
199   bool m_allowResetSelection   = false;
200   int m_timerInterval          = 100;
201   // State data
202 
203   QPoint m_pos;  //!< Last mouse position.
204 
205   const QSize m_iconSize;
206   const int m_frameLabelWidth;
207 
208   std::pair<int, int> m_selectingRange;
209 
210   int m_scrollSpeed,
211       m_dragSelectionStartIndex,  //!< Starting level index during drag
212                                   //! selections.
213       m_dragSelectionEndIndex,  //!< Ending level index during drag selections.
214       m_timerId;                // per l'autoscroll
215 
216   bool m_selecting, m_dragDropArmed, m_readOnly;
217 
218   QPoint m_naviRectPos;
219   QPointF m_icon2ViewerRatio;
220   bool m_isNavigatorPanning;
221 };
222 
223 //=============================================================================
224 // Filmstrip
225 //-----------------------------------------------------------------------------
226 
227 class Filmstrip final : public QWidget, public SaveLoadQSettings {
228   Q_OBJECT
229 
230   FilmstripFrames *m_frames;
231 
232   QScrollArea *m_frameArea;
233   QComboBox *m_chooseLevelCombo;
234 
235   std::vector<TXshSimpleLevel *> m_levels;
236   std::map<TXshSimpleLevel *, TFrameId> m_workingFrames;
237   bool m_isVertical    = true;
238   bool m_showNavigator = true;
239   bool m_showComboBox  = true;
240 
241 public:
242 #if QT_VERSION >= 0x050500
243   Filmstrip(QWidget *parent = 0, Qt::WindowFlags flags = 0);
244 #else
245   Filmstrip(QWidget *parent = 0, Qt::WFlags flags = 0);
246 #endif
247   ~Filmstrip();
248 
249   // SaveLoadQSettings
250   virtual void save(QSettings &settings) const override;
251   virtual void load(QSettings &settings) override;
252 
253 protected:
254   void setOrientation(bool isVertical);
255   void showEvent(QShowEvent *) override;
256   void hideEvent(QHideEvent *) override;
257   void resizeEvent(QResizeEvent *) override;
258   // void keyPressEvent(QKeyEvent* event){
259   //  event->ignore();
260   //}
261 
262 public slots:
263   //! Aggiorna il "titolo" del widget e rinfresca la filmstrip se c'e' qualche
264   //! "check" attivo.
265   void onLevelSwitched(TXshLevel *oldLevel);
266   // void ensureValuesVisible(int x, int y);
267 
268   void onSliderMoved(int);
269   void onLevelChanged();
270   // update combo items when the contents of scene cast are changed
271   void updateChooseLevelComboItems();
272   // change the current level when the combo item selected
273   void onChooseLevelComboChanged(int index);
274 
275   void onFrameSwitched();
276   void orientationToggled(bool);
277   void comboBoxToggled();
278   void navigatorToggled();
279 
280 private:
281   void updateWindowTitle();
282   // synchronize the current index of combo to the current level
283   void updateCurrentLevelComboItem();
284 };
285 
286 //=============================================================================
287 // inbetweenDialog
288 //-----------------------------------------------------------------------------
289 
290 class InbetweenDialog final : public DVGui::Dialog {
291   Q_OBJECT
292   QComboBox *m_comboBox;
293 
294 public:
295   InbetweenDialog(QWidget *parent);
296 
297   void setValue(const QString &value);
298   QString getValue();
299 
300   int getIndex(const QString &text);
301 };
302 
303 #endif  // FILMSTRIP_H
304