1
2
3 #include "xsheetviewer.h"
4 #include "sceneviewerevents.h"
5 #include "tapp.h"
6 #include "floatingpanelcommand.h"
7 #include "menubarcommandids.h"
8 #include "toonz/tcolumnhandle.h"
9 #include "toonz/txsheethandle.h"
10 #include "toonz/tfxhandle.h"
11 #include "toonz/tscenehandle.h"
12 #include "toonz/tframehandle.h"
13 #include "toonz/tobjecthandle.h"
14 #include "toonz/txshpalettelevel.h"
15 #include "toonz/preferences.h"
16 #include "toonz/sceneproperties.h"
17 #include "toonzqt/tselectionhandle.h"
18 #include "toonzqt/icongenerator.h"
19 #include "cellselection.h"
20 #include "keyframeselection.h"
21 #include "cellkeyframeselection.h"
22 #include "columnselection.h"
23 #include "xsheetdragtool.h"
24 #include "toonzqt/gutil.h"
25
26 #include "toonz/txsheet.h"
27 #include "toonz/txshcell.h"
28 #include "toonz/txshleveltypes.h"
29 #include "toonz/txshzeraryfxcolumn.h"
30 #include "toonz/toonzscene.h"
31 #include "toonz/columnfan.h"
32 #include "toonz/txshnoteset.h"
33 #include "toonz/childstack.h"
34 #include "toonz/txshlevelhandle.h"
35 #include "toonz/tproject.h"
36 #include "tconvert.h"
37
38 #include "tenv.h"
39
40 #include <QPainter>
41 #include <QScrollBar>
42 #include <QMouseEvent>
43
44 TEnv::IntVar FrameDisplayStyleInXsheetRowArea(
45 "FrameDisplayStyleInXsheetRowArea", 0);
46
47 //=============================================================================
48 namespace XsheetGUI {
49 //-----------------------------------------------------------------------------
50
51 const int ColumnWidth = 74;
52 const int RowHeight = 20;
53 const int SCROLLBAR_WIDTH = 16;
54 const int TOOLBAR_HEIGHT = 29;
55 const int ZOOM_FACTOR_MAX = 100;
56 const int ZOOM_FACTOR_MIN = 20;
57 } // namespace XsheetGUI
58
59 //=============================================================================
60 // XsheetViewer
61 //-----------------------------------------------------------------------------
62
getCellTypeAndColors(int & ltype,QColor & cellColor,QColor & sideColor,const TXshCell & cell,bool isSelected)63 void XsheetViewer::getCellTypeAndColors(int <ype, QColor &cellColor,
64 QColor &sideColor, const TXshCell &cell,
65 bool isSelected) {
66 if (cell.isEmpty())
67 ltype = NO_XSHLEVEL;
68 else {
69 ltype = cell.m_level->getType();
70 switch (ltype) {
71 case TZI_XSHLEVEL:
72 case OVL_XSHLEVEL:
73 cellColor = (isSelected) ? getSelectedFullcolorColumnColor()
74 : getFullcolorColumnColor();
75 sideColor = getFullcolorColumnBorderColor();
76 break;
77 case PLI_XSHLEVEL:
78 cellColor = (isSelected) ? getSelectedVectorColumnColor()
79 : getVectorColumnColor();
80 sideColor = getVectorColumnBorderColor();
81 break;
82 case TZP_XSHLEVEL:
83 cellColor =
84 (isSelected) ? getSelectedLevelColumnColor() : getLevelColumnColor();
85 sideColor = getLevelColumnBorderColor();
86 break;
87 case ZERARYFX_XSHLEVEL:
88 cellColor =
89 (isSelected) ? getSelectedFxColumnColor() : getFxColumnColor();
90 sideColor = getFxColumnBorderColor();
91 break;
92 case CHILD_XSHLEVEL:
93 cellColor =
94 (isSelected) ? getSelectedChildColumnColor() : getChildColumnColor();
95 sideColor = getChildColumnBorderColor();
96 break;
97 case SND_XSHLEVEL:
98 cellColor =
99 (isSelected) ? m_selectedSoundColumnColor : m_soundColumnColor;
100 sideColor = m_soundColumnBorderColor;
101 break;
102 case SND_TXT_XSHLEVEL:
103 cellColor = (isSelected) ? getSelectedSoundTextColumnColor()
104 : getSoundTextColumnColor();
105 sideColor = getSoundTextColumnBorderColor();
106 break;
107 case MESH_XSHLEVEL:
108 cellColor =
109 (isSelected) ? getSelectedMeshColumnColor() : getMeshColumnColor();
110 sideColor = getMeshColumnBorderColor();
111 break;
112 case UNKNOWN_XSHLEVEL:
113 case NO_XSHLEVEL:
114 default:
115 // non dovrebbe succedere
116 cellColor = grey210;
117 sideColor = grey150;
118 }
119 }
120 }
121
122 //-----------------------------------------------------------------------------
123
getColumnColor(QColor & color,QColor & sideColor,int index,TXsheet * xsh)124 void XsheetViewer::getColumnColor(QColor &color, QColor &sideColor, int index,
125 TXsheet *xsh) {
126 if (index < 0 || xsh->isColumnEmpty(index)) return;
127 int r0, r1;
128 xsh->getCellRange(index, r0, r1);
129 if (0 <= r0 && r0 <= r1) {
130 // column color depends on the level type in the top-most occupied cell
131 if (xsh->getColumn(index)->getSoundColumn()) {
132 color = m_soundColumnColor;
133 sideColor = m_soundColumnBorderColor;
134 } else {
135 TXshCell cell = xsh->getCell(r0, index);
136 int ltype;
137 getCellTypeAndColors(ltype, color, sideColor, cell);
138 }
139 }
140 if (xsh->getColumn(index)->isMask()) color = QColor(255, 0, 255);
141 }
142
143 //-----------------------------------------------------------------------------
144
getButton(int & btype,QColor & bgColor,QImage & iconImage,bool isTimeline)145 void XsheetViewer::getButton(int &btype, QColor &bgColor, QImage &iconImage,
146 bool isTimeline) {
147 switch (btype) {
148 case PREVIEW_ON_XSHBUTTON:
149 bgColor = (isTimeline) ? getTimelinePreviewButtonBgOnColor()
150 : getXsheetPreviewButtonBgOnColor();
151 iconImage = (isTimeline) ? getTimelinePreviewButtonOnImage()
152 : getXsheetPreviewButtonOnImage();
153 break;
154 case PREVIEW_OFF_XSHBUTTON:
155 bgColor = (isTimeline) ? getTimelinePreviewButtonBgOffColor()
156 : getXsheetPreviewButtonBgOffColor();
157 iconImage = (isTimeline) ? getTimelinePreviewButtonOffImage()
158 : getXsheetPreviewButtonOffImage();
159 break;
160 case CAMSTAND_ON_XSHBUTTON:
161 bgColor = (isTimeline) ? getTimelineCamstandButtonBgOnColor()
162 : getXsheetCamstandButtonBgOnColor();
163 iconImage = (isTimeline) ? getTimelineCamstandButtonOnImage()
164 : getXsheetCamstandButtonOnImage();
165 break;
166 case CAMSTAND_TRANSP_XSHBUTTON:
167 bgColor = (isTimeline) ? getTimelineCamstandButtonBgOnColor()
168 : getXsheetCamstandButtonBgOnColor();
169 iconImage = (isTimeline) ? getTimelineCamstandButtonTranspImage()
170 : getXsheetCamstandButtonTranspImage();
171 break;
172 case CAMSTAND_OFF_XSHBUTTON:
173 bgColor = (isTimeline) ? getTimelineCamstandButtonBgOffColor()
174 : getXsheetCamstandButtonBgOffColor();
175 iconImage = (isTimeline) ? getTimelineCamstandButtonOffImage()
176 : getXsheetCamstandButtonOffImage();
177 break;
178 case LOCK_ON_XSHBUTTON:
179 bgColor = (isTimeline) ? getTimelineLockButtonBgOnColor()
180 : getXsheetLockButtonBgOnColor();
181 iconImage = (isTimeline) ? getTimelineLockButtonOnImage()
182 : getXsheetLockButtonOnImage();
183 break;
184 case LOCK_OFF_XSHBUTTON:
185 bgColor = (isTimeline) ? getTimelineLockButtonBgOffColor()
186 : getXsheetLockButtonBgOffColor();
187 iconImage = (isTimeline) ? getTimelineLockButtonOffImage()
188 : getXsheetLockButtonOffImage();
189 break;
190 case CONFIG_XSHBUTTON:
191 bgColor = (isTimeline) ? getTimelineConfigButtonBgColor()
192 : getXsheetConfigButtonBgColor();
193 iconImage = (isTimeline) ? getTimelineConfigButtonImage()
194 : getXsheetConfigButtonImage();
195 break;
196 default:
197 bgColor = grey210;
198 static QImage iconignored;
199 iconImage = iconignored;
200 }
201 }
202
203 //-----------------------------------------------------------------------------
204
205 #if QT_VERSION >= 0x050500
XsheetViewer(QWidget * parent,Qt::WindowFlags flags)206 XsheetViewer::XsheetViewer(QWidget *parent, Qt::WindowFlags flags)
207 #else
208 XsheetViewer::XsheetViewer(QWidget *parent, Qt::WFlags flags)
209 #endif
210 : QFrame(parent)
211 , m_timerId(0)
212 , m_autoPanSpeed(0, 0)
213 , m_dragTool(0)
214 , m_columnSelection(new TColumnSelection())
215 , m_cellKeyframeSelection(new TCellKeyframeSelection(
216 new TCellSelection(), new TKeyframeSelection()))
217 , m_scrubCol(-1)
218 , m_scrubRow0(-1)
219 , m_scrubRow1(-1)
220 , m_isCurrentFrameSwitched(false)
221 , m_isCurrentColumnSwitched(false)
222 , m_isComputingSize(false)
223 , m_currentNoteIndex(0)
224 , m_qtModifiers(0)
225 , m_frameDisplayStyle(to_enum(FrameDisplayStyleInXsheetRowArea))
226 , m_orientation(nullptr)
227 , m_xsheetLayout("Classic")
228 , m_frameZoomFactor(100) {
229
230 m_xsheetLayout = Preferences::instance()->getLoadedXsheetLayout();
231
232 setFocusPolicy(Qt::StrongFocus);
233
234 setFrameStyle(QFrame::StyledPanel);
235 setObjectName("XsheetViewer");
236
237 m_orientation = Orientations::topToBottom();
238
239 m_cellKeyframeSelection->setXsheetHandle(
240 TApp::instance()->getCurrentXsheet());
241
242 m_toolbarScrollArea = new XsheetScrollArea(this);
243 m_toolbarScrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
244 m_toolbarScrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
245 m_toolbar = new XsheetGUI::XSheetToolbar(this, 0, true);
246 m_toolbarScrollArea->setWidget(m_toolbar);
247
248 QRect noteArea(0, 0, 75, 120);
249 m_noteArea = new XsheetGUI::NoteArea(this);
250 m_noteScrollArea = new XsheetScrollArea(this);
251 m_noteScrollArea->setObjectName("xsheetArea");
252 m_noteScrollArea->setWidget(m_noteArea);
253 m_noteScrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
254 m_noteScrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
255
256 m_cellArea = new XsheetGUI::CellArea(this);
257 m_cellScrollArea = new XsheetScrollArea(this);
258 m_cellScrollArea->setObjectName("xsheetArea");
259 m_cellScrollArea->setWidget(m_cellArea);
260 m_cellScrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
261 m_cellScrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
262
263 m_columnArea = new XsheetGUI::ColumnArea(this);
264 m_columnScrollArea = new XsheetScrollArea(this);
265 m_columnScrollArea->setObjectName("xsheetArea");
266 m_columnScrollArea->setWidget(m_columnArea);
267 m_columnScrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
268 m_columnScrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
269
270 m_rowArea = new XsheetGUI::RowArea(this);
271 m_rowScrollArea = new XsheetScrollArea(this);
272 m_rowScrollArea->setObjectName("xsheetArea");
273 m_rowScrollArea->setWidget(m_rowArea);
274 m_rowScrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
275 m_rowScrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
276
277 m_layerFooterPanel = new LayerFooterPanel(this, this);
278
279 m_frameScroller.setFrameScrollArea(m_cellScrollArea);
280 connect(&m_frameScroller, &Spreadsheet::FrameScroller::prepareToScrollOffset,
281 this, &XsheetViewer::onPrepareToScrollOffset);
282 connect(&m_frameScroller, &Spreadsheet::FrameScroller::zoomScrollAdjust, this,
283 &XsheetViewer::onZoomScrollAdjust);
284
285 connectScrollBars();
286
287 connect(this, &XsheetViewer::orientationChanged, this,
288 &XsheetViewer::onOrientationChanged);
289 connect(m_toolbar, SIGNAL(updateVisibility()), this,
290 SLOT(positionSections()));
291
292 emit orientationChanged(orientation());
293
294 onPreferenceChanged("XsheetCamera");
295 }
296
297 //-----------------------------------------------------------------------------
298
~XsheetViewer()299 XsheetViewer::~XsheetViewer() {
300 delete m_cellKeyframeSelection;
301 delete m_dragTool;
302 }
303
304 //-----------------------------------------------------------------------------
305
setDragTool(XsheetGUI::DragTool * dragTool)306 void XsheetViewer::setDragTool(XsheetGUI::DragTool *dragTool) {
307 assert(m_dragTool == 0);
308 m_dragTool = dragTool;
309 }
310
311 //-----------------------------------------------------------------------------
312
dragToolClick(QMouseEvent * e)313 void XsheetViewer::dragToolClick(QMouseEvent *e) {
314 if (m_dragTool) m_dragTool->onClick(e);
315 }
316
dragToolDrag(QMouseEvent * e)317 void XsheetViewer::dragToolDrag(QMouseEvent *e) {
318 if (m_dragTool) m_dragTool->onDrag(e);
319 }
320
dragToolRelease(QMouseEvent * e)321 void XsheetViewer::dragToolRelease(QMouseEvent *e) {
322 if (m_dragTool) {
323 m_dragTool->onRelease(e);
324 delete getDragTool();
325 m_dragTool = 0;
326 }
327 }
328
329 //-----------------------------------------------------------------------------
330
dragToolClick(QDropEvent * e)331 void XsheetViewer::dragToolClick(QDropEvent *e) {
332 if (m_dragTool) m_dragTool->onClick(e);
333 }
334
dragToolDrag(QDropEvent * e)335 void XsheetViewer::dragToolDrag(QDropEvent *e) {
336 if (m_dragTool) m_dragTool->onDrag(e);
337 }
338
dragToolRelease(QDropEvent * e)339 void XsheetViewer::dragToolRelease(QDropEvent *e) {
340 if (m_dragTool) {
341 m_dragTool->onRelease(e);
342 delete getDragTool();
343 m_dragTool = 0;
344 }
345 }
346
dragToolLeave(QEvent * e)347 void XsheetViewer::dragToolLeave(QEvent *e) {
348 if (m_dragTool) {
349 delete getDragTool();
350 m_dragTool = 0;
351 }
352 }
353
354 //-----------------------------------------------------------------------------
355
orientation() const356 const Orientation *XsheetViewer::orientation() const {
357 if (!m_orientation) throw std::runtime_error("!m_orientation");
358 return m_orientation;
359 }
360
flipOrientation()361 void XsheetViewer::flipOrientation() {
362 m_orientation = orientation()->next();
363 emit orientationChanged(orientation());
364 }
365
onOrientationChanged(const Orientation * newOrientation)366 void XsheetViewer::onOrientationChanged(const Orientation *newOrientation) {
367 disconnectScrollBars();
368
369 positionSections();
370 m_frameScroller.setOrientation(newOrientation);
371 refreshContentSize(0, 0);
372
373 connectScrollBars();
374
375 update();
376 }
377
positionSections()378 void XsheetViewer::positionSections() {
379 if (!isVisible()) return;
380 const Orientation *o = orientation();
381 QRect size = QRect(QPoint(0, 0), geometry().size());
382 NumberRange allLayer = o->layerSide(size);
383 NumberRange allFrame = o->frameSide(size);
384
385 NumberRange headerLayer = o->range(PredefinedRange::HEADER_LAYER);
386 NumberRange headerFrame = o->range(PredefinedRange::HEADER_FRAME);
387 NumberRange bodyLayer(headerLayer.to(), allLayer.to());
388 NumberRange bodyFrame(headerFrame.to(), allFrame.to());
389
390 if (Preferences::instance()->isShowXSheetToolbarEnabled()) {
391 m_toolbar->showToolbar(true);
392 int w = visibleRegion().boundingRect().width();
393 m_toolbarScrollArea->setGeometry(0, 0, w, XsheetGUI::TOOLBAR_HEIGHT);
394 m_toolbar->setFixedWidth(w);
395 if (o->isVerticalTimeline()) {
396 headerFrame = headerFrame.adjusted(XsheetGUI::TOOLBAR_HEIGHT,
397 XsheetGUI::TOOLBAR_HEIGHT);
398 bodyFrame = bodyFrame.adjusted(XsheetGUI::TOOLBAR_HEIGHT, 0);
399 } else {
400 headerLayer = headerLayer.adjusted(XsheetGUI::TOOLBAR_HEIGHT,
401 XsheetGUI::TOOLBAR_HEIGHT);
402 bodyLayer = bodyLayer.adjusted(XsheetGUI::TOOLBAR_HEIGHT, 0);
403 }
404 } else {
405 m_toolbar->showToolbar(false);
406 }
407
408 m_noteScrollArea->setGeometry(o->frameLayerRect(headerFrame, headerLayer));
409 m_cellScrollArea->setGeometry(o->frameLayerRect(bodyFrame, bodyLayer));
410 m_columnScrollArea->setGeometry(
411 o->frameLayerRect(headerFrame.adjusted(-1, -1),
412 bodyLayer.adjusted(0, -XsheetGUI::SCROLLBAR_WIDTH)));
413 m_rowScrollArea->setGeometry(o->frameLayerRect(
414 bodyFrame.adjusted(0, -XsheetGUI::SCROLLBAR_WIDTH), headerLayer));
415
416 m_layerFooterPanel->setGeometry(0,
417 m_columnScrollArea->geometry().bottom() + 1,
418 m_columnScrollArea->width(), 14);
419
420 m_layerFooterPanel->showOrHide(o);
421 }
422
disconnectScrollBars()423 void XsheetViewer::disconnectScrollBars() {
424 connectOrDisconnectScrollBars(false);
425 }
connectScrollBars()426 void XsheetViewer::connectScrollBars() { connectOrDisconnectScrollBars(true); }
427
connectOrDisconnectScrollBars(bool toConnect)428 void XsheetViewer::connectOrDisconnectScrollBars(bool toConnect) {
429 const Orientation *o = orientation();
430 bool isVertical = o->isVerticalTimeline();
431 QWidget *scrolledVertically =
432 (isVertical ? m_rowScrollArea : m_columnScrollArea)->verticalScrollBar();
433 QWidget *scrolledHorizontally =
434 (isVertical ? m_columnScrollArea : m_rowScrollArea)
435 ->horizontalScrollBar();
436
437 connectOrDisconnect(toConnect, scrolledVertically, SIGNAL(valueChanged(int)),
438 m_cellScrollArea->verticalScrollBar(),
439 SLOT(setValue(int)));
440 connectOrDisconnect(toConnect, m_cellScrollArea->verticalScrollBar(),
441 SIGNAL(valueChanged(int)), scrolledVertically,
442 SLOT(setValue(int)));
443
444 connectOrDisconnect(
445 toConnect, scrolledHorizontally, SIGNAL(valueChanged(int)),
446 m_cellScrollArea->horizontalScrollBar(), SLOT(setValue(int)));
447 connectOrDisconnect(toConnect, m_cellScrollArea->horizontalScrollBar(),
448 SIGNAL(valueChanged(int)), scrolledHorizontally,
449 SLOT(setValue(int)));
450
451 connectOrDisconnect(
452 toConnect, m_cellScrollArea->verticalScrollBar(),
453 SIGNAL(valueChanged(int)), this,
454 isVertical ? SLOT(updateCellRowAree()) : SLOT(updateCellColumnAree()));
455 connectOrDisconnect(
456 toConnect, m_cellScrollArea->horizontalScrollBar(),
457 SIGNAL(valueChanged(int)), this,
458 isVertical ? SLOT(updateCellColumnAree()) : SLOT(updateCellRowAree()));
459 }
460
connectOrDisconnect(bool toConnect,QWidget * sender,const char * signal,QWidget * receiver,const char * slot)461 void XsheetViewer::connectOrDisconnect(bool toConnect, QWidget *sender,
462 const char *signal, QWidget *receiver,
463 const char *slot) {
464 if (toConnect)
465 connect(sender, signal, receiver, slot);
466 else
467 disconnect(sender, signal, receiver, slot);
468 }
469
470 //-----------------------------------------------------------------------------
471
getXsheet() const472 TXsheet *XsheetViewer::getXsheet() const {
473 return TApp::instance()->getCurrentXsheet()->getXsheet();
474 }
475
476 //-----------------------------------------------------------------------------
477
getCurrentColumn() const478 int XsheetViewer::getCurrentColumn() const {
479 return TApp::instance()->getCurrentColumn()->getColumnIndex();
480 }
481
482 //-----------------------------------------------------------------------------
483
getCurrentRow() const484 int XsheetViewer::getCurrentRow() const {
485 return TApp::instance()->getCurrentFrame()->getFrame();
486 }
487
488 //-----------------------------------------------------------------------------
489
getObjectId(int col) const490 TStageObjectId XsheetViewer::getObjectId(int col) const {
491 TXsheet *xsh = getXsheet();
492 if (col < 0) return TStageObjectId::CameraId(xsh->getCameraColumnIndex());
493 return TStageObjectId::ColumnId(col);
494 }
495 //-----------------------------------------------------------------------------
496
setCurrentColumn(int col)497 void XsheetViewer::setCurrentColumn(int col) {
498 TColumnHandle *columnHandle = TApp::instance()->getCurrentColumn();
499 if (col != columnHandle->getColumnIndex()) {
500 columnHandle->setColumnIndex(col);
501 // E' necessario per il caso in cui si passa da colonna di camera a altra
502 // colonna
503 // o nel caso in cui si passa da una spline a una colonna.
504 TObjectHandle *objectHandle = TApp::instance()->getCurrentObject();
505 if (col >= 0 && objectHandle->isSpline()) objectHandle->setIsSpline(false);
506 updateCellColumnAree();
507 if (col >= 0) {
508 objectHandle->setObjectId(TStageObjectId::ColumnId(col));
509 TXsheet *xsh = getXsheet();
510 TXshColumn *column = xsh->getColumn(col);
511 if (!column || !column->getZeraryFxColumn()) return;
512 TFx *fx = column->getZeraryFxColumn()->getZeraryColumnFx();
513 TApp::instance()->getCurrentFx()->setFx(fx);
514 }
515 return;
516 }
517 }
518
519 //-----------------------------------------------------------------------------
520
setCurrentRow(int row)521 void XsheetViewer::setCurrentRow(int row) {
522 // POTREBBE NON ESSER PIU' NECESSARIO CON LE NUOVE MODIFICHE PER CLEANUP A
523 // COLORI
524 /*TFrameHandle* frameHandle = TApp::instance()->getCurrentFrame();
525 if(row == frameHandle->getFrameIndex() && frameHandle->getFrameType() ==
526 TFrameHandle::SceneFrame)
527 {
528 //E' necessario per il caso in cui la paletta corrente e' la paletta di cleanup.
529 TPaletteHandle* levelPaletteHandle =
530 TApp::instance()->getPaletteController()->getCurrentLevelPalette();
531 TXshLevel *xl = TApp::instance()->getCurrentLevel()->getLevel();
532 if(xl && xl->getSimpleLevel())
533 levelPaletteHandle->setPalette(xl->getSimpleLevel()->getPalette());
534 else if(xl && xl->getPaletteLevel())
535 levelPaletteHandle->setPalette(xl->getPaletteLevel()->getPalette());
536 else
537 levelPaletteHandle->setPalette(0);
538 return;
539 }
540 frameHandle->setFrame(row);*/
541 TApp::instance()->getCurrentFrame()->setFrame(row);
542 }
543
544 //-----------------------------------------------------------------------------
545
scroll(QPoint delta)546 void XsheetViewer::scroll(QPoint delta) {
547 int x = delta.x();
548 int y = delta.y();
549
550 int valueH = m_cellScrollArea->horizontalScrollBar()->value() + x;
551 int valueV = m_cellScrollArea->verticalScrollBar()->value() + y;
552 int maxValueH = m_cellScrollArea->horizontalScrollBar()->maximum();
553 int maxValueV = m_cellScrollArea->verticalScrollBar()->maximum();
554
555 bool notUpdateSizeH = maxValueH > valueH && x >= 0;
556 bool notUpdateSizeV = maxValueV > valueV && y >= 0;
557 if (!notUpdateSizeH && !notUpdateSizeV) // Resize orizzontale e verticale
558 refreshContentSize(x, y);
559 else if (notUpdateSizeH && !notUpdateSizeV) // Resize verticale
560 refreshContentSize(0, y);
561 else if (!notUpdateSizeH && notUpdateSizeV) // Resize orizzontale
562 refreshContentSize(x, 0);
563
564 // Recheck in case refreshContentSize changed the max
565 if (!notUpdateSizeH)
566 maxValueH = m_cellScrollArea->horizontalScrollBar()->maximum();
567 if (!notUpdateSizeV)
568 maxValueV = m_cellScrollArea->verticalScrollBar()->maximum();
569
570 if (valueH > maxValueH && x > 0) // Se il valore e' maggiore del max e x>0
571 // scrollo al massimo valore orizzontale
572 valueH = m_cellScrollArea->horizontalScrollBar()->maximum();
573
574 if (valueV > maxValueV && y > 0) // Se il valore e' maggiore del max e y>0
575 // scrollo al massimo valore verticale
576 valueV = m_cellScrollArea->verticalScrollBar()->maximum();
577
578 m_cellScrollArea->horizontalScrollBar()->setValue(valueH);
579 m_cellScrollArea->verticalScrollBar()->setValue(valueV);
580 }
581
582 //-----------------------------------------------------------------------------
583
onPrepareToScrollOffset(const QPoint & offset)584 void XsheetViewer::onPrepareToScrollOffset(const QPoint &offset) {
585 refreshContentSize(offset.x(), offset.y());
586 }
587
588 //-----------------------------------------------------------------------------
589
onZoomScrollAdjust(QPoint & offset,bool toZoom)590 void XsheetViewer::onZoomScrollAdjust(QPoint &offset, bool toZoom) {
591 int frameZoomFactor = getFrameZoomFactor();
592
593 // toZoom = true: Adjust standardized offset down to zoom factor
594 // toZoom = false: Adjust zoomed offset up to standardized offset
595 int newX;
596 if (toZoom)
597 newX = (offset.x() * frameZoomFactor) / 100;
598 else
599 newX = (offset.x() * 100) / frameZoomFactor;
600
601 offset.setX(newX);
602 }
603
604 //-----------------------------------------------------------------------------
605
setAutoPanSpeed(const QPoint & speed)606 void XsheetViewer::setAutoPanSpeed(const QPoint &speed) {
607 bool wasAutoPanning = isAutoPanning();
608 m_autoPanSpeed = speed;
609 if (isAutoPanning() && !wasAutoPanning && m_timerId == 0)
610 m_timerId = startTimer(40);
611 else if (!isAutoPanning() && wasAutoPanning && m_timerId != 0) {
612 killTimer(m_timerId);
613 m_timerId = 0;
614 }
615 }
616
617 //-----------------------------------------------------------------------------
618
getAutoPanSpeed(int pixels)619 static int getAutoPanSpeed(int pixels) {
620 int f = 40;
621 return std::min(100, (f - 1 + pixels * f) / 100);
622 }
623
624 //-----------------------------------------------------------------------------
625
setAutoPanSpeed(const QRect & widgetBounds,const QPoint & mousePos)626 void XsheetViewer::setAutoPanSpeed(const QRect &widgetBounds,
627 const QPoint &mousePos) {
628 QPoint speed;
629 int limit = 100, factor = 30;
630 if (mousePos.x() < widgetBounds.left())
631 speed.setX(-getAutoPanSpeed(widgetBounds.left() - mousePos.x()));
632 else if (mousePos.x() > widgetBounds.right())
633 speed.setX(getAutoPanSpeed(mousePos.x() - widgetBounds.right()));
634 if (mousePos.y() < widgetBounds.top())
635 speed.setY(-getAutoPanSpeed(widgetBounds.top() - mousePos.y()));
636 else if (mousePos.y() > widgetBounds.bottom())
637 speed.setY(getAutoPanSpeed(mousePos.y() - widgetBounds.bottom()));
638 setAutoPanSpeed(speed);
639 m_lastAutoPanPos = mousePos;
640 }
641
642 //-----------------------------------------------------------------------------
643
timerEvent(QTimerEvent *)644 void XsheetViewer::timerEvent(QTimerEvent *) {
645 if (!isAutoPanning()) return;
646 scroll(m_autoPanSpeed);
647 if (!m_dragTool) return;
648 QMouseEvent mouseEvent(QEvent::MouseMove, m_lastAutoPanPos - m_autoPanSpeed,
649 Qt::NoButton, 0, m_qtModifiers);
650 m_dragTool->onDrag(&mouseEvent);
651 m_lastAutoPanPos += m_autoPanSpeed;
652 }
653
654 //-----------------------------------------------------------------------------
655
656 // adjust sizes after scrolling event
refreshContentSize(int dx,int dy)657 bool XsheetViewer::refreshContentSize(int dx, int dy) {
658 QSize viewportSize = m_cellScrollArea->viewport()->size();
659 QPoint offset = m_cellArea->pos();
660 offset = QPoint(std::min(0, offset.x() - dx),
661 std::min(0, offset.y() - dy)); // what?
662
663 TXsheet *xsh = getXsheet();
664 int frameCount = xsh ? xsh->getFrameCount() : 0;
665 int columnCount = xsh ? xsh->getColumnCount() : 0;
666 QPoint contentSize;
667
668 if (m_orientation->isVerticalTimeline())
669 contentSize = positionToXY(CellPosition(frameCount + 1, columnCount + 1));
670 else {
671 int firstCol =
672 Preferences::instance()->isXsheetCameraColumnVisible() ? -1 : 0;
673 contentSize = positionToXY(CellPosition(frameCount + 1, firstCol));
674
675 ColumnFan *fan = xsh->getColumnFan(m_orientation);
676 contentSize.setY(contentSize.y() + 1 +
677 (fan->isActive(firstCol)
678 ? m_orientation->cellHeight()
679 : m_orientation->foldedCellSize()));
680 }
681
682 QSize actualSize(contentSize.x(), contentSize.y());
683 int x = viewportSize.width() - offset.x(); // wtf is going on
684 int y = viewportSize.height() - offset.y();
685 if (x > actualSize.width()) actualSize.setWidth(x);
686 if (m_orientation->isVerticalTimeline() && y > actualSize.height())
687 actualSize.setHeight(y);
688
689 if (actualSize == m_cellArea->size())
690 return false;
691 else {
692 const Orientation *o = orientation();
693 NumberRange allLayer = o->layerSide(QRect(QPoint(0, 0), actualSize));
694 NumberRange allFrame = o->frameSide(QRect(QPoint(0, 0), actualSize));
695 NumberRange headerLayer = o->range(PredefinedRange::HEADER_LAYER);
696 NumberRange headerFrame = o->range(PredefinedRange::HEADER_FRAME);
697
698 m_isComputingSize = true;
699 m_noteArea->setFixedSize(o->rect(PredefinedRect::NOTE_AREA).size());
700 m_cellArea->setFixedSize(actualSize);
701 m_rowArea->setFixedSize(o->frameLayerRect(allFrame, headerLayer).size());
702 m_columnArea->setFixedSize(o->frameLayerRect(headerFrame, allLayer).size());
703 m_isComputingSize = false;
704 return true;
705 }
706 }
707
708 //-----------------------------------------------------------------------------
709
710 // call when in doubt
updateAreeSize()711 void XsheetViewer::updateAreeSize() {
712 const Orientation *o = orientation();
713 QRect viewArea(QPoint(0, 0), m_cellScrollArea->geometry()
714 .adjusted(0, 0, -XsheetGUI::SCROLLBAR_WIDTH,
715 -XsheetGUI::SCROLLBAR_WIDTH)
716 .size());
717
718 QPoint areaFilled(0, 0);
719 TXsheet *xsh = getXsheet();
720 if (xsh) {
721 if (o->isVerticalTimeline())
722 areaFilled = positionToXY(
723 CellPosition(xsh->getFrameCount() + 1, xsh->getColumnCount() + 1));
724 else {
725 int firstCol =
726 Preferences::instance()->isXsheetCameraColumnVisible() ? -1 : 0;
727 areaFilled =
728 positionToXY(CellPosition(xsh->getFrameCount() + 1, firstCol));
729
730 ColumnFan *fan = xsh->getColumnFan(m_orientation);
731 areaFilled.setY(
732 areaFilled.y() + 1 +
733 (fan->isActive(firstCol) ? o->cellHeight() : o->foldedCellSize()));
734 }
735 }
736 if (viewArea.width() < areaFilled.x()) viewArea.setWidth(areaFilled.x());
737 if (viewArea.height() < areaFilled.y() ||
738 (!o->isVerticalTimeline() && viewArea.height() != areaFilled.y()))
739 viewArea.setHeight(areaFilled.y());
740
741 NumberRange allLayer = o->layerSide(viewArea);
742 NumberRange allFrame = o->frameSide(viewArea);
743 NumberRange headerLayer = o->range(PredefinedRange::HEADER_LAYER);
744 NumberRange headerFrame = o->range(PredefinedRange::HEADER_FRAME);
745
746 m_cellArea->setFixedSize(viewArea.size());
747 m_rowArea->setFixedSize(o->frameLayerRect(allFrame, headerLayer).size());
748 m_columnArea->setFixedSize(o->frameLayerRect(headerFrame, allLayer).size());
749 }
750
751 //-----------------------------------------------------------------------------
752
colToTimelineLayerAxis(int layer) const753 int XsheetViewer::colToTimelineLayerAxis(int layer) const {
754 const Orientation *o = orientation();
755 TXsheet *xsh = getXsheet();
756 if (!xsh) return 0;
757 ColumnFan *fan = xsh->getColumnFan(o);
758
759 int yBottom = o->colToLayerAxis(layer, fan) +
760 (fan->isActive(layer) ? o->cellHeight() : o->foldedCellSize()) -
761 1;
762 int columnCount = std::max(1, xsh->getColumnCount());
763 int layerHeightActual =
764 m_columnArea->height() - 2; // o->colToLayerAxis(columnCount, fan) - 1;
765
766 return layerHeightActual - yBottom;
767 }
768
769 //-----------------------------------------------------------------------------
770
xyToPosition(const QPoint & point) const771 CellPosition XsheetViewer::xyToPosition(const QPoint &point) const {
772 const Orientation *o = orientation();
773 QPoint usePoint = point;
774 TXsheet *xsh = getXsheet();
775
776 if (!xsh) return CellPosition(0, 0);
777
778 ColumnFan *fan = xsh->getColumnFan(o);
779
780 if (!o->isVerticalTimeline())
781 usePoint.setX((usePoint.x() * 100) / getFrameZoomFactor());
782
783 if (o->isVerticalTimeline()) return o->xyToPosition(usePoint, fan);
784
785 // For timeline mode, we need to base the Y axis on the bottom of the column
786 // area
787 // since the layers are flipped
788 int columnCount = std::max(1, xsh->getColumnCount());
789 int colAreaHeight = o->colToLayerAxis(columnCount, fan);
790
791 usePoint.setY(colAreaHeight - usePoint.y());
792
793 CellPosition resultCP = o->xyToPosition(usePoint, fan);
794 if (point.y() > colAreaHeight) {
795 int colsBelow = ((point.y() - colAreaHeight) / o->cellHeight()) + 1;
796 resultCP.setLayer(-colsBelow);
797 }
798 return resultCP;
799 }
xyToPosition(const TPoint & point) const800 CellPosition XsheetViewer::xyToPosition(const TPoint &point) const {
801 return xyToPosition(QPoint(point.x, point.y));
802 }
xyToPosition(const TPointD & point) const803 CellPosition XsheetViewer::xyToPosition(const TPointD &point) const {
804 return xyToPosition(QPoint((int)point.x, (int)point.y));
805 }
806
807 //-----------------------------------------------------------------------------
808
positionToXY(const CellPosition & pos) const809 QPoint XsheetViewer::positionToXY(const CellPosition &pos) const {
810 const Orientation *o = orientation();
811 TXsheet *xsh = getXsheet();
812 if (!xsh) return QPoint(0, 0);
813 ColumnFan *fan = xsh->getColumnFan(o);
814 QPoint usePoint = o->positionToXY(pos, fan);
815
816 if (!o->isVerticalTimeline())
817 usePoint.setX((usePoint.x() * getFrameZoomFactor()) / 100);
818
819 if (o->isVerticalTimeline()) return usePoint;
820
821 // For timeline mode, we need to base the Y axis on the bottom of the column
822 // area
823 // since the layers are flipped
824
825 usePoint.setY(
826 usePoint.y() - o->cellHeight() +
827 (fan->isActive(pos.layer()) ? o->cellHeight() : o->foldedCellSize()));
828 int columnCount = std::max(1, xsh->getColumnCount());
829 int colsHeight = o->colToLayerAxis(columnCount, fan);
830
831 if (colsHeight)
832 usePoint.setY(colsHeight - usePoint.y() - o->cellHeight());
833 else
834 usePoint.setY(0);
835
836 return usePoint;
837 }
838
columnToLayerAxis(int layer) const839 int XsheetViewer::columnToLayerAxis(int layer) const {
840 const Orientation *o = orientation();
841 TXsheet *xsh = getXsheet();
842 if (!xsh) return 0;
843 if (o->isVerticalTimeline())
844 return o->colToLayerAxis(layer, xsh->getColumnFan(o));
845 else
846 return colToTimelineLayerAxis(layer);
847 }
rowToFrameAxis(int frame) const848 int XsheetViewer::rowToFrameAxis(int frame) const {
849 int result = orientation()->rowToFrameAxis(frame);
850 if (!orientation()->isVerticalTimeline())
851 result = (result * getFrameZoomFactor()) / 100;
852 return result;
853 }
854
855 //-----------------------------------------------------------------------------
856
xyRectToRange(const QRect & rect) const857 CellRange XsheetViewer::xyRectToRange(const QRect &rect) const {
858 CellPosition topLeft = xyToPosition(rect.topLeft());
859 CellPosition bottomRight = xyToPosition(rect.bottomRight());
860 return CellRange(topLeft, bottomRight);
861 }
862
863 //-----------------------------------------------------------------------------
864
rangeToXYRect(const CellRange & range) const865 QRect XsheetViewer::rangeToXYRect(const CellRange &range) const {
866 QPoint from = positionToXY(range.from());
867 QPoint to = positionToXY(range.to());
868 QPoint topLeft =
869 QPoint(std::min(from.x(), to.x()), std::min(from.y(), to.y()));
870 QPoint bottomRight =
871 QPoint(std::max(from.x(), to.x()), std::max(from.y(), to.y()));
872 return QRect(topLeft, bottomRight);
873 }
874
875 //-----------------------------------------------------------------------------
876
drawPredefinedPath(QPainter & p,PredefinedPath which,const CellPosition & pos,optional<QColor> fill,optional<QColor> outline) const877 void XsheetViewer::drawPredefinedPath(QPainter &p, PredefinedPath which,
878 const CellPosition &pos,
879 optional<QColor> fill,
880 optional<QColor> outline) const {
881 QPoint xy = positionToXY(pos);
882 QPainterPath path = orientation()->path(which).translated(xy);
883 if (fill) p.fillPath(path, QBrush(*fill));
884 if (outline) {
885 p.setPen(*outline);
886 p.drawPath(path);
887 }
888 }
889
890 //-----------------------------------------------------------------------------
891
drawPredefinedPath(QPainter & p,PredefinedPath which,QPoint xy,optional<QColor> fill,optional<QColor> outline) const892 void XsheetViewer::drawPredefinedPath(QPainter &p, PredefinedPath which,
893 QPoint xy, optional<QColor> fill,
894 optional<QColor> outline) const {
895 QPainterPath path = orientation()->path(which).translated(xy);
896 if (fill) p.fillPath(path, QBrush(*fill));
897 if (outline) {
898 p.setPen(*outline);
899 p.drawPath(path);
900 }
901 }
902
903 //-----------------------------------------------------------------------------
904
areCellsSelectedEmpty()905 bool XsheetViewer::areCellsSelectedEmpty() {
906 int r0, c0, r1, c1;
907 getCellSelection()->getSelectedCells(r0, c0, r1, c1);
908 int i, j;
909 for (i = r0; i <= r1; i++)
910 for (j = c0; j <= c1; j++)
911 if (!getXsheet()->getCell(i, j).isEmpty()) return false;
912 return true;
913 }
914
915 //-----------------------------------------------------------------------------
916
areSoundCellsSelected()917 bool XsheetViewer::areSoundCellsSelected() {
918 int r0, c0, r1, c1;
919 getCellSelection()->getSelectedCells(r0, c0, r1, c1);
920 if (c0 < 0) return false;
921 int i, j;
922 for (i = r0; i <= r1; i++)
923 for (j = c0; j <= c1; j++) {
924 TXshCell cell = getXsheet()->getCell(i, j);
925 if (cell.isEmpty() || cell.getSoundLevel()) continue;
926 return false;
927 }
928 return !areCellsSelectedEmpty();
929 }
930
931 //-----------------------------------------------------------------------------
932
areSoundTextCellsSelected()933 bool XsheetViewer::areSoundTextCellsSelected() {
934 int r0, c0, r1, c1;
935 getCellSelection()->getSelectedCells(r0, c0, r1, c1);
936 if (c0 < 0) return false;
937 int i, j;
938 for (i = r0; i <= r1; i++)
939 for (j = c0; j <= c1; j++) {
940 TXshCell cell = getXsheet()->getCell(i, j);
941 if (cell.isEmpty() || cell.getSoundTextLevel()) continue;
942 return false;
943 }
944 return !areCellsSelectedEmpty();
945 }
946
947 //-----------------------------------------------------------------------------
948
areCameraCellsSelected()949 bool XsheetViewer::areCameraCellsSelected() {
950 int r0, c0, r1, c1;
951 getCellSelection()->getSelectedCells(r0, c0, r1, c1);
952 return c0 < 0;
953 }
954
955 //-----------------------------------------------------------------------------
956
setScrubHighlight(int row,int startRow,int col)957 void XsheetViewer::setScrubHighlight(int row, int startRow, int col) {
958 if (m_scrubCol == -1) m_scrubCol = col;
959 m_scrubRow0 = std::min(row, startRow);
960 m_scrubRow1 = std::max(row, startRow);
961 return;
962 }
963
964 //-----------------------------------------------------------------------------
965
resetScrubHighlight()966 void XsheetViewer::resetScrubHighlight() {
967 m_scrubCol = m_scrubRow0 = m_scrubRow1 = -1;
968 return;
969 }
970
971 //-----------------------------------------------------------------------------
972
getScrubHeighlight(int & R0,int & R1)973 void XsheetViewer::getScrubHeighlight(int &R0, int &R1) {
974 R0 = m_scrubRow0;
975 R1 = m_scrubRow1;
976 return;
977 }
978
979 //-----------------------------------------------------------------------------
980
isScrubHighlighted(int row,int col)981 bool XsheetViewer::isScrubHighlighted(int row, int col) {
982 if (m_scrubCol == col && m_scrubRow0 <= row && row <= m_scrubRow1)
983 return true;
984 return false;
985 }
986
987 //-----------------------------------------------------------------------------
988
showEvent(QShowEvent *)989 void XsheetViewer::showEvent(QShowEvent *) {
990 m_frameScroller.registerFrameScroller();
991 if (m_isCurrentFrameSwitched) onCurrentFrameSwitched();
992 if (m_isCurrentColumnSwitched) onCurrentColumnSwitched();
993 m_isCurrentFrameSwitched = false;
994
995 TApp *app = TApp::instance();
996
997 bool ret = connect(app->getCurrentColumn(), SIGNAL(columnIndexSwitched()),
998 this, SLOT(onCurrentColumnSwitched()));
999 ret = ret && connect(app->getCurrentFrame(), SIGNAL(frameSwitched()), this,
1000 SLOT(onCurrentFrameSwitched()));
1001 ret = ret && connect(app->getCurrentFrame(), SIGNAL(isPlayingStatusChanged()),
1002 this, SLOT(onPlayingStatusChanged()));
1003 ret = ret && connect(app->getCurrentFrame(), SIGNAL(scrubStopped()), this,
1004 SLOT(onScrubStopped()));
1005
1006 ret = ret && connect(app->getCurrentObject(), SIGNAL(objectChanged(bool)),
1007 this, SLOT(updateAllAree(bool)));
1008
1009 TSceneHandle *sceneHandle = app->getCurrentScene();
1010 ret = ret && connect(sceneHandle, SIGNAL(sceneSwitched()), this,
1011 SLOT(onSceneSwitched()));
1012 ret = ret && connect(sceneHandle, SIGNAL(nameSceneChanged()), this,
1013 SLOT(changeWindowTitle()));
1014 ret = ret && connect(sceneHandle, SIGNAL(preferenceChanged(const QString &)),
1015 this, SLOT(onPreferenceChanged(const QString &)));
1016
1017 TXsheetHandle *xsheetHandle = app->getCurrentXsheet();
1018 ret = ret && connect(xsheetHandle, SIGNAL(xsheetSwitched()), this,
1019 SLOT(updateAllAree()));
1020 ret = ret && connect(xsheetHandle, SIGNAL(xsheetSwitched()), this,
1021 SLOT(resetXsheetNotes()));
1022 ret = ret && connect(xsheetHandle, SIGNAL(xsheetChanged()), this,
1023 SLOT(onXsheetChanged()));
1024 ret = ret && connect(xsheetHandle, SIGNAL(xsheetChanged()), this,
1025 SLOT(changeWindowTitle()));
1026
1027 ret = ret &&
1028 connect(app->getCurrentSelection(),
1029 SIGNAL(selectionSwitched(TSelection *, TSelection *)), this,
1030 SLOT(onSelectionSwitched(TSelection *, TSelection *)));
1031 // update titlebar when the cell selection region is changed
1032 ret = ret && connect(app->getCurrentSelection(),
1033 SIGNAL(selectionChanged(TSelection *)), this,
1034 SLOT(onSelectionChanged(TSelection *)));
1035 // show the current level name to title bar
1036 ret = ret &&
1037 connect(app->getCurrentLevel(), SIGNAL(xshLevelSwitched(TXshLevel *)),
1038 this, SLOT(changeWindowTitle()));
1039
1040 ret = ret && connect(IconGenerator::instance(), SIGNAL(iconGenerated()), this,
1041 SLOT(updateColumnArea()));
1042
1043 assert(ret);
1044 refreshContentSize(0, 0);
1045 changeWindowTitle();
1046 }
1047
1048 //-----------------------------------------------------------------------------
1049
hideEvent(QHideEvent *)1050 void XsheetViewer::hideEvent(QHideEvent *) {
1051 m_frameScroller.unregisterFrameScroller();
1052
1053 TApp *app = TApp::instance();
1054
1055 disconnect(app->getCurrentColumn(), SIGNAL(columnIndexSwitched()), this,
1056 SLOT(onCurrentColumnSwitched()));
1057 disconnect(app->getCurrentFrame(), SIGNAL(frameSwitched()), this,
1058 SLOT(onCurrentFrameSwitched()));
1059 disconnect(app->getCurrentFrame(), SIGNAL(scrubStopped()), this,
1060 SLOT(onScrubStopped()));
1061
1062 disconnect(app->getCurrentObject(), SIGNAL(objectChanged(bool)), this,
1063 SLOT(updateAllAree(bool)));
1064
1065 TSceneHandle *sceneHandle = app->getCurrentScene();
1066 disconnect(sceneHandle, SIGNAL(sceneSwitched()), this,
1067 SLOT(onSceneSwitched()));
1068 disconnect(sceneHandle, SIGNAL(nameSceneChanged()), this,
1069 SLOT(changeWindowTitle()));
1070
1071 TXsheetHandle *xsheetHandle = app->getCurrentXsheet();
1072 disconnect(xsheetHandle, SIGNAL(xsheetSwitched()), this,
1073 SLOT(updateAllAree()));
1074 disconnect(xsheetHandle, SIGNAL(xsheetChanged()), this,
1075 SLOT(onXsheetChanged()));
1076 disconnect(xsheetHandle, SIGNAL(xsheetChanged()), this,
1077 SLOT(changeWindowTitle()));
1078
1079 disconnect(app->getCurrentSelection(),
1080 SIGNAL(selectionSwitched(TSelection *, TSelection *)), this,
1081 SLOT(onSelectionSwitched(TSelection *, TSelection *)));
1082
1083 disconnect(app->getCurrentSelection(), SIGNAL(selectionChanged(TSelection *)),
1084 this, SLOT(onSelectionChanged(TSelection *)));
1085
1086 disconnect(app->getCurrentLevel(), SIGNAL(xshLevelSwitched(TXshLevel *)),
1087 this, SLOT(changeWindowTitle()));
1088
1089 disconnect(IconGenerator::instance(), SIGNAL(iconGenerated()), this,
1090 SLOT(updateColumnArea()));
1091 }
1092
1093 //-----------------------------------------------------------------------------
1094
resizeEvent(QResizeEvent * event)1095 void XsheetViewer::resizeEvent(QResizeEvent *event) {
1096 positionSections();
1097
1098 //(New Layout Manager) introduced automatic refresh
1099 refreshContentSize(
1100 0,
1101 0); // Don't updateAreeSize because you have to account scrollbars
1102 updateAllAree();
1103 }
1104
1105 //-----------------------------------------------------------------------------
1106
wheelEvent(QWheelEvent * event)1107 void XsheetViewer::wheelEvent(QWheelEvent *event) {
1108 switch (event->source()) {
1109 case Qt::MouseEventNotSynthesized: {
1110 if (0 != (event->modifiers() & Qt::ControlModifier) &&
1111 event->angleDelta().y() != 0) {
1112 QPoint pos(event->pos().x() - m_columnArea->geometry().width() +
1113 m_cellArea->visibleRegion().boundingRect().left(),
1114 event->pos().y());
1115 int targetFrame = xyToPosition(pos).frame();
1116
1117 int newFactor =
1118 getFrameZoomFactor() + ((event->angleDelta().y() > 0 ? 1 : -1) * 10);
1119 if (newFactor > XsheetGUI::ZOOM_FACTOR_MAX)
1120 newFactor = XsheetGUI::ZOOM_FACTOR_MAX;
1121 else if (newFactor < XsheetGUI::ZOOM_FACTOR_MIN)
1122 newFactor = XsheetGUI::ZOOM_FACTOR_MIN;
1123 zoomOnFrame(targetFrame, newFactor);
1124
1125 event->accept();
1126 return;
1127 }
1128
1129 int markerDistance = 0, markerOffset = 0;
1130 TApp::instance()
1131 ->getCurrentScene()
1132 ->getScene()
1133 ->getProperties()
1134 ->getMarkers(markerDistance, markerOffset);
1135
1136 if (event->angleDelta().x() == 0) { // vertical scroll
1137 if (!orientation()->isVerticalTimeline()) markerDistance = 1;
1138 int scrollPixels = (event->angleDelta().y() > 0 ? 1 : -1) *
1139 markerDistance * orientation()->cellHeight();
1140 scroll(QPoint(0, -scrollPixels));
1141 } else { // horizontal scroll
1142 if (orientation()->isVerticalTimeline()) markerDistance = 1;
1143 int scrollPixels = (event->angleDelta().x() > 0 ? 1 : -1) *
1144 markerDistance * orientation()->cellWidth();
1145 scroll(QPoint(-scrollPixels, 0));
1146 }
1147 break;
1148 }
1149
1150 case Qt::MouseEventSynthesizedBySystem: // macbook touch-pad
1151 {
1152 QPoint numPixels = event->pixelDelta();
1153 QPoint numDegrees = event->angleDelta() / 8;
1154 if (!numPixels.isNull()) {
1155 scroll(-numPixels);
1156 } else if (!numDegrees.isNull()) {
1157 QPoint numSteps = numDegrees / 15;
1158 scroll(-numSteps);
1159 }
1160 break;
1161 }
1162
1163 default: // Qt::MouseEventSynthesizedByQt,
1164 // Qt::MouseEventSynthesizedByApplication
1165 {
1166 std::cout << "not supported event: Qt::MouseEventSynthesizedByQt, "
1167 "Qt::MouseEventSynthesizedByApplication"
1168 << std::endl;
1169 break;
1170 }
1171
1172 } // end switch
1173 }
1174
1175 //-----------------------------------------------------------------------------
1176
keyPressEvent(QKeyEvent * event)1177 void XsheetViewer::keyPressEvent(QKeyEvent *event) {
1178 struct Locals {
1179 XsheetViewer *m_this;
1180
1181 void scrollVertTo(double y, const QRect &visibleRect) {
1182 int deltaY = (y < visibleRect.top()) ? y - visibleRect.top()
1183 : y - visibleRect.bottom();
1184
1185 m_this->scroll(QPoint(0, deltaY));
1186 }
1187
1188 void scrollHorizTo(double x, const QRect &visibleRect) {
1189 int deltaX = (x < visibleRect.left()) ? x - visibleRect.left()
1190 : x - visibleRect.right();
1191
1192 m_this->scroll(QPoint(deltaX, 0));
1193 }
1194 } locals = {this};
1195
1196 if (changeFrameSkippingHolds(event)) return;
1197
1198 int frameCount = getXsheet()->getFrameCount();
1199 CellPosition now(getCurrentRow(), getCurrentColumn());
1200 CellPosition shift = orientation()->arrowShift(event->key());
1201 CellPosition stride(1, 1); // stride in row and column axes
1202
1203 TCellSelection *cellSel =
1204 dynamic_cast<TCellSelection *>(TSelection::getCurrent());
1205 int firstCol =
1206 Preferences::instance()->isXsheetCameraColumnVisible() ? -1 : 0;
1207 // Use arrow keys to shift the cell selection. Ctrl + arrow keys to resize the
1208 // selection range.
1209 if (Preferences::instance()->isUseArrowKeyToShiftCellSelectionEnabled() &&
1210 cellSel && !cellSel->isEmpty()) {
1211 int r0, c0, r1, c1;
1212 cellSel->getSelectedCells(r0, c0, r1, c1);
1213 stride.setFrame(cellSel->getSelectedCells().getRowCount());
1214
1215 if (m_cellArea->isControlPressed()) { // resize
1216 if (r0 == r1 && shift.frame() < 0) return;
1217 if (c0 == c1 && shift.layer() < firstCol) return;
1218 cellSel->selectCells(r0, c0, r1 + shift.frame(), c1 + shift.layer());
1219 updateCells();
1220 TApp::instance()->getCurrentSelection()->notifySelectionChanged();
1221 return;
1222 } else { // shift
1223 CellPosition offset(shift * stride);
1224 int movedR0 = std::max(0, r0 + offset.frame());
1225 int movedC0 = std::max(firstCol, c0 + offset.layer());
1226 int diffFrame = movedR0 - r0;
1227 int diffLayer = movedC0 - c0;
1228 cellSel->selectCells(r0 + diffFrame, c0 + diffLayer, r1 + diffFrame,
1229 c1 + diffLayer);
1230 TApp::instance()->getCurrentSelection()->notifySelectionChanged();
1231 }
1232 }
1233
1234 if (shift) {
1235 now = now + shift * stride;
1236 now.ensureValid();
1237 if (now.layer() < firstCol) now.setLayer(firstCol);
1238 setCurrentRow(now.frame());
1239 setCurrentColumn(now.layer());
1240 return;
1241 }
1242
1243 switch (int key = event->key()) {
1244 case Qt::Key_Control:
1245 // display the upper-directional smart tab only when the ctrl key is pressed
1246 m_cellArea->onControlPressed(true);
1247 m_columnArea->onControlPressed(true);
1248 m_layerFooterPanel->onControlPressed(true);
1249 break;
1250
1251 default: {
1252 QRect visibleRect = m_cellArea->visibleRegion().boundingRect();
1253 int visibleRowCount = visibleRect.height() / orientation()->cellHeight();
1254
1255 switch (key) {
1256 case Qt::Key_PageUp:
1257 locals.scrollVertTo(
1258 visibleRect.top() - visibleRowCount * orientation()->cellHeight(),
1259 visibleRect);
1260 break;
1261 case Qt::Key_PageDown:
1262 locals.scrollVertTo(
1263 visibleRect.bottom() + visibleRowCount * orientation()->cellHeight(),
1264 visibleRect);
1265 break;
1266 case Qt::Key_Home:
1267 if (orientation()->isVerticalTimeline())
1268 locals.scrollVertTo(0, visibleRect);
1269 else
1270 locals.scrollHorizTo(0, visibleRect);
1271
1272 break;
1273 case Qt::Key_End:
1274 if (orientation()->isVerticalTimeline())
1275 locals.scrollVertTo((frameCount + 1) * orientation()->cellHeight(),
1276 visibleRect);
1277 else {
1278 int x = (((frameCount + 1) * orientation()->cellWidth()) *
1279 getFrameZoomFactor()) /
1280 100;
1281 locals.scrollHorizTo(x, visibleRect);
1282 }
1283 break;
1284 }
1285 break;
1286 }
1287 }
1288 }
1289
1290 //-----------------------------------------------------------------------------
1291 // display the upper-directional smart tab only when the ctrl key is pressed
keyReleaseEvent(QKeyEvent * event)1292 void XsheetViewer::keyReleaseEvent(QKeyEvent *event) {
1293 if (event->key() == Qt::Key_Control) {
1294 m_cellArea->onControlPressed(false);
1295 m_columnArea->onControlPressed(false);
1296 m_layerFooterPanel->onControlPressed(false);
1297 }
1298 }
1299
enterEvent(QEvent *)1300 void XsheetViewer::enterEvent(QEvent *) {
1301 m_cellArea->onControlPressed(false);
1302 m_columnArea->onControlPressed(false);
1303 TApp *app = TApp::instance();
1304 app->setCurrentXsheetViewer(this);
1305 }
1306
1307 //-----------------------------------------------------------------------------
1308 /*! scroll the cell area to make a cell at (row,col) visible
1309 */
scrollTo(int row,int col)1310 void XsheetViewer::scrollTo(int row, int col) {
1311 QRect visibleRect = m_cellArea->visibleRegion().boundingRect();
1312 QPoint topLeft = positionToXY(CellPosition(row, col));
1313 QRect cellRect(
1314 topLeft, QSize(orientation()->cellWidth(), orientation()->cellHeight()));
1315
1316 int deltaX = 0;
1317 int deltaY = 0;
1318
1319 if (cellRect.left() < visibleRect.left())
1320 deltaX = cellRect.left() - visibleRect.left();
1321 else if (cellRect.right() > visibleRect.right())
1322 deltaX = cellRect.left() - visibleRect.left();
1323
1324 if (cellRect.top() < visibleRect.top())
1325 deltaY = cellRect.top() - visibleRect.top();
1326 else if (cellRect.bottom() > visibleRect.bottom())
1327 deltaY = cellRect.bottom() - visibleRect.bottom();
1328
1329 if (deltaX != 0 || deltaY != 0) {
1330 scroll(QPoint(deltaX, deltaY));
1331 }
1332 }
1333
1334 //-----------------------------------------------------------------------------
1335
onSceneSwitched()1336 void XsheetViewer::onSceneSwitched() {
1337 refreshContentSize(0, 0);
1338 updateAreeSize();
1339 updateAllAree();
1340 clearNoteWidgets();
1341 m_noteArea->updateButtons();
1342 }
1343
1344 //-----------------------------------------------------------------------------
1345
onXsheetChanged()1346 void XsheetViewer::onXsheetChanged() {
1347 refreshContentSize(0, 0);
1348 updateAllAree();
1349 }
1350
1351 //-----------------------------------------------------------------------------
1352
onPreferenceChanged(const QString & prefName)1353 void XsheetViewer::onPreferenceChanged(const QString &prefName) {
1354 if (prefName == "XSheetToolbar") {
1355 positionSections();
1356 refreshContentSize(0, 0);
1357 } else if (prefName == "XsheetCamera") {
1358 refreshContentSize(0, 0);
1359 }
1360 }
1361
1362 //-----------------------------------------------------------------------------
1363
onCurrentFrameSwitched()1364 void XsheetViewer::onCurrentFrameSwitched() {
1365 int row = TApp::instance()->getCurrentFrame()->getFrame();
1366 QRect visibleRect = m_cellArea->visibleRegion().boundingRect();
1367 if (visibleRect.isEmpty()) {
1368 m_isCurrentFrameSwitched = true;
1369 return;
1370 }
1371 m_isCurrentFrameSwitched = false;
1372 scrollToRow(row);
1373 }
1374
1375 //-----------------------------------------------------------------------------
1376
onPlayingStatusChanged()1377 void XsheetViewer::onPlayingStatusChanged() {
1378 if (!Preferences::instance()->isXsheetAutopanEnabled())
1379 onCurrentFrameSwitched();
1380 }
1381
1382 //-----------------------------------------------------------------------------
1383
onCurrentColumnSwitched()1384 void XsheetViewer::onCurrentColumnSwitched() {
1385 int col = TApp::instance()->getCurrentColumn()->getColumnIndex();
1386 QRect visibleRect = m_columnArea->visibleRegion().boundingRect();
1387 if (visibleRect.isEmpty()) {
1388 m_isCurrentColumnSwitched = true;
1389 return;
1390 }
1391 m_isCurrentColumnSwitched = false;
1392 scrollToColumn(col);
1393 }
1394
1395 //-----------------------------------------------------------------------------
1396
scrollToColumn(int col)1397 void XsheetViewer::scrollToColumn(int col) {
1398 int colNext = col + (m_orientation->isVerticalTimeline() ? 1 : -1);
1399 if (colNext < 0) colNext = -1;
1400 int x0 = columnToLayerAxis(col);
1401 int x1 = columnToLayerAxis(colNext);
1402
1403 if (orientation()->isVerticalTimeline())
1404 scrollToHorizontalRange(x0, x1);
1405 else {
1406 if (colNext == col) x1 += m_orientation->cellHeight();
1407
1408 scrollToVerticalRange(x0, x1);
1409 }
1410 }
1411
1412 //-----------------------------------------------------------------------------
1413
scrollToHorizontalRange(int x0,int x1)1414 void XsheetViewer::scrollToHorizontalRange(int x0, int x1) {
1415 QRect visibleRect = m_cellArea->visibleRegion().boundingRect();
1416 if (visibleRect.isEmpty()) return;
1417 int visibleLeft = visibleRect.left();
1418 int visibleRight = visibleRect.right();
1419
1420 if (visibleLeft > x0) { // If they are out of left visible region
1421 int deltaX = x0 - visibleLeft;
1422 if (!TApp::instance()->getCurrentFrame()->isPlaying() ||
1423 Preferences::instance()->isXsheetAutopanEnabled()) {
1424 scroll(QPoint(deltaX, 0));
1425 return;
1426 }
1427 }
1428 if (visibleRight < x1) { // If they are out of right visible region
1429 int deltaX = x1 + 2 - visibleRight;
1430 if (!TApp::instance()->getCurrentFrame()->isPlaying() ||
1431 Preferences::instance()->isXsheetAutopanEnabled()) {
1432 scroll(QPoint(deltaX, 0));
1433 return;
1434 }
1435 }
1436 if (orientation()->isVerticalTimeline())
1437 updateCellColumnAree();
1438 else
1439 updateCellRowAree();
1440 }
1441
1442 //-----------------------------------------------------------------------------
1443
scrollToRow(int row)1444 void XsheetViewer::scrollToRow(int row) {
1445 int y0 = rowToFrameAxis(row);
1446 int y1 = rowToFrameAxis(row + 1);
1447
1448 if (orientation()->isVerticalTimeline())
1449 scrollToVerticalRange(y0, y1);
1450 else
1451 scrollToHorizontalRange(y0, y1);
1452 }
1453
1454 //-----------------------------------------------------------------------------
1455
scrollToVerticalRange(int y0,int y1)1456 void XsheetViewer::scrollToVerticalRange(int y0, int y1) {
1457 int yMin = std::min(y0, y1);
1458 int yMax = std::max(y0, y1);
1459 QRect visibleRect = m_cellArea->visibleRegion().boundingRect();
1460 if (visibleRect.isEmpty()) return;
1461 int visibleTop = visibleRect.top();
1462 int visibleBottom = visibleRect.bottom();
1463
1464 if (visibleTop > yMin) { // If they are out of top visible region
1465 int deltaY = yMin - visibleTop;
1466 if (!TApp::instance()->getCurrentFrame()->isPlaying() ||
1467 Preferences::instance()->isXsheetAutopanEnabled()) {
1468 scroll(QPoint(0, deltaY));
1469 return;
1470 }
1471 }
1472
1473 if (visibleBottom < yMax) { // If they are out of bottom visible region
1474 int deltaY = yMax + 2 - visibleBottom;
1475 if (!TApp::instance()->getCurrentFrame()->isPlaying() ||
1476 Preferences::instance()->isXsheetAutopanEnabled()) {
1477 scroll(QPoint(0, deltaY));
1478 return;
1479 }
1480 }
1481 if (orientation()->isVerticalTimeline())
1482 updateCellRowAree();
1483 else
1484 updateCellColumnAree();
1485 }
1486
1487 //-----------------------------------------------------------------------------
1488
onSelectionSwitched(TSelection * oldSelection,TSelection * newSelection)1489 void XsheetViewer::onSelectionSwitched(TSelection *oldSelection,
1490 TSelection *newSelection) {
1491 if ((TSelection *)getCellSelection() == oldSelection) {
1492 m_cellArea->update(m_cellArea->visibleRegion());
1493 m_rowArea->update(m_rowArea->visibleRegion());
1494 changeWindowTitle();
1495 } else if ((TSelection *)m_columnSelection == oldSelection)
1496 m_columnArea->update(m_columnArea->visibleRegion());
1497 }
1498
1499 //-----------------------------------------------------------------------------
1500 /*! update display of the cell selection range in title bar
1501 */
onSelectionChanged(TSelection * selection)1502 void XsheetViewer::onSelectionChanged(TSelection *selection) {
1503 if ((TSelection *)getCellSelection() == selection) {
1504 changeWindowTitle();
1505 if (Preferences::instance()->isInputCellsWithoutDoubleClickingEnabled()) {
1506 TCellSelection *cellSel = getCellSelection();
1507 if (cellSel->isEmpty())
1508 m_cellArea->hideRenameField();
1509 else
1510 m_cellArea->showRenameField(
1511 cellSel->getSelectedCells().m_r0, cellSel->getSelectedCells().m_c0,
1512 cellSel->getSelectedCells().getColCount() > 1);
1513 }
1514 }
1515 }
1516
1517 //-----------------------------------------------------------------------------
1518
updateAllAree(bool isDragging)1519 void XsheetViewer::updateAllAree(bool isDragging) {
1520 m_cellArea->update(m_cellArea->visibleRegion());
1521 if (!isDragging) {
1522 m_rowArea->update(m_rowArea->visibleRegion());
1523 m_columnArea->update(m_columnArea->visibleRegion());
1524 }
1525 m_toolbar->update(m_toolbar->visibleRegion());
1526 }
1527
1528 //-----------------------------------------------------------------------------
1529
updateColumnArea()1530 void XsheetViewer::updateColumnArea() {
1531 m_columnArea->update(m_columnArea->visibleRegion());
1532 }
1533
1534 //-----------------------------------------------------------------------------
1535
updateCellColumnAree()1536 void XsheetViewer::updateCellColumnAree() {
1537 m_columnArea->update(m_columnArea->visibleRegion());
1538 m_cellArea->update(m_cellArea->visibleRegion());
1539 }
1540
1541 //-----------------------------------------------------------------------------
1542
updateCellRowAree()1543 void XsheetViewer::updateCellRowAree() {
1544 m_rowArea->update(m_rowArea->visibleRegion());
1545 m_cellArea->update(m_cellArea->visibleRegion());
1546 }
1547
1548 //-----------------------------------------------------------------------------
1549
onScrubStopped()1550 void XsheetViewer::onScrubStopped() {
1551 resetScrubHighlight();
1552 updateCells();
1553 }
1554
1555 //-----------------------------------------------------------------------------
1556
discardNoteWidget()1557 void XsheetViewer::discardNoteWidget() {
1558 if (m_currentNoteIndex == -1) return;
1559 TXshNoteSet *notes = getXsheet()->getNotes();
1560 int i;
1561 for (i = m_currentNoteIndex + 1; i < m_noteWidgets.size(); i++) {
1562 XsheetGUI::NoteWidget *w = m_noteWidgets.at(i);
1563 int index = w->getNoteIndex();
1564 w->setNoteIndex(index - 1);
1565 w->update();
1566 }
1567 delete m_noteWidgets.at(m_currentNoteIndex);
1568 m_noteWidgets.removeAt(m_currentNoteIndex);
1569 m_noteArea->updateButtons();
1570 updateCells();
1571 }
1572
1573 //-----------------------------------------------------------------------------
1574
getNotesWidget() const1575 QList<XsheetGUI::NoteWidget *> XsheetViewer::getNotesWidget() const {
1576 return m_noteWidgets;
1577 }
1578
1579 //-----------------------------------------------------------------------------
1580
addNoteWidget(XsheetGUI::NoteWidget * w)1581 void XsheetViewer::addNoteWidget(XsheetGUI::NoteWidget *w) {
1582 m_noteWidgets.push_back(w);
1583 m_noteArea->updateButtons();
1584 }
1585
1586 //-----------------------------------------------------------------------------
1587
getCurrentNoteIndex() const1588 int XsheetViewer::getCurrentNoteIndex() const { return m_currentNoteIndex; }
1589
1590 //-----------------------------------------------------------------------------
1591
setCurrentNoteIndex(int currentNoteIndex)1592 void XsheetViewer::setCurrentNoteIndex(int currentNoteIndex) {
1593 m_currentNoteIndex = currentNoteIndex;
1594 m_noteArea->updateButtons();
1595
1596 if (currentNoteIndex < 0) return;
1597
1598 TXshNoteSet *notes = getXsheet()->getNotes();
1599 int row = notes->getNoteRow(currentNoteIndex);
1600 int col = notes->getNoteCol(currentNoteIndex);
1601 TPointD pos = notes->getNotePos(currentNoteIndex);
1602
1603 QPoint topLeft = positionToXY(CellPosition(row, col)) +
1604 QPoint(pos.x, pos.y); // actually xy
1605 QSize size(XsheetGUI::NoteWidth, XsheetGUI::NoteHeight);
1606 QRect noteRect(topLeft, size);
1607 scrollToHorizontalRange(noteRect.left(), noteRect.right());
1608 scrollToVerticalRange(noteRect.top(), noteRect.bottom());
1609 }
1610
1611 //-----------------------------------------------------------------------------
1612
resetXsheetNotes()1613 void XsheetViewer::resetXsheetNotes() { m_noteArea->updateButtons(); }
1614
1615 //-----------------------------------------------------------------------------
1616
updateNoteWidgets()1617 void XsheetViewer::updateNoteWidgets() {
1618 int i;
1619 for (i = 0; i < m_noteWidgets.size(); i++) m_noteWidgets.at(i)->update();
1620 m_noteArea->updatePopup();
1621 updateCells();
1622 }
1623
1624 //-----------------------------------------------------------------------------
1625
clearNoteWidgets()1626 void XsheetViewer::clearNoteWidgets() {
1627 int i;
1628 for (i = 0; i < m_noteWidgets.size(); i++) delete m_noteWidgets.at(i);
1629 m_noteWidgets.clear();
1630 }
1631
1632 //-----------------------------------------------------------------------------
1633
changeWindowTitle()1634 void XsheetViewer::changeWindowTitle() {
1635 TApp *app = TApp::instance();
1636 ToonzScene *scene = app->getCurrentScene()->getScene();
1637 if (!scene || !app->getCurrentFrame()->isEditingScene()) return;
1638 TProject *project = scene->getProject();
1639 QString sceneName = QString::fromStdWString(scene->getSceneName());
1640 if (sceneName.isEmpty()) sceneName = tr("Untitled");
1641 if (app->getCurrentScene()->getDirtyFlag()) sceneName += QString("*");
1642 QString name = tr("Scene: ") + sceneName;
1643 int frameCount = scene->getFrameCount();
1644 name = name + " :: " + tr(std::to_string(frameCount).c_str()) +
1645 (frameCount == 1 ? tr(" Frame") : tr(" Frames"));
1646
1647 // subXsheet or not
1648 ChildStack *childStack = scene->getChildStack();
1649 if (childStack && childStack->getAncestorCount() > 0) {
1650 name += tr(" (Sub)");
1651 }
1652 // current level name
1653 TXshLevel *level = app->getCurrentLevel()->getLevel();
1654 if (level) {
1655 QString levelName = QString::fromStdWString(level->getName());
1656 name += tr(" Level: ") + levelName;
1657 }
1658 // cell selection range
1659 if ((TSelection *)getCellSelection() ==
1660 app->getCurrentSelection()->getSelection() &&
1661 !getCellSelection()->isEmpty()) {
1662 int r0, r1, c0, c1;
1663 getCellSelection()->getSelectedCells(r0, c0, r1, c1);
1664 name += tr(" Selected: ") + QString::number(r1 - r0 + 1) +
1665 ((r1 - r0 + 1 == 1) ? tr(" frame : ") : tr(" frames * ")) +
1666 QString::number(c1 - c0 + 1) +
1667 ((c1 - c0 + 1 == 1) ? tr(" column") : tr(" columns"));
1668 }
1669
1670 parentWidget()->setWindowTitle(name);
1671 }
1672
1673 //-----------------------------------------------------------------------------
1674 /*! convert the last one digit of the frame number to alphabet
1675 Ex. 12 -> 1B 21 -> 2A 30 -> 3
1676 */
getFrameNumberWithLetters(int frame)1677 QString XsheetViewer::getFrameNumberWithLetters(int frame) {
1678 int letterNum = frame % 10;
1679 QChar letter;
1680
1681 switch (letterNum) {
1682 case 0:
1683 letter = QChar();
1684 break;
1685 case 1:
1686 letter = 'A';
1687 break;
1688 case 2:
1689 letter = 'B';
1690 break;
1691 case 3:
1692 letter = 'C';
1693 break;
1694 case 4:
1695 letter = 'D';
1696 break;
1697 case 5:
1698 letter = 'E';
1699 break;
1700 case 6:
1701 letter = 'F';
1702 break;
1703 case 7:
1704 letter = 'G';
1705 break;
1706 case 8:
1707 letter = 'H';
1708 break;
1709 case 9:
1710 letter = 'I';
1711 break;
1712 default:
1713 letter = QChar();
1714 break;
1715 }
1716
1717 QString number;
1718 if (frame >= 10) {
1719 number = QString::number(frame);
1720 number.chop(1);
1721 } else
1722 number = "0";
1723
1724 return (QChar(letter).isNull()) ? number : number.append(letter);
1725 }
1726 //-----------------------------------------------------------------------------
1727
setFrameDisplayStyle(FrameDisplayStyle style)1728 void XsheetViewer::setFrameDisplayStyle(FrameDisplayStyle style) {
1729 m_frameDisplayStyle = style;
1730 FrameDisplayStyleInXsheetRowArea = (int)style;
1731 }
1732
1733 //-----------------------------------------------------------------------------
1734
save(QSettings & settings) const1735 void XsheetViewer::save(QSettings &settings) const {
1736 settings.setValue("orientation", orientation()->name());
1737 settings.setValue("frameZoomFactor", m_frameZoomFactor);
1738 }
load(QSettings & settings)1739 void XsheetViewer::load(QSettings &settings) {
1740 QVariant zoomFactor = settings.value("frameZoomFactor");
1741 QVariant name = settings.value("orientation");
1742
1743 if (zoomFactor.canConvert(QVariant::Int)) {
1744 m_frameZoomFactor = zoomFactor.toInt();
1745 m_layerFooterPanel->setZoomSliderValue(m_frameZoomFactor);
1746 }
1747
1748 if (name.canConvert(QVariant::String)) {
1749 m_orientation = Orientations::byName(name.toString());
1750 emit orientationChanged(orientation());
1751 }
1752 }
1753
1754 //-----------------------------------------------------------------------------
1755 /*
1756 TPanel *createXsheetViewer(QWidget *parent)
1757 {
1758 TPanel *panel = new TPanel(parent);
1759 panel->setPanelType("Xsheet");
1760 panel->setWidget(new XsheetViewer(panel));
1761 return panel;
1762 }
1763 */
1764
1765 //----------------------------------------------------------------
getFrameZoomFactor() const1766 int XsheetViewer::getFrameZoomFactor() const {
1767 if (orientation()->isVerticalTimeline()) return 100;
1768
1769 return m_frameZoomFactor;
1770 }
1771
getFrameZoomAdjustment()1772 int XsheetViewer::getFrameZoomAdjustment() {
1773 if (orientation()->isVerticalTimeline()) return 0;
1774
1775 QRect frameRect = orientation()->rect(PredefinedRect::FRAME_HEADER);
1776 int adj = frameRect.width() -
1777 ((frameRect.width() * getFrameZoomFactor()) / 100) - 1;
1778
1779 return std::max(0, adj);
1780 }
1781
zoomOnFrame(int frame,int factor)1782 void XsheetViewer::zoomOnFrame(int frame, int factor) {
1783 QPoint xyOrig = positionToXY(CellPosition(frame, -1));
1784
1785 m_frameZoomFactor = factor;
1786 m_layerFooterPanel->setZoomSliderValue(m_frameZoomFactor);
1787
1788 QPoint xyNew = positionToXY(CellPosition(frame, -1));
1789
1790 int viewShift = xyNew.x() - xyOrig.x();
1791
1792 scroll(QPoint(viewShift, 0));
1793
1794 TApp::instance()->getCurrentXsheet()->notifyXsheetChanged();
1795 m_rowArea->update();
1796 }
1797
getSelectedColumnTextColor() const1798 QColor XsheetViewer::getSelectedColumnTextColor() const {
1799 // get colors
1800 TPixel currentColumnPixel;
1801 Preferences::instance()->getCurrentColumnData(currentColumnPixel);
1802 QColor currentColumnColor((int)currentColumnPixel.r,
1803 (int)currentColumnPixel.g,
1804 (int)currentColumnPixel.b, 255);
1805 return currentColumnColor;
1806 }
1807
1808 //=============================================================================
1809 // XSheetViewerCommand
1810 //-----------------------------------------------------------------------------
1811
1812 OpenFloatingPanel openXsheetViewerCommand(MI_OpenXshView, "Xsheet",
1813 QObject::tr("Xsheet"));
1814
1815 OpenFloatingPanel openTimelineViewerCommand(MI_OpenTimelineView, "Timeline",
1816 QObject::tr("Timeline"));
1817