enhance viewer preview - render all frames, multi-thread mode - render cell selection range mode - enable to set shortcut key - enable to set sub camera larger than the original

This commit is contained in:
shun-iwasawa 2022-12-14 09:55:24 +09:00 committed by manongjohn
parent 793337e5b8
commit 2c5f655363
15 changed files with 551 additions and 62 deletions

View file

@ -300,6 +300,7 @@ public:
UINT getCustomizeMask() { return m_customizeMask; }
void setCustomizemask(UINT mask);
void setStopAt(int frame);
void setStartAt(int frame);
// the main (currently the only) use for current flipconsole and setActive is
// to
@ -382,6 +383,8 @@ private:
int m_from, m_to, m_step;
int m_currentFrame, m_framesCount;
int m_stopAt = -1;
int m_startAt =
-1; // used in the "play selection" mode of the viewer preview
ImagePainter::VisualSettings m_settings;
bool m_isPlay;

View file

@ -489,6 +489,9 @@ centralWidget->setLayout(centralWidgetLayout);*/
if (TSystem::doesExistFileOrLevel(TFilePath(ffmpegCachePath))) {
TSystem::rmDirTree(TFilePath(ffmpegCachePath));
}
connect(TApp::instance(), SIGNAL(activeViewerChanged()), this,
SLOT(onActiveViewerChanged()));
}
//-----------------------------------------------------------------------------
@ -1358,6 +1361,27 @@ void MainWindow::onUpdateCheckerDone(bool error) {
disconnect(m_updateChecker);
m_updateChecker->deleteLater();
}
//-----------------------------------------------------------------------------
void MainWindow::onActiveViewerChanged() {
// sync the command state to the button state of the activated viewer
SceneViewer *activeViewer = TApp::instance()->getActiveViewer();
if (!activeViewer) return;
BaseViewerPanel *bvp = qobject_cast<BaseViewerPanel *>(
activeViewer->parentWidget()->parentWidget());
if (!bvp) return;
bool prev, subCamPrev;
bvp->getPreviewButtonStates(prev, subCamPrev);
CommandManager::instance()
->getAction(MI_ToggleViewerPreview)
->setChecked(prev);
CommandManager::instance()
->getAction(MI_ToggleViewerSubCameraPreview)
->setChecked(subCamPrev);
}
//-----------------------------------------------------------------------------
void MainWindow::closeEvent(QCloseEvent *event) {
@ -2176,6 +2200,12 @@ void MainWindow::defineActions() {
createMenuRenderAction(MI_SavePreviewedFrames,
QT_TR_NOOP("&Save Previewed Frames"), "",
"save_previewed_frames", tr("Save the images created during preview to a specified location."));
createToggle(MI_ToggleViewerPreview, QT_TR_NOOP("Toggle Viewer Preview"), "",
false, MenuRenderCommandType, "pane_preview");
createToggle(MI_ToggleViewerSubCameraPreview,
QT_TR_NOOP("Toggle Viewer Sub-camera Preview"), "", false,
MenuRenderCommandType, "pane_subpreview");
createMenuRenderAction(MI_SaveAndRender, QT_TR_NOOP("&Save and Render"), "", "render",
tr("Saves the current scene and renders according to the settings and "
"location set in Output Settings."));

View file

@ -246,6 +246,7 @@ protected slots:
void onInk1CheckTriggered(bool on);
void onUpdateCheckerDone(bool);
void onActiveViewerChanged();
void toggleStatusBar(bool);
void toggleTransparency(bool);

View file

@ -64,6 +64,8 @@
#define MI_FreezePreview "MI_FrezzePreview"
#define MI_SavePreviewedFrames "MI_SavePreviewedFrames"
// #define MI_SavePreview "MI_SavePreview"
#define MI_ToggleViewerPreview "MI_ToggleViewerPreview"
#define MI_ToggleViewerSubCameraPreview "MI_ToggleViewerSubCameraPreview"
#define MI_Print "MI_Print"
#define MI_Preferences "MI_Preferences"
#define MI_SavePreset "MI_SavePreset"

View file

@ -44,6 +44,7 @@
#include <QGroupBox>
extern TEnv::StringVar EnvSafeAreaName;
extern TEnv::IntVar EnvViewerPreviewBehavior;
extern TEnv::IntVar CameraViewTransparency;
extern TEnv::IntVar ShowRuleOfThirds;
extern TEnv::IntVar ShowGoldenRatio;
@ -475,6 +476,58 @@ void TPanelTitleBarButtonForGrids::mousePressEvent(QMouseEvent *e) {
m_menu->exec(e->globalPos() + QPoint(-100, 12));
}
//=============================================================================
// TPanelTitleBarButtonForPreview
//-----------------------------------------------------------------------------
void TPanelTitleBarButtonForPreview::mousePressEvent(QMouseEvent *e) {
if (e->button() != Qt::RightButton) {
m_pressed = !m_pressed;
emit toggled(m_pressed);
update();
}
}
//-----------------------------------------------------------------------------
void TPanelTitleBarButtonForPreview::contextMenuEvent(QContextMenuEvent *e) {
QMenu menu(this);
// 0: current frame
// 1: all frames in the preview range
// 2: selected cell, auto play once & stop
QStringList behaviorsStrList = {tr("Current frame"),
tr("All preview range frames"),
tr("Selected cells - Auto play")};
QActionGroup *behaviorGroup = new QActionGroup(this);
for (int i = 0; i < behaviorsStrList.size(); i++) {
QAction *action = menu.addAction(behaviorsStrList.at(i));
action->setData(i);
connect(action, SIGNAL(triggered()), this, SLOT(onSetPreviewBehavior()));
action->setCheckable(true);
behaviorGroup->addAction(action);
if (i == EnvViewerPreviewBehavior) action->setChecked(true);
}
menu.exec(e->globalPos());
}
//-----------------------------------------------------------------------------
void TPanelTitleBarButtonForPreview::onSetPreviewBehavior() {
int behaviorId = qobject_cast<QAction *>(sender())->data().toInt();
// change safearea if the different one is selected
if (EnvViewerPreviewBehavior != behaviorId) {
EnvViewerPreviewBehavior = behaviorId;
// emit sceneChanged without setting dirty flag
TApp::instance()->getCurrentScene()->notifySceneChanged(false);
}
}
//-----------------------------------------------------------------------------
//=============================================================================
// TPanelTitleBarButtonSet
//-----------------------------------------------------------------------------

View file

@ -75,7 +75,7 @@ signals:
};
//-----------------------------------------------------------------------------
/*! specialized button for sage area which enables to choose safe area size by
/*! specialized button for safe area which enables to choose safe area size by
* context menu
*/
@ -130,6 +130,27 @@ signals:
void updateViewer();
};
//-----------------------------------------------------------------------------
/*! specialized button for safe area which enables to choose safe area size by
* context menu
*/
class TPanelTitleBarButtonForPreview final : public TPanelTitleBarButton {
Q_OBJECT
public:
TPanelTitleBarButtonForPreview(QWidget *parent,
const QString &standardPixmapName)
: TPanelTitleBarButton(parent, standardPixmapName) {}
bool isChecked() { return m_pressed; }
protected:
void contextMenuEvent(QContextMenuEvent *event) override;
void mousePressEvent(QMouseEvent *event) override;
protected slots:
void onSetPreviewBehavior();
};
//-----------------------------------------------------------------------------
//! a buttonset can group different TPanelTitleBarButton

