diff --git a/toonz/sources/include/orientation.h b/toonz/sources/include/orientation.h
index 2b51735..ef37228 100644
--- a/toonz/sources/include/orientation.h
+++ b/toonz/sources/include/orientation.h
@@ -107,8 +107,10 @@ enum class PredefinedRect {
PEGBAR_NAME, //! where to display pegbar name
PARENT_HANDLE_NAME, //! where to display parent handle number
FILTER_COLOR, //! where to show layer's filter color
- CONFIG_AREA, //! clickable area larger than the config icon, containing it
- CONFIG //! the config icon itself
+ CONFIG_AREA, //! clickable area larger than the config icon, containing it
+ CONFIG, //! the config icon itself
+ FRAME_DOT, //! Cell's frame indicator
+ FRAME_INDICATOR //! Row # indicator
};
enum class PredefinedLine {
LOCKED, //! dotted vertical line when cell is locked
diff --git a/toonz/sources/include/toonzqt/spreadsheetviewer.h b/toonz/sources/include/toonzqt/spreadsheetviewer.h
index e49170b..4581e40 100644
--- a/toonz/sources/include/toonzqt/spreadsheetviewer.h
+++ b/toonz/sources/include/toonzqt/spreadsheetviewer.h
@@ -69,7 +69,7 @@ private:
void connectScrollbars();
void disconnectScrollbars();
- void handleScroll(const QPoint &offset) const;
+ void handleScroll(QPoint &offset);
void onScroll(const CellPositionRatio &offset);
void prepareToScrollRatio(const CellPositionRatio &offset);
@@ -79,6 +79,7 @@ private slots:
void onHScroll(int value);
signals:
void prepareToScrollOffset(const QPoint &offset);
+ void zoomScrollAdjust(QPoint &offset, bool toZoom);
};
//-------------------------------------------------------------------
diff --git a/toonz/sources/toonz/Resources/zoom_in.svg b/toonz/sources/toonz/Resources/zoom_in.svg
new file mode 100644
index 0000000..a4b7cf6
--- /dev/null
+++ b/toonz/sources/toonz/Resources/zoom_in.svg
@@ -0,0 +1,10 @@
+
+
+
diff --git a/toonz/sources/toonz/Resources/zoom_out.svg b/toonz/sources/toonz/Resources/zoom_out.svg
new file mode 100644
index 0000000..bf9edb8
--- /dev/null
+++ b/toonz/sources/toonz/Resources/zoom_out.svg
@@ -0,0 +1,9 @@
+
+
+
diff --git a/toonz/sources/toonz/toonz.qrc b/toonz/sources/toonz/toonz.qrc
index b76e317..be7026c 100644
--- a/toonz/sources/toonz/toonz.qrc
+++ b/toonz/sources/toonz/toonz.qrc
@@ -452,5 +452,7 @@
Resources/locator_over.svg
Resources/refresh.svg
Resources/refresh_over.svg
+ Resources/zoom_in.svg
+ Resources/zoom_out.svg
diff --git a/toonz/sources/toonz/xshcellviewer.cpp b/toonz/sources/toonz/xshcellviewer.cpp
index 6af036e..6eec2eb 100644
--- a/toonz/sources/toonz/xshcellviewer.cpp
+++ b/toonz/sources/toonz/xshcellviewer.cpp
@@ -1307,7 +1307,11 @@ void CellArea::drawSoundCell(QPainter &p, int row, int col, bool isReference) {
else
xy.setX(xy.x() + 1);
}
- QRect cellRect = o->rect(PredefinedRect::CELL).translated(QPoint(x, y));
+
+ int frameAdj = m_viewer->getFrameZoomAdjustment();
+ int frameZoomF = m_viewer->getFrameZoomFactor();
+ QRect cellRect = o->rect(PredefinedRect::CELL).translated(QPoint(x, y));
+ cellRect.adjust(0, 0, -frameAdj, 0);
QRect rect = cellRect.adjusted(1, 1, 0, 0);
int maxNumFrame = soundColumn->getMaxFrame() + 1;
int startFrame = soundColumn->getFirstRow();
@@ -1358,8 +1362,12 @@ void CellArea::drawSoundCell(QPainter &p, int row, int col, bool isReference) {
drawEndOfDragHandle(p, isLastRow, xy, cellColor);
drawLockedDottedLine(p, soundColumn->isLocked(), xy, cellColor);
- QRect trackRect = o->rect(PredefinedRect::SOUND_TRACK).translated(xy);
- QRect previewRect = o->rect(PredefinedRect::PREVIEW_TRACK).translated(xy);
+ QRect trackRect = o->rect(PredefinedRect::SOUND_TRACK)
+ .adjusted(0, 0, -frameAdj, 0)
+ .translated(xy);
+ QRect previewRect = o->rect(PredefinedRect::PREVIEW_TRACK)
+ .adjusted(0, 0, -frameAdj, 0)
+ .translated(xy);
NumberRange trackBounds = o->layerSide(trackRect);
NumberRange previewBounds = o->layerSide(previewRect);
NumberRange trackAndPreview(trackBounds.from(), previewBounds.to());
@@ -1367,10 +1375,10 @@ void CellArea::drawSoundCell(QPainter &p, int row, int col, bool isReference) {
NumberRange timeBounds = o->frameSide(trackRect);
int offset =
row - cell.getFrameId().getNumber(); // rows since start of the clip
- int begin = timeBounds.from(); // time axis
- int end = timeBounds.to();
- int soundPixel =
- begin - m_viewer->rowToFrameAxis(offset); // pixels since start of clip
+ int begin = timeBounds.from(); // time axis
+ int end = timeBounds.to();
+ int soundPixel = o->rowToFrameAxis(row) -
+ o->rowToFrameAxis(offset); // pixels since start of clip
int trackWidth = trackBounds.length();
int lastMin, lastMax;
@@ -1387,9 +1395,10 @@ void CellArea::drawSoundCell(QPainter &p, int row, int col, bool isReference) {
bool scrub = m_viewer->isScrubHighlighted(row, col);
int i;
+ int z = 100 / frameZoomF;
for (i = begin; i <= end; i++) {
soundLevel->getValueAtPixel(o, soundPixel, minmax);
- soundPixel++;
+ soundPixel += z; // ++;
int min, max;
pmin = minmax.first;
pmax = minmax.second;
@@ -1411,7 +1420,6 @@ void CellArea::drawSoundCell(QPainter &p, int row, int col, bool isReference) {
QLine stroke = o->horizontalLine(i, previewBounds.adjusted(-1, -1));
p.drawLine(stroke);
}
-
if (i != begin) {
// "audio track" in the middle of the column
p.setPen(m_viewer->getSoundColumnTrackColor());
@@ -1435,6 +1443,7 @@ void CellArea::drawSoundCell(QPainter &p, int row, int col, bool isReference) {
if (isFirstRow) {
QRect modifierRect = m_viewer->orientation()
->rect(PredefinedRect::BEGIN_SOUND_EDIT)
+ .adjusted(-frameAdj, 0, -frameAdj, 0)
.translated(xy);
if (r0 != r0WithoutOff) p.fillRect(modifierRect, SoundColumnExtenderColor);
m_soundLevelModifyRects.append(modifierRect); // list of clipping rects
@@ -1442,6 +1451,7 @@ void CellArea::drawSoundCell(QPainter &p, int row, int col, bool isReference) {
if (isLastRow) {
QRect modifierRect = m_viewer->orientation()
->rect(PredefinedRect::END_SOUND_EDIT)
+ .adjusted(-frameAdj, 0, -frameAdj, 0)
.translated(xy);
if (r1 != r1WithoutOff) p.fillRect(modifierRect, SoundColumnExtenderColor);
m_soundLevelModifyRects.append(modifierRect);
@@ -1453,8 +1463,10 @@ void CellArea::drawSoundCell(QPainter &p, int row, int col, bool isReference) {
// paint side bar
void CellArea::drawDragHandle(QPainter &p, const QPoint &xy,
const QColor &sideColor) const {
+ int frameAdj = m_viewer->getFrameZoomAdjustment();
QRect dragHandleRect = m_viewer->orientation()
->rect(PredefinedRect::DRAG_HANDLE_CORNER)
+ .adjusted(0, 0, -frameAdj, 0)
.translated(xy);
p.fillRect(dragHandleRect, QBrush(sideColor));
}
@@ -1463,9 +1475,10 @@ void CellArea::drawDragHandle(QPainter &p, const QPoint &xy,
void CellArea::drawEndOfDragHandle(QPainter &p, bool isEnd, const QPoint &xy,
const QColor &cellColor) const {
if (!isEnd) return;
+ int frameAdj = m_viewer->getFrameZoomAdjustment();
QPainterPath corner = m_viewer->orientation()
->path(PredefinedPath::DRAG_HANDLE_CORNER)
- .translated(xy);
+ .translated(xy - QPoint(frameAdj, 0));
p.fillPath(corner, QBrush(cellColor));
}
@@ -1475,16 +1488,20 @@ void CellArea::drawLockedDottedLine(QPainter &p, bool isLocked,
const QColor &cellColor) const {
if (!isLocked) return;
p.setPen(QPen(cellColor, 2, Qt::DotLine));
+ int frameAdj = m_viewer->getFrameZoomAdjustment();
QLine dottedLine =
m_viewer->orientation()->line(PredefinedLine::LOCKED).translated(xy);
+ dottedLine.setP2(QPoint(dottedLine.x2() - frameAdj, dottedLine.y2()));
p.drawLine(dottedLine);
}
void CellArea::drawCurrentTimeIndicator(QPainter &p, const QPoint &xy) {
+ int frameAdj = m_viewer->getFrameZoomAdjustment();
QRect cell =
m_viewer->orientation()->rect(PredefinedRect::CELL).translated(xy);
+ cell.adjust(-frameAdj / 2, 0, -frameAdj / 2, 0);
- int cellMid = cell.left() + (cell.width() / 2);
+ int cellMid = cell.left() + (cell.width() / 2) - 1;
int cellTop = cell.top();
int cellBottom = cell.bottom();
@@ -1530,8 +1547,10 @@ void CellArea::drawLevelCell(QPainter &p, int row, int col, bool isReference) {
TXshCell nextCell;
nextCell = xsh->getCell(row + 1, col); // cell in next frame
+ int frameAdj = m_viewer->getFrameZoomAdjustment();
QRect cellRect = o->rect(PredefinedRect::CELL).translated(QPoint(x, y));
- QRect rect = cellRect.adjusted(1, 1, 0, 0);
+ cellRect.adjust(0, 0, -frameAdj, 0);
+ QRect rect = cellRect.adjusted(1, 1, 0, 0);
if (cell.isEmpty()) { // it means previous is not empty
// diagonal cross meaning end of level
QColor levelEndColor = m_viewer->getTextColor();
@@ -1623,6 +1642,8 @@ void CellArea::drawLevelCell(QPainter &p, int row, int col, bool isReference) {
.translated(QPoint(x, y));
}
+ nameRect.adjust(0, 0, -frameAdj, 0);
+
// draw text in red if the file does not exist
bool isRed = false;
TXshSimpleLevel *sl = cell.getSimpleLevel();
@@ -1660,10 +1681,23 @@ void CellArea::drawLevelCell(QPainter &p, int row, int col, bool isReference) {
: PredefinedLine::CONTINUE_LEVEL;
QLine continueLine = o->line(which).translated(xy);
+ continueLine.setP2(QPoint(continueLine.x2() - frameAdj, continueLine.y2()));
p.drawLine(continueLine);
}
// draw frame number
else {
+ if (m_viewer->getFrameZoomFactor() <= 50) {
+ p.setPen(Qt::black);
+ p.setBrush(isRed ? QColor(230, 100, 100) : m_viewer->getTextColor());
+ QRect dotRect = m_viewer->orientation()
+ ->rect(PredefinedRect::FRAME_DOT)
+ .translated(QPoint(x, y));
+ dotRect.adjust(-frameAdj / 2, 0, -frameAdj / 2, 0);
+ p.drawEllipse(dotRect);
+ p.setBrush(Qt::NoBrush);
+ return;
+ }
+
TFrameId fid = cell.m_frameId;
// convert the last one digit of the frame number to alphabet
@@ -1738,8 +1772,10 @@ void CellArea::drawSoundTextCell(QPainter &p, int row, int col) {
TXshCell nextCell;
nextCell = xsh->getCell(row + 1, col);
+ int frameAdj = m_viewer->getFrameZoomAdjustment();
QRect cellRect = o->rect(PredefinedRect::CELL).translated(QPoint(x, y));
- QRect rect = cellRect.adjusted(1, 1, 0, 0);
+ cellRect.adjust(0, 0, -frameAdj, 0);
+ QRect rect = cellRect.adjusted(1, 1, 0, 0);
if (cell.isEmpty()) { // diagonal cross meaning end of level
QColor levelEndColor = m_viewer->getTextColor();
levelEndColor.setAlphaF(0.3);
@@ -1795,6 +1831,7 @@ void CellArea::drawSoundTextCell(QPainter &p, int row, int col) {
p.setPen(Qt::black);
QRect nameRect = o->rect(PredefinedRect::CELL_NAME).translated(QPoint(x, y));
+ nameRect.adjust(0, 0, -frameAdj, 0);
// il nome va scritto se e' diverso dalla cella precedente oppure se
// siamo su una marker line
@@ -1819,6 +1856,7 @@ void CellArea::drawSoundTextCell(QPainter &p, int row, int col) {
? PredefinedLine::CONTINUE_LEVEL_WITH_NAME
: PredefinedLine::CONTINUE_LEVEL;
QLine continueLine = o->line(which).translated(xy);
+ continueLine.setP2(QPoint(continueLine.x2() - frameAdj, continueLine.y2()));
p.drawLine(continueLine);
}
@@ -1870,8 +1908,11 @@ void CellArea::drawPaletteCell(QPainter &p, int row, int col,
return;
}
+
+ int frameAdj = m_viewer->getFrameZoomAdjustment();
QRect cellRect = o->rect(PredefinedRect::CELL).translated(QPoint(x, y));
- QRect rect = cellRect.adjusted(1, 1, 0, 0);
+ cellRect.adjust(0, 0, -frameAdj, 0);
+ QRect rect = cellRect.adjusted(1, 1, 0, 0);
if (cell.isEmpty()) { // this means the former is not empty
QColor levelEndColor = m_viewer->getTextColor();
levelEndColor.setAlphaF(0.3);
@@ -1932,6 +1973,7 @@ void CellArea::drawPaletteCell(QPainter &p, int row, int col,
QPen oldPen = p.pen();
p.setPen(QPen(m_viewer->getTextColor(), 1));
QLine continueLine = o->line(PredefinedLine::CONTINUE_LEVEL).translated(xy);
+ continueLine.setP2(QPoint(continueLine.x2() - frameAdj, continueLine.y2()));
p.drawLine(continueLine);
p.setPen(oldPen);
} else {
@@ -1953,6 +1995,7 @@ void CellArea::drawPaletteCell(QPainter &p, int row, int col,
.translated(QPoint(x, y));
}
+ nameRect.adjust(0, 0, -frameAdj, 0);
bool isRed = false;
TXshPaletteLevel *pl = cell.getPaletteLevel();
if (pl && !pl->getPalette()) isRed = true;
@@ -2021,7 +2064,9 @@ void CellArea::drawKeyframe(QPainter &p, const QRect toBeUpdated) {
static QPixmap selectedKey = svgToPixmap(":Resources/selected_key.svg");
static QPixmap key = svgToPixmap(":Resources/key.svg");
- const QRect &keyRect = o->rect(PredefinedRect::KEY_ICON);
+ int frameAdj = m_viewer->getFrameZoomAdjustment();
+ const QRect &keyRect = o->rect(PredefinedRect::KEY_ICON)
+ .adjusted(-frameAdj / 2, 0, -frameAdj / 2, 0);
TXsheet *xsh = m_viewer->getXsheet();
ColumnFan *columnFan = xsh->getColumnFan(o);
@@ -2057,13 +2102,16 @@ void CellArea::drawKeyframe(QPainter &p, const QRect toBeUpdated) {
int handleRow0, handleRow1;
if (getEaseHandles(segmentRow0, segmentRow1, ease0, ease1, handleRow0,
handleRow1)) {
+ QPoint topLeft =
+ m_viewer->positionToXY(CellPosition(handleRow0, col));
m_viewer->drawPredefinedPath(p, PredefinedPath::BEGIN_EASE_TRIANGLE,
- CellPosition(handleRow0, col),
+ topLeft + QPoint(-frameAdj / 2, 0),
m_viewer->getLightLineColor(),
m_viewer->getTextColor());
+ topLeft = m_viewer->positionToXY(CellPosition(handleRow1, col));
m_viewer->drawPredefinedPath(p, PredefinedPath::END_EASE_TRIANGLE,
- CellPosition(handleRow1, col),
+ topLeft + QPoint(-frameAdj / 2, 0),
m_viewer->getLightLineColor(),
m_viewer->getTextColor());
}
@@ -2138,8 +2186,10 @@ void CellArea::drawKeyframe(QPainter &p, const QRect toBeUpdated) {
void CellArea::drawKeyframeLine(QPainter &p, int col,
const NumberRange &rows) const {
- const QRect &keyRect =
- m_viewer->orientation()->rect(PredefinedRect::KEY_ICON);
+ int frameAdj = m_viewer->getFrameZoomAdjustment();
+ const QRect &keyRect = m_viewer->orientation()
+ ->rect(PredefinedRect::KEY_ICON)
+ .adjusted(-frameAdj / 2, 0, -frameAdj / 2, 0);
QPoint begin =
keyRect.center() + m_viewer->positionToXY(CellPosition(rows.from(), col));
QPoint end =
@@ -2247,13 +2297,14 @@ void CellArea::paintEvent(QPaintEvent *event) {
if (getDragTool()) getDragTool()->drawCellsArea(p);
// focus cell border
- int row = m_viewer->getCurrentRow();
- int col = m_viewer->getCurrentColumn();
- QPoint xy = m_viewer->positionToXY(CellPosition(row, col));
- QRect rect = m_viewer->orientation()
+ int frameAdj = m_viewer->getFrameZoomAdjustment();
+ int row = m_viewer->getCurrentRow();
+ int col = m_viewer->getCurrentColumn();
+ QPoint xy = m_viewer->positionToXY(CellPosition(row, col));
+ QRect rect = m_viewer->orientation()
->rect(PredefinedRect::CELL)
.translated(xy)
- .adjusted(1, 1, -1, -1);
+ .adjusted(1, 1, -1 - frameAdj, -1);
p.setPen(Qt::black);
p.setBrush(Qt::NoBrush);
p.drawRect(rect);
@@ -2290,6 +2341,7 @@ void CellArea::mousePressEvent(QMouseEvent *event) {
m_viewer->setQtModifiers(event->modifiers());
assert(!m_isPanning);
m_isMousePressed = true;
+ int frameAdj = m_viewer->getFrameZoomAdjustment();
if (event->button() == Qt::LeftButton) {
assert(getDragTool() == 0);
@@ -2353,10 +2405,12 @@ void CellArea::mousePressEvent(QMouseEvent *event) {
bool isKeyframeFrame = pegbar && pegbar->getKeyframeRange(k0, k1) &&
(k1 > k0 || k0 == row) && k0 <= row &&
row <= k1 + 1;
- bool isKeyFrameArea =
- isKeyframeFrame &&
- o->rect(PredefinedRect::KEYFRAME_AREA).contains(mouseInCell) &&
- row < k1 + 1;
+
+ bool isKeyFrameArea = isKeyframeFrame &&
+ o->rect(PredefinedRect::KEYFRAME_AREA)
+ .adjusted(-frameAdj / 2, 0, -frameAdj / 2, 0)
+ .contains(mouseInCell) &&
+ row < k1 + 1;
bool accept = false;
if (isKeyFrameArea) { // They are in the keyframe selection
@@ -2455,6 +2509,7 @@ void CellArea::mousePressEvent(QMouseEvent *event) {
void CellArea::mouseMoveEvent(QMouseEvent *event) {
const Orientation *o = m_viewer->orientation();
+ int frameAdj = m_viewer->getFrameZoomAdjustment();
m_viewer->setQtModifiers(event->modifiers());
setCursor(Qt::ArrowCursor);
@@ -2538,8 +2593,8 @@ void CellArea::mouseMoveEvent(QMouseEvent *event) {
->getZeraryColumnFx()
->getZeraryFx()
->getName());
- else if ((!xsh->getCell(row, col).isEmpty() && !isSoundColumn) && x > 6 &&
- x < o->cellWidth()) {
+ else if ((!xsh->getCell(row, col).isEmpty() && !isSoundColumn) && // x > 6 &&
+ x < (o->cellWidth() - frameAdj)) {
TXshCell cell = xsh->getCell(row, col);
TFrameId fid = cell.getFrameId();
std::wstring levelName = cell.m_level->getName();
diff --git a/toonz/sources/toonz/xsheetviewer.cpp b/toonz/sources/toonz/xsheetviewer.cpp
index df49b3f..ba18fb7 100644
--- a/toonz/sources/toonz/xsheetviewer.cpp
+++ b/toonz/sources/toonz/xsheetviewer.cpp
@@ -48,11 +48,11 @@ TEnv::IntVar FrameDisplayStyleInXsheetRowArea(
namespace XsheetGUI {
//-----------------------------------------------------------------------------
-const int ColumnWidth = 74;
-const int RowHeight = 20;
-const int SCROLLBAR_WIDTH = 16;
-const int TOOLBAR_HEIGHT = 30;
-
+const int ColumnWidth = 74;
+const int RowHeight = 20;
+const int SCROLLBAR_WIDTH = 16;
+const int TOOLBAR_HEIGHT = 30;
+const int ZOOM_SLIDER_WIDTH = 80;
} // namespace XsheetGUI
//=============================================================================
@@ -217,7 +217,8 @@ XsheetViewer::XsheetViewer(QWidget *parent, Qt::WFlags flags)
, m_qtModifiers(0)
, m_frameDisplayStyle(to_enum(FrameDisplayStyleInXsheetRowArea))
, m_orientation(nullptr)
- , m_xsheetLayout("Classic") {
+ , m_xsheetLayout("Classic")
+ , m_frameZoomFactor(100) {
m_xsheetLayout = Preferences::instance()->getLoadedXsheetLayout();
@@ -269,6 +270,14 @@ XsheetViewer::XsheetViewer(QWidget *parent, Qt::WFlags flags)
m_frameScroller.setFrameScrollArea(m_cellScrollArea);
connect(&m_frameScroller, &Spreadsheet::FrameScroller::prepareToScrollOffset,
this, &XsheetViewer::onPrepareToScrollOffset);
+ connect(&m_frameScroller, &Spreadsheet::FrameScroller::zoomScrollAdjust, this,
+ &XsheetViewer::onZoomScrollAdjust);
+
+ m_frameZoomSlider = new QSlider(Qt::Horizontal, this);
+ m_frameZoomSlider->setMinimum(20);
+ m_frameZoomSlider->setMaximum(100);
+ m_frameZoomSlider->setValue(m_frameZoomFactor);
+ m_frameZoomSlider->setToolTip(tr("Zoom in/out of timeline"));
connectScrollBars();
@@ -277,6 +286,11 @@ XsheetViewer::XsheetViewer(QWidget *parent, Qt::WFlags flags)
connect(m_toolbar, SIGNAL(updateVisibility()), this,
SLOT(positionSections()));
+ connect(m_frameZoomSlider, SIGNAL(sliderReleased()), this,
+ SLOT(onFrameZoomSliderReleased()));
+ connect(m_frameZoomSlider, SIGNAL(valueChanged(int)), this,
+ SLOT(onFrameZoomSliderValueChanged(int)));
+
emit orientationChanged(orientation());
}
@@ -397,6 +411,18 @@ void XsheetViewer::positionSections() {
bodyLayer.adjusted(0, -XsheetGUI::SCROLLBAR_WIDTH)));
m_rowScrollArea->setGeometry(o->frameLayerRect(
bodyFrame.adjusted(0, -XsheetGUI::SCROLLBAR_WIDTH), headerLayer));
+ if (o->isVerticalTimeline())
+ m_frameZoomSlider->hide();
+ else {
+ if (m_frameZoomSlider->isHidden()) m_frameZoomSlider->show();
+ QRect sliderRect =
+ QRect(0, 0, XsheetGUI::ZOOM_SLIDER_WIDTH,
+ XsheetGUI::SCROLLBAR_WIDTH - 2)
+ .translated(m_columnScrollArea->rect().right() -
+ XsheetGUI::ZOOM_SLIDER_WIDTH - 17,
+ height() - XsheetGUI::SCROLLBAR_WIDTH + 1);
+ m_frameZoomSlider->setGeometry(sliderRect);
+ }
}
void XsheetViewer::disconnectScrollBars() {
@@ -540,6 +566,12 @@ void XsheetViewer::scroll(QPoint delta) {
else if (!notUpdateSizeH && notUpdateSizeV) // Resize orizzontale
refreshContentSize(x, 0);
+ // Recheck in case refreshContentSize changed the max
+ if (!notUpdateSizeH)
+ maxValueH = m_cellScrollArea->horizontalScrollBar()->maximum();
+ if (!notUpdateSizeV)
+ maxValueV = m_cellScrollArea->verticalScrollBar()->maximum();
+
if (valueH > maxValueH && x > 0) // Se il valore e' maggiore del max e x>0
// scrollo al massimo valore orizzontale
valueH = m_cellScrollArea->horizontalScrollBar()->maximum();
@@ -560,6 +592,22 @@ void XsheetViewer::onPrepareToScrollOffset(const QPoint &offset) {
//-----------------------------------------------------------------------------
+void XsheetViewer::onZoomScrollAdjust(QPoint &offset, bool toZoom) {
+ int frameZoomFactor = getFrameZoomFactor();
+
+ // toZoom = true: Adjust standardized offset down to zoom factor
+ // toZoom = false: Adjust zoomed offset up to standardized offset
+ int newX;
+ if (toZoom)
+ newX = (offset.x() * frameZoomFactor) / 100;
+ else
+ newX = (offset.x() * 100) / frameZoomFactor;
+
+ offset.setX(newX);
+}
+
+//-----------------------------------------------------------------------------
+
void XsheetViewer::setAutoPanSpeed(const QPoint &speed) {
bool wasAutoPanning = isAutoPanning();
m_autoPanSpeed = speed;
@@ -679,7 +727,10 @@ void XsheetViewer::updateAreeSize() {
CellPosition XsheetViewer::xyToPosition(const QPoint &point) const {
const Orientation *o = orientation();
- return o->xyToPosition(point, getXsheet()->getColumnFan(o));
+ QPoint usePoint = point;
+ if (!o->isVerticalTimeline())
+ usePoint.setX((usePoint.x() * 100) / getFrameZoomFactor());
+ return o->xyToPosition(usePoint, getXsheet()->getColumnFan(o));
}
CellPosition XsheetViewer::xyToPosition(const TPoint &point) const {
return xyToPosition(QPoint(point.x, point.y));
@@ -692,7 +743,10 @@ CellPosition XsheetViewer::xyToPosition(const TPointD &point) const {
QPoint XsheetViewer::positionToXY(const CellPosition &pos) const {
const Orientation *o = orientation();
- return o->positionToXY(pos, getXsheet()->getColumnFan(o));
+ QPoint result = o->positionToXY(pos, getXsheet()->getColumnFan(o));
+ if (!o->isVerticalTimeline())
+ result.setX((result.x() * getFrameZoomFactor()) / 100);
+ return result;
}
int XsheetViewer::columnToLayerAxis(int layer) const {
@@ -700,7 +754,10 @@ int XsheetViewer::columnToLayerAxis(int layer) const {
return o->colToLayerAxis(layer, getXsheet()->getColumnFan(o));
}
int XsheetViewer::rowToFrameAxis(int frame) const {
- return orientation()->rowToFrameAxis(frame);
+ int result = orientation()->rowToFrameAxis(frame);
+ if (!orientation()->isVerticalTimeline())
+ result = (result * getFrameZoomFactor()) / 100;
+ return result;
}
//-----------------------------------------------------------------------------
@@ -738,6 +795,19 @@ void XsheetViewer::drawPredefinedPath(QPainter &p, PredefinedPath which,
//-----------------------------------------------------------------------------
+void XsheetViewer::drawPredefinedPath(QPainter &p, PredefinedPath which,
+ QPoint xy, optional fill,
+ optional outline) const {
+ QPainterPath path = orientation()->path(which).translated(xy);
+ if (fill) p.fillPath(path, QBrush(*fill));
+ if (outline) {
+ p.setPen(*outline);
+ p.drawPath(path);
+ }
+}
+
+//-----------------------------------------------------------------------------
+
bool XsheetViewer::areCellsSelectedEmpty() {
int r0, c0, r1, c1;
getCellSelection()->getSelectedCells(r0, c0, r1, c1);
@@ -918,12 +988,20 @@ void XsheetViewer::hideEvent(QHideEvent *) {
//-----------------------------------------------------------------------------
-/*
-void XsheetViewer::paintEvent(QPaintEvent*)
-{
+void XsheetViewer::paintEvent(QPaintEvent *) {
QPainter p(this);
- //p.fillRect(visibleRegion().boundingRect().adjusted(1,1,-1,-1),QBrush(grey150));
-}*/
+
+ static QPixmap zoomIn = svgToPixmap(":Resources/zoom_in.svg");
+ const QRect zoomInRect = QRect(m_frameZoomSlider->geometry().right() + 2,
+ m_frameZoomSlider->geometry().top(), 14, 14);
+ static QPixmap zoomOut = svgToPixmap(":Resources/zoom_out.svg");
+ const QRect zoomOutRect = QRect(m_frameZoomSlider->geometry().left() - 16,
+ m_frameZoomSlider->geometry().top(), 14, 14);
+
+ p.setRenderHint(QPainter::SmoothPixmapTransform, true);
+ p.drawPixmap(zoomInRect, zoomIn);
+ p.drawPixmap(zoomOutRect, zoomOut);
+}
//-----------------------------------------------------------------------------
@@ -942,6 +1020,25 @@ void XsheetViewer::resizeEvent(QResizeEvent *event) {
void XsheetViewer::wheelEvent(QWheelEvent *event) {
switch (event->source()) {
case Qt::MouseEventNotSynthesized: {
+ if (0 != (event->modifiers() & Qt::ControlModifier) &&
+ event->angleDelta().y() != 0) {
+ QPoint pos(event->pos().x() - m_columnArea->geometry().width() +
+ m_cellArea->visibleRegion().boundingRect().left(),
+ event->pos().y());
+ int targetFrame = xyToPosition(pos).frame();
+
+ int newFactor =
+ getFrameZoomFactor() + ((event->angleDelta().y() > 0 ? 1 : -1) * 10);
+ if (newFactor > m_frameZoomSlider->maximum())
+ newFactor = m_frameZoomSlider->maximum();
+ else if (newFactor < m_frameZoomSlider->minimum())
+ newFactor = m_frameZoomSlider->minimum();
+
+ zoomOnFrame(targetFrame, newFactor);
+ event->accept();
+ return;
+ }
+
int markerDistance = 6, markerOffset = 0;
TApp::instance()
->getCurrentScene()
@@ -1512,13 +1609,20 @@ void XsheetViewer::setFrameDisplayStyle(FrameDisplayStyle style) {
void XsheetViewer::save(QSettings &settings) const {
settings.setValue("orientation", orientation()->name());
+ settings.setValue("frameZoomFactor", m_frameZoomFactor);
}
void XsheetViewer::load(QSettings &settings) {
- QVariant name = settings.value("orientation");
- if (!name.canConvert(QVariant::String)) return;
+ QVariant zoomFactor = settings.value("frameZoomFactor");
+ QVariant name = settings.value("orientation");
- m_orientation = Orientations::byName(name.toString());
- emit orientationChanged(orientation());
+ if (zoomFactor.canConvert(QVariant::Int)) {
+ m_frameZoomSlider->setValue(zoomFactor.toInt());
+ }
+
+ if (name.canConvert(QVariant::String)) {
+ m_orientation = Orientations::byName(name.toString());
+ emit orientationChanged(orientation());
+ }
}
//-----------------------------------------------------------------------------
@@ -1532,6 +1636,49 @@ TPanel *createXsheetViewer(QWidget *parent)
}
*/
+//----------------------------------------------------------------
+int XsheetViewer::getFrameZoomFactor() const {
+ if (orientation()->isVerticalTimeline()) return 100;
+
+ return m_frameZoomFactor;
+}
+
+int XsheetViewer::getFrameZoomAdjustment() {
+ if (orientation()->isVerticalTimeline()) return 0;
+
+ QRect frameRect = orientation()->rect(PredefinedRect::FRAME_HEADER);
+ int adj = frameRect.width() -
+ ((frameRect.width() * getFrameZoomFactor()) / 100) - 1;
+
+ return qMax(0, adj);
+}
+
+void XsheetViewer::zoomOnFrame(int frame, int factor) {
+ QPoint xyOrig = positionToXY(CellPosition(frame, 0));
+
+ m_frameZoomFactor = factor;
+ m_frameZoomSlider->blockSignals(true);
+ m_frameZoomSlider->setValue(factor);
+ m_frameZoomSlider->blockSignals(false);
+
+ QPoint xyNew = positionToXY(CellPosition(frame, 0));
+
+ int viewShift = xyNew.x() - xyOrig.x();
+
+ scroll(QPoint(viewShift, 0));
+
+ onFrameZoomSliderReleased();
+}
+
+void XsheetViewer::onFrameZoomSliderValueChanged(int val) {
+ zoomOnFrame(getCurrentRow(), val);
+}
+
+void XsheetViewer::onFrameZoomSliderReleased() {
+ TApp::instance()->getCurrentXsheet()->notifyXsheetChanged();
+ m_rowArea->update();
+}
+
//=============================================================================
// XSheetViewerCommand
//-----------------------------------------------------------------------------
diff --git a/toonz/sources/toonz/xsheetviewer.h b/toonz/sources/toonz/xsheetviewer.h
index 4cd2852..65cff19 100644
--- a/toonz/sources/toonz/xsheetviewer.h
+++ b/toonz/sources/toonz/xsheetviewer.h
@@ -525,6 +525,9 @@ class XsheetViewer final : public QFrame, public SaveLoadQSettings {
QString m_xsheetLayout;
+ int m_frameZoomFactor;
+ QSlider *m_frameZoomSlider;
+
public:
enum FrameDisplayStyle { Frame = 0, SecAndFrame, SixSecSheet, ThreeSecSheet };
@@ -624,6 +627,11 @@ public:
void drawPredefinedPath(QPainter &p, PredefinedPath which,
const CellPosition &pos, optional fill,
optional outline) const;
+
+ void drawPredefinedPath(QPainter &p, PredefinedPath which, QPoint xy,
+ optional fill,
+ optional outline) const;
+
//---------
void updateCells() { m_cellArea->update(m_cellArea->visibleRegion()); }
@@ -1085,6 +1093,8 @@ protected:
void scrollToRow(int row);
void scrollToVerticalRange(int y0, int y1);
+ void paintEvent(QPaintEvent *) override;
+
void showEvent(QShowEvent *) override;
void hideEvent(QHideEvent *) override;
void resizeEvent(QResizeEvent *event) override;
@@ -1128,6 +1138,16 @@ public slots:
void onOrientationChanged(const Orientation *newOrientation);
void onPrepareToScrollOffset(const QPoint &offset);
+ void onZoomScrollAdjust(QPoint &offset, bool toZoom);
+
+ void setFrameZoomFactor(int f) { m_frameZoomFactor = f; }
+ int getFrameZoomFactor() const;
+ int getFrameZoomAdjustment();
+
+ void zoomOnFrame(int frame, int factor);
+
+ void onFrameZoomSliderValueChanged(int val);
+ void onFrameZoomSliderReleased();
};
#endif // XSHEETVIEWER_H
diff --git a/toonz/sources/toonz/xshrowviewer.cpp b/toonz/sources/toonz/xshrowviewer.cpp
index 14ac76e..73c9e95 100644
--- a/toonz/sources/toonz/xshrowviewer.cpp
+++ b/toonz/sources/toonz/xshrowviewer.cpp
@@ -78,6 +78,7 @@ void RowArea::setDragTool(DragTool *dragTool) {
//-----------------------------------------------------------------------------
void RowArea::drawRows(QPainter &p, int r0, int r1) {
+ const Orientation *o = m_viewer->orientation();
int playR0, playR1, step;
XsheetGUI::getPlayRange(playR0, playR1, step);
@@ -115,7 +116,9 @@ void RowArea::drawRows(QPainter &p, int r0, int r1) {
int x1 = visibleRect.right();
int y0 = visibleRect.top();
int y1 = visibleRect.bottom();
- NumberRange layerSide = m_viewer->orientation()->layerSide(visibleRect);
+ NumberRange layerSide = o->layerSide(visibleRect);
+
+ int frameAdj = m_viewer->getFrameZoomAdjustment();
for (int r = r0; r <= r1; r++) {
int frameAxis = m_viewer->rowToFrameAxis(r);
@@ -125,10 +128,29 @@ void RowArea::drawRows(QPainter &p, int r0, int r1) {
? m_viewer->getMarkerLineColor()
: m_viewer->getLightLineColor();
p.setPen(color);
- QLine horizontalLine =
- m_viewer->orientation()->horizontalLine(frameAxis, layerSide);
+ QLine horizontalLine = o->horizontalLine(frameAxis, layerSide);
p.drawLine(horizontalLine);
+ if (!o->isVerticalTimeline() && m_viewer->getFrameZoomFactor() <= 50) {
+ QPoint basePoint = m_viewer->positionToXY(CellPosition(r, 0));
+ QRect indRect =
+ o->rect(PredefinedRect::FRAME_INDICATOR).translated(basePoint);
+ indRect.adjust(-frameAdj / 2, 0, -frameAdj / 2, 0);
+ QColor useColor;
+ if (playR0 <= r && r <= playR1) {
+ useColor = ((r - m_r0) % step == 0)
+ ? m_viewer->getPreviewFrameTextColor()
+ : m_viewer->getTextColor();
+ }
+ // not in preview range
+ else
+ useColor = m_viewer->getTextColor();
+ p.fillRect(indRect, useColor);
+ }
+ }
+
+ int z = 0;
+ for (int r = r0; r <= r1; r++) {
// draw frame text
if (playR0 <= r && r <= playR1) {
p.setPen(((r - m_r0) % step == 0) ? m_viewer->getPreviewFrameTextColor()
@@ -139,12 +161,13 @@ void RowArea::drawRows(QPainter &p, int r0, int r1) {
p.setPen(m_viewer->getTextColor());
QPoint basePoint = m_viewer->positionToXY(CellPosition(r, 0));
- QRect labelRect = m_viewer->orientation()
- ->rect(PredefinedRect::FRAME_LABEL)
- .translated(basePoint);
- int align = m_viewer->orientation()->dimension(
- PredefinedDimension::FRAME_LABEL_ALIGN);
+ QRect labelRect =
+ o->rect(PredefinedRect::FRAME_LABEL).translated(basePoint);
+ labelRect.adjust(-frameAdj / 2, 0, -frameAdj / 2, 0);
+
+ int align = o->dimension(PredefinedDimension::FRAME_LABEL_ALIGN);
// display time and/or frame number
+ z++;
switch (m_viewer->getFrameDisplayStyle()) {
case XsheetViewer::SecAndFrame: {
int frameRate = TApp::instance()
@@ -153,6 +176,8 @@ void RowArea::drawRows(QPainter &p, int r0, int r1) {
->getProperties()
->getOutputProperties()
->getFrameRate();
+ int zz = frameRate / 5;
+ zz = frameRate / zz;
QString str;
int koma = (r + 1) % frameRate;
if (koma == 1) {
@@ -160,7 +185,12 @@ void RowArea::drawRows(QPainter &p, int r0, int r1) {
str = QString("%1' %2\"")
.arg(QString::number(sec).rightJustified(2, '0'))
.arg(QString::number(koma).rightJustified(2, '0'));
+ z = 0;
} else {
+ if (!o->isVerticalTimeline() && m_viewer->getFrameZoomFactor() <= 50) {
+ if ((z + 1) % zz) break;
+ if (r % frameRate == 1 || (r + 2) % frameRate == 1) break;
+ }
if (koma == 0) koma = frameRate;
str = QString("%1\"").arg(QString::number(koma).rightJustified(2, '0'));
}
@@ -171,6 +201,9 @@ void RowArea::drawRows(QPainter &p, int r0, int r1) {
}
case XsheetViewer::Frame: {
+ if (!o->isVerticalTimeline() && m_viewer->getFrameZoomFactor() <= 50 &&
+ r > 0 && (r + 1) % 5)
+ break;
QString number = QString::number(r + 1);
p.drawText(labelRect, align, number);
break;
@@ -184,6 +217,8 @@ void RowArea::drawRows(QPainter &p, int r0, int r1) {
->getProperties()
->getOutputProperties()
->getFrameRate();
+ int zz = frameRate / 5;
+ zz = frameRate / zz;
QString str;
int koma = (r + 1) % (frameRate * 6);
if ((r + 1) % frameRate == 1) {
@@ -191,7 +226,12 @@ void RowArea::drawRows(QPainter &p, int r0, int r1) {
str = QString("p%1 %2")
.arg(QString::number(page))
.arg(QString::number(koma).rightJustified(3, '0'));
+ z = 0;
} else {
+ if (!o->isVerticalTimeline() && m_viewer->getFrameZoomFactor() <= 50) {
+ if ((z + 1) % zz) break;
+ if (r % frameRate == 1 || (r + 2) % frameRate == 1) break;
+ }
if (koma == 0) koma = frameRate * 6;
str = QString("%1").arg(QString::number(koma).rightJustified(3, '0'));
}
@@ -206,6 +246,8 @@ void RowArea::drawRows(QPainter &p, int r0, int r1) {
->getProperties()
->getOutputProperties()
->getFrameRate();
+ int zz = frameRate / 5;
+ zz = frameRate / zz;
QString str;
int koma = (r + 1) % (frameRate * 3);
if ((r + 1) % frameRate == 1) {
@@ -213,7 +255,12 @@ void RowArea::drawRows(QPainter &p, int r0, int r1) {
str = QString("p%1 %2")
.arg(QString::number(page))
.arg(QString::number(koma).rightJustified(2, '0'));
+ z = 0;
} else {
+ if (!o->isVerticalTimeline() && m_viewer->getFrameZoomFactor() <= 50) {
+ if ((z + 1) % zz) break;
+ if (r % frameRate == 1 || (r + 2) % frameRate == 1) break;
+ }
if (koma == 0) koma = frameRate * 3;
str = QString("%1").arg(QString::number(koma).rightJustified(2, '0'));
}
@@ -228,6 +275,7 @@ void RowArea::drawRows(QPainter &p, int r0, int r1) {
void RowArea::drawPlayRange(QPainter &p, int r0, int r1) {
bool playRangeEnabled = XsheetGUI::isPlayRangeEnabled();
+ int frameAdj = m_viewer->getFrameZoomAdjustment();
// Update the play range internal fields
if (playRangeEnabled) {
@@ -246,15 +294,18 @@ void RowArea::drawPlayRange(QPainter &p, int r0, int r1) {
QColor ArrowColor = (playRangeEnabled) ? QColor(255, 255, 255) : grey150;
p.setBrush(QBrush(ArrowColor));
- if (m_r0 > r0 - 1 && r1 + 1 > m_r0)
- m_viewer->drawPredefinedPath(p, PredefinedPath::BEGIN_PLAY_RANGE,
- CellPosition(m_r0, 0), ArrowColor,
- QColor(Qt::black));
+ if (m_r0 > r0 - 1 && r1 + 1 > m_r0) {
+ QPoint topLeft = m_viewer->positionToXY(CellPosition(m_r0, 0));
+ m_viewer->drawPredefinedPath(p, PredefinedPath::BEGIN_PLAY_RANGE, topLeft,
+ ArrowColor, QColor(Qt::black));
+ }
- if (m_r1 > r0 - 1 && r1 + 1 > m_r1)
- m_viewer->drawPredefinedPath(p, PredefinedPath::END_PLAY_RANGE,
- CellPosition(m_r1, 0), ArrowColor,
- QColor(Qt::black));
+ if (m_r1 > r0 - 1 && r1 + 1 > m_r1) {
+ QPoint topLeft = m_viewer->positionToXY(CellPosition(m_r1, 0));
+ topLeft.setX(topLeft.x() - frameAdj);
+ m_viewer->drawPredefinedPath(p, PredefinedPath::END_PLAY_RANGE, topLeft,
+ ArrowColor, QColor(Qt::black));
+ }
}
//-----------------------------------------------------------------------------
@@ -266,8 +317,9 @@ void RowArea::drawCurrentRowGadget(QPainter &p, int r0, int r1) {
QPoint topLeft = m_viewer->positionToXY(CellPosition(currentRow, 0));
QRect header = m_viewer->orientation()
->rect(PredefinedRect::FRAME_HEADER)
- .translated(topLeft)
- .adjusted(1, 1, 0, 0);
+ .translated(topLeft);
+ int frameAdj = m_viewer->getFrameZoomAdjustment();
+ header.adjust(1, 1, -frameAdj, 0);
p.fillRect(header, m_viewer->getCurrentRowBgColor());
}
@@ -281,6 +333,8 @@ void RowArea::drawOnionSkinSelection(QPainter &p) {
assert(xsh);
int currentRow = m_viewer->getCurrentRow();
+ int frameAdj = m_viewer->getFrameZoomAdjustment();
+
// get onion colors
TPixel frontPixel, backPixel;
bool inksOnly;
@@ -319,10 +373,11 @@ void RowArea::drawOnionSkinSelection(QPainter &p) {
p.setBrush(Qt::NoBrush);
if (minMos < 0) // previous frames
{
- int layerAxis = onionCenter_layer;
- int fromFrameAxis =
- m_viewer->rowToFrameAxis(currentRow + minMos) + onionCenter_frame;
- int toFrameAxis = m_viewer->rowToFrameAxis(currentRow) + onionCenter_frame;
+ int layerAxis = onionCenter_layer;
+ int fromFrameAxis = m_viewer->rowToFrameAxis(currentRow + minMos) +
+ onionCenter_frame - (frameAdj / 2);
+ int toFrameAxis = m_viewer->rowToFrameAxis(currentRow) + onionCenter_frame -
+ (frameAdj / 2);
QLine verticalLine = m_viewer->orientation()->verticalLine(
layerAxis, NumberRange(fromFrameAxis, toFrameAxis));
if (m_viewer->orientation()->isVerticalTimeline())
@@ -334,11 +389,11 @@ void RowArea::drawOnionSkinSelection(QPainter &p) {
}
if (maxMos > 0) // forward frames
{
- int layerAxis = onionCenter_layer;
- int fromFrameAxis =
- m_viewer->rowToFrameAxis(currentRow) + onionCenter_frame;
- int toFrameAxis =
- m_viewer->rowToFrameAxis(currentRow + maxMos) + onionCenter_frame;
+ int layerAxis = onionCenter_layer;
+ int fromFrameAxis = m_viewer->rowToFrameAxis(currentRow) +
+ onionCenter_frame - (frameAdj / 2);
+ int toFrameAxis = m_viewer->rowToFrameAxis(currentRow + maxMos) +
+ onionCenter_frame - (frameAdj / 2);
QLine verticalLine = m_viewer->orientation()->verticalLine(
layerAxis, NumberRange(fromFrameAxis, toFrameAxis));
if (m_viewer->orientation()->isVerticalTimeline())
@@ -351,7 +406,8 @@ void RowArea::drawOnionSkinSelection(QPainter &p) {
// Draw onion skin main handle
QPoint handleTopLeft = m_viewer->positionToXY(CellPosition(currentRow, 0));
QRect handleRect = onionRect.translated(handleTopLeft);
- int angle180 = 16 * 180;
+ handleRect.adjust(-frameAdj / 2, 0, -frameAdj / 2, 0);
+ int angle180 = 16 * 180;
int turn =
m_viewer->orientation()->dimension(PredefinedDimension::ONION_TURN) * 16;
p.setBrush(QBrush(backColor));
@@ -375,6 +431,7 @@ void RowArea::drawOnionSkinSelection(QPainter &p) {
QRect dotRect = m_viewer->orientation()
->rect(PredefinedRect::ONION_DOT)
.translated(topLeft);
+ dotRect.adjust(-frameAdj / 2, 0, -frameAdj / 2, 0);
p.drawEllipse(dotRect);
}
@@ -393,6 +450,7 @@ void RowArea::drawOnionSkinSelection(QPainter &p) {
QRect dotRect = m_viewer->orientation()
->rect(PredefinedRect::ONION_DOT_FIXED)
.translated(topLeft);
+ dotRect.adjust(-frameAdj / 2, 0, -frameAdj / 2, 0);
p.drawEllipse(dotRect);
}
@@ -406,6 +464,7 @@ void RowArea::drawOnionSkinSelection(QPainter &p) {
->rect(m_showOnionToSet == Fos ? PredefinedRect::ONION_DOT_FIXED
: PredefinedRect::ONION_DOT)
.translated(topLeft);
+ dotRect.adjust(-frameAdj / 2, 0, -frameAdj / 2, 0);
p.drawEllipse(dotRect);
}
}
@@ -413,14 +472,16 @@ void RowArea::drawOnionSkinSelection(QPainter &p) {
//-----------------------------------------------------------------------------
void RowArea::drawCurrentTimeIndicator(QPainter &p) {
+ int frameAdj = m_viewer->getFrameZoomAdjustment();
int currentRow = m_viewer->getCurrentRow();
QPoint topLeft = m_viewer->positionToXY(CellPosition(currentRow, 0));
QRect header = m_viewer->orientation()
->rect(PredefinedRect::FRAME_HEADER)
+ .adjusted(-frameAdj / 2, 0, -frameAdj / 2, 0)
.translated(topLeft);
- int frameMid = header.left() + (header.width() / 2);
+ int frameMid = header.left() + (header.width() / 2) - 1;
int frameTop = header.top() + 22;
QPainterPath markerHead = m_viewer->orientation()
@@ -434,14 +495,16 @@ void RowArea::drawCurrentTimeIndicator(QPainter &p) {
}
void RowArea::drawCurrentTimeLine(QPainter &p) {
+ int frameAdj = m_viewer->getFrameZoomAdjustment();
int currentRow = m_viewer->getCurrentRow();
QPoint topLeft = m_viewer->positionToXY(CellPosition(currentRow, 0));
QRect header = m_viewer->orientation()
->rect(PredefinedRect::FRAME_HEADER)
+ .adjusted(-frameAdj / 2, 0, -frameAdj / 2, 0)
.translated(topLeft);
- int frameMid = header.left() + (header.width() / 2);
+ int frameMid = header.left() + (header.width() / 2) - 1;
int frameTop = header.top();
int frameBottom = header.bottom();
@@ -489,9 +552,11 @@ void RowArea::drawPinnedCenterKeys(QPainter &p, int r0, int r1) {
int columnCount = xsh->getColumnCount();
int prev_pinnedCol = -2;
+ int frameAdj = m_viewer->getFrameZoomAdjustment();
- QRect keyRect =
- m_viewer->orientation()->rect(PredefinedRect::PINNED_CENTER_KEY);
+ QRect keyRect = m_viewer->orientation()
+ ->rect(PredefinedRect::PINNED_CENTER_KEY)
+ .adjusted(-frameAdj / 2, 0, -frameAdj / 2, 0);
p.setPen(Qt::black);
r1 = (r1 < xsh->getFrameCount() - 1) ? xsh->getFrameCount() - 1 : r1;
@@ -549,6 +614,8 @@ void RowArea::paintEvent(QPaintEvent *event) {
// current frame
drawCurrentRowGadget(p, r0, r1);
+ drawRows(p, r0, r1);
+
if (TApp::instance()->getCurrentFrame()->isEditingScene()) {
if (Preferences::instance()->isOnionSkinEnabled())
drawOnionSkinSelection(p);
@@ -561,7 +628,7 @@ void RowArea::paintEvent(QPaintEvent *event) {
drawCurrentTimeLine(p);
}
- drawRows(p, r0, r1);
+ // drawRows(p, r0, r1);
if (TApp::instance()->getCurrentTool()->getTool()->getName() == T_Skeleton)
drawPinnedCenterKeys(p, r0, r1);
@@ -592,18 +659,24 @@ void RowArea::mousePressEvent(QMouseEvent *event) {
int row = m_viewer->xyToPosition(pos).frame();
QPoint topLeft = m_viewer->positionToXY(CellPosition(row, 0));
QPoint mouseInCell = event->pos() - topLeft;
+ int frameAdj = m_viewer->getFrameZoomAdjustment();
if (Preferences::instance()->isOnionSkinEnabled() &&
- o->rect(PredefinedRect::ONION_AREA).contains(mouseInCell)) {
+ o->rect(PredefinedRect::ONION_AREA)
+ .adjusted(0, 0, -frameAdj, 0)
+ .contains(mouseInCell)) {
if (row == currentFrame) {
setDragTool(
XsheetGUI::DragTool::makeCurrentFrameModifierTool(m_viewer));
frameAreaIsClicked = true;
} else if (o->rect(PredefinedRect::ONION_FIXED_DOT_AREA)
+ .adjusted(0, 0, -frameAdj, 0)
.contains(mouseInCell))
setDragTool(XsheetGUI::DragTool::makeKeyOnionSkinMaskModifierTool(
m_viewer, true));
- else if (o->rect(PredefinedRect::ONION_DOT_AREA).contains(mouseInCell))
+ else if (o->rect(PredefinedRect::ONION_DOT_AREA)
+ .adjusted(0, 0, -frameAdj, 0)
+ .contains(mouseInCell))
setDragTool(XsheetGUI::DragTool::makeKeyOnionSkinMaskModifierTool(
m_viewer, false));
else {
@@ -626,7 +699,9 @@ void RowArea::mousePressEvent(QMouseEvent *event) {
setDragTool(
XsheetGUI::DragTool::makeCurrentFrameModifierTool(m_viewer));
frameAreaIsClicked = true;
- } else if (o->rect(PredefinedRect::PLAY_RANGE).contains(mouseInCell) &&
+ } else if (o->rect(PredefinedRect::PLAY_RANGE)
+ .adjusted(0, 0, -frameAdj, 0)
+ .contains(mouseInCell) &&
(row == playR0 || row == playR1)) {
if (!playRangeEnabled) XsheetGUI::setPlayRange(playR0, playR1, step);
setDragTool(XsheetGUI::DragTool::makePlayRangeModifierTool(m_viewer));
@@ -655,7 +730,7 @@ void RowArea::mousePressEvent(QMouseEvent *event) {
m_viewer->dragToolClick(event);
event->accept();
} // left-click
- // pan by middle-drag
+ // pan by middle-drag
else if (event->button() == Qt::MidButton) {
m_pos = event->pos();
m_isPanning = true;
@@ -703,14 +778,19 @@ void RowArea::mouseMoveEvent(QMouseEvent *event) {
int currentRow = TApp::instance()->getCurrentFrame()->getFrame();
int row = m_viewer->xyToPosition(m_pos).frame();
+ int frameAdj = m_viewer->getFrameZoomAdjustment();
QPoint mouseInCell =
event->pos() - m_viewer->positionToXY(CellPosition(row, 0));
if (row < 0) return;
// whether to show ability to set onion marks
if (Preferences::instance()->isOnionSkinEnabled() && row != currentRow) {
- if (o->rect(PredefinedRect::ONION_FIXED_DOT_AREA).contains(mouseInCell))
+ if (o->rect(PredefinedRect::ONION_FIXED_DOT_AREA)
+ .adjusted(0, 0, -frameAdj, 0)
+ .contains(mouseInCell))
m_showOnionToSet = Fos;
- else if (o->rect(PredefinedRect::ONION_DOT_AREA).contains(mouseInCell))
+ else if (o->rect(PredefinedRect::ONION_DOT_AREA)
+ .adjusted(0, 0, -frameAdj, 0)
+ .contains(mouseInCell))
m_showOnionToSet = Mos;
}
@@ -719,7 +799,9 @@ void RowArea::mouseMoveEvent(QMouseEvent *event) {
bool isRootBonePinned;
int pinnedCenterColumnId = -1;
if (TApp::instance()->getCurrentTool()->getTool()->getName() == T_Skeleton &&
- o->rect(PredefinedRect::PINNED_CENTER_KEY).contains(mouseInCell)) {
+ o->rect(PredefinedRect::PINNED_CENTER_KEY)
+ .adjusted(-frameAdj, 0, -frameAdj, 0)
+ .contains(mouseInCell)) {
int col = m_viewer->getCurrentColumn();
TXsheet *xsh = m_viewer->getXsheet();
if (col >= 0 && xsh && !xsh->isColumnEmpty(col)) {
diff --git a/toonz/sources/toonzlib/orientation.cpp b/toonz/sources/toonzlib/orientation.cpp
index 4db5531..0e9b386 100644
--- a/toonz/sources/toonzlib/orientation.cpp
+++ b/toonz/sources/toonzlib/orientation.cpp
@@ -17,6 +17,8 @@ const int PLAY_MARKER_SIZE = 10;
const int ONION_SIZE = 19;
const int ONION_DOT_SIZE = 8;
const int PINNED_SIZE = 10;
+const int FRAME_DOT_SIZE = 8;
+const int FRAME_IND_SIZE = 3;
}
class TopToBottomOrientation : public Orientation {
@@ -81,7 +83,7 @@ class LeftToRightOrientation : public Orientation {
const int EXTENDER_HEIGHT = 12;
const int SOUND_PREVIEW_HEIGHT = 6;
const int FRAME_HEADER_HEIGHT = 50;
- const int ONION_X = (CELL_WIDTH - ONION_SIZE) / 2, ONION_Y = 0;
+ const int ONION_X = 0, ONION_Y = 0;
const int PLAY_RANGE_Y = ONION_SIZE;
const int ICON_WIDTH = 20;
const int ICON_HEIGHT = 20;
@@ -300,6 +302,7 @@ TopToBottomOrientation::TopToBottomOrientation() {
PredefinedRect::END_SOUND_EDIT,
QRect(CELL_DRAG_WIDTH, CELL_HEIGHT - 2, CELL_WIDTH - CELL_DRAG_WIDTH, 2));
addRect(PredefinedRect::LOOP_ICON, QRect(keyRect.left(), 0, 10, 11));
+ addRect(PredefinedRect::FRAME_DOT, QRect(0, 0, -1, -1)); // hide
// Note viewer
addRect(
@@ -338,6 +341,7 @@ TopToBottomOrientation::TopToBottomOrientation() {
addRect(PredefinedRect::PINNED_CENTER_KEY,
QRect((FRAME_HEADER_WIDTH - PINNED_SIZE) / 2,
(CELL_HEIGHT - PINNED_SIZE) / 2, PINNED_SIZE, PINNED_SIZE));
+ addRect(PredefinedRect::FRAME_INDICATOR, QRect(0, 0, -1, -1)); // hide
// Column viewer
addRect(PredefinedRect::LAYER_HEADER,
@@ -889,6 +893,10 @@ LeftToRightOrientation::LeftToRightOrientation() {
QRect(CELL_WIDTH - 2, CELL_DRAG_HEIGHT, 2,
CELL_HEIGHT - CELL_DRAG_HEIGHT));
addRect(PredefinedRect::LOOP_ICON, QRect(0, keyRect.top(), 10, 11));
+ addRect(
+ PredefinedRect::FRAME_DOT,
+ QRect((CELL_WIDTH - FRAME_DOT_SIZE) / 2 - 1,
+ CELL_HEIGHT - FRAME_DOT_SIZE - 6, FRAME_DOT_SIZE, FRAME_DOT_SIZE));
// Notes viewer
addRect(
@@ -908,16 +916,18 @@ LeftToRightOrientation::LeftToRightOrientation() {
addRect(PredefinedRect::PLAY_RANGE,
QRect(0, PLAY_RANGE_Y, CELL_WIDTH, PLAY_MARKER_SIZE));
addRect(PredefinedRect::ONION,
- QRect(ONION_X, ONION_Y + (3 * ONION_DOT_SIZE - ONION_SIZE) / 2,
- ONION_SIZE, ONION_SIZE)
+ QRect(ONION_X + (CELL_WIDTH - ONION_SIZE) / 2 - 1,
+ ONION_Y + (3 * ONION_DOT_SIZE - ONION_SIZE) / 2, ONION_SIZE,
+ ONION_SIZE)
.adjusted(1, 2, 1, 2));
int adjustOnion = (ONION_SIZE - ONION_DOT_SIZE) / 2;
addRect(PredefinedRect::ONION_DOT,
- QRect(ONION_X + adjustOnion, ONION_Y + ONION_DOT_SIZE, ONION_DOT_SIZE,
- ONION_DOT_SIZE)
+ QRect(ONION_X + adjustOnion + (CELL_WIDTH - ONION_SIZE) / 2,
+ ONION_Y + ONION_DOT_SIZE, ONION_DOT_SIZE, ONION_DOT_SIZE)
.adjusted(1, 1, 1, 1));
addRect(PredefinedRect::ONION_DOT_FIXED,
- QRect(ONION_X + adjustOnion, ONION_Y, ONION_DOT_SIZE, ONION_DOT_SIZE)
+ QRect(ONION_X + adjustOnion + (CELL_WIDTH - ONION_SIZE) / 2, ONION_Y,
+ ONION_DOT_SIZE, ONION_DOT_SIZE)
.adjusted(1, 1, 1, 1));
addRect(PredefinedRect::ONION_AREA,
QRect(ONION_X, ONION_Y, CELL_WIDTH, ONION_SIZE));
@@ -929,6 +939,10 @@ LeftToRightOrientation::LeftToRightOrientation() {
PredefinedRect::PINNED_CENTER_KEY,
QRect((CELL_WIDTH - PINNED_SIZE) / 2,
(FRAME_HEADER_HEIGHT - PINNED_SIZE) / 2, PINNED_SIZE, PINNED_SIZE));
+ addRect(PredefinedRect::FRAME_INDICATOR,
+ QRect((CELL_WIDTH - FRAME_IND_SIZE) / 2,
+ FRAME_HEADER_HEIGHT - FRAME_IND_SIZE, FRAME_IND_SIZE,
+ FRAME_IND_SIZE));
// Column viewer
addRect(PredefinedRect::LAYER_HEADER,
diff --git a/toonz/sources/toonzqt/spreadsheetviewer.cpp b/toonz/sources/toonzqt/spreadsheetviewer.cpp
index 9a7e7a8..37a233c 100644
--- a/toonz/sources/toonzqt/spreadsheetviewer.cpp
+++ b/toonz/sources/toonzqt/spreadsheetviewer.cpp
@@ -75,13 +75,18 @@ void FrameScroller::onHScroll(int x) {
static QList frameScrollers;
-void FrameScroller::handleScroll(const QPoint &offset) const {
- CellPositionRatio ratio = orientation()->xyToPositionRatio(offset);
+void FrameScroller::handleScroll(QPoint &offset) {
if ((m_orientation->isVerticalTimeline() && offset.x()) ||
(!m_orientation->isVerticalTimeline() &&
offset.y())) // only synchronize changes by frames axis
return;
+ // In case of a zoomed viewer is sending this out, adjust the
+ // zoomed offset back to a standardized offset
+ emit zoomScrollAdjust(offset, false);
+
+ CellPositionRatio ratio = orientation()->xyToPositionRatio(offset);
+
for (int i = 0; i < frameScrollers.size(); i++)
if (frameScrollers[i] != this) {
if (!frameScrollers[i]->isSyncing()) {
@@ -95,6 +100,11 @@ void adjustScrollbar(QScrollBar *scrollBar, int add);
void FrameScroller::onScroll(const CellPositionRatio &ratio) {
QPoint offset = orientation()->positionRatioToXY(ratio);
+
+ // In case of a zoomed viewer is receiving this, adjust the
+ // standardized offset to zoomed offset
+ emit zoomScrollAdjust(offset, true);
+
// scroll area should be resized before moving down the scroll bar.
// SpreadsheetViewer::onPrepareToScrollOffset() will be invoked immediately
// since the receiver is in the same thread.