diff --git a/stuff/config/qss/Blue/Blue.qss b/stuff/config/qss/Blue/Blue.qss
index f733955..ad09a59 100644
--- a/stuff/config/qss/Blue/Blue.qss
+++ b/stuff/config/qss/Blue/Blue.qss
@@ -1193,30 +1193,49 @@ QGroupBox:disabled {
/* -----------------------------------------------------------------------------
Slider
----------------------------------------------------------------------------- */
-.Slider::groove:horizontal,
-QSlider::groove:horizontal {
+.Slider::groove,
+QSlider::groove {
background-color: transparent;
background-image: url('../Default/imgs/white/slider-groove.svg');
background-position: center center;
- background-repeat: repeat-x;
margin: 0;
+}
+.Slider::groove:horizontal,
+QSlider::groove:horizontal {
+ background-repeat: repeat-x;
height: 20;
min-height: 20;
}
-.Slider::groove:horizontal:disabled,
-QSlider::groove:horizontal:disabled {
+.Slider::groove:vertical,
+QSlider::groove:vertical {
+ background-repeat: repeat-y;
+ width: 20;
+ min-width: 20;
+}
+.Slider::groove:disabled,
+QSlider::groove:disabled {
background-image: url('../Default/imgs/white/slider-groove_disabled.svg');
}
.Slider::handle:horizontal,
QSlider::handle:horizontal {
- width: 10;
margin: -2 -1;
+ width: 10;
image: url('../Default/imgs/white/slider-handle.svg');
}
.Slider::handle:horizontal:disabled,
QSlider::handle:horizontal:disabled {
image: url('../Default/imgs/white/slider-handle_disabled.svg');
}
+.Slider::handle:vertical,
+QSlider::handle:vertical {
+ margin: -1 -2;
+ height: 10;
+ image: url('../Default/imgs/white/slider-v-handle.svg');
+}
+.Slider::handle:vertical:disabled,
+QSlider::handle:vertical:disabled {
+ image: url('../Default/imgs/white/slider-v-handle_disabled.svg');
+}
/* -----------------------------------------------------------------------------
Double Slider
----------------------------------------------------------------------------- */
diff --git a/stuff/config/qss/Dark/Dark.qss b/stuff/config/qss/Dark/Dark.qss
index d2564a4..80dc897 100644
--- a/stuff/config/qss/Dark/Dark.qss
+++ b/stuff/config/qss/Dark/Dark.qss
@@ -1193,30 +1193,49 @@ QGroupBox:disabled {
/* -----------------------------------------------------------------------------
Slider
----------------------------------------------------------------------------- */
-.Slider::groove:horizontal,
-QSlider::groove:horizontal {
+.Slider::groove,
+QSlider::groove {
background-color: transparent;
background-image: url('../Default/imgs/white/slider-groove_dark.svg');
background-position: center center;
- background-repeat: repeat-x;
margin: 0;
+}
+.Slider::groove:horizontal,
+QSlider::groove:horizontal {
+ background-repeat: repeat-x;
height: 20;
min-height: 20;
}
-.Slider::groove:horizontal:disabled,
-QSlider::groove:horizontal:disabled {
+.Slider::groove:vertical,
+QSlider::groove:vertical {
+ background-repeat: repeat-y;
+ width: 20;
+ min-width: 20;
+}
+.Slider::groove:disabled,
+QSlider::groove:disabled {
background-image: url('../Default/imgs/white/slider-groove_disabled_dark.svg');
}
.Slider::handle:horizontal,
QSlider::handle:horizontal {
- width: 10;
margin: -2 -1;
+ width: 10;
image: url('../Default/imgs/white/slider-handle.svg');
}
.Slider::handle:horizontal:disabled,
QSlider::handle:horizontal:disabled {
image: url('../Default/imgs/white/slider-handle_disabled.svg');
}
+.Slider::handle:vertical,
+QSlider::handle:vertical {
+ margin: -1 -2;
+ height: 10;
+ image: url('../Default/imgs/white/slider-v-handle.svg');
+}
+.Slider::handle:vertical:disabled,
+QSlider::handle:vertical:disabled {
+ image: url('../Default/imgs/white/slider-v-handle_disabled.svg');
+}
/* -----------------------------------------------------------------------------
Double Slider
----------------------------------------------------------------------------- */
diff --git a/stuff/config/qss/Default/Default.qss b/stuff/config/qss/Default/Default.qss
index 41ec273..a36989a 100644
--- a/stuff/config/qss/Default/Default.qss
+++ b/stuff/config/qss/Default/Default.qss
@@ -1193,30 +1193,49 @@ QGroupBox:disabled {
/* -----------------------------------------------------------------------------
Slider
----------------------------------------------------------------------------- */
-.Slider::groove:horizontal,
-QSlider::groove:horizontal {
+.Slider::groove,
+QSlider::groove {
background-color: transparent;
background-image: url('imgs/white/slider-groove.svg');
background-position: center center;
- background-repeat: repeat-x;
margin: 0;
+}
+.Slider::groove:horizontal,
+QSlider::groove:horizontal {
+ background-repeat: repeat-x;
height: 20;
min-height: 20;
}
-.Slider::groove:horizontal:disabled,
-QSlider::groove:horizontal:disabled {
+.Slider::groove:vertical,
+QSlider::groove:vertical {
+ background-repeat: repeat-y;
+ width: 20;
+ min-width: 20;
+}
+.Slider::groove:disabled,
+QSlider::groove:disabled {
background-image: url('imgs/white/slider-groove_disabled.svg');
}
.Slider::handle:horizontal,
QSlider::handle:horizontal {
- width: 10;
margin: -2 -1;
+ width: 10;
image: url('imgs/white/slider-handle.svg');
}
.Slider::handle:horizontal:disabled,
QSlider::handle:horizontal:disabled {
image: url('imgs/white/slider-handle_disabled.svg');
}
+.Slider::handle:vertical,
+QSlider::handle:vertical {
+ margin: -1 -2;
+ height: 10;
+ image: url('imgs/white/slider-v-handle.svg');
+}
+.Slider::handle:vertical:disabled,
+QSlider::handle:vertical:disabled {
+ image: url('imgs/white/slider-v-handle_disabled.svg');
+}
/* -----------------------------------------------------------------------------
Double Slider
----------------------------------------------------------------------------- */
diff --git a/stuff/config/qss/Default/imgs/black/slider-v-handle.svg b/stuff/config/qss/Default/imgs/black/slider-v-handle.svg
new file mode 100644
index 0000000..742e54a
--- /dev/null
+++ b/stuff/config/qss/Default/imgs/black/slider-v-handle.svg
@@ -0,0 +1,55 @@
+
+
\ No newline at end of file
diff --git a/stuff/config/qss/Default/imgs/black/slider-v-handle_disabled.svg b/stuff/config/qss/Default/imgs/black/slider-v-handle_disabled.svg
new file mode 100644
index 0000000..28a9e3b
--- /dev/null
+++ b/stuff/config/qss/Default/imgs/black/slider-v-handle_disabled.svg
@@ -0,0 +1,55 @@
+
+
\ No newline at end of file
diff --git a/stuff/config/qss/Default/imgs/black/slider-v-handle_disabled_light.svg b/stuff/config/qss/Default/imgs/black/slider-v-handle_disabled_light.svg
new file mode 100644
index 0000000..70f13b4
--- /dev/null
+++ b/stuff/config/qss/Default/imgs/black/slider-v-handle_disabled_light.svg
@@ -0,0 +1,55 @@
+
+
\ No newline at end of file
diff --git a/stuff/config/qss/Default/imgs/black/slider-v-handle_light.svg b/stuff/config/qss/Default/imgs/black/slider-v-handle_light.svg
new file mode 100644
index 0000000..0ab7dc1
--- /dev/null
+++ b/stuff/config/qss/Default/imgs/black/slider-v-handle_light.svg
@@ -0,0 +1,55 @@
+
+
\ No newline at end of file
diff --git a/stuff/config/qss/Default/imgs/white/slider-v-handle.svg b/stuff/config/qss/Default/imgs/white/slider-v-handle.svg
new file mode 100644
index 0000000..6f6e280
--- /dev/null
+++ b/stuff/config/qss/Default/imgs/white/slider-v-handle.svg
@@ -0,0 +1,62 @@
+
+
+
+
\ No newline at end of file
diff --git a/stuff/config/qss/Default/imgs/white/slider-v-handle_disabled.svg b/stuff/config/qss/Default/imgs/white/slider-v-handle_disabled.svg
new file mode 100644
index 0000000..cbfd8fc
--- /dev/null
+++ b/stuff/config/qss/Default/imgs/white/slider-v-handle_disabled.svg
@@ -0,0 +1,62 @@
+
+
+
+
\ No newline at end of file
diff --git a/stuff/config/qss/Default/less/Default.less b/stuff/config/qss/Default/less/Default.less
index 49a65d2..ff01577 100644
--- a/stuff/config/qss/Default/less/Default.less
+++ b/stuff/config/qss/Default/less/Default.less
@@ -279,6 +279,8 @@
@slider-handle-width: 10;
@slider-handle-img: 'slider-handle.svg';
@slider-handle-img-disabled: 'slider-handle_disabled.svg';
+@slider-v-handle-img: 'slider-v-handle.svg';
+@slider-v-handle-img-disabled: 'slider-v-handle_disabled.svg';
// This one is used only for #ViewerFpsSlider
@slider-handle-margin: -2 -1;
diff --git a/stuff/config/qss/Default/less/layouts/controls.less b/stuff/config/qss/Default/less/layouts/controls.less
index fc8a32d..cd5d469 100644
--- a/stuff/config/qss/Default/less/layouts/controls.less
+++ b/stuff/config/qss/Default/less/layouts/controls.less
@@ -310,24 +310,41 @@ QGroupBox {
----------------------------------------------------------------------------- */
.Slider {
- &::groove:horizontal {
+ &::groove{
background-color: transparent;
background-image: url('@{img-url}/@{slider-groove-img}');
background-position: center center;
- background-repeat: repeat-x;
margin: 0;
+ &:horizontal {
+ background-repeat: repeat-x;
height: 20;
min-height: 20;
+ }
+ &:vertical {
+ background-repeat: repeat-y;
+ width: 20;
+ min-width: 20;
+ }
&:disabled {
background-image: url('@{img-url}/@{slider-groove-img-disabled}');
}
}
- &::handle:horizontal {
+ &::handle{
+ &:horizontal {
+ margin: @slider-handle-margin;
width: @slider-handle-width;
- margin: @slider-handle-margin;
image: url('@{img-url}/@{slider-handle-img}');
&:disabled {
image: url('@{img-url}/@{slider-handle-img-disabled}');
+ }
+ }
+ &:vertical {
+ margin: -1 -2;
+ height: @slider-handle-width;
+ image: url('@{img-url}/@{slider-v-handle-img}');
+ &:disabled {
+ image: url('@{img-url}/@{slider-v-handle-img-disabled}');
+ }
}
}
}
diff --git a/stuff/config/qss/Default/less/themes/Light.less b/stuff/config/qss/Default/less/themes/Light.less
index 0abf22b..ba4c0f6 100644
--- a/stuff/config/qss/Default/less/themes/Light.less
+++ b/stuff/config/qss/Default/less/themes/Light.less
@@ -157,6 +157,8 @@
@slider-groove-img-disabled: 'slider-groove_disabled_light.svg';
@slider-handle-img: 'slider-handle_light.svg';
@slider-handle-img-disabled: 'slider-handle_disabled_light.svg';
+@slider-v-handle-img: 'slider-v-handle_light.svg';
+@slider-v-handle-img-disabled: 'slider-v-handle_disabled_light.svg';
// This one is used only for #ViewerFpsSlider
@slider-handle-bg-color: lighten(@bg, -10);
diff --git a/stuff/config/qss/Light/Light.qss b/stuff/config/qss/Light/Light.qss
index 9d37d55..071172d 100644
--- a/stuff/config/qss/Light/Light.qss
+++ b/stuff/config/qss/Light/Light.qss
@@ -1193,30 +1193,49 @@ QGroupBox:disabled {
/* -----------------------------------------------------------------------------
Slider
----------------------------------------------------------------------------- */
-.Slider::groove:horizontal,
-QSlider::groove:horizontal {
+.Slider::groove,
+QSlider::groove {
background-color: transparent;
background-image: url('../Default/imgs/black/slider-groove_light.svg');
background-position: center center;
- background-repeat: repeat-x;
margin: 0;
+}
+.Slider::groove:horizontal,
+QSlider::groove:horizontal {
+ background-repeat: repeat-x;
height: 20;
min-height: 20;
}
-.Slider::groove:horizontal:disabled,
-QSlider::groove:horizontal:disabled {
+.Slider::groove:vertical,
+QSlider::groove:vertical {
+ background-repeat: repeat-y;
+ width: 20;
+ min-width: 20;
+}
+.Slider::groove:disabled,
+QSlider::groove:disabled {
background-image: url('../Default/imgs/black/slider-groove_disabled_light.svg');
}
.Slider::handle:horizontal,
QSlider::handle:horizontal {
- width: 10;
margin: -2 0;
+ width: 10;
image: url('../Default/imgs/black/slider-handle_light.svg');
}
.Slider::handle:horizontal:disabled,
QSlider::handle:horizontal:disabled {
image: url('../Default/imgs/black/slider-handle_disabled_light.svg');
}
+.Slider::handle:vertical,
+QSlider::handle:vertical {
+ margin: -1 -2;
+ height: 10;
+ image: url('../Default/imgs/black/slider-v-handle_light.svg');
+}
+.Slider::handle:vertical:disabled,
+QSlider::handle:vertical:disabled {
+ image: url('../Default/imgs/black/slider-v-handle_disabled_light.svg');
+}
/* -----------------------------------------------------------------------------
Double Slider
----------------------------------------------------------------------------- */
diff --git a/stuff/config/qss/Neutral/Neutral.qss b/stuff/config/qss/Neutral/Neutral.qss
index 9887d45..69f9e7c 100644
--- a/stuff/config/qss/Neutral/Neutral.qss
+++ b/stuff/config/qss/Neutral/Neutral.qss
@@ -1193,30 +1193,49 @@ QGroupBox:disabled {
/* -----------------------------------------------------------------------------
Slider
----------------------------------------------------------------------------- */
-.Slider::groove:horizontal,
-QSlider::groove:horizontal {
+.Slider::groove,
+QSlider::groove {
background-color: transparent;
background-image: url('../Default/imgs/black/slider-groove.svg');
background-position: center center;
- background-repeat: repeat-x;
margin: 0;
+}
+.Slider::groove:horizontal,
+QSlider::groove:horizontal {
+ background-repeat: repeat-x;
height: 20;
min-height: 20;
}
-.Slider::groove:horizontal:disabled,
-QSlider::groove:horizontal:disabled {
+.Slider::groove:vertical,
+QSlider::groove:vertical {
+ background-repeat: repeat-y;
+ width: 20;
+ min-width: 20;
+}
+.Slider::groove:disabled,
+QSlider::groove:disabled {
background-image: url('../Default/imgs/black/slider-groove_disabled.svg');
}
.Slider::handle:horizontal,
QSlider::handle:horizontal {
- width: 10;
margin: -2 0;
+ width: 10;
image: url('../Default/imgs/black/slider-handle.svg');
}
.Slider::handle:horizontal:disabled,
QSlider::handle:horizontal:disabled {
image: url('../Default/imgs/black/slider-handle_disabled.svg');
}
+.Slider::handle:vertical,
+QSlider::handle:vertical {
+ margin: -1 -2;
+ height: 10;
+ image: url('../Default/imgs/black/slider-v-handle.svg');
+}
+.Slider::handle:vertical:disabled,
+QSlider::handle:vertical:disabled {
+ image: url('../Default/imgs/black/slider-v-handle_disabled.svg');
+}
/* -----------------------------------------------------------------------------
Double Slider
----------------------------------------------------------------------------- */
diff --git a/toonz/sources/include/orientation.h b/toonz/sources/include/orientation.h
index 5f1130f..e95c2d2 100644
--- a/toonz/sources/include/orientation.h
+++ b/toonz/sources/include/orientation.h
@@ -116,10 +116,11 @@ enum class PredefinedRect {
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
- CAMERA_CONFIG_AREA, //! config area for the camera column
- CAMERA_CONFIG, //! the config icon for camera column
- FRAME_MARKER_AREA, //! Cell's frame indicator
- FRAME_INDICATOR, //! Row # indicator
+ CAMERA_CONFIG_AREA, //! config area for the camera column
+ CAMERA_CONFIG, //! the config icon for camera column
+ FRAME_MARKER_AREA, //! Cell's frame indicator
+ CAMERA_FRAME_MARKER_AREA, //! Cell's frame indicator for camera column
+ FRAME_INDICATOR, //! Row # indicator
ZOOM_SLIDER_AREA,
ZOOM_SLIDER,
ZOOM_IN_AREA,
@@ -151,7 +152,8 @@ enum class PredefinedDimension {
ONION_TURN, //! onion handle turn in degrees
QBOXLAYOUT_DIRECTION, //! direction of QBoxLayout
CENTER_ALIGN, //! horizontal / vertical align
- CAMERA_LAYER //! width of a camera column / height of camera row
+ CAMERA_LAYER, //! width of a camera column / height of camera row
+ SCALE_THRESHOLD //! scale threshold to simplify the view
};
enum class PredefinedPath {
DRAG_HANDLE_CORNER, //! triangle corner at drag sidebar
@@ -213,11 +215,11 @@ protected:
public:
virtual CellPosition xyToPosition(const QPoint &xy,
- const ColumnFan *fan) const = 0;
+ const ColumnFan *fan) const = 0;
virtual QPoint positionToXY(const CellPosition &position,
- const ColumnFan *fan) const = 0;
- virtual CellPositionRatio xyToPositionRatio(const QPoint &xy) const = 0;
- virtual QPoint positionRatioToXY(const CellPositionRatio &ratio) const = 0;
+ const ColumnFan *fan) const = 0;
+ virtual CellPositionRatio xyToPositionRatio(const QPointF &xy) const = 0;
+ virtual QPointF positionRatioToXY(const CellPositionRatio &ratio) const = 0;
virtual int colToLayerAxis(int layer, const ColumnFan *fan) const = 0;
virtual int rowToFrameAxis(int frame) const = 0;
diff --git a/toonz/sources/include/toonz/cellpositionratio.h b/toonz/sources/include/toonz/cellpositionratio.h
index a46d708..e37fcb4 100644
--- a/toonz/sources/include/toonz/cellpositionratio.h
+++ b/toonz/sources/include/toonz/cellpositionratio.h
@@ -15,34 +15,15 @@
#include "tcommon.h"
-class DVAPI Ratio {
- int m_num, m_denom;
-
- void normalize();
- Ratio normalized() const;
-
-public:
- Ratio(int num, int denom);
-
- friend Ratio operator+(const Ratio &a, const Ratio &b);
- friend Ratio operator-(const Ratio &a, const Ratio &b);
- friend Ratio operator*(const Ratio &a, const Ratio &b);
- friend Ratio operator/(const Ratio &a, const Ratio &b);
-
- friend int operator*(const Ratio &a, int b);
-
- bool operator!() const { return m_num == 0; }
-};
-
class DVAPI CellPositionRatio {
- Ratio m_frame, m_layer;
+ double m_frameRatio, m_layerRatio;
public:
- CellPositionRatio(const Ratio &frame, const Ratio &layer)
- : m_frame(frame), m_layer(layer) {}
+ CellPositionRatio(const double frameRatio, const double layerRatio)
+ : m_frameRatio(frameRatio), m_layerRatio(layerRatio) {}
- Ratio frame() const { return m_frame; }
- Ratio layer() const { return m_layer; }
+ double frame() const { return m_frameRatio; }
+ double layer() const { return m_layerRatio; }
};
#endif
diff --git a/toonz/sources/include/toonz/txsheethandle.h b/toonz/sources/include/toonz/txsheethandle.h
index d851017..3c995c2 100644
--- a/toonz/sources/include/toonz/txsheethandle.h
+++ b/toonz/sources/include/toonz/txsheethandle.h
@@ -28,6 +28,7 @@ class DVAPI TXsheetHandle final : public QObject {
Q_OBJECT
TXsheet *m_xsheet;
+ int m_zoomFactor;
public:
TXsheetHandle();
@@ -39,12 +40,18 @@ public:
void notifyXsheetSwitched() { emit xsheetSwitched(); }
void notifyXsheetSoundChanged() { emit xsheetSoundChanged(); }
void changeXsheetCamera(int index) { emit xsheetCameraChange(index); }
+ void notifyZoomScaleChanged(int factor) {
+ m_zoomFactor = factor;
+ emit zoomScaleChanged();
+ }
+ int getZoomFactor() { return m_zoomFactor; }
signals:
void xsheetSwitched();
void xsheetChanged();
void xsheetSoundChanged();
void xsheetCameraChange(int);
+ void zoomScaleChanged();
};
#endif // TXSHEETHANDLE_H
diff --git a/toonz/sources/include/toonzqt/functionsheet.h b/toonz/sources/include/toonzqt/functionsheet.h
index acb2333..76f8259 100644
--- a/toonz/sources/include/toonzqt/functionsheet.h
+++ b/toonz/sources/include/toonzqt/functionsheet.h
@@ -27,6 +27,17 @@ class TDoubleParam;
class TFrameHandle;
class FunctionSelection;
+class FunctionSheetButtonArea final : public QWidget {
+ Q_OBJECT
+ QPushButton *m_syncSizeBtn;
+
+public:
+ FunctionSheetButtonArea(QWidget *parent);
+ void setSyncSizeBtnState(bool);
+signals:
+ void syncSizeBtnToggled(bool);
+};
+
class FunctionSheetRowViewer final : public Spreadsheet::RowPanel {
FunctionSheet *m_sheet;
@@ -98,7 +109,20 @@ private slots:
class FunctionSheet final : public SpreadsheetViewer {
Q_OBJECT
+
+ FunctionSheetRowViewer *m_rowViewer;
+ FunctionSheetColumnHeadViewer *m_columnHeadViewer;
+ FunctionSheetCellViewer *m_cellViewer;
+ FunctionSelection *m_selection;
+ FunctionTreeModel *m_functionTreeModel;
+ FunctionViewer *m_functionViewer;
+ FunctionSheetButtonArea *m_buttonArea;
+ TXsheetHandle *m_xshHandle;
+
+ QRect m_selectedCells;
+ bool m_isFloating;
bool m_showIbtwnValue = true;
+ bool m_syncSize = true;
public:
FunctionSheet(QWidget *parent = 0, bool isFloating = false);
@@ -138,21 +162,16 @@ public:
update();
}
+ bool isSyncSize() { return m_syncSize; }
+ void setSyncSize(bool on);
+ void setXsheetHandle(TXsheetHandle *xshHandle) { m_xshHandle = xshHandle; }
+
+ int getFrameZoomFactor() const override;
+
protected:
void showEvent(QShowEvent *e) override;
void hideEvent(QHideEvent *e) override;
-private:
- FunctionSheetRowViewer *m_rowViewer;
- FunctionSheetColumnHeadViewer *m_columnHeadViewer;
- FunctionSheetCellViewer *m_cellViewer;
- FunctionSelection *m_selection;
- FunctionTreeModel *m_functionTreeModel;
- FunctionViewer *m_functionViewer;
-
- QRect m_selectedCells;
- bool m_isFloating;
-
public slots:
void updateAll();
@@ -160,6 +179,9 @@ public slots:
/*---
* カレントChannelが切り替わったら、NumericalColumnsがそのChannelを表示できるようにスクロールする。---*/
void onCurrentChannelChanged(FunctionTreeModel::Channel *);
+
+ void onSyncSizeBtnToggled(bool);
+ void onZoomScaleChanged();
};
#endif
diff --git a/toonz/sources/include/toonzqt/spreadsheetviewer.h b/toonz/sources/include/toonzqt/spreadsheetviewer.h
index 1ae6ed0..1d7fbab 100644
--- a/toonz/sources/include/toonzqt/spreadsheetviewer.h
+++ b/toonz/sources/include/toonzqt/spreadsheetviewer.h
@@ -61,7 +61,7 @@ public:
void registerFrameScroller();
void unregisterFrameScroller();
- void prepareToScrollOthers(const QPoint &offset);
+ void prepareToScrollOthers(const QPointF &offset);
void setSyncing(bool s) { m_syncing = s; }
bool isSyncing() { return m_syncing; }
@@ -79,8 +79,8 @@ private slots:
void onVScroll(int value);
void onHScroll(int value);
signals:
- void prepareToScrollOffset(const QPoint &offset);
- void zoomScrollAdjust(QPoint &offset, bool toZoom);
+ void prepareToScrollOffset(const QPointF &offset);
+ void zoomScrollAdjust(QPointF &offset, bool toZoom);
};
//-------------------------------------------------------------------
@@ -303,6 +303,7 @@ class DVAPI SpreadsheetViewer : public QDialog {
int m_columnWidth;
int m_rowHeight;
+ int m_scaleFactor;
// QPoint m_delta;
int m_timerId;
@@ -328,9 +329,12 @@ public:
int getRowHeight() const { return m_rowHeight; }
void setRowHeight(int height) { m_rowHeight = height; }
+ void setScaleFactor(int factor) { m_scaleFactor = factor; }
+
void setRowsPanel(Spreadsheet::RowPanel *rows);
void setColumnsPanel(Spreadsheet::ColumnPanel *columns);
void setCellsPanel(Spreadsheet::CellPanel *cells);
+ void setButtonAreaWidget(QWidget *widget);
int getRowCount() const { return m_rowCount; }
@@ -466,6 +470,8 @@ public:
void ensureVisibleCol(int col);
+ virtual int getFrameZoomFactor() const { return 100; }
+
protected:
void showEvent(QShowEvent *) override;
void hideEvent(QHideEvent *) override;
@@ -484,7 +490,9 @@ public slots:
void onVSliderChanged(int);
void onHSliderChanged(int);
- void onPrepareToScrollOffset(const QPoint &offset);
+ void onPrepareToScrollOffset(const QPointF &offset);
+ void onZoomScrollAdjust(QPointF &offset, bool toZoom);
+
/*
void updateAllAree();
void updateCellColumnAree();
diff --git a/toonz/sources/toonz/icons/dark/actions/17/syncscale.svg b/toonz/sources/toonz/icons/dark/actions/17/syncscale.svg
new file mode 100644
index 0000000..4609a0f
--- /dev/null
+++ b/toonz/sources/toonz/icons/dark/actions/17/syncscale.svg
@@ -0,0 +1,61 @@
+
+
\ No newline at end of file
diff --git a/toonz/sources/toonz/layerfooterpanel.cpp b/toonz/sources/toonz/layerfooterpanel.cpp
index 3c607ee..7ebeca7 100644
--- a/toonz/sources/toonz/layerfooterpanel.cpp
+++ b/toonz/sources/toonz/layerfooterpanel.cpp
@@ -26,20 +26,26 @@ LayerFooterPanel::LayerFooterPanel(XsheetViewer *viewer, QWidget *parent,
Qt::WFlags flags)
#endif
: QWidget(parent, flags), m_viewer(viewer) {
- const Orientation *o = Orientations::leftToRight();
- QRect rect = o->rect(PredefinedRect::LAYER_FOOTER_PANEL);
+ const Orientation *o = viewer->orientation();
setObjectName("layerFooterPanel");
- setFixedSize(rect.size());
-
setMouseTracking(true);
- m_frameZoomSlider = new QSlider(Qt::Horizontal, this);
+ Qt::Orientation ori =
+ (o->isVerticalTimeline()) ? Qt::Vertical : Qt::Horizontal;
+ bool invDirection = o->isVerticalTimeline();
+ QString tooltipStr = (o->isVerticalTimeline())
+ ? tr("Zoom in/out of xsheet")
+ : tr("Zoom in/out of timeline");
+
+ m_frameZoomSlider = new QSlider(ori, this);
m_frameZoomSlider->setMinimum(20);
m_frameZoomSlider->setMaximum(100);
m_frameZoomSlider->setValue(m_viewer->getFrameZoomFactor());
- m_frameZoomSlider->setToolTip(tr("Zoom in/out of timeline"));
+ m_frameZoomSlider->setToolTip(tooltipStr);
+ m_frameZoomSlider->setInvertedAppearance(invDirection);
+ m_frameZoomSlider->setInvertedControls(invDirection);
connect(m_frameZoomSlider, SIGNAL(valueChanged(int)), this,
SLOT(onFrameZoomSliderValueChanged(int)));
@@ -66,13 +72,13 @@ QRect shorter(const QRect original) { return original.adjusted(0, 2, 0, -2); }
QLine leftSide(const QRect &r) { return QLine(r.topLeft(), r.bottomLeft()); }
QLine rightSide(const QRect &r) { return QLine(r.topRight(), r.bottomRight()); }
-}
+} // namespace
void LayerFooterPanel::paintEvent(QPaintEvent *event) {
QPainter p(this);
p.setRenderHint(QPainter::SmoothPixmapTransform, true);
- const Orientation *o = Orientations::leftToRight();
+ const Orientation *o = m_viewer->orientation();
QRect zoomSliderRect = o->rect(PredefinedRect::ZOOM_SLIDER_AREA);
p.fillRect(zoomSliderRect, Qt::NoBrush);
@@ -103,18 +109,29 @@ void LayerFooterPanel::paintEvent(QPaintEvent *event) {
else
p.drawPixmap(zoomOutImgRect, zoomOut);
- p.setPen(m_viewer->getVerticalLineColor());
-
- QLine line = {leftSide(shorter(zoomOutImgRect)).translated(-2, 0)};
- p.drawLine(line);
+ if (!o->isVerticalTimeline()) {
+ p.setPen(m_viewer->getVerticalLineColor());
+ QLine line = {leftSide(shorter(zoomOutImgRect)).translated(-2, 0)};
+ p.drawLine(line);
+ }
}
void LayerFooterPanel::showOrHide(const Orientation *o) {
QRect rect = o->rect(PredefinedRect::LAYER_FOOTER_PANEL);
- if (rect.isEmpty())
- hide();
- else
- show();
+ setFixedSize(rect.size());
+ Qt::Orientation ori =
+ (o->isVerticalTimeline()) ? Qt::Vertical : Qt::Horizontal;
+ bool invDirection = o->isVerticalTimeline();
+ QString tooltipStr = (o->isVerticalTimeline())
+ ? tr("Zoom in/out of xsheet")
+ : tr("Zoom in/out of timeline");
+
+ m_frameZoomSlider->setOrientation(ori);
+ m_frameZoomSlider->setToolTip(tooltipStr);
+ m_frameZoomSlider->setInvertedAppearance(invDirection);
+ m_frameZoomSlider->setInvertedControls(invDirection);
+
+ show();
}
//-----------------------------------------------------------------------------
@@ -133,7 +150,7 @@ void LayerFooterPanel::leaveEvent(QEvent *) {
}
void LayerFooterPanel::mousePressEvent(QMouseEvent *event) {
- const Orientation *o = Orientations::leftToRight();
+ const Orientation *o = m_viewer->orientation();
if (event->button() == Qt::LeftButton) {
// get mouse position
@@ -153,7 +170,7 @@ void LayerFooterPanel::mousePressEvent(QMouseEvent *event) {
}
void LayerFooterPanel::mouseMoveEvent(QMouseEvent *event) {
- const Orientation *o = Orientations::leftToRight();
+ const Orientation *o = m_viewer->orientation();
QPoint pos = event->pos();
@@ -188,6 +205,28 @@ bool LayerFooterPanel::event(QEvent *event) {
//-----------------------------------------------------------------------------
+void LayerFooterPanel::contextMenuEvent(QContextMenuEvent *event) {
+ if (!m_viewer->orientation()->isVerticalTimeline()) {
+ event->ignore();
+ return;
+ }
+
+ QList frames = m_viewer->availableFramesPerPage();
+ if (frames.isEmpty()) {
+ return;
+ }
+
+ QMenu *menu = new QMenu(this);
+ for (auto frame : frames) {
+ QAction *action = menu->addAction(tr("%1 frames per page").arg(frame));
+ action->setData(frame);
+ connect(action, SIGNAL(triggered()), this, SLOT(onFramesPerPageSelected()));
+ }
+ menu->exec(event->globalPos());
+}
+
+//-----------------------------------------------------------------------------
+
void LayerFooterPanel::setZoomSliderValue(int val) {
if (val > m_frameZoomSlider->maximum())
val = m_frameZoomSlider->maximum();
@@ -207,6 +246,14 @@ void LayerFooterPanel::onFrameZoomSliderValueChanged(int val) {
//-----------------------------------------------------------------------------
+void LayerFooterPanel::onFramesPerPageSelected() {
+ QAction *action = (QAction *)QObject::sender();
+ int frame = action->data().toInt();
+ m_viewer->zoomToFramesPerPage(frame);
+}
+
+//-----------------------------------------------------------------------------
+
void LayerFooterPanel::onControlPressed(bool pressed) {
isCtrlPressed = pressed;
update();
diff --git a/toonz/sources/toonz/layerfooterpanel.h b/toonz/sources/toonz/layerfooterpanel.h
index 2eb2e31..804ccc2 100644
--- a/toonz/sources/toonz/layerfooterpanel.h
+++ b/toonz/sources/toonz/layerfooterpanel.h
@@ -16,51 +16,53 @@ class XsheetViewer;
// Panel showing column footers for layers in timeline mode
class LayerFooterPanel final : public QWidget {
- Q_OBJECT
+ Q_OBJECT
- QString m_tooltip;
- QPoint m_pos;
+ QString m_tooltip;
+ QPoint m_pos;
- QSlider *m_frameZoomSlider;
+ QSlider *m_frameZoomSlider;
- bool isCtrlPressed = false;
- bool m_zoomInHighlighted = false;
- bool m_zoomOutHighlighted = false;
+ bool isCtrlPressed = false;
+ bool m_zoomInHighlighted = false;
+ bool m_zoomOutHighlighted = false;
private:
- XsheetViewer *m_viewer;
+ XsheetViewer *m_viewer;
public:
#if QT_VERSION >= 0x050500
- LayerFooterPanel(XsheetViewer *viewer, QWidget *parent = 0,
- Qt::WindowFlags flags = 0);
+ LayerFooterPanel(XsheetViewer *viewer, QWidget *parent = 0,
+ Qt::WindowFlags flags = 0);
#else
- LayerFooterPanel(XsheetViewer *viewer, QWidget *parent = 0,
- Qt::WFlags flags = 0);
+ LayerFooterPanel(XsheetViewer *viewer, QWidget *parent = 0,
+ Qt::WFlags flags = 0);
#endif
- ~LayerFooterPanel();
+ ~LayerFooterPanel();
- void showOrHide(const Orientation *o);
+ void showOrHide(const Orientation *o);
- void setZoomSliderValue(int val);
+ void setZoomSliderValue(int val);
- void onControlPressed(bool pressed);
- const bool isControlPressed();
+ void onControlPressed(bool pressed);
+ const bool isControlPressed();
protected:
- void paintEvent(QPaintEvent *event) override;
+ void paintEvent(QPaintEvent *event) override;
- void enterEvent(QEvent *) override;
- void leaveEvent(QEvent *) override;
- void mousePressEvent(QMouseEvent *event) override;
- void mouseMoveEvent(QMouseEvent *event) override;
- bool event(QEvent *event) override;
+ void enterEvent(QEvent *) override;
+ void leaveEvent(QEvent *) override;
+ void mousePressEvent(QMouseEvent *event) override;
+ void mouseMoveEvent(QMouseEvent *event) override;
+ bool event(QEvent *event) override;
+ void contextMenuEvent(QContextMenuEvent *) override;
- void keyPressEvent(QKeyEvent *event) override { event->ignore(); }
- void wheelEvent(QWheelEvent *event) override { event->ignore(); }
+ void keyPressEvent(QKeyEvent *event) override { event->ignore(); }
+ void wheelEvent(QWheelEvent *event) override { event->ignore(); }
public slots:
- void onFrameZoomSliderValueChanged(int val);
+ void onFrameZoomSliderValueChanged(int val);
+ void onFramesPerPageSelected();
};
#endif
#pragma once
diff --git a/toonz/sources/toonz/toonz.qrc b/toonz/sources/toonz/toonz.qrc
index 2985300..492add9 100644
--- a/toonz/sources/toonz/toonz.qrc
+++ b/toonz/sources/toonz/toonz.qrc
@@ -530,6 +530,7 @@
icons/dark/actions/16/tool_options.svg
icons/dark/actions/16/view_file.svg
icons/dark/actions/16/level_strip.svg
+ icons/dark/actions/17/syncscale.svg
icons/dark/actions/20/key_off.svg
diff --git a/toonz/sources/toonz/xshcellviewer.cpp b/toonz/sources/toonz/xshcellviewer.cpp
index e56e4d2..0375e9c 100644
--- a/toonz/sources/toonz/xshcellviewer.cpp
+++ b/toonz/sources/toonz/xshcellviewer.cpp
@@ -1391,10 +1391,10 @@ void CellArea::drawSoundCell(QPainter &p, int row, int col, bool isReference) {
nextCell = soundColumn->getSoundCell(row + 1); // cell in next frame
bool isNextEmpty = nextCell.getFrameId().getNumber() < 0;
- 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);
+ QPoint frameAdj = m_viewer->getFrameZoomAdjustment();
+ int frameZoomF = m_viewer->getFrameZoomFactor();
+ QRect cellRect = o->rect(PredefinedRect::CELL).translated(QPoint(x, y));
+ cellRect.adjust(0, 0, -frameAdj.x(), -frameAdj.y());
QRect rect = cellRect.adjusted(
1, 1,
(!m_viewer->orientation()->isVerticalTimeline() && !isNextEmpty ? 2 : 0),
@@ -1458,10 +1458,10 @@ void CellArea::drawSoundCell(QPainter &p, int row, int col, bool isReference) {
drawLockedDottedLine(p, soundColumn->isLocked(), xy, cellColor);
QRect trackRect = o->rect(PredefinedRect::SOUND_TRACK)
- .adjusted(0, 0, -frameAdj, 0)
+ .adjusted(0, 0, -frameAdj.x(), -frameAdj.y())
.translated(xy);
QRect previewRect = o->rect(PredefinedRect::PREVIEW_TRACK)
- .adjusted(0, 0, -frameAdj, 0)
+ .adjusted(0, 0, -frameAdj.x(), -frameAdj.y())
.translated(xy);
NumberRange trackBounds = o->layerSide(trackRect);
NumberRange previewBounds = o->layerSide(previewRect);
@@ -1536,7 +1536,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(-frameAdj)
.translated(xy);
if (r1 != r1WithoutOff) p.fillRect(modifierRect, SoundColumnExtenderColor);
m_soundLevelModifyRects.append(modifierRect);
@@ -1561,10 +1561,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();
+ QPoint frameAdj = m_viewer->getFrameZoomAdjustment();
QRect dragHandleRect = m_viewer->orientation()
->rect(PredefinedRect::DRAG_HANDLE_CORNER)
- .adjusted(0, 0, -frameAdj, 0)
+ .adjusted(0, 0, -frameAdj.x(), -frameAdj.y())
.translated(xy);
p.fillRect(dragHandleRect, QBrush(sideColor));
}
@@ -1573,10 +1573,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();
+ QPoint frameAdj = m_viewer->getFrameZoomAdjustment();
QPainterPath corner = m_viewer->orientation()
->path(PredefinedPath::DRAG_HANDLE_CORNER)
- .translated(xy - QPoint(frameAdj, 0));
+ .translated(xy - frameAdj);
p.fillPath(corner, QBrush(cellColor));
}
@@ -1586,19 +1586,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();
+ QPoint frameAdj = m_viewer->getFrameZoomAdjustment();
QLine dottedLine =
m_viewer->orientation()->line(PredefinedLine::LOCKED).translated(xy);
- dottedLine.setP2(QPoint(dottedLine.x2() - frameAdj, dottedLine.y2()));
+ dottedLine.setP2(QPoint(dottedLine.x2(), dottedLine.y2()) - frameAdj);
p.drawLine(dottedLine);
}
void CellArea::drawCurrentTimeIndicator(QPainter &p, const QPoint &xy,
bool isFolded) {
- int frameAdj = m_viewer->getFrameZoomAdjustment();
- QRect cell =
- m_viewer->orientation()->rect(PredefinedRect::CELL).translated(xy);
- cell.adjust(-frameAdj / 2, 0, -frameAdj / 2, 0);
+ QPoint frameAdj = m_viewer->getFrameZoomAdjustment();
+ QRect cell = m_viewer->orientation()
+ ->rect(PredefinedRect::CELL)
+ .translated(xy)
+ .translated(-frameAdj / 2);
int cellMid = cell.left() + (cell.width() / 2) - 1;
int cellTop = cell.top();
@@ -1615,19 +1616,34 @@ void CellArea::drawCurrentTimeIndicator(QPainter &p, const QPoint &xy,
}
void CellArea::drawFrameMarker(QPainter &p, const QPoint &xy, QColor color,
- bool isKeyFrame) {
+ bool isKeyFrame, bool isCamera) {
QColor outlineColor = Qt::black;
- int frameAdj = m_viewer->getFrameZoomAdjustment();
- QRect dotRect = m_viewer->orientation()
- ->rect(PredefinedRect::FRAME_MARKER_AREA)
- .translated(xy);
- dotRect.adjust(-frameAdj / 2, 0, -frameAdj / 2, 0);
+ QPoint frameAdj = m_viewer->getFrameZoomAdjustment();
+ QRect dotRect = (isCamera)
+ ? m_viewer->orientation()
+ ->rect(PredefinedRect::CAMERA_FRAME_MARKER_AREA)
+ .translated(xy)
+ .translated(-frameAdj / 2)
+ : m_viewer->orientation()
+ ->rect(PredefinedRect::FRAME_MARKER_AREA)
+ .translated(xy)
+ .translated(-frameAdj / 2);
if (isKeyFrame)
m_viewer->drawPredefinedPath(p, PredefinedPath::FRAME_MARKER_DIAMOND,
dotRect.adjusted(1, 1, 1, 1).center(), color,
outlineColor);
else {
+ // move to column center
+ if (m_viewer->orientation()->isVerticalTimeline()) {
+ PredefinedLine which =
+ Preferences::instance()->isLevelNameOnEachMarkerEnabled()
+ ? PredefinedLine::CONTINUE_LEVEL_WITH_NAME
+ : PredefinedLine::CONTINUE_LEVEL;
+
+ QLine continueLine = m_viewer->orientation()->line(which).translated(xy);
+ dotRect.moveCenter(QPoint(continueLine.x1() - 1, dotRect.center().y()));
+ }
p.setPen(outlineColor);
p.setBrush(color);
p.drawEllipse(dotRect);
@@ -1666,11 +1682,11 @@ 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();
+ QPoint frameAdj = m_viewer->getFrameZoomAdjustment();
QRect cellRect =
o->rect((col < 0) ? PredefinedRect::CAMERA_CELL : PredefinedRect::CELL)
.translated(QPoint(x, y));
- cellRect.adjust(0, 0, -frameAdj, 0);
+ cellRect.adjust(0, 0, -frameAdj.x(), -frameAdj.y());
QRect rect = cellRect.adjusted(
1, 1,
(!m_viewer->orientation()->isVerticalTimeline() && !nextCell.isEmpty()
@@ -1796,6 +1812,8 @@ void CellArea::drawLevelCell(QPainter &p, int row, int col, bool isReference) {
// if (distance == 0) distance = 6;
bool isAfterMarkers =
distance > 0 && ((row - offset) % distance) == 0 && row != 0;
+ bool isSimpleView = m_viewer->getFrameZoomFactor() <=
+ o->dimension(PredefinedDimension::SCALE_THRESHOLD);
// draw marker interval
if (o->isVerticalTimeline() && isAfterMarkers) {
@@ -1813,7 +1831,7 @@ void CellArea::drawLevelCell(QPainter &p, int row, int col, bool isReference) {
.translated(QPoint(x, y));
}
- nameRect.adjust(0, 0, -frameAdj, 0);
+ nameRect.adjust(0, 0, -frameAdj.x(), -frameAdj.y());
// draw text in red if the file does not exist
bool isRed = false;
@@ -1854,15 +1872,17 @@ 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()));
+ continueLine.setP2(QPoint(continueLine.x2(), continueLine.y2()) - frameAdj);
p.drawLine(continueLine);
}
// draw frame number
else {
- if (m_viewer->getFrameZoomFactor() <= 50) {
- // Lets not draw normal marker if there is a keyframe here
- TStageObject *pegbar = xsh->getStageObject(m_viewer->getObjectId(col));
- if (pegbar->isKeyframe(row)) return;
+ if (isSimpleView) {
+ if (!o->isVerticalTimeline()) {
+ // Lets not draw normal marker if there is a keyframe here
+ TStageObject *pegbar = xsh->getStageObject(m_viewer->getObjectId(col));
+ if (pegbar->isKeyframe(row)) return;
+ }
drawFrameMarker(p, QPoint(x, y), (isRed ? Qt::red : Qt::black));
return;
@@ -1888,7 +1908,7 @@ void CellArea::drawLevelCell(QPainter &p, int row, int col, bool isReference) {
// draw level name
if (!sameLevel ||
- (isAfterMarkers &&
+ (isAfterMarkers && !isSimpleView &&
Preferences::instance()->isLevelNameOnEachMarkerEnabled())) {
std::wstring levelName = cell.m_level->getName();
QString text = QString::fromStdWString(levelName);
@@ -1952,9 +1972,9 @@ 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));
- cellRect.adjust(0, 0, -frameAdj, 0);
+ QPoint frameAdj = m_viewer->getFrameZoomAdjustment();
+ QRect cellRect = o->rect(PredefinedRect::CELL).translated(QPoint(x, y));
+ cellRect.adjust(0, 0, -frameAdj.x(), -frameAdj.y());
QRect rect = cellRect.adjusted(
1, 1,
(!m_viewer->orientation()->isVerticalTimeline() && !nextCell.isEmpty()
@@ -2023,7 +2043,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);
+ nameRect.adjust(0, 0, -frameAdj.x(), -frameAdj.y());
// il nome va scritto se e' diverso dalla cella precedente oppure se
// siamo su una marker line
@@ -2049,7 +2069,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()));
+ continueLine.setP2(QPoint(continueLine.x2(), continueLine.y2()) - frameAdj);
p.drawLine(continueLine);
}
@@ -2125,9 +2145,9 @@ void CellArea::drawPaletteCell(QPainter &p, int row, int col,
prevCell.m_frameId == cell.m_frameId);
drawFrameSeparator(p, row, col, false, heldFrame);
- int frameAdj = m_viewer->getFrameZoomAdjustment();
- QRect cellRect = o->rect(PredefinedRect::CELL).translated(QPoint(x, y));
- cellRect.adjust(0, 0, -frameAdj, 0);
+ QPoint frameAdj = m_viewer->getFrameZoomAdjustment();
+ QRect cellRect = o->rect(PredefinedRect::CELL).translated(QPoint(x, y));
+ cellRect.adjust(0, 0, -frameAdj.x(), -frameAdj.y());
QRect rect = cellRect.adjusted(
1, 1,
(!m_viewer->orientation()->isVerticalTimeline() && !nextCell.isEmpty()
@@ -2194,14 +2214,17 @@ 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()));
+ continueLine.setP2(QPoint(continueLine.x2(), continueLine.y2()) - frameAdj);
p.drawLine(continueLine);
p.setPen(oldPen);
} else {
- if (m_viewer->getFrameZoomFactor() <= 50) {
- // Lets not draw normal marker if there is a keyframe here
- TStageObject *pegbar = xsh->getStageObject(m_viewer->getObjectId(col));
- if (pegbar->isKeyframe(row)) return;
+ if (m_viewer->getFrameZoomFactor() <=
+ o->dimension(PredefinedDimension::SCALE_THRESHOLD)) {
+ if (!o->isVerticalTimeline()) {
+ // Lets not draw normal marker if there is a keyframe here
+ TStageObject *pegbar = xsh->getStageObject(m_viewer->getObjectId(col));
+ if (pegbar->isKeyframe(row)) return;
+ }
drawFrameMarker(p, QPoint(x, y), (isRed ? Qt::red : Qt::black));
return;
}
@@ -2224,7 +2247,7 @@ void CellArea::drawPaletteCell(QPainter &p, int row, int col,
.translated(QPoint(x, y));
}
- nameRect.adjust(0, 0, -frameAdj, 0);
+ nameRect.adjust(0, 0, -frameAdj.x(), -frameAdj.y());
QColor penColor = isRed ? QColor(m_viewer->getErrorTextColor())
: m_viewer->getTextColor();
p.setPen(penColor);
@@ -2291,9 +2314,9 @@ void CellArea::drawKeyframe(QPainter &p, const QRect toBeUpdated) {
static QPixmap selectedKey = svgToPixmap(":Resources/selected_key.svg");
static QPixmap key = svgToPixmap(":Resources/key.svg");
- int frameAdj = m_viewer->getFrameZoomAdjustment();
- const QRect &keyRect = o->rect(PredefinedRect::KEY_ICON)
- .adjusted(-frameAdj / 2, 0, -frameAdj / 2, 0);
+ QPoint frameAdj = m_viewer->getFrameZoomAdjustment();
+ const QRect &keyRect =
+ o->rect(PredefinedRect::KEY_ICON).translated(-frameAdj / 2);
TXsheet *xsh = m_viewer->getXsheet();
ColumnFan *columnFan = xsh->getColumnFan(o);
@@ -2314,10 +2337,9 @@ void CellArea::drawKeyframe(QPainter &p, const QRect toBeUpdated) {
row0 = std::max(row0, r0);
row1 = std::min(row1, r1);
- QRect tmpKeyRect = (col >= 0)
- ? keyRect
- : o->rect(PredefinedRect::CAMERA_KEY_ICON)
- .adjusted(-frameAdj / 2, 0, -frameAdj / 2, 0);
+ QRect tmpKeyRect = (col >= 0) ? keyRect
+ : o->rect(PredefinedRect::CAMERA_KEY_ICON)
+ .translated(-frameAdj / 2);
/*- first, draw key segments -*/
p.setPen(m_viewer->getTextColor());
@@ -2363,7 +2385,8 @@ void CellArea::drawKeyframe(QPainter &p, const QRect toBeUpdated) {
if (pegbar->isKeyframe(row)) {
QPoint xy = m_viewer->positionToXY(CellPosition(row, col));
QPoint target = tmpKeyRect.translated(xy).topLeft();
- if (!o->isVerticalTimeline() && m_viewer->getFrameZoomFactor() <= 50) {
+ if (m_viewer->getFrameZoomFactor() <=
+ o->dimension(PredefinedDimension::SCALE_THRESHOLD)) {
QColor color = Qt::white;
int x = xy.x();
int y = xy.y();
@@ -2378,7 +2401,7 @@ void CellArea::drawKeyframe(QPainter &p, const QRect toBeUpdated) {
m_viewer->getKeyframeSelection()->isSelected(row, col))
color = QColor(85, 157, 255);
- drawFrameMarker(p, QPoint(x, y), color, true);
+ drawFrameMarker(p, QPoint(x, y), color, true, col < 0);
} else if (m_viewer->getKeyframeSelection() &&
m_viewer->getKeyframeSelection()->isSelected(row, col)) {
@@ -2434,11 +2457,11 @@ void CellArea::drawKeyframe(QPainter &p, const QRect toBeUpdated) {
void CellArea::drawKeyframeLine(QPainter &p, int col,
const NumberRange &rows) const {
- int frameAdj = m_viewer->getFrameZoomAdjustment();
+ QPoint frameAdj = m_viewer->getFrameZoomAdjustment();
const QRect &keyRect = m_viewer->orientation()
->rect((col < 0) ? PredefinedRect::CAMERA_KEY_ICON
: PredefinedRect::KEY_ICON)
- .adjusted(-frameAdj / 2, 0, -frameAdj / 2, 0);
+ .translated(-frameAdj / 2);
QPoint begin =
keyRect.center() + m_viewer->positionToXY(CellPosition(rows.from(), col));
QPoint end =
@@ -2543,15 +2566,15 @@ void CellArea::paintEvent(QPaintEvent *event) {
drawNotes(p, toBeUpdated);
// focus cell border
- int frameAdj = m_viewer->getFrameZoomAdjustment();
- int row = m_viewer->getCurrentRow();
- int col = m_viewer->getCurrentColumn();
- QPoint xy = m_viewer->positionToXY(CellPosition(row, col));
+ QPoint 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((col < 0) ? PredefinedRect::CAMERA_CELL : PredefinedRect::CELL)
.translated(xy)
- .adjusted(0, 0, -1 - frameAdj, 0);
+ .adjusted(0, 0, -1 - frameAdj.x(), -frameAdj.y());
p.setPen(m_viewer->getCellFocusColor());
p.setBrush(Qt::NoBrush);
for (int i = 0; i < 2; i++) // thick border within cell
@@ -2603,7 +2626,7 @@ bool CellArea::isKeyFrameArea(int col, int row, QPoint mouseInCell) {
if (!isKeyframeFrame) return false;
const Orientation *o = m_viewer->orientation();
- int frameAdj = m_viewer->getFrameZoomAdjustment();
+ QPoint frameAdj = m_viewer->getFrameZoomAdjustment();
if (o->isVerticalTimeline())
return o->rect((col < 0) ? PredefinedRect::CAMERA_CELL
@@ -2611,14 +2634,14 @@ bool CellArea::isKeyFrameArea(int col, int row, QPoint mouseInCell) {
.contains(mouseInCell) &&
row < k1 + 1;
- QRect activeArea = (m_viewer->getFrameZoomFactor() > 50
+ QRect activeArea = (m_viewer->getFrameZoomFactor() >
+ o->dimension(PredefinedDimension::SCALE_THRESHOLD)
? o->rect(PredefinedRect::KEYFRAME_AREA)
: o->rect(PredefinedRect::FRAME_MARKER_AREA));
// If directly over keyframe icon, return true
if (pegbar->isKeyframe(row) &&
- activeArea.adjusted(-frameAdj / 2, 0, -frameAdj / 2, 0)
- .contains(mouseInCell) &&
+ activeArea.translated(-frameAdj / 2).contains(mouseInCell) &&
row < k1 + 1)
return true;
@@ -2633,8 +2656,7 @@ bool CellArea::isKeyFrameArea(int col, int row, QPoint mouseInCell) {
if (row < k1)
activeArea.adjust(0, 0, (o->cellWidth() - activeArea.right()), 0);
- return activeArea.adjusted(-frameAdj / 2, 0, -frameAdj / 2, 0)
- .contains(mouseInCell) &&
+ return activeArea.translated(-frameAdj / 2).contains(mouseInCell) &&
row < k1 + 1;
}
@@ -2644,7 +2666,7 @@ void CellArea::mousePressEvent(QMouseEvent *event) {
m_viewer->setQtModifiers(event->modifiers());
assert(!m_isPanning);
m_isMousePressed = true;
- int frameAdj = m_viewer->getFrameZoomAdjustment();
+ QPoint frameAdj = m_viewer->getFrameZoomAdjustment();
if (event->button() == Qt::LeftButton) {
assert(getDragTool() == 0);
@@ -2768,7 +2790,7 @@ void CellArea::mousePressEvent(QMouseEvent *event) {
XsheetGUI::DragTool::makeLevelExtenderTool(m_viewer, false, true));
} else if ((!xsh->getCell(row, col).isEmpty()) &&
o->rect(PredefinedRect::DRAG_AREA)
- .adjusted(0, 0, -frameAdj, 0)
+ .adjusted(0, 0, -frameAdj.x(), -frameAdj.y())
.contains(mouseInCell)) {
TXshColumn *column = xsh->getColumn(col);
if (column && !m_viewer->getCellSelection()->isCellSelected(row, col)) {
@@ -2795,7 +2817,7 @@ void CellArea::mousePressEvent(QMouseEvent *event) {
} else {
m_viewer->getKeyframeSelection()->selectNone();
if (isSoundColumn && o->rect(PredefinedRect::PREVIEW_TRACK)
- .adjusted(0, 0, -frameAdj, 0)
+ .adjusted(0, 0, -frameAdj.x(), -frameAdj.y())
.contains(mouseInCell))
setDragTool(XsheetGUI::DragTool::makeSoundScrubTool(
m_viewer, column->getSoundColumn()));
@@ -2818,7 +2840,7 @@ void CellArea::mousePressEvent(QMouseEvent *event) {
void CellArea::mouseMoveEvent(QMouseEvent *event) {
const Orientation *o = m_viewer->orientation();
- int frameAdj = m_viewer->getFrameZoomAdjustment();
+ QPoint frameAdj = m_viewer->getFrameZoomAdjustment();
m_viewer->setQtModifiers(event->modifiers());
setCursor(Qt::ArrowCursor);
@@ -2896,7 +2918,7 @@ void CellArea::mouseMoveEvent(QMouseEvent *event) {
m_tooltip = tr("Set the cycle of previous keyframes");
else if ((!xsh->getCell(row, col).isEmpty()) &&
o->rect(PredefinedRect::DRAG_AREA)
- .adjusted(0, 0, -frameAdj, 0)
+ .adjusted(0, 0, -frameAdj.x(), -frameAdj.y())
.contains(mouseInCell))
m_tooltip = tr("Click and drag to move the selection");
else if (isZeraryColumn)
@@ -2905,7 +2927,7 @@ void CellArea::mouseMoveEvent(QMouseEvent *event) {
->getZeraryFx()
->getName());
else if ((!isSoundColumn && !xsh->getCell(row, col).isEmpty()) && // x > 6 &&
- x < (o->cellWidth() - frameAdj)) {
+ x < (o->cellWidth() - frameAdj.x())) {
TXshCell cell = xsh->getCell(row, col);
TFrameId fid = cell.getFrameId();
std::wstring levelName = cell.m_level->getName();
@@ -2932,7 +2954,7 @@ void CellArea::mouseMoveEvent(QMouseEvent *event) {
QString::fromStdString(frameNumber));
}
} else if (isSoundColumn && o->rect(PredefinedRect::PREVIEW_TRACK)
- .adjusted(0, 0, -frameAdj, 0)
+ .adjusted(0, 0, -frameAdj.x(), -frameAdj.y())
.contains(mouseInCell))
m_tooltip = tr("Click and drag to play");
else if (m_levelExtenderRect.contains(pos))
@@ -2961,7 +2983,6 @@ void CellArea::mouseReleaseEvent(QMouseEvent *event) {
void CellArea::mouseDoubleClickEvent(QMouseEvent *event) {
const Orientation *o = m_viewer->orientation();
- int frameAdj = m_viewer->getFrameZoomAdjustment();
TPoint pos(event->pos().x(), event->pos().y());
CellPosition cellPosition = m_viewer->xyToPosition(event->pos());
int row = cellPosition.frame();
@@ -3009,7 +3030,6 @@ void CellArea::mouseDoubleClickEvent(QMouseEvent *event) {
void CellArea::contextMenuEvent(QContextMenuEvent *event) {
const Orientation *o = m_viewer->orientation();
- int frameAdj = m_viewer->getFrameZoomAdjustment();
TPoint pos(event->pos().x(), event->pos().y());
CellPosition cellPosition = m_viewer->xyToPosition(event->pos());
int row = cellPosition.frame();
diff --git a/toonz/sources/toonz/xshcellviewer.h b/toonz/sources/toonz/xshcellviewer.h
index 43a219a..fe047d1 100644
--- a/toonz/sources/toonz/xshcellviewer.h
+++ b/toonz/sources/toonz/xshcellviewer.h
@@ -104,7 +104,7 @@ class CellArea final : public QWidget {
bool isFolded = false);
void drawFrameMarker(QPainter &p, const QPoint &xy, QColor color,
- bool isKeyFrame = false);
+ bool isKeyFrame = false, bool isCamera = false);
// Restistusce true
bool getEaseHandles(int r0, int r1, double e0, double e1, int &rh0, int &rh1);
diff --git a/toonz/sources/toonz/xsheetviewer.cpp b/toonz/sources/toonz/xsheetviewer.cpp
index 4913be5..2d56bc0 100644
--- a/toonz/sources/toonz/xsheetviewer.cpp
+++ b/toonz/sources/toonz/xsheetviewer.cpp
@@ -14,6 +14,7 @@
#include "toonz/txshpalettelevel.h"
#include "toonz/preferences.h"
#include "toonz/sceneproperties.h"
+#include "toutputproperties.h"
#include "toonzqt/tselectionhandle.h"
#include "toonzqt/icongenerator.h"
#include "cellselection.h"
@@ -40,6 +41,7 @@
#include
#include
#include
+#include
TEnv::IntVar FrameDisplayStyleInXsheetRowArea(
"FrameDisplayStyleInXsheetRowArea", 0);
@@ -360,6 +362,10 @@ const Orientation *XsheetViewer::orientation() const {
void XsheetViewer::flipOrientation() {
m_orientation = orientation()->next();
+
+ int factor = (m_orientation->isVerticalTimeline()) ? m_frameZoomFactor : 100;
+ TApp::instance()->getCurrentXsheet()->notifyZoomScaleChanged(factor);
+
emit orientationChanged(orientation());
}
@@ -413,9 +419,15 @@ void XsheetViewer::positionSections() {
m_rowScrollArea->setGeometry(o->frameLayerRect(
bodyFrame.adjusted(0, -XsheetGUI::SCROLLBAR_WIDTH), headerLayer));
- m_layerFooterPanel->setGeometry(0,
- m_columnScrollArea->geometry().bottom() + 1,
- m_columnScrollArea->width(), 14);
+ if (o->isVerticalTimeline()) {
+ m_layerFooterPanel->setGeometry(m_columnScrollArea->geometry().right() + 1,
+ m_columnScrollArea->geometry().top(), 14,
+ m_columnScrollArea->height());
+ } else {
+ m_layerFooterPanel->setGeometry(0,
+ m_columnScrollArea->geometry().bottom() + 1,
+ m_columnScrollArea->width(), 14);
+ }
m_layerFooterPanel->showOrHide(o);
}
@@ -581,24 +593,36 @@ void XsheetViewer::scroll(QPoint delta) {
//-----------------------------------------------------------------------------
-void XsheetViewer::onPrepareToScrollOffset(const QPoint &offset) {
- refreshContentSize(offset.x(), offset.y());
+void XsheetViewer::onPrepareToScrollOffset(const QPointF &offset) {
+ refreshContentSize((int)offset.x(), (int)offset.y());
}
//-----------------------------------------------------------------------------
-void XsheetViewer::onZoomScrollAdjust(QPoint &offset, bool toZoom) {
- int frameZoomFactor = getFrameZoomFactor();
+void XsheetViewer::onZoomScrollAdjust(QPointF &offset, bool toZoom) {
+ double frameZoomFactor = (double)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;
+ if (orientation()->isVerticalTimeline()) {
+ // toZoom = true: Adjust standardized offset down to zoom factor
+ // toZoom = false: Adjust zoomed offset up to standardized offset
+ double newY;
+ if (toZoom)
+ newY = (offset.y() * frameZoomFactor) / 100.0;
+ else
+ newY = (offset.y() * 100.0) / frameZoomFactor;
- offset.setX(newX);
+ offset.setY(newY);
+ } else {
+ // toZoom = true: Adjust standardized offset down to zoom factor
+ // toZoom = false: Adjust zoomed offset up to standardized offset
+ double newX;
+ if (toZoom)
+ newX = (offset.x() * frameZoomFactor) / 100.0;
+ else
+ newX = (offset.x() * 100.0) / frameZoomFactor;
+
+ offset.setX(newX);
+ }
}
//-----------------------------------------------------------------------------
@@ -777,7 +801,9 @@ CellPosition XsheetViewer::xyToPosition(const QPoint &point) const {
ColumnFan *fan = xsh->getColumnFan(o);
- if (!o->isVerticalTimeline())
+ if (o->isVerticalTimeline())
+ usePoint.setY((usePoint.y() * 100) / getFrameZoomFactor());
+ else
usePoint.setX((usePoint.x() * 100) / getFrameZoomFactor());
if (o->isVerticalTimeline()) return o->xyToPosition(usePoint, fan);
@@ -813,7 +839,9 @@ QPoint XsheetViewer::positionToXY(const CellPosition &pos) const {
ColumnFan *fan = xsh->getColumnFan(o);
QPoint usePoint = o->positionToXY(pos, fan);
- if (!o->isVerticalTimeline())
+ if (o->isVerticalTimeline())
+ usePoint.setY((usePoint.y() * getFrameZoomFactor()) / 100);
+ else
usePoint.setX((usePoint.x() * getFrameZoomFactor()) / 100);
if (o->isVerticalTimeline()) return usePoint;
@@ -847,8 +875,8 @@ int XsheetViewer::columnToLayerAxis(int layer) const {
}
int XsheetViewer::rowToFrameAxis(int frame) const {
int result = orientation()->rowToFrameAxis(frame);
- if (!orientation()->isVerticalTimeline())
- result = (result * getFrameZoomFactor()) / 100;
+ // if (!orientation()->isVerticalTimeline())
+ result = (result * getFrameZoomFactor()) / 100;
return result;
}
@@ -1043,6 +1071,8 @@ void XsheetViewer::showEvent(QShowEvent *) {
assert(ret);
refreshContentSize(0, 0);
changeWindowTitle();
+
+ xsheetHandle->notifyZoomScaleChanged(m_frameZoomFactor);
}
//-----------------------------------------------------------------------------
@@ -1088,6 +1118,8 @@ void XsheetViewer::hideEvent(QHideEvent *) {
disconnect(IconGenerator::instance(), SIGNAL(iconGenerated()), this,
SLOT(updateColumnArea()));
+
+ xsheetHandle->notifyZoomScaleChanged(100);
}
//-----------------------------------------------------------------------------
@@ -1271,10 +1303,12 @@ void XsheetViewer::keyPressEvent(QKeyEvent *event) {
break;
case Qt::Key_End:
- if (orientation()->isVerticalTimeline())
- locals.scrollVertTo((frameCount + 1) * orientation()->cellHeight(),
- visibleRect);
- else {
+ if (orientation()->isVerticalTimeline()) {
+ int y = (((frameCount + 1) * orientation()->cellHeight()) *
+ getFrameZoomFactor()) /
+ 100;
+ locals.scrollVertTo(y, visibleRect);
+ } else {
int x = (((frameCount + 1) * orientation()->cellWidth()) *
getFrameZoomFactor()) /
100;
@@ -1736,6 +1770,7 @@ void XsheetViewer::save(QSettings &settings) const {
settings.setValue("orientation", orientation()->name());
settings.setValue("frameZoomFactor", m_frameZoomFactor);
}
+
void XsheetViewer::load(QSettings &settings) {
QVariant zoomFactor = settings.value("frameZoomFactor");
QVariant name = settings.value("orientation");
@@ -1763,20 +1798,92 @@ TPanel *createXsheetViewer(QWidget *parent)
*/
//----------------------------------------------------------------
+
+QList XsheetViewer::availableFramesPerPage() {
+ int frameRate = TApp::instance()
+ ->getCurrentScene()
+ ->getScene()
+ ->getProperties()
+ ->getOutputProperties()
+ ->getFrameRate();
+ // 1sec, 1.5sec, 2sec, 3sec, 4sec, 6sec
+ QList ret;
+ ret << frameRate;
+ if (frameRate % 2 == 0) ret << frameRate * 3 / 2;
+ ret << frameRate * 2;
+ ret << frameRate * 3;
+ ret << frameRate * 4;
+ ret << frameRate * 6;
+
+ // visible area size
+ int size = (orientation()->isVerticalTimeline())
+ ? m_cellScrollArea->viewport()->height()
+ : m_cellScrollArea->viewport()->width();
+ int scaleMin = (orientation()->isVerticalTimeline()) ? 50 : 20;
+ int scaleMax = 100;
+
+ int frameMin = (int)std::ceil(
+ (double)size /
+ ((double)orientation()->dimension(PredefinedDimension::FRAME) *
+ (double)scaleMax / 100.0));
+ int frameMax = (int)std::floor(
+ (double)size /
+ ((double)orientation()->dimension(PredefinedDimension::FRAME) *
+ (double)scaleMin / 100.0));
+
+ for (auto itr = ret.begin(); itr != ret.end();) {
+ // erase unavailable items
+ if (*itr < frameMin || *itr > frameMax) {
+ itr = ret.erase(itr);
+ continue;
+ }
+ itr++;
+ }
+ return ret;
+}
+
+//----------------------------------------------------------------
+
+void XsheetViewer::zoomToFramesPerPage(int frames) {
+ int size = (orientation()->isVerticalTimeline())
+ ? m_cellScrollArea->viewport()->height()
+ : m_cellScrollArea->viewport()->width();
+ int frameDim = orientation()->dimension(PredefinedDimension::FRAME);
+
+ double scale = (double)size / ((double)frameDim * (double)frames);
+
+ // convert to factor value
+ int factor;
+ if (orientation()->isVerticalTimeline())
+ factor = (int)std::round((0.2 + (scale - 0.5) * 8.0 / 5.0) * 100);
+ else
+ factor = (int)std::round(scale * 100);
+
+ zoomOnFrame(getCurrentRow(), factor);
+}
+
+//----------------------------------------------------------------
int XsheetViewer::getFrameZoomFactor() const {
- if (orientation()->isVerticalTimeline()) return 100;
+ if (orientation()->isVerticalTimeline())
+ return 50 + (m_frameZoomFactor - 20) * 5 / 8;
return m_frameZoomFactor;
}
-int XsheetViewer::getFrameZoomAdjustment() {
- if (orientation()->isVerticalTimeline()) return 0;
+QPoint XsheetViewer::getFrameZoomAdjustment() {
+ // if (orientation()->isVerticalTimeline()) return 0;
QRect frameRect = orientation()->rect(PredefinedRect::FRAME_HEADER);
- int adj = frameRect.width() -
- ((frameRect.width() * getFrameZoomFactor()) / 100) - 1;
-
- return std::max(0, adj);
+ int adj;
+ if (orientation()->isVerticalTimeline()) {
+ adj = frameRect.height() -
+ ((frameRect.height() * getFrameZoomFactor()) / 100) - 1;
+ return QPoint(0, std::max(0, adj));
+ } else {
+ adj = frameRect.width() -
+ ((frameRect.width() * getFrameZoomFactor()) / 100) - 1;
+ return QPoint(std::max(0, adj), 0);
+ }
}
void XsheetViewer::zoomOnFrame(int frame, int factor) {
@@ -1787,11 +1894,11 @@ void XsheetViewer::zoomOnFrame(int frame, int factor) {
QPoint xyNew = positionToXY(CellPosition(frame, -1));
- int viewShift = xyNew.x() - xyOrig.x();
-
- scroll(QPoint(viewShift, 0));
+ scroll(xyNew - xyOrig);
TApp::instance()->getCurrentXsheet()->notifyXsheetChanged();
+ if (orientation()->isVerticalTimeline())
+ TApp::instance()->getCurrentXsheet()->notifyZoomScaleChanged(factor);
m_rowArea->update();
}
diff --git a/toonz/sources/toonz/xsheetviewer.h b/toonz/sources/toonz/xsheetviewer.h
index 7cc073e..ddb51cc 100644
--- a/toonz/sources/toonz/xsheetviewer.h
+++ b/toonz/sources/toonz/xsheetviewer.h
@@ -1253,6 +1253,9 @@ public:
virtual void load(QSettings &settings) override;
QString getXsheetLayout() const { return m_xsheetLayout; }
+ // returns a list of frame amount per page displayable in the current size
+ QList availableFramesPerPage();
+ void zoomToFramesPerPage(int frames);
protected:
void scrollToColumn(int col);
@@ -1302,12 +1305,12 @@ public slots:
void resetXsheetNotes();
void onOrientationChanged(const Orientation *newOrientation);
- void onPrepareToScrollOffset(const QPoint &offset);
- void onZoomScrollAdjust(QPoint &offset, bool toZoom);
+ void onPrepareToScrollOffset(const QPointF &offset);
+ void onZoomScrollAdjust(QPointF &offset, bool toZoom);
void setFrameZoomFactor(int f) { m_frameZoomFactor = f; }
int getFrameZoomFactor() const;
- int getFrameZoomAdjustment();
+ QPoint getFrameZoomAdjustment();
void zoomOnFrame(int frame, int factor);
};
diff --git a/toonz/sources/toonz/xshrowviewer.cpp b/toonz/sources/toonz/xshrowviewer.cpp
index 088741b..5c59ffb 100644
--- a/toonz/sources/toonz/xshrowviewer.cpp
+++ b/toonz/sources/toonz/xshrowviewer.cpp
@@ -121,7 +121,9 @@ void RowArea::drawRows(QPainter &p, int r0, int r1) {
int y1 = visibleRect.bottom();
NumberRange layerSide = o->layerSide(visibleRect);
- int frameAdj = m_viewer->getFrameZoomAdjustment();
+ QPoint frameAdj = m_viewer->getFrameZoomAdjustment();
+ bool simpleView = m_viewer->getFrameZoomFactor() <=
+ o->dimension(PredefinedDimension::SCALE_THRESHOLD);
for (int r = r0; r <= r1; r++) {
int frameAxis = m_viewer->rowToFrameAxis(r);
@@ -161,7 +163,8 @@ void RowArea::drawRows(QPainter &p, int r0, int r1) {
QRect labelRect = m_viewer->orientation()
->rect(PredefinedRect::FRAME_LABEL)
.translated(basePoint);
- labelRect.adjust(-frameAdj / 2, 0, -frameAdj / 2, 0);
+ labelRect.adjust(-frameAdj.x() / 2, -frameAdj.y() / 2, -frameAdj.x() / 2,
+ -frameAdj.y() / 2);
int align = m_viewer->orientation()->dimension(
PredefinedDimension::FRAME_LABEL_ALIGN);
// display time and/or frame number
@@ -185,7 +188,7 @@ void RowArea::drawRows(QPainter &p, int r0, int r1) {
.arg(QString::number(koma).rightJustified(2, '0'));
z = 0;
} else {
- if (!o->isVerticalTimeline() && m_viewer->getFrameZoomFactor() <= 50) {
+ if (simpleView) {
if ((z + 1) % zz) break;
if (r % frameRate == 1 || (r + 2) % frameRate == 1) break;
}
@@ -199,9 +202,7 @@ void RowArea::drawRows(QPainter &p, int r0, int r1) {
}
case XsheetViewer::Frame: {
- if (!o->isVerticalTimeline() && m_viewer->getFrameZoomFactor() <= 50 &&
- r > 0 && (r + 1) % (distance > 0 ? distance : 5))
- break;
+ if (simpleView && r > 0 && (r + 1) % (distance > 0 ? distance : 5)) break;
QString number = QString::number(r + 1);
p.drawText(labelRect, align, number);
break;
@@ -226,7 +227,7 @@ void RowArea::drawRows(QPainter &p, int r0, int r1) {
.arg(QString::number(koma).rightJustified(3, '0'));
z = 0;
} else {
- if (!o->isVerticalTimeline() && m_viewer->getFrameZoomFactor() <= 50) {
+ if (simpleView) {
if ((z + 1) % zz) break;
if (r % frameRate == 1 || (r + 2) % frameRate == 1) break;
}
@@ -255,7 +256,7 @@ void RowArea::drawRows(QPainter &p, int r0, int r1) {
.arg(QString::number(koma).rightJustified(2, '0'));
z = 0;
} else {
- if (!o->isVerticalTimeline() && m_viewer->getFrameZoomFactor() <= 50) {
+ if (simpleView) {
if ((z + 1) % zz) break;
if (r % frameRate == 1 || (r + 2) % frameRate == 1) break;
}
@@ -275,7 +276,7 @@ void RowArea::drawPlayRangeBackground(QPainter &p, int r0, int r1) {
const Orientation *o = m_viewer->orientation();
TXsheet *xsh = m_viewer->getXsheet();
- int frameAdj = m_viewer->getFrameZoomAdjustment();
+ QPoint frameAdj = m_viewer->getFrameZoomAdjustment();
QRect playRangeRect = o->rect(PredefinedRect::PLAY_RANGE);
int playR0, playR1, step;
@@ -291,7 +292,7 @@ void RowArea::drawPlayRangeBackground(QPainter &p, int r0, int r1) {
basePoint.setX(0);
QRect previewBoxRect = o->rect(PredefinedRect::PREVIEW_FRAME_AREA)
- .adjusted(0, 0, -frameAdj, 0)
+ .adjusted(0, 0, -frameAdj.x(), -frameAdj.y())
.translated(basePoint);
p.fillRect(previewBoxRect, m_viewer->getPlayRangeColor());
@@ -313,7 +314,7 @@ void RowArea::drawPlayRangeBackground(QPainter &p, int r0, int r1) {
void RowArea::drawPlayRange(QPainter &p, int r0, int r1) {
bool playRangeEnabled = XsheetGUI::isPlayRangeEnabled();
- int frameAdj = m_viewer->getFrameZoomAdjustment();
+ QPoint frameAdj = m_viewer->getFrameZoomAdjustment();
TXsheet *xsh = m_viewer->getXsheet();
// Update the play range internal fields
@@ -344,7 +345,7 @@ void RowArea::drawPlayRange(QPainter &p, int r0, int r1) {
if (m_r1 > r0 - 1 && r1 + 1 > m_r1) {
QPoint topLeft = m_viewer->positionToXY(CellPosition(m_r1, -1));
- topLeft.setX(topLeft.x() - frameAdj);
+ topLeft -= frameAdj;
if (!m_viewer->orientation()->isVerticalTimeline())
topLeft.setY(0);
else
@@ -368,8 +369,8 @@ void RowArea::drawCurrentRowGadget(QPainter &p, int r0, int r1) {
QRect header = m_viewer->orientation()
->rect(PredefinedRect::FRAME_HEADER)
.translated(topLeft);
- int frameAdj = m_viewer->getFrameZoomAdjustment();
- header.adjust(1, 1, -frameAdj, 0);
+ QPoint frameAdj = m_viewer->getFrameZoomAdjustment();
+ header.adjust(1, 1, -frameAdj.x(), -frameAdj.y());
p.fillRect(header, m_viewer->getCurrentRowBgColor());
}
@@ -385,8 +386,8 @@ void RowArea::drawStopMotionCameraIndicator(QPainter &p) {
QRect header = m_viewer->orientation()
->rect(PredefinedRect::FRAME_HEADER)
.translated(topLeft);
- int frameAdj = m_viewer->getFrameZoomAdjustment();
- header.adjust(1, 1, -frameAdj, 0);
+ QPoint frameAdj = m_viewer->getFrameZoomAdjustment();
+ header.adjust(1, 1, -frameAdj.x(), -frameAdj.y());
p.fillRect(header, Qt::GlobalColor::darkGreen);
}
@@ -396,7 +397,7 @@ void RowArea::drawStopMotionCameraIndicator(QPainter &p) {
void RowArea::drawOnionSkinBackground(QPainter &p, int r0, int r1) {
const Orientation *o = m_viewer->orientation();
- int frameAdj = m_viewer->getFrameZoomAdjustment();
+ QPoint frameAdj = m_viewer->getFrameZoomAdjustment();
for (int r = r0; r <= r1; r++) {
QPoint basePoint = m_viewer->positionToXY(CellPosition(r, -1));
@@ -407,7 +408,7 @@ void RowArea::drawOnionSkinBackground(QPainter &p, int r0, int r1) {
QRect oRect = m_viewer->orientation()
->rect(PredefinedRect::ONION_AREA)
- .adjusted(0, 0, -frameAdj, 0)
+ .adjusted(0, 0, -frameAdj.x(), -frameAdj.y())
.translated(basePoint);
p.fillRect(oRect, m_viewer->getOnionSkinAreaBgColor());
}
@@ -423,7 +424,7 @@ void RowArea::drawOnionSkinSelection(QPainter &p) {
assert(xsh);
int currentRow = m_viewer->getCurrentRow();
- int frameAdj = m_viewer->getFrameZoomAdjustment();
+ QPoint frameAdj = m_viewer->getFrameZoomAdjustment();
// get onion colors
TPixel frontPixel, backPixel;
@@ -482,13 +483,16 @@ void RowArea::drawOnionSkinSelection(QPainter &p) {
if (maxMos < mos) maxMos = mos;
}
p.setBrush(Qt::NoBrush);
+ int frameAdj_i = (m_viewer->orientation()->isVerticalTimeline())
+ ? frameAdj.y()
+ : frameAdj.x();
if (minMos < 0) // previous frames
{
int layerAxis = onionCenter_layer;
int fromFrameAxis = m_viewer->rowToFrameAxis(currentRow + minMos) +
- onionCenter_frame - (frameAdj / 2);
+ onionCenter_frame - (frameAdj_i / 2);
int toFrameAxis = m_viewer->rowToFrameAxis(currentRow) + onionCenter_frame -
- (frameAdj / 2);
+ (frameAdj_i / 2);
QLine verticalLine = m_viewer->orientation()->verticalLine(
layerAxis, NumberRange(fromFrameAxis, toFrameAxis));
p.setPen(backPen);
@@ -503,9 +507,9 @@ void RowArea::drawOnionSkinSelection(QPainter &p) {
{
int layerAxis = onionCenter_layer;
int fromFrameAxis = m_viewer->rowToFrameAxis(currentRow) +
- onionCenter_frame - (frameAdj / 2);
+ onionCenter_frame - (frameAdj_i / 2);
int toFrameAxis = m_viewer->rowToFrameAxis(currentRow + maxMos) +
- onionCenter_frame - (frameAdj / 2);
+ onionCenter_frame - (frameAdj_i / 2);
QLine verticalLine = m_viewer->orientation()->verticalLine(
layerAxis, NumberRange(fromFrameAxis, toFrameAxis));
p.setPen(frontPen);
@@ -522,8 +526,8 @@ void RowArea::drawOnionSkinSelection(QPainter &p) {
handleTopLeft.setY(0);
else
handleTopLeft.setX(0);
- QRect handleRect = onionRect.translated(handleTopLeft);
- handleRect.adjust(-frameAdj / 2, 0, -frameAdj / 2, 0);
+ QRect handleRect =
+ onionRect.translated(handleTopLeft).translated(-frameAdj / 2);
int angle180 = 16 * 180;
int turn =
m_viewer->orientation()->dimension(PredefinedDimension::ONION_TURN) * 16;
@@ -553,8 +557,8 @@ void RowArea::drawOnionSkinSelection(QPainter &p) {
topLeft.setX(0);
QRect dotRect = m_viewer->orientation()
->rect(PredefinedRect::ONION_DOT)
- .translated(topLeft);
- dotRect.adjust(-frameAdj / 2, 0, -frameAdj / 2, 0);
+ .translated(topLeft)
+ .translated(-frameAdj / 2);
p.drawEllipse(dotRect);
}
@@ -585,8 +589,8 @@ void RowArea::drawOnionSkinSelection(QPainter &p) {
topLeft.setX(0);
QRect dotRect = m_viewer->orientation()
->rect(PredefinedRect::ONION_DOT_FIXED)
- .translated(topLeft);
- dotRect.adjust(-frameAdj / 2, 0, -frameAdj / 2, 0);
+ .translated(topLeft)
+ .translated(-frameAdj / 2);
p.drawEllipse(dotRect);
}
@@ -603,8 +607,8 @@ void RowArea::drawOnionSkinSelection(QPainter &p) {
m_viewer->orientation()
->rect(m_showOnionToSet == Fos ? PredefinedRect::ONION_DOT_FIXED
: PredefinedRect::ONION_DOT)
- .translated(topLeft);
- dotRect.adjust(-frameAdj / 2, 0, -frameAdj / 2, 0);
+ .translated(topLeft)
+ .translated(-frameAdj / 2);
p.drawEllipse(dotRect);
}
}
@@ -612,8 +616,8 @@ void RowArea::drawOnionSkinSelection(QPainter &p) {
//-----------------------------------------------------------------------------
void RowArea::drawCurrentTimeIndicator(QPainter &p) {
- int frameAdj = m_viewer->getFrameZoomAdjustment();
- int currentRow = m_viewer->getCurrentRow();
+ QPoint frameAdj = m_viewer->getFrameZoomAdjustment();
+ int currentRow = m_viewer->getCurrentRow();
QPoint topLeft = m_viewer->positionToXY(CellPosition(currentRow, -1));
if (!m_viewer->orientation()->isVerticalTimeline())
@@ -622,8 +626,8 @@ void RowArea::drawCurrentTimeIndicator(QPainter &p) {
topLeft.setX(0);
QRect header = m_viewer->orientation()
->rect(PredefinedRect::FRAME_HEADER)
- .adjusted(-frameAdj / 2, 0, -frameAdj / 2, 0)
- .translated(topLeft);
+ .translated(topLeft)
+ .translated(-frameAdj / 2);
int frameMid = header.left() + (header.width() / 2) - 1;
int frameTop = header.top() + 22;
@@ -639,8 +643,8 @@ void RowArea::drawCurrentTimeIndicator(QPainter &p) {
}
void RowArea::drawCurrentTimeLine(QPainter &p) {
- int frameAdj = m_viewer->getFrameZoomAdjustment();
- int currentRow = m_viewer->getCurrentRow();
+ QPoint frameAdj = m_viewer->getFrameZoomAdjustment();
+ int currentRow = m_viewer->getCurrentRow();
QPoint topLeft = m_viewer->positionToXY(CellPosition(currentRow, -1));
if (!m_viewer->orientation()->isVerticalTimeline())
@@ -649,8 +653,8 @@ void RowArea::drawCurrentTimeLine(QPainter &p) {
topLeft.setX(0);
QRect header = m_viewer->orientation()
->rect(PredefinedRect::FRAME_HEADER)
- .adjusted(-frameAdj / 2, 0, -frameAdj / 2, 0)
- .translated(topLeft);
+ .translated(topLeft)
+ .translated(-frameAdj / 2);
int frameMid = header.left() + (header.width() / 2) - 1;
int frameTop = header.top();
@@ -670,7 +674,10 @@ void RowArea::drawShiftTraceMarker(QPainter &p) {
assert(xsh);
int currentRow = m_viewer->getCurrentRow();
- int frameAdj = m_viewer->getFrameZoomAdjustment();
+ QPoint frameAdj = m_viewer->getFrameZoomAdjustment();
+ int frameAdj_i = (m_viewer->orientation()->isVerticalTimeline())
+ ? frameAdj.y()
+ : frameAdj.x();
// get onion colors
TPixel frontPixel, backPixel;
@@ -694,9 +701,9 @@ void RowArea::drawShiftTraceMarker(QPainter &p) {
{
int layerAxis = onionCenter_layer;
int fromFrameAxis = m_viewer->rowToFrameAxis(currentRow + prevOffset) +
- onionCenter_frame - (frameAdj / 2);
+ onionCenter_frame - (frameAdj_i / 2);
int toFrameAxis = m_viewer->rowToFrameAxis(currentRow) + onionCenter_frame -
- (frameAdj / 2);
+ (frameAdj_i / 2);
QLine verticalLine = m_viewer->orientation()->verticalLine(
layerAxis, NumberRange(fromFrameAxis, toFrameAxis));
p.setPen(backColor);
@@ -707,9 +714,9 @@ void RowArea::drawShiftTraceMarker(QPainter &p) {
{
int layerAxis = onionCenter_layer;
int fromFrameAxis = m_viewer->rowToFrameAxis(currentRow) +
- onionCenter_frame - (frameAdj / 2);
+ onionCenter_frame - (frameAdj_i / 2);
int toFrameAxis = m_viewer->rowToFrameAxis(currentRow + forwardOffset) +
- onionCenter_frame - (frameAdj / 2);
+ onionCenter_frame - (frameAdj_i / 2);
QLine verticalLine = m_viewer->orientation()->verticalLine(
layerAxis, NumberRange(fromFrameAxis, toFrameAxis));
p.setPen(frontColor);
@@ -739,8 +746,8 @@ void RowArea::drawShiftTraceMarker(QPainter &p) {
topLeft.setX(0);
QRect dotRect = m_viewer->orientation()
->rect(PredefinedRect::SHIFTTRACE_DOT)
- .translated(topLeft);
- dotRect.adjust(-frameAdj / 2, 0, -frameAdj / 2, 0);
+ .translated(topLeft)
+ .translated(-frameAdj / 2);
p.drawRect(dotRect);
// draw shortcut numbers
p.setPen(Qt::black);
@@ -759,8 +766,8 @@ void RowArea::drawShiftTraceMarker(QPainter &p) {
topLeft.setX(0);
QRect dotRect = m_viewer->orientation()
->rect(PredefinedRect::SHIFTTRACE_DOT)
- .translated(topLeft);
- dotRect.adjust(-frameAdj / 2, 0, -frameAdj / 2, 0);
+ .translated(topLeft)
+ .translated(-frameAdj / 2);
p.drawRect(dotRect);
}
}
@@ -805,11 +812,11 @@ void RowArea::drawPinnedCenterKeys(QPainter &p, int r0, int r1) {
int columnCount = xsh->getColumnCount();
int prev_pinnedCol = -2;
- int frameAdj = m_viewer->getFrameZoomAdjustment();
+ QPoint frameAdj = m_viewer->getFrameZoomAdjustment();
QRect keyRect = m_viewer->orientation()
->rect(PredefinedRect::PINNED_CENTER_KEY)
- .adjusted(-frameAdj / 2, 0, -frameAdj / 2, 0);
+ .translated(-frameAdj / 2);
p.setPen(Qt::black);
r1 = (r1 < xsh->getFrameCount() - 1) ? xsh->getFrameCount() - 1 : r1;
@@ -933,11 +940,11 @@ void RowArea::mousePressEvent(QMouseEvent *event) {
else
topLeft.setX(0);
QPoint mouseInCell = event->pos() - topLeft;
- int frameAdj = m_viewer->getFrameZoomAdjustment();
+ QPoint frameAdj = m_viewer->getFrameZoomAdjustment();
if (CommandManager::instance()->getAction(MI_ShiftTrace)->isChecked() &&
o->rect(PredefinedRect::SHIFTTRACE_DOT_AREA)
- .adjusted(0, 0, -frameAdj, 0)
+ .adjusted(0, 0, -frameAdj.x(), -frameAdj.y())
.contains(mouseInCell)) {
// Reset ghosts to neighbor frames
if (row == currentFrame)
@@ -968,19 +975,19 @@ void RowArea::mousePressEvent(QMouseEvent *event) {
->isChecked() &&
Preferences::instance()->isOnionSkinEnabled() &&
o->rect(PredefinedRect::ONION_AREA)
- .adjusted(0, 0, -frameAdj, 0)
+ .adjusted(0, 0, -frameAdj.x(), -frameAdj.y())
.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)
+ .adjusted(0, 0, -frameAdj.x(), -frameAdj.y())
.contains(mouseInCell))
setDragTool(XsheetGUI::DragTool::makeKeyOnionSkinMaskModifierTool(
m_viewer, true));
else if (o->rect(PredefinedRect::ONION_DOT_AREA)
- .adjusted(0, 0, -frameAdj, 0)
+ .adjusted(0, 0, -frameAdj.x(), -frameAdj.y())
.contains(mouseInCell))
setDragTool(XsheetGUI::DragTool::makeKeyOnionSkinMaskModifierTool(
m_viewer, false));
@@ -1000,7 +1007,7 @@ void RowArea::mousePressEvent(QMouseEvent *event) {
XsheetGUI::DragTool::makeCurrentFrameModifierTool(m_viewer));
frameAreaIsClicked = true;
} else if (o->rect(PredefinedRect::PLAY_RANGE)
- .adjusted(0, 0, -frameAdj, 0)
+ .adjusted(0, 0, -frameAdj.x(), -frameAdj.y())
.contains(mouseInCell) &&
(row == playR0 || row == playR1)) {
if (!playRangeEnabled) XsheetGUI::setPlayRange(playR0, playR1, step);
@@ -1076,10 +1083,10 @@ void RowArea::mouseMoveEvent(QMouseEvent *event) {
if (getDragTool()) return;
- int currentRow = TApp::instance()->getCurrentFrame()->getFrame();
- int row = m_viewer->xyToPosition(m_pos).frame();
- int frameAdj = m_viewer->getFrameZoomAdjustment();
- QPoint topLeft = m_viewer->positionToXY(CellPosition(row, -1));
+ int currentRow = TApp::instance()->getCurrentFrame()->getFrame();
+ int row = m_viewer->xyToPosition(m_pos).frame();
+ QPoint frameAdj = m_viewer->getFrameZoomAdjustment();
+ QPoint topLeft = m_viewer->positionToXY(CellPosition(row, -1));
if (!m_viewer->orientation()->isVerticalTimeline())
topLeft.setY(0);
else
@@ -1092,7 +1099,7 @@ void RowArea::mouseMoveEvent(QMouseEvent *event) {
// whether to show ability to move the shift and trace ghost frame
if (CommandManager::instance()->getAction(MI_ShiftTrace)->isChecked()) {
if (o->rect(PredefinedRect::SHIFTTRACE_DOT_AREA)
- .adjusted(0, 0, -frameAdj, 0)
+ .adjusted(0, 0, -frameAdj.x(), -frameAdj.y())
.contains(mouseInCell)) {
m_showOnionToSet = ShiftTraceGhost;
@@ -1119,11 +1126,11 @@ void RowArea::mouseMoveEvent(QMouseEvent *event) {
// whether to show ability to set onion marks
else if (Preferences::instance()->isOnionSkinEnabled() && row != currentRow) {
if (o->rect(PredefinedRect::ONION_FIXED_DOT_AREA)
- .adjusted(0, 0, -frameAdj, 0)
+ .adjusted(0, 0, -frameAdj.x(), -frameAdj.y())
.contains(mouseInCell))
m_showOnionToSet = Fos;
else if (o->rect(PredefinedRect::ONION_DOT_AREA)
- .adjusted(0, 0, -frameAdj, 0)
+ .adjusted(0, 0, -frameAdj.x(), -frameAdj.y())
.contains(mouseInCell))
m_showOnionToSet = Mos;
}
@@ -1134,7 +1141,7 @@ void RowArea::mouseMoveEvent(QMouseEvent *event) {
int pinnedCenterColumnId = -1;
if (TApp::instance()->getCurrentTool()->getTool()->getName() == T_Skeleton &&
o->rect(PredefinedRect::PINNED_CENTER_KEY)
- .adjusted(-frameAdj / 2, 0, -frameAdj / 2, 0)
+ .translated(-frameAdj / 2)
.contains(mouseInCell)) {
int col = m_viewer->getCurrentColumn();
TXsheet *xsh = m_viewer->getXsheet();
@@ -1185,7 +1192,7 @@ void RowArea::mouseMoveEvent(QMouseEvent *event) {
else if (row == currentRow) {
if (Preferences::instance()->isOnionSkinEnabled() &&
o->rect(PredefinedRect::ONION)
- .adjusted(-frameAdj / 2, 0, -frameAdj / 2, 0)
+ .translated(-frameAdj / 2)
.contains(mouseInCell))
m_tooltip = tr("Double Click to Toggle Onion Skin");
else
@@ -1295,7 +1302,7 @@ int RowArea::getNonEmptyCell(int row, int column, Direction direction) {
void RowArea::mouseDoubleClickEvent(QMouseEvent *event) {
int currentFrame = TApp::instance()->getCurrentFrame()->getFrame();
int row = m_viewer->xyToPosition(event->pos()).frame();
- int frameAdj = m_viewer->getFrameZoomAdjustment();
+ QPoint frameAdj = m_viewer->getFrameZoomAdjustment();
QPoint topLeft = m_viewer->positionToXY(CellPosition(row, -1));
if (!m_viewer->orientation()->isVerticalTimeline())
topLeft.setY(0);
@@ -1307,7 +1314,7 @@ void RowArea::mouseDoubleClickEvent(QMouseEvent *event) {
Preferences::instance()->isOnionSkinEnabled() && row == currentFrame &&
m_viewer->orientation()
->rect(PredefinedRect::ONION)
- .adjusted(-frameAdj / 2, 0, -frameAdj / 2, 0)
+ .translated(-frameAdj / 2)
.contains(mouseInCell)) {
TOnionSkinMaskHandle *osmh = TApp::instance()->getCurrentOnionSkin();
OnionSkinMask osm = osmh->getOnionSkinMask();
diff --git a/toonz/sources/toonzlib/CMakeLists.txt b/toonz/sources/toonzlib/CMakeLists.txt
index e382fee..70b8871 100644
--- a/toonz/sources/toonzlib/CMakeLists.txt
+++ b/toonz/sources/toonzlib/CMakeLists.txt
@@ -169,7 +169,6 @@ set(SOURCES
autoclose.cpp
autopos.cpp
captureparameters.cpp
- cellpositionratio.cpp
childstack.cpp
cleanupcolorstyles.cpp
cleanuppalette.cpp
diff --git a/toonz/sources/toonzlib/cellpositionratio.cpp b/toonz/sources/toonzlib/cellpositionratio.cpp
deleted file mode 100644
index f3286ec..0000000
--- a/toonz/sources/toonzlib/cellpositionratio.cpp
+++ /dev/null
@@ -1,68 +0,0 @@
-#include "toonz/cellpositionratio.h"
-
-#include
-#include
-
-// Euclid's algorithm
-static int greatestCommonDivisor(int a, int b) {
- a = std::abs(a);
- b = std::abs(b);
- int c = std::max(a, b);
- int d = std::min(a, b);
- while (d) {
- int q = c / d;
- int r = c % d;
- c = d;
- d = r;
- }
- return c;
-}
-
-#if 0 /* UNUSED */
-int leastCommonMultiple(int a, int b) {
- return a * b / greatestCommonDivisor(a, b);
-}
-#endif
-
-void Ratio::normalize() {
- int gcd = greatestCommonDivisor(m_num, m_denom);
- if (m_denom < 0) gcd = -gcd;
- m_num /= gcd;
- m_denom /= gcd;
-}
-
-Ratio Ratio::normalized() const {
- Ratio copy(*this);
- copy.normalize();
- return copy;
-}
-
-Ratio::Ratio(int num, int denom) : m_num(num), m_denom(denom) {
- if (!denom) throw std::runtime_error("ratio with denominator == 0");
- normalize();
-}
-
-Ratio operator*(const Ratio &a, const Ratio &b) {
- return Ratio(a.m_num * b.m_num, a.m_denom * b.m_denom);
-}
-Ratio operator/(const Ratio &a, const Ratio &b) {
- return Ratio(a.m_num * b.m_denom, a.m_denom * b.m_num);
-}
-
-Ratio operator+(const Ratio &a, const Ratio &b) {
- int gcd = greatestCommonDivisor(a.m_denom, b.m_denom);
- int denom = a.m_denom * b.m_denom / gcd;
- int aMult = b.m_denom * gcd;
- int bMult = a.m_denom * gcd;
- return Ratio(a.m_num * aMult + b.m_num * bMult, denom);
-}
-
-Ratio operator-(const Ratio &a, const Ratio &b) {
- int gcd = greatestCommonDivisor(a.m_denom, b.m_denom);
- int denom = a.m_denom * b.m_denom / gcd;
- int aMult = b.m_denom * gcd;
- int bMult = a.m_denom * gcd;
- return Ratio(a.m_num * aMult - b.m_num * bMult, denom);
-}
-
-int operator*(const Ratio &a, int b) { return a.m_num * b / a.m_denom; }
diff --git a/toonz/sources/toonzlib/orientation.cpp b/toonz/sources/toonzlib/orientation.cpp
index 7f7e79e..e5dbfb6 100644
--- a/toonz/sources/toonzlib/orientation.cpp
+++ b/toonz/sources/toonzlib/orientation.cpp
@@ -42,11 +42,12 @@ class TopToBottomOrientation : public Orientation {
const int FRAME_HEADER_WIDTH = CELL_WIDTH;
const int PLAY_RANGE_X = FRAME_HEADER_WIDTH / 2 - PLAY_MARKER_SIZE;
const int ONION_X = 0, ONION_Y = 0;
- const int ICON_WIDTH = 18;
- const int ICON_HEIGHT = 18;
- const int TRACKLEN = 60;
- const int SHIFTTRACE_DOT_OFFSET = 3;
- const int CAMERA_CELL_WIDTH = 22;
+ const int ICON_WIDTH = 18;
+ const int ICON_HEIGHT = 18;
+ const int TRACKLEN = 60;
+ const int SHIFTTRACE_DOT_OFFSET = 3;
+ const int CAMERA_CELL_WIDTH = 22;
+ const int LAYER_FOOTER_PANEL_WIDTH = 16;
public:
TopToBottomOrientation();
@@ -55,8 +56,8 @@ public:
const ColumnFan *fan) const override;
virtual QPoint positionToXY(const CellPosition &position,
const ColumnFan *fan) const override;
- virtual CellPositionRatio xyToPositionRatio(const QPoint &xy) const override;
- virtual QPoint positionRatioToXY(
+ virtual CellPositionRatio xyToPositionRatio(const QPointF &xy) const override;
+ virtual QPointF positionRatioToXY(
const CellPositionRatio &ratio) const override;
virtual int colToLayerAxis(int layer, const ColumnFan *fan) const override;
@@ -120,8 +121,8 @@ public:
const ColumnFan *fan) const override;
virtual QPoint positionToXY(const CellPosition &position,
const ColumnFan *fan) const override;
- virtual CellPositionRatio xyToPositionRatio(const QPoint &xy) const override;
- virtual QPoint positionRatioToXY(
+ virtual CellPositionRatio xyToPositionRatio(const QPointF &xy) const override;
+ virtual QPointF positionRatioToXY(
const CellPositionRatio &ratio) const override;
virtual int colToLayerAxis(int layer, const ColumnFan *fan) const override;
@@ -327,7 +328,12 @@ TopToBottomOrientation::TopToBottomOrientation() {
addRect(PredefinedRect::LOOP_ICON, QRect(keyRect.left(), 0, 10, 11));
addRect(PredefinedRect::CAMERA_LOOP_ICON,
QRect(cameraKeyRect.left(), 0, 10, 11));
- addRect(PredefinedRect::FRAME_MARKER_AREA, QRect(0, 0, -1, -1)); // hide
+ QRect frameMarker(CELL_WIDTH - FRAME_MARKER_SIZE - 4,
+ (CELL_HEIGHT - FRAME_MARKER_SIZE) / 2, FRAME_MARKER_SIZE,
+ FRAME_MARKER_SIZE);
+ addRect(PredefinedRect::FRAME_MARKER_AREA, frameMarker);
+ addRect(PredefinedRect::CAMERA_FRAME_MARKER_AREA,
+ cameraKeyRect.translated(-1, 0));
// Note viewer
addRect(
@@ -345,7 +351,7 @@ TopToBottomOrientation::TopToBottomOrientation() {
// Row viewer
addRect(PredefinedRect::FRAME_LABEL,
- QRect(CELL_WIDTH / 2, 1, CELL_WIDTH / 2, CELL_HEIGHT - 2));
+ QRect(0, 0, CELL_WIDTH - 4, CELL_HEIGHT));
addRect(PredefinedRect::FRAME_HEADER,
QRect(0, 0, FRAME_HEADER_WIDTH, CELL_HEIGHT));
addRect(PredefinedRect::PLAY_RANGE,
@@ -743,11 +749,30 @@ TopToBottomOrientation::TopToBottomOrientation() {
}
// Layer footer panel
+ QRect layerFooterPanel(
+ QRect(0, 0, LAYER_FOOTER_PANEL_WIDTH + 2, use_header_height));
+ addRect(PredefinedRect::LAYER_FOOTER_PANEL, layerFooterPanel);
+
+ QRect zoomSlider, zoomIn, zoomOut;
+
+ zoomSlider = QRect(0, 17, LAYER_FOOTER_PANEL_WIDTH, use_header_height - 34);
+ addRect(PredefinedRect::ZOOM_SLIDER_AREA, zoomSlider);
+ addRect(PredefinedRect::ZOOM_SLIDER, zoomSlider.adjusted(0, 1, 0, 0));
+
+ zoomIn = QRect(0, zoomSlider.bottom() + 1, LAYER_FOOTER_PANEL_WIDTH, 16);
+ addRect(PredefinedRect::ZOOM_IN_AREA, zoomIn);
+ addRect(PredefinedRect::ZOOM_IN, zoomIn.adjusted(1, 1, 0, 0));
+
+ zoomOut = QRect(0, zoomSlider.top() - 17, LAYER_FOOTER_PANEL_WIDTH, 16);
+ addRect(PredefinedRect::ZOOM_OUT_AREA, zoomOut);
+ addRect(PredefinedRect::ZOOM_OUT, zoomOut.adjusted(1, 1, 0, 0));
+ /*
+ // Layer footer panel
addRect(PredefinedRect::LAYER_FOOTER_PANEL, QRect(0, 0, -1, -1)); // hide
addRect(PredefinedRect::ZOOM_SLIDER, QRect(0, 0, -1, -1));
addRect(PredefinedRect::ZOOM_IN, QRect(0, 0, -1, -1));
addRect(PredefinedRect::ZOOM_OUT, QRect(0, 0, -1, -1));
-
+ */
//
// Lines
//
@@ -770,12 +795,14 @@ TopToBottomOrientation::TopToBottomOrientation() {
addDimension(PredefinedDimension::INDEX, 0);
addDimension(PredefinedDimension::SOUND_AMPLITUDE,
int(sqrt(CELL_HEIGHT * soundRect.width()) / 2));
- addDimension(PredefinedDimension::FRAME_LABEL_ALIGN, Qt::AlignCenter);
+ addDimension(PredefinedDimension::FRAME_LABEL_ALIGN,
+ Qt::AlignVCenter | Qt::AlignRight);
addDimension(PredefinedDimension::ONION_TURN, 0);
addDimension(PredefinedDimension::QBOXLAYOUT_DIRECTION,
QBoxLayout::Direction::TopToBottom);
addDimension(PredefinedDimension::CENTER_ALIGN, Qt::AlignHCenter);
addDimension(PredefinedDimension::CAMERA_LAYER, CAMERA_CELL_WIDTH);
+ addDimension(PredefinedDimension::SCALE_THRESHOLD, 57);
//
// Paths
@@ -786,6 +813,13 @@ TopToBottomOrientation::TopToBottomOrientation() {
corner.lineTo(QPointF(0, CELL_HEIGHT));
addPath(PredefinedPath::DRAG_HANDLE_CORNER, corner);
+ QPainterPath diamond(QPointF(0, -4));
+ diamond.lineTo(4, 0);
+ diamond.lineTo(0, 4);
+ diamond.lineTo(-4, 0);
+ diamond.lineTo(0, -4);
+ addPath(PredefinedPath::FRAME_MARKER_DIAMOND, diamond);
+
QPainterPath fromTriangle(QPointF(0, EASE_TRIANGLE_SIZE / 2));
fromTriangle.lineTo(QPointF(EASE_TRIANGLE_SIZE, -EASE_TRIANGLE_SIZE / 2));
fromTriangle.lineTo(QPointF(-EASE_TRIANGLE_SIZE, -EASE_TRIANGLE_SIZE / 2));
@@ -880,16 +914,16 @@ QPoint TopToBottomOrientation::positionToXY(const CellPosition &position,
return QPoint(x, y);
}
CellPositionRatio TopToBottomOrientation::xyToPositionRatio(
- const QPoint &xy) const {
- Ratio frame{xy.y(), CELL_HEIGHT};
- Ratio layer{xy.x(), CELL_WIDTH};
+ const QPointF &xy) const {
+ double frame = xy.y() / (double)CELL_HEIGHT;
+ double layer = xy.x() / (double)CELL_WIDTH;
return CellPositionRatio{frame, layer};
}
-QPoint TopToBottomOrientation::positionRatioToXY(
+QPointF TopToBottomOrientation::positionRatioToXY(
const CellPositionRatio &ratio) const {
- int x = ratio.layer() * CELL_WIDTH;
- int y = ratio.frame() * CELL_HEIGHT;
- return QPoint(x, y);
+ double x = ratio.layer() * (double)CELL_WIDTH;
+ double y = ratio.frame() * (double)CELL_HEIGHT;
+ return QPointF(x, y);
}
int TopToBottomOrientation::colToLayerAxis(int layer,
@@ -975,6 +1009,8 @@ LeftToRightOrientation::LeftToRightOrientation() {
CELL_HEIGHT - FRAME_MARKER_SIZE - 7, FRAME_MARKER_SIZE,
FRAME_MARKER_SIZE);
addRect(PredefinedRect::FRAME_MARKER_AREA, frameMarker);
+ addRect(PredefinedRect::CAMERA_FRAME_MARKER_AREA,
+ rect(PredefinedRect::FRAME_MARKER_AREA));
// Notes viewer
addRect(
@@ -1182,6 +1218,7 @@ LeftToRightOrientation::LeftToRightOrientation() {
QBoxLayout::Direction::LeftToRight);
addDimension(PredefinedDimension::CENTER_ALIGN, Qt::AlignVCenter);
addDimension(PredefinedDimension::CAMERA_LAYER, CAMERA_CELL_HEIGHT);
+ addDimension(PredefinedDimension::SCALE_THRESHOLD, 50);
//
// Paths
@@ -1279,16 +1316,16 @@ QPoint LeftToRightOrientation::positionToXY(const CellPosition &position,
return QPoint(x, y);
}
CellPositionRatio LeftToRightOrientation::xyToPositionRatio(
- const QPoint &xy) const {
- Ratio frame{xy.x(), CELL_WIDTH};
- Ratio layer{xy.y(), CELL_HEIGHT};
+ const QPointF &xy) const {
+ double frame = xy.x() / (double)CELL_WIDTH;
+ double layer = xy.y() / (double)CELL_HEIGHT;
return CellPositionRatio{frame, layer};
}
-QPoint LeftToRightOrientation::positionRatioToXY(
+QPointF LeftToRightOrientation::positionRatioToXY(
const CellPositionRatio &ratio) const {
- int x = ratio.frame() * CELL_WIDTH;
- int y = ratio.layer() * CELL_HEIGHT;
- return QPoint(x, y);
+ double x = ratio.frame() * (double)CELL_WIDTH;
+ double y = ratio.layer() * (double)CELL_HEIGHT;
+ return QPointF(x, y);
}
int LeftToRightOrientation::colToLayerAxis(int layer,
diff --git a/toonz/sources/toonzlib/txsheethandle.cpp b/toonz/sources/toonzlib/txsheethandle.cpp
index 3b79750..ad1b142 100644
--- a/toonz/sources/toonzlib/txsheethandle.cpp
+++ b/toonz/sources/toonzlib/txsheethandle.cpp
@@ -9,7 +9,7 @@
// TXsheeHandle
//-----------------------------------------------------------------------------
-TXsheetHandle::TXsheetHandle() : m_xsheet(0) {}
+TXsheetHandle::TXsheetHandle() : m_xsheet(0), m_zoomFactor(100) {}
//-----------------------------------------------------------------------------
diff --git a/toonz/sources/toonzqt/functionsheet.cpp b/toonz/sources/toonzqt/functionsheet.cpp
index 714008f..593617a 100644
--- a/toonz/sources/toonzqt/functionsheet.cpp
+++ b/toonz/sources/toonzqt/functionsheet.cpp
@@ -27,6 +27,7 @@
#include
#include //for drag&drop
#include
+#include
//********************************************************************************
// Local namespace stuff
@@ -187,6 +188,48 @@ public:
};
//********************************************************************************
+// FunctionSheetButtonArea implementation
+//********************************************************************************
+
+FunctionSheetButtonArea::FunctionSheetButtonArea(QWidget *parent)
+ : QWidget(parent) {
+ m_syncSizeBtn = new QPushButton("", this);
+ m_syncSizeBtn->setCheckable(true);
+ m_syncSizeBtn->setFixedSize(20, 20);
+ static QPixmap syncScaleImg =
+ recolorPixmap(svgToPixmap(getIconThemePath("actions/17/syncscale.svg")));
+ QPixmap offPm(17, 17);
+ offPm.fill(Qt::transparent);
+ {
+ QPainter p(&offPm);
+ p.setOpacity(0.7);
+ p.drawPixmap(0, 0, syncScaleImg);
+ }
+ QIcon icon;
+ icon.addPixmap(offPm);
+ icon.addPixmap(syncScaleImg, QIcon::Normal, QIcon::On);
+ m_syncSizeBtn->setIcon(icon);
+
+ m_syncSizeBtn->setToolTip(tr("Toggle synchronizing zoom with xsheet"));
+
+ QVBoxLayout *layout = new QVBoxLayout();
+ layout->setMargin(2);
+ layout->setSpacing(0);
+ {
+ layout->addStretch();
+ layout->addWidget(m_syncSizeBtn, 0, Qt::AlignCenter);
+ }
+ setLayout(layout);
+
+ connect(m_syncSizeBtn, SIGNAL(clicked(bool)), this,
+ SIGNAL(syncSizeBtnToggled(bool)));
+}
+
+void FunctionSheetButtonArea::setSyncSizeBtnState(bool on) {
+ m_syncSizeBtn->setChecked(on);
+}
+
+//********************************************************************************
// FunctionSheetRowViewer implementation
//********************************************************************************
@@ -655,6 +698,11 @@ void FunctionSheetCellViewer::drawCells(QPainter &painter, int r0, int c0,
TXsheet *xsh = m_sheet->getViewer()->getXsheetHandle()->getXsheet();
+ bool simpleView = getViewer()->getFrameZoomFactor() <=
+ Orientations::topToBottom()->dimension(
+ PredefinedDimension::SCALE_THRESHOLD);
+ bool showIbtwn = !simpleView && m_sheet->isIbtwnValueVisible();
+
// top and bottom pos
int y0 = getViewer()->rowToY(r0);
int y1 = getViewer()->rowToY(r1 + 1) - 1;
@@ -723,7 +771,7 @@ void FunctionSheetCellViewer::drawCells(QPainter &painter, int r0, int c0,
// when the inbetween values are hidden, change the cell colors to
// semi-transparent if the frame is in middle of the value step
- if (!m_sheet->isIbtwnValueVisible()) {
+ if (!showIbtwn) {
TDoubleKeyframe kf =
curve->getKeyframe(curve->getPrevKeyframe(row));
int step = kf.m_step;
@@ -751,9 +799,8 @@ void FunctionSheetCellViewer::drawCells(QPainter &painter, int r0, int c0,
}
}
- drawValue = (curve->isKeyframe(row))
- ? Key
- : (m_sheet->isIbtwnValueVisible()) ? Inbetween : None;
+ drawValue =
+ (curve->isKeyframe(row)) ? Key : (showIbtwn) ? Inbetween : None;
}
// empty cells
@@ -1138,7 +1185,8 @@ FunctionSheet::FunctionSheet(QWidget *parent, bool isFloating)
: SpreadsheetViewer(parent)
, m_selectedCells()
, m_selection(0)
- , m_isFloating(isFloating) {
+ , m_isFloating(isFloating)
+ , m_buttonArea(nullptr) {
setColumnsPanel(m_columnHeadViewer = new FunctionSheetColumnHeadViewer(this));
setRowsPanel(m_rowViewer = new FunctionSheetRowViewer(this));
setCellsPanel(m_cellViewer = new FunctionSheetCellViewer(this));
@@ -1156,6 +1204,10 @@ FunctionSheet::FunctionSheet(QWidget *parent, bool isFloating)
setGeometry(settings.value("FunctionSpreadsheet", QRect(500, 500, 400, 300))
.toRect());
}
+
+ setButtonAreaWidget(m_buttonArea = new FunctionSheetButtonArea(this));
+ connect(m_buttonArea, SIGNAL(syncSizeBtnToggled(bool)), this,
+ SLOT(onSyncSizeBtnToggled(bool)));
}
//-----------------------------------------------------------------------------
@@ -1189,6 +1241,12 @@ void FunctionSheet::setSelection(FunctionSelection *selection) {
void FunctionSheet::showEvent(QShowEvent *e) {
m_frameScroller.registerFrameScroller();
SpreadsheetViewer::showEvent(e);
+
+ if (m_xshHandle && m_syncSize) {
+ connect(m_xshHandle, SIGNAL(zoomScaleChanged()), this,
+ SLOT(onZoomScaleChanged()));
+ onZoomScaleChanged();
+ }
}
//-----------------------------------------------------------------------------
@@ -1196,6 +1254,11 @@ void FunctionSheet::showEvent(QShowEvent *e) {
void FunctionSheet::hideEvent(QHideEvent *e) {
m_frameScroller.unregisterFrameScroller();
SpreadsheetViewer::hideEvent(e);
+
+ if (m_xshHandle && m_syncSize) {
+ disconnect(m_xshHandle, SIGNAL(zoomScaleChanged()), this,
+ SLOT(onZoomScaleChanged()));
+ }
}
//-----------------------------------------------------------------------------
@@ -1343,4 +1406,49 @@ TStageObject *FunctionSheet::getStageObject(int column) {
if (!stageItem) return nullptr;
return stageItem->getStageObject();
+}
+
+//-----------------------------------------------------------------------------
+
+void FunctionSheet::setSyncSize(bool on) {
+ m_syncSize = on;
+ m_buttonArea->setSyncSizeBtnState(on);
+ update();
+}
+
+//-----------------------------------------------------------------------------
+
+int FunctionSheet::getFrameZoomFactor() const {
+ if (m_syncSize && m_xshHandle) {
+ int zoomFactor = m_xshHandle->getZoomFactor();
+ return 50 + (zoomFactor - 20) * 5 / 8;
+ }
+ return 100;
+}
+
+//-----------------------------------------------------------------------------
+
+void FunctionSheet::onSyncSizeBtnToggled(bool on) {
+ // switch the flag
+ m_syncSize = on;
+
+ if (m_xshHandle) {
+ if (on)
+ connect(m_xshHandle, SIGNAL(zoomScaleChanged()), this,
+ SLOT(onZoomScaleChanged()));
+ else
+ disconnect(m_xshHandle, SIGNAL(zoomScaleChanged()), this,
+ SLOT(onZoomScaleChanged()));
+ onZoomScaleChanged();
+ }
+}
+
+//-----------------------------------------------------------------------------
+
+void FunctionSheet::onZoomScaleChanged() {
+ QPoint xyOrig = positionToXY(CellPosition(getCurrentFrame(), -1));
+ setScaleFactor(getFrameZoomFactor());
+ QPoint xyNew = positionToXY(CellPosition(getCurrentFrame(), -1));
+ scroll(xyNew - xyOrig);
+ update();
}
\ No newline at end of file
diff --git a/toonz/sources/toonzqt/functionviewer.cpp b/toonz/sources/toonzqt/functionviewer.cpp
index a0d4a6a..a138303 100644
--- a/toonz/sources/toonzqt/functionviewer.cpp
+++ b/toonz/sources/toonzqt/functionviewer.cpp
@@ -387,6 +387,7 @@ void FunctionViewer::setXsheetHandle(TXsheetHandle *xshHandle) {
m_xshHandle = xshHandle;
m_segmentViewer->setXsheetHandle(xshHandle);
m_treeView->setXsheetHandle(xshHandle);
+ m_numericalColumns->setXsheetHandle(xshHandle);
if (m_xshHandle && isVisible()) {
TXsheet *xsh = m_xshHandle->getXsheet();
@@ -729,6 +730,7 @@ void FunctionViewer::save(QSettings &settings) const {
settings.setValue("toggleStatus", m_toggleStatus);
settings.setValue("showIbtwnValuesInSheet",
m_numericalColumns->isIbtwnValueVisible());
+ settings.setValue("syncSize", m_numericalColumns->isSyncSize());
}
//----------------------------------------------------------------------------
@@ -744,6 +746,10 @@ void FunctionViewer::load(QSettings &settings) {
m_numericalColumns->isIbtwnValueVisible())
.toBool();
m_numericalColumns->setIbtwnValueVisible(ibtwnVisible);
+
+ bool syncSize =
+ settings.value("syncSize", m_numericalColumns->isSyncSize()).toBool();
+ m_numericalColumns->setSyncSize(syncSize);
}
//-----------------------------------------------------------------------------
diff --git a/toonz/sources/toonzqt/spreadsheetviewer.cpp b/toonz/sources/toonzqt/spreadsheetviewer.cpp
index 82e0698..c52ddb4 100644
--- a/toonz/sources/toonzqt/spreadsheetviewer.cpp
+++ b/toonz/sources/toonzqt/spreadsheetviewer.cpp
@@ -82,11 +82,12 @@ void FrameScroller::handleScroll(QPoint &offset) {
offset.y())) // only synchronize changes by frames axis
return;
+ QPointF offsetF(offset);
// In case of a zoomed viewer is sending this out, adjust the
// zoomed offset back to a standardized offset
- emit zoomScrollAdjust(offset, false);
+ emit zoomScrollAdjust(offsetF, false);
- CellPositionRatio ratio = orientation()->xyToPositionRatio(offset);
+ CellPositionRatio ratio = orientation()->xyToPositionRatio(offsetF);
for (int i = 0; i < frameScrollers.size(); i++)
if (frameScrollers[i] != this) {
@@ -100,10 +101,11 @@ void FrameScroller::handleScroll(QPoint &offset) {
void adjustScrollbar(QScrollBar *scrollBar, int add);
void FrameScroller::onScroll(const CellPositionRatio &ratio) {
- QPoint offset = orientation()->positionRatioToXY(ratio);
+ QPointF 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.
@@ -111,11 +113,11 @@ void FrameScroller::onScroll(const CellPositionRatio &ratio) {
// since the receiver is in the same thread.
// when moving up the scroll bar, resizing will be done in
// SpreadsheetViewer::onVSliderChanged().
- if (offset.x() > 0 || offset.y() > 0) emit prepareToScrollOffset(offset);
- if (offset.x())
- adjustScrollbar(m_scrollArea->horizontalScrollBar(), offset.x());
- if (offset.y())
- adjustScrollbar(m_scrollArea->verticalScrollBar(), offset.y());
+ if (offset.x() > 0.0 || offset.y() > 0.0) emit prepareToScrollOffset(offset);
+ if ((int)offset.x())
+ adjustScrollbar(m_scrollArea->horizontalScrollBar(), (int)offset.x());
+ if ((int)offset.y())
+ adjustScrollbar(m_scrollArea->verticalScrollBar(), (int)offset.y());
}
void adjustScrollbar(QScrollBar *scrollBar, int add) {
@@ -130,14 +132,14 @@ void FrameScroller::unregisterFrameScroller() {
if (frameScrollers.contains(this)) frameScrollers.removeAll(this);
}
-void FrameScroller::prepareToScrollOthers(const QPoint &offset) {
+void FrameScroller::prepareToScrollOthers(const QPointF &offset) {
CellPositionRatio ratio = orientation()->xyToPositionRatio(offset);
for (int i = 0; i < frameScrollers.size(); i++)
if (frameScrollers[i] != this)
frameScrollers[i]->prepareToScrollRatio(ratio);
}
void FrameScroller::prepareToScrollRatio(const CellPositionRatio &ratio) {
- QPoint offset = orientation()->positionRatioToXY(ratio);
+ QPointF offset = orientation()->positionRatioToXY(ratio);
emit prepareToScrollOffset(offset);
}
@@ -321,9 +323,13 @@ void RowPanel::drawRows(QPainter &p, int r0, int r1) {
int y0 = visibleRect.top();
int y1 = visibleRect.bottom();
+ bool simpleView = getViewer()->getFrameZoomFactor() <=
+ Orientations::topToBottom()->dimension(
+ PredefinedDimension::SCALE_THRESHOLD);
int r;
+ int y = getViewer()->rowToY(r0);
for (r = r0; r <= r1; r++) {
- int y = getViewer()->rowToY(r);
+ int next_y = getViewer()->rowToY(r + 1);
// draw horizontal line
QColor color = (getViewer()->isMarkRow(r))
? getViewer()->getMarkerLineColor()
@@ -331,12 +337,18 @@ void RowPanel::drawRows(QPainter &p, int r0, int r1) {
p.setPen(color);
p.drawLine(x0, y, x1, y);
+ if (simpleView && r > 0 && !getViewer()->isMarkRow(r + 1)) {
+ y = next_y;
+ continue;
+ }
+
// draw numbers
p.setPen(getViewer()->getTextColor());
QString number = QString::number(r + 1);
- p.drawText(QRect(x0, y + 1, width(), 18),
- Qt::AlignHCenter | Qt::AlignBottom, number);
+ p.drawText(QRect(x0, y + 1, width() - 4, next_y - y - 1),
+ Qt::AlignVCenter | Qt::AlignRight, number);
+ y = next_y;
}
// erase the marker interval at upper-end
if (r0 == 0) {
@@ -349,9 +361,13 @@ void RowPanel::drawRows(QPainter &p, int r0, int r1) {
void RowPanel::drawCurrentRowGadget(QPainter &p, int r0, int r1) {
int currentRow = getViewer()->getCurrentRow();
- int y = getViewer()->rowToY(currentRow);
+ // int y = getViewer()->rowToY(currentRow);
if (currentRow < r0 || r1 < currentRow) return;
- p.fillRect(1, y + 1, width() - 1, 19, getViewer()->getCurrentRowBgColor());
+ int top = getViewer()->rowToY(currentRow);
+ int bottom = getViewer()->rowToY(currentRow + 1) - 1;
+ QRect rect(1, top, width() - 1, bottom - top);
+
+ p.fillRect(rect, getViewer()->getCurrentRowBgColor());
}
//-----------------------------------------------------------------------------
@@ -455,6 +471,7 @@ SpreadsheetViewer::SpreadsheetViewer(QWidget *parent)
, m_frameHandle(0)
, m_columnWidth(50)
, m_rowHeight(20)
+ , m_scaleFactor(100)
, m_timerId(0)
, m_autoPanSpeed(0, 0)
, m_lastAutoPanPos(0, 0)
@@ -501,12 +518,14 @@ SpreadsheetViewer::SpreadsheetViewer(QWidget *parent)
QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Ignored));
m_rowScrollArea->setFixedWidth(30);
- m_columnScrollArea->setFixedHeight(m_rowHeight * 3 - 3);
+ m_columnScrollArea->setFixedHeight(m_rowHeight * 3 - 4);
// m_columnScrollArea->setFixedHeight(m_rowHeight * 3 + 60 - 63);
m_frameScroller.setFrameScrollArea(m_cellScrollArea);
connect(&m_frameScroller, &Spreadsheet::FrameScroller::prepareToScrollOffset,
this, &SpreadsheetViewer::onPrepareToScrollOffset);
+ connect(&m_frameScroller, &Spreadsheet::FrameScroller::zoomScrollAdjust, this,
+ &SpreadsheetViewer::onZoomScrollAdjust);
//---- layout
QGridLayout *layout = new QGridLayout();
@@ -520,7 +539,8 @@ SpreadsheetViewer::SpreadsheetViewer(QWidget *parent)
int scrollBarWidth = 16;
// upper-right
QWidget *w = new QWidget(this);
- w->setFixedSize(QSize(scrollBarWidth, m_rowHeight * 3 + 60 - 63));
+ w->setFixedWidth(scrollBarWidth);
+ w->setFixedHeight(m_columnScrollArea->height());
layout->addWidget(w, 0, 2);
// lower-left
@@ -584,6 +604,11 @@ void SpreadsheetViewer::setCellsPanel(Spreadsheet::CellPanel *cells) {
m_cellScrollArea->setWidget(cells);
}
+void SpreadsheetViewer::setButtonAreaWidget(QWidget *widget) {
+ QGridLayout *lay = dynamic_cast(layout());
+ lay->addWidget(widget, 0, 0);
+}
+
void SpreadsheetViewer::setRowCount(int rowCount) {
if (m_rowCount != rowCount) {
m_rowCount = rowCount;
@@ -619,6 +644,10 @@ void SpreadsheetViewer::scroll(QPoint delta) {
else if (!notUpdateSizeH && notUpdateSizeV)
refreshContentSize(x, 0);
+ // Recheck in case refreshContentSize changed the max
+ if (!notUpdateSizeH) maxValueH = hSc->maximum();
+ if (!notUpdateSizeV) maxValueV = vSc->maximum();
+
if (valueH > maxValueH && x > 0) valueH = hSc->maximum();
if (valueV > maxValueV && y > 0) valueV = vSc->maximum();
@@ -627,8 +656,22 @@ void SpreadsheetViewer::scroll(QPoint delta) {
vSc->setValue(valueV);
}
-void SpreadsheetViewer::onPrepareToScrollOffset(const QPoint &offset) {
- refreshContentSize(offset.x(), offset.y());
+void SpreadsheetViewer::onPrepareToScrollOffset(const QPointF &offset) {
+ refreshContentSize((int)offset.x(), (int)offset.y());
+}
+
+void SpreadsheetViewer::onZoomScrollAdjust(QPointF &offset, bool toZoom) {
+ double frameZoomFactor = (double)getFrameZoomFactor();
+
+ // toZoom = true: Adjust standardized offset down to zoom factor
+ // toZoom = false: Adjust zoomed offset up to standardized offset
+ double newY;
+ if (toZoom)
+ newY = (offset.y() * frameZoomFactor) / 100.0;
+ else
+ newY = (offset.y() * 100.0) / frameZoomFactor;
+
+ offset.setY(newY);
}
void SpreadsheetViewer::setAutoPanSpeed(const QPoint &speed) {
@@ -686,7 +729,7 @@ int SpreadsheetViewer::rowToY(int row) const {
/*!Shift is a consequence of style sheet border.*/
CellPosition SpreadsheetViewer::xyToPosition(const QPoint &point) const {
- int row = (point.y() + 1) / m_rowHeight;
+ int row = (point.y() * 100 / m_scaleFactor) / m_rowHeight;
int col = (point.x()) / m_columnWidth;
return CellPosition(row, col);
}
@@ -694,7 +737,8 @@ CellPosition SpreadsheetViewer::xyToPosition(const QPoint &point) const {
/*!Shift is a consequence of style sheet border.*/
QPoint SpreadsheetViewer::positionToXY(const CellPosition &pos) const {
int x = (pos.layer() * m_columnWidth);
- int y = (pos.frame() * m_rowHeight) - 1;
+ int y = pos.frame() * m_rowHeight * m_scaleFactor / 100;
+ // int y = (pos.frame() * m_rowHeight * m_scaleFactor / 100) - 1;
return QPoint(x, y);
}
@@ -728,6 +772,7 @@ bool SpreadsheetViewer::refreshContentSize(int scrollDx, int scrollDy) {
m_columnScrollArea->widget()->setFixedSize(
actualSize.width(), m_columnScrollArea->viewport()->height());
m_isComputingSize = false;
+
return true;
}
}
@@ -738,7 +783,8 @@ void SpreadsheetViewer::showEvent(QShowEvent *) {
QScrollBar *vSc = m_cellScrollArea->verticalScrollBar();
int actualContentHeight =
std::max(contentHeight, vSc->value() + viewportHeight);
- m_rowScrollArea->widget()->setFixedHeight(actualContentHeight);
+ m_rowScrollArea->widget()->setFixedSize(m_rowScrollArea->viewport()->width(),
+ actualContentHeight);
m_cellScrollArea->widget()->setFixedHeight(actualContentHeight);
if (m_frameHandle)
connect(m_frameHandle, SIGNAL(frameSwitched()), this,