#include "lib/film.h"
#include "lib/image_content.h"
#include "lib/playlist.h"
-#include "lib/scope_guard.h"
#include "lib/text_content.h"
#include "lib/timer.h"
#include "lib/video_content.h"
+#include <dcp/scope_guard.h>
#include <dcp/warnings.h>
LIBDCP_DISABLE_WARNINGS
#include <wx/graphics.h>
_main_canvas->Bind (wxEVT_RIGHT_DOWN, boost::bind (&Timeline::right_down, this, _1));
_main_canvas->Bind (wxEVT_MOTION, boost::bind (&Timeline::mouse_moved, this, _1));
_main_canvas->Bind (wxEVT_SIZE, boost::bind (&Timeline::resized, this));
+ _main_canvas->Bind (wxEVT_MOUSEWHEEL, boost::bind(&Timeline::mouse_wheel_turned, this, _1));
_main_canvas->Bind (wxEVT_SCROLLWIN_TOP, boost::bind (&Timeline::scrolled, this, _1));
_main_canvas->Bind (wxEVT_SCROLLWIN_BOTTOM, boost::bind (&Timeline::scrolled, this, _1));
_main_canvas->Bind (wxEVT_SCROLLWIN_LINEUP, boost::bind (&Timeline::scrolled, this, _1));
_main_canvas->Bind (wxEVT_SCROLLWIN_PAGEDOWN, boost::bind (&Timeline::scrolled, this, _1));
_main_canvas->Bind (wxEVT_SCROLLWIN_THUMBTRACK, boost::bind (&Timeline::scrolled, this, _1));
- film_change (ChangeType::DONE, Film::Property::CONTENT);
+ film_change(ChangeType::DONE, FilmProperty::CONTENT);
SetMinSize (wxSize (640, 4 * pixels_per_track() + 96));
}
+void
+Timeline::mouse_wheel_turned(wxMouseEvent& event)
+{
+ auto const rotation = event.GetWheelRotation();
+
+ if (event.ControlDown()) {
+ /* On my mouse one click of the scroll wheel is 120, and it's -ve when
+ * scrolling the wheel towards me.
+ */
+ auto const scale = rotation > 0 ?
+ (1.0 / (rotation / 90.0)) :
+ (-rotation / 90.0);
+
+ int before_start_x;
+ int before_start_y;
+ _main_canvas->GetViewStart(&before_start_x, &before_start_y);
+
+ auto const before_pps = _pixels_per_second.get_value_or(1);
+ auto const before_pos = _last_mouse_wheel_x && *_last_mouse_wheel_x == event.GetX() ?
+ *_last_mouse_wheel_time :
+ (before_start_x * _x_scroll_rate + event.GetX()) / before_pps;
+
+ set_pixels_per_second(before_pps * scale);
+ setup_scrollbars();
+
+ auto after_left = std::max(0.0, before_pos * _pixels_per_second.get_value_or(1) - event.GetX());
+ _main_canvas->Scroll(after_left / _x_scroll_rate, before_start_y);
+ _labels_canvas->Scroll(0, before_start_y);
+ Refresh();
+
+ if (!_last_mouse_wheel_x || *_last_mouse_wheel_x != event.GetX()) {
+ _last_mouse_wheel_x = event.GetX();
+ _last_mouse_wheel_time = before_pos;
+ }
+ } else if (event.ShiftDown()) {
+ int before_start_x;
+ int before_start_y;
+ _main_canvas->GetViewStart(&before_start_x, &before_start_y);
+ auto const width = _main_canvas->GetSize().GetWidth();
+ _main_canvas->Scroll(std::max(0.0, before_start_x - rotation * 100.0 / width), before_start_y);
+ }
+}
+
+
void
Timeline::update_playhead ()
{
return;
}
- ScopeGuard sg = [gc]() { delete gc; };
+ dcp::ScopeGuard sg = [gc]() { delete gc; };
int vsx, vsy;
_labels_canvas->GetViewStart (&vsx, &vsy);
Timeline::paint_main ()
{
wxPaintDC dc (_main_canvas);
+ dc.Clear();
auto film = _film.lock();
if (film->content().empty()) {
return;
}
- ScopeGuard sg = [gc]() { delete gc; };
+ dcp::ScopeGuard sg = [gc]() { delete gc; };
gc->SetAntialiasMode (wxANTIALIAS_DEFAULT);
void
-Timeline::film_change (ChangeType type, Film::Property p)
+Timeline::film_change(ChangeType type, FilmProperty p)
{
if (type != ChangeType::DONE) {
return;
}
- if (p == Film::Property::CONTENT || p == Film::Property::REEL_TYPE || p == Film::Property::REEL_LENGTH) {
+ if (p == FilmProperty::CONTENT || p == FilmProperty::REEL_TYPE || p == FilmProperty::REEL_LENGTH) {
ensure_ui_thread ();
recreate_views ();
- } else if (p == Film::Property::CONTENT_ORDER) {
+ } else if (p == FilmProperty::CONTENT_ORDER) {
Refresh ();
}
}
_views.push_back (make_shared<TimelineVideoContentView>(*this, i));
}
- if (i->audio && !i->audio->mapping().mapped_output_channels().empty ()) {
+ if (i->has_mapped_audio()) {
_views.push_back (make_shared<TimelineAudioContentView>(*this, i));
}
}
auto cv = dynamic_pointer_cast<TimelineContentView> (i);
+ DCPOMATIC_ASSERT(cv);
int t = base;