1
2 #include "xshcolumnviewer.h"
3
4 // Tnz6 includes
5 #include "xsheetviewer.h"
6 #include "tapp.h"
7 #include "menubarcommandids.h"
8 #include "columnselection.h"
9 #include "xsheetdragtool.h"
10
11 // TnzTools includes
12 #include "tools/toolhandle.h"
13 #include "tools/toolcommandids.h"
14
15 // TnzQt includes
16 #include "toonzqt/tselectionhandle.h"
17 #include "toonzqt/gutil.h"
18 #include "toonzqt/icongenerator.h"
19 #include "toonzqt/intfield.h"
20
21 // TnzLib includes
22 #include "toonz/txshcolumn.h"
23 #include "toonz/tscenehandle.h"
24 #include "toonz/txsheethandle.h"
25 #include "toonz/txshlevelhandle.h"
26 #include "toonz/tobjecthandle.h"
27 #include "toonz/stage2.h"
28 #include "toonz/txshpalettecolumn.h"
29 #include "toonz/txsheet.h"
30 #include "toonz/toonzscene.h"
31 #include "toonz/txshcell.h"
32 #include "toonz/tstageobject.h"
33 #include "toonz/tstageobjecttree.h"
34 #include "toonz/sceneproperties.h"
35 #include "toonz/txshzeraryfxcolumn.h"
36 #include "toonz/tcolumnfx.h"
37 #include "toonz/txshsoundcolumn.h"
38 #include "toonz/txshsimplelevel.h"
39 #include "toonz/columnfan.h"
40 #include "toonz/tstageobjectcmd.h"
41 #include "toonz/fxcommand.h"
42 #include "toonz/txshleveltypes.h"
43 #include "toonz/levelproperties.h"
44 #include "toonz/preferences.h"
45 #include "toonz/childstack.h"
46 #include "toonz/txshlevelcolumn.h"
47 #include "toonz/txshmeshcolumn.h"
48 #include "toonz/tfxhandle.h"
49 #include "toonz/tcamera.h"
50 #include "toonz/tcolumnhandle.h"
51
52 // TnzCore includes
53 #include "tconvert.h"
54
55 #include <QApplication>
56 #include <QMainWindow>
57 #include <QPainter>
58 #include <QMouseEvent>
59 #include <QMenu>
60 #include <QToolTip>
61 #include <QTimer>
62 #include <QLabel>
63 #include <QComboBox>
64 #include <QPushButton>
65 #include <QDesktopWidget>
66
67 #include <QBitmap>
68 //=============================================================================
69
70 namespace {
getLevels(TXshColumn * column)71 const QSet<TXshSimpleLevel *> getLevels(TXshColumn *column) {
72 QSet<TXshSimpleLevel *> levels;
73 TXshCellColumn *cellColumn = column->getCellColumn();
74 if (cellColumn) {
75 int i, r0, r1;
76 cellColumn->getRange(r0, r1);
77 for (i = r0; i <= r1; i++) {
78 TXshCell cell = cellColumn->getCell(i);
79 TXshSimpleLevel *sl = cell.getSimpleLevel();
80 if (sl) levels.insert(sl);
81 }
82 }
83 return levels;
84 }
85
containsRasterLevel(TColumnSelection * selection)86 bool containsRasterLevel(TColumnSelection *selection) {
87 if (!selection || selection->isEmpty()) return false;
88 std::set<int> indexes = selection->getIndices();
89 TXsheet *xsh = TApp::instance()->getCurrentXsheet()->getXsheet();
90 for (auto const &e : indexes) {
91 TXshColumn *col = xsh->getColumn(e);
92 if (!col || col->getColumnType() != TXshColumn::eLevelType) continue;
93
94 TXshCellColumn *cellCol = col->getCellColumn();
95 if (!cellCol) continue;
96
97 int i;
98 for (i = 0; i < cellCol->getMaxFrame() + 1; i++) {
99 TXshCell cell = cellCol->getCell(i);
100 if (cell.isEmpty()) continue;
101 TXshSimpleLevel *level = cell.getSimpleLevel();
102 if (!level || level->getChildLevel() ||
103 level->getProperties()->getDirtyFlag())
104 continue;
105 int type = level->getType();
106 if (type == OVL_XSHLEVEL || type == TZP_XSHLEVEL) return true;
107 }
108 }
109 return false;
110 }
111
getColorChipIcon(TPixel32 color)112 const QIcon getColorChipIcon(TPixel32 color) {
113 QColor qCol((int)color.r, (int)color.g, (int)color.b, (int)color.m);
114 QPixmap pixmap(12, 12);
115 pixmap.fill(qCol);
116 return QIcon(pixmap);
117 }
118
containsVectorLevel(int col)119 bool containsVectorLevel(int col) {
120 TXshColumn *column =
121 TApp::instance()->getCurrentXsheet()->getXsheet()->getColumn(col);
122 TXshColumn::ColumnType type = column->getColumnType();
123 if (type != TXshColumn::eLevelType) return false;
124
125 const QSet<TXshSimpleLevel *> levels = getLevels(column);
126 QSet<TXshSimpleLevel *>::const_iterator it2;
127 bool isVector = false;
128 for (it2 = levels.begin(); it2 != levels.end(); it2++) {
129 TXshSimpleLevel *sl = *it2;
130 int type = sl->getType();
131 if (type == PLI_XSHLEVEL) {
132 isVector = true;
133 return true;
134 }
135 }
136 return false;
137 }
138
139 bool isCtrlPressed = false;
140 } // namespace
141
142 //=============================================================================
143 // ColumnMaskUndo
144 //-----------------------------------------------------------------------------
145 class ColumnMaskUndo final : public TUndo {
146 int m_col;
147 bool m_isMask;
148 std::string m_name;
149
150 public:
ColumnMaskUndo(int column,bool isMask,std::string name)151 ColumnMaskUndo(int column, bool isMask, std::string name)
152 : m_col(column), m_isMask(isMask), m_name(name) {}
~ColumnMaskUndo()153 ~ColumnMaskUndo() {}
154
undo() const155 void undo() const override {
156 TXshColumn *column =
157 TApp::instance()->getCurrentXsheet()->getXsheet()->getColumn(m_col);
158 TXshColumn::ColumnType type = column->getColumnType();
159 if (type != TXshColumn::eLevelType) return;
160
161 if (containsVectorLevel(m_col)) {
162 column->setIsMask(m_isMask);
163 TApp::instance()->getCurrentScene()->notifySceneChanged();
164 TApp::instance()->getCurrentXsheet()->notifyXsheetChanged();
165 TApp::instance()->getCurrentScene()->setDirtyFlag(true);
166 }
167 }
168
redo() const169 void redo() const override {
170 TXshColumn *column =
171 TApp::instance()->getCurrentXsheet()->getXsheet()->getColumn(m_col);
172 TXshColumn::ColumnType type = column->getColumnType();
173 if (type != TXshColumn::eLevelType) return;
174
175 if (containsVectorLevel(m_col)) {
176 column->setIsMask(!m_isMask);
177 TApp::instance()->getCurrentScene()->notifySceneChanged();
178 TApp::instance()->getCurrentXsheet()->notifyXsheetChanged();
179 TApp::instance()->getCurrentScene()->setDirtyFlag(true);
180 }
181 }
182
getSize() const183 int getSize() const override { return sizeof(*this); }
184
getHistoryString()185 QString getHistoryString() override {
186 QString str = QObject::tr("Toggle vector column as mask. ");
187 return str;
188 }
getHistoryType()189 int getHistoryType() override { return HistoryType::Xsheet; }
190 };
191
192 //-----------------------------------------------------------------------------
193
194 namespace XsheetGUI {
195
196 //-----------------------------------------------------------------------------
197
getVolumeCursorRect(QRect & out,double volume,const QPoint & origin)198 static void getVolumeCursorRect(QRect &out, double volume,
199 const QPoint &origin) {
200 int ly = 60;
201 int v = tcrop(0, ly, (int)(volume * ly));
202 out.setX(origin.x() + 11);
203 out.setY(origin.y() + 60 - v);
204 out.setWidth(8);
205 out.setHeight(8);
206 }
207
208 //=============================================================================
209 // MotionPathMenu
210 //-----------------------------------------------------------------------------
211
212 #if QT_VERSION >= 0x050500
MotionPathMenu(QWidget * parent,Qt::WindowFlags flags)213 MotionPathMenu::MotionPathMenu(QWidget *parent, Qt::WindowFlags flags)
214 #else
215 MotionPathMenu::MotionPathMenu(QWidget *parent, Qt::WFlags flags)
216 #endif
217 : QWidget(parent, flags)
218 , m_mDeleteRect(QRect(0, 0, ColumnWidth - 13, RowHeight))
219 , m_mNormalRect(QRect(0, RowHeight, ColumnWidth - 13, RowHeight))
220 , m_mRotateRect(QRect(0, RowHeight * 2, ColumnWidth - 13, RowHeight))
221 , m_pos(QPoint()) {
222 setMouseTracking(true);
223 setFixedSize(ColumnWidth - 12, 3 * RowHeight);
224 setWindowFlags(Qt::FramelessWindowHint);
225 }
226
227 //-----------------------------------------------------------------------------
228
~MotionPathMenu()229 MotionPathMenu::~MotionPathMenu() {}
230
231 //-----------------------------------------------------------------------------
232
paintEvent(QPaintEvent *)233 void MotionPathMenu::paintEvent(QPaintEvent *) {
234 QPainter p(this);
235
236 static QPixmap motionPixmap = QPixmap(":Resources/motionpath.svg");
237 static QPixmap motionDeletePixmap =
238 QPixmap(":Resources/motionpath_delete.svg");
239 static QPixmap motionRotatePixmap = QPixmap(":Resources/motionpath_rot.svg");
240
241 QColor overColor = QColor(49, 106, 197);
242
243 p.fillRect(m_mDeleteRect,
244 QBrush((m_mDeleteRect.contains(m_pos)) ? overColor : grey225));
245 p.drawPixmap(m_mDeleteRect, motionDeletePixmap);
246
247 p.fillRect(m_mNormalRect,
248 QBrush((m_mNormalRect.contains(m_pos)) ? overColor : grey225));
249 p.drawPixmap(m_mNormalRect, motionPixmap);
250
251 p.fillRect(m_mRotateRect,
252 QBrush((m_mRotateRect.contains(m_pos)) ? overColor : grey225));
253 p.drawPixmap(m_mRotateRect, motionRotatePixmap);
254 }
255
256 //-----------------------------------------------------------------------------
257
mousePressEvent(QMouseEvent * event)258 void MotionPathMenu::mousePressEvent(QMouseEvent *event) {
259 m_pos = event->pos();
260 TStageObjectId objectId = TApp::instance()->getCurrentObject()->getObjectId();
261 TStageObject *pegbar =
262 TApp::instance()->getCurrentXsheet()->getXsheet()->getStageObject(
263 objectId);
264
265 if (m_mDeleteRect.contains(m_pos))
266 pegbar->setStatus(TStageObject::XY);
267 else if (m_mNormalRect.contains(m_pos)) {
268 pegbar->setStatus(TStageObject::PATH);
269 TApp::instance()->getCurrentObject()->setIsSpline(true);
270 } else if (m_mRotateRect.contains(m_pos)) {
271 pegbar->setStatus(TStageObject::PATH_AIM);
272 TApp::instance()->getCurrentObject()->setIsSpline(true);
273 }
274 TApp::instance()->getCurrentXsheet()->notifyXsheetChanged();
275 hide();
276 }
277
278 //-----------------------------------------------------------------------------
279
mouseMoveEvent(QMouseEvent * event)280 void MotionPathMenu::mouseMoveEvent(QMouseEvent *event) {
281 m_pos = event->pos();
282 update();
283 }
284
285 //-----------------------------------------------------------------------------
286
mouseReleaseEvent(QMouseEvent * event)287 void MotionPathMenu::mouseReleaseEvent(QMouseEvent *event) {}
288
289 //-----------------------------------------------------------------------------
290
leaveEvent(QEvent * event)291 void MotionPathMenu::leaveEvent(QEvent *event) { hide(); }
292
293 //=============================================================================
294 // ChangeObjectWidget
295 //-----------------------------------------------------------------------------
296
ChangeObjectWidget(QWidget * parent)297 ChangeObjectWidget::ChangeObjectWidget(QWidget *parent)
298 : QListWidget(parent), m_width(40) {
299 setMouseTracking(true);
300 setObjectName("XshColumnChangeObjectWidget");
301 setAutoFillBackground(true);
302 }
303
304 //-----------------------------------------------------------------------------
305
~ChangeObjectWidget()306 ChangeObjectWidget::~ChangeObjectWidget() {}
307
308 //-----------------------------------------------------------------------------
309
show(const QPoint & pos)310 void ChangeObjectWidget::show(const QPoint &pos) {
311 refresh();
312 int itemNumber = count();
313 if (itemNumber > 10) {
314 itemNumber = 10;
315 m_width += 15;
316 }
317 setGeometry(pos.x(), pos.y(), m_width, itemNumber * 16 + 2);
318 QListWidget::show();
319 setFocus();
320 scrollToItem(currentItem());
321 }
322
323 //-----------------------------------------------------------------------------
324
setObjectHandle(TObjectHandle * objectHandle)325 void ChangeObjectWidget::setObjectHandle(TObjectHandle *objectHandle) {
326 m_objectHandle = objectHandle;
327 }
328
329 //-----------------------------------------------------------------------------
330
setXsheetHandle(TXsheetHandle * xsheetHandle)331 void ChangeObjectWidget::setXsheetHandle(TXsheetHandle *xsheetHandle) {
332 m_xsheetHandle = xsheetHandle;
333 }
334
335 //-----------------------------------------------------------------------------
336
mouseMoveEvent(QMouseEvent * event)337 void ChangeObjectWidget::mouseMoveEvent(QMouseEvent *event) {
338 QListWidgetItem *currentWidgetItem = itemAt(event->pos());
339 if (!currentWidgetItem) return;
340 clearSelection();
341 currentWidgetItem->setSelected(true);
342 }
343
344 //-----------------------------------------------------------------------------
345
focusOutEvent(QFocusEvent * e)346 void ChangeObjectWidget::focusOutEvent(QFocusEvent *e) {
347 if (!isVisible()) return;
348 hide();
349 parentWidget()->update();
350 }
351
352 //-----------------------------------------------------------------------------
353
selectCurrent(const QString & text)354 void ChangeObjectWidget::selectCurrent(const QString &text) {
355 QList<QListWidgetItem *> itemList = findItems(text, Qt::MatchExactly);
356 clearSelection();
357 if (itemList.size() < 1) return;
358 QListWidgetItem *currentWidgetItem = itemList.at(0);
359 setCurrentItem(currentWidgetItem);
360 }
361
362 //=============================================================================
363 // ChangeObjectParent
364 //-----------------------------------------------------------------------------
365
ChangeObjectParent(QWidget * parent)366 ChangeObjectParent::ChangeObjectParent(QWidget *parent)
367 : ChangeObjectWidget(parent) {
368 bool ret = connect(this, SIGNAL(currentTextChanged(const QString &)), this,
369 SLOT(onTextChanged(const QString &)));
370 assert(ret);
371 }
372
373 //-----------------------------------------------------------------------------
374
~ChangeObjectParent()375 ChangeObjectParent::~ChangeObjectParent() {}
376
377 //-----------------------------------------------------------------------------
378
refresh()379 void ChangeObjectParent::refresh() {
380 clear();
381 assert(m_xsheetHandle);
382 assert(m_objectHandle);
383 TXsheet *xsh = m_xsheetHandle->getXsheet();
384 TStageObjectId currentObjectId = m_objectHandle->getObjectId();
385 TStageObjectId parentId = xsh->getStageObject(currentObjectId)->getParent();
386 TStageObjectTree *tree = xsh->getStageObjectTree();
387 int objectCount = tree->getStageObjectCount();
388 QString text;
389 QList<QString> pegbarList;
390 QList<QString> columnList;
391 QString theLongestTxt;
392 int i;
393 for (i = 0; i < objectCount; i++) {
394 TStageObjectId id = tree->getStageObject(i)->getId();
395 int index = id.getIndex();
396 QString indexStr(std::to_string(id.getIndex() + 1).c_str());
397 QString newText;
398 if (id == parentId) {
399 if (parentId.isPegbar())
400 text = QString("Peg ") + indexStr;
401 else if (parentId.isColumn())
402 text = QString("Col ") + indexStr;
403 }
404 if (id == currentObjectId) continue;
405 if (id.isPegbar()) {
406 newText = QString("Peg ") + indexStr;
407 pegbarList.append(newText);
408 }
409 if (id.isColumn() && (!xsh->isColumnEmpty(index) || index < 2)) {
410 newText = QString("Col ") + indexStr;
411 columnList.append(newText);
412 }
413 if (newText.length() > theLongestTxt.length()) theLongestTxt = newText;
414 }
415 for (i = 0; i < columnList.size(); i++) addItem(columnList.at(i));
416 for (i = 0; i < pegbarList.size(); i++) addItem(pegbarList.at(i));
417
418 QString fontName = Preferences::instance()->getInterfaceFont();
419 if (fontName == "") {
420 #ifdef _WIN32
421 fontName = "Arial";
422 #else
423 fontName = "Helvetica";
424 #endif
425 }
426 static QFont font(fontName, -1, QFont::Normal);
427 // set font size in pixel
428 font.setPixelSize(XSHEET_FONT_PX_SIZE);
429
430 m_width = QFontMetrics(font).width(theLongestTxt) + 2;
431 selectCurrent(text);
432 }
433
434 //-----------------------------------------------------------------------------
435
onTextChanged(const QString & text)436 void ChangeObjectParent::onTextChanged(const QString &text) {
437 assert(m_xsheetHandle);
438 assert(m_objectHandle);
439 if (text.isEmpty()) {
440 hide();
441 return;
442 }
443 bool isPegbar = false;
444 if (text.startsWith("Peg")) isPegbar = true;
445 QString number = text;
446 number.remove(0, 4);
447 int index = number.toInt() - 1;
448 if (index < 0) {
449 hide();
450 return;
451 }
452 TStageObjectId currentObjectId = m_objectHandle->getObjectId();
453 TStageObjectId newStageObjectId;
454 if (isPegbar)
455 newStageObjectId = TStageObjectId::PegbarId(index);
456 else
457 newStageObjectId = TStageObjectId::ColumnId(index);
458
459 if (newStageObjectId == currentObjectId) return;
460
461 TStageObject *stageObject =
462 m_xsheetHandle->getXsheet()->getStageObject(currentObjectId);
463 TStageObjectCmd::setParent(currentObjectId, newStageObjectId, "B",
464 m_xsheetHandle);
465
466 hide();
467 m_objectHandle->notifyObjectIdChanged(false);
468 m_xsheetHandle->notifyXsheetChanged();
469 }
470
471 //=============================================================================
472 // ChangeObjectHandle
473 //-----------------------------------------------------------------------------
474
ChangeObjectHandle(QWidget * parent)475 ChangeObjectHandle::ChangeObjectHandle(QWidget *parent)
476 : ChangeObjectWidget(parent) {
477 bool ret = connect(this, SIGNAL(currentTextChanged(const QString &)), this,
478 SLOT(onTextChanged(const QString &)));
479 assert(ret);
480 }
481
482 //-----------------------------------------------------------------------------
483
~ChangeObjectHandle()484 ChangeObjectHandle::~ChangeObjectHandle() {}
485
486 //-----------------------------------------------------------------------------
487
refresh()488 void ChangeObjectHandle::refresh() {
489 clear();
490 assert(m_xsheetHandle);
491 assert(m_objectHandle);
492 TXsheet *xsh = m_xsheetHandle->getXsheet();
493 assert(xsh);
494 TStageObjectId currentObjectId = m_objectHandle->getObjectId();
495 TStageObject *stageObject = xsh->getStageObject(currentObjectId);
496 m_width = 28;
497
498 int i;
499 QString str;
500 if (stageObject->getParent().isColumn()) {
501 for (i = 0; i < 20; i++) addItem(str.number(20 - i));
502 }
503 for (i = 0; i < 26; i++) addItem(QString(char('A' + i)));
504
505 std::string handle = stageObject->getParentHandle();
506 if (handle[0] == 'H' && handle.length() > 1) handle = handle.substr(1);
507
508 selectCurrent(QString::fromStdString(handle));
509 }
510
511 //-----------------------------------------------------------------------------
512
onTextChanged(const QString & text)513 void ChangeObjectHandle::onTextChanged(const QString &text) {
514 assert(m_xsheetHandle);
515 assert(m_objectHandle);
516 TStageObjectId currentObjectId = m_objectHandle->getObjectId();
517 QString handle = text;
518 if (text.toInt() != 0) handle = QString("H") + handle;
519 if (handle.isEmpty()) return;
520 std::vector<TStageObjectId> ids;
521 ids.push_back(currentObjectId);
522 TStageObjectCmd::setParentHandle(ids, handle.toStdString(), m_xsheetHandle);
523 hide();
524 m_objectHandle->notifyObjectIdChanged(false);
525 m_xsheetHandle->notifyXsheetChanged();
526 }
527
528 //=============================================================================
529 // RenameColumnField
530 //-----------------------------------------------------------------------------
531
RenameColumnField(QWidget * parent,XsheetViewer * viewer)532 RenameColumnField::RenameColumnField(QWidget *parent, XsheetViewer *viewer)
533 : QLineEdit(parent), m_col(-1) {
534 setFixedSize(20, 20);
535 connect(this, SIGNAL(returnPressed()), SLOT(renameColumn()));
536 }
537
538 //-----------------------------------------------------------------------------
539
show(const QRect & rect,int col)540 void RenameColumnField::show(const QRect &rect, int col) {
541 move(rect.topLeft());
542 setFixedSize(rect.size());
543 QString fontName = Preferences::instance()->getInterfaceFont();
544 if (fontName == "") {
545 #ifdef _WIN32
546 fontName = "Arial";
547 #else
548 fontName = "Helvetica";
549 #endif
550 }
551 static QFont font(fontName, -1, QFont::Normal);
552 font.setPixelSize(XSHEET_FONT_PX_SIZE);
553 setFont(font);
554 m_col = col;
555
556 TXsheet *xsh = m_xsheetHandle->getXsheet();
557 int cameraIndex = xsh->getCameraColumnIndex();
558 std::string name =
559 col >= 0 ? xsh->getStageObject(TStageObjectId::ColumnId(col))->getName()
560 : xsh->getStageObject(TStageObjectId::CameraId(cameraIndex))
561 ->getName();
562 TXshColumn *column = xsh->getColumn(col);
563 TXshZeraryFxColumn *zColumn = dynamic_cast<TXshZeraryFxColumn *>(column);
564 if (zColumn)
565 name = ::to_string(zColumn->getZeraryColumnFx()->getZeraryFx()->getName());
566 setText(QString(name.c_str()));
567 selectAll();
568
569 QWidget::show();
570 raise();
571 setFocus();
572 }
573
574 //-----------------------------------------------------------------------------
575
renameColumn()576 void RenameColumnField::renameColumn() {
577 std::string newName = text().toStdString();
578 int cameraIndex = m_xsheetHandle->getXsheet()->getCameraColumnIndex();
579 TStageObjectId columnId = m_col >= 0 ? TStageObjectId::ColumnId(m_col)
580 : TStageObjectId::CameraId(cameraIndex);
581 TXshColumn *column =
582 m_xsheetHandle->getXsheet()->getColumn(columnId.getIndex());
583 TXshZeraryFxColumn *zColumn = dynamic_cast<TXshZeraryFxColumn *>(column);
584 if (zColumn)
585 TFxCommand::renameFx(zColumn->getZeraryColumnFx(), ::to_wstring(newName),
586 m_xsheetHandle);
587 else
588 TStageObjectCmd::rename(columnId, newName, m_xsheetHandle);
589 m_xsheetHandle->notifyXsheetChanged();
590 m_col = -1;
591 setText("");
592 hide();
593 }
594
595 //-----------------------------------------------------------------------------
596
focusOutEvent(QFocusEvent * e)597 void RenameColumnField::focusOutEvent(QFocusEvent *e) {
598 std::wstring newName = text().toStdWString();
599 if (!newName.empty())
600 renameColumn();
601 else
602 hide();
603
604 QLineEdit::focusOutEvent(e);
605 }
606
607 //=============================================================================
608 // ColumnArea
609 //-----------------------------------------------------------------------------
610
onControlPressed(bool pressed)611 void ColumnArea::onControlPressed(bool pressed) {
612 isCtrlPressed = pressed;
613 update();
614 }
615
isControlPressed()616 const bool ColumnArea::isControlPressed() { return isCtrlPressed; }
617
618 //-----------------------------------------------------------------------------
619
DrawHeader(ColumnArea * nArea,QPainter & nP,int nCol)620 ColumnArea::DrawHeader::DrawHeader(ColumnArea *nArea, QPainter &nP, int nCol)
621 : area(nArea), p(nP), col(nCol) {
622 m_viewer = area->m_viewer;
623 o = m_viewer->orientation();
624 app = TApp::instance();
625 xsh = m_viewer->getXsheet();
626 column = xsh->getColumn(col);
627 isEmpty = col >= 0 ? xsh->isColumnEmpty(col) : false;
628
629 TStageObjectId currentColumnId = app->getCurrentObject()->getObjectId();
630
631 // check if the column is current
632 isCurrent = false;
633 if (currentColumnId ==
634 TStageObjectId::CameraId(xsh->getCameraColumnIndex())) // CAMERA
635 isCurrent = col == -1;
636 else
637 isCurrent = m_viewer->getCurrentColumn() == col;
638
639 orig = m_viewer->positionToXY(CellPosition(0, std::max(col, -1)));
640 }
641
prepare() const642 void ColumnArea::DrawHeader::prepare() const {
643 // Preparing painter
644 QString fontName = Preferences::instance()->getInterfaceFont();
645 if (fontName == "") {
646 #ifdef _WIN32
647 fontName = "Arial";
648 #else
649 fontName = "Helvetica";
650 #endif
651 }
652 static QFont font(fontName, -1, QFont::Normal);
653 font.setPixelSize(XSHEET_FONT_PX_SIZE);
654
655 p.setFont(font);
656 p.setRenderHint(QPainter::SmoothPixmapTransform, true);
657 }
658
659 //-----------------------------------------------------------------------------
sound()660 const QPixmap &ColumnArea::Pixmaps::sound() {
661 static QPixmap sound =
662 svgToPixmap(getIconThemePath("actions/30/sound_header.svg"));
663 return sound;
664 }
soundPlaying()665 const QPixmap &ColumnArea::Pixmaps::soundPlaying() {
666 static QPixmap soundPlaying =
667 svgToPixmap(getIconThemePath("actions/30/sound_header_on.svg"));
668 return soundPlaying;
669 }
670
671 //-----------------------------------------------------------------------------
672
levelColors(QColor & columnColor,QColor & dragColor) const673 void ColumnArea::DrawHeader::levelColors(QColor &columnColor,
674 QColor &dragColor) const {
675 if (col < 0) {
676 TStageObjectId cameraId =
677 m_viewer->getXsheet()->getStageObjectTree()->getCurrentCameraId();
678 bool isActive =
679 cameraId.getIndex() == m_viewer->getXsheet()->getCameraColumnIndex();
680 columnColor = isActive ? m_viewer->getActiveCameraColor()
681 : m_viewer->getOtherCameraColor();
682 dragColor = isActive ? m_viewer->getActiveCameraColor()
683 : m_viewer->getOtherCameraColor();
684 return;
685 }
686 enum { Normal, Reference, Control } usage = Reference;
687 if (column) {
688 if (column->isControl()) usage = Control;
689 if (column->isRendered() || column->getMeshColumn()) usage = Normal;
690 }
691
692 if (usage == Reference) {
693 columnColor = m_viewer->getReferenceColumnColor();
694 dragColor = m_viewer->getReferenceColumnBorderColor();
695 } else
696 m_viewer->getColumnColor(columnColor, dragColor, col, xsh);
697 }
soundColors(QColor & columnColor,QColor & dragColor) const698 void ColumnArea::DrawHeader::soundColors(QColor &columnColor,
699 QColor &dragColor) const {
700 m_viewer->getColumnColor(columnColor, dragColor, col, xsh);
701 }
paletteColors(QColor & columnColor,QColor & dragColor) const702 void ColumnArea::DrawHeader::paletteColors(QColor &columnColor,
703 QColor &dragColor) const {
704 enum { Normal, Reference, Control } usage = Reference;
705 if (column) { // Check if column is a mask
706 if (column->isControl()) usage = Control;
707 if (column->isRendered()) usage = Normal;
708 }
709
710 if (usage == Reference) {
711 columnColor = m_viewer->getReferenceColumnColor();
712 dragColor = m_viewer->getReferenceColumnBorderColor();
713 } else {
714 columnColor = m_viewer->getPaletteColumnColor();
715 dragColor = m_viewer->getPaletteColumnBorderColor();
716 }
717 }
718
drawBaseFill(const QColor & columnColor,const QColor & dragColor) const719 void ColumnArea::DrawHeader::drawBaseFill(const QColor &columnColor,
720 const QColor &dragColor) const {
721 // check if the column is reference
722 bool isEditingSpline = app->getCurrentObject()->isSpline();
723
724 QRect rect = o->rect((col < 0) ? PredefinedRect::CAMERA_LAYER_HEADER
725 : PredefinedRect::LAYER_HEADER)
726 .translated(orig);
727
728 int x0 = rect.left();
729 int x1 = rect.right();
730 int y0 = rect.top();
731 int y1 = rect.bottom();
732
733 // Fill base color, in timeline view adjust it right upto thumbnail so column
734 // head color doesn't show under icon switches.
735 if (isEmpty)
736 p.fillRect(o->isVerticalTimeline() ? rect : rect.adjusted(80, 0, 0, 0),
737 m_viewer->getEmptyColumnHeadColor());
738 else if (col < 0)
739 p.fillRect(o->isVerticalTimeline() ? rect : rect.adjusted(80, 0, 0, 0),
740 columnColor);
741 else {
742 p.fillRect(o->isVerticalTimeline() ? rect : rect.adjusted(80, 0, 0, 0),
743 columnColor);
744
745 if (o->flag(PredefinedFlag::DRAG_LAYER_VISIBLE)) {
746 // column handle
747 QRect sideBar = o->rect(PredefinedRect::DRAG_LAYER).translated(x0, y0);
748
749 if (o->flag(PredefinedFlag::DRAG_LAYER_BORDER)) {
750 p.setPen(m_viewer->getVerticalLineColor());
751 p.drawRect(sideBar);
752 }
753
754 p.fillRect(sideBar, sideBar.contains(area->m_pos)
755 ? m_viewer->getXsheetDragBarHighlightColor()
756 : dragColor);
757 }
758 }
759
760 p.setPen(m_viewer->getVerticalLineHeadColor());
761 QLine vertical =
762 o->verticalLine(m_viewer->columnToLayerAxis(col), o->frameSide(rect));
763 if (isEmpty || o->isVerticalTimeline()) p.drawLine(vertical);
764
765 // highlight selection
766 bool isSelected =
767 m_viewer->getColumnSelection()->isColumnSelected(col) && !isEditingSpline;
768 bool isCameraSelected = col == -1 && isCurrent && !isEditingSpline;
769
770 QColor pastelizer(m_viewer->getColumnHeadPastelizer());
771
772 QColor colorSelection(m_viewer->getSelectedColumnHead());
773 p.fillRect(o->isVerticalTimeline() ? rect : rect.adjusted(80, 0, 0, 0),
774 isSelected ? colorSelection : pastelizer);
775 }
776
drawEye() const777 void ColumnArea::DrawHeader::drawEye() const {
778 if (isEmpty || !o->flag(PredefinedFlag::EYE_AREA_VISIBLE)) return;
779 if (col < 0 && o->isVerticalTimeline())
780 return; // no preview eye in the camera column
781 QColor bgColor;
782 QImage icon;
783 int buttonType = !column->isPreviewVisible() ? PREVIEW_OFF_XSHBUTTON
784 : PREVIEW_ON_XSHBUTTON;
785 m_viewer->getButton(buttonType, bgColor, icon, !o->isVerticalTimeline());
786
787 QRect prevViewRect = o->rect(PredefinedRect::EYE_AREA).translated(orig);
788 QRect eyeRect = o->rect(PredefinedRect::EYE).translated(orig);
789 // preview visible toggle
790 if (o->isVerticalTimeline())
791 p.setPen(m_viewer->getColumnIconLineColor()); // Preview border color
792 else
793 p.setPen(m_viewer->getTimelineIconLineColor()); // Preview border color
794
795 if (col < 0 || column->getSoundTextColumn()) {
796 if (o->flag(PredefinedFlag::EYE_AREA_BORDER)) p.drawRect(prevViewRect);
797 return;
798 }
799
800 p.fillRect(prevViewRect, bgColor); // PreviewVisibleColor);
801 if (o->flag(PredefinedFlag::EYE_AREA_BORDER)) p.drawRect(prevViewRect);
802
803 // For Legacy (layout=1), Preview Off button is not displayed in Xsheet mode
804 if (o->isVerticalTimeline() &&
805 m_viewer->getXsheetLayout() == QString("Classic") &&
806 buttonType == PREVIEW_OFF_XSHBUTTON)
807 return;
808
809 p.drawImage(eyeRect, icon);
810 }
811
drawPreviewToggle(int opacity) const812 void ColumnArea::DrawHeader::drawPreviewToggle(int opacity) const {
813 if (isEmpty || !o->flag(PredefinedFlag::PREVIEW_LAYER_AREA_VISIBLE)) return;
814 if (col < 0 && o->isVerticalTimeline())
815 return; // no camstand toggle in the camera column
816 // camstand visible toggle
817 QColor bgColor;
818 QImage icon;
819 int buttonType =
820 !column->isCamstandVisible()
821 ? CAMSTAND_OFF_XSHBUTTON
822 : opacity < 255 ? CAMSTAND_TRANSP_XSHBUTTON : CAMSTAND_ON_XSHBUTTON;
823 m_viewer->getButton(buttonType, bgColor, icon, !o->isVerticalTimeline());
824
825 QRect tableViewRect =
826 o->rect(PredefinedRect::PREVIEW_LAYER_AREA).translated(orig);
827 QRect tableViewImgRect =
828 o->rect(PredefinedRect::PREVIEW_LAYER).translated(orig);
829
830 if (o->isVerticalTimeline())
831 p.setPen(m_viewer->getColumnIconLineColor()); // Camstand border color
832 else
833 p.setPen(m_viewer->getTimelineIconLineColor()); // Camstand border color
834
835 if (col < 0 || column->getPaletteColumn() || column->getSoundTextColumn()) {
836 if (o->flag(PredefinedFlag::PREVIEW_LAYER_AREA_BORDER))
837 p.drawRect(tableViewRect);
838 return;
839 }
840
841 p.fillRect(tableViewRect, bgColor); // CamStandVisibleColor);
842 if (o->flag(PredefinedFlag::PREVIEW_LAYER_AREA_BORDER))
843 p.drawRect(tableViewRect);
844
845 // For Legacy (layout=1), Camstand Off button is not displayed in Xsheet mode
846 if (o->isVerticalTimeline() &&
847 m_viewer->getXsheetLayout() == QString("Classic") &&
848 buttonType == CAMSTAND_OFF_XSHBUTTON)
849 return;
850 p.drawImage(tableViewImgRect, icon);
851 }
852
drawLock() const853 void ColumnArea::DrawHeader::drawLock() const {
854 if (isEmpty || !o->flag(PredefinedFlag::LOCK_AREA_VISIBLE)) return;
855 QColor bgColor;
856 QImage icon;
857 int buttonType = !column->isLocked() ? LOCK_OFF_XSHBUTTON : LOCK_ON_XSHBUTTON;
858 m_viewer->getButton(buttonType, bgColor, icon, !o->isVerticalTimeline());
859
860 QRect lockModeRect = o->rect((col < 0) ? PredefinedRect::CAMERA_LOCK_AREA
861 : PredefinedRect::LOCK_AREA)
862 .translated(orig);
863 QRect lockModeImgRect =
864 o->rect((col < 0) ? PredefinedRect::CAMERA_LOCK : PredefinedRect::LOCK)
865 .translated(orig);
866
867 if (o->isVerticalTimeline() &&
868 m_viewer->getXsheetLayout() == QString("Classic") &&
869 buttonType == LOCK_OFF_XSHBUTTON && !bgColor.alpha())
870 bgColor = QColor(255, 255, 255, 128);
871
872 // lock button
873 if (o->isVerticalTimeline())
874 p.setPen(m_viewer->getColumnIconLineColor()); // Lock border color
875 else
876 p.setPen(m_viewer->getTimelineIconLineColor()); // Lock border color
877
878 p.fillRect(lockModeRect, bgColor);
879 if (o->flag(PredefinedFlag::LOCK_AREA_BORDER)) p.drawRect(lockModeRect);
880
881 // For Legacy (layout=1), Lock Off button is not displayed in Xsheet mode
882 if (o->isVerticalTimeline() &&
883 m_viewer->getXsheetLayout() == QString("Classic") &&
884 buttonType == LOCK_OFF_XSHBUTTON)
885 return;
886 p.drawImage(lockModeImgRect, icon);
887 }
888
drawConfig() const889 void ColumnArea::DrawHeader::drawConfig() const {
890 if (isEmpty || (col >= 0 && !o->flag(PredefinedFlag::CONFIG_AREA_VISIBLE)) ||
891 (col < 0 && !o->flag(PredefinedFlag::CAMERA_CONFIG_AREA_VISIBLE)))
892 return;
893 QColor bgColor;
894 QImage icon;
895 int buttonType = CONFIG_XSHBUTTON;
896 m_viewer->getButton(buttonType, bgColor, icon, !o->isVerticalTimeline());
897
898 QRect configRect = o->rect((col < 0) ? PredefinedRect::CAMERA_CONFIG_AREA
899 : PredefinedRect::CONFIG_AREA)
900 .translated(orig);
901 QRect configImgRect = o->rect((col < 0) ? PredefinedRect::CAMERA_CONFIG
902 : PredefinedRect::CONFIG)
903 .translated(orig);
904
905 // config button
906 if (o->isVerticalTimeline())
907 p.setPen(m_viewer->getColumnIconLineColor());
908 else
909 p.setPen(m_viewer->getTimelineIconLineColor());
910 p.fillRect(configRect, bgColor);
911 if (o->flag((col < 0) ? PredefinedFlag::CAMERA_CONFIG_AREA_BORDER
912 : PredefinedFlag::CONFIG_AREA_BORDER))
913 p.drawRect(configRect);
914
915 TXshZeraryFxColumn *zColumn = dynamic_cast<TXshZeraryFxColumn *>(column);
916
917 if (zColumn || column->getPaletteColumn() || column->getSoundTextColumn())
918 return;
919
920 p.drawImage(configImgRect, icon);
921 }
922
drawColumnNumber() const923 void ColumnArea::DrawHeader::drawColumnNumber() const {
924 if (col < 0 || isEmpty || !o->flag(PredefinedFlag::LAYER_NUMBER_VISIBLE) ||
925 !Preferences::instance()->isShowColumnNumbersEnabled())
926 return;
927
928 QRect pos = o->rect(PredefinedRect::LAYER_NUMBER).translated(orig);
929
930 p.setPen(m_viewer->getVerticalLineColor());
931 if (o->flag(PredefinedFlag::LAYER_NUMBER_BORDER)) p.drawRect(pos);
932
933 p.setPen((isCurrent) ? m_viewer->getSelectedColumnTextColor()
934 : m_viewer->getTextColor());
935
936 int valign = o->isVerticalTimeline() ? Qt::AlignVCenter : Qt::AlignBottom;
937
938 p.drawText(pos, Qt::AlignHCenter | valign | Qt::TextSingleLine,
939 QString::number(col + 1));
940 }
941
drawColumnName() const942 void ColumnArea::DrawHeader::drawColumnName() const {
943 if (!o->flag(PredefinedFlag::LAYER_NAME_VISIBLE)) return;
944
945 TStageObjectId columnId = m_viewer->getObjectId(col);
946 TStageObject *columnObject = xsh->getStageObject(columnId);
947
948 // Build column name
949 std::string name(columnObject->getName());
950 // if (col < 0) name = std::string("Camera");
951
952 // ZeraryFx columns store name elsewhere
953 TXshZeraryFxColumn *zColumn = dynamic_cast<TXshZeraryFxColumn *>(column);
954 if (zColumn)
955 name = ::to_string(zColumn->getZeraryColumnFx()->getZeraryFx()->getName());
956
957 QRect columnName = o->rect((col < 0) ? PredefinedRect::CAMERA_LAYER_NAME
958 : PredefinedRect::LAYER_NAME)
959 .translated(orig);
960
961 bool nameBacklit = false;
962 int rightadj = -2;
963 int leftadj = 3;
964 int valign = o->isVerticalTimeline() ? Qt::AlignVCenter : Qt::AlignBottom;
965
966 if (!isEmpty) {
967 if (o->isVerticalTimeline() &&
968 m_viewer->getXsheetLayout() !=
969 QString("Classic")) // Legacy - No background
970 {
971 if (columnName.contains(area->m_pos) && col >= 0) {
972 p.fillRect(columnName.adjusted(0, -1, 0, 0),
973 m_viewer->getXsheetDragBarHighlightColor()); // Qt::yellow);
974 nameBacklit = true;
975 } else
976 p.fillRect(columnName, m_viewer->getXsheetColumnNameBgColor());
977 }
978
979 if (o->flag(PredefinedFlag::LAYER_NAME_BORDER))
980 p.drawRect(columnName.adjusted(0, 0, 2, 0));
981
982 if (o->isVerticalTimeline() &&
983 m_viewer->getXsheetLayout() == QString("Classic")) {
984 rightadj = -20;
985
986 if (column->isPreviewVisible() && !column->getSoundTextColumn() &&
987 !column->getPaletteColumn() && col >= 0)
988 nameBacklit = true;
989 } else if (Preferences::instance()->isShowColumnNumbersEnabled()) {
990 if (o->isVerticalTimeline())
991 rightadj = -20;
992 else
993 leftadj = 24;
994 }
995
996 p.setPen((isCurrent) ? m_viewer->getSelectedColumnTextColor()
997 : nameBacklit ? Qt::black : m_viewer->getTextColor());
998 } else
999 p.setPen((isCurrent) ? m_viewer->getSelectedColumnTextColor()
1000 : m_viewer->getTextColor());
1001
1002 if (o->isVerticalTimeline() && col < 0) {
1003 QString cameraName = QString::fromStdString(name);
1004 p.save();
1005 p.translate(columnName.topRight());
1006 p.rotate(90);
1007 p.drawText(columnName.translated(-columnName.topLeft())
1008 .transposed()
1009 .adjusted(5, 0, 0, 0),
1010 Qt::AlignLeft | valign, cameraName);
1011 p.restore();
1012 return;
1013 }
1014
1015 p.drawText(columnName.adjusted(leftadj, 0, rightadj, 0),
1016 Qt::AlignLeft | valign | Qt::TextSingleLine,
1017 QString(name.c_str()));
1018 }
1019
drawThumbnail(QPixmap & iconPixmap) const1020 void ColumnArea::DrawHeader::drawThumbnail(QPixmap &iconPixmap) const {
1021 if (isEmpty) return;
1022
1023 QRect thumbnailRect = o->rect((col < 0) ? PredefinedRect::CAMERA_ICON_AREA
1024 : PredefinedRect::THUMBNAIL_AREA)
1025 .translated(orig);
1026 p.setPen(m_viewer->getVerticalLineColor());
1027 if (o->flag(PredefinedFlag::THUMBNAIL_AREA_BORDER)) p.drawRect(thumbnailRect);
1028
1029 // sound thumbnail
1030 if (column->getSoundColumn()) {
1031 TXshSoundColumn *sc =
1032 xsh->getColumn(col) ? xsh->getColumn(col)->getSoundColumn() : 0;
1033
1034 drawSoundIcon(sc->isPlaying());
1035 // Volume control now in config button. If no config button
1036 // draw control
1037 if (!o->flag(PredefinedFlag::CONFIG_AREA_VISIBLE))
1038 drawVolumeControl(sc->getVolume());
1039 return;
1040 }
1041
1042 if (!o->flag((col < 0) ? PredefinedFlag::CAMERA_ICON_VISIBLE
1043 : PredefinedFlag::THUMBNAIL_AREA_VISIBLE))
1044 return;
1045 QRect thumbnailImageRect = o->rect((col < 0) ? PredefinedRect::CAMERA_ICON
1046 : PredefinedRect::THUMBNAIL)
1047 .translated(orig);
1048
1049 // pallete thumbnail
1050 if (column->getPaletteColumn()) {
1051 p.drawPixmap(thumbnailImageRect, iconPixmap);
1052 return;
1053 }
1054
1055 // soundtext thumbnail
1056 if (column->getSoundTextColumn()) {
1057 p.drawPixmap(thumbnailImageRect, iconPixmap);
1058 return;
1059 }
1060
1061 // All other thumbnails
1062 p.setPen(m_viewer->getTextColor());
1063
1064 // for zerary fx, display fxId here instead of thumbnail
1065 TXshZeraryFxColumn *zColumn = dynamic_cast<TXshZeraryFxColumn *>(column);
1066 if (zColumn) {
1067 QFont lastfont = p.font();
1068 QFont font("Verdana", 8);
1069 p.setFont(font);
1070
1071 TFx *fx = zColumn->getZeraryColumnFx()->getZeraryFx();
1072 QString fxName = QString::fromStdWString(fx->getFxId());
1073 p.drawText(thumbnailImageRect, Qt::TextWrapAnywhere | Qt::TextWordWrap,
1074 fxName);
1075 p.setFont(lastfont);
1076 } else {
1077 TXshLevelColumn *levelColumn = column->getLevelColumn();
1078 TXshMeshColumn *meshColumn = column->getMeshColumn();
1079
1080 if (Preferences::instance()->getColumnIconLoadingPolicy() ==
1081 Preferences::LoadOnDemand &&
1082 ((levelColumn && !levelColumn->isIconVisible()) ||
1083 (meshColumn && !meshColumn->isIconVisible())) &&
1084 col >= 0) {
1085 // display nothing
1086 } else {
1087 if (!iconPixmap.isNull()) {
1088 p.drawPixmap(thumbnailImageRect, iconPixmap);
1089 }
1090 // notify that the column icon is already shown
1091 if (levelColumn)
1092 levelColumn->setIconVisible(true);
1093 else if (meshColumn)
1094 meshColumn->setIconVisible(true);
1095 }
1096 }
1097 }
1098
drawPegbarName() const1099 void ColumnArea::DrawHeader::drawPegbarName() const {
1100 if (isEmpty || !o->flag(PredefinedFlag::PEGBAR_NAME_VISIBLE)) return;
1101 // the camera column may have parent pegbar, but it is not displayed for now
1102 if (col < 0) return;
1103
1104 TStageObjectId columnId = m_viewer->getObjectId(col);
1105 TStageObjectId parentId = xsh->getStageObjectParent(columnId);
1106
1107 // pegbar name
1108 QRect pegbarnamerect = o->rect(PredefinedRect::PEGBAR_NAME).translated(orig);
1109 p.setPen(m_viewer->getVerticalLineColor());
1110 if (o->flag(PredefinedFlag::PEGBAR_NAME_BORDER)) p.drawRect(pegbarnamerect);
1111
1112 if (column->getSoundColumn() || column->getSoundTextColumn() ||
1113 column->getPaletteColumn())
1114 return;
1115
1116 p.setPen(m_viewer->getTextColor());
1117
1118 p.drawText(pegbarnamerect.adjusted(3, 0, 0, 0),
1119 Qt::AlignLeft | Qt::AlignVCenter | Qt::TextSingleLine,
1120 QString(parentId.toString().c_str()));
1121 }
1122
drawParentHandleName() const1123 void ColumnArea::DrawHeader::drawParentHandleName() const {
1124 if (col < 0 || isEmpty ||
1125 !o->flag(PredefinedFlag::PARENT_HANDLE_NAME_VISIBILE) ||
1126 column->getSoundColumn() || column->getSoundTextColumn() ||
1127 column->getPaletteColumn())
1128 return;
1129
1130 QRect parenthandleRect =
1131 o->rect(PredefinedRect::PARENT_HANDLE_NAME).translated(orig);
1132 p.setPen(Qt::yellow); // m_viewer->getVerticalLineColor());
1133 if (o->flag(PredefinedFlag::PARENT_HANDLE_NAME_BORDER))
1134 p.drawRect(parenthandleRect);
1135
1136 TStageObjectId columnId = m_viewer->getObjectId(col);
1137 TStageObjectId parentId = xsh->getStageObjectParent(columnId);
1138
1139 p.setPen(m_viewer->getTextColor());
1140
1141 std::string handle = xsh->getStageObject(columnId)->getParentHandle();
1142 if (handle[0] == 'H' && handle.length() > 1) handle = handle.substr(1);
1143 if (parentId != TStageObjectId::TableId)
1144 p.drawText(parenthandleRect,
1145 Qt::AlignHCenter | Qt::AlignVCenter | Qt::TextSingleLine,
1146 QString::fromStdString(handle));
1147 }
1148
drawFilterColor() const1149 void ColumnArea::DrawHeader::drawFilterColor() const {
1150 if (col < 0 || isEmpty || !column->getFilterColorId() ||
1151 column->getSoundColumn() || column->getSoundTextColumn() ||
1152 column->getPaletteColumn())
1153 return;
1154
1155 QRect filterColorRect =
1156 o->rect(PredefinedRect::FILTER_COLOR).translated(orig);
1157 p.drawPixmap(filterColorRect,
1158 getColorChipIcon(column->getFilterColor()).pixmap(12, 12));
1159 }
1160
drawSoundIcon(bool isPlaying) const1161 void ColumnArea::DrawHeader::drawSoundIcon(bool isPlaying) const {
1162 QRect rect = m_viewer->orientation()
1163 ->rect(PredefinedRect::SOUND_ICON)
1164 .translated(orig);
1165 p.drawPixmap(rect, isPlaying ? Pixmaps::soundPlaying() : Pixmaps::sound());
1166 }
1167
drawVolumeControl(double volume) const1168 void ColumnArea::DrawHeader::drawVolumeControl(double volume) const {
1169 // slider subdivisions
1170 p.setPen(m_viewer->getTextColor());
1171 QPoint divisionsTopLeft =
1172 o->point(PredefinedPoint::VOLUME_DIVISIONS_TOP_LEFT) + orig;
1173 int layerAxis = o->layerAxis(divisionsTopLeft);
1174 int frameAxis = o->frameAxis(divisionsTopLeft);
1175 if (o->isVerticalTimeline()) {
1176 if (m_viewer->getXsheetLayout() == QString("Classic")) {
1177 for (int i = 0; i <= 20; i++, frameAxis += 3)
1178 if ((i % 10) == 0)
1179 p.drawLine(o->horizontalLine(frameAxis,
1180 NumberRange(layerAxis - 3, layerAxis)));
1181 else if (i & 1)
1182 p.drawLine(
1183 o->horizontalLine(frameAxis, NumberRange(layerAxis, layerAxis)));
1184 else
1185 p.drawLine(o->horizontalLine(frameAxis,
1186 NumberRange(layerAxis - 2, layerAxis)));
1187 } else {
1188 for (int i = 0; i <= 20; i++, layerAxis += 3)
1189 if ((i % 10) == 0)
1190 p.drawLine(o->verticalLine(layerAxis,
1191 NumberRange(frameAxis, frameAxis + 3)));
1192 else if (i & 1)
1193 p.drawLine(
1194 o->verticalLine(layerAxis, NumberRange(frameAxis, frameAxis)));
1195 else
1196 p.drawLine(o->verticalLine(layerAxis,
1197 NumberRange(frameAxis, frameAxis + 2)));
1198 }
1199 } else {
1200 for (int i = 0; i <= 20; i++, frameAxis += 3)
1201 if ((i % 10) == 0)
1202 p.drawLine(o->horizontalLine(frameAxis,
1203 NumberRange(layerAxis, layerAxis + 3)));
1204 else if (i & 1)
1205 p.drawLine(
1206 o->horizontalLine(frameAxis, NumberRange(layerAxis, layerAxis)));
1207 else
1208 p.drawLine(o->horizontalLine(frameAxis,
1209 NumberRange(layerAxis, layerAxis + 2)));
1210 }
1211
1212 // slider track
1213 QPainterPath track =
1214 o->path(PredefinedPath::VOLUME_SLIDER_TRACK).translated(orig);
1215 p.drawPath(track);
1216
1217 // cursor
1218 QRect trackRect = o->rect(PredefinedRect::VOLUME_TRACK).translated(orig);
1219 if (o->flag(PredefinedFlag::VOLUME_AREA_VERTICAL)) volume = 1 - volume;
1220
1221 layerAxis = o->layerSide(trackRect).middle();
1222 frameAxis = o->frameSide(trackRect).weight(volume);
1223 if (o->isVerticalTimeline() &&
1224 !o->flag(PredefinedFlag::VOLUME_AREA_VERTICAL)) {
1225 layerAxis = o->frameSide(trackRect).middle();
1226 frameAxis = o->layerSide(trackRect).weight(volume);
1227 }
1228 QPoint cursor = o->frameLayerToXY(frameAxis, layerAxis) + QPoint(1, 0);
1229 if (o->isVerticalTimeline() &&
1230 !o->flag(PredefinedFlag::VOLUME_AREA_VERTICAL)) {
1231 cursor = o->frameLayerToXY(layerAxis, frameAxis) + QPoint(1, 0);
1232 }
1233 QPainterPath head =
1234 o->path(PredefinedPath::VOLUME_SLIDER_HEAD).translated(cursor);
1235 p.fillPath(head, QBrush(Qt::white));
1236 p.setPen(m_viewer->getLightLineColor());
1237 p.drawPath(head);
1238 }
1239
1240 //=============================================================================
1241 // ColumnArea
1242 //-----------------------------------------------------------------------------
1243 #if QT_VERSION >= 0x050500
ColumnArea(XsheetViewer * parent,Qt::WindowFlags flags)1244 ColumnArea::ColumnArea(XsheetViewer *parent, Qt::WindowFlags flags)
1245 #else
1246 ColumnArea::ColumnArea(XsheetViewer *parent, Qt::WFlags flags)
1247 #endif
1248 : QWidget(parent, flags)
1249 , m_viewer(parent)
1250 , m_pos(-1, -1)
1251 , m_tooltip(tr(""))
1252 , m_col(-1)
1253 , m_columnTransparencyPopup(0)
1254 , m_transparencyPopupTimer(0)
1255 , m_isPanning(false)
1256 , m_soundColumnPopup(0) {
1257 TXsheetHandle *xsheetHandle = TApp::instance()->getCurrentXsheet();
1258 TObjectHandle *objectHandle = TApp::instance()->getCurrentObject();
1259 m_changeObjectParent = new ChangeObjectParent(0);
1260 m_changeObjectParent->setObjectHandle(objectHandle);
1261 m_changeObjectParent->setXsheetHandle(xsheetHandle);
1262 m_changeObjectParent->hide();
1263
1264 m_changeObjectHandle = new ChangeObjectHandle(0);
1265 m_changeObjectHandle->setObjectHandle(objectHandle);
1266 m_changeObjectHandle->setXsheetHandle(xsheetHandle);
1267 m_changeObjectHandle->hide();
1268
1269 #ifdef LINETEST
1270 // linetest had options around a motion path
1271 // you could configure from the column header
1272 m_motionPathMenu = new MotionPathMenu(0);
1273 #endif
1274
1275 m_renameColumnField = new RenameColumnField(this, m_viewer);
1276 m_renameColumnField->setXsheetHandle(xsheetHandle);
1277 m_renameColumnField->hide();
1278
1279 QActionGroup *actionGroup = new QActionGroup(this);
1280 m_subsampling1 = new QAction(tr("&Subsampling 1"), actionGroup);
1281 m_subsampling2 = new QAction(tr("&Subsampling 2"), actionGroup);
1282 m_subsampling3 = new QAction(tr("&Subsampling 3"), actionGroup);
1283 m_subsampling4 = new QAction(tr("&Subsampling 4"), actionGroup);
1284 actionGroup->addAction(m_subsampling1);
1285 actionGroup->addAction(m_subsampling2);
1286 actionGroup->addAction(m_subsampling3);
1287 actionGroup->addAction(m_subsampling4);
1288
1289 connect(actionGroup, SIGNAL(triggered(QAction *)), this,
1290 SLOT(onSubSampling(QAction *)));
1291 connect(xsheetHandle, SIGNAL(xsheetCameraChange(int)), this,
1292 SLOT(onXsheetCameraChange(int)));
1293 setMouseTracking(true);
1294 }
1295
1296 //-----------------------------------------------------------------------------
1297
~ColumnArea()1298 ColumnArea::~ColumnArea() {}
1299
1300 //-----------------------------------------------------------------------------
1301
getDragTool() const1302 DragTool *ColumnArea::getDragTool() const { return m_viewer->getDragTool(); }
setDragTool(DragTool * dragTool)1303 void ColumnArea::setDragTool(DragTool *dragTool) {
1304 m_viewer->setDragTool(dragTool);
1305 }
1306
1307 //-----------------------------------------------------------------------------
drawFoldedColumnHead(QPainter & p,int col)1308 void ColumnArea::drawFoldedColumnHead(QPainter &p, int col) {
1309 const Orientation *o = m_viewer->orientation();
1310
1311 QPoint orig = m_viewer->positionToXY(CellPosition(0, col));
1312 QRect rect = o->rect(PredefinedRect::FOLDED_LAYER_HEADER).translated(orig);
1313
1314 int x0, y0, x, y;
1315
1316 if (o->isVerticalTimeline()) {
1317 x0 = rect.topLeft().x() + 1;
1318 y0 = 0;
1319
1320 p.setPen(m_viewer->getDarkLineColor());
1321 p.fillRect(x0, y0 + 1, rect.width(), 18,
1322 QBrush(m_viewer->getFoldedColumnBGColor()));
1323 p.fillRect(x0, y0 + 17, 2, rect.height() - 34,
1324 QBrush(m_viewer->getFoldedColumnBGColor()));
1325 p.fillRect(x0 + 3, y0 + 20, 2, rect.height() - 36,
1326 QBrush(m_viewer->getFoldedColumnBGColor()));
1327 p.fillRect(x0 + 6, y0 + 17, 2, rect.height() - 34,
1328 QBrush(m_viewer->getFoldedColumnBGColor()));
1329
1330 p.setPen(m_viewer->getFoldedColumnLineColor());
1331 p.drawLine(x0 - 1, y0 + 17, x0 - 1, rect.height());
1332 p.setPen(m_viewer->getFoldedColumnLineColor());
1333 p.drawLine(x0 + 2, y0 + 17, x0 + 2, rect.height());
1334 p.drawLine(x0 + 5, y0 + 17, x0 + 5, rect.height());
1335 p.drawLine(x0, y0 + 17, x0 + 1, 17);
1336 p.drawLine(x0 + 3, y0 + 20, x0 + 4, 20);
1337 p.drawLine(x0 + 6, y0 + 17, x0 + 7, 17);
1338
1339 // triangolini
1340 p.setPen(Qt::black);
1341 x = x0;
1342 y = 12;
1343 p.drawPoint(QPointF(x, y));
1344 x++;
1345 p.drawLine(x, y - 1, x, y + 1);
1346 x++;
1347 p.drawLine(x, y - 2, x, y + 2);
1348 x += 3;
1349 p.drawLine(x, y - 2, x, y + 2);
1350 x++;
1351 p.drawLine(x, y - 1, x, y + 1);
1352 x++;
1353 p.drawPoint(x, y);
1354 } else {
1355 x0 = 0;
1356 y0 = rect.topLeft().y() + 1;
1357
1358 p.setPen(m_viewer->getFoldedColumnLineColor());
1359 p.fillRect(x0 + 1, y0, 18, rect.height(),
1360 QBrush(m_viewer->getFoldedColumnBGColor()));
1361 p.fillRect(x0 + 17, y0, rect.width() - 34, 2,
1362 QBrush(m_viewer->getFoldedColumnBGColor()));
1363 p.fillRect(x0 + 20, y0 + 3, rect.width() - 36, 2,
1364 QBrush(m_viewer->getFoldedColumnBGColor()));
1365 p.fillRect(x0 + 17, y0 + 6, rect.width() - 34, 2,
1366 QBrush(m_viewer->getFoldedColumnBGColor()));
1367
1368 p.setPen(m_viewer->getFoldedColumnLineColor());
1369 p.drawLine(x0 + 17, y0 - 1, rect.width(), y0 - 1);
1370 p.setPen(m_viewer->getFoldedColumnLineColor());
1371 p.drawLine(x0 + 17, y0 + 2, rect.width(), y0 + 2);
1372 p.drawLine(x0 + 17, y0 + 5, rect.width(), y0 + 5);
1373 p.drawLine(x0 + 17, y0, 17, y0 + 1);
1374 p.drawLine(x0 + 20, y0 + 3, 20, y0 + 4);
1375 p.drawLine(x0 + 17, y0 + 6, 17, y0 + 7);
1376
1377 // triangolini
1378 p.setPen(Qt::black);
1379 x = 12;
1380 y = y0;
1381 p.drawPoint(QPointF(x, y));
1382 y++;
1383 p.drawLine(x - 1, y, x + 1, y);
1384 y++;
1385 p.drawLine(x - 2, y, x + 2, y);
1386 y += 3;
1387 p.drawLine(x - 2, y, x + 2, y);
1388 y++;
1389 p.drawLine(x - 1, y, x + 1, y);
1390 y++;
1391 p.drawPoint(x, y);
1392 }
1393 }
1394
drawLevelColumnHead(QPainter & p,int col)1395 void ColumnArea::drawLevelColumnHead(QPainter &p, int col) {
1396 TColumnSelection *selection = m_viewer->getColumnSelection();
1397 const Orientation *o = m_viewer->orientation();
1398
1399 // Preparing painter
1400 QString fontName = Preferences::instance()->getInterfaceFont();
1401 if (fontName == "") {
1402 #ifdef _WIN32
1403 fontName = "Arial";
1404 #else
1405 fontName = "Helvetica";
1406 #endif
1407 }
1408 static QFont font(fontName, -1, QFont::Normal);
1409 font.setPixelSize(XSHEET_FONT_PX_SIZE);
1410
1411 p.setFont(font);
1412 p.setRenderHint(QPainter::SmoothPixmapTransform, true);
1413
1414 // Retrieve reference coordinates
1415 int currentColumnIndex = m_viewer->getCurrentColumn();
1416 int layerAxis = m_viewer->columnToLayerAxis(col);
1417
1418 QPoint orig = m_viewer->positionToXY(CellPosition(0, col));
1419 QRect rect = o->rect(PredefinedRect::LAYER_HEADER).translated(orig);
1420
1421 TApp *app = TApp::instance();
1422 TXsheet *xsh = m_viewer->getXsheet();
1423
1424 TStageObjectId columnId = m_viewer->getObjectId(col);
1425 TStageObjectId currentColumnId = app->getCurrentObject()->getObjectId();
1426 TStageObjectId parentId = xsh->getStageObjectParent(columnId);
1427
1428 // Retrieve column properties
1429 // Check if the column is empty
1430 bool isEmpty = col >= 0 && xsh->isColumnEmpty(col);
1431 TXshColumn *column = col >= 0 ? xsh->getColumn(col) : 0;
1432
1433 bool isEditingSpline = app->getCurrentObject()->isSpline();
1434
1435 // check if the column is current
1436 bool isCurrent = false;
1437 if (currentColumnId ==
1438 TStageObjectId::CameraId(xsh->getCameraColumnIndex())) // CAMERA
1439 isCurrent = col == -1;
1440 else
1441 isCurrent = m_viewer->getCurrentColumn() == col;
1442
1443 bool isSelected =
1444 m_viewer->getColumnSelection()->isColumnSelected(col) && !isEditingSpline;
1445 bool isCameraSelected = col == -1 && isCurrent && !isEditingSpline;
1446
1447 // Draw column
1448 DrawHeader drawHeader(this, p, col);
1449 drawHeader.prepare();
1450 QColor columnColor, dragColor;
1451 drawHeader.levelColors(columnColor, dragColor);
1452 drawHeader.drawBaseFill(columnColor, dragColor);
1453 drawHeader.drawEye();
1454 drawHeader.drawPreviewToggle(column ? column->getOpacity() : 0);
1455 drawHeader.drawLock();
1456 drawHeader.drawConfig();
1457 drawHeader.drawColumnName();
1458 drawHeader.drawColumnNumber();
1459 QPixmap iconPixmap = getColumnIcon(col);
1460 drawHeader.drawThumbnail(iconPixmap);
1461 drawHeader.drawPegbarName();
1462 drawHeader.drawParentHandleName();
1463 drawHeader.drawFilterColor();
1464 }
1465
1466 //-----------------------------------------------------------------------------
1467
drawSoundColumnHead(QPainter & p,int col)1468 void ColumnArea::drawSoundColumnHead(QPainter &p, int col) { // AREA
1469 TColumnSelection *selection = m_viewer->getColumnSelection();
1470 const Orientation *o = m_viewer->orientation();
1471
1472 int x = m_viewer->columnToLayerAxis(col);
1473
1474 p.setRenderHint(QPainter::SmoothPixmapTransform, true);
1475 QString fontName = Preferences::instance()->getInterfaceFont();
1476 if (fontName == "") {
1477 #ifdef _WIN32
1478 fontName = "Arial";
1479 #else
1480 fontName = "Helvetica";
1481 #endif
1482 }
1483 static QFont font(fontName, -1, QFont::Normal);
1484 font.setPixelSize(XSHEET_FONT_PX_SIZE);
1485 p.setFont(font);
1486
1487 TXsheet *xsh = m_viewer->getXsheet();
1488 TXshSoundColumn *sc =
1489 xsh->getColumn(col) ? xsh->getColumn(col)->getSoundColumn() : 0;
1490
1491 QPoint orig = m_viewer->positionToXY(CellPosition(0, col));
1492 QRect rect = m_viewer->orientation()
1493 ->rect(PredefinedRect::LAYER_HEADER)
1494 .translated(orig);
1495
1496 QPoint columnNamePos = orig + QPoint(12, o->cellHeight());
1497
1498 bool isCurrent = m_viewer->getCurrentColumn() == col;
1499
1500 DrawHeader drawHeader(this, p, col);
1501 drawHeader.prepare();
1502 QColor columnColor, dragColor;
1503 // drawHeader.soundColors(columnColor, dragColor);
1504 drawHeader.levelColors(columnColor, dragColor);
1505 drawHeader.drawBaseFill(columnColor, dragColor);
1506 drawHeader.drawEye();
1507 drawHeader.drawPreviewToggle(sc ? (troundp(255.0 * sc->getVolume())) : 0);
1508 drawHeader.drawLock();
1509 drawHeader.drawConfig();
1510 drawHeader.drawColumnName();
1511 drawHeader.drawColumnNumber();
1512 // Sound columns don't have an image. Passing in an image
1513 // for arguement, but it will be ignored.
1514 static QPixmap iconignored;
1515 drawHeader.drawThumbnail(iconignored);
1516 drawHeader.drawPegbarName();
1517 drawHeader.drawParentHandleName();
1518 drawHeader.drawFilterColor();
1519 }
1520
1521 //-----------------------------------------------------------------------------
1522
drawPaletteColumnHead(QPainter & p,int col)1523 void ColumnArea::drawPaletteColumnHead(QPainter &p, int col) { // AREA
1524 TColumnSelection *selection = m_viewer->getColumnSelection();
1525 const Orientation *o = m_viewer->orientation();
1526
1527 QPoint orig = m_viewer->positionToXY(CellPosition(0, std::max(col, -1)));
1528
1529 QString fontName = Preferences::instance()->getInterfaceFont();
1530 if (fontName == "") {
1531 #ifdef _WIN32
1532 fontName = "Arial";
1533 #else
1534 fontName = "Helvetica";
1535 #endif
1536 }
1537 static QFont font(fontName, -1, QFont::Normal);
1538 font.setPixelSize(XSHEET_FONT_PX_SIZE);
1539
1540 p.setFont(font);
1541 p.setRenderHint(QPainter::SmoothPixmapTransform, true);
1542
1543 int currentColumnIndex = m_viewer->getCurrentColumn();
1544 int x = m_viewer->columnToLayerAxis(col);
1545
1546 QRect rect(x, 0, o->cellWidth(), height());
1547
1548 TXsheet *xsh = m_viewer->getXsheet();
1549
1550 bool isEmpty = false;
1551 if (col >= 0) // Verifico se la colonna e' vuota
1552 isEmpty = xsh->isColumnEmpty(col);
1553
1554 DrawHeader drawHeader(this, p, col);
1555 drawHeader.prepare();
1556 QColor columnColor, dragColor;
1557 drawHeader.paletteColors(columnColor, dragColor);
1558 drawHeader.drawBaseFill(columnColor, dragColor);
1559 drawHeader.drawEye();
1560 drawHeader.drawPreviewToggle(0);
1561 drawHeader.drawLock();
1562 drawHeader.drawConfig();
1563 drawHeader.drawColumnName();
1564 drawHeader.drawColumnNumber();
1565 static QPixmap iconPixmap(svgToPixmap(":Resources/palette_header.svg"));
1566 drawHeader.drawThumbnail(iconPixmap);
1567 drawHeader.drawPegbarName();
1568 drawHeader.drawParentHandleName();
1569 drawHeader.drawFilterColor();
1570 }
1571
1572 //-----------------------------------------------------------------------------
1573
drawSoundTextColumnHead(QPainter & p,int col)1574 void ColumnArea::drawSoundTextColumnHead(QPainter &p, int col) { // AREA
1575 TColumnSelection *selection = m_viewer->getColumnSelection();
1576 const Orientation *o = m_viewer->orientation();
1577
1578 int x = m_viewer->columnToLayerAxis(col);
1579
1580 p.setRenderHint(QPainter::SmoothPixmapTransform, true);
1581 QString fontName = Preferences::instance()->getInterfaceFont();
1582 if (fontName == "") {
1583 #ifdef _WIN32
1584 fontName = "Arial";
1585 #else
1586 fontName = "Helvetica";
1587 #endif
1588 }
1589 static QFont font(fontName, -1, QFont::Normal);
1590 font.setPixelSize(XSHEET_FONT_PX_SIZE);
1591 p.setFont(font);
1592
1593 QRect rect(x, 0, o->cellWidth(), height());
1594
1595 TApp *app = TApp::instance();
1596 TXsheet *xsh = m_viewer->getXsheet();
1597
1598 TStageObjectId columnId = m_viewer->getObjectId(col);
1599 std::string name = xsh->getStageObject(columnId)->getName();
1600
1601 bool isEditingSpline = app->getCurrentObject()->isSpline();
1602
1603 // Check if column is locked and selected
1604 TXshColumn *column = col >= 0 ? xsh->getColumn(col) : 0;
1605 bool isLocked = column != 0 && column->isLocked();
1606 bool isCurrent = m_viewer->getCurrentColumn() == col;
1607 bool isSelected =
1608 m_viewer->getColumnSelection()->isColumnSelected(col) && !isEditingSpline;
1609
1610 DrawHeader drawHeader(this, p, col);
1611 drawHeader.prepare();
1612 QColor columnColor, dragColor;
1613 drawHeader.paletteColors(columnColor, dragColor);
1614 drawHeader.drawBaseFill(columnColor, dragColor);
1615 drawHeader.drawEye();
1616 drawHeader.drawPreviewToggle(255);
1617 drawHeader.drawLock();
1618 drawHeader.drawConfig();
1619 drawHeader.drawColumnName();
1620 drawHeader.drawColumnNumber();
1621 static QPixmap iconPixmap(
1622 recolorPixmap(svgToPixmap(getIconThemePath("actions/74/notelevel.svg"))));
1623 drawHeader.drawThumbnail(iconPixmap);
1624 drawHeader.drawPegbarName();
1625 drawHeader.drawParentHandleName();
1626 drawHeader.drawFilterColor();
1627 }
1628
1629 //-----------------------------------------------------------------------------
1630
getColumnIcon(int columnIndex)1631 QPixmap ColumnArea::getColumnIcon(int columnIndex) {
1632 const Orientation *o = m_viewer->orientation();
1633
1634 if (columnIndex == -1) { // Indice colonna = -1 -> CAMERA
1635 if (o->isVerticalTimeline()) {
1636 static QPixmap camera = svgToPixmap(":Resources/camera_small.svg");
1637 return camera;
1638 } else {
1639 static QPixmap camera = svgToPixmap(":Resources/camera.svg");
1640 return camera;
1641 }
1642 }
1643 TXsheet *xsh = m_viewer->getXsheet();
1644 if (!xsh) return QPixmap();
1645 if (xsh->isColumnEmpty(columnIndex)) return QPixmap();
1646 int r0, r1;
1647 xsh->getCellRange(columnIndex, r0, r1);
1648 if (r0 > r1) return QPixmap();
1649 TXshCell cell = xsh->getCell(r0, columnIndex);
1650 TXshLevel *xl = cell.m_level.getPointer();
1651 if (!xl)
1652 return QPixmap();
1653 else {
1654 bool onDemand = false;
1655 if (Preferences::instance()->getColumnIconLoadingPolicy() ==
1656 Preferences::LoadOnDemand) {
1657 onDemand = m_viewer->getCurrentColumn() != columnIndex;
1658 if (!onDemand) {
1659 TXshColumn *column = xsh->getColumn(columnIndex);
1660 TXshLevelColumn *levelColumn = column->getLevelColumn();
1661 TXshMeshColumn *meshColumn = column->getMeshColumn();
1662 if ((levelColumn && !levelColumn->isIconVisible()) ||
1663 (meshColumn && !meshColumn->isIconVisible()))
1664 return QPixmap();
1665 }
1666 }
1667 QPixmap icon =
1668 IconGenerator::instance()->getIcon(xl, cell.m_frameId, false, onDemand);
1669 QRect thumbnailImageRect = o->rect(PredefinedRect::THUMBNAIL);
1670 if (thumbnailImageRect.isEmpty()) return QPixmap();
1671 return scalePixmapKeepingAspectRatio(icon, thumbnailImageRect.size());
1672 }
1673 }
1674
1675 //-----------------------------------------------------------------------------
1676
paintEvent(QPaintEvent * event)1677 void ColumnArea::paintEvent(QPaintEvent *event) { // AREA
1678 QRect toBeUpdated = event->rect();
1679
1680 QPainter p(this);
1681 p.setClipRect(toBeUpdated);
1682
1683 TXsheet *xsh = m_viewer->getXsheet();
1684 CellRange cellRange = m_viewer->xyRectToRange(toBeUpdated);
1685 int c0, c1; // range of visible columns
1686 c0 = cellRange.from().layer();
1687 c1 = cellRange.to().layer();
1688 if (!m_viewer->orientation()->isVerticalTimeline()) {
1689 int colCount = std::max(1, xsh->getColumnCount());
1690 c1 = std::min(c1, colCount - 1);
1691 }
1692
1693 ColumnFan *columnFan = xsh->getColumnFan(m_viewer->orientation());
1694 int col;
1695 for (col = c0; col <= c1; col++) {
1696 // draw column fan (collapsed columns)
1697 if (!columnFan->isActive(col)) {
1698 drawFoldedColumnHead(p, col);
1699 } else {
1700 TXshColumn *column = m_viewer->getXsheet()->getColumn(col);
1701
1702 int colType = (column && !column->isEmpty()) ? column->getColumnType()
1703 : TXshColumn::eLevelType;
1704
1705 switch (colType) {
1706 case TXshColumn::ePaletteType:
1707 drawPaletteColumnHead(p, col);
1708 break;
1709 case TXshColumn::eSoundType:
1710 drawSoundColumnHead(p, col);
1711 break;
1712 case TXshColumn::eSoundTextType:
1713 drawSoundTextColumnHead(p, col);
1714 break;
1715 default:
1716 drawLevelColumnHead(p, col); // camera column is also painted here
1717 break;
1718 }
1719 }
1720 }
1721
1722 p.setPen(m_viewer->getVerticalLineHeadColor());
1723 p.setBrush(Qt::NoBrush);
1724 if (m_viewer->orientation()->isVerticalTimeline())
1725 p.drawRect(toBeUpdated.adjusted(-1, 0, -1, -3));
1726 else
1727 p.drawRect(toBeUpdated.adjusted(0, 0, -2, -1));
1728
1729 if (getDragTool()) getDragTool()->drawColumnsArea(p);
1730 }
1731
1732 //-----------------------------------------------------------------------------
1733 using namespace DVGui;
1734
ColumnTransparencyPopup(QWidget * parent)1735 ColumnTransparencyPopup::ColumnTransparencyPopup(QWidget *parent)
1736 : QWidget(parent, Qt::Popup) {
1737 setFixedWidth(8 + 78 + 8 + 100 + 8 + 8 + 8 + 7);
1738
1739 m_slider = new QSlider(Qt::Horizontal, this);
1740 m_slider->setMinimum(1);
1741 m_slider->setMaximum(100);
1742 m_slider->setFixedHeight(14);
1743 m_slider->setFixedWidth(100);
1744
1745 m_value = new DVGui::IntLineEdit(this, 1, 1, 100);
1746 /*m_value->setValidator(new QIntValidator (1, 100, m_value));
1747 m_value->setFixedHeight(16);
1748 m_value->setFixedWidth(30);
1749 static QFont font("Helvetica", 7, QFont::Normal);
1750 m_value->setFont(font);*/
1751
1752 m_filterColorCombo = new QComboBox(this);
1753 for (int f = 0; f < (int)TXshColumn::FilterAmount; f++) {
1754 QPair<QString, TPixel32> info =
1755 TXshColumn::getFilterInfo((TXshColumn::FilterColor)f);
1756 if ((TXshColumn::FilterColor)f == TXshColumn::FilterNone)
1757 m_filterColorCombo->addItem(info.first, f);
1758 else
1759 m_filterColorCombo->addItem(getColorChipIcon(info.second), info.first, f);
1760 }
1761
1762 QLabel *filterLabel = new QLabel(tr("Filter:"), this);
1763 QLabel *sliderLabel = new QLabel(tr("Opacity:"), this);
1764
1765 QVBoxLayout *mainLayout = new QVBoxLayout();
1766 mainLayout->setMargin(3);
1767 mainLayout->setSpacing(3);
1768 {
1769 QHBoxLayout *hlayout = new QHBoxLayout;
1770 // hlayout->setContentsMargins(0, 3, 0, 3);
1771 hlayout->setMargin(0);
1772 hlayout->setSpacing(3);
1773 hlayout->addWidget(sliderLabel, 0);
1774 hlayout->addWidget(m_slider);
1775 hlayout->addWidget(m_value);
1776 hlayout->addWidget(new QLabel("%"));
1777 mainLayout->addLayout(hlayout, 0);
1778
1779 QHBoxLayout *filterColorLay = new QHBoxLayout();
1780 filterColorLay->setMargin(0);
1781 filterColorLay->setSpacing(2);
1782 {
1783 filterColorLay->addWidget(filterLabel, 0);
1784 filterColorLay->addWidget(m_filterColorCombo, 1);
1785 }
1786 mainLayout->addLayout(filterColorLay, 0);
1787 }
1788 setLayout(mainLayout);
1789
1790 bool ret = connect(m_slider, SIGNAL(sliderReleased()), this,
1791 SLOT(onSliderReleased()));
1792 ret = ret && connect(m_slider, SIGNAL(sliderMoved(int)), this,
1793 SLOT(onSliderChange(int)));
1794 ret = ret && connect(m_slider, SIGNAL(valueChanged(int)), this,
1795 SLOT(onSliderValueChanged(int)));
1796 ret = ret && connect(m_value, SIGNAL(textChanged(const QString &)), this,
1797 SLOT(onValueChanged(const QString &)));
1798
1799 ret = ret && connect(m_filterColorCombo, SIGNAL(activated(int)), this,
1800 SLOT(onFilterColorChanged(int)));
1801 assert(ret);
1802 }
1803
1804 //----------------------------------------------------------------
1805
onSliderValueChanged(int val)1806 void ColumnTransparencyPopup::onSliderValueChanged(int val) {
1807 if (m_slider->isSliderDown()) return;
1808 m_value->setText(QString::number(val));
1809 onSliderReleased();
1810 }
1811
onSliderReleased()1812 void ColumnTransparencyPopup::onSliderReleased() {
1813 m_column->setOpacity(troundp(255.0 * m_slider->value() / 100.0));
1814 TApp::instance()->getCurrentScene()->notifySceneChanged();
1815 TApp::instance()->getCurrentXsheet()->notifyXsheetChanged();
1816 ((ColumnArea *)parent())->update();
1817 }
1818
1819 //-----------------------------------------------------------------------
1820
onSliderChange(int val)1821 void ColumnTransparencyPopup::onSliderChange(int val) {
1822 disconnect(m_value, SIGNAL(textChanged(const QString &)), 0, 0);
1823 m_value->setText(QString::number(val));
1824 connect(m_value, SIGNAL(textChanged(const QString &)), this,
1825 SLOT(onValueChanged(const QString &)));
1826 }
1827
1828 //----------------------------------------------------------------
1829
onValueChanged(const QString & str)1830 void ColumnTransparencyPopup::onValueChanged(const QString &str) {
1831 int val = str.toInt();
1832 m_slider->setValue(val);
1833 m_column->setOpacity(troundp(255.0 * val / 100.0));
1834
1835 TApp::instance()->getCurrentScene()->notifySceneChanged();
1836 TApp::instance()->getCurrentXsheet()->notifyXsheetChanged();
1837 ((ColumnArea *)parent())->update();
1838 }
1839
1840 //----------------------------------------------------------------
1841
onFilterColorChanged(int id)1842 void ColumnTransparencyPopup::onFilterColorChanged(int id) {
1843 m_column->setFilterColorId((TXshColumn::FilterColor)id);
1844 TApp::instance()->getCurrentScene()->notifySceneChanged();
1845 TApp::instance()->getCurrentXsheet()->notifyXsheetChanged();
1846 ((ColumnArea *)parent())->update();
1847 }
1848
1849 //----------------------------------------------------------------
1850
setColumn(TXshColumn * column)1851 void ColumnTransparencyPopup::setColumn(TXshColumn *column) {
1852 m_column = column;
1853 assert(m_column);
1854 int val = (int)troundp(100.0 * m_column->getOpacity() / 255.0);
1855 m_slider->setValue(val);
1856 disconnect(m_value, SIGNAL(textChanged(const QString &)), 0, 0);
1857 m_value->setText(QString::number(val));
1858 connect(m_value, SIGNAL(textChanged(const QString &)), this,
1859 SLOT(onValueChanged(const QString &)));
1860
1861 m_filterColorCombo->setCurrentIndex(m_column->getFilterColorId());
1862 }
1863
1864 /*void ColumnTransparencyPopup::mouseMoveEvent ( QMouseEvent * e )
1865 {
1866 int val = tcrop((e->pos().x()+10)/(this->width()/(99-1+1)), 1, 99);
1867 m_value->setText(QString::number(val));
1868 m_slider->setValue(val);
1869 }*/
1870
mouseReleaseEvent(QMouseEvent * e)1871 void ColumnTransparencyPopup::mouseReleaseEvent(QMouseEvent *e) {
1872 // hide();
1873 }
1874
1875 //------------------------------------------------------------------------------
1876
SoundColumnPopup(QWidget * parent)1877 SoundColumnPopup::SoundColumnPopup(QWidget *parent)
1878 : QWidget(parent, Qt::Popup) {
1879 setFixedWidth(8 + 78 + 8 + 100 + 8 + 8 + 8 + 7);
1880
1881 m_slider = new QSlider(Qt::Horizontal, this);
1882 m_slider->setMinimum(0);
1883 m_slider->setMaximum(100);
1884 m_slider->setFixedHeight(14);
1885 m_slider->setFixedWidth(100);
1886
1887 m_value = new DVGui::IntLineEdit(this, 1, 1, 100);
1888
1889 QLabel *sliderLabel = new QLabel(tr("Volume:"), this);
1890
1891 QVBoxLayout *mainLayout = new QVBoxLayout();
1892 mainLayout->setMargin(3);
1893 mainLayout->setSpacing(3);
1894 {
1895 QHBoxLayout *hlayout = new QHBoxLayout;
1896 // hlayout->setContentsMargins(0, 3, 0, 3);
1897 hlayout->setMargin(0);
1898 hlayout->setSpacing(3);
1899 hlayout->addWidget(sliderLabel, 0);
1900 hlayout->addWidget(m_slider);
1901 hlayout->addWidget(m_value);
1902 hlayout->addWidget(new QLabel("%"));
1903 mainLayout->addLayout(hlayout, 0);
1904 }
1905 setLayout(mainLayout);
1906
1907 bool ret = connect(m_slider, SIGNAL(sliderReleased()), this,
1908 SLOT(onSliderReleased()));
1909 ret = ret && connect(m_slider, SIGNAL(sliderMoved(int)), this,
1910 SLOT(onSliderChange(int)));
1911 ret = ret && connect(m_slider, SIGNAL(valueChanged(int)), this,
1912 SLOT(onSliderValueChanged(int)));
1913 ret = ret && connect(m_value, SIGNAL(textChanged(const QString &)), this,
1914 SLOT(onValueChanged(const QString &)));
1915 assert(ret);
1916 }
1917
1918 //----------------------------------------------------------------
1919
onSliderValueChanged(int val)1920 void SoundColumnPopup::onSliderValueChanged(int val) {
1921 if (m_slider->isSliderDown()) return;
1922 m_value->setText(QString::number(val));
1923 onSliderReleased();
1924 }
1925
onSliderReleased()1926 void SoundColumnPopup::onSliderReleased() {
1927 int val = m_slider->value();
1928 m_column->getSoundColumn()->setVolume(((double)val / 100.0));
1929 TApp::instance()->getCurrentXsheet()->notifyXsheetSoundChanged();
1930 TApp::instance()->getCurrentScene()->notifySceneChanged();
1931 TApp::instance()->getCurrentXsheet()->notifyXsheetChanged();
1932 ((ColumnArea *)parent())->update();
1933 }
1934
1935 //-----------------------------------------------------------------------
1936
onSliderChange(int val)1937 void SoundColumnPopup::onSliderChange(int val) {
1938 disconnect(m_value, SIGNAL(textChanged(const QString &)), 0, 0);
1939 m_value->setText(QString::number(val));
1940 connect(m_value, SIGNAL(textChanged(const QString &)), this,
1941 SLOT(onValueChanged(const QString &)));
1942 }
1943
1944 //----------------------------------------------------------------
1945
onValueChanged(const QString & str)1946 void SoundColumnPopup::onValueChanged(const QString &str) {
1947 int val = str.toInt();
1948 m_slider->setValue(val);
1949 m_column->getSoundColumn()->setVolume(((double)val / 100.0));
1950
1951 TApp::instance()->getCurrentXsheet()->notifyXsheetSoundChanged();
1952 TApp::instance()->getCurrentScene()->notifySceneChanged();
1953 TApp::instance()->getCurrentXsheet()->notifyXsheetChanged();
1954 ((ColumnArea *)parent())->update();
1955 }
1956
1957 //----------------------------------------------------------------
1958
setColumn(TXshColumn * column)1959 void SoundColumnPopup::setColumn(TXshColumn *column) {
1960 m_column = column;
1961 assert(m_column);
1962 double volume = m_column->getSoundColumn()->getVolume();
1963 int val = (int)troundp(100.0 * volume);
1964 m_slider->setValue(val);
1965 disconnect(m_value, SIGNAL(textChanged(const QString &)), 0, 0);
1966 m_value->setText(QString::number(val));
1967 connect(m_value, SIGNAL(textChanged(const QString &)), this,
1968 SLOT(onValueChanged(const QString &)));
1969 }
1970
mouseReleaseEvent(QMouseEvent * e)1971 void SoundColumnPopup::mouseReleaseEvent(QMouseEvent *e) {
1972 // hide();
1973 }
1974
1975 //----------------------------------------------------------------
1976
openTransparencyPopup()1977 void ColumnArea::openTransparencyPopup() {
1978 if (m_transparencyPopupTimer) m_transparencyPopupTimer->stop();
1979 if (m_col < 0) return;
1980 TXshColumn *column = m_viewer->getXsheet()->getColumn(m_col);
1981 if (!column || column->isEmpty()) return;
1982
1983 if (!column->isCamstandVisible()) {
1984 column->setCamstandVisible(true);
1985 TApp::instance()->getCurrentScene()->notifySceneChanged();
1986 TApp::instance()->getCurrentXsheet()->notifyXsheetChanged();
1987 update();
1988 }
1989
1990 m_columnTransparencyPopup->setColumn(column);
1991 m_columnTransparencyPopup->show();
1992 }
1993
openSoundColumnPopup()1994 void ColumnArea::openSoundColumnPopup() {
1995 if (m_col < 0) return;
1996 TXshColumn *column = m_viewer->getXsheet()->getColumn(m_col);
1997 if (!column || column->isEmpty()) return;
1998
1999 if (!column->isCamstandVisible()) {
2000 column->setCamstandVisible(true);
2001 TApp::instance()->getCurrentXsheet()->notifyXsheetSoundChanged();
2002 TApp::instance()->getCurrentScene()->notifySceneChanged();
2003 TApp::instance()->getCurrentXsheet()->notifyXsheetChanged();
2004 update();
2005 }
2006
2007 m_soundColumnPopup->setColumn(column);
2008 m_soundColumnPopup->show();
2009 }
2010
openCameraColumnPopup(QPoint pos)2011 void ColumnArea::openCameraColumnPopup(QPoint pos) {
2012 QMenu menu(this);
2013
2014 TXsheet *xsh = TApp::instance()->getCurrentXsheet()->getXsheet();
2015 TStageObjectTree *tree = xsh->getStageObjectTree();
2016 int i, objCount = tree->getStageObjectCount();
2017 for (i = 0; i < objCount; i++) {
2018 TStageObject *obj = tree->getStageObject(i);
2019 if (!obj || !obj->getId().isCamera()) continue;
2020 TStageObjectId objId = obj->getId();
2021 std::string objName = obj->getName();
2022 QAction *action = new QAction(QString::fromStdString(objName), this);
2023 action->setData(objId.getIndex());
2024 connect(action, SIGNAL(triggered()), this,
2025 SLOT(onCameraColumnChangedTriggered()));
2026 menu.addAction(action);
2027 }
2028
2029 menu.exec(pos);
2030 }
2031
onCameraColumnChangedTriggered()2032 void ColumnArea::onCameraColumnChangedTriggered() {
2033 int newIndex = qobject_cast<QAction *>(sender())->data().toInt();
2034 onXsheetCameraChange(newIndex);
2035 }
2036
2037 //----------------------------------------------------------------
2038
onXsheetCameraChange(int newIndex)2039 void ColumnArea::onXsheetCameraChange(int newIndex) {
2040 int oldIndex = m_viewer->getXsheet()->getCameraColumnIndex();
2041 if (newIndex == oldIndex) return;
2042
2043 TXsheetHandle *xsheetHandle = TApp::instance()->getCurrentXsheet();
2044
2045 CameraColumnSwitchUndo *undo =
2046 new CameraColumnSwitchUndo(oldIndex, newIndex, xsheetHandle);
2047 undo->redo();
2048 TUndoManager::manager()->add(undo);
2049 }
2050
2051 //----------------------------------------------------------------
2052
startTransparencyPopupTimer(QMouseEvent * e)2053 void ColumnArea::startTransparencyPopupTimer(QMouseEvent *e) { // AREA
2054 if (!m_columnTransparencyPopup)
2055 m_columnTransparencyPopup = new ColumnTransparencyPopup(
2056 this); // Qt::ToolTip|Qt::MSWindowsFixedSizeDialogHint);//Qt::MSWindowsFixedSizeDialogHint|Qt::Tool);
2057
2058 m_columnTransparencyPopup->move(e->globalPos().x(), e->globalPos().y());
2059
2060 if (!m_transparencyPopupTimer) {
2061 m_transparencyPopupTimer = new QTimer(this);
2062 bool ret = connect(m_transparencyPopupTimer, SIGNAL(timeout()), this,
2063 SLOT(openTransparencyPopup()));
2064 assert(ret);
2065 m_transparencyPopupTimer->setSingleShot(true);
2066 }
2067
2068 m_transparencyPopupTimer->start(300);
2069 }
2070
2071 //----------------------------------------------------------------
2072
mousePressEvent(QMouseEvent * event)2073 void ColumnArea::mousePressEvent(QMouseEvent *event) {
2074 const Orientation *o = m_viewer->orientation();
2075
2076 m_doOnRelease = 0;
2077 m_viewer->setQtModifiers(event->modifiers());
2078 assert(getDragTool() == 0);
2079
2080 m_col = -1; // new in 6.4
2081
2082 // both left and right click can change the selection
2083 if (event->button() == Qt::LeftButton || event->button() == Qt::RightButton) {
2084 TXsheet *xsh = m_viewer->getXsheet();
2085 ColumnFan *fan = xsh->getColumnFan(o);
2086 m_col = m_viewer->xyToPosition(event->pos()).layer();
2087 // when clicking the column fan
2088 if (!fan->isActive(m_col)) // column Fan
2089 {
2090 for (auto o : Orientations::all()) {
2091 fan = xsh->getColumnFan(o);
2092 for (int i = m_col; !fan->isActive(i); i--) fan->activate(i);
2093 }
2094
2095 TApp::instance()->getCurrentScene()->setDirtyFlag(true);
2096 TApp::instance()->getCurrentXsheet()->notifyXsheetChanged();
2097 return;
2098 }
2099 // set the clicked column to current
2100 else
2101 m_viewer->setCurrentColumn(m_col);
2102
2103 TXshColumn *column = xsh->getColumn(m_col);
2104 bool isEmpty = !column || column->isEmpty();
2105 TApp::instance()->getCurrentObject()->setIsSpline(false);
2106
2107 // get mouse position
2108 QPoint mouseInCell =
2109 event->pos() - m_viewer->positionToXY(CellPosition(0, m_col));
2110 // int x = event->pos().x() - m_viewer->columnToX(m_col);
2111 // int y = event->pos().y();
2112 // QPoint mouseInCell(x, y);
2113 int x = mouseInCell.x(), y = mouseInCell.y();
2114
2115 // clicking on the camera column
2116 if (m_col < 0) {
2117 // lock button
2118 if (o->rect(PredefinedRect::CAMERA_LOCK_AREA).contains(mouseInCell) &&
2119 event->button() == Qt::LeftButton)
2120 m_doOnRelease = isCtrlPressed ? ToggleAllLock : ToggleLock;
2121 // config button
2122 else if (o->rect(PredefinedRect::CAMERA_CONFIG_AREA)
2123 .contains(mouseInCell) &&
2124 event->button() == Qt::LeftButton)
2125 m_doOnRelease = OpenSettings;
2126 // clicking another area means column selection
2127 else {
2128 if (m_viewer->getColumnSelection()->isColumnSelected(m_col) &&
2129 event->button() == Qt::RightButton)
2130 return;
2131 setDragTool(XsheetGUI::DragTool::makeColumnSelectionTool(m_viewer));
2132 }
2133 }
2134 // clicking on the normal columns
2135 else if (!isEmpty) {
2136 // grabbing the left side of the column enables column move
2137 if (o->rect(PredefinedRect::DRAG_LAYER).contains(mouseInCell) ||
2138 (!o->flag(PredefinedFlag::DRAG_LAYER_VISIBLE) // If dragbar hidden,
2139 // layer name/number
2140 // becomes dragbar
2141 && (o->rect(PredefinedRect::LAYER_NUMBER).contains(mouseInCell) ||
2142 o->rect(PredefinedRect::LAYER_NAME).contains(mouseInCell)))) {
2143 setDragTool(XsheetGUI::DragTool::makeColumnMoveTool(m_viewer));
2144 }
2145 // lock button
2146 else if (o->rect(PredefinedRect::LOCK_AREA).contains(mouseInCell) &&
2147 event->button() == Qt::LeftButton) {
2148 m_doOnRelease = isCtrlPressed ? ToggleAllLock : ToggleLock;
2149 }
2150 // preview button
2151 else if (o->rect(PredefinedRect::EYE_AREA).contains(mouseInCell) &&
2152 event->button() == Qt::LeftButton) {
2153 if (column->getSoundTextColumn()) {
2154 // do nothing
2155 } else {
2156 m_doOnRelease =
2157 isCtrlPressed ? ToggleAllPreviewVisible : TogglePreviewVisible;
2158 if (column->getSoundColumn())
2159 TApp::instance()->getCurrentXsheet()->notifyXsheetSoundChanged();
2160 }
2161 }
2162 // camstand button
2163 else if (o->rect(PredefinedRect::PREVIEW_LAYER_AREA)
2164 .contains(mouseInCell) &&
2165 event->button() == Qt::LeftButton) {
2166 if (column->getPaletteColumn() || column->getSoundTextColumn()) {
2167 // do nothing
2168 } else {
2169 m_doOnRelease =
2170 isCtrlPressed ? ToggleAllTransparency : ToggleTransparency;
2171 if (!o->flag(PredefinedFlag::CONFIG_AREA_VISIBLE) &&
2172 !column->getSoundColumn())
2173 startTransparencyPopupTimer(event);
2174 }
2175 }
2176 // config button
2177 else if (o->rect(PredefinedRect::CONFIG_AREA).contains(mouseInCell) &&
2178 event->button() == Qt::LeftButton) {
2179 TXshZeraryFxColumn *zColumn =
2180 dynamic_cast<TXshZeraryFxColumn *>(column);
2181
2182 if (column && (zColumn || column->getPaletteColumn() ||
2183 column->getSoundTextColumn())) {
2184 // do nothing
2185 } else
2186 m_doOnRelease = OpenSettings;
2187 }
2188 // sound column
2189 else if (column && column->getSoundColumn()) {
2190 if (o->rect(PredefinedRect::SOUND_ICON).contains(mouseInCell)) {
2191 TXshSoundColumn *s = column->getSoundColumn();
2192 if (s) {
2193 if (s->isPlaying())
2194 s->stop();
2195 else {
2196 s->play();
2197 if (!s->isPlaying())
2198 s->stop(); // Serve per vista, quando le casse non sono
2199 // attaccate
2200 }
2201 int interval = 0;
2202 if (s->isPlaying()) {
2203 TSoundTrackP sTrack = s->getCurrentPlaySoundTruck();
2204 interval = sTrack->getDuration() * 1000 + 300;
2205 }
2206 if (s->isPlaying() && interval > 0) {
2207 QTimer::singleShot(interval, this, [this, s] {
2208 if (s && s->isPlaying()) s->stop();
2209 update();
2210 });
2211 }
2212 }
2213 update();
2214 } else if (!o->flag(PredefinedFlag::CONFIG_AREA_VISIBLE) &&
2215 o->rect(PredefinedRect::VOLUME_AREA).contains(mouseInCell))
2216 setDragTool(XsheetGUI::DragTool::makeVolumeDragTool(m_viewer));
2217 else
2218 setDragTool(XsheetGUI::DragTool::makeColumnSelectionTool(m_viewer));
2219 }
2220 // clicking another area means column selection
2221 else {
2222 if (m_viewer->getColumnSelection()->isColumnSelected(m_col) &&
2223 event->button() == Qt::RightButton)
2224 return;
2225
2226 setDragTool(XsheetGUI::DragTool::makeColumnSelectionTool(m_viewer));
2227
2228 if (column) {
2229 // toggle columnIcon visibility with alt+click
2230 TXshLevelColumn *levelColumn = column->getLevelColumn();
2231 TXshMeshColumn *meshColumn = column->getMeshColumn();
2232 if (Preferences::instance()->getColumnIconLoadingPolicy() ==
2233 Preferences::LoadOnDemand &&
2234 (event->modifiers() & Qt::AltModifier)) {
2235 if (levelColumn)
2236 levelColumn->setIconVisible(!levelColumn->isIconVisible());
2237 else if (meshColumn)
2238 meshColumn->setIconVisible(!meshColumn->isIconVisible());
2239 }
2240 }
2241 }
2242 // update the current fx when zerary fx column is clicked
2243 if (column && column->getZeraryFxColumn()) {
2244 TFx *fx = column->getZeraryFxColumn()->getZeraryColumnFx();
2245 TApp::instance()->getCurrentFx()->setFx(fx);
2246 }
2247 } else {
2248 if (m_viewer->getColumnSelection()->isColumnSelected(m_col) &&
2249 event->button() == Qt::RightButton)
2250 return;
2251 setDragTool(XsheetGUI::DragTool::makeColumnSelectionTool(m_viewer));
2252 }
2253
2254 m_viewer->dragToolClick(event);
2255 update();
2256
2257 } else if (event->button() == Qt::MidButton) {
2258 m_pos = event->pos();
2259 m_isPanning = true;
2260 }
2261 }
2262
2263 //-----------------------------------------------------------------------------
2264
mouseMoveEvent(QMouseEvent * event)2265 void ColumnArea::mouseMoveEvent(QMouseEvent *event) {
2266 const Orientation *o = m_viewer->orientation();
2267
2268 m_viewer->setQtModifiers(event->modifiers());
2269 QPoint pos = event->pos();
2270
2271 if (m_isPanning) { // Pan tasto centrale
2272 QPoint delta = m_pos - pos;
2273 if (o->isVerticalTimeline())
2274 delta.setY(0);
2275 else
2276 delta.setX(0);
2277 m_viewer->scroll(delta);
2278 return;
2279 }
2280
2281 int col = m_viewer->xyToPosition(pos).layer();
2282 if (col < -1) col = 0;
2283 TXsheet *xsh = m_viewer->getXsheet();
2284 TXshColumn *column = xsh->getColumn(col);
2285 QPoint mouseInCell = pos - m_viewer->positionToXY(CellPosition(0, col));
2286 int x = mouseInCell.x(), y = mouseInCell.y();
2287
2288 #ifdef LINETEST
2289 // Ensure that the menu of the motion path is hidden
2290 if ((x - m_mtypeBox.left() > 20 || y < m_mtypeBox.y() ||
2291 y > m_mtypeBox.bottom()) &&
2292 !m_motionPathMenu->isHidden())
2293 m_motionPathMenu->hide();
2294 #endif
2295 if ((event->buttons() & Qt::LeftButton) != 0 &&
2296 !visibleRegion().contains(pos)) {
2297 QRect bounds = visibleRegion().boundingRect();
2298 if (o->isVerticalTimeline())
2299 m_viewer->setAutoPanSpeed(bounds, QPoint(pos.x(), bounds.top()));
2300 else
2301 m_viewer->setAutoPanSpeed(bounds, QPoint(bounds.left(), pos.y()));
2302 } else
2303 m_viewer->stopAutoPan();
2304
2305 m_pos = pos;
2306
2307 if (event->buttons() && getDragTool()) {
2308 m_viewer->dragToolDrag(event);
2309 update();
2310 return;
2311 }
2312
2313 // Setto i toolTip
2314 TStageObjectId columnId = m_viewer->getObjectId(col);
2315 TStageObjectId parentId = xsh->getStageObjectParent(columnId);
2316
2317 if (col < 0)
2318 m_tooltip = tr("Click to select camera");
2319 else if (o->rect(PredefinedRect::DRAG_LAYER).contains(mouseInCell)) {
2320 m_tooltip = tr("Click to select column, drag to move it");
2321 } else if (o->rect(PredefinedRect::LAYER_NUMBER).contains(mouseInCell)) {
2322 if (o->isVerticalTimeline())
2323 m_tooltip = tr("Click to select column, drag to move it");
2324 else
2325 m_tooltip = tr("Click to select column");
2326 } else if (o->rect(PredefinedRect::LAYER_NAME).contains(mouseInCell)) {
2327 if (o->isVerticalTimeline())
2328 m_tooltip =
2329 tr("Click to select column, drag to move it, double-click to edit");
2330 else if (column && column->getSoundColumn()) {
2331 // sound column
2332 if (o->rect(PredefinedRect::SOUND_ICON).contains(mouseInCell))
2333 m_tooltip = tr("Click to play the soundtrack back");
2334 else if (!o->flag(PredefinedFlag::CONFIG_AREA_VISIBLE) &&
2335 o->rect(PredefinedRect::VOLUME_AREA).contains(mouseInCell))
2336 m_tooltip = tr("Set the volume of the soundtrack");
2337 } else
2338 m_tooltip = tr("Click to select column, double-click to edit");
2339 } else if (o->rect(PredefinedRect::LOCK_AREA).contains(mouseInCell)) {
2340 m_tooltip = tr("Lock Toggle");
2341 } else if (o->rect(PredefinedRect::CONFIG_AREA).contains(mouseInCell)) {
2342 m_tooltip = tr("Additional column settings");
2343 } else if (o->rect(PredefinedRect::EYE_AREA).contains(mouseInCell)) {
2344 m_tooltip = tr("Preview Visibility Toggle");
2345 } else if (o->rect(PredefinedRect::PREVIEW_LAYER_AREA)
2346 .contains(mouseInCell)) {
2347 m_tooltip = tr("Camera Stand Visibility Toggle");
2348 } else {
2349 if (column && column->getSoundColumn()) {
2350 // sound column
2351 if (o->rect(PredefinedRect::SOUND_ICON).contains(mouseInCell))
2352 m_tooltip = tr("Click to play the soundtrack back");
2353 else if (!o->flag(PredefinedFlag::CONFIG_AREA_VISIBLE) &&
2354 o->rect(PredefinedRect::VOLUME_AREA).contains(mouseInCell))
2355 m_tooltip = tr("Set the volume of the soundtrack");
2356 } else if (Preferences::instance()->getColumnIconLoadingPolicy() ==
2357 Preferences::LoadOnDemand)
2358 m_tooltip = tr("Alt + Click to Toggle Thumbnail");
2359 else
2360 m_tooltip = tr("");
2361 }
2362 update();
2363 }
2364
2365 //-----------------------------------------------------------------------------
2366
event(QEvent * event)2367 bool ColumnArea::event(QEvent *event) {
2368 if (event->type() == QEvent::ToolTip) {
2369 if (!m_tooltip.isEmpty())
2370 QToolTip::showText(mapToGlobal(m_pos), m_tooltip);
2371 else
2372 QToolTip::hideText();
2373 }
2374 return QWidget::event(event);
2375 }
2376
2377 //-----------------------------------------------------------------------------
2378
mouseReleaseEvent(QMouseEvent * event)2379 void ColumnArea::mouseReleaseEvent(QMouseEvent *event) {
2380 TApp *app = TApp::instance();
2381 TXsheet *xsh = m_viewer->getXsheet();
2382 int col, totcols = xsh->getColumnCount();
2383 if (m_doOnRelease != 0) {
2384 TXshColumn *column = xsh->getColumn(m_col);
2385 if (m_doOnRelease == ToggleTransparency) {
2386 column->setCamstandVisible(!column->isCamstandVisible());
2387 if (column->getSoundColumn())
2388 app->getCurrentXsheet()->notifyXsheetSoundChanged();
2389 } else if (m_doOnRelease == TogglePreviewVisible)
2390 column->setPreviewVisible(!column->isPreviewVisible());
2391 else if (m_doOnRelease == ToggleLock)
2392 column->lock(!column->isLocked());
2393 else if (m_doOnRelease == OpenSettings) {
2394 QPoint pos = event->pos();
2395 int col = m_viewer->xyToPosition(pos).layer();
2396 // Align popup to be below to CONFIG button
2397 QRect configRect = m_viewer->orientation()->rect(
2398 (col < 0) ? PredefinedRect::CAMERA_CONFIG_AREA
2399 : PredefinedRect::CONFIG_AREA);
2400 CellPosition cellPosition(0, col);
2401 QPoint topLeft = m_viewer->positionToXY(cellPosition);
2402 QPoint mouseInCell = pos - topLeft;
2403 int x = configRect.left() - mouseInCell.x() +
2404 1; // distance from right edge of CONFIG button
2405 int y =
2406 mouseInCell.y() -
2407 configRect.bottom(); // distance from bottum edge of CONFIG button
2408
2409 if (col < 0) {
2410 openCameraColumnPopup(
2411 QPoint(event->globalPos().x() + x, event->globalPos().y() - y));
2412 } else if (column->getSoundColumn()) {
2413 if (!m_soundColumnPopup)
2414 m_soundColumnPopup = new SoundColumnPopup(this);
2415
2416 m_soundColumnPopup->move(event->globalPos().x() + x,
2417 event->globalPos().y() - y);
2418
2419 openSoundColumnPopup();
2420 } else {
2421 if (!m_columnTransparencyPopup)
2422 m_columnTransparencyPopup = new ColumnTransparencyPopup(this);
2423
2424 m_columnTransparencyPopup->move(event->globalPos().x() + x,
2425 event->globalPos().y() - y);
2426
2427 // make sure the popup doesn't go off the screen to the right
2428 QDesktopWidget *desktop = qApp->desktop();
2429 QRect screenRect = desktop->screenGeometry(app->getMainWindow());
2430
2431 int popupLeft = event->globalPos().x() + x;
2432 int popupRight = popupLeft + m_columnTransparencyPopup->width();
2433
2434 // first condition checks if popup is on same monitor as main app;
2435 // if popup is on different monitor, leave as is
2436 if (popupLeft < screenRect.right() && popupRight > screenRect.right()) {
2437 int distance = popupRight - screenRect.right();
2438 m_columnTransparencyPopup->move(
2439 m_columnTransparencyPopup->x() - distance,
2440 m_columnTransparencyPopup->y());
2441 }
2442
2443 openTransparencyPopup();
2444 }
2445 } else if (m_doOnRelease == ToggleAllPreviewVisible) {
2446 for (col = 0; col < totcols; col++) {
2447 TXshColumn *column = xsh->getColumn(col);
2448 if (!xsh->isColumnEmpty(col) && !column->getPaletteColumn() &&
2449 !column->getSoundTextColumn()) {
2450 column->setPreviewVisible(!column->isPreviewVisible());
2451 }
2452 }
2453 } else if (m_doOnRelease == ToggleAllTransparency) {
2454 bool sound_changed = false;
2455 for (col = 0; col < totcols; col++) {
2456 TXshColumn *column = xsh->getColumn(col);
2457 if (!xsh->isColumnEmpty(col) && !column->getPaletteColumn() &&
2458 !column->getSoundTextColumn()) {
2459 column->setCamstandVisible(!column->isCamstandVisible());
2460 if (column->getSoundColumn()) sound_changed = true;
2461 }
2462 }
2463
2464 if (sound_changed) {
2465 app->getCurrentXsheet()->notifyXsheetSoundChanged();
2466 }
2467 } else if (m_doOnRelease == ToggleAllLock) {
2468 int startCol =
2469 Preferences::instance()->isXsheetCameraColumnVisible() ? -1 : 0;
2470 for (col = startCol; col < totcols; col++) {
2471 TXshColumn *column = xsh->getColumn(col);
2472 if (!xsh->isColumnEmpty(col)) {
2473 column->lock(!column->isLocked());
2474 }
2475 }
2476 } else
2477 assert(false);
2478
2479 app->getCurrentScene()->notifySceneChanged();
2480 // signal XsheetChanged will invoke PreviewFxManager to all rendered frames,
2481 // if necessary. it causes slowness when opening preview flipbook of large
2482 // scene.
2483 bool isTransparencyRendered = app->getCurrentScene()
2484 ->getScene()
2485 ->getProperties()
2486 ->isColumnColorFilterOnRenderEnabled();
2487 if ((isTransparencyRendered && (m_doOnRelease == ToggleTransparency ||
2488 m_doOnRelease == ToggleAllTransparency ||
2489 m_doOnRelease == OpenSettings)) ||
2490 m_doOnRelease == TogglePreviewVisible ||
2491 m_doOnRelease == ToggleAllPreviewVisible)
2492 app->getCurrentXsheet()->notifyXsheetChanged();
2493 update();
2494 m_doOnRelease = 0;
2495 }
2496
2497 if (m_transparencyPopupTimer) m_transparencyPopupTimer->stop();
2498
2499 m_viewer->setQtModifiers(0);
2500 m_viewer->dragToolRelease(event);
2501 m_isPanning = false;
2502 m_viewer->stopAutoPan();
2503 }
2504
2505 //-----------------------------------------------------------------------------
2506
mouseDoubleClickEvent(QMouseEvent * event)2507 void ColumnArea::mouseDoubleClickEvent(QMouseEvent *event) {
2508 const Orientation *o = m_viewer->orientation();
2509
2510 QPoint pos = event->pos();
2511 int col = m_viewer->xyToPosition(pos).layer();
2512 CellPosition cellPosition(0, col);
2513 QPoint topLeft = m_viewer->positionToXY(cellPosition);
2514 QPoint mouseInCell = pos - topLeft;
2515
2516 QRect nameRect = o->rect((col < 0) ? PredefinedRect::CAMERA_LAYER_NAME
2517 : PredefinedRect::LAYER_NAME);
2518 if (!nameRect.contains(mouseInCell)) return;
2519
2520 TXsheet *xsh = m_viewer->getXsheet();
2521 if (col >= 0 && xsh->isColumnEmpty(col)) return;
2522
2523 QPoint fieldPos =
2524 (col < 0 && o->isVerticalTimeline()) ? nameRect.topLeft() : topLeft;
2525 QRect renameRect =
2526 o->rect(PredefinedRect::RENAME_COLUMN).translated(fieldPos);
2527 m_renameColumnField->show(renameRect, col);
2528 }
2529
2530 //-----------------------------------------------------------------------------
2531
contextMenuEvent(QContextMenuEvent * event)2532 void ColumnArea::contextMenuEvent(QContextMenuEvent *event) {
2533 #ifndef _WIN32
2534 /* On windows the widget receive the release event before the menu
2535 is shown, on linux and osx the release event is lost, never
2536 received by the widget */
2537 QMouseEvent fakeRelease(QEvent::MouseButtonRelease, event->pos(),
2538 Qt::RightButton, Qt::NoButton, Qt::NoModifier);
2539
2540 QApplication::instance()->sendEvent(this, &fakeRelease);
2541 #endif
2542 const Orientation *o = m_viewer->orientation();
2543
2544 int col = m_viewer->xyToPosition(event->pos()).layer();
2545
2546 bool isCamera = col < 0;
2547
2548 m_viewer->setCurrentColumn(col);
2549 TXsheet *xsh = m_viewer->getXsheet();
2550 QPoint topLeft = m_viewer->positionToXY(CellPosition(0, col));
2551 QPoint mouseInCell = event->pos() - topLeft;
2552
2553 QMenu menu(this);
2554 CommandManager *cmdManager = CommandManager::instance();
2555
2556 //---- Preview
2557 if (((isCamera && !o->isVerticalTimeline()) || !xsh->isColumnEmpty(col)) &&
2558 o->rect(PredefinedRect::EYE_AREA).contains(mouseInCell)) {
2559 menu.setObjectName("xsheetColumnAreaMenu_Preview");
2560
2561 menu.addAction(cmdManager->getAction("MI_EnableThisColumnOnly"));
2562 menu.addAction(cmdManager->getAction("MI_EnableSelectedColumns"));
2563 menu.addAction(cmdManager->getAction("MI_EnableAllColumns"));
2564 menu.addAction(cmdManager->getAction("MI_DisableAllColumns"));
2565 menu.addAction(cmdManager->getAction("MI_DisableSelectedColumns"));
2566 menu.addAction(cmdManager->getAction("MI_SwapEnabledColumns"));
2567 }
2568 //---- Lock
2569 else if ((isCamera || !xsh->isColumnEmpty(col)) &&
2570 o->rect((isCamera) ? PredefinedRect::CAMERA_LOCK_AREA
2571 : PredefinedRect::LOCK_AREA)
2572 .contains(mouseInCell)) {
2573 menu.setObjectName("xsheetColumnAreaMenu_Lock");
2574
2575 menu.addAction(cmdManager->getAction("MI_LockThisColumnOnly"));
2576 menu.addAction(cmdManager->getAction("MI_LockSelectedColumns"));
2577 menu.addAction(cmdManager->getAction("MI_LockAllColumns"));
2578 menu.addAction(cmdManager->getAction("MI_UnlockSelectedColumns"));
2579 menu.addAction(cmdManager->getAction("MI_UnlockAllColumns"));
2580 menu.addAction(cmdManager->getAction("MI_ToggleColumnLocks"));
2581 }
2582 //---- Camstand
2583 else if (((isCamera && !o->isVerticalTimeline()) ||
2584 !xsh->isColumnEmpty(col)) &&
2585 o->rect(PredefinedRect::PREVIEW_LAYER_AREA).contains(mouseInCell)) {
2586 menu.setObjectName("xsheetColumnAreaMenu_Camstand");
2587
2588 menu.addAction(cmdManager->getAction("MI_ActivateThisColumnOnly"));
2589 menu.addAction(cmdManager->getAction("MI_ActivateSelectedColumns"));
2590 menu.addAction(cmdManager->getAction("MI_ActivateAllColumns"));
2591 menu.addAction(cmdManager->getAction("MI_DeactivateAllColumns"));
2592 menu.addAction(cmdManager->getAction("MI_DeactivateSelectedColumns"));
2593 menu.addAction(cmdManager->getAction("MI_ToggleColumnsActivation"));
2594 // hide all columns placed on the left
2595 menu.addAction(cmdManager->getAction("MI_DeactivateUpperColumns"));
2596 }
2597 // right clicking another area / right clicking empty column head
2598 else {
2599 if (!isCamera) {
2600 int r0, r1;
2601 xsh->getCellRange(col, r0, r1);
2602 TXshCell cell = xsh->getCell(r0, col);
2603 menu.addAction(cmdManager->getAction(MI_Cut));
2604 menu.addAction(cmdManager->getAction(MI_Copy));
2605 menu.addAction(cmdManager->getAction(MI_Paste));
2606 menu.addAction(cmdManager->getAction(MI_PasteAbove));
2607 menu.addAction(cmdManager->getAction(MI_Clear));
2608 menu.addAction(cmdManager->getAction(MI_Insert));
2609 menu.addAction(cmdManager->getAction(MI_InsertAbove));
2610 menu.addSeparator();
2611 menu.addAction(cmdManager->getAction(MI_InsertFx));
2612 menu.addAction(cmdManager->getAction(MI_NewNoteLevel));
2613 menu.addAction(cmdManager->getAction(MI_RemoveEmptyColumns));
2614 menu.addSeparator();
2615 if (m_viewer->getXsheet()->isColumnEmpty(col) ||
2616 (cell.m_level && cell.m_level->getChildLevel()))
2617 menu.addAction(cmdManager->getAction(MI_OpenChild));
2618
2619 // Close sub xsheet and move to parent sheet
2620 ToonzScene *scene = TApp::instance()->getCurrentScene()->getScene();
2621 ChildStack *childStack = scene->getChildStack();
2622 if (childStack && childStack->getAncestorCount() > 0) {
2623 menu.addAction(cmdManager->getAction(MI_CloseChild));
2624 }
2625
2626 menu.addAction(cmdManager->getAction(MI_Collapse));
2627 if (cell.m_level && cell.m_level->getChildLevel()) {
2628 menu.addAction(cmdManager->getAction(MI_Resequence));
2629 menu.addAction(cmdManager->getAction(MI_CloneChild));
2630 menu.addAction(cmdManager->getAction(MI_ExplodeChild));
2631 }
2632 menu.addSeparator();
2633 }
2634 menu.addAction(cmdManager->getAction(MI_FoldColumns));
2635 if (Preferences::instance()->isShowKeyframesOnXsheetCellAreaEnabled()) {
2636 QAction *cameraToggle =
2637 cmdManager->getAction(MI_ToggleXsheetCameraColumn);
2638 bool cameraVisible =
2639 Preferences::instance()->isXsheetCameraColumnVisible();
2640 if (cameraVisible)
2641 cameraToggle->setText(tr("Hide Camera Column"));
2642 else
2643 cameraToggle->setText(tr("Show Camera Column"));
2644 menu.addAction(cameraToggle);
2645 }
2646 menu.addSeparator();
2647 menu.addAction(cmdManager->getAction(MI_ToggleXSheetToolbar));
2648
2649 if (isCamera) {
2650 menu.exec(event->globalPos());
2651 return;
2652 }
2653
2654 // force the selected cells placed in n-steps
2655 if (!xsh->isColumnEmpty(col)) {
2656 menu.addSeparator();
2657 QMenu *reframeSubMenu = new QMenu(tr("Reframe"), this);
2658 {
2659 reframeSubMenu->addAction(cmdManager->getAction(MI_Reframe1));
2660 reframeSubMenu->addAction(cmdManager->getAction(MI_Reframe2));
2661 reframeSubMenu->addAction(cmdManager->getAction(MI_Reframe3));
2662 reframeSubMenu->addAction(cmdManager->getAction(MI_Reframe4));
2663 reframeSubMenu->addAction(
2664 cmdManager->getAction(MI_ReframeWithEmptyInbetweens));
2665 }
2666 menu.addMenu(reframeSubMenu);
2667 menu.addAction(cmdManager->getAction(MI_AutoInputCellNumber));
2668 }
2669
2670 if (containsRasterLevel(m_viewer->getColumnSelection())) {
2671 QMenu *subsampleSubMenu = new QMenu(tr("Subsampling"), this);
2672 {
2673 subsampleSubMenu->addAction(m_subsampling1);
2674 subsampleSubMenu->addAction(m_subsampling2);
2675 subsampleSubMenu->addAction(m_subsampling3);
2676 subsampleSubMenu->addAction(m_subsampling4);
2677 }
2678 menu.addMenu(subsampleSubMenu);
2679 }
2680
2681 if (!xsh->isColumnEmpty(col)) {
2682 menu.addAction(cmdManager->getAction(MI_ReplaceLevel));
2683 menu.addAction(cmdManager->getAction(MI_ReplaceParentDirectory));
2684
2685 // if (containsVectorLevel(col)) {
2686 // menu.addSeparator();
2687 // QAction *setMask =
2688 // new QAction(tr("Temporary Mask (Not in final render)"), this);
2689 // setMask->setCheckable(true);
2690 // setMask->setChecked(xsh->getColumn(col)->isMask());
2691 // setMask->setToolTip(
2692 // tr("Only Toonz Vector levels can be used as masks. \n Masks don't
2693 // "
2694 // "show up in final renders."));
2695 // bool ret = true;
2696 // ret = ret &&
2697 // connect(setMask, &QAction::toggled, [=]() { onSetMask(col); });
2698 // assert(ret);
2699 // menu.addAction(setMask);
2700 //}
2701 }
2702 }
2703
2704 QAction *act = cmdManager->getAction(MI_Insert),
2705 *act2 = cmdManager->getAction(MI_InsertAbove),
2706 *act3 = cmdManager->getAction(MI_Paste),
2707 *act4 = cmdManager->getAction(MI_PasteAbove);
2708
2709 QString actText = act->text(), act2Text = act2->text(),
2710 act3Text = act3->text(), act4Text = act4->text();
2711
2712 if (o->isVerticalTimeline()) {
2713 act->setText(tr("&Insert Before"));
2714 act2->setText(tr("&Insert After"));
2715 act3->setText(tr("&Paste Insert Before"));
2716 act4->setText(tr("&Paste Insert After"));
2717 } else {
2718 act->setText(tr("&Insert Below"));
2719 act2->setText(tr("&Insert Above"));
2720 act3->setText(tr("&Paste Insert Below"));
2721 act4->setText(tr("&Paste Insert Above"));
2722 }
2723
2724 menu.exec(event->globalPos());
2725
2726 act->setText(actText);
2727 act2->setText(act2Text);
2728 act3->setText(act3Text);
2729 act4->setText(act4Text);
2730 }
2731
2732 //-----------------------------------------------------------------------------
2733
onSetMask(int col)2734 void ColumnArea::onSetMask(int col) {
2735 TXshColumn *column = m_viewer->getXsheet()->getColumn(m_col);
2736
2737 std::string name = m_viewer->getXsheet()
2738 ->getStageObject(TStageObjectId::ColumnId(col))
2739 ->getName();
2740 ColumnMaskUndo *undo = new ColumnMaskUndo(col, column->isMask(), name);
2741 undo->redo();
2742 TUndoManager::manager()->add(undo);
2743 update();
2744 }
2745
2746 //-----------------------------------------------------------------------------
2747
onSubSampling(QAction * action)2748 void ColumnArea::onSubSampling(QAction *action) {
2749 int subsampling;
2750 if (action == m_subsampling1)
2751 subsampling = 1;
2752 else if (action == m_subsampling2)
2753 subsampling = 2;
2754 else if (action == m_subsampling3)
2755 subsampling = 3;
2756 else if (action == m_subsampling4)
2757 subsampling = 4;
2758
2759 TColumnSelection *selection = m_viewer->getColumnSelection();
2760 TXsheet *xsh = m_viewer->getXsheet();
2761 assert(selection && xsh);
2762 const std::set<int> indexes = selection->getIndices();
2763 for (auto const &e : indexes) {
2764 if (e < 0) continue; // Ignore camera column
2765 TXshColumn *column = xsh->getColumn(e);
2766 TXshColumn::ColumnType type = column->getColumnType();
2767 if (type != TXshColumn::eLevelType) continue;
2768 const QSet<TXshSimpleLevel *> levels = getLevels(column);
2769 QSet<TXshSimpleLevel *>::const_iterator it2;
2770 for (it2 = levels.begin(); it2 != levels.end(); it2++) {
2771 TXshSimpleLevel *sl = *it2;
2772 if (sl->getProperties()->getDirtyFlag()) continue;
2773 int type = sl->getType();
2774 if (type == TZI_XSHLEVEL || type == TZP_XSHLEVEL ||
2775 type == OVL_XSHLEVEL) {
2776 sl->getProperties()->setSubsampling(subsampling);
2777 sl->invalidateFrames();
2778 }
2779 }
2780 }
2781 TApp::instance()
2782 ->getCurrentXsheet()
2783 ->getXsheet()
2784 ->getStageObjectTree()
2785 ->invalidateAll();
2786 TApp::instance()->getCurrentScene()->notifySceneChanged();
2787 }
2788 } // namespace XsheetGUI
2789