Blob Blame History Raw


#include "linetestpane.h"
#ifdef LINETEST
#include "xsheetdragtool.h"
#include "toutputproperties.h"
#include "tapp.h"
#include "toutputproperties.h"
#include "toonz/tcolumnhandle.h"
#include "toonz/txshlevelhandle.h"
#include "toonz/toonzscene.h"
#include "toonz/sceneproperties.h"

#include <QThread>
#include <QStackedWidget>

using namespace DVGui;

//=============================================================================
// MixAudioThread
//-----------------------------------------------------------------------------

MixAudioThread::MixAudioThread(QObject *parent)
	: QThread(parent), m_abort(false), m_restart(false)
{
}

//-----------------------------------------------------------------------------

MixAudioThread::~MixAudioThread()
{
	m_mutex.lock();
	m_abort = true;
	m_condition.wakeOne();
	m_mutex.unlock();
	wait();
}

//-----------------------------------------------------------------------------

void MixAudioThread::run()
{
	forever
	{
		m_mutex.lock();
		int from = this->m_from;
		int to = this->m_to;
		m_mutex.unlock();

		if (m_abort)
			return;

		TXsheet::SoundProperties *prop = new TXsheet::SoundProperties();
		prop->m_fromFrame = from;
		prop->m_toFrame = to;
		m_computedBuffer = TApp::instance()->getCurrentXsheet()->getXsheet()->makeSound(prop);
		m_buffer = TSoundTrackP();
		if (m_computedBuffer)
			m_buffer = m_computedBuffer->clone();

		if (!m_restart && m_buffer)
			emit computedBuffer();

		m_mutex.lock();
		if (!m_restart)
			m_condition.wait(&m_mutex);
		m_restart = false;
		m_mutex.unlock();
	}
}

//-----------------------------------------------------------------------------

void MixAudioThread::computeBuffer(int fromFrame, int toFrame)
{
	QMutexLocker locker(&m_mutex);

	this->m_from = fromFrame;
	this->m_to = toFrame;

	if (!isRunning()) {
		start(QThread::NormalPriority);
	} else {
		m_restart = true;
		m_condition.wakeOne();
	}
}

//=============================================================================
// LineTestPane
//-----------------------------------------------------------------------------

LineTestPane::LineTestPane(QWidget *parent, Qt::WFlags flags)
	: TPanel(parent), m_flipConsole(0), m_keyFrameButton(0), m_mainTrack(0), m_startTrack(0), m_player(0), m_trackStartFrame(0), m_startPlayRange(-1), m_endPlayRange(0), m_bufferSize(0), m_nextBufferSize(0)
{
	bool ret = true;
	QFrame *hbox = new QFrame(this);
	hbox->setFrameStyle(QFrame::StyledPanel);
	hbox->setObjectName("OnePixelMarginFrame");

	QVBoxLayout *mainLayout = new QVBoxLayout(hbox);
	mainLayout->setMargin(0);
	mainLayout->setSpacing(0);

	//Viewer
	m_stackedWidget = new QStackedWidget(this);
	m_sceneViewer = new SceneViewer(this);
	m_stackedWidget->addWidget(m_sceneViewer);
	m_lineTestViewer = new LineTestViewer(this);
	m_stackedWidget->addWidget(m_lineTestViewer);

	mainLayout->addWidget(m_stackedWidget, Qt::AlignCenter);

	TApp *app = TApp::instance();
	m_keyFrameButton = new ViewerKeyframeNavigator(0, app->getCurrentFrame());
	m_keyFrameButton->setObjectHandle(app->getCurrentObject());
	m_keyFrameButton->setXsheetHandle(app->getCurrentXsheet());

	int buttons = FlipConsole::cFullConsole;

	buttons &= (~FlipConsole::eSound);
	buttons &= (~FlipConsole::eCheckBg);
	buttons &= (~FlipConsole::eWhiteBg);
	buttons &= (~FlipConsole::eBlackBg);
	buttons &= (~FlipConsole::eSave);
	buttons &= (~FlipConsole::eCompare);
	buttons &= (~FlipConsole::eSaveImg);
	buttons &= (~FlipConsole::eHisto);
	buttons &= (~FlipConsole::eCustomize);
	buttons &= (~FlipConsole::eMatte);
	buttons &= (~FlipConsole::eGRed);
	buttons &= (~FlipConsole::eGGreen);
	buttons &= (~FlipConsole::eGBlue);
	buttons &= (~FlipConsole::eRed);
	buttons &= (~FlipConsole::eGreen);
	buttons &= (~FlipConsole::eBlue);
	buttons &= (~FlipConsole::eDefineSubCamera);
	buttons &= (~FlipConsole::eDefineLoadBox);
	buttons &= (~FlipConsole::eUseLoadBox);

	m_flipConsole = new FlipConsole(mainLayout, buttons, false, m_keyFrameButton, "SceneViewerConsole");

	ret = ret && connect(m_sceneViewer, SIGNAL(onZoomChanged()), SLOT(changeWindowTitle()));
	ret = ret && connect(m_lineTestViewer, SIGNAL(onZoomChanged()), SLOT(changeWindowTitle()));

	ret = connect(m_flipConsole, SIGNAL(drawFrame(int, const ImagePainter::VisualSettings &)), this, SLOT(onDrawFrame(int, const ImagePainter::VisualSettings &)));
	ret = ret && connect(m_flipConsole, SIGNAL(playStateChanged(bool)), this, SLOT(onPlayStateChanged(bool)));
	ret = ret && connect(m_flipConsole, SIGNAL(buttonPressed(FlipConsole::EGadget)), m_lineTestViewer, SLOT(onButtonPressed(FlipConsole::EGadget)));
	ret = ret && connect(m_flipConsole, SIGNAL(buttonPressed(FlipConsole::EGadget)), m_sceneViewer, SLOT(onButtonPressed(FlipConsole::EGadget)));
	ret = ret && connect(m_flipConsole, SIGNAL(sliderReleased()), this, SLOT(onFlipSliderReleased()));

	m_flipConsole->setFrameRate(app->getCurrentScene()->getScene()->getProperties()->getOutputProperties()->getFrameRate());

	hbox->setLayout(mainLayout);

	setWidget(hbox);

	initializeTitleBar(getTitleBar());

	ret = ret && connect(&m_mixAudioThread, SIGNAL(computedBuffer()), this, SLOT(onComputedBuffer()), Qt::DirectConnection);

	ret = ret && connect(app->getCurrentScene(), SIGNAL(sceneSwitched()), this, SLOT(onSceneSwitched()));

	assert(ret);
	setCurrentViewType(0);
}

//-----------------------------------------------------------------------------

LineTestPane::~LineTestPane()
{
}

//-----------------------------------------------------------------------------

void LineTestPane::showEvent(QShowEvent *)
{
	TApp *app = TApp::instance();
	TFrameHandle *frameHandle = app->getCurrentFrame();
	TSceneHandle *sceneHandle = app->getCurrentScene();
	TXshLevelHandle *levelHandle = app->getCurrentLevel();
	TObjectHandle *objectHandle = app->getCurrentObject();
	TXsheetHandle *xshHandle = app->getCurrentXsheet();

	updateFrameRange();

	bool ret = true;

	ret = ret && connect(xshHandle, SIGNAL(xsheetChanged()), this, SLOT(onSceneChanged()));

	ret = ret && connect(sceneHandle, SIGNAL(sceneChanged()), this, SLOT(onSceneChanged()));
	ret = ret && connect(sceneHandle, SIGNAL(nameSceneChanged()), this, SLOT(changeWindowTitle()));

	ret = ret && connect(levelHandle, SIGNAL(xshLevelSwitched(TXshLevel *)), this, SLOT(onXshLevelSwitched(TXshLevel *)));
	ret = ret && connect(levelHandle, SIGNAL(xshLevelChanged()), this, SLOT(changeWindowTitle()));
	ret = ret && connect(levelHandle, SIGNAL(xshLevelTitleChanged()), this, SLOT(changeWindowTitle()));
	ret = ret && connect(levelHandle, SIGNAL(xshLevelChanged()), this, SLOT(updateFrameRange()));

	ret = ret && connect(frameHandle, SIGNAL(frameSwitched()), this, SLOT(changeWindowTitle()));
	ret = ret && connect(frameHandle, SIGNAL(frameSwitched()), this, SLOT(onFrameSwitched()));
	ret = ret && connect(frameHandle, SIGNAL(frameTypeChanged()), this, SLOT(onFrameTypeChanged()));

	assert(ret);

	//Aggiorno FPS al valore definito nel viewer corrente.
	m_flipConsole->setActive(true);
}

//-----------------------------------------------------------------------------

void LineTestPane::hideEvent(QHideEvent *)
{
	TApp *app = TApp::instance();
	TFrameHandle *frameHandle = app->getCurrentFrame();
	TSceneHandle *sceneHandle = app->getCurrentScene();
	TXshLevelHandle *levelHandle = app->getCurrentLevel();
	TObjectHandle *objectHandle = app->getCurrentObject();
	TXsheetHandle *xshHandle = app->getCurrentXsheet();

	disconnect(xshHandle, SIGNAL(xsheetChanged()), this, SLOT(onSceneChanged()));

	disconnect(sceneHandle, SIGNAL(sceneChanged()), this, SLOT(onSceneChanged()));
	disconnect(sceneHandle, SIGNAL(nameSceneChanged()), this, SLOT(changeWindowTitle()));

	disconnect(levelHandle, SIGNAL(xshLevelSwitched(TXshLevel *)), this, SLOT(onXshLevelSwitched(TXshLevel *)));
	disconnect(levelHandle, SIGNAL(xshLevelChanged()), this, SLOT(changeWindowTitle()));
	disconnect(levelHandle, SIGNAL(xshLevelTitleChanged()), this, SLOT(changeWindowTitle()));
	disconnect(levelHandle, SIGNAL(xshLevelChanged()), this, SLOT(updateFrameRange()));

	disconnect(frameHandle, SIGNAL(frameSwitched()), this, SLOT(changeWindowTitle()));
	disconnect(frameHandle, SIGNAL(frameSwitched()), this, SLOT(onFrameSwitched()));
	disconnect(frameHandle, SIGNAL(frameTypeChanged()), this, SLOT(onFrameTypeChanged()));

	m_flipConsole->setActive(false);
}

//-----------------------------------------------------------------------------

int LineTestPane::computeBufferSize(int frame)
{
	int bufferSize = 0;
	double time = 2.0;
	ToonzScene *scene = TApp::instance()->getCurrentScene()->getScene();
	TOutputProperties *outputSettings = scene->getProperties()->getOutputProperties();
	int frameRate = outputSettings->getFrameRate();
	if (m_endPlayRange > m_startPlayRange) {
		int range = m_endPlayRange - m_startPlayRange;
		time = double(range) / double(frameRate);
		int minuts = tround(time / 60.0);
		if (minuts == 0)
			minuts = 1;
		while (time > 2.0 * minuts)
			time = time * 0.5;
	}
	bufferSize = tfloor(frameRate * time) + 1;
	//qDebug("BUFFER SIZE: %d", bufferSize);

	if (frame + bufferSize > m_endPlayRange) {
		bufferSize = m_endPlayRange - frame + 1;
		//qDebug("\n BUFFER SIZE: %d \n", bufferSize);
	}

	return bufferSize;
}

//-----------------------------------------------------------------------------

void LineTestPane::computeBuffer(int frame)
{
	int startFrame = m_trackStartFrame + m_bufferSize;
	if (startFrame >= m_endPlayRange) {
		//qDebug("\n OPS \n");
		return;
	}
	//qDebug("COMPUTE BUFFER SIZE AT FRAME: %d", startFrame);
	m_nextBufferSize = computeBufferSize(startFrame);
	//qDebug("start frame: %d, start next buffer size: %d", startFrame, m_nextBufferSize);
	m_mixAudioThread.computeBuffer(startFrame, startFrame + m_nextBufferSize);
}

//-----------------------------------------------------------------------------

void LineTestPane::initSound()
{
	m_mainTrack = 0;
	m_startTrack = 0;
	TXsheet *xsh = TApp::instance()->getCurrentXsheet()->getXsheet();
	TFrameHandle *frameHandle = TApp::instance()->getCurrentFrame();
	m_trackStartFrame = frameHandle->getFrame();

	m_startPlayRange = 0;
	m_endPlayRange = frameHandle->getMaxFrameIndex();
	int fromMarker, toMarker, step;
	if (XsheetGUI::getPlayRange(fromMarker, toMarker, step)) {
		m_startPlayRange = fromMarker;
		m_endPlayRange = toMarker;
	}

	m_bufferSize = computeBufferSize(m_trackStartFrame);
	//qDebug("initSound()");
	//qDebug("m_startPlayRange: %d", m_startPlayRange);
	//qDebug("m_endPlayRange: %d", m_endPlayRange);
	//qDebug("start frame: %d, start bufferSize: %d", m_trackStartFrame, m_bufferSize);

	if (xsh) {
		if (!m_player)
			m_player = new TSoundOutputDevice();
		// Compute the first seconds and then launch the thread to compute the next buffer
		TXsheet::SoundProperties *prop = new TXsheet::SoundProperties();
		prop->m_fromFrame = m_trackStartFrame;
		prop->m_toFrame = m_trackStartFrame + m_bufferSize;
		m_mainTrack = xsh->makeSound(prop);
		if (m_trackStartFrame == m_startPlayRange) {
			//qDebug("set start track");
			m_startTrack = m_mainTrack;
			m_startBufferSize = m_bufferSize;
		} else //compute start track (it's necessary to avoid async in loop)
		{
			m_startBufferSize = computeBufferSize(m_startPlayRange);
			TXsheet::SoundProperties *prop = new TXsheet::SoundProperties();
			prop->m_fromFrame = m_startPlayRange;
			prop->m_toFrame = m_startPlayRange + m_startBufferSize;
			m_startTrack = xsh->makeSound(prop);
		}
		computeBuffer(m_trackStartFrame);
	} else {
		m_mainTrack = 0;
		m_startTrack = 0;
	}
}

//-----------------------------------------------------------------------------

void LineTestPane::playSound()
{
	if (m_player && m_mainTrack) {
		try {
			int currentFrame = TApp::instance()->getCurrentFrame()->getFrame();
			double t0 = (double)(currentFrame - m_trackStartFrame) / (double)(m_mainTrack->getSampleRate());
			// Pay attention at don't call play everytime (there is a big leak otherwise !)
			double trackDuration = m_mainTrack->getDuration();
			//qDebug("trackDuration: %f", trackDuration);
			if (m_mainTrack && trackDuration != 0)
				if (trackDuration > t0)
					m_player->play(m_mainTrack, t0, trackDuration);
		} catch (TSoundDeviceException &e) {
		}
	}
}

//-----------------------------------------------------------------------------

void LineTestPane::initializeTitleBar(TPanelTitleBar *titleBar)
{
	bool ret = true;

	TPanelTitleBarButtonSet *viewModeButtonSet;
	viewModeButtonSet = new TPanelTitleBarButtonSet();
	int x = -100;
	int iconWidth = 17;
	TPanelTitleBarButton *button;

	m_cameraStandButton = new TPanelTitleBarButton(titleBar, ":Resources/standard.png",
												   ":Resources/standard_over.png", ":Resources/standard_on.png");
	m_cameraStandButton->setToolTip("Camera Stand View");
	x += 18 + iconWidth;
	titleBar->add(QPoint(x, 2), m_cameraStandButton);
	m_cameraStandButton->setButtonSet(viewModeButtonSet, 0);
	m_cameraStandButton->setPressed(true);

	m_previewButton = new TPanelTitleBarButton(titleBar, ":Resources/viewpreview.png",
											   ":Resources/viewpreview_over.png", ":Resources/viewpreview_on.png");
	m_previewButton->setToolTip(tr("Preview"));
	x += 5 + iconWidth;
	titleBar->add(QPoint(x, 2), m_previewButton);
	m_previewButton->setButtonSet(viewModeButtonSet, 1);

	ret = ret && connect(viewModeButtonSet, SIGNAL(selected(int)), this, SLOT(setCurrentViewType(int)));
	assert(ret);
}

//-----------------------------------------------------------------------------

void LineTestPane::onXshLevelSwitched(TXshLevel *)
{
	changeWindowTitle();
}

//-----------------------------------------------------------------------------

void LineTestPane::changeWindowTitle()
{
	TApp *app = TApp::instance();
	ToonzScene *scene = app->getCurrentScene()->getScene();
	if (!scene)
		return;
	int frame = app->getCurrentFrame()->getFrame();
	QString name;
	if (app->getCurrentFrame()->isEditingScene()) {
		QString sceneName = QString::fromStdWString(scene->getSceneName());
		if (sceneName.isEmpty())
			sceneName = tr("Untitled");
		if (app->getCurrentScene()->getDirtyFlag())
			sceneName += QString("*");
		name = tr("Scene: ") + sceneName;
		if (frame >= 0)
			name = name + tr("   ::   Frame: ") + tr(toString(frame + 1).c_str());
		int col = app->getCurrentColumn()->getColumnIndex();
		if (col < 0) {
			setWindowTitle(name);
			return;
		}
		TXsheet *xsh = app->getCurrentXsheet()->getXsheet();
		TXshCell cell = xsh->getCell(frame, col);
		if (cell.isEmpty()) {
			setWindowTitle(name);
			return;
		}
		assert(cell.m_level.getPointer());
		TFilePath fp(cell.m_level->getName());
		QString imageName = QString::fromStdWString(fp.withFrame(cell.m_frameId).getWideString());
		name = name + tr("   ::   Level: ") + imageName;
	} else {
		TXshLevel *level = app->getCurrentLevel()->getLevel();
		if (level) {
			TFilePath fp(level->getName());
			QString imageName = QString::fromStdWString(fp.withFrame(app->getCurrentFrame()->getFid()).getWideString());
			name = name + tr("Level: ") + imageName;
		}
	}
	if (m_stackedWidget->currentIndex() == 0) {
		TAffine aff = m_sceneViewer->getViewMatrix() * m_sceneViewer->getNormalZoomScale().inv();
		name = name + "  ::  Zoom : " + QString::number(tround(100.0 * sqrt(aff.det()))) + "%";
	} else {
		TAffine aff = m_lineTestViewer->getViewMatrix() * m_lineTestViewer->getNormalZoomScale().inv();
		name = name + "  ::  Zoom : " + QString::number(tround(100.0 * sqrt(aff.det()))) + "%";
	}

	setWindowTitle(name);
}

//-----------------------------------------------------------------------------

void LineTestPane::updateFrameRange()
{
	TApp *app = TApp::instance();
	TFrameHandle *fh = app->getCurrentFrame();
	int frameIndex = fh->getFrameIndex();
	int maxFrameIndex = fh->getMaxFrameIndex();
	m_flipConsole->setFrameRange(1, maxFrameIndex + 1, 1, frameIndex + 1);
}

//-----------------------------------------------------------------------------

void LineTestPane::updateFrameMarkers()
{
	int fromIndex, toIndex, dummy;
	XsheetGUI::getPlayRange(fromIndex, toIndex, dummy);
	TFrameHandle *fh = TApp::instance()->getCurrentFrame();
	if (fh->isEditingLevel()) {
		fromIndex = 0;
		toIndex = -1;
	}
	m_flipConsole->setMarkers(fromIndex, toIndex);
}

//-----------------------------------------------------------------------------

void LineTestPane::setCurrentViewType(int index)
{
	TFrameHandle *frameHandle = TApp::instance()->getCurrentFrame();
	if (index == 1 && frameHandle->getFrameType() == TFrameHandle::LevelFrame)
		frameHandle->setFrame(frameHandle->getFrameIndex());
	m_stackedWidget->setCurrentIndex(index);
	if (index == 0) {
		CommandManager::instance()->enable("MI_ViewTable", true);
		CommandManager::instance()->enable("MI_FieldGuide", true);
		CommandManager::instance()->enable("MI_SafeArea", true);
		CommandManager::instance()->enable("MI_RasterizePli", true);
		CommandManager::instance()->enable("MI_ViewColorcard", true);
		CommandManager::instance()->enable("MI_ViewCamera", true);
		m_flipConsole->enableButton(FlipConsole::eFilledRaster, false, false);
	} else {
		CommandManager::instance()->enable("MI_ViewTable", false);
		CommandManager::instance()->enable("MI_FieldGuide", false);
		CommandManager::instance()->enable("MI_SafeArea", false);
		CommandManager::instance()->enable("MI_RasterizePli", false);
		CommandManager::instance()->enable("MI_ViewColorcard", false);
		CommandManager::instance()->enable("MI_ViewCamera", false);
		if (m_flipConsole)
			m_flipConsole->enableButton(FlipConsole::eFilledRaster, true, false);
	}
	changeWindowTitle();
}

//-----------------------------------------------------------------------------

void LineTestPane::onDrawFrame(int frame, const ImagePainter::VisualSettings &settings)
{
	TApp *app = TApp::instance();
	TFrameHandle *frameHandle = app->getCurrentFrame();

	assert(frame >= 0);
	if (frame != frameHandle->getFrameIndex() + 1) {
		int oldFrame = frameHandle->getFrame();
		frameHandle->setCurrentFrame(frame);
		if (!m_mainTrack && !frameHandle->isPlaying() && !frameHandle->isEditingLevel() && oldFrame != frameHandle->getFrame())
			frameHandle->scrubXsheet(frame - 1, frame - 1, TApp::instance()->getCurrentXsheet()->getXsheet());

		//qDebug("frame: %d",frame);
		if (m_mainTrack && frameHandle->isPlaying() && !frameHandle->isEditingLevel()) {
			if (frame == m_startPlayRange + 1) {
				if (m_startTrack) {
					m_mainTrack = m_startTrack;
					m_trackStartFrame = frame;
					//qDebug("1. play at m_trackStartFrame: %d", m_trackStartFrame);
					playSound();

					m_bufferSize = m_startBufferSize;
					computeBuffer(frame);
				} else {
					//qDebug("2. play at m_trackStartFrame: %d", m_trackStartFrame);
					assert(0);
					initSound();
				}
			}
			int frameElapsed = frame - m_trackStartFrame - 1;
			if (frameElapsed >= (m_bufferSize)) {
				if (m_buffer)
					m_mainTrack = m_buffer->clone();

				m_trackStartFrame = frame;
				//qDebug("PLAY SOUND AT FRAME: %d", frame);
				playSound();

				//qDebug("3. play at m_trackStartFrame: %d", m_trackStartFrame);
				m_bufferSize = m_nextBufferSize;
				computeBuffer(frame);
			}
		}
	}
}

//-----------------------------------------------------------------------------

void LineTestPane::onComputedBuffer()
{
	m_buffer = TSoundTrackP();
	m_buffer = m_mixAudioThread.getBuffer();
}

//-----------------------------------------------------------------------------

void LineTestPane::onPlayStateChanged(bool value)
{
	TFrameHandle *frameHandle = TApp::instance()->getCurrentFrame();
	bool wasPlaying = frameHandle->isPlaying();
	frameHandle->setPlaying(value);
	if (value && !frameHandle->isEditingLevel()) {
		if (m_player && wasPlaying) {
			m_player->close();
			if (m_mainTrack)
				m_mainTrack = TSoundTrackP();
			if (m_startTrack)
				m_startTrack = TSoundTrackP();
			if (m_buffer)
				m_buffer = TSoundTrackP();
		}
		initSound();
		playSound();
	} else if (m_player) {
		m_player->close();
		if (m_mainTrack)
			m_mainTrack = TSoundTrackP();
		if (m_startTrack)
			m_startTrack = TSoundTrackP();
		if (m_buffer)
			m_buffer = TSoundTrackP();
	}
}

//-----------------------------------------------------------------------------

void LineTestPane::onSceneChanged()
{
	TApp *app = TApp::instance();
	ToonzScene *scene = app->getCurrentScene()->getScene();
	assert(scene);
	m_flipConsole->updateCurrentFPS(scene->getProperties()->getOutputProperties()->getFrameRate());

	updateFrameRange();
	updateFrameMarkers();
	changeWindowTitle();

	int frameIndex = app->getCurrentFrame()->getFrameIndex();
	if (m_keyFrameButton->getCurrentFrame() != frameIndex)
		m_keyFrameButton->setCurrentFrame(frameIndex);
}

//-----------------------------------------------------------------------------

void LineTestPane::onSceneSwitched()
{
	if (!isHidden())
		onSceneChanged();
	m_flipConsole->setFrameRate(TApp::instance()->getCurrentScene()->getScene()->getProperties()->getOutputProperties()->getFrameRate());
}

//-----------------------------------------------------------------------------

void LineTestPane::onFrameSwitched()
{
	int frameIndex = TApp::instance()->getCurrentFrame()->getFrameIndex();
	m_flipConsole->setCurrentFrame(frameIndex + 1);
	if (m_keyFrameButton->getCurrentFrame() != frameIndex)
		m_keyFrameButton->setCurrentFrame(frameIndex);
}

//-----------------------------------------------------------------------------

void LineTestPane::onFrameTypeChanged()
{
	if (TApp::instance()->getCurrentFrame()->getFrameType() == TFrameHandle::LevelFrame) {
		if (m_stackedWidget->currentIndex() != 0) {
			m_cameraStandButton->setPressed(true);
			m_previewButton->setPressed(false);
			setCurrentViewType(0);
		}
	}

	updateFrameRange();
	updateFrameMarkers();
}

//-----------------------------------------------------------------------------

void LineTestPane::onFlipSliderReleased()
{
	TApp::instance()->getCurrentXsheet()->getXsheet()->stopScrub();
}

#endif