diff --git a/toonz/sources/toonz/filmstrip.cpp b/toonz/sources/toonz/filmstrip.cpp index 7ad1db5..0067ed4 100644 --- a/toonz/sources/toonz/filmstrip.cpp +++ b/toonz/sources/toonz/filmstrip.cpp @@ -119,9 +119,14 @@ FilmstripFrames::FilmstripFrames(QScrollArea *parent, Qt::WFlags flags) setFrameStyle(QFrame::StyledPanel); setFocusPolicy(Qt::StrongFocus); - setFixedWidth(m_iconSize.width() + fs_leftMargin + fs_rightMargin + - fs_iconMarginLR * 2); - setFixedHeight(parentWidget()->height()); + if (m_isVertical) { + setFixedWidth(m_iconSize.width() + fs_leftMargin + fs_rightMargin + + fs_iconMarginLR * 2); + setFixedHeight(parentWidget()->height()); + } else { + setFixedHeight(parentWidget()->height()); + setFixedWidth(parentWidget()->width()); + } // la testa mobile che indica il frame corrente (e gestisce la GUI dell'onion // skin) @@ -158,6 +163,14 @@ int FilmstripFrames::y2index(int y) const { //----------------------------------------------------------------------------- +int FilmstripFrames::x2index(int x) const { + const int dx = getIconSize().width() + fs_frameSpacing + fs_iconMarginLR + + fs_leftMargin + fs_rightMargin; + return x / dx; +} + +//----------------------------------------------------------------------------- + int FilmstripFrames::index2y(int index) const { const int dy = getIconSize().height() + fs_frameSpacing + fs_iconMarginTop + fs_iconMarginBottom; @@ -166,6 +179,14 @@ int FilmstripFrames::index2y(int index) const { //----------------------------------------------------------------------------- +int FilmstripFrames::index2x(int index) const { + const int dx = getIconSize().width() + fs_frameSpacing + fs_iconMarginLR + + fs_leftMargin + fs_rightMargin; + return index * dx; +} + +//----------------------------------------------------------------------------- + TFrameId FilmstripFrames::index2fid(int index) const { TXshSimpleLevel *sl = getLevel(); if (!sl || index < 0) return TFrameId(); @@ -192,53 +213,110 @@ int FilmstripFrames::getFramesHeight() const { //----------------------------------------------------------------------------- +int FilmstripFrames::getFramesWidth() const { + TXshSimpleLevel *level = getLevel(); + int frameCount = level ? level->getFrameCount() : 1; + int frameWidth = m_iconSize.width() + fs_frameSpacing + fs_leftMargin + + fs_rightMargin + fs_iconMarginLR; + return frameWidth * (frameCount + 1); +} + +//----------------------------------------------------------------------------- + int FilmstripFrames::getOneFrameHeight() { return m_iconSize.height() + fs_frameSpacing + fs_iconMarginTop + fs_iconMarginBottom; } //----------------------------------------------------------------------------- + +int FilmstripFrames::getOneFrameWidth() { + return m_iconSize.width() + fs_frameSpacing + fs_leftMargin + + fs_iconMarginLR + fs_rightMargin; +} + +//----------------------------------------------------------------------------- void FilmstripFrames::updateContentHeight(int minimumHeight) { if (minimumHeight < 0) - minimumHeight = visibleRegion().boundingRect().bottom(); + minimumHeight = visibleRegion().boundingRect().bottom(); int contentHeight = getFramesHeight(); if (contentHeight < minimumHeight) contentHeight = minimumHeight; - int parentHeight = parentWidget()->height(); - if (contentHeight < parentHeight) contentHeight = parentHeight; + int parentHeight = parentWidget()->height(); + if (contentHeight < parentHeight) contentHeight = parentHeight; if (contentHeight != height()) setFixedHeight(contentHeight); } //----------------------------------------------------------------------------- +void FilmstripFrames::updateContentWidth(int minimumWidth) { + setFixedHeight(getOneFrameHeight()); + if (minimumWidth < 0) minimumWidth = visibleRegion().boundingRect().right(); + int contentWidth = getFramesWidth(); + if (contentWidth < minimumWidth) contentWidth = minimumWidth; + int parentWidth = parentWidget()->width(); + if (contentWidth < parentWidth) contentWidth = parentWidth; + if (contentWidth != width()) setFixedWidth(contentWidth); +} + +//----------------------------------------------------------------------------- void FilmstripFrames::showFrame(int index) { TXshSimpleLevel *level = getLevel(); - - if (!level->isFid(index2fid(index))) return; - int y0 = index2y(index); - int y1 = y0 + m_iconSize.height() + fs_frameSpacing + fs_iconMarginTop + - fs_iconMarginBottom; - if (y1 > height()) setFixedHeight(y1); - m_scrollArea->ensureVisible(0, (y0 + y1) / 2, 50, (y1 - y0) / 2); + if (m_isVertical) { + if (!level->isFid(index2fid(index))) { + if (!level->isFid(index2fid(index))) return; + } + int y0 = index2y(index); + int y1 = y0 + m_iconSize.height() + fs_frameSpacing + fs_iconMarginTop + + fs_iconMarginBottom; + if (y1 > height()) setFixedHeight(y1); + m_scrollArea->ensureVisible(0, (y0 + y1) / 2, 50, (y1 - y0) / 2); + } else { + if (!level->isFid(index2fid(index))) { + if (!level->isFid(index2fid(index - 1))) return; + } + int x0 = index2x(index); + int x1 = x0 + m_iconSize.width() + fs_frameSpacing + fs_leftMargin + + fs_rightMargin + fs_iconMarginLR; + if (x1 > width()) setFixedWidth(x1); + m_scrollArea->ensureVisible((x0 + x1) / 2, 0, (x1 - x0) / 2, 50); + } } //----------------------------------------------------------------------------- void FilmstripFrames::scroll(int dy) { - QScrollBar *sb = m_scrollArea->verticalScrollBar(); - int sbValue = sb->value(); + if (m_isVertical) { + QScrollBar *sb = m_scrollArea->verticalScrollBar(); + int sbValue = sb->value(); - updateContentHeight(getFramesHeight()); - if (sbValue + dy > getFramesHeight()) { - sb->setValue(getFramesHeight()); - return; + updateContentHeight(getFramesHeight()); + if (sbValue + dy > getFramesHeight()) { + sb->setValue(getFramesHeight()); + return; + } + sb->setValue(sbValue + dy); + } else { + QScrollBar *sb = m_scrollArea->horizontalScrollBar(); + int sbValue = sb->value(); + + updateContentWidth(getFramesWidth()); + if (sbValue + dy > getFramesWidth()) { + sb->setValue(getFramesWidth()); + return; + } + sb->setValue(sbValue + dy); } - sb->setValue(sbValue + dy); } //--------------------------------------------------------------------------- void FilmstripFrames::mouseDoubleClickEvent(QMouseEvent *event) { - int index = y2index(event->pos().y()); + int index; + if (m_isVertical) { + index = y2index(event->pos().y()); + } else { + index = x2index(event->pos().x()); + } select(index, ONLY_SELECT); // ONLY_SELECT } @@ -458,10 +536,17 @@ void FilmstripFrames::paintEvent(QPaintEvent *evt) { QRect(QPoint(fs_leftMargin, fs_frameSpacing / 2), frameSize); int oneFrameHeight = frameSize.height() + fs_frameSpacing; + int oneFrameWidth = frameSize.width() + fs_frameSpacing; // visible frame index range - int i0 = y2index(clipRect.top()); - int i1 = y2index(clipRect.bottom()); + int i0, i1; + if (m_isVertical) { + i0 = y2index(clipRect.top()); + i1 = y2index(clipRect.bottom()); + } else { + i0 = x2index(clipRect.left()); + i1 = x2index(clipRect.right()); + } // fids, frameCount <- frames del livello std::vector fids; @@ -471,7 +556,12 @@ void FilmstripFrames::paintEvent(QPaintEvent *evt) { else { for (int i = i0; i <= i1; i++) { // draw white rectangles if obtaining the level is failed - QRect iconRect = frameRect.translated(QPoint(0, oneFrameHeight * i)); + QRect iconRect; + if (m_isVertical) { + iconRect = frameRect.translated(QPoint(0, oneFrameHeight * i)); + } else { + iconRect = frameRect.translated(QPoint(oneFrameWidth * i, 0)); + } p.setBrush(QColor(192, 192, 192)); p.setPen(Qt::NoPen); p.drawRect(iconRect); @@ -512,8 +602,9 @@ void FilmstripFrames::paintEvent(QPaintEvent *evt) { QRectF naviRatio( (-(float)m_viewer->width() * 0.5f - (float)imgBottomLeft.x) / imgSizeInViewer.width(), - 1.0f - ((float)m_viewer->height() * 0.5f - (float)imgBottomLeft.y) / - imgSizeInViewer.height(), + 1.0f - + ((float)m_viewer->height() * 0.5f - (float)imgBottomLeft.y) / + imgSizeInViewer.height(), (float)m_viewer->width() / imgSizeInViewer.width(), (float)m_viewer->height() / imgSizeInViewer.height()); @@ -538,7 +629,7 @@ void FilmstripFrames::paintEvent(QPaintEvent *evt) { int frameCount = (int)fids.size(); - bool isReadOnly = false; + bool isReadOnly = false; if (sl) isReadOnly = sl->isReadOnly(); int i; @@ -550,17 +641,27 @@ void FilmstripFrames::paintEvent(QPaintEvent *evt) { // linee orizzontali che separano i frames p.setPen(getLightLineColor()); for (i = i0; i <= i1; i++) { - int y = index2y(i) + frameHeight; - p.drawLine(0, y, x1, y); + if (m_isVertical) { + int y = index2y(i) + frameHeight; + p.drawLine(0, y, x1, y); + } else { + int x = index2x(i) + iconWidth; + p.drawLine(x, 0, x, frameHeight); + } } TFilmstripSelection::InbetweenRange range = m_selection->getInbetweenRange(); // draw for each frames for (i = i0; i <= i1; i++) { - QRect tmp_iconImgRect = - iconImgRect.translated(QPoint(0, oneFrameHeight * i)); - QRect tmp_frameRect = frameRect.translated(QPoint(0, oneFrameHeight * i)); + QRect tmp_iconImgRect, tmp_frameRect; + if (m_isVertical) { + tmp_iconImgRect = iconImgRect.translated(QPoint(0, oneFrameHeight * i)); + tmp_frameRect = frameRect.translated(QPoint(0, oneFrameHeight * i)); + } else { + tmp_iconImgRect = iconImgRect.translated(QPoint(oneFrameWidth * i, 0)); + tmp_frameRect = frameRect.translated(QPoint(oneFrameWidth * i, 0)); + } bool isCurrentFrame = (i == sl->fid2index(TApp::instance()->getCurrentFrame()->getFid())); bool isSelected = @@ -622,9 +723,14 @@ void FilmstripFrames::paintEvent(QPaintEvent *evt) { } // navigator rect - if (naviRect.isValid() && fid >= 0 && fid == getCurrentFrameId()) { + if (m_showNavigator && naviRect.isValid() && fid >= 0 && + fid == getCurrentFrameId()) { p.setPen(QPen(Qt::red, 1)); - p.drawRect(naviRect.translated(0, oneFrameHeight * i)); + if (m_isVertical) { + p.drawRect(naviRect.translated(0, oneFrameHeight * i)); + } else { + p.drawRect(naviRect.translated(oneFrameWidth * i, 0)); + } p.setPen(Qt::NoPen); } @@ -661,29 +767,43 @@ void FilmstripFrames::drawFrameIcon(QPainter &p, const QRect &r, int index, p.drawPixmap(r.left(), r.top(), pm); if (sl && sl->getType() == PLI_XSHLEVEL && flags & F_INBETWEEN_RANGE) { - int x1 = r.right(); - int x0 = x1 - 12; - int y0 = r.top(); - int y1 = r.bottom(); - p.fillRect(x0, y0, x1 - x0 + 1, y1 - y0 + 1, QColor(180, 180, 180, 255)); - p.setPen(Qt::black); - p.drawLine(x0 - 1, y0, x0 - 1, y1); - - QPixmap inbetweenPixmap( - svgToPixmap(":Resources/filmstrip_inbetween.svg")); - - if (r.height() - 6 < inbetweenPixmap.height()) { - QSize rectSize(inbetweenPixmap.size()); - rectSize.setHeight(r.height() - 6); - inbetweenPixmap = inbetweenPixmap.scaled( - rectSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation); - } + if (m_isVertical) { + int x1 = r.right(); + int x0 = x1 - 12; + int y0 = r.top(); + int y1 = r.bottom(); + p.fillRect(x0, y0, x1 - x0 + 1, y1 - y0 + 1, + QColor(180, 180, 180, 255)); + p.setPen(Qt::black); + p.drawLine(x0 - 1, y0, x0 - 1, y1); + + QPixmap inbetweenPixmap( + svgToPixmap(":Resources/filmstrip_inbetween.svg")); + + if (r.height() - 6 < inbetweenPixmap.height()) { + QSize rectSize(inbetweenPixmap.size()); + rectSize.setHeight(r.height() - 6); + inbetweenPixmap = inbetweenPixmap.scaled( + rectSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation); + } - p.drawPixmap( - x0 + 2, - y1 - inbetweenPixmap.height() / inbetweenPixmap.devicePixelRatio() - - 3, - inbetweenPixmap); + p.drawPixmap( + x0 + 2, + y1 - inbetweenPixmap.height() / inbetweenPixmap.devicePixelRatio() - + 3, + inbetweenPixmap); + } else { + int x1 = r.right(); + int x0 = r.left(); + int y0 = r.bottom() - 15; + int y1 = r.bottom(); + p.fillRect(x0, y0, x1 - x0 + 1, y1 - y0 + 1, + QColor(180, 180, 180, 255)); + p.setPen(Qt::black); + p.drawLine(x0, y0, x1, y0); + p.drawText(r, tr("INBETWEEN"), + QTextOption(Qt::AlignBottom | Qt::AlignHCenter)); + } } } else { // non riesco (per qualche ragione) a visualizzare l'icona @@ -718,16 +838,33 @@ TFrameId FilmstripFrames::getCurrentFrameId() { //----------------------------------------------------------------------------- void FilmstripFrames::mousePressEvent(QMouseEvent *event) { - m_selecting = false; - int index = y2index(event->pos().y()); + m_selecting = false; + int index = 0; + if (m_isVertical) { + index = y2index(event->pos().y()); + } else { + index = x2index(event->pos().x()); + } TFrameId fid = index2fid(index); TXshSimpleLevel *sl = getLevel(); - int i0 = y2index(0); int frameHeight = m_iconSize.height() + fs_frameSpacing + fs_iconMarginTop + fs_iconMarginBottom; - QPoint clickedPos = event->pos() - QPoint(0, (index - i0) * frameHeight); - bool actualIconClicked = + int frameWidth = m_iconSize.width() + fs_frameSpacing + fs_iconMarginLR + + fs_leftMargin + fs_rightMargin; + + int i0; + QPoint clickedPos; + bool actualIconClicked; + + if (m_isVertical) { + i0 = y2index(0); + clickedPos = event->pos() - QPoint(0, (index - i0) * frameHeight); + } else { + i0 = x2index(0); + clickedPos = event->pos() - QPoint((index - i0) * frameWidth, 0); + } + actualIconClicked = QRect(QPoint(fs_leftMargin + fs_iconMarginLR, fs_frameSpacing / 2 + fs_iconMarginTop) //<- top-left position of the icon @@ -744,9 +881,11 @@ void FilmstripFrames::mousePressEvent(QMouseEvent *event) { (sl->getType() == TZP_XSHLEVEL || sl->getType() == OVL_XSHLEVEL) && m_viewer && m_viewer->isVisible() && actualIconClicked && event->button() == Qt::MiddleButton) { - m_isNavigatorPanning = true; - execNavigatorPan(event->pos()); - QApplication::setOverrideCursor(Qt::ClosedHandCursor); + if (m_showNavigator) { + m_isNavigatorPanning = true; + execNavigatorPan(event->pos()); + QApplication::setOverrideCursor(Qt::ClosedHandCursor); + } } else m_isNavigatorPanning = false; // end of navigator section @@ -757,6 +896,15 @@ void FilmstripFrames::mousePressEvent(QMouseEvent *event) { return; } + // was the inbetween button clicked? + bool inbetweenSelected = false; + if (m_isVertical) + inbetweenSelected = event->pos().x() > width() - 20 - fs_rightMargin; + else + inbetweenSelected = + event->pos().y() > height() - fs_iconMarginBottom - 20 && + event->pos().y() < height() - fs_iconMarginBottom - fs_frameSpacing; + // with shift or control if (event->modifiers() & Qt::ShiftModifier) { select(index, SHIFT_SELECT); @@ -769,10 +917,8 @@ void FilmstripFrames::mousePressEvent(QMouseEvent *event) { } else if (event->modifiers() & Qt::ControlModifier) select(index, CTRL_SELECT); - // was the inbetween button clicked? else if (sl->getType() == PLI_XSHLEVEL && - m_selection->isInInbetweenRange(fid) && - event->pos().x() > width() - 20 - fs_rightMargin) { + m_selection->isInInbetweenRange(fid) && inbetweenSelected) { inbetween(); } else { // move current frame when clicked without modifier @@ -814,13 +960,18 @@ void FilmstripFrames::mousePressEvent(QMouseEvent *event) { //----------------------------------------------------------------------------- void FilmstripFrames::execNavigatorPan(const QPoint &point) { - int index = y2index(point.y()); - TFrameId fid = index2fid(index); - int i0 = y2index(0); + int index = y2index(point.y()); + if (!m_isVertical) index = x2index(point.x()); + TFrameId fid = index2fid(index); + int i0 = y2index(0); + if (!m_isVertical) i0 = x2index(0); int frameHeight = m_iconSize.height() + fs_frameSpacing + fs_iconMarginTop + fs_iconMarginBottom; - QPoint clickedPos = point - QPoint(0, (index - i0) * frameHeight); + int frameWidth = m_iconSize.width() + fs_frameSpacing + fs_iconMarginLR + + fs_leftMargin + fs_rightMargin; + QPoint clickedPos = point - QPoint(0, (index - i0) * frameHeight); + if (!m_isVertical) clickedPos = point - QPoint((index - i0) * frameWidth, 0); if (fid != getCurrentFrameId()) return; @@ -864,11 +1015,12 @@ void FilmstripFrames::mouseReleaseEvent(QMouseEvent *e) { //----------------------------------------------------------------------------- void FilmstripFrames::mouseMoveEvent(QMouseEvent *e) { - QPoint pos = e->pos(); - int index = y2index(e->pos().y()); + QPoint pos = e->pos(); + int index = y2index(e->pos().y()); + if (!m_isVertical) index = x2index(e->pos().x()); if (e->buttons() & Qt::LeftButton || e->buttons() & Qt::MiddleButton) { // navigator pan - if (m_isNavigatorPanning) { + if (m_showNavigator && m_isNavigatorPanning) { execNavigatorPan(e->pos()); e->accept(); return; @@ -886,31 +1038,55 @@ void FilmstripFrames::mouseMoveEvent(QMouseEvent *e) { } // autopan - int speed = getOneFrameHeight() / 64; + int speed = getOneFrameHeight() / 64; + if (!m_isVertical) speed = getOneFrameWidth() / 64; QRect visibleRect = visibleRegion().boundingRect(); int visibleTop = visibleRect.top(); int visibleBottom = visibleRect.bottom(); - if (pos.y() < visibleRect.top()) { - m_scrollSpeed = -speed; - if (visibleRect.top() - pos.y() > 30) { - m_timerInterval = 50; - } else if (visibleRect.top() - pos.y() > 15) { - m_timerInterval = 150; - } else { - m_timerInterval = 300; - } - } else if (pos.y() > visibleRect.bottom()) { - m_scrollSpeed = speed; - if (pos.y() - visibleRect.bottom() > 30) { - m_timerInterval = 50; - } else if (pos.y() - visibleRect.bottom() > 15) { - m_timerInterval = 150; - } else { - m_timerInterval = 300; - } - } else - m_scrollSpeed = 0; + if (m_isVertical) { + if (pos.y() < visibleRect.top()) { + m_scrollSpeed = -speed; + if (visibleRect.top() - pos.y() > 30) { + m_timerInterval = 50; + } else if (visibleRect.top() - pos.y() > 15) { + m_timerInterval = 150; + } else { + m_timerInterval = 300; + } + } else if (pos.y() > visibleRect.bottom()) { + m_scrollSpeed = speed; + if (pos.y() - visibleRect.bottom() > 30) { + m_timerInterval = 50; + } else if (pos.y() - visibleRect.bottom() > 15) { + m_timerInterval = 150; + } else { + m_timerInterval = 300; + } + } else + m_scrollSpeed = 0; + } else { + if (pos.x() < visibleRect.left()) { + m_scrollSpeed = -speed; + if (visibleRect.left() - pos.x() > 30) { + m_timerInterval = 50; + } else if (visibleRect.left() - pos.x() > 15) { + m_timerInterval = 150; + } else { + m_timerInterval = 300; + } + } else if (pos.x() > visibleRect.right()) { + m_scrollSpeed = speed; + if (pos.x() - visibleRect.right() > 30) { + m_timerInterval = 50; + } else if (pos.x() - visibleRect.right() > 15) { + m_timerInterval = 150; + } else { + m_timerInterval = 300; + } + } else + m_scrollSpeed = 0; + } if (m_scrollSpeed != 0) { startAutoPanning(); } else @@ -919,17 +1095,27 @@ void FilmstripFrames::mouseMoveEvent(QMouseEvent *e) { } else if (e->buttons() & Qt::MidButton) { // scroll con il tasto centrale pos = e->globalPos(); - scroll((m_pos.y() - pos.y()) * 10); + if (m_isVertical) { + scroll((m_pos.y() - pos.y()) * 10); + } else { + scroll((m_pos.x() - pos.x()) * 10); + } m_pos = pos; } else { TFrameId fid = index2fid(index); TXshSimpleLevel *sl = getLevel(); - if (sl && m_selection && sl->getType() == PLI_XSHLEVEL && + if (m_isVertical && sl && m_selection && sl->getType() == PLI_XSHLEVEL && m_selection->isInInbetweenRange(fid) && e->pos().x() > width() - 20 - fs_rightMargin) { setToolTip(tr("Auto Inbetween")); } + if (!m_isVertical && sl && m_selection && sl->getType() == PLI_XSHLEVEL && + m_selection->isInInbetweenRange(fid) && + e->pos().y() > height() - 15 - fs_iconMarginBottom && + e->pos().y() < height() - fs_iconMarginBottom - fs_frameSpacing) { + setToolTip(tr("Auto Inbetween")); + } } } @@ -953,25 +1139,39 @@ void FilmstripFrames::keyPressEvent(QKeyEvent *event) { } fh->setFrameIds(fids); - if (event->key() == Qt::Key_Up) + if (event->key() == Qt::Key_Up || event->key() == Qt::Key_Left) fh->prevFrame(); - else if (event->key() == Qt::Key_Down) + else if (event->key() == Qt::Key_Down || event->key() == Qt::Key_Right) fh->nextFrame(newId); else if (event->key() == Qt::Key_Home) fh->firstFrame(); else if (event->key() == Qt::Key_End) fh->lastFrame(); else if (event->key() == Qt::Key_PageDown) { - int frameHeight = m_iconSize.height(); - int visibleHeight = visibleRegion().rects()[0].height(); - int visibleFrames = double(visibleHeight) / double(frameHeight); - scroll(visibleFrames * frameHeight); + if (m_isVertical) { + int frameHeight = m_iconSize.height(); + int visibleHeight = visibleRegion().rects()[0].height(); + int visibleFrames = double(visibleHeight) / double(frameHeight); + scroll(visibleFrames * frameHeight); + } else { + int frameWidth = m_iconSize.width(); + int visibleWidth = visibleRegion().rects()[0].width(); + int visibleFrames = double(visibleWidth) / double(frameWidth); + scroll(visibleFrames * frameWidth); + } return; } else if (event->key() == Qt::Key_PageUp) { - int frameHeight = m_iconSize.height(); - int visibleHeight = visibleRegion().rects()[0].height(); - int visibleFrames = double(visibleHeight) / double(frameHeight); - scroll(-visibleFrames * frameHeight); + if (m_isVertical) { + int frameHeight = m_iconSize.height(); + int visibleHeight = visibleRegion().rects()[0].height(); + int visibleFrames = double(visibleHeight) / double(frameHeight); + scroll(-visibleFrames * frameHeight); + } else { + int frameWidth = m_iconSize.width(); + int visibleWidth = visibleRegion().rects()[0].width(); + int visibleFrames = double(visibleWidth) / double(frameWidth); + scroll(-visibleFrames * frameWidth); + } return; } else return; @@ -1013,8 +1213,9 @@ void FilmstripFrames::timerEvent(QTimerEvent *) { m_timerId = 0; m_timerId = startTimer(m_timerInterval); if (m_selecting) { - QPoint pos = mapFromGlobal(m_pos); - int index = y2index(pos.y()); + QPoint pos = mapFromGlobal(m_pos); + int index = y2index(pos.y()); + if (!m_isVertical) index = x2index(pos.x()); select(index, DRAG_SELECT); showFrame(index); update(); @@ -1068,21 +1269,139 @@ void FilmstripFrames::contextMenuEvent(QContextMenuEvent *event) { (sl->getType() == OVL_XSHLEVEL && sl->getPath().getType() != "gif" && sl->getPath().getType() != "mp4" && sl->getPath().getType() != "webm"))) menu->addAction(cm->getAction(MI_RevertToLastSaved)); + menu->addSeparator(); + createSelectLevelMenu(menu); + QMenu *panelMenu = menu->addMenu(tr("Panel Settings")); + QAction *toggleOrientation = panelMenu->addAction(tr("Toggle Orientation")); + QAction *hideComboBox = panelMenu->addAction(tr("Show/Hide Drop Down Menu")); + QAction *hideNavigator = + panelMenu->addAction(tr("Show/Hide Level Navigator")); + hideComboBox->setCheckable(true); + hideComboBox->setChecked(m_showComboBox); + hideNavigator->setCheckable(true); + hideNavigator->setChecked(m_showNavigator); + connect(toggleOrientation, SIGNAL(triggered(bool)), this, + SLOT(orientationToggled(bool))); + connect(hideComboBox, SIGNAL(triggered(bool)), this, + SLOT(comboBoxToggled(bool))); + connect(hideNavigator, SIGNAL(triggered(bool)), this, + SLOT(navigatorToggled(bool))); menu->exec(event->globalPos()); } //----------------------------------------------------------------------------- +void FilmstripFrames::createSelectLevelMenu(QMenu *menu) { + ToonzScene *scene = TApp::instance()->getCurrentScene()->getScene(); + if (scene) { + std::vector levels; + scene->getLevelSet()->listLevels(levels); + std::vector::iterator it; + int i = 0; + bool active = false; + QMenu *levelSelectMenu; + for (it = levels.begin(); it != levels.end(); ++it) { + TXshSimpleLevel *sl = (*it)->getSimpleLevel(); + if (sl) { + // register only used level in xsheet + if (!scene->getTopXsheet()->isLevelUsed(sl)) continue; + QString levelName = QString::fromStdWString(sl->getName()); + if (i == 0) { + levelSelectMenu = menu->addMenu(tr("Select Level")); + active = true; + } + if (active) { + QAction *action = levelSelectMenu->addAction(levelName); + connect(action, &QAction::triggered, [=] { levelSelected(i); }); + } + i++; + } + } + } +} + +//----------------------------------------------------------------------------- + +void FilmstripFrames::levelSelected(int index) { + emit(levelSelectedSignal(index)); +} + +//----------------------------------------------------------------------------- + +void FilmstripFrames::comboBoxToggled(bool ignore) { + emit(comboBoxToggledSignal()); +} + +//----------------------------------------------------------------------------- + +void FilmstripFrames::navigatorToggled(bool ignore) { + emit(navigatorToggledSignal()); +} + +//----------------------------------------------------------------------------- + +void FilmstripFrames::orientationToggled(bool ignore) { + m_isVertical = !m_isVertical; + emit(orientationToggledSignal(m_isVertical)); +} + +//----------------------------------------------------------------------------- + +void FilmstripFrames::setOrientation(bool isVertical) { + m_isVertical = isVertical; + if (m_isVertical) { + setFixedWidth(m_iconSize.width() + fs_leftMargin + fs_rightMargin + + fs_iconMarginLR * 2); + setFixedHeight(parentWidget()->height()); + } else { + setFixedHeight(parentWidget()->height()); + setFixedWidth(parentWidget()->width()); + } + if (m_isVertical) + updateContentHeight(); + else + updateContentWidth(); + TApp *app = TApp::instance(); + TFrameHandle *fh = app->getCurrentFrame(); + TFrameId fid = getCurrentFrameId(); + + int index = fid2index(fid); + if (index >= 0) { + showFrame(index); + } + update(); +} + +//----------------------------------------------------------------------------- + +void FilmstripFrames::setNavigator(bool showNavigator) { + m_showNavigator = showNavigator; +} + +//----------------------------------------------------------------------------- + +void FilmstripFrames::setComboBox(bool showComboBox) { + m_showComboBox = showComboBox; +} + +//----------------------------------------------------------------------------- + void FilmstripFrames::onLevelChanged() { - updateContentHeight(); + if (m_isVertical) + updateContentHeight(); + else + updateContentWidth(); update(); } //----------------------------------------------------------------------------- void FilmstripFrames::onLevelSwitched(TXshLevel *) { - updateContentHeight(0); + if (m_isVertical) + updateContentHeight(0); + else + updateContentWidth(0); onFrameSwitched(); // deve visualizzare il frame corrente nella levelstrip } @@ -1190,17 +1509,14 @@ Filmstrip::Filmstrip(QWidget *parent, Qt::WFlags flags) m_frames = new FilmstripFrames(m_frameArea); //---- - + m_frames->m_isVertical = m_isVertical; m_frameArea->setObjectName("filmScrollArea"); m_frameArea->setFrameStyle(QFrame::StyledPanel); - m_frameArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - m_frameArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); + setOrientation(m_isVertical); - m_frameArea->verticalScrollBar()->setObjectName("LevelStripScrollBar"); m_frameArea->setWidget(m_frames); m_chooseLevelCombo->setMaxVisibleItems(50); - // layout QVBoxLayout *mainLayout = new QVBoxLayout(); mainLayout->setMargin(0); @@ -1220,6 +1536,14 @@ Filmstrip::Filmstrip(QWidget *parent, Qt::WFlags flags) // changed connect(m_chooseLevelCombo, SIGNAL(activated(int)), this, SLOT(onChooseLevelComboChanged(int))); + connect(m_frames, SIGNAL(orientationToggledSignal(bool)), this, + SLOT(orientationToggled(bool))); + connect(m_frames, SIGNAL(comboBoxToggledSignal()), this, + SLOT(comboBoxToggled())); + connect(m_frames, SIGNAL(navigatorToggledSignal()), this, + SLOT(navigatorToggled())); + connect(m_frames, SIGNAL(levelSelectedSignal(int)), this, + SLOT(onChooseLevelComboChanged(int))); } //----------------------------------------------------------------------------- @@ -1365,7 +1689,7 @@ void Filmstrip::showEvent(QShowEvent *) { TXshLevelHandle *levelHandle = app->getCurrentLevel(); bool ret = connect(levelHandle, SIGNAL(xshLevelSwitched(TXshLevel *)), SLOT(onLevelSwitched(TXshLevel *))); - ret = ret && + ret = ret && connect(levelHandle, SIGNAL(xshLevelChanged()), SLOT(onLevelChanged())); // updateWindowTitle is called in the onLevelChanged @@ -1434,9 +1758,15 @@ void Filmstrip::hideEvent(QHideEvent *) { //----------------------------------------------------------------------------- void Filmstrip::resizeEvent(QResizeEvent *e) { - m_frames->updateContentHeight(); - m_frameArea->verticalScrollBar()->setSingleStep( - m_frames->getOneFrameHeight()); + if (m_isVertical) { + m_frames->updateContentHeight(); + m_frameArea->verticalScrollBar()->setSingleStep( + m_frames->getOneFrameHeight()); + } else { + m_frames->updateContentWidth(); + m_frameArea->horizontalScrollBar()->setSingleStep( + m_frames->getOneFrameWidth()); + } } //----------------------------------------------------------------------------- @@ -1493,9 +1823,17 @@ void Filmstrip::onLevelSwitched(TXshLevel *oldLevel) { void Filmstrip::onSliderMoved(int val) { int oneFrameHeight = m_frames->getIconSize().height() + fs_frameSpacing + fs_iconMarginTop + fs_iconMarginBottom; - int tmpVal = - (int)((float)val / (float)oneFrameHeight + 0.5f) * oneFrameHeight; - m_frameArea->verticalScrollBar()->setValue(tmpVal); + int oneFrameWidth = + m_frames->getIconSize().width() + fs_frameSpacing + fs_iconMarginLR; + if (m_isVertical) { + int tmpVal = + (int)((float)val / (float)oneFrameHeight + 0.5f) * oneFrameHeight; + m_frameArea->verticalScrollBar()->setValue(tmpVal); + } else { + int tmpVal = + (int)((float)val / (float)oneFrameWidth + 0.5f) * oneFrameWidth; + m_frameArea->horizontalScrollBar()->setValue(tmpVal); + } } //----------------------------------------------------------------------------- @@ -1522,6 +1860,80 @@ void Filmstrip::onFrameSwitched() { levelName); } +//----------------------------------------------------------------------------- + +void Filmstrip::orientationToggled(bool isVertical) { + setOrientation(isVertical); +} + +//----------------------------------------------------------------------------- + +void Filmstrip::comboBoxToggled() { + if (m_chooseLevelCombo->isHidden()) + m_chooseLevelCombo->show(); + else + m_chooseLevelCombo->hide(); + m_showComboBox = !m_chooseLevelCombo->isHidden(); + m_frames->setComboBox(m_showComboBox); +} + +//----------------------------------------------------------------------------- + +void Filmstrip::navigatorToggled() { + m_showNavigator = !m_showNavigator; + m_frames->setNavigator(m_showNavigator); +} + +//----------------------------------------------------------------------------- + +void Filmstrip::setOrientation(bool isVertical) { + m_isVertical = isVertical; + if (isVertical) { + m_frameArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + m_frameArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); + m_frameArea->verticalScrollBar()->setObjectName("LevelStripScrollBar"); + } else { + m_frameArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn); + m_frameArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + m_frameArea->horizontalScrollBar()->setObjectName("LevelStripScrollBar"); + } + m_frames->setOrientation(m_isVertical); +} + +// SaveLoadQSettings +void Filmstrip::save(QSettings &settings) const { + UINT orientation = 0; + orientation = m_isVertical ? 1 : 0; + settings.setValue("vertical", orientation); + + UINT showCombo = 0; + showCombo = m_chooseLevelCombo->isHidden() ? 0 : 1; + settings.setValue("showCombo", showCombo); + + UINT navigator = 0; + navigator = m_showNavigator ? 1 : 0; + settings.setValue("navigator", navigator); +} + +void Filmstrip::load(QSettings &settings) { + UINT orientation = settings.value("vertical", 1).toUInt(); + m_isVertical = orientation == 1; + setOrientation(m_isVertical); + + UINT navigator = settings.value("navigator", 1).toUInt(); + m_showNavigator = navigator == 1; + m_frames->setNavigator(m_showNavigator); + + UINT showCombo = settings.value("showCombo", 1).toUInt(); + m_showComboBox = showCombo == 1; + if (showCombo == 1) { + m_chooseLevelCombo->show(); + } else { + m_chooseLevelCombo->hide(); + } + m_frames->setComboBox(m_showComboBox); +} + //============================================================================= // inbetweenDialog //----------------------------------------------------------------------------- @@ -1558,7 +1970,7 @@ QString InbetweenDialog::getValue() { return m_comboBox->currentText(); } //----------------------------------------------------------------------------- void InbetweenDialog::setValue(const QString &value) { - int currentIndex = m_comboBox->findText(value); + int currentIndex = m_comboBox->findText(value); if (currentIndex < 0) currentIndex = 0; m_comboBox->setCurrentIndex(currentIndex); } diff --git a/toonz/sources/toonz/filmstrip.h b/toonz/sources/toonz/filmstrip.h index e72d5a4..fb3cb97 100644 --- a/toonz/sources/toonz/filmstrip.h +++ b/toonz/sources/toonz/filmstrip.h @@ -6,6 +6,7 @@ // TnzQt includes #include "toonzqt/dvdialog.h" #include "toonzqt/selection.h" +#include "saveloadqsettings.h" // Qt includes #include @@ -48,6 +49,10 @@ public: #endif ~FilmstripFrames(); + bool m_isVertical = true; + bool m_showNavigator = true; + bool m_showComboBox = true; + void setBGColor(const QColor &color) { m_bgColor = color; } QColor getBGColor() const { return m_bgColor; } void setLightLineColor(const QColor &color) { m_lightLineColor = color; } @@ -65,6 +70,10 @@ public: int y2index(int y) const; int index2y(int index) const; + // convert mouse coordinate x to a frame index and vice versa + int x2index(int x) const; + int index2x(int index) const; + // returns the frame id of the provided index if index >= 0 // otherwise returns TFrameId() TFrameId index2fid(int index) const; @@ -75,6 +84,9 @@ public: // returns the height of all frames plus a blank one int getFramesHeight() const; + // returns the width of all frames plus a blank one + int getFramesWidth() const; + // aggiorna le dimensioni del QWidget in base al numero di fotogrammi del // livello // la dimensione verticale e' sempre >= minimumHeight. Questo permette di @@ -83,6 +95,7 @@ public: // se minimumHeight == -1 viene utilizzato // visibleRegion().boundingRect().bottom() void updateContentHeight(int minimumHeight = -1); + void updateContentWidth(int minimumHeight = -1); // makes sure that the indexed frame is visible (scrolling if necessary) void showFrame(int index); @@ -106,6 +119,16 @@ public: void select(int index, SelectionMode mode = SIMPLE_SELECT); int getOneFrameHeight(); + int getOneFrameWidth(); + void setOrientation(bool isVertical); + void setNavigator(bool showNavigator); + void setComboBox(bool showComboBox); + +signals: + void orientationToggledSignal(bool); + void comboBoxToggledSignal(); + void navigatorToggledSignal(); + void levelSelectedSignal(int); protected: void showEvent(QShowEvent *) override; @@ -134,7 +157,7 @@ protected: void contextMenuEvent(QContextMenuEvent *event) override; void startDragDrop(); - + void createSelectLevelMenu(QMenu *menu); void inbetween(); void execNavigatorPan(const QPoint &point); @@ -145,6 +168,10 @@ protected slots: void onLevelSwitched(TXshLevel *); void onFrameSwitched(); void getViewer(); + void orientationToggled(bool); + void comboBoxToggled(bool); + void navigatorToggled(bool); + void levelSelected(int); private: // QSS Properties @@ -196,7 +223,7 @@ private: // Filmstrip //----------------------------------------------------------------------------- -class Filmstrip final : public QWidget { +class Filmstrip final : public QWidget, public SaveLoadQSettings { Q_OBJECT FilmstripFrames *m_frames; @@ -206,6 +233,9 @@ class Filmstrip final : public QWidget { std::vector m_levels; std::map m_workingFrames; + bool m_isVertical = true; + bool m_showNavigator = true; + bool m_showComboBox = true; public: #if QT_VERSION >= 0x050500 @@ -215,7 +245,12 @@ public: #endif ~Filmstrip(); + // SaveLoadQSettings + virtual void save(QSettings &settings) const override; + virtual void load(QSettings &settings) override; + protected: + void setOrientation(bool isVertical); void showEvent(QShowEvent *) override; void hideEvent(QHideEvent *) override; void resizeEvent(QResizeEvent *) override; @@ -237,6 +272,9 @@ public slots: void onChooseLevelComboChanged(int index); void onFrameSwitched(); + void orientationToggled(bool); + void comboBoxToggled(); + void navigatorToggled(); private: void updateWindowTitle(); diff --git a/toonz/sources/toonz/frameheadgadget.cpp b/toonz/sources/toonz/frameheadgadget.cpp index 1e799a8..ce59878 100644 --- a/toonz/sources/toonz/frameheadgadget.cpp +++ b/toonz/sources/toonz/frameheadgadget.cpp @@ -297,6 +297,8 @@ FilmstripFrameHeadGadget::FilmstripFrameHeadGadget(FilmstripFrames *filmstrip) : m_filmstrip(filmstrip) , m_dy(m_filmstrip->getIconSize().height() + fs_frameSpacing + fs_iconMarginTop + fs_iconMarginBottom) + , m_dx(m_filmstrip->getIconSize().width() + fs_frameSpacing + + fs_leftMargin + fs_rightMargin + fs_iconMarginLR) , m_highlightedghostFrame(-1) {} int FilmstripFrameHeadGadget::getY() const { return 50; } @@ -305,6 +307,12 @@ int FilmstripFrameHeadGadget::index2y(int index) const { return index * m_dy; } int FilmstripFrameHeadGadget::y2index(int y) const { return y / m_dy; } +int FilmstripFrameHeadGadget::getX() const { return 50; } + +int FilmstripFrameHeadGadget::index2x(int index) const { return index * m_dx; } + +int FilmstripFrameHeadGadget::x2index(int x) const { return x / m_dx; } + void FilmstripFrameHeadGadget::setCurrentFrame(int index) const { TXshSimpleLevel *level = m_filmstrip->getLevel(); if (!level) return; @@ -339,6 +347,7 @@ void FilmstripFrameHeadGadget::drawOnionSkinSelection(QPainter &p, int i; // OnionSkinの円の左上座標のy値 int onionDotYPos = m_dy / 2 - 5; + int onionDotXPos = m_dx / 2 - 5; p.setPen(Qt::red); //--- OnionSkinが有効なら実線、無効なら点線 @@ -356,8 +365,12 @@ void FilmstripFrameHeadGadget::drawOnionSkinSelection(QPainter &p, //上向きのハンドル:1フレーム目のときは描画しない if (currentRow > 0) { int y0 = index2y(currentRow) - 15; + int x0 = index2x(currentRow) - 15; p.setBrush(QBrush(backColor)); - p.drawChord(handleRect.translated(0, y0), 0, angle180); + if (m_filmstrip->m_isVertical) + p.drawChord(handleRect.translated(0, y0), 0, angle180); + else + p.drawChord(handleRect.translated(x0, 0), 16 * 90, angle180); } //下向きのハンドル:最終フレームの時は描画しない @@ -366,8 +379,13 @@ void FilmstripFrameHeadGadget::drawOnionSkinSelection(QPainter &p, int frameCount = (int)fids.size(); if (currentRow < frameCount - 1) { int y1 = index2y(currentRow + 1) - 15; + int x1 = index2x(currentRow + 1) - 15; p.setBrush(QBrush(frontColor)); - p.drawChord(handleRect.translated(0, y1), angle180, angle180); + + if (m_filmstrip->m_isVertical) + p.drawChord(handleRect.translated(0, y1), angle180, angle180); + else + p.drawChord(handleRect.translated(x1, 0), 16 * 90, -angle180); } //--- 動く Onion Skinの描画 その1 @@ -384,15 +402,29 @@ void FilmstripFrameHeadGadget::drawOnionSkinSelection(QPainter &p, // min/maxが更新されていたら、線を描く if (minMos < 0) //上方向に伸ばす線 { - int y0 = index2y(currentRow + minMos) + onionDotYPos + 10; // 10は●の直径 - int y1 = index2y(currentRow) - 15; - p.drawLine(15, y0, 15, y1); + if (m_filmstrip->m_isVertical) { + int y0 = + index2y(currentRow + minMos) + onionDotYPos + 10; // 10は●の直径 + int y1 = index2y(currentRow) - 15; + p.drawLine(15, y0, 15, y1); + } else { + int x0 = + index2x(currentRow + minMos) + onionDotXPos + 10; // 10は●の直径 + int x1 = index2x(currentRow) - 15; + p.drawLine(x0, 15, x1, 15); + } } if (maxMos > 0) //下方向に伸ばす線 { - int y0 = index2y(currentRow + 1) + 15; - int y1 = index2y(currentRow + maxMos) + onionDotYPos; - p.drawLine(15, y0, 15, y1); + if (m_filmstrip->m_isVertical) { + int y0 = index2y(currentRow + 1) + 15; + int y1 = index2y(currentRow + maxMos) + onionDotYPos; + p.drawLine(15, y0, 15, y1); + } else { + int x0 = index2x(currentRow + 1) + 15; + int x1 = index2x(currentRow + maxMos) + onionDotXPos; + p.drawLine(x0, 15, x1, 15); + } } } @@ -401,11 +433,15 @@ void FilmstripFrameHeadGadget::drawOnionSkinSelection(QPainter &p, int fos = osMask.getFos(i); // if(fos == currentRow) continue; int y = index2y(fos) + onionDotYPos; + int x = index2x(fos) + onionDotXPos; p.setPen(Qt::red); // OnionSkinがDisableなら中空にする p.setBrush(osMask.isEnabled() ? QBrush(QColor(0, 255, 255, 128)) : Qt::NoBrush); - p.drawEllipse(0, y, 10, 10); + if (m_filmstrip->m_isVertical) + p.drawEllipse(0, y, 10, 10); + else + p.drawEllipse(x, 0, 10, 10); } //--- @@ -420,10 +456,14 @@ void FilmstripFrameHeadGadget::drawOnionSkinSelection(QPainter &p, if (currentRow + mos == m_highlightedMosFrame) continue; int y = index2y(currentRow + mos) + onionDotYPos; + int x = index2x(currentRow + mos) + onionDotXPos; p.setBrush(mos < 0 ? backColor : frontColor); - p.drawEllipse(10, y, 10, 10); + if (m_filmstrip->m_isVertical) + p.drawEllipse(10, y, 10, 10); + else + p.drawEllipse(x, 10, 10, 10); } // Fix Onion Skin ハイライトの描画 @@ -432,14 +472,20 @@ void FilmstripFrameHeadGadget::drawOnionSkinSelection(QPainter &p, if (m_highlightedFosFrame >= 0 && m_highlightedFosFrame != currentRow) { p.setPen(QColor(255, 128, 0)); p.setBrush(QBrush(QColor(255, 255, 0, 200))); - p.drawEllipse(0, index2y(m_highlightedFosFrame) + onionDotYPos, 10, 10); + if (m_filmstrip->m_isVertical) + p.drawEllipse(0, index2y(m_highlightedFosFrame) + onionDotYPos, 10, 10); + else + p.drawEllipse(index2x(m_highlightedFosFrame) + onionDotXPos, 0, 10, 10); } //通常のOnion Skin ハイライトの描画 if (m_highlightedMosFrame >= 0 && m_highlightedMosFrame != currentRow) { p.setPen(QColor(255, 128, 0)); p.setBrush(QBrush(QColor(255, 255, 0, 200))); - p.drawEllipse(10, index2y(m_highlightedMosFrame) + onionDotYPos, 10, 10); + if (m_filmstrip->m_isVertical) + p.drawEllipse(10, index2y(m_highlightedMosFrame) + onionDotYPos, 10, 10); + else + p.drawEllipse(index2x(m_highlightedMosFrame) + onionDotXPos, 10, 10, 10); } } @@ -463,23 +509,43 @@ void FilmstripFrameHeadGadget::drawShiftTraceMarker(QPainter &p) { const int shiftTraceDotSize = 12; const int shiftTraceDotXOffset = 3; + const int shiftTraceDotYOffset = 3; int dotYPos = (m_dy - shiftTraceDotSize) / 2; + int dotXPos = (m_dx - shiftTraceDotSize) / 2; if (currentRow > 0 && prevOffset < 0) // previous ghost { - p.setPen(backColor); - int y0 = index2y(currentRow + prevOffset) + dotYPos + shiftTraceDotSize; - int y1 = index2y(currentRow); - p.drawLine(shiftTraceDotXOffset + shiftTraceDotSize / 2, y0, - shiftTraceDotXOffset + shiftTraceDotSize / 2, y1); + if (m_filmstrip->m_isVertical) { + p.setPen(backColor); + int y0 = index2y(currentRow + prevOffset) + dotYPos + shiftTraceDotSize; + int y1 = index2y(currentRow); + p.drawLine(shiftTraceDotXOffset + shiftTraceDotSize / 2, y0, + shiftTraceDotXOffset + shiftTraceDotSize / 2, y1); + } else { + p.setPen(backColor); + int x0 = index2x(currentRow + prevOffset) + dotXPos + shiftTraceDotSize; + int x1 = index2x(currentRow); + p.drawLine(x0, shiftTraceDotYOffset + shiftTraceDotSize / 2, x1, + shiftTraceDotYOffset + shiftTraceDotSize / 2); + } } if (forwardOffset > 0) // forward ghost { - p.setPen(frontColor); - int y0 = index2y(currentRow + 1); - int y1 = index2y(currentRow + forwardOffset) + dotYPos + shiftTraceDotSize; - p.drawLine(shiftTraceDotXOffset + shiftTraceDotSize / 2, y0, - shiftTraceDotXOffset + shiftTraceDotSize / 2, y1); + if (m_filmstrip->m_isVertical) { + p.setPen(frontColor); + int y0 = index2y(currentRow + 1); + int y1 = + index2y(currentRow + forwardOffset) + dotYPos + shiftTraceDotSize; + p.drawLine(shiftTraceDotXOffset + shiftTraceDotSize / 2, y0, + shiftTraceDotXOffset + shiftTraceDotSize / 2, y1); + } else { + p.setPen(frontColor); + int x0 = index2x(currentRow + 1); + int x1 = + index2x(currentRow + forwardOffset) + dotXPos + shiftTraceDotSize; + p.drawLine(x0, shiftTraceDotYOffset + shiftTraceDotSize / 2, x1, + shiftTraceDotYOffset + shiftTraceDotSize / 2); + } } // draw dots std::vector offsVec = {prevOffset, 0, forwardOffset}; @@ -493,9 +559,17 @@ void FilmstripFrameHeadGadget::drawShiftTraceMarker(QPainter &p) { if (i != 1 && offsVec[i] == 0) continue; p.setPen(colorsVec[i]); p.setBrush(Qt::gray); - int topPos = index2y(currentRow + offsVec[i]) + dotYPos; - QRect dotRect(shiftTraceDotXOffset, topPos, shiftTraceDotSize, - shiftTraceDotSize); + int topPos; + QRect dotRect; + if (m_filmstrip->m_isVertical) { + topPos = index2y(currentRow + offsVec[i]) + dotYPos; + dotRect = QRect(shiftTraceDotXOffset, topPos, shiftTraceDotSize, + shiftTraceDotSize); + } else { + topPos = index2x(currentRow + offsVec[i]) + dotXPos; + dotRect = QRect(topPos, shiftTraceDotYOffset, shiftTraceDotSize, + shiftTraceDotSize); + } p.drawRect(dotRect); // draw shortcut numbers @@ -508,9 +582,17 @@ void FilmstripFrameHeadGadget::drawShiftTraceMarker(QPainter &p) { if (m_highlightedghostFrame >= 0) { p.setPen(QColor(255, 255, 0)); p.setBrush(QColor(255, 255, 0, 180)); - int topPos = index2y(m_highlightedghostFrame) + dotYPos; - QRect dotRect(shiftTraceDotXOffset, topPos, shiftTraceDotSize, - shiftTraceDotSize); + int topPos; + QRect dotRect; + if (m_filmstrip->m_isVertical) { + topPos = index2y(m_highlightedghostFrame) + dotYPos; + dotRect = QRect(shiftTraceDotXOffset, topPos, shiftTraceDotSize, + shiftTraceDotSize); + } else { + topPos = index2x(m_highlightedghostFrame) + dotXPos; + dotRect = QRect(topPos, shiftTraceDotYOffset, shiftTraceDotSize, + shiftTraceDotSize); + } p.drawRect(dotRect); } } @@ -538,14 +620,22 @@ bool FilmstripFrameHeadGadget::eventFilter(QObject *obj, QEvent *e) { //それぞれのパーツの位置Rectの指定。各フレームの右上座標からのオフセットも含む。 // OnionSkinの円の左上座標のy値 int onionDotYPos = m_dy / 2 - 5; + int onionDotXPos = m_dx / 2 - 5; // OnionSkinの●のRect QRect onionDotRect(10, onionDotYPos, 10, 10); + if (!m_filmstrip->m_isVertical) + onionDotRect = QRect(onionDotXPos, 10, 10, 10); // FixedOnionSkinの●のRect QRect fixedOnionDotRect(0, onionDotYPos, 10, 10); + if (!m_filmstrip->m_isVertical) + fixedOnionDotRect = QRect(onionDotXPos, 0, 10, 10); //上方向のOnionSkinタブのRect QRect backOnionTabRect(0, m_dy - 15, 30, 15); + if (!m_filmstrip->m_isVertical) + backOnionTabRect = QRect(m_dx - 15, 0, 15, 30); //下方向のOnionSkinタブのRect QRect frontOnionTabRect(0, 0, 30, 15); + if (!m_filmstrip->m_isVertical) frontOnionTabRect = QRect(0, 0, 15, 30); //----- //----- ハイライト表示、actionのリセット @@ -563,13 +653,16 @@ bool FilmstripFrameHeadGadget::eventFilter(QObject *obj, QEvent *e) { //----- 以下、クリック位置に応じてアクションを変えていく //クリックされたフレームを取得 - QMouseEvent *mouseEvent = dynamic_cast(e); - int frame = y2index(mouseEvent->pos().y()); - m_buttonPressCellIndex = frame; - int currentFrame = getCurrentFrame(); + QMouseEvent *mouseEvent = dynamic_cast(e); + int frame = y2index(mouseEvent->pos().y()); + if (!m_filmstrip->m_isVertical) frame = x2index(mouseEvent->pos().x()); + m_buttonPressCellIndex = frame; + int currentFrame = getCurrentFrame(); //各フレーム左上からの位置 QPoint clickedPos = mouseEvent->pos() + QPoint(0, -index2y(frame)); + if (!m_filmstrip->m_isVertical) + clickedPos = mouseEvent->pos() + QPoint(-index2x(frame), 0); //カレントフレームの場合、無視 if (frame == currentFrame) return false; @@ -608,15 +701,21 @@ bool FilmstripFrameHeadGadget::eventFilter(QObject *obj, QEvent *e) { else if (e->type() == QEvent::MouseButtonDblClick) { QMouseEvent *mouseEvent = dynamic_cast(e); if (mouseEvent->buttons() & Qt::LeftButton) { - int frame = y2index(mouseEvent->pos().y()); + int frame = y2index(mouseEvent->pos().y()); + if (!m_filmstrip->m_isVertical) frame = x2index(mouseEvent->pos().x()); //各フレーム左上からの位置 QPoint clickedPos = mouseEvent->pos() + QPoint(0, -index2y(frame)); + if (!m_filmstrip->m_isVertical) + clickedPos = mouseEvent->pos() + QPoint(-index2x(frame), 0); //カレントフレーム int currentFrame = getCurrentFrame(); //上方向のOnionSkinタブのRect QRect backOnionTabRect(0, m_dy - 15, 30, 15); + if (!m_filmstrip->m_isVertical) + backOnionTabRect = QRect(m_dx - 15, 0, 15, 30); //下方向のOnionSkinタブのRect QRect frontOnionTabRect(0, 0, 30, 15); + if (!m_filmstrip->m_isVertical) frontOnionTabRect = QRect(0, 0, 15, 30); if ((currentFrame - 1 == frame && backOnionTabRect.contains(clickedPos)) || (currentFrame + 1 == frame && @@ -629,10 +728,13 @@ bool FilmstripFrameHeadGadget::eventFilter(QObject *obj, QEvent *e) { } //---- else if (e->type() == QEvent::MouseMove) { - QMouseEvent *mouseEvent = dynamic_cast(e); - int frame = y2index(mouseEvent->pos().y()); + QMouseEvent *mouseEvent = dynamic_cast(e); + int frame = y2index(mouseEvent->pos().y()); + if (!m_filmstrip->m_isVertical) frame = x2index(mouseEvent->pos().x()); //各フレーム左上からの位置 QPoint clickedPos = mouseEvent->pos() + QPoint(0, -index2y(frame)); + if (!m_filmstrip->m_isVertical) + clickedPos = mouseEvent->pos() + QPoint(-index2x(frame), 0); //カレントフレーム int currentFrame = getCurrentFrame(); //マウスボタンが押されていない場合 @@ -641,15 +743,22 @@ bool FilmstripFrameHeadGadget::eventFilter(QObject *obj, QEvent *e) { //それぞれのパーツの位置Rectの指定。各フレームの右上座標からのオフセットも含む。 // OnionSkinの円の左上座標のy値 int onionDotYPos = m_dy / 2 - 5; - // OnionSkinの●のRect + int onionDotXPos = m_dx / 2 - 5; + QRect onionDotRect(10, onionDotYPos, 10, 10); + if (!m_filmstrip->m_isVertical) + onionDotRect = QRect(onionDotXPos, 10, 10, 10); // FixedOnionSkinの●のRect QRect fixedOnionDotRect(0, onionDotYPos, 10, 10); + if (!m_filmstrip->m_isVertical) + fixedOnionDotRect = QRect(onionDotXPos, 0, 10, 10); //上方向のOnionSkinタブのRect QRect backOnionTabRect(0, m_dy - 15, 30, 15); + if (!m_filmstrip->m_isVertical) + backOnionTabRect = QRect(m_dx - 15, 0, 15, 30); //下方向のOnionSkinタブのRect QRect frontOnionTabRect(0, 0, 30, 15); - //----- + if (!m_filmstrip->m_isVertical) frontOnionTabRect = QRect(0, 0, 15, 30); //----- Fixed Onion Skin の ハイライト int highlightedFrame; @@ -737,9 +846,15 @@ bool FilmstripFrameHeadGadget::shiftTraceEventFilter(QObject *obj, QEvent *e) { const int shiftTraceDotSize = 12; const int shiftTraceDotXOffset = 3; + const int shiftTraceDotYOffset = 3; int dotYPos = (m_dy - shiftTraceDotSize) / 2; + int dotXPos = (m_dx - shiftTraceDotSize) / 2; QRect dotRect(shiftTraceDotXOffset, dotYPos, shiftTraceDotSize, shiftTraceDotSize); + if (!m_filmstrip->m_isVertical) { + dotRect = QRect(dotXPos, shiftTraceDotYOffset, shiftTraceDotSize, + shiftTraceDotSize); + } // reset highlight if (m_highlightedghostFrame >= 0) { @@ -747,14 +862,22 @@ bool FilmstripFrameHeadGadget::shiftTraceEventFilter(QObject *obj, QEvent *e) { viewer->update(); } - QMouseEvent *mouseEvent = dynamic_cast(e); - int frame = y2index(mouseEvent->pos().y()); + QMouseEvent *mouseEvent = dynamic_cast(e); + int frame = y2index(mouseEvent->pos().y()); + if (!m_filmstrip->m_isVertical) frame = x2index(mouseEvent->pos().x()); // position from top-left of the frame - QPoint mousePos = mouseEvent->pos() + QPoint(0, -index2y(frame)); + QPoint mousePos = mouseEvent->pos() + QPoint(0, -index2y(frame)); + if (!m_filmstrip->m_isVertical) + mousePos = mouseEvent->pos() + QPoint(-index2x(frame), 0); int currentFrame = getCurrentFrame(); - if (mousePos.x() < dotRect.left() || mousePos.x() > dotRect.right()) - return false; + if (m_filmstrip->m_isVertical) { + if (mousePos.x() < dotRect.left() || mousePos.x() > dotRect.right()) + return false; + } else { + if (mousePos.y() < dotRect.top() || mousePos.y() > dotRect.bottom()) + return false; + } if (e->type() == QEvent::MouseButtonPress) { if (frame == currentFrame) { diff --git a/toonz/sources/toonz/frameheadgadget.h b/toonz/sources/toonz/frameheadgadget.h index 9e4f8ae..a1c31c3 100644 --- a/toonz/sources/toonz/frameheadgadget.h +++ b/toonz/sources/toonz/frameheadgadget.h @@ -72,7 +72,7 @@ public: class FilmstripFrameHeadGadget final : public FrameHeadGadget { Q_OBJECT FilmstripFrames *m_filmstrip; - int m_dy; + int m_dy, m_dx; int m_highlightedghostFrame; public: @@ -82,6 +82,10 @@ public: int index2y(int index) const override; int y2index(int y) const override; + int getX() const; + int index2x(int index) const; + int x2index(int y) const; + void drawOnionSkinSelection(QPainter &p, const QColor &lightColor, const QColor &darkColor) override; diff --git a/toonz/sources/toonzqt/docklayout.cpp b/toonz/sources/toonzqt/docklayout.cpp index f0ccdac..65cd369 100644 --- a/toonz/sources/toonzqt/docklayout.cpp +++ b/toonz/sources/toonzqt/docklayout.cpp @@ -201,9 +201,9 @@ QSize DockLayout::maximumSize() const { QSize DockLayout::sizeHint() const { QSize s(0, 0); - int n = m_items.size(); + int n = m_items.size(); if (n > 0) s = QSize(100, 70); // start with a nice default size - int i = 0; + int i = 0; while (i < n) { QLayoutItem *o = m_items[i]; s = s.expandedTo(o->sizeHint()); @@ -424,7 +424,7 @@ void DockLayout::applyTransform(const QTransform &transform) { // check if the region will be with fixed width bool Region::checkWidgetsToBeFixedWidth(std::vector &widgets) { if (m_item) { - if (m_item->objectName() == "FilmStrip" || + if ( // m_item->objectName() == "FilmStrip" || m_item->objectName() == "StyleEditor") { widgets.push_back(m_item); return true; @@ -1498,7 +1498,7 @@ bool DockLayout::restoreState(const State &state) { } // Else, deallocate old regions and substitute with new ones - for (j = 0; j < m_regions.size(); ++j) delete m_regions[j]; + for (j = 0; j < m_regions.size(); ++j) delete m_regions[j]; m_regions = newHierarchy; // Now re-initialize dock widgets' infos.