Level Strip Overhaul (#1405)
*Enabled navigator for all * Modified selecting and dragging behaviors * Modified scroll range
This commit is contained in:
parent
c189d1a1bc
commit
6ee71e6fc1
7 changed files with 240 additions and 153 deletions
|
@ -112,6 +112,7 @@ FilmstripFrames::FilmstripFrames(QScrollArea *parent, Qt::WFlags flags)
|
||||||
, m_dragSelectionStartIndex(-1)
|
, m_dragSelectionStartIndex(-1)
|
||||||
, m_dragSelectionEndIndex(-1)
|
, m_dragSelectionEndIndex(-1)
|
||||||
, m_timerId(0)
|
, m_timerId(0)
|
||||||
|
, m_isGhibli(false)
|
||||||
, m_selecting(false)
|
, m_selecting(false)
|
||||||
, m_dragDropArmed(false)
|
, m_dragDropArmed(false)
|
||||||
, m_readOnly(false) {
|
, m_readOnly(false) {
|
||||||
|
@ -130,6 +131,11 @@ FilmstripFrames::FilmstripFrames(QScrollArea *parent, Qt::WFlags flags)
|
||||||
|
|
||||||
m_selection->setView(this);
|
m_selection->setView(this);
|
||||||
setMouseTracking(true);
|
setMouseTracking(true);
|
||||||
|
|
||||||
|
std::string room =
|
||||||
|
Preferences::instance()->getCurrentRoomChoice().toStdString();
|
||||||
|
m_isGhibli = room == "StudioGhibli";
|
||||||
|
m_viewer = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
@ -208,12 +214,14 @@ void FilmstripFrames::updateContentHeight(int minimumHeight) {
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
void FilmstripFrames::exponeFrame(int index) {
|
void FilmstripFrames::showFrame(int index) {
|
||||||
|
TXshSimpleLevel *level = getLevel();
|
||||||
|
|
||||||
|
if (!level->isFid(index2fid(index))) return;
|
||||||
int y0 = index2y(index);
|
int y0 = index2y(index);
|
||||||
int y1 = y0 + m_iconSize.height() + fs_frameSpacing + fs_iconMarginTop +
|
int y1 = y0 + m_iconSize.height() + fs_frameSpacing + fs_iconMarginTop +
|
||||||
fs_iconMarginBottom;
|
fs_iconMarginBottom;
|
||||||
if (y1 > height()) setFixedHeight(y1);
|
if (y1 > height()) setFixedHeight(y1);
|
||||||
// else if(height()-y1>=m_iconSize.height()) updateContentHeight();
|
|
||||||
m_scrollArea->ensureVisible(0, (y0 + y1) / 2, 50, (y1 - y0) / 2);
|
m_scrollArea->ensureVisible(0, (y0 + y1) / 2, 50, (y1 - y0) / 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -222,9 +230,12 @@ void FilmstripFrames::exponeFrame(int index) {
|
||||||
void FilmstripFrames::scroll(int dy) {
|
void FilmstripFrames::scroll(int dy) {
|
||||||
QScrollBar *sb = m_scrollArea->verticalScrollBar();
|
QScrollBar *sb = m_scrollArea->verticalScrollBar();
|
||||||
int sbValue = sb->value();
|
int sbValue = sb->value();
|
||||||
int y = visibleRegion().boundingRect().bottom() + dy + 1;
|
|
||||||
if (y < 0) y = 0;
|
updateContentHeight(getFramesHeight());
|
||||||
updateContentHeight(y);
|
if (sbValue + dy > getFramesHeight()) {
|
||||||
|
sb->setValue(getFramesHeight());
|
||||||
|
return;
|
||||||
|
}
|
||||||
sb->setValue(sbValue + dy);
|
sb->setValue(sbValue + dy);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -239,8 +250,7 @@ void FilmstripFrames::mouseDoubleClickEvent(QMouseEvent *event) {
|
||||||
|
|
||||||
void FilmstripFrames::select(int index, SelectionMode mode) {
|
void FilmstripFrames::select(int index, SelectionMode mode) {
|
||||||
TXshSimpleLevel *sl = getLevel();
|
TXshSimpleLevel *sl = getLevel();
|
||||||
|
bool outOfRange = !sl || index < 0 || index >= sl->getFrameCount();
|
||||||
bool outOfRange = !sl || index < 0 || index >= sl->getFrameCount();
|
|
||||||
|
|
||||||
TFrameId fid;
|
TFrameId fid;
|
||||||
if (!outOfRange) fid = index2fid(index);
|
if (!outOfRange) fid = index2fid(index);
|
||||||
|
@ -367,15 +377,7 @@ void FilmstripFrames::showEvent(QShowEvent *) {
|
||||||
connect(app->getCurrentOnionSkin(), SIGNAL(onionSkinMaskChanged()), this,
|
connect(app->getCurrentOnionSkin(), SIGNAL(onionSkinMaskChanged()), this,
|
||||||
SLOT(update()));
|
SLOT(update()));
|
||||||
|
|
||||||
// enable navigator link with the Viewer in the InknPaint page
|
getViewer();
|
||||||
ComboViewerPanel *inknPaintViewerPanel = app->getInknPaintViewerPanel();
|
|
||||||
if (inknPaintViewerPanel) {
|
|
||||||
SceneViewer *viewer = inknPaintViewerPanel->getSceneViewer();
|
|
||||||
if (viewer) {
|
|
||||||
connect(viewer, SIGNAL(onZoomChanged()), this, SLOT(update()));
|
|
||||||
connect(viewer, SIGNAL(refreshNavi()), this, SLOT(update()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
@ -400,13 +402,33 @@ void FilmstripFrames::hideEvent(QHideEvent *) {
|
||||||
disconnect(app->getCurrentOnionSkin(), SIGNAL(onionSkinMaskChanged()), this,
|
disconnect(app->getCurrentOnionSkin(), SIGNAL(onionSkinMaskChanged()), this,
|
||||||
SLOT(update()));
|
SLOT(update()));
|
||||||
|
|
||||||
ComboViewerPanel *inknPaintViewerPanel = app->getInknPaintViewerPanel();
|
if (m_viewer) {
|
||||||
if (inknPaintViewerPanel) {
|
disconnect(m_viewer, SIGNAL(onZoomChanged()), this, SLOT(update()));
|
||||||
SceneViewer *viewer = inknPaintViewerPanel->getSceneViewer();
|
disconnect(m_viewer, SIGNAL(refreshNavi()), this, SLOT(update()));
|
||||||
if (viewer) {
|
}
|
||||||
disconnect(viewer, SIGNAL(onZoomChanged()), this, SLOT(update()));
|
}
|
||||||
disconnect(viewer, SIGNAL(refreshNavi()), this, SLOT(update()));
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void FilmstripFrames::getViewer() {
|
||||||
|
bool viewerChanged = false;
|
||||||
|
if (m_viewer != TApp::instance()->getActiveViewer()) {
|
||||||
|
if (m_viewer) {
|
||||||
|
disconnect(m_viewer, SIGNAL(onZoomChanged()), this, SLOT(update()));
|
||||||
|
disconnect(m_viewer, SIGNAL(refreshNavi()), this, SLOT(update()));
|
||||||
}
|
}
|
||||||
|
viewerChanged = true;
|
||||||
|
}
|
||||||
|
ComboViewerPanel *inknPaintViewerPanel =
|
||||||
|
TApp::instance()->getInknPaintViewerPanel();
|
||||||
|
if (m_isGhibli && inknPaintViewerPanel) {
|
||||||
|
m_viewer = inknPaintViewerPanel->getSceneViewer();
|
||||||
|
} else {
|
||||||
|
m_viewer = TApp::instance()->getActiveViewer();
|
||||||
|
}
|
||||||
|
if (m_viewer && viewerChanged) {
|
||||||
|
connect(m_viewer, SIGNAL(onZoomChanged()), this, SLOT(update()));
|
||||||
|
connect(m_viewer, SIGNAL(refreshNavi()), this, SLOT(update()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -456,62 +478,57 @@ void FilmstripFrames::paintEvent(QPaintEvent *evt) {
|
||||||
//--- compute navigator rect ---
|
//--- compute navigator rect ---
|
||||||
|
|
||||||
QRect naviRect;
|
QRect naviRect;
|
||||||
ComboViewerPanel *inknPaintViewerPanel =
|
|
||||||
TApp::instance()->getInknPaintViewerPanel();
|
|
||||||
if (sl->getType() == TZP_XSHLEVEL && inknPaintViewerPanel) {
|
|
||||||
// show navigator only if the inknpaint viewer is visible
|
|
||||||
if (inknPaintViewerPanel->isVisible()) {
|
|
||||||
SceneViewer *viewer = inknPaintViewerPanel->getSceneViewer();
|
|
||||||
// imgSize: image's pixel size
|
|
||||||
QSize imgSize(sl->getProperties()->getImageRes().lx,
|
|
||||||
sl->getProperties()->getImageRes().ly);
|
|
||||||
// Viewer affine
|
|
||||||
TAffine viewerAff =
|
|
||||||
inknPaintViewerPanel->getSceneViewer()->getViewMatrix();
|
|
||||||
// pixel size which will be displayed with 100% scale in Viewer Stage
|
|
||||||
TFrameId currentId = TApp::instance()->getCurrentFrame()->getFid();
|
|
||||||
double imgPixelWidth =
|
|
||||||
(double)(imgSize.width()) / sl->getDpi(currentId).x * Stage::inch;
|
|
||||||
double imgPixelHeight =
|
|
||||||
(double)(imgSize.height()) / sl->getDpi(currentId).y * Stage::inch;
|
|
||||||
|
|
||||||
// get the image's corner positions in viewer matrix (with current zoom
|
if ((sl->getType() == TZP_XSHLEVEL || sl->getType() == OVL_XSHLEVEL) &&
|
||||||
// scale)
|
m_viewer && m_viewer->isVisible()) {
|
||||||
TPointD imgTopRight =
|
// imgSize: image's pixel size
|
||||||
viewerAff * TPointD(imgPixelWidth / 2.0f, imgPixelHeight / 2.0f);
|
QSize imgSize(sl->getProperties()->getImageRes().lx,
|
||||||
TPointD imgBottomLeft =
|
sl->getProperties()->getImageRes().ly);
|
||||||
viewerAff * TPointD(-imgPixelWidth / 2.0f, -imgPixelHeight / 2.0f);
|
// Viewer affine
|
||||||
|
TAffine viewerAff = m_viewer->getViewMatrix();
|
||||||
|
// pixel size which will be displayed with 100% scale in Viewer Stage
|
||||||
|
TFrameId currentId = TApp::instance()->getCurrentFrame()->getFid();
|
||||||
|
double imgPixelWidth =
|
||||||
|
(double)(imgSize.width()) / sl->getDpi(currentId).x * Stage::inch;
|
||||||
|
double imgPixelHeight =
|
||||||
|
(double)(imgSize.height()) / sl->getDpi(currentId).y * Stage::inch;
|
||||||
|
|
||||||
// pixel size in viewer matrix ( with current zoom scale )
|
// get the image's corner positions in viewer matrix (with current zoom
|
||||||
QSizeF imgSizeInViewer(imgTopRight.x - imgBottomLeft.x,
|
// scale)
|
||||||
imgTopRight.y - imgBottomLeft.y);
|
TPointD imgTopRight =
|
||||||
|
viewerAff * TPointD(imgPixelWidth / 2.0f, imgPixelHeight / 2.0f);
|
||||||
|
TPointD imgBottomLeft =
|
||||||
|
viewerAff * TPointD(-imgPixelWidth / 2.0f, -imgPixelHeight / 2.0f);
|
||||||
|
|
||||||
// ratio of the Viewer frame's position and size
|
// pixel size in viewer matrix ( with current zoom scale )
|
||||||
QRectF naviRatio(
|
QSizeF imgSizeInViewer(imgTopRight.x - imgBottomLeft.x,
|
||||||
(-(float)viewer->width() * 0.5f - (float)imgBottomLeft.x) /
|
imgTopRight.y - imgBottomLeft.y);
|
||||||
imgSizeInViewer.width(),
|
|
||||||
1.0f -
|
|
||||||
((float)viewer->height() * 0.5f - (float)imgBottomLeft.y) /
|
|
||||||
imgSizeInViewer.height(),
|
|
||||||
(float)viewer->width() / imgSizeInViewer.width(),
|
|
||||||
(float)viewer->height() / imgSizeInViewer.height());
|
|
||||||
|
|
||||||
naviRect = QRect(iconImgRect.left() +
|
// ratio of the Viewer frame's position and size
|
||||||
(int)(naviRatio.left() * (float)iconImgRect.width()),
|
QRectF naviRatio(
|
||||||
iconImgRect.top() +
|
(-(float)m_viewer->width() * 0.5f - (float)imgBottomLeft.x) /
|
||||||
(int)(naviRatio.top() * (float)iconImgRect.height()),
|
imgSizeInViewer.width(),
|
||||||
(int)((float)iconImgRect.width() * naviRatio.width()),
|
1.0f -
|
||||||
(int)((float)iconImgRect.height() * naviRatio.height()));
|
((float)m_viewer->height() * 0.5f - (float)imgBottomLeft.y) /
|
||||||
// for drag move
|
imgSizeInViewer.height(),
|
||||||
m_naviRectPos = naviRect.center();
|
(float)m_viewer->width() / imgSizeInViewer.width(),
|
||||||
|
(float)m_viewer->height() / imgSizeInViewer.height());
|
||||||
|
|
||||||
naviRect = naviRect.intersected(frameRect);
|
naviRect = QRect(iconImgRect.left() +
|
||||||
|
(int)(naviRatio.left() * (float)iconImgRect.width()),
|
||||||
|
iconImgRect.top() +
|
||||||
|
(int)(naviRatio.top() * (float)iconImgRect.height()),
|
||||||
|
(int)((float)iconImgRect.width() * naviRatio.width()),
|
||||||
|
(int)((float)iconImgRect.height() * naviRatio.height()));
|
||||||
|
// for drag move
|
||||||
|
m_naviRectPos = naviRect.center();
|
||||||
|
|
||||||
m_icon2ViewerRatio.setX(imgSizeInViewer.width() /
|
naviRect = naviRect.intersected(frameRect);
|
||||||
(float)iconImgRect.width());
|
|
||||||
m_icon2ViewerRatio.setY(imgSizeInViewer.height() /
|
m_icon2ViewerRatio.setX(imgSizeInViewer.width() /
|
||||||
(float)iconImgRect.height());
|
(float)iconImgRect.width());
|
||||||
}
|
m_icon2ViewerRatio.setY(imgSizeInViewer.height() /
|
||||||
|
(float)iconImgRect.height());
|
||||||
}
|
}
|
||||||
|
|
||||||
//--- compute navigator rect end ---
|
//--- compute navigator rect end ---
|
||||||
|
@ -545,15 +562,13 @@ void FilmstripFrames::paintEvent(QPaintEvent *evt) {
|
||||||
QRect tmp_iconImgRect =
|
QRect tmp_iconImgRect =
|
||||||
iconImgRect.translated(QPoint(0, oneFrameHeight * i));
|
iconImgRect.translated(QPoint(0, oneFrameHeight * i));
|
||||||
QRect tmp_frameRect = frameRect.translated(QPoint(0, oneFrameHeight * i));
|
QRect tmp_frameRect = frameRect.translated(QPoint(0, oneFrameHeight * i));
|
||||||
|
|
||||||
bool isCurrentFrame =
|
bool isCurrentFrame =
|
||||||
(i == sl->fid2index(TApp::instance()->getCurrentFrame()->getFid()));
|
(i == sl->fid2index(TApp::instance()->getCurrentFrame()->getFid()));
|
||||||
bool isSelected =
|
bool isSelected =
|
||||||
(0 <= i && i < frameCount && m_selection->isSelected(fids[i]));
|
(0 <= i && i < frameCount && m_selection->isSelected(fids[i]));
|
||||||
|
TFrameId fid;
|
||||||
if (0 <= i && i < frameCount) {
|
if (0 <= i && i < frameCount) {
|
||||||
TFrameId fid = fids[i];
|
fid = fids[i];
|
||||||
|
|
||||||
// normal or inbetween (for vector levels)
|
// normal or inbetween (for vector levels)
|
||||||
int flags = (sl->getType() == PLI_XSHLEVEL && range.first < fid &&
|
int flags = (sl->getType() == PLI_XSHLEVEL && range.first < fid &&
|
||||||
fid < range.second)
|
fid < range.second)
|
||||||
|
@ -608,7 +623,7 @@ void FilmstripFrames::paintEvent(QPaintEvent *evt) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// navigator rect
|
// navigator rect
|
||||||
if (naviRect.isValid() && isCurrentFrame) {
|
if (naviRect.isValid() && fid >= 0 && fid == getCurrentFrameId()) {
|
||||||
p.setPen(QPen(Qt::red, 1));
|
p.setPen(QPen(Qt::red, 1));
|
||||||
p.drawRect(naviRect.translated(0, oneFrameHeight * i));
|
p.drawRect(naviRect.translated(0, oneFrameHeight * i));
|
||||||
p.setPen(Qt::NoPen);
|
p.setPen(Qt::NoPen);
|
||||||
|
@ -671,6 +686,28 @@ void FilmstripFrames::drawFrameIcon(QPainter &p, const QRect &r, int index,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FilmstripFrames::enterEvent(QEvent *event) { getViewer(); }
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
TFrameId FilmstripFrames::getCurrentFrameId() {
|
||||||
|
TApp *app = TApp::instance();
|
||||||
|
TFrameHandle *fh = app->getCurrentFrame();
|
||||||
|
TFrameId currFid;
|
||||||
|
if (fh->isEditingLevel())
|
||||||
|
currFid = fh->getFid();
|
||||||
|
else {
|
||||||
|
TXsheet *xsh = app->getCurrentXsheet()->getXsheet();
|
||||||
|
int col = app->getCurrentColumn()->getColumnIndex();
|
||||||
|
int row = fh->getFrame();
|
||||||
|
if (row < 0 || col < 0) return TFrameId();
|
||||||
|
TXshCell cell = xsh->getCell(row, col);
|
||||||
|
// if (cell.isEmpty()) return;
|
||||||
|
currFid = cell.getFrameId();
|
||||||
|
}
|
||||||
|
return currFid;
|
||||||
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
void FilmstripFrames::mousePressEvent(QMouseEvent *event) {
|
void FilmstripFrames::mousePressEvent(QMouseEvent *event) {
|
||||||
|
@ -683,40 +720,49 @@ void FilmstripFrames::mousePressEvent(QMouseEvent *event) {
|
||||||
int frameHeight = m_iconSize.height() + fs_frameSpacing + fs_iconMarginTop +
|
int frameHeight = m_iconSize.height() + fs_frameSpacing + fs_iconMarginTop +
|
||||||
fs_iconMarginBottom;
|
fs_iconMarginBottom;
|
||||||
QPoint clickedPos = event->pos() - QPoint(0, (index - i0) * frameHeight);
|
QPoint clickedPos = event->pos() - QPoint(0, (index - i0) * frameHeight);
|
||||||
|
bool actualIconClicked =
|
||||||
|
QRect(QPoint(fs_leftMargin + fs_iconMarginLR,
|
||||||
|
fs_frameSpacing / 2 +
|
||||||
|
fs_iconMarginTop) //<- top-left position of the icon
|
||||||
|
,
|
||||||
|
m_iconSize)
|
||||||
|
.contains(clickedPos);
|
||||||
|
|
||||||
if (event->button() == Qt::LeftButton) {
|
if (event->button() == Qt::LeftButton ||
|
||||||
if (fid == TFrameId()) return;
|
event->button() == Qt::MiddleButton) {
|
||||||
|
|
||||||
ComboViewerPanel *inknPaintViewerPanel =
|
|
||||||
TApp::instance()->getInknPaintViewerPanel();
|
|
||||||
|
|
||||||
// navigator pan
|
// navigator pan
|
||||||
if (fid == TApp::instance()->getCurrentFrame()->getFid() &&
|
// make sure the viewer is visible and that a toonz raster or raster level
|
||||||
sl->getType() == TZP_XSHLEVEL && inknPaintViewerPanel &&
|
// is current
|
||||||
inknPaintViewerPanel->isVisible() &&
|
if (fid.getNumber() >= 0 && fid == getCurrentFrameId() &&
|
||||||
QRect(QPoint(fs_leftMargin + fs_iconMarginLR,
|
(sl->getType() == TZP_XSHLEVEL || sl->getType() == OVL_XSHLEVEL) &&
|
||||||
fs_frameSpacing / 2 +
|
m_viewer && m_viewer->isVisible() && actualIconClicked &&
|
||||||
fs_iconMarginTop) //<- top-left position of the icon
|
(m_isGhibli != (event->button() == Qt::MiddleButton))) {
|
||||||
,
|
|
||||||
m_iconSize)
|
|
||||||
.contains(clickedPos)) {
|
|
||||||
m_isNavigatorPanning = true;
|
m_isNavigatorPanning = true;
|
||||||
execNavigatorPan(event->pos());
|
execNavigatorPan(event->pos());
|
||||||
QApplication::setOverrideCursor(Qt::ClosedHandCursor);
|
QApplication::setOverrideCursor(Qt::ClosedHandCursor);
|
||||||
} else
|
} else
|
||||||
m_isNavigatorPanning = false;
|
m_isNavigatorPanning = false;
|
||||||
|
// end of navigator section
|
||||||
|
|
||||||
|
// return if frame empty or middle button pressed
|
||||||
|
if (fid == TFrameId() || event->button() == Qt::MiddleButton) {
|
||||||
|
m_justStartedSelection = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// with shift or control
|
||||||
if (event->modifiers() & Qt::ShiftModifier) {
|
if (event->modifiers() & Qt::ShiftModifier) {
|
||||||
select(index, SHIFT_SELECT);
|
select(index, SHIFT_SELECT);
|
||||||
if (m_selection->isSelected(fid)) {
|
if (m_selection->isSelected(fid)) {
|
||||||
// click su di un frame gia' selezionato. Puo' essere l'inizio di un
|
// If the frame is already selected enable
|
||||||
// drag'n'drop
|
// drag'n'drop
|
||||||
m_dragDropArmed = true;
|
m_dragDropArmed = true;
|
||||||
m_pos = event->pos();
|
m_pos = event->pos();
|
||||||
}
|
}
|
||||||
} else if (event->modifiers() & Qt::ControlModifier)
|
} else if (event->modifiers() & Qt::ControlModifier)
|
||||||
select(index, CTRL_SELECT);
|
select(index, CTRL_SELECT);
|
||||||
// inbetween
|
|
||||||
|
// was the inbetween button clicked?
|
||||||
else if (sl->getType() == PLI_XSHLEVEL &&
|
else if (sl->getType() == PLI_XSHLEVEL &&
|
||||||
m_selection->isInInbetweenRange(fid) &&
|
m_selection->isInInbetweenRange(fid) &&
|
||||||
event->pos().x() > width() - 20 - fs_rightMargin) {
|
event->pos().x() > width() - 20 - fs_rightMargin) {
|
||||||
|
@ -731,25 +777,31 @@ void FilmstripFrames::mousePressEvent(QMouseEvent *event) {
|
||||||
tapp->getCurrentFrame()->setFrameIds(fids);
|
tapp->getCurrentFrame()->setFrameIds(fids);
|
||||||
tapp->getCurrentFrame()->setFid(fid);
|
tapp->getCurrentFrame()->setFid(fid);
|
||||||
|
|
||||||
if (!m_selection->isSelected(fid)) // selezione semplice
|
if (actualIconClicked &&
|
||||||
{
|
(!m_selection->isSelected(fid) || m_justStartedSelection)) {
|
||||||
// click su un frame non selezionato
|
// click on a non-selected frame
|
||||||
m_selecting = true; // posso estendere la selezione con il drag
|
m_selecting = true; // allow drag-select
|
||||||
select(index, START_DRAG_SELECT);
|
select(index, START_DRAG_SELECT);
|
||||||
} else if (m_selection->isSelected(fid)) {
|
} else if (m_selection->isSelected(fid)) {
|
||||||
// click su di un frame gia' selezionato. Puo' essere l'inizio di un
|
// if it's already selected - it can be drag and dropped
|
||||||
// drag'n'drop
|
m_dragDropArmed = true;
|
||||||
|
m_pos = event->pos();
|
||||||
|
// allow a the frame to be reselected if the mouse isn't moved far
|
||||||
|
// this is to enable a group selection to become a single selection
|
||||||
|
m_allowResetSelection = true;
|
||||||
|
m_indexForResetSelection = index;
|
||||||
|
} else if (!actualIconClicked) {
|
||||||
|
// this allows clicking the frame number to trigger an instant drag
|
||||||
|
select(index, ONLY_SELECT);
|
||||||
m_dragDropArmed = true;
|
m_dragDropArmed = true;
|
||||||
m_pos = event->pos();
|
m_pos = event->pos();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
update();
|
update();
|
||||||
} else if (event->button() == Qt::MidButton) {
|
|
||||||
m_pos = event->globalPos();
|
|
||||||
return;
|
|
||||||
} else if (event->button() == Qt::RightButton) {
|
} else if (event->button() == Qt::RightButton) {
|
||||||
select(index);
|
select(index);
|
||||||
}
|
}
|
||||||
|
m_justStartedSelection = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
@ -763,7 +815,7 @@ void FilmstripFrames::execNavigatorPan(const QPoint &point) {
|
||||||
fs_iconMarginBottom;
|
fs_iconMarginBottom;
|
||||||
QPoint clickedPos = point - QPoint(0, (index - i0) * frameHeight);
|
QPoint clickedPos = point - QPoint(0, (index - i0) * frameHeight);
|
||||||
|
|
||||||
if (fid != TApp::instance()->getCurrentFrame()->getFid()) return;
|
if (fid != getCurrentFrameId()) return;
|
||||||
|
|
||||||
QRect iconRect =
|
QRect iconRect =
|
||||||
QRect(QPoint(fs_leftMargin + fs_iconMarginLR,
|
QRect(QPoint(fs_leftMargin + fs_iconMarginLR,
|
||||||
|
@ -783,21 +835,22 @@ void FilmstripFrames::execNavigatorPan(const QPoint &point) {
|
||||||
delta.setX(delta.x() * m_icon2ViewerRatio.x());
|
delta.setX(delta.x() * m_icon2ViewerRatio.x());
|
||||||
delta.setY(delta.y() * m_icon2ViewerRatio.y());
|
delta.setY(delta.y() * m_icon2ViewerRatio.y());
|
||||||
|
|
||||||
if (TApp::instance()->getInknPaintViewerPanel()) {
|
if (m_viewer) m_viewer->navigatorPan(delta.toPoint());
|
||||||
SceneViewer *viewer =
|
|
||||||
TApp::instance()->getInknPaintViewerPanel()->getSceneViewer();
|
|
||||||
if (viewer) viewer->navigatorPan(delta.toPoint());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
void FilmstripFrames::mouseReleaseEvent(QMouseEvent *) {
|
void FilmstripFrames::mouseReleaseEvent(QMouseEvent *e) {
|
||||||
stopAutoPanning();
|
stopAutoPanning();
|
||||||
m_selecting = false;
|
m_selecting = false;
|
||||||
m_dragDropArmed = false;
|
m_dragDropArmed = false;
|
||||||
m_isNavigatorPanning = false;
|
m_isNavigatorPanning = false;
|
||||||
|
if (m_allowResetSelection) {
|
||||||
|
select(m_indexForResetSelection, ONLY_SELECT);
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
m_allowResetSelection = false;
|
||||||
|
m_indexForResetSelection = -1;
|
||||||
QApplication::restoreOverrideCursor();
|
QApplication::restoreOverrideCursor();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -806,18 +859,19 @@ void FilmstripFrames::mouseReleaseEvent(QMouseEvent *) {
|
||||||
void FilmstripFrames::mouseMoveEvent(QMouseEvent *e) {
|
void FilmstripFrames::mouseMoveEvent(QMouseEvent *e) {
|
||||||
QPoint pos = e->pos();
|
QPoint pos = e->pos();
|
||||||
int index = y2index(e->pos().y());
|
int index = y2index(e->pos().y());
|
||||||
if (e->buttons() & Qt::LeftButton) {
|
if (e->buttons() & Qt::LeftButton || e->buttons() & Qt::MiddleButton) {
|
||||||
// navigator pan
|
// navigator pan
|
||||||
if (m_isNavigatorPanning) {
|
if (m_isNavigatorPanning) {
|
||||||
execNavigatorPan(e->pos());
|
execNavigatorPan(e->pos());
|
||||||
e->accept();
|
e->accept();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (e->buttons() & Qt::MiddleButton) return;
|
||||||
if (m_dragDropArmed) {
|
if (m_dragDropArmed) {
|
||||||
if ((m_pos - e->pos()).manhattanLength() > 10) {
|
if ((m_pos - e->pos()).manhattanLength() > 10) {
|
||||||
startDragDrop();
|
startDragDrop();
|
||||||
m_dragDropArmed = false;
|
m_dragDropArmed = false;
|
||||||
|
m_allowResetSelection = false;
|
||||||
}
|
}
|
||||||
} else if (m_selecting) {
|
} else if (m_selecting) {
|
||||||
m_pos = e->globalPos();
|
m_pos = e->globalPos();
|
||||||
|
@ -825,22 +879,40 @@ void FilmstripFrames::mouseMoveEvent(QMouseEvent *e) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// autopan
|
// autopan
|
||||||
|
int speed = getOneFrameHeight() / 64;
|
||||||
|
|
||||||
QRect visibleRect = visibleRegion().boundingRect();
|
QRect visibleRect = visibleRegion().boundingRect();
|
||||||
if (pos.y() < visibleRect.top())
|
int visibleTop = visibleRect.top();
|
||||||
m_scrollSpeed = -(5 + (visibleRect.top() - pos.y()) / 4);
|
int visibleBottom = visibleRect.bottom();
|
||||||
else if (pos.y() > visibleRect.bottom())
|
if (pos.y() < visibleRect.top()) {
|
||||||
m_scrollSpeed = (5 + (pos.y() - visibleRect.bottom()) / 4);
|
m_scrollSpeed = -speed;
|
||||||
else
|
if (visibleRect.top() - pos.y() > 30) {
|
||||||
|
m_timerInterval = 50;
|
||||||
|
} else if (visibleRect.top() - pos.y() > 15) {
|
||||||
|
m_timerInterval = 150;
|
||||||
|
} else {
|
||||||
|
m_timerInterval = 300;
|
||||||
|
}
|
||||||
|
} else if (pos.y() > visibleRect.bottom()) {
|
||||||
|
m_scrollSpeed = speed;
|
||||||
|
if (pos.y() - visibleRect.bottom() > 30) {
|
||||||
|
m_timerInterval = 50;
|
||||||
|
} else if (pos.y() - visibleRect.bottom() > 15) {
|
||||||
|
m_timerInterval = 150;
|
||||||
|
} else {
|
||||||
|
m_timerInterval = 300;
|
||||||
|
}
|
||||||
|
} else
|
||||||
m_scrollSpeed = 0;
|
m_scrollSpeed = 0;
|
||||||
if (m_scrollSpeed != 0)
|
if (m_scrollSpeed != 0) {
|
||||||
startAutoPanning();
|
startAutoPanning();
|
||||||
else
|
} else
|
||||||
stopAutoPanning();
|
stopAutoPanning();
|
||||||
update();
|
update();
|
||||||
} else if (e->buttons() & Qt::MidButton) {
|
} else if (e->buttons() & Qt::MidButton) {
|
||||||
// scroll con il tasto centrale
|
// scroll con il tasto centrale
|
||||||
pos = e->globalPos();
|
pos = e->globalPos();
|
||||||
scroll(m_pos.y() - pos.y());
|
scroll((m_pos.y() - pos.y()) * 10);
|
||||||
m_pos = pos;
|
m_pos = pos;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -882,7 +954,7 @@ void FilmstripFrames::keyPressEvent(QKeyEvent *event) {
|
||||||
m_selection->selectNone();
|
m_selection->selectNone();
|
||||||
if (getLevel()) m_selection->select(fh->getFid());
|
if (getLevel()) m_selection->select(fh->getFid());
|
||||||
int index = fid2index(fh->getFid());
|
int index = fid2index(fh->getFid());
|
||||||
if (index >= 0) exponeFrame(index);
|
if (index >= 0) showFrame(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
@ -894,7 +966,7 @@ void FilmstripFrames::wheelEvent(QWheelEvent *event) {
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
void FilmstripFrames::startAutoPanning() {
|
void FilmstripFrames::startAutoPanning() {
|
||||||
if (m_timerId == 0) m_timerId = startTimer(40);
|
if (m_timerId == 0) m_timerId = startTimer(m_timerInterval);
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
@ -911,11 +983,15 @@ void FilmstripFrames::stopAutoPanning() {
|
||||||
|
|
||||||
void FilmstripFrames::timerEvent(QTimerEvent *) {
|
void FilmstripFrames::timerEvent(QTimerEvent *) {
|
||||||
scroll(m_scrollSpeed);
|
scroll(m_scrollSpeed);
|
||||||
|
// reset the timer in case m_scroll speed has changed
|
||||||
|
killTimer(m_timerId);
|
||||||
|
m_timerId = 0;
|
||||||
|
m_timerId = startTimer(m_timerInterval);
|
||||||
if (m_selecting) {
|
if (m_selecting) {
|
||||||
QPoint pos = mapFromGlobal(m_pos);
|
QPoint pos = mapFromGlobal(m_pos);
|
||||||
int index = y2index(pos.y());
|
int index = y2index(pos.y());
|
||||||
select(index, DRAG_SELECT);
|
select(index, DRAG_SELECT);
|
||||||
|
showFrame(index);
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -991,25 +1067,20 @@ void FilmstripFrames::onFrameSwitched() {
|
||||||
// m_selection->selectNone();
|
// m_selection->selectNone();
|
||||||
TApp *app = TApp::instance();
|
TApp *app = TApp::instance();
|
||||||
TFrameHandle *fh = app->getCurrentFrame();
|
TFrameHandle *fh = app->getCurrentFrame();
|
||||||
TFrameId fid;
|
TFrameId fid = getCurrentFrameId();
|
||||||
if (fh->isEditingLevel())
|
|
||||||
fid = fh->getFid();
|
|
||||||
else {
|
|
||||||
TXsheet *xsh = app->getCurrentXsheet()->getXsheet();
|
|
||||||
int col = app->getCurrentColumn()->getColumnIndex();
|
|
||||||
int row = fh->getFrame();
|
|
||||||
if (row < 0 || col < 0) return;
|
|
||||||
TXshCell cell = xsh->getCell(row, col);
|
|
||||||
if (cell.isEmpty()) return;
|
|
||||||
fid = cell.getFrameId();
|
|
||||||
}
|
|
||||||
int index = fid2index(fid);
|
int index = fid2index(fid);
|
||||||
if (index >= 0) {
|
if (index >= 0) {
|
||||||
exponeFrame(index);
|
showFrame(index);
|
||||||
// clear selection and select only the destination frame
|
|
||||||
TFilmstripSelection *fsSelection =
|
TFilmstripSelection *fsSelection =
|
||||||
dynamic_cast<TFilmstripSelection *>(TSelection::getCurrent());
|
dynamic_cast<TFilmstripSelection *>(TSelection::getCurrent());
|
||||||
if (fsSelection) select(index, ONLY_SELECT);
|
|
||||||
|
// don't select if already selected - may be part of a group selection
|
||||||
|
if (!m_selection->isSelected(index2fid(index)) && fsSelection) {
|
||||||
|
select(index, ONLY_SELECT);
|
||||||
|
m_justStartedSelection = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,7 @@ class TXshSimpleLevel;
|
||||||
class QComboBox;
|
class QComboBox;
|
||||||
class InbetweenDialog;
|
class InbetweenDialog;
|
||||||
class TXshLevel;
|
class TXshLevel;
|
||||||
|
class SceneViewer;
|
||||||
|
|
||||||
const int fs_leftMargin = 2;
|
const int fs_leftMargin = 2;
|
||||||
const int fs_rightMargin = 3;
|
const int fs_rightMargin = 3;
|
||||||
|
@ -54,25 +55,24 @@ public:
|
||||||
void setDarkLineColor(const QColor &color) { m_darkLineColor = color; }
|
void setDarkLineColor(const QColor &color) { m_darkLineColor = color; }
|
||||||
QColor getDarkLineColor() const { return m_darkLineColor; }
|
QColor getDarkLineColor() const { return m_darkLineColor; }
|
||||||
|
|
||||||
// helper method: ritorna il livello corrente
|
// helper method: get the current level
|
||||||
TXshSimpleLevel *getLevel() const;
|
TXshSimpleLevel *getLevel() const;
|
||||||
|
|
||||||
QSize getIconSize() const { return m_iconSize; }
|
QSize getIconSize() const { return m_iconSize; }
|
||||||
int getFrameLabelWidth() const { return m_frameLabelWidth; }
|
int getFrameLabelWidth() const { return m_frameLabelWidth; }
|
||||||
|
|
||||||
// la y si riferisce al margine superiore dell'iconcina index-esima
|
// convert mouse coordinate y to a frame index and vice versa
|
||||||
int y2index(int y) const;
|
int y2index(int y) const;
|
||||||
int index2y(int index) const;
|
int index2y(int index) const;
|
||||||
|
|
||||||
// se c'e' un livello e 0<=index<frameCount ritorna il frameid index-esimo
|
// returns the frame id of the provided index if index >= 0
|
||||||
// altrimenti ritorna TFrameId()
|
// otherwise returns TFrameId()
|
||||||
TFrameId index2fid(int index) const;
|
TFrameId index2fid(int index) const;
|
||||||
|
|
||||||
// se c'e' un livello e fid e' un frame del livello ritorna l'indice.
|
// returns the index if the frame exists, otherwise -1
|
||||||
// altrimenti -1
|
|
||||||
int fid2index(const TFrameId &fid) const;
|
int fid2index(const TFrameId &fid) const;
|
||||||
|
|
||||||
// restituisce l'altezza dei frames esistenti (piu' uno vuoto)
|
// returns the height of all frames plus a blank one
|
||||||
int getFramesHeight() const;
|
int getFramesHeight() const;
|
||||||
|
|
||||||
// aggiorna le dimensioni del QWidget in base al numero di fotogrammi del
|
// aggiorna le dimensioni del QWidget in base al numero di fotogrammi del
|
||||||
|
@ -84,9 +84,8 @@ public:
|
||||||
// visibleRegion().boundingRect().bottom()
|
// visibleRegion().boundingRect().bottom()
|
||||||
void updateContentHeight(int minimumHeight = -1);
|
void updateContentHeight(int minimumHeight = -1);
|
||||||
|
|
||||||
// assicura che il frame index-esimo sia visibile (eventualmente facendo
|
// makes sure that the indexed frame is visible (scrolling if necessary)
|
||||||
// scroll)
|
void showFrame(int index);
|
||||||
void exponeFrame(int index);
|
|
||||||
|
|
||||||
// esegue uno scroll di dy pixel. se dy<0 fa scorrere i fotogrammi verso
|
// esegue uno scroll di dy pixel. se dy<0 fa scorrere i fotogrammi verso
|
||||||
// l'alto
|
// l'alto
|
||||||
|
@ -124,13 +123,15 @@ protected:
|
||||||
void mousePressEvent(QMouseEvent *event) override;
|
void mousePressEvent(QMouseEvent *event) override;
|
||||||
void mouseReleaseEvent(QMouseEvent *event) override;
|
void mouseReleaseEvent(QMouseEvent *event) override;
|
||||||
void mouseMoveEvent(QMouseEvent *) override;
|
void mouseMoveEvent(QMouseEvent *) override;
|
||||||
|
void enterEvent(QEvent *event) override;
|
||||||
void keyPressEvent(QKeyEvent *event) override;
|
void keyPressEvent(QKeyEvent *event) override;
|
||||||
void wheelEvent(QWheelEvent *event) override;
|
void wheelEvent(QWheelEvent *event) override;
|
||||||
|
|
||||||
void startAutoPanning();
|
void startAutoPanning();
|
||||||
void stopAutoPanning();
|
void stopAutoPanning();
|
||||||
void timerEvent(QTimerEvent *) override;
|
void timerEvent(QTimerEvent *) override;
|
||||||
|
TFrameId getCurrentFrameId();
|
||||||
|
void getViewer();
|
||||||
void contextMenuEvent(QContextMenuEvent *event) override;
|
void contextMenuEvent(QContextMenuEvent *event) override;
|
||||||
|
|
||||||
void startDragDrop();
|
void startDragDrop();
|
||||||
|
@ -164,7 +165,12 @@ private:
|
||||||
TFilmstripSelection *m_selection;
|
TFilmstripSelection *m_selection;
|
||||||
FilmstripFrameHeadGadget *m_frameHeadGadget;
|
FilmstripFrameHeadGadget *m_frameHeadGadget;
|
||||||
InbetweenDialog *m_inbetweenDialog;
|
InbetweenDialog *m_inbetweenDialog;
|
||||||
|
SceneViewer *m_viewer;
|
||||||
|
bool m_isGhibli = false;
|
||||||
|
bool m_justStartedSelection = false;
|
||||||
|
int m_indexForResetSelection = -1;
|
||||||
|
bool m_allowResetSelection = false;
|
||||||
|
int m_timerInterval = 100;
|
||||||
// State data
|
// State data
|
||||||
|
|
||||||
QPoint m_pos; //!< Last mouse position.
|
QPoint m_pos; //!< Last mouse position.
|
||||||
|
|
|
@ -53,6 +53,7 @@ FrameHeadGadget::~FrameHeadGadget() {}
|
||||||
|
|
||||||
void FrameHeadGadget::draw(QPainter &p, const QColor &lightColor,
|
void FrameHeadGadget::draw(QPainter &p, const QColor &lightColor,
|
||||||
const QColor &darkColor) {
|
const QColor &darkColor) {
|
||||||
|
// drawPlayingHead(p, lightColor, darkColor);
|
||||||
if (!Preferences::instance()->isOnionSkinEnabled()) return;
|
if (!Preferences::instance()->isOnionSkinEnabled()) return;
|
||||||
drawOnionSkinSelection(p, lightColor, darkColor);
|
drawOnionSkinSelection(p, lightColor, darkColor);
|
||||||
}
|
}
|
||||||
|
|
|
@ -758,6 +758,7 @@ void SceneViewer::showEvent(QShowEvent *) {
|
||||||
fitToCamera();
|
fitToCamera();
|
||||||
m_shownOnce = true;
|
m_shownOnce = true;
|
||||||
}
|
}
|
||||||
|
TApp::instance()->setActiveViewer(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
|
@ -322,7 +322,8 @@ void SceneViewer::enterEvent(QEvent *) {
|
||||||
|
|
||||||
m_isMouseEntered = true;
|
m_isMouseEntered = true;
|
||||||
|
|
||||||
TApp *app = TApp::instance();
|
TApp *app = TApp::instance();
|
||||||
|
app->setActiveViewer(this);
|
||||||
modifiers = 0;
|
modifiers = 0;
|
||||||
TTool *tool = app->getCurrentTool()->getTool();
|
TTool *tool = app->getCurrentTool()->getTool();
|
||||||
TXshLevel *level = app->getCurrentLevel()->getLevel();
|
TXshLevel *level = app->getCurrentLevel()->getLevel();
|
||||||
|
|
|
@ -25,6 +25,7 @@ class QMainWindow;
|
||||||
|
|
||||||
class TMainWindow;
|
class TMainWindow;
|
||||||
class ComboViewerPanel;
|
class ComboViewerPanel;
|
||||||
|
class SceneViewer;
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
// TXsheeHandle
|
// TXsheeHandle
|
||||||
|
@ -82,6 +83,7 @@ class TApp final : public QObject,
|
||||||
// keep a pointer of the inknpaint viewer in order to enable navigator pan in
|
// keep a pointer of the inknpaint viewer in order to enable navigator pan in
|
||||||
// the filmstrip
|
// the filmstrip
|
||||||
ComboViewerPanel *m_inknPaintViewerPanel;
|
ComboViewerPanel *m_inknPaintViewerPanel;
|
||||||
|
SceneViewer *m_activeViewer;
|
||||||
|
|
||||||
int m_autosavePeriod; // minutes
|
int m_autosavePeriod; // minutes
|
||||||
bool m_autosaveSuspended;
|
bool m_autosaveSuspended;
|
||||||
|
@ -195,6 +197,10 @@ public:
|
||||||
return m_inknPaintViewerPanel;
|
return m_inknPaintViewerPanel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setActiveViewer(SceneViewer *viewer) { m_activeViewer = viewer; }
|
||||||
|
|
||||||
|
SceneViewer *getActiveViewer() const { return m_activeViewer; }
|
||||||
|
|
||||||
bool isApplicationStarting() { return m_isStarting; }
|
bool isApplicationStarting() { return m_isStarting; }
|
||||||
|
|
||||||
bool isPenCloseToTablet() const { return m_isPenCloseToTablet; }
|
bool isPenCloseToTablet() const { return m_isPenCloseToTablet; }
|
||||||
|
|
|
@ -70,6 +70,7 @@
|
||||||
#include "toonz/txshcell.h"
|
#include "toonz/txshcell.h"
|
||||||
#include "toonz/cleanupcolorstyles.h"
|
#include "toonz/cleanupcolorstyles.h"
|
||||||
#include "toonz/palettecmd.h"
|
#include "toonz/palettecmd.h"
|
||||||
|
#include "toonz/preferences.h"
|
||||||
#include "tw/stringtable.h"
|
#include "tw/stringtable.h"
|
||||||
|
|
||||||
// TnzBase includes
|
// TnzBase includes
|
||||||
|
|
Loading…
Reference in a new issue