1 #pragma once
2 
3 #ifndef SPREADSHEETVIEWER_H
4 #define SPREADSHEETVIEWER_H
5 
6 #include "tcommon.h"
7 #include "cellposition.h"
8 #include "toonz/cellpositionratio.h"
9 // #include "orientation.h"
10 
11 #include <QDialog>
12 #include <QScrollArea>
13 
14 #undef DVAPI
15 #undef DVVAR
16 #ifdef TOONZQT_EXPORTS
17 #define DVAPI DV_EXPORT_API
18 #define DVVAR DV_EXPORT_VAR
19 #else
20 #define DVAPI DV_IMPORT_API
21 #define DVVAR DV_IMPORT_VAR
22 #endif
23 
24 // forward declaration
25 class TFrameHandle;
26 class SpreadsheetViewer;
27 class Orientation;
28 
29 //-------------------------------------------------------------------
30 
31 namespace Spreadsheet {
32 
33 // forward declaration
34 class GenericPanel;
35 
36 //-------------------------------------------------------------------
37 
38 // Use composition rather than inheritance.
39 // How this works:
40 // * scroll area scrollbars sends event to this;
41 // * it notifies every other FrameScroller with difference;
42 // * they handle it by adjusting their scrollbars
43 class DVAPI FrameScroller final : public QObject {
44   Q_OBJECT
45 
46   const Orientation *m_orientation;
47   QScrollArea *m_scrollArea;
48   int m_lastX, m_lastY;
49   bool m_syncing;
50 
51 public:
52   FrameScroller();
53   virtual ~FrameScroller();
54 
55   void setFrameScrollArea(QScrollArea *scrollArea);
getFrameScrollArea()56   QScrollArea *getFrameScrollArea() const { return m_scrollArea; }
57 
setOrientation(const Orientation * o)58   void setOrientation(const Orientation *o) { m_orientation = o; }
orientation()59   const Orientation *orientation() const { return m_orientation; }
60 
61   void registerFrameScroller();
62   void unregisterFrameScroller();
63 
64   void prepareToScrollOthers(const QPoint &offset);
65 
setSyncing(bool s)66   void setSyncing(bool s) { m_syncing = s; }
isSyncing()67   bool isSyncing() { return m_syncing; }
68 
69 private:
70   void connectScrollbars();
71   void disconnectScrollbars();
72 
73   void handleScroll(QPoint &offset);
74   void onScroll(const CellPositionRatio &offset);
75 
76   void prepareToScrollRatio(const CellPositionRatio &offset);
77 
78 private slots:
79   void onVScroll(int value);
80   void onHScroll(int value);
81 signals:
82   void prepareToScrollOffset(const QPoint &offset);
83   void zoomScrollAdjust(QPoint &offset, bool toZoom);
84 };
85 
86 //-------------------------------------------------------------------
87 
88 class DVAPI DragTool {
89 public:
DragTool()90   DragTool() {}
~DragTool()91   virtual ~DragTool() {}
92 
click(int row,int col,QMouseEvent * e)93   virtual void click(int row, int col, QMouseEvent *e) {}
drag(int row,int col,QMouseEvent * e)94   virtual void drag(int row, int col, QMouseEvent *e) {}
release(int row,int col,QMouseEvent * e)95   virtual void release(int row, int col, QMouseEvent *e) {}
96 };
97 
98 //-------------------------------------------------------------------
99 
100 class DVAPI SetFrameDragTool final : public DragTool {
101   TFrameHandle *m_frameHandle;
102 
103 public:
SetFrameDragTool(TFrameHandle * frameHandle)104   SetFrameDragTool(TFrameHandle *frameHandle) : m_frameHandle(frameHandle) {}
105 
106   void click(int row, int col, QMouseEvent *e) override;
107   void drag(int row, int col, QMouseEvent *e) override;
108   void release(int row, int col, QMouseEvent *e) override;
109 };
110 
111 //-------------------------------------------------------------------
112 
113 class DVAPI SelectionDragTool final : public DragTool {
114   SpreadsheetViewer *m_viewer;
115   int m_firstRow, m_firstCol;
116 
117 public:
118   SelectionDragTool(SpreadsheetViewer *viewer);
119 
120   void click(int row, int col, QMouseEvent *e) override;
121   void drag(int row, int col, QMouseEvent *e) override;
122   void release(int row, int col, QMouseEvent *e) override;
123 };
124 
125 //-------------------------------------------------------------------
126 
127 class DVAPI PanTool final : public DragTool {
128   SpreadsheetViewer *m_viewer;
129   GenericPanel *m_panel;
130   QPoint m_lastPos;
131 
132 public:
133   PanTool(GenericPanel *panel);
134 
135   void click(int row, int col, QMouseEvent *e) override;
136   void drag(int row, int col, QMouseEvent *e) override;
137   void release(int row, int col, QMouseEvent *e) override;
138 };
139 
140 //-------------------------------------------------------------------
141 
142 class DVAPI ScrollArea final : public QScrollArea {
143   Q_OBJECT
144 
145 public:
146 #if QT_VERSION >= 0x050500
147   ScrollArea(QWidget *parent = 0, Qt::WindowFlags flags = 0);
148 #else
149   ScrollArea(QWidget *parent = 0, Qt::WFlags flags = 0);
150 #endif
151   virtual ~ScrollArea();
152 
153 protected:
154   // keyPressEvent and wheelEvent are ignored by the ScrollArea
155   // and therefore they are handled by the parent (Viewer)
156   void keyPressEvent(QKeyEvent *e) override;
157   void wheelEvent(QWheelEvent *e) override;
158 };
159 
160 //-------------------------------------------------------------------
161 
162 class DVAPI GenericPanel : public QWidget {
163   Q_OBJECT
164   SpreadsheetViewer *m_viewer;
165   DragTool *m_dragTool;
166 
167 public:
168   GenericPanel(SpreadsheetViewer *viewer);
169   virtual ~GenericPanel();
170 
getViewer()171   SpreadsheetViewer *getViewer() const { return m_viewer; }
172 
createDragTool(QMouseEvent *)173   virtual DragTool *createDragTool(QMouseEvent *) { return 0; };
174 
175 protected:
176   void paintEvent(QPaintEvent *) override;
177   void mousePressEvent(QMouseEvent *) override;
178   void mouseReleaseEvent(QMouseEvent *) override;
179   void mouseMoveEvent(QMouseEvent *) override;
180 };
181 
182 //-------------------------------------------------------------------
183 
184 class DVAPI RowPanel : public GenericPanel {
185   Q_OBJECT
186   const int m_xa;  // frame cells start at m_xa
187 public:
188   RowPanel(SpreadsheetViewer *viewer);
~RowPanel()189   virtual ~RowPanel() {}
190 
191   DragTool *createDragTool(QMouseEvent *) override;
192 
193 protected:
194   void paintEvent(QPaintEvent *) override;
195   void drawRows(QPainter &p, int r0, int r1);
196   void drawCurrentRowGadget(QPainter &p, int r0, int r1);
197 };
198 
199 //-------------------------------------------------------------------
200 
201 class DVAPI ColumnPanel : public GenericPanel {
202   Q_OBJECT
203 public:
204   ColumnPanel(SpreadsheetViewer *viewer);
~ColumnPanel()205   virtual ~ColumnPanel() {}
206 };
207 
208 //-------------------------------------------------------------------
209 
210 class DVAPI CellPanel : public GenericPanel {
211   Q_OBJECT
212 
213 public:
214   CellPanel(SpreadsheetViewer *viewer);
~CellPanel()215   virtual ~CellPanel() {}
216 
217   DragTool *createDragTool(QMouseEvent *) override;
218 
219 protected:
220   void paintEvent(QPaintEvent *) override;
drawCells(QPainter & p,int r0,int c0,int r1,int c1)221   virtual void drawCells(QPainter &p, int r0, int c0, int r1, int c1) {}
222 };
223 }  // namespace Spreadsheet
224 
225 //-------------------------------------------------------------------
226 
227 class DVAPI SpreadsheetViewer : public QDialog {
228   Q_OBJECT
229 
230   QColor m_lightLightBgColor;  // RowPanel background (124,124,124)
231   QColor m_bgColor;         // RowPanel background in scene range(164,164,164)
232   QColor m_lightLineColor;  // horizontal line (146,144,146)
233 
234   Q_PROPERTY(QColor LightLightBGColor READ getLightLightBGColor WRITE
235                  setLightLightBGColor)
236   Q_PROPERTY(QColor BGColor READ getBGColor WRITE setBGColor)
237   Q_PROPERTY(
238       QColor LightLineColor READ getLightLineColor WRITE setLightLineColor)
239 
240   QColor m_currentRowBgColor;  // current frame, column
241   QColor m_markerLineColor;    // marker interval (0, 255, 246)
242   QColor m_textColor;          // text (black)
243   QColor m_verticalLineColor;  // vertical line (black)
244   Q_PROPERTY(QColor CurrentRowBgColor READ getCurrentRowBgColor WRITE
245                  setCurrentRowBgColor)
246   Q_PROPERTY(
247       QColor MarkerLineColor READ getMarkerLineColor WRITE setMarkerLineColor)
248   Q_PROPERTY(QColor TextColor READ getTextColor WRITE setTextColor)
249   Q_PROPERTY(QColor VerticalLineColor READ getVerticalLineColor WRITE
250                  setVerticalLineColor)
251 
252   // key frame
253   QColor m_keyFrameColor;          // (219,139,54)
254   QColor m_keyFrameBorderColor;    // (82,51,20)
255   QColor m_selectedKeyFrameColor;  // (237,197,155)
256   QColor m_ignoredKeyFrameColor;
257   QColor m_selectedIgnoredKeyFrameColor;
258   // key frame inbetween
259   QColor m_inBetweenColor;          // (194,194,176)
260   QColor m_inBetweenBorderColor;    // (72,72,65)
261   QColor m_selectedInBetweenColor;  // (225,225,216)
262   QColor m_ignoredInBetweenColor;
263   QColor m_selectedIgnoredInBetweenColor;
264   // empty cell
265   QColor m_selectedEmptyColor;  // (190,190,190)
266   // empty cell in the scene range
267   QColor m_selectedSceneRangeEmptyColor;  // (210,210,210)
268   Q_PROPERTY(QColor KeyFrameColor READ getKeyFrameColor WRITE setKeyFrameColor)
269   Q_PROPERTY(QColor KeyFrameBorderColor READ getKeyFrameBorderColor WRITE
270                  setKeyFrameBorderColor)
271   Q_PROPERTY(QColor SelectedKeyFrameColor READ getSelectedKeyFrameColor WRITE
272                  setSelectedKeyFrameColor)
273   Q_PROPERTY(QColor IgnoredKeyFrameColor READ getIgnoredKeyFrameColor WRITE
274                  setIgnoredKeyFrameColor)
275   Q_PROPERTY(
276       QColor SelectedIgnoredKeyFrameColor READ getSelectedIgnoredKeyFrameColor
277           WRITE setSelectedIgnoredKeyFrameColor)
278   Q_PROPERTY(
279       QColor InBetweenColor READ getInBetweenColor WRITE setInBetweenColor)
280   Q_PROPERTY(QColor InBetweenBorderColor READ getInBetweenBorderColor WRITE
281                  setInBetweenBorderColor)
282   Q_PROPERTY(QColor SelectedInBetweenColor READ getSelectedInBetweenColor WRITE
283                  setSelectedInBetweenColor)
284   Q_PROPERTY(QColor IgnoredInBetweenColor READ getIgnoredInBetweenColor WRITE
285                  setIgnoredInBetweenColor)
286   Q_PROPERTY(
287       QColor SelectedIgnoredInBetweenColor READ getSelectedIgnoredInBetweenColor
288           WRITE setSelectedIgnoredInBetweenColor)
289   Q_PROPERTY(QColor SelectedEmptyColor READ getSelectedEmptyColor WRITE
290                  setSelectedEmptyColor)
291   Q_PROPERTY(
292       QColor SelectedSceneRangeEmptyColor READ getSelectedSceneRangeEmptyColor
293           WRITE setSelectedSceneRangeEmptyColor)
294 
295   QColor m_columnHeaderBorderColor;  // column header border lines (46,47,46)
296   Q_PROPERTY(QColor ColumnHeaderBorderColor READ getColumnHeaderBorderColor
297                  WRITE setColumnHeaderBorderColor)
298 
299   Spreadsheet::ScrollArea *m_columnScrollArea;
300   Spreadsheet::ScrollArea *m_rowScrollArea;
301   Spreadsheet::ScrollArea *m_cellScrollArea;
302   TFrameHandle *m_frameHandle;
303 
304   int m_columnWidth;
305   int m_rowHeight;
306 
307   // QPoint m_delta;
308   int m_timerId;
309   QPoint m_autoPanSpeed;
310   QPoint m_lastAutoPanPos;
311   int m_rowCount, m_columnCount;
312   int m_currentRow;
313   int m_markRowDistance, m_markRowOffset;
314   // QRect m_selectedCells; // x=col, y=row
315   bool m_isComputingSize;
316   // const Orientation *m_orientation;
317 
318 protected:
319   Spreadsheet::FrameScroller m_frameScroller;
320 
321 public:
322   SpreadsheetViewer(QWidget *parent);
323   virtual ~SpreadsheetViewer();
324 
getColumnWidth()325   int getColumnWidth() const { return m_columnWidth; }
setColumnWidth(int width)326   void setColumnWidth(int width) { m_columnWidth = width; }
327 
getRowHeight()328   int getRowHeight() const { return m_rowHeight; }
setRowHeight(int height)329   void setRowHeight(int height) { m_rowHeight = height; }
330 
331   void setRowsPanel(Spreadsheet::RowPanel *rows);
332   void setColumnsPanel(Spreadsheet::ColumnPanel *columns);
333   void setCellsPanel(Spreadsheet::CellPanel *cells);
334 
getRowCount()335   int getRowCount() const { return m_rowCount; }
336 
337   // QProperty
setLightLightBGColor(const QColor & color)338   void setLightLightBGColor(const QColor &color) {
339     m_lightLightBgColor = color;
340   }
getLightLightBGColor()341   QColor getLightLightBGColor() const { return m_lightLightBgColor; }
setBGColor(const QColor & color)342   void setBGColor(const QColor &color) { m_bgColor = color; }
getBGColor()343   QColor getBGColor() const { return m_bgColor; }
setLightLineColor(const QColor & color)344   void setLightLineColor(const QColor &color) { m_lightLineColor = color; }
getLightLineColor()345   QColor getLightLineColor() const { return m_lightLineColor; }
setCurrentRowBgColor(const QColor & color)346   void setCurrentRowBgColor(const QColor &color) {
347     m_currentRowBgColor = color;
348   }
getCurrentRowBgColor()349   QColor getCurrentRowBgColor() const { return m_currentRowBgColor; }
setMarkerLineColor(const QColor & color)350   void setMarkerLineColor(const QColor &color) { m_markerLineColor = color; }
getMarkerLineColor()351   QColor getMarkerLineColor() const { return m_markerLineColor; }
setTextColor(const QColor & color)352   void setTextColor(const QColor &color) { m_textColor = color; }
getTextColor()353   QColor getTextColor() const { return m_textColor; }
setVerticalLineColor(const QColor & color)354   void setVerticalLineColor(const QColor &color) {
355     m_verticalLineColor = color;
356   }
getVerticalLineColor()357   QColor getVerticalLineColor() const { return m_verticalLineColor; }
setKeyFrameColor(const QColor & color)358   void setKeyFrameColor(const QColor &color) { m_keyFrameColor = color; }
getKeyFrameColor()359   QColor getKeyFrameColor() const { return m_keyFrameColor; }
setKeyFrameBorderColor(const QColor & color)360   void setKeyFrameBorderColor(const QColor &color) {
361     m_keyFrameBorderColor = color;
362   }
getKeyFrameBorderColor()363   QColor getKeyFrameBorderColor() const { return m_keyFrameBorderColor; }
setSelectedKeyFrameColor(const QColor & color)364   void setSelectedKeyFrameColor(const QColor &color) {
365     m_selectedKeyFrameColor = color;
366   }
getSelectedKeyFrameColor()367   QColor getSelectedKeyFrameColor() const { return m_selectedKeyFrameColor; }
368 
setIgnoredKeyFrameColor(const QColor & color)369   void setIgnoredKeyFrameColor(const QColor &color) {
370     m_ignoredKeyFrameColor = color;
371   }
getIgnoredKeyFrameColor()372   QColor getIgnoredKeyFrameColor() const { return m_ignoredKeyFrameColor; }
setSelectedIgnoredKeyFrameColor(const QColor & color)373   void setSelectedIgnoredKeyFrameColor(const QColor &color) {
374     m_selectedIgnoredKeyFrameColor = color;
375   }
getSelectedIgnoredKeyFrameColor()376   QColor getSelectedIgnoredKeyFrameColor() const {
377     return m_selectedIgnoredKeyFrameColor;
378   }
379 
setInBetweenColor(const QColor & color)380   void setInBetweenColor(const QColor &color) { m_inBetweenColor = color; }
getInBetweenColor()381   QColor getInBetweenColor() const { return m_inBetweenColor; }
setInBetweenBorderColor(const QColor & color)382   void setInBetweenBorderColor(const QColor &color) {
383     m_inBetweenBorderColor = color;
384   }
getInBetweenBorderColor()385   QColor getInBetweenBorderColor() const { return m_inBetweenBorderColor; }
setSelectedInBetweenColor(const QColor & color)386   void setSelectedInBetweenColor(const QColor &color) {
387     m_selectedInBetweenColor = color;
388   }
getSelectedInBetweenColor()389   QColor getSelectedInBetweenColor() const { return m_selectedInBetweenColor; }
390 
setIgnoredInBetweenColor(const QColor & color)391   void setIgnoredInBetweenColor(const QColor &color) {
392     m_ignoredInBetweenColor = color;
393   }
getIgnoredInBetweenColor()394   QColor getIgnoredInBetweenColor() const { return m_ignoredInBetweenColor; }
setSelectedIgnoredInBetweenColor(const QColor & color)395   void setSelectedIgnoredInBetweenColor(const QColor &color) {
396     m_selectedIgnoredInBetweenColor = color;
397   }
getSelectedIgnoredInBetweenColor()398   QColor getSelectedIgnoredInBetweenColor() const {
399     return m_selectedIgnoredInBetweenColor;
400   }
401 
setSelectedEmptyColor(const QColor & color)402   void setSelectedEmptyColor(const QColor &color) {
403     m_selectedEmptyColor = color;
404   }
getSelectedEmptyColor()405   QColor getSelectedEmptyColor() const { return m_selectedEmptyColor; }
setSelectedSceneRangeEmptyColor(const QColor & color)406   void setSelectedSceneRangeEmptyColor(const QColor &color) {
407     m_selectedSceneRangeEmptyColor = color;
408   }
getSelectedSceneRangeEmptyColor()409   QColor getSelectedSceneRangeEmptyColor() const {
410     return m_selectedSceneRangeEmptyColor;
411   }
setColumnHeaderBorderColor(const QColor & color)412   void setColumnHeaderBorderColor(const QColor &color) {
413     m_columnHeaderBorderColor = color;
414   }
getColumnHeaderBorderColor()415   QColor getColumnHeaderBorderColor() const {
416     return m_columnHeaderBorderColor;
417   }
418 
419   void scroll(QPoint delta);
420 
421   void setAutoPanSpeed(const QPoint &speed);
422   void setAutoPanSpeed(const QRect &widgetBounds, const QPoint &mousePos);
stopAutoPan()423   void stopAutoPan() { setAutoPanSpeed(QPoint()); }
isAutoPanning()424   bool isAutoPanning() const {
425     return m_autoPanSpeed.x() != 0 || m_autoPanSpeed.y() != 0;
426   }
427 
428   int xToColumn(int x) const;
429   int yToRow(int y) const;
430   int columnToX(int col) const;
431   int rowToY(int row) const;
432 
433   CellPosition xyToPosition(const QPoint &point) const;
434   QPoint positionToXY(const CellPosition &pos) const;
435 
436   CellRange xyRectToRange(const QRect &rect) const;
437 
438   // const Orientation *orientation () const { return m_orientation; }
439 
440   bool refreshContentSize(int scrollDx, int scrollDy);
441 
getCurrentRow()442   int getCurrentRow() const { return m_currentRow; }
setCurrentRow(int row)443   void setCurrentRow(int row) { m_currentRow = row; }
444 
445   virtual QRect getSelectedCells() const               = 0;
446   virtual void selectCells(const QRect &selectedCells) = 0;
447 
isSelectedCell(int row,int col)448   bool isSelectedCell(int row, int col) const {
449     return getSelectedCells().contains(QPoint(col, row));
450   }
setMarkRow(int distance,int offset)451   void setMarkRow(int distance, int offset) {
452     m_markRowDistance = distance;  // distance > 0 ? distance : 6;
453     m_markRowOffset   = offset;
454   }
getMarkRow(int & distance,int & offset)455   void getMarkRow(int &distance, int &offset) const {
456     distance = m_markRowDistance;
457     offset   = m_markRowOffset;
458   }
isMarkRow(int row)459   int isMarkRow(int row) const {
460     return m_markRowDistance > 0 &&
461            ((row - m_markRowOffset) % m_markRowDistance) == 0;
462   }
463 
464   void setFrameHandle(TFrameHandle *frameHandle);
getFrameHandle()465   TFrameHandle *getFrameHandle() const { return m_frameHandle; }
466 
467   void ensureVisibleCol(int col);
468 
469 protected:
470   void showEvent(QShowEvent *) override;
471   void hideEvent(QHideEvent *) override;
472   void resizeEvent(QResizeEvent *event) override;
473   void keyPressEvent(QKeyEvent *event) override;
474   void wheelEvent(QWheelEvent *event) override;
475   void timerEvent(QTimerEvent *) override;
476 
477 public slots:
478   void setRowCount(int rowCount);
479   void setColumnCount(int columnCount);
480 
481   void frameSwitched();
482 
483   void updateAreas();
484   void onVSliderChanged(int);
485   void onHSliderChanged(int);
486 
487   void onPrepareToScrollOffset(const QPoint &offset);
488   /*
489 void updateAllAree();
490 void updateCellColumnAree();
491 void updateCellRowAree();
492 */
493 };
494 
495 #endif
496