+ dc.DrawRectangle (_inter_position.x, _inter_position.y + (panel_size.GetHeight() - out_size.height) / 2, _inter_size.width, _inter_size.height);
+ }
+ _state_timer.unset();
+}
+
+void
+SimpleVideoView::update ()
+{
+ _state_timer.set ("update-view");
+ _panel->Refresh ();
+ _panel->Update ();
+ _state_timer.unset ();
+}
+
+void
+SimpleVideoView::timer ()
+{
+ if (!_viewer->playing()) {
+ return;
+ }
+
+ display_next_frame (false);
+ DCPTime const next = _viewer->position() + _viewer->one_video_frame();
+
+ if (next >= length()) {
+ _viewer->stop ();
+ _viewer->Finished ();
+ return;
+ }
+
+ LOG_DEBUG_PLAYER("%1 -> %2; delay %3", next.seconds(), _viewer->time().seconds(), max((next.seconds() - _viewer->time().seconds()) * 1000, 1.0));
+ _timer.Start (time_until_next_frame(), wxTIMER_ONE_SHOT);
+
+ if (_viewer->butler()) {
+ _viewer->butler()->rethrow ();
+ }
+}
+
+void
+SimpleVideoView::start ()
+{
+ VideoView::start ();
+ timer ();
+}
+
+/** Try to get a frame from the butler and display it.
+ * @param non_blocking true to return false quickly if no video is available quickly (i.e. we are waiting for the butler).
+ * false to ask the butler to block until it has video (unless it is suspended).
+ * @return true on success, false if we did nothing because it would have taken too long.
+ */
+bool
+SimpleVideoView::display_next_frame (bool non_blocking)
+{
+ bool r = get_next_frame (non_blocking);
+ if (!r) {
+ if (non_blocking) {
+ /* No video available; return saying we failed */
+ return false;
+ } else {
+ /* Player was suspended; come back later */
+ signal_manager->when_idle (boost::bind(&SimpleVideoView::display_next_frame, this, false));
+ return false;
+ }
+ }
+
+ display_player_video ();
+
+ try {
+ _viewer->butler()->rethrow ();
+ } catch (DecodeError& e) {
+ error_dialog (get(), e.what());