From 870c0567c526586c08824f2250f733a533b99cc6 Mon Sep 17 00:00:00 2001 From: Rodney Date: Jun 10 2021 04:11:52 +0000 Subject: Merge pull request #3974 from shun-iwasawa/g/fix_sync_scroll Modify sync scroll between Xsheet and Function editor panels --- diff --git a/toonz/sources/include/toonzqt/spreadsheetviewer.h b/toonz/sources/include/toonzqt/spreadsheetviewer.h index 1d7fbab..656601c 100644 --- a/toonz/sources/include/toonzqt/spreadsheetviewer.h +++ b/toonz/sources/include/toonzqt/spreadsheetviewer.h @@ -70,8 +70,9 @@ private: void connectScrollbars(); void disconnectScrollbars(); - void handleScroll(QPoint &offset); + void handleScroll(QPoint &offset, int senderMaximum, int senderValue); void onScroll(const CellPositionRatio &offset); + bool exactScroll(const int senderMaximum, const int senderValue); void prepareToScrollRatio(const CellPositionRatio &offset); diff --git a/toonz/sources/toonz/xsheetviewer.cpp b/toonz/sources/toonz/xsheetviewer.cpp index 2d56bc0..a05aaf1 100644 --- a/toonz/sources/toonz/xsheetviewer.cpp +++ b/toonz/sources/toonz/xsheetviewer.cpp @@ -1568,6 +1568,7 @@ void XsheetViewer::updateColumnArea() { //----------------------------------------------------------------------------- void XsheetViewer::updateCellColumnAree() { + if (!m_isComputingSize) refreshContentSize(0, 0); m_columnArea->update(m_columnArea->visibleRegion()); m_cellArea->update(m_cellArea->visibleRegion()); } @@ -1575,6 +1576,7 @@ void XsheetViewer::updateCellColumnAree() { //----------------------------------------------------------------------------- void XsheetViewer::updateCellRowAree() { + if (!m_isComputingSize) refreshContentSize(0, 0); m_rowArea->update(m_rowArea->visibleRegion()); m_cellArea->update(m_cellArea->visibleRegion()); } diff --git a/toonz/sources/toonzqt/spreadsheetviewer.cpp b/toonz/sources/toonzqt/spreadsheetviewer.cpp index c52ddb4..e3c872d 100644 --- a/toonz/sources/toonzqt/spreadsheetviewer.cpp +++ b/toonz/sources/toonzqt/spreadsheetviewer.cpp @@ -61,27 +61,56 @@ void FrameScroller::onVScroll(int y) { QPoint offset(0, y - m_lastY); if (isSyncing()) return; m_lastY = y; + + int senderMaximum = 0; + QScrollBar *scrollBar = dynamic_cast(sender()); + if (scrollBar) senderMaximum = scrollBar->maximum(); + setSyncing(true); - handleScroll(offset); + handleScroll(offset, senderMaximum, y); setSyncing(false); } void FrameScroller::onHScroll(int x) { QPoint offset(x - m_lastX, 0); if (isSyncing()) return; m_lastX = x; + + int senderMaximum = 0; + QScrollBar *scrollBar = dynamic_cast(sender()); + if (scrollBar) senderMaximum = scrollBar->maximum(); + setSyncing(true); - handleScroll(offset); + handleScroll(offset, senderMaximum, x); setSyncing(false); } static QList frameScrollers; -void FrameScroller::handleScroll(QPoint &offset) { +void FrameScroller::handleScroll(QPoint &offset, int senderMaximum, + int senderValue) { if ((m_orientation->isVerticalTimeline() && offset.x()) || (!m_orientation->isVerticalTimeline() && offset.y())) // only synchronize changes by frames axis return; + // If the scroller has the same maximum size, assume it as the scroll bar in + // the neighbor panel with the same height & scale. In such case just set the + // same value as the sender without zoom adjusting whichi may cause error due + // to rounding off. + QList scrollBarCue; + for (auto frameScroller : frameScrollers) + if (frameScroller != this) { + if (!frameScroller->isSyncing()) { + if (!frameScroller->exactScroll(senderMaximum, senderValue)) { + // If the size is different from the sender, then put it in the cue + // for adjusting offset and scrolling. + scrollBarCue.append(frameScroller); + } + } + } + + if (scrollBarCue.isEmpty()) return; + QPointF offsetF(offset); // In case of a zoomed viewer is sending this out, adjust the // zoomed offset back to a standardized offset @@ -89,10 +118,10 @@ void FrameScroller::handleScroll(QPoint &offset) { CellPositionRatio ratio = orientation()->xyToPositionRatio(offsetF); - for (int i = 0; i < frameScrollers.size(); i++) - if (frameScrollers[i] != this) { - if (!frameScrollers[i]->isSyncing()) { - frameScrollers[i]->onScroll(ratio); + for (auto frameScroller : scrollBarCue) + if (frameScroller != this) { + if (!frameScroller->isSyncing()) { + frameScroller->onScroll(ratio); break; } } @@ -100,6 +129,22 @@ void FrameScroller::handleScroll(QPoint &offset) { void adjustScrollbar(QScrollBar *scrollBar, int add); +// Check if the scroll bar has the same size as the sender and just put the +// value +bool FrameScroller::exactScroll(const int senderMaximum, + const int senderValue) { + QScrollBar *scrollBar = (m_orientation->isVerticalTimeline()) + ? m_scrollArea->verticalScrollBar() + : m_scrollArea->horizontalScrollBar(); + + if (scrollBar->maximum() == senderMaximum) { + scrollBar->setValue(senderValue); + return true; + } + + return false; +} + void FrameScroller::onScroll(const CellPositionRatio &ratio) { QPointF offset = orientation()->positionRatioToXY(ratio);