View file

@ -196,6 +196,9 @@ public:
// are assumed correct.
void refreshFrame(int frame);
void addRenderData(std::vector<TRenderer::RenderData> &datas, int frame);
void addFramesToRenderQueue(const std::vector<int> frames);
// TRenderPort methods
void onRenderRasterStarted(const RenderData &renderData) override;
void onRenderRasterCompleted(const RenderData &renderData) override;
@ -709,21 +712,33 @@ void Previewer::Imp::doOnRenderRasterCompleted(const RenderData &renderData) {
it->second
.m_rectUnderRender); // Extract may MODIFY IT! E.g. with shrinks..!
cachedRas = cachedRas->extract(rectUnderRender);
if (cachedRas) {
cachedRas->copy(ras);
TImageCache::instance()->add(str, ri);
}
// Submit the image to the cache, for all cluster's frames
unsigned int i, size = renderData.m_frames.size();
for (i = 0; i < size; ++i) {
int f = renderData.m_frames[i];
std::map<int, FrameInfo>::iterator f_it = m_frames.find(f);
if (f_it == m_frames.end()) continue;
if (cachedRas) {
std::string f_str = m_cachePrefix + std::to_string(f);
TImageCache::instance()->add(f_str, ri);
}
// Update the FrameInfo
it->second.m_renderedRegion += toQRect(it->second.m_rectUnderRender);
it->second.m_rectUnderRender = TRect();
f_it->second.m_renderedRegion += toQRect(f_it->second.m_rectUnderRender);
f_it->second.m_rectUnderRender = TRect();
// Update the progress bar status
if (frame < m_pbStatus.size())
m_pbStatus[frame] = FlipSlider::PBFrameFinished;
if (f < m_pbStatus.size()) m_pbStatus[f] = FlipSlider::PBFrameFinished;
// Notify listeners
notifyCompleted(frame);
notifyCompleted(f);
}
}
//-----------------------------------------------------------------------------
@ -977,6 +992,69 @@ void Previewer::Imp::saveFrame() {
savedFrames = 0;
}
//-----------------------------------------------------------------------------
void Previewer::Imp::addRenderData(std::vector<TRenderer::RenderData> &datas,
int frame) {
// Build the TFxPair to be passed to TRenderer
TFxPair fxPair = buildSceneFx(frame);
// Update the RenderInfos associated with frame
m_frames[frame].m_rectUnderRender = m_previewRect;
m_frames[frame].m_alias = fxPair.m_frameA->getAlias(frame, m_renderSettings);
if (fxPair.m_frameB)
m_frames[frame].m_alias =
m_frames[frame].m_alias +
fxPair.m_frameB->getAlias(frame, m_renderSettings);
// Retrieve the renderId of the rendering instance
m_frames[frame].m_renderId = m_renderer.nextRenderId();
std::string contextName("P");
contextName += m_subcamera ? "SC" : "FU";
contextName += std::to_string(frame);
TPassiveCacheManager::instance()->setContextName(m_frames[frame].m_renderId,
contextName);
datas.push_back(TRenderer::RenderData(frame, m_renderSettings, fxPair));
}
//-----------------------------------------------------------------------------
void Previewer::Imp::addFramesToRenderQueue(const std::vector<int> frames) {
if (suspendedRendering) return;
// Build the region to render
updatePreviewRect();
if (m_previewRect.getLx() <= 0 || m_previewRect.getLy() <= 0) return;
RenderDataVector *renderDatas = new RenderDataVector;
for (const auto &f : frames) {
std::map<int, FrameInfo>::iterator it = m_frames.find(f);
if (it == m_frames.end()) {
it = m_frames.insert(std::make_pair(f, FrameInfo())).first;
// In case the frame is not in the frame range, we add a temporary
// supplement
// to the progress bar.
if (f >= (int)m_pbStatus.size()) m_pbStatus.resize(f + 1);
addRenderData(*renderDatas, f);
} else if (f < m_pbStatus.size() &&
m_pbStatus[f] == FlipSlider::PBFrameNotStarted) {
// In case the rect we would render is contained in the frame's rendered
// region, quit
if (::contains(it->second.m_renderedRegion, m_previewRect)) return;
// Then, check the m_previewRect against the frame's m_rectUnderRendering.
// Ensure that we're not re-launching the very same render.
if (it->second.m_rectUnderRender == m_previewRect) return;
// Stop any frame's previously running render process
m_renderer.abortRendering(it->second.m_renderId);
addRenderData(*renderDatas, f);
}
}
// Finally, start rendering all frames which were not found in cache
m_renderer.startRendering(renderDatas);
}
//=============================================================================
// Previewer
//-----------------------------------------------------------------------------
@ -1138,8 +1216,8 @@ void Previewer::saveRenderedFrames() {
//-----------------------------------------------------------------------------
/*! Restituisce un puntatore al raster randerizzato se il frame e' disponibile,
altrimenti comincia a calcolarlo*/
/*! Returns a pointer to the rendered raster if the frame is available,
otherwise start calculating it */
TRasterP Previewer::getRaster(int frame, bool renderIfNeeded) const {
if (frame < 0) return TRasterP();
std::map<int, Imp::FrameInfo>::iterator it = m_imp->m_frames.find(frame);
@ -1184,6 +1262,13 @@ TRasterP Previewer::getRaster(int frame, bool renderIfNeeded) const {
//-----------------------------------------------------------------------------
void Previewer::addFramesToRenderQueue(const std::vector<int> frames) const {
if (suspendedRendering) return;
m_imp->addFramesToRenderQueue(frames);
}
//-----------------------------------------------------------------------------
//! Verifica se \b frame e' nella cache, cioe' se il frame e' disponibile
bool Previewer::isFrameReady(int frame) const {
if (frame < 0 || frame >= (int)m_imp->m_pbStatus.size()) return false;

View file

@ -70,6 +70,7 @@ public:
void removeListener(Listener *);
TRasterP getRaster(int frame, bool renderIfNeeded = true) const;
void addFramesToRenderQueue(const std::vector<int> frames) const;
bool isFrameReady(int frame) const;
bool doSaveRenderedFrames(TFilePath fp);

View file

@ -12,6 +12,8 @@
#include "ruler.h"
#include "locatorpopup.h"
#include "../stopmotion/stopmotion.h"
#include "tenv.h"
#include "cellselection.h"
// TnzTools includes
#include "tools/cursors.h"
@ -59,6 +61,7 @@
#include "toonz/toonzimageutils.h"
#include "toonz/txshleveltypes.h"
#include "subcameramanager.h"
#include "toutputproperties.h"
// TnzCore includes
#include "tpalette.h"
@ -96,6 +99,11 @@ TEnv::IntVar ShowSymmetryGuide("ShowSymmetryGuide", 1);
void drawSpline(const TAffine &viewMatrix, const TRect &clipRect, bool camera3d,
double pixelSize);
// 0: current frame
// 1: all frames in the preview range
// 2: selected cell, auto play once & stop
TEnv::IntVar EnvViewerPreviewBehavior("ViewerPreviewBehavior", 0);
//-------------------------------------------------------------------------------
namespace {
@ -968,16 +976,47 @@ void SceneViewer::enablePreview(int previewMode) {
Previewer::instance(m_previewMode == SUBCAMERA_PREVIEW)
->removeListener(this);
m_previewMode = previewMode;
// Schedule as a listener to Previewer.
if (previewMode != NO_PREVIEW) {
if (m_previewMode != NO_PREVIEW) {
Previewer *previewer =
Previewer::instance(previewMode == SUBCAMERA_PREVIEW);
Previewer::instance(m_previewMode == SUBCAMERA_PREVIEW);
previewer->addListener(this);
// 0: current frame
// 1: all frames in the preview range
// 2: selected cell, auto play once & stop
if (EnvViewerPreviewBehavior == 1) {
int r0, r1, step;
ToonzScene *scene = app->getCurrentScene()->getScene();
scene->getProperties()->getPreviewProperties()->getRange(r0, r1, step);
if (r0 > r1) {
r0 = 0;
r1 = scene->getFrameCount() - 1;
}
int currentFrame = app->getCurrentFrame()->getFrame();
std::vector<int> queueFrames;
for (int f = currentFrame; f <= r1; f += step) queueFrames.push_back(f);
for (int f = r0; f < currentFrame; f += step) queueFrames.push_back(f);
previewer->addFramesToRenderQueue(queueFrames);
} else if (EnvViewerPreviewBehavior == 2) {
TCellSelection *cellSel =
dynamic_cast<TCellSelection *>(TSelection::getCurrent());
if (cellSel && !cellSel->isEmpty()) {
int r0, c0, r1, c1;
cellSel->getSelectedCells(r0, c0, r1, c1);
if (r0 < r1) {
std::vector<int> queueFrames;
for (int f = r0; f <= r1; f++) queueFrames.push_back(f);
previewer->addFramesToRenderQueue(queueFrames);
}
}
}
previewer->update();
}
m_previewMode = previewMode;
GLInvalidateAll();
// for updating the title bar
@ -1043,7 +1082,8 @@ void SceneViewer::showEvent(QShowEvent *) {
m_visualSettings.m_sceneProperties =
TApp::instance()->getCurrentScene()->getScene()->getProperties();
// If the viewer is hidden and preview is activated, remove the listener from preview
// If the viewer is hidden and preview is activated, remove the listener from
// preview
if (m_previewMode != NO_PREVIEW)
Previewer::instance(m_previewMode == SUBCAMERA_PREVIEW)->addListener(this);
@ -1127,7 +1167,8 @@ void SceneViewer::showEvent(QShowEvent *) {
//-----------------------------------------------------------------------------
void SceneViewer::hideEvent(QHideEvent *) {
// If the viewer is hidden and preview is activated, remove the listener from preview
// If the viewer is hidden and preview is activated, remove the listener from
// preview
if (m_previewMode != NO_PREVIEW)
Previewer::instance(m_previewMode == SUBCAMERA_PREVIEW)
->removeListener(this);

View file

@ -31,6 +31,11 @@ inline bool bitwiseContains(UCHAR flag, UCHAR state) {
inline bool bitwiseExclude(UCHAR flag, UCHAR state) {
return bitwiseContains(~state, flag);
}
inline bool areNear(double v0, double v1, double thres = 20.0) {
return std::abs(v0 - v1) < thres;
}
} // namespace
//********************************************************************************
@ -147,6 +152,27 @@ bool PreviewSubCameraManager::mouseMoveEvent(SceneViewer *viewer,
TPointD worldCurPos(viewer->winToWorld(curPos));
TApp *app = TApp::instance();
TCamera *camera = app->getCurrentScene()->getScene()->getCurrentCamera();
TRectD cameraStageRect(camera->getCameraToStageRef() *
convert(TRect(camera->getRes())));
// Snap to the current camera frame
// horizontal
if (worldCurPos.x < worldMousePressPos.x &&
areNear(worldCurPos.x, cameraStageRect.x0))
worldCurPos.x = cameraStageRect.x0;
else if (worldCurPos.x > worldMousePressPos.x &&
areNear(worldCurPos.x, cameraStageRect.x1))
worldCurPos.x = cameraStageRect.x1;
// vertical
if (worldCurPos.y < worldMousePressPos.y &&
areNear(worldCurPos.y, cameraStageRect.y0))
worldCurPos.y = cameraStageRect.y0;
else if (worldCurPos.y > worldMousePressPos.y &&
areNear(worldCurPos.y, cameraStageRect.y1))
worldCurPos.y = cameraStageRect.y1;
TAffine cameraAffInv(
app->getCurrentXsheet()
->getXsheet()
@ -162,15 +188,17 @@ bool PreviewSubCameraManager::mouseMoveEvent(SceneViewer *viewer,
std::max(worldMousePressPos.x, worldCurPos.x),
std::max(worldMousePressPos.y, worldCurPos.y));
TCamera *camera = app->getCurrentScene()->getScene()->getCurrentCamera();
// camera->setInterestStageRect(worldPreviewSubCameraRect);
TRectD previewSubCameraD(camera->getStageToCameraRef() *
worldPreviewSubCameraRect);
m_editingInterestRect =
TRect(previewSubCameraD.x0, previewSubCameraD.y0,
previewSubCameraD.x1 - 1, previewSubCameraD.y1 - 1) *
TRect(camera->getRes());
previewSubCameraD.x1 - 1, previewSubCameraD.y1 - 1);
// m_editingInterestRect =
// TRect(previewSubCameraD.x0, previewSubCameraD.y0,
// previewSubCameraD.x1 - 1, previewSubCameraD.y1 - 1) *
// TRect(camera->getRes());
viewer->update();
} else {
@ -194,7 +222,8 @@ bool PreviewSubCameraManager::mouseMoveEvent(SceneViewer *viewer,
subRect.y1 = subRect.y1 + dragDistance.y;
}
m_editingInterestRect = subRect * TRect(camera->getRes());
m_editingInterestRect = subRect;
// m_editingInterestRect = subRect * TRect(camera->getRes());
viewer->update();
}
@ -301,11 +330,32 @@ UCHAR PreviewSubCameraManager::getSubCameraDragEnum(SceneViewer *viewer,
//-----------------------------------------------------------------------------
TPoint PreviewSubCameraManager::getSubCameraDragDistance(
SceneViewer *viewer, const QPointF &mousePos) {
TPoint PreviewSubCameraManager::getSubCameraDragDistance(SceneViewer *viewer,
QPointF &mousePos) {
// Build the camera drag distance
if (m_clickAndDrag) return TPoint();
// Snap to the current camera frame
TCamera *camera =
TApp::instance()->getCurrentScene()->getScene()->getCurrentCamera();
if (!bitwiseExclude(m_dragType, OUTER)) {
TPointD btmLft(cameraToWin(viewer, TPointD(0, 0)));
TPointD tpRght(
cameraToWin(viewer, TPointD(camera->getRes().lx, camera->getRes().ly)));
if (bitwiseContains(m_dragType, DRAG_LEFT) &&
areNear(mousePos.x(), btmLft.x))
mousePos.setX(btmLft.x);
else if (bitwiseContains(m_dragType, DRAG_RIGHT) &&
areNear(mousePos.x(), tpRght.x))
mousePos.setX(tpRght.x);
if (bitwiseContains(m_dragType, DRAG_BOTTOM) &&
areNear(mousePos.y(), (double)viewer->height() - btmLft.y))
mousePos.setY((double)viewer->height() - btmLft.y);
else if (bitwiseContains(m_dragType, DRAG_TOP) &&
areNear(mousePos.y(), (double)viewer->height() - tpRght.y))
mousePos.setY((double)viewer->height() - tpRght.y);
}
TPointD cameraMousePos(winToCamera(viewer, mousePos));
if (bitwiseExclude(m_dragType, OUTER)) {
@ -313,8 +363,6 @@ TPoint PreviewSubCameraManager::getSubCameraDragDistance(
return TPoint(resultD.x, resultD.y);
}
TCamera *camera =
TApp::instance()->getCurrentScene()->getScene()->getCurrentCamera();
TRect subCamera = camera->getInterestRect();
TRectD subCameraD(subCamera.x0, subCamera.y0, subCamera.x1 + 1,
subCamera.y1 + 1);

View file

@ -110,7 +110,7 @@ private:
TPointD cameraToWin(SceneViewer *viewer, const TPointD &cameraPos) const;
UCHAR getSubCameraDragEnum(SceneViewer *viewer, const QPointF &mousePos);
TPoint getSubCameraDragDistance(SceneViewer *viewer, const QPointF &mousePos);
TPoint getSubCameraDragDistance(SceneViewer *viewer, QPointF &mousePos);
};
#endif // SUBCAMERAMANAGER_INCLUDED

View file

@ -44,6 +44,8 @@
#include "xsheetdragtool.h"
#include "ruler.h"
#include "menubarcommandids.h"
#include "tenv.h"
#include "cellselection.h"
// Qt includes
#include <QPainter>
@ -66,6 +68,7 @@
using namespace DVGui;
extern TEnv::IntVar EnvViewerPreviewBehavior;
//=============================================================================
//
// BaseViewerPanel
@ -140,7 +143,7 @@ BaseViewerPanel::BaseViewerPanel(QWidget *parent, Qt::WindowFlags flags)
this, SLOT(onButtonPressed(FlipConsole::EGadget)));
ret = ret && connect(m_sceneViewer, SIGNAL(previewStatusChanged()), this,
SLOT(update()));
SLOT(onPreviewStatusChanged()));
ret = ret && connect(m_sceneViewer, SIGNAL(onFlipHChanged(bool)), this,
SLOT(setFlipHButtonChecked(bool)));
ret = ret && connect(m_sceneViewer, SIGNAL(onFlipVChanged(bool)), this,
@ -149,6 +152,9 @@ BaseViewerPanel::BaseViewerPanel(QWidget *parent, Qt::WindowFlags flags)
ret = ret && connect(app->getCurrentScene(), SIGNAL(sceneSwitched()), this,
SLOT(onSceneSwitched()));
ret = ret && connect(app, SIGNAL(activeViewerChanged()), this,
SLOT(onActiveViewerChanged()));
assert(ret);
UINT mask = 0;
@ -269,7 +275,7 @@ void BaseViewerPanel::onDrawFrame(int frame,
}
// assert(frame >= 0); // frame can be negative in rare cases
if (frame != frameHandle->getFrameIndex() + 1) {
if (frame != frameHandle->getFrameIndex() + 1 && !settings.m_drawBlankFrame) {
int oldFrame = frameHandle->getFrame();
frameHandle->setCurrentFrame(frame);
if (!frameHandle->isPlaying() && !frameHandle->isEditingLevel() &&
@ -462,30 +468,51 @@ void BaseViewerPanel::initializeTitleBar(TPanelTitleBar *titleBar) {
SLOT(freeze(bool)));
// preview toggles
m_previewButton = new TPanelTitleBarButton(
m_previewButton = new TPanelTitleBarButtonForPreview(
titleBar, getIconThemePath("actions/20/pane_preview.svg"));
x += 10 + iconWidth;
titleBar->add(QPoint(x, 0), m_previewButton);
m_previewButton->setToolTip(tr("Preview"));
ret = ret && connect(m_previewButton, SIGNAL(toggled(bool)),
SLOT(enableFullPreview(bool)));
m_subcameraPreviewButton = new TPanelTitleBarButton(
// ret = ret && connect(m_previewButton, SIGNAL(toggled(bool)),
// SLOT(enableFullPreview(bool)));
m_subcameraPreviewButton = new TPanelTitleBarButtonForPreview(
titleBar, getIconThemePath("actions/20/pane_subpreview.svg"));
x += 1 + 24; // width of pane_preview.svg = 24px
titleBar->add(QPoint(x, 0), m_subcameraPreviewButton);
m_subcameraPreviewButton->setToolTip(tr("Sub-camera Preview"));
ret = ret && connect(m_subcameraPreviewButton, SIGNAL(toggled(bool)),
SLOT(enableSubCameraPreview(bool)));
// ret = ret && connect(m_subcameraPreviewButton, SIGNAL(toggled(bool)),
// SLOT(enableSubCameraPreview(bool)));
assert(ret);
}
//-----------------------------------------------------------------------------
void BaseViewerPanel::getPreviewButtonStates(bool &prev, bool &subCamPrev) {
prev = m_previewButton->isChecked();
subCamPrev = m_subcameraPreviewButton->isChecked();
}
//-----------------------------------------------------------------------------
void BaseViewerPanel::enableFullPreview(bool enabled) {
m_subcameraPreviewButton->setPressed(false);
if (CommandManager::instance()
->getAction(MI_ToggleViewerSubCameraPreview)
->isChecked())
CommandManager::instance()
->getAction(MI_ToggleViewerSubCameraPreview)
->setChecked(false);
if (!enabled && EnvViewerPreviewBehavior == 2 &&
FlipConsole::getCurrent() == m_flipConsole &&
TApp::instance()->getCurrentFrame()->isPlaying())
CommandManager::instance()->execute(MI_Pause);
m_sceneViewer->enablePreview(enabled ? SceneViewer::FULL_PREVIEW
: SceneViewer::NO_PREVIEW);
m_flipConsole->setProgressBarStatus(
@ -497,6 +524,18 @@ void BaseViewerPanel::enableFullPreview(bool enabled) {
void BaseViewerPanel::enableSubCameraPreview(bool enabled) {
m_previewButton->setPressed(false);
if (CommandManager::instance()
->getAction(MI_ToggleViewerPreview)
->isChecked())
CommandManager::instance()
->getAction(MI_ToggleViewerPreview)
->setChecked(false);
if (!enabled && EnvViewerPreviewBehavior == 2 &&
FlipConsole::getCurrent() == m_flipConsole &&
TApp::instance()->getCurrentFrame()->isPlaying())
CommandManager::instance()->execute(MI_Pause);
m_sceneViewer->enablePreview(enabled ? SceneViewer::SUBCAMERA_PREVIEW
: SceneViewer::NO_PREVIEW);
m_flipConsole->setProgressBarStatus(
@ -542,6 +581,26 @@ void BaseViewerPanel::onPlayingStatusChanged(bool playing) {
m_playing = false;
m_first = true;
}
// if preview behavior mode is "selected cells", release preview mode when
// stopped
if (!playing && EnvViewerPreviewBehavior == 2 &&
FlipConsole::getCurrent() == m_flipConsole &&
!Previewer::instance(m_sceneViewer->getPreviewMode() ==
SceneViewer::SUBCAMERA_PREVIEW)
->isBusy()) {
if (CommandManager::instance()
->getAction(MI_ToggleViewerPreview)
->isChecked())
CommandManager::instance()->getAction(MI_ToggleViewerPreview)->trigger();
else if (CommandManager::instance()
->getAction(MI_ToggleViewerSubCameraPreview)
->isChecked())
CommandManager::instance()
->getAction(MI_ToggleViewerSubCameraPreview)
->trigger();
}
if (Preferences::instance()->getOnionSkinDuringPlayback()) return;
OnionSkinMask osm =
TApp::instance()->getCurrentOnionSkin()->getOnionSkinMask();
@ -870,6 +929,90 @@ void BaseViewerPanel::load(QSettings &settings) {
settings.value("consoleParts", mask).toUInt());
}
//-----------------------------------------------------------------------------
void BaseViewerPanel::onPreviewStatusChanged() {
// if preview behavior mode is "selected cells", play once the all frames are
// completed
if (EnvViewerPreviewBehavior == 2 &&
FlipConsole::getCurrent() == m_flipConsole &&
!TApp::instance()->getCurrentFrame()->isPlaying() &&
m_sceneViewer->isPreviewEnabled() &&
!Previewer::instance(m_sceneViewer->getPreviewMode() ==
SceneViewer::SUBCAMERA_PREVIEW)
->isBusy()) {
TCellSelection *cellSel =
dynamic_cast<TCellSelection *>(TSelection::getCurrent());
if (cellSel && !cellSel->isEmpty()) {
int r0, c0, r1, c1;
cellSel->getSelectedCells(r0, c0, r1, c1);
if (r0 < r1) {
// check if all frame range is rendered. this check is needed since
// isBusy() will not be true just after the preview is triggered
for (int r = r0; r <= r1; r++) {
if (!Previewer::instance(m_sceneViewer->getPreviewMode() ==
SceneViewer::SUBCAMERA_PREVIEW)
->isFrameReady(r)) {
update();
return;
}
}
m_flipConsole->setStopAt(r1 + 1);
m_flipConsole->setStartAt(r0 + 1);
TApp::instance()->getCurrentFrame()->setFrame(r0);
CommandManager::instance()->execute(MI_Loop);
}
}
}
update();
}
//-----------------------------------------------------------------------------
// sync preview commands and buttons states when the viewer becomes active
void BaseViewerPanel::onActiveViewerChanged() {
bool ret = true;
if (TApp::instance()->getActiveViewer() == m_sceneViewer) {
ret = ret &&
connect(m_previewButton, SIGNAL(toggled(bool)),
CommandManager::instance()->getAction(MI_ToggleViewerPreview),
SLOT(trigger()));
ret = ret &&
connect(CommandManager::instance()->getAction(MI_ToggleViewerPreview),
SIGNAL(triggered(bool)), m_previewButton,
SLOT(setPressed(bool)));
ret = ret && connect(m_subcameraPreviewButton, SIGNAL(toggled(bool)),
CommandManager::instance()->getAction(
MI_ToggleViewerSubCameraPreview),
SLOT(trigger()));
ret = ret && connect(CommandManager::instance()->getAction(
MI_ToggleViewerSubCameraPreview),
SIGNAL(triggered(bool)), m_subcameraPreviewButton,
SLOT(setPressed(bool)));
m_isActive = true;
} else if (m_isActive) {
ret = ret && disconnect(m_previewButton, SIGNAL(toggled(bool)),
CommandManager::instance()->getAction(
MI_ToggleViewerPreview),
SLOT(trigger()));
ret = ret &&
disconnect(
CommandManager::instance()->getAction(MI_ToggleViewerPreview),
SIGNAL(triggered(bool)), m_previewButton, SLOT(setPressed(bool)));
ret = ret && disconnect(m_subcameraPreviewButton, SIGNAL(toggled(bool)),
CommandManager::instance()->getAction(
MI_ToggleViewerSubCameraPreview),
SLOT(trigger()));
ret = ret && disconnect(CommandManager::instance()->getAction(
MI_ToggleViewerSubCameraPreview),
SIGNAL(triggered(bool)), m_subcameraPreviewButton,
SLOT(setPressed(bool)));
m_isActive = false;
}
assert(ret);
}
//=============================================================================
//
// SceneViewerPanel
@ -913,3 +1056,44 @@ void SceneViewerPanel::checkOldVersionVisblePartsFlags(QSettings &settings) {
settings.remove("visibleParts");
settings.setValue("viewerVisibleParts", m_visiblePartsFlag);
}
//=========================================================
class ViewerPreviewCommands : public QObject {
public:
ViewerPreviewCommands() {
setCommandHandler("MI_ToggleViewerPreview", this,
&ViewerPreviewCommands::onPreview);
setCommandHandler("MI_ToggleViewerSubCameraPreview", this,
&ViewerPreviewCommands::onSubCameraPreview);
}
void onPreview();
void onSubCameraPreview();
};
void ViewerPreviewCommands::onPreview() {
SceneViewer *activeViewer = TApp::instance()->getActiveViewer();
if (!activeViewer) return;
BaseViewerPanel *bvp = qobject_cast<BaseViewerPanel *>(
activeViewer->parentWidget()->parentWidget());
if (!bvp) return;
bool on = CommandManager::instance()
->getAction(MI_ToggleViewerPreview)
->isChecked();
bvp->enableFullPreview(on);
}
void ViewerPreviewCommands::onSubCameraPreview() {
SceneViewer *activeViewer = TApp::instance()->getActiveViewer();
if (!activeViewer) return;
BaseViewerPanel *bvp = qobject_cast<BaseViewerPanel *>(
activeViewer->parentWidget()->parentWidget());
if (!bvp) return;
bool on = CommandManager::instance()
->getAction(MI_ToggleViewerSubCameraPreview)
->isChecked();
bvp->enableSubCameraPreview(on);
}
ViewerPreviewCommands viewerPreviewCommands;

View file

@ -51,8 +51,8 @@ protected:
FlipConsole *m_flipConsole;
ViewerKeyframeNavigator *m_keyFrameButton;
TPanelTitleBarButtonSet *m_referenceModeBs;
TPanelTitleBarButton *m_previewButton;
TPanelTitleBarButton *m_subcameraPreviewButton;
TPanelTitleBarButtonForPreview *m_previewButton;
TPanelTitleBarButtonForPreview *m_subcameraPreviewButton;
bool m_onionSkinActive = false;
UINT m_visiblePartsFlag;
bool m_playSound = true;
@ -64,6 +64,8 @@ protected:
bool m_first = true;
TSoundTrack *m_sound = NULL;
bool m_isActive = false;
public:
BaseViewerPanel(QWidget *parent = 0, Qt::WindowFlags flags = 0);
~BaseViewerPanel() {}
@ -91,6 +93,8 @@ public:
void initializeTitleBar(TPanelTitleBar *titleBar);
void getPreviewButtonStates(bool &prev, bool &subCamPrev);
protected:
// void contextMenuEvent(QContextMenuEvent *event) override;
void showEvent(QShowEvent *) override;
@ -111,6 +115,8 @@ public slots:
void onButtonPressed(FlipConsole::EGadget button);
void setFlipHButtonChecked(bool checked);
void setFlipVButtonChecked(bool checked);
void enableFullPreview(bool enabled);
void enableSubCameraPreview(bool enabled);
void changeSceneFps(int value);
protected slots:
@ -121,8 +127,8 @@ protected slots:
void onPlayingStatusChanged(bool playing);
// for showing/hiding the parts
void onShowHideActionTriggered(QAction *);
void enableFullPreview(bool enabled);
void enableSubCameraPreview(bool enabled);
void onPreviewStatusChanged();
void onActiveViewerChanged();
};
class SceneViewerPanel final : public BaseViewerPanel {

View file

@ -11,9 +11,7 @@
TCamera::TCamera()
//: m_size(12, 9), m_res(768, 576), m_xPrevalence(true)
//: m_size(36, 20.25),
: m_size(16, 9),
m_res(1920, 1080),
m_xPrevalence(true) {}
: m_size(16, 9), m_res(1920, 1080), m_xPrevalence(true) {}
//-------------------------------------------------------------------
@ -110,15 +108,18 @@ TRectD TCamera::getStageRect() const {
//-------------------------------------------------------------------
void TCamera::setInterestRect(const TRect &rect) {
// Not using the TRect's common intersection. Unfortunately, in case
// the rect's coordinates have lx or ly < 0, the intersection returns
// the default (empty) rect. We want to maintain the coordinates instead.
// m_interestRect = rect * TRect(m_res);
m_interestRect.x0 = std::max(rect.x0, 0);
m_interestRect.y0 = std::max(rect.y0, 0);
m_interestRect.x1 = std::min(rect.x1, m_res.lx - 1);
m_interestRect.y1 = std::min(rect.y1, m_res.ly - 1);
// enable to preview outside of the original camera rect
m_interestRect = rect;
return;
//// Not using the TRect's common intersection. Unfortunately, in case
//// the rect's coordinates have lx or ly < 0, the intersection returns
//// the default (empty) rect. We want to maintain the coordinates instead.
//// m_interestRect = rect * TRect(m_res);
//
// m_interestRect.x0 = std::max(rect.x0, 0);
// m_interestRect.y0 = std::max(rect.y0, 0);
// m_interestRect.x1 = std::min(rect.x1, m_res.lx - 1);
// m_interestRect.y1 = std::min(rect.y1, m_res.ly - 1);
}
//-------------------------------------------------------------------

View file

@ -821,9 +821,11 @@ void FlipConsole::onNextFrame(int fps, QElapsedTimer *timer,
else
m_fpsField->setLineEditBackgroundColor(Qt::red);
}
if (m_stopAt > 0 && m_currentFrame >= m_stopAt) {
if (m_stopAt > 0 && m_currentFrame >= m_stopAt &&
(m_isPlay || m_startAt == -1)) {
doButtonPressed(ePause);
m_stopAt = -1;
m_startAt = -1;
}
}
@ -849,6 +851,10 @@ void FlipConsole::playNextFrame(QElapsedTimer *timer, qint64 targetInstant) {
int from = m_from, to = m_to;
if (m_markerFrom <= m_markerTo && m_stopAt == -1)
from = m_markerFrom, to = m_markerTo;
else if (m_stopAt > 0 && m_startAt > 0) {
from = m_startAt;
to = m_stopAt;
}
if (m_framesCount == 0 ||
(m_isPlay && m_currentFrame == (m_reverse ? from : to))) {
@ -1577,6 +1583,7 @@ void FlipConsole::onButtonPressed(int button) {
playingConsole->setChecked(ePause, true);
stoppedOther = true;
m_stopAt = -1;
m_startAt = -1;
}
}
if (stoppedOther) {
@ -1733,6 +1740,7 @@ void FlipConsole::doButtonPressed(UINT button) {
}
}
m_stopAt = -1;
m_startAt = -1;
return;
}
@ -1740,6 +1748,7 @@ void FlipConsole::doButtonPressed(UINT button) {
if (m_playbackExecutor.isRunning()) m_playbackExecutor.abort();
m_stopAt = -1;
m_startAt = -1;
m_isPlay = false;
m_blanksToDraw = 0;
@ -1885,6 +1894,10 @@ void FlipConsole::setStopAt(int frame) { m_stopAt = frame; }
//--------------------------------------------------------------------
void FlipConsole::setStartAt(int frame) { m_startAt = frame; }
//--------------------------------------------------------------------
QFrame *FlipConsole::createFrameSlider() {
QFrame *frameSliderFrame = new QFrame(this);