37 #include <QMouseEvent>
57 BaseWidget(parent,
"PlaybackWidget",
"Playback")
60 this->setToolTip(
"Replay current session");
63 mTimer->initialize(QDateTime::currentDateTime(), 100000);
64 connect(mTimer.get(), SIGNAL(changed()), SLOT(timeChangedSlot()));
66 QVBoxLayout* topLayout =
new QVBoxLayout(
this);
68 mStartTimeLabel =
new QLabel;
69 topLayout->addWidget(mStartTimeLabel);
70 mTotalLengthLabel =
new QLabel;
71 topLayout->addWidget(mTotalLengthLabel);
73 topLayout->addWidget(mLabel);
76 connect(mToolTimelineWidget, SIGNAL(positionChanged()),
this, SLOT(timeLineWidgetValueChangedSlot()));
77 topLayout->addWidget(mToolTimelineWidget);
80 QHBoxLayout* playButtonsLayout =
new QHBoxLayout;
81 topLayout->addLayout(playButtonsLayout);
84 QIcon(
":/icons/open_icon_library/button-red.png"),
86 SLOT(toggleOpenSlot()),
89 QIcon(
":/icons/open_icon_library/media-seek-backward-3.png"),
94 QIcon(
":/icons/open_icon_library/media-playback-start-3.png"),
99 QIcon(
":/icons/open_icon_library/media-seek-forward-3.png"),
104 QIcon(
":/icons/open_icon_library/media-playback-stop-3.png"),
109 QIcon(
":/icons/open_icon_library/system-run-5.png"),
110 "Details",
"Details",
111 SLOT(toggleDetailsSlot()),
117 "Set speed of playback, 0 is normal speed.", 0,
DoubleRange(-5,5,1),0);
118 connect(mSpeedAdapter.get(), SIGNAL(changed()),
this, SLOT(speedChangedSlot()));
121 playButtonsLayout->addStretch();
123 topLayout->addStretch();
131 void PlaybackWidget::toggleDetailsSlot()
137 void PlaybackWidget::showDetails()
139 bool on =
settings()->
value(
"playback/ShowDetails").toBool();
141 mStartTimeLabel->setVisible(on);
142 mTotalLengthLabel->setVisible(on);
145 void PlaybackWidget::timeLineWidgetValueChangedSlot()
147 mTimer->setTime(QDateTime::fromMSecsSinceEpoch(mToolTimelineWidget->
getPos()));
150 void PlaybackWidget::toggleOpenSlot()
163 reportError(
"trackingService is not in playback mode");
167 report(QString(
"Started Playback with start time [%1] and end time [%2]")
171 this->toolManagerInitializedSlot();
175 QColor PlaybackWidget::generateRandomToolColor()
const
177 std::vector<QColor> colors;
180 colors.push_back(QColor::fromHsv(110, s, v));
181 colors.push_back(QColor::fromHsv(80, s, v));
182 colors.push_back(QColor::fromHsv(140, s, v));
183 colors.push_back(QColor::fromHsv(95, s, v));
184 colors.push_back(QColor::fromHsv(125, s, v));
186 static int gCounter = 0;
187 return colors[(gCounter++)%colors.size()];
190 std::vector<TimelineEvent> PlaybackWidget::convertHistoryToEvents(
ToolPtr tool)
192 std::vector<TimelineEvent> retval;
194 if (!history || history->empty())
196 double timeout = 200;
197 TimelineEvent currentEvent(tool->getName() +
" visible", history->begin()->first);
198 currentEvent.mGroup =
"tool";
199 currentEvent.mColor = this->generateRandomToolColor();
202 for(TimedTransformMap::iterator iter=history->begin(); iter!=history->end(); ++iter)
204 double current = iter->first;
206 if (current - currentEvent.mEndTime > timeout)
208 retval.push_back(currentEvent);
209 currentEvent.mStartTime = currentEvent.mEndTime = current;
213 currentEvent.mEndTime = current;
216 if (!
similar(currentEvent.mEndTime - currentEvent.mStartTime, 0))
217 retval.push_back(currentEvent);
224 std::vector<TimelineEvent> events;
226 std::vector<RegistrationTransform> tr = reg->getData();
227 for (
unsigned i=0; i<tr.size(); ++i)
229 if (!tr[i].mTimestamp.isValid())
232 QString text = QString(
"Registraton %1, fixed=%2").arg(tr[i].mType).arg(tr[i].mFixed);
233 if (!tr[i].mMoving.isEmpty())
234 text = QString(
"%1, moving=%2").arg(text).arg(tr[i].mMoving);
236 events.push_back(TimelineEvent(text,
237 tr[i].mTimestamp.toMSecsSinceEpoch()));
245 std::vector<TimelineEvent> PlaybackWidget::createEvents()
247 typedef std::vector<TimelineEvent> TimelineEventVector;
250 TimelineEventVector events;
252 for (TrackingService::ToolMap::iterator iter=tools.begin(); iter!=tools.end(); ++iter)
256 TimelineEventVector current = convertHistoryToEvents(iter->second);
257 copy(current.begin(), current.end(), std::back_inserter(events));
262 for (std::map<QString, DataPtr>::iterator iter=data.begin(); iter!=data.end(); ++iter)
264 QString desc(
"loaded " + iter->second->getName());
265 if (iter->second->getAcquisitionTime().isValid())
267 double acqTime = iter->second->getAcquisitionTime().toMSecsSinceEpoch();
268 events.push_back(TimelineEvent(desc, acqTime));
272 TimelineEventVector current = this->convertRegistrationHistoryToEvents(reg);
273 copy(current.begin(), current.end(), std::back_inserter(events));
277 TimelineEventVector current = this->convertRegistrationHistoryToEvents(reg);
278 copy(current.begin(), current.end(), std::back_inserter(events));
281 copy(current.begin(), current.end(), std::back_inserter(events));
290 std::pair<double,double> PlaybackWidget::findTimeRange(std::vector<TimelineEvent> events)
294 double now = QDateTime::currentDateTime().toMSecsSinceEpoch();
295 return std::make_pair(now, now+1000);
301 for (
unsigned i=0; i<events.size(); ++i)
303 timeRange.first = std::min(timeRange.first, events[i].mStartTime);
304 timeRange.second = std::max(timeRange.second, events[i].mEndTime);
319 void PlaybackWidget::toolManagerInitializedSlot()
323 mOpenAction->setText(
"Close Playback");
324 mOpenAction->setIcon(QIcon(
":/icons/open_icon_library/button-green.png"));
328 mOpenAction->setText(
"Open Playback");
329 mOpenAction->setIcon(QIcon(
":/icons/open_icon_library/button-red.png"));
330 mToolTimelineWidget->
setEvents(std::vector<TimelineEvent>());
337 std::vector<TimelineEvent> events = this->createEvents();
338 std::pair<double,double> range = this->findTimeRange(events);
341 mTimer->initialize(QDateTime::fromMSecsSinceEpoch(range.first), range.second - range.first);
344 mToolTimelineWidget->
setRange(range.first, range.second);
347 QString startDate = mTimer->getStartTime().toString(
"yyyy-MM-dd");
348 QString startTime = mTimer->getStartTime().toString(
"hh:mm");
349 QString endTime = mTimer->getStartTime().addMSecs(mTimer->getLength()).toString(
"hh:mm");
351 QString
length = this->convertMillisecsToNiceString(mTimer->getLength());
352 mStartTimeLabel->setText(
353 QString(
"Date:").leftJustified(15) +
"" + startDate+
"\n" +
354 QString(
"Time:").leftJustified(15) +
"" + startTime +
" - " + endTime +
"\n" +
355 QString(
"Duration:").leftJustified(15)+
"" + length);
357 this->timeChangedSlot();
377 QString PlaybackWidget::convertMillisecsToNiceString(qint64 length)
const
381 qint64 ms = length % 1000;
382 qint64 s = (length / 1000) % 60;
383 qint64 m = (length / (1000*60)) % 60;
384 qint64 h = (length / (1000*60*60));
387 retval = QString(
"%1:%2.%3").arg(m,2,10,c).arg(s,2,10,c).arg(ms,3,10,c);
389 retval = QString(
"%1:%2").arg(h).arg(retval);
394 void PlaybackWidget::speedChangedSlot()
396 double speed = mSpeedAdapter->getValue();
397 speed = pow(2,speed);
398 mTimer->setSpeed(speed);
402 void PlaybackWidget::timeChangedSlot()
404 QString color(
"green");
406 qint64 offset = mTimer->getOffset();
407 QString format = QString(
"<font size=%1 color=%2><b>%3</b></font>").arg(fontSize).arg(color);
409 QString currentTime = mTimer->getTime().toString(
"hh:mm:ss");
411 QString currentOffset = this->convertMillisecsToNiceString(offset);
413 mLabel->setText(format.arg(
"Elapsed: "+currentOffset+
" \tTime: " + currentTime));
415 if (mTimer->isPlaying())
417 mPlayAction->setIcon(QIcon(
":/icons/open_icon_library/media-playback-pause-3.png"));
418 mPlayAction->setText(
"Pause");
422 mPlayAction->setIcon(QIcon(
":/icons/open_icon_library/media-playback-start-3.png"));
423 mPlayAction->setText(
"Play");
435 mToolTimelineWidget->blockSignals(
true);
436 mToolTimelineWidget->
setPos(mTimer->getTime().toMSecsSinceEpoch());
437 mToolTimelineWidget->blockSignals(
false);
440 void PlaybackWidget::playSlot()
442 if (mTimer->isPlaying())
455 void PlaybackWidget::stopSlot()
459 void PlaybackWidget::forwardSlot()
461 mTimer->forward(1000*mTimer->getSpeed());
463 void PlaybackWidget::rewindSlot()
465 mTimer->rewind(1000*mTimer->getSpeed());
void reportError(QString msg)
boost::shared_ptr< class RegistrationHistory > RegistrationHistoryPtr
Utility class for describing a bounded numeric range.
double getMilliSecondsSinceEpoch()
QVariant value(const QString &key, const QVariant &defaultValue=QVariant()) const
bool similar(const DoubleBoundingBox3D &a, const DoubleBoundingBox3D &b, double tol)
boost::shared_ptr< class PlaybackTime > PlaybackTimePtr
void setValue(const QString &key, const QVariant &value)
boost::shared_ptr< TimedTransformMap > TimedTransformMapPtr
Settings * settings()
Shortcut for accessing the settings instance.
std::map< QString, ToolPtr > ToolMap
cxLogicManager_EXPORT VideoServicePtr videoService()
cxLogicManager_EXPORT PatientModelServicePtr patientService()
static DoublePropertyPtr initialize(const QString &uid, QString name, QString help, double value, DoubleRange range, int decimals, QDomNode root=QDomNode())
RealScalar length() const
cxLogicManager_EXPORT TrackingServicePtr trackingService()
Controller for historic time, playback etc.
QString timestampMilliSecondsFormatNice()
boost::shared_ptr< class Tool > ToolPtr