X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=src%2Fwx%2Ffilm_viewer.cc;h=5262338332e7073884b37bbc398c9d007eb057ca;hb=c0e04acd1e9875fa67800a7861bd8a370157b49f;hp=8c298ea57d3087915204efaa2b5f826ff5c0a150;hpb=ed70b4faf0f53b106aebd4b9195ccc81da97880e;p=dcpomatic.git diff --git a/src/wx/film_viewer.cc b/src/wx/film_viewer.cc index 8c298ea57..526233833 100644 --- a/src/wx/film_viewer.cc +++ b/src/wx/film_viewer.cc @@ -26,10 +26,10 @@ #include "lib/film.h" #include "lib/format.h" #include "lib/util.h" -#include "lib/thumbs_job.h" #include "lib/job_manager.h" #include "lib/film_state.h" #include "lib/options.h" +#include "lib/subtitle.h" #include "film_viewer.h" #include "wx_util.h" @@ -42,41 +42,42 @@ public: ThumbPanel (wxPanel* parent, Film* film) : wxPanel (parent) , _film (film) - { - } + , _frame_rebuild_needed (false) + , _composition_needed (false) + {} /** Handle a paint event */ void paint_event (wxPaintEvent& ev) { - if (_current_index != _pending_index) { - _image.reset (new wxImage (std_to_wx (_film->thumb_file (_pending_index)))); - _current_index = _pending_index; + if (!_film || _film->thumbs().size() == 0) { + wxPaintDC dc (this); + return; + } - _subtitles.clear (); + if (_frame_rebuild_needed) { + _image.reset (new wxImage (std_to_wx (_film->thumb_file (_index)))); - cout << "=== SUBS for " << _film->thumb_frame (_pending_index) << "\n"; - list > s = _film->thumb_subtitles (_pending_index); - for (list >::iterator i = s.begin(); i != s.end(); ++i) { - _subtitles.push_back (SubtitleView (i->first, std_to_wx (i->second))); + _subtitle.reset (); + pair s = _film->thumb_subtitle (_index); + if (!s.second.empty ()) { + _subtitle.reset (new SubtitleView (s.first, std_to_wx (s.second))); } - setup (); + _frame_rebuild_needed = false; + compose (); } - if (_current_crop != _pending_crop) { - _current_crop = _pending_crop; - setup (); + if (_composition_needed) { + compose (); } wxPaintDC dc (this); if (_bitmap) { - cout << "frame bm " << _bitmap->GetWidth() << " " << _bitmap->GetHeight() << "\n"; dc.DrawBitmap (*_bitmap, 0, 0, false); } - for (list::iterator i = _subtitles.begin(); i != _subtitles.end(); ++i) { - dc.DrawBitmap (*i->bitmap, i->position.x, i->position.y, true); - cout << "\tsub bm at " << i->position.x << " " << i->position.y << " size " << i->bitmap->GetWidth() << " by " << i->bitmap->GetHeight() << "\n"; + if (_film->with_subtitles() && _subtitle) { + dc.DrawBitmap (*_subtitle->bitmap, _subtitle->transformed_area.x, _subtitle->transformed_area.y, true); } } @@ -87,20 +88,14 @@ public: return; } - setup (); - Refresh (); + recompose (); } /** @param n Thumbnail index */ void set (int n) { - _pending_index = n; - Refresh (); - } - - void set_crop (Crop c) - { - _pending_crop = c; + _index = n; + _frame_rebuild_needed = true; Refresh (); } @@ -109,9 +104,10 @@ public: _film = f; if (!_film) { clear (); + _frame_rebuild_needed = true; Refresh (); } else { - setup (); + _frame_rebuild_needed = true; Refresh (); } } @@ -121,12 +117,12 @@ public: { _bitmap.reset (); _image.reset (); - _subtitles.clear (); + _subtitle.reset (); } - void refresh () + void recompose () { - setup (); + _composition_needed = true; Refresh (); } @@ -134,8 +130,10 @@ public: private: - void setup () + void compose () { + _composition_needed = false; + if (!_film || !_image) { return; } @@ -144,90 +142,80 @@ private: int vw, vh; GetSize (&vw, &vh); + Crop const fc = _film->crop (); + /* Cropped rectangle */ - Rectangle cropped ( - _current_crop.left, - _current_crop.top, - _image->GetWidth() - (_current_crop.left + _current_crop.right), - _image->GetHeight() - (_current_crop.top + _current_crop.bottom) + Rect cropped_area ( + fc.left, + fc.top, + _image->GetWidth() - (fc.left + fc.right), + _image->GetHeight() - (fc.top + fc.bottom) ); /* Target ratio */ float const target = _film->format() ? _film->format()->ratio_as_float (_film) : 1.78; - _cropped_image = _image->GetSubImage (wxRect (cropped.x, cropped.y, cropped.w, cropped.h)); + _transformed_image = _image->GetSubImage (wxRect (cropped_area.x, cropped_area.y, cropped_area.width, cropped_area.height)); float x_scale = 1; float y_scale = 1; if ((float (vw) / vh) > target) { /* view is longer (horizontally) than the ratio; fit height */ - _cropped_image.Rescale (vh * target, vh, wxIMAGE_QUALITY_HIGH); - x_scale = vh * target / _image->GetWidth (); - y_scale = float (vh) / _image->GetHeight (); + _transformed_image.Rescale (vh * target, vh, wxIMAGE_QUALITY_HIGH); + x_scale = vh * target / cropped_area.width; + y_scale = float (vh) / cropped_area.height; } else { /* view is shorter (horizontally) than the ratio; fit width */ - _cropped_image.Rescale (vw, vw / target, wxIMAGE_QUALITY_HIGH); - x_scale = float (vw) / _image->GetWidth (); - y_scale = (vw / target) / _image->GetHeight (); + _transformed_image.Rescale (vw, vw / target, wxIMAGE_QUALITY_HIGH); + x_scale = float (vw) / cropped_area.width; + y_scale = (vw / target) / cropped_area.height; } - _bitmap.reset (new wxBitmap (_cropped_image)); + _bitmap.reset (new wxBitmap (_transformed_image)); - for (list::iterator i = _subtitles.begin(); i != _subtitles.end(); ++i) { - Rectangle sub_rect (i->position.x, i->position.y, i->image.GetWidth(), i->image.GetHeight()); - Rectangle cropped_sub_rect = sub_rect.intersection (cropped); - - cout << "sub " << sub_rect.x << " " << sub_rect.y << " " << sub_rect.w << " " << sub_rect.h << "\n"; - cout << "cropped " << cropped_sub_rect.x << " " << cropped_sub_rect.y << " " << cropped_sub_rect.w << " " << cropped_sub_rect.h << "\n"; - - i->cropped_image = i->image.GetSubImage ( - wxRect ( - cropped_sub_rect.x - sub_rect.x, - cropped_sub_rect.y - sub_rect.y, - cropped_sub_rect.w, - cropped_sub_rect.h - ) - ); - - i->cropped_image.Rescale (cropped_sub_rect.w * x_scale, cropped_sub_rect.h * y_scale, wxIMAGE_QUALITY_HIGH); + if (_subtitle) { - i->position = Position ( - cropped_sub_rect.x * x_scale, - cropped_sub_rect.y * y_scale + _subtitle->transformed_area = subtitle_transformed_area ( + x_scale, y_scale, _subtitle->base_area, _film->subtitle_offset(), _film->subtitle_scale() ); - cout << "scales are " << x_scale << " " << y_scale << "\n"; - cout << "scaled to " << (cropped_sub_rect.w * x_scale) << " " << (cropped_sub_rect.h * y_scale) << "\n"; - - i->bitmap.reset (new wxBitmap (i->cropped_image)); + _subtitle->transformed_image = _subtitle->base_image; + _subtitle->transformed_image.Rescale (_subtitle->transformed_area.width, _subtitle->transformed_area.height, wxIMAGE_QUALITY_HIGH); + _subtitle->transformed_area.x -= rint (_film->crop().left * x_scale); + _subtitle->transformed_area.y -= rint (_film->crop().top * y_scale); + _subtitle->bitmap.reset (new wxBitmap (_subtitle->transformed_image)); } } Film* _film; shared_ptr _image; - wxImage _cropped_image; + wxImage _transformed_image; /** currently-displayed thumbnail index */ - int _current_index; - int _pending_index; + int _index; shared_ptr _bitmap; - Crop _current_crop; - Crop _pending_crop; + bool _frame_rebuild_needed; + bool _composition_needed; struct SubtitleView { SubtitleView (Position p, wxString const & i) - : position (p) - , image (i) - {} - - Position position; - wxImage image; - wxImage cropped_image; + : base_image (i) + { + base_area.x = p.x; + base_area.y = p.y; + base_area.width = base_image.GetWidth (); + base_area.height = base_image.GetHeight (); + } + + Rect base_area; + Rect transformed_area; + wxImage base_image; + wxImage transformed_image; shared_ptr bitmap; }; - list _subtitles; + shared_ptr _subtitle; }; BEGIN_EVENT_TABLE (ThumbPanel, wxPanel) @@ -245,8 +233,8 @@ FilmViewer::FilmViewer (Film* f, wxWindow* p) _thumb_panel = new ThumbPanel (this, f); _sizer->Add (_thumb_panel, 1, wxEXPAND); - int const max = f ? f->num_thumbs() - 1 : 0; - _slider = new wxSlider (this, wxID_ANY, 0, 0, max); + int const m = max ((size_t) 1, f ? f->thumbs().size() - 1 : 0); + _slider = new wxSlider (this, wxID_ANY, 0, 0, m); _sizer->Add (_slider, 0, wxEXPAND | wxLEFT | wxRIGHT); set_thumbnail (0); @@ -258,7 +246,7 @@ FilmViewer::FilmViewer (Film* f, wxWindow* p) void FilmViewer::set_thumbnail (int n) { - if (_film == 0 || _film->num_thumbs() <= n) { + if (_film == 0 || int (_film->thumbs().size()) <= n) { return; } @@ -272,13 +260,14 @@ FilmViewer::slider_changed (wxCommandEvent &) } void -FilmViewer::film_changed (Film::Property p) +FilmViewer::film_changed (FilmState::Property p) { - if (p == Film::CROP) { - _thumb_panel->set_crop (_film->crop ()); - } else if (p == Film::THUMBS) { - if (_film && _film->num_thumbs() > 1) { - _slider->SetRange (0, _film->num_thumbs () - 1); + ensure_ui_thread (); + + switch (p) { + case FilmState::THUMBS: + if (_film && _film->thumbs().size() > 1) { + _slider->SetRange (0, _film->thumbs().size() - 1); } else { _thumb_panel->clear (); _slider->SetRange (0, 1); @@ -286,12 +275,19 @@ FilmViewer::film_changed (Film::Property p) _slider->SetValue (0); set_thumbnail (0); - } else if (p == Film::FORMAT) { - _thumb_panel->refresh (); - } else if (p == Film::CONTENT) { + break; + case FilmState::CONTENT: setup_visibility (); - _film->examine_content (); - update_thumbs (); + break; + case FilmState::CROP: + case FilmState::FORMAT: + case FilmState::WITH_SUBTITLES: + case FilmState::SUBTITLE_OFFSET: + case FilmState::SUBTITLE_SCALE: + _thumb_panel->recompose (); + break; + default: + break; } } @@ -312,31 +308,9 @@ FilmViewer::set_film (Film* f) _film->Changed.connect (sigc::mem_fun (*this, &FilmViewer::film_changed)); film_changed (Film::CROP); film_changed (Film::THUMBS); - _thumb_panel->refresh (); setup_visibility (); } -void -FilmViewer::update_thumbs () -{ - if (!_film) { - return; - } - - _film->update_thumbs_pre_gui (); - - shared_ptr s = _film->state_copy (); - shared_ptr o (new Options (s->dir ("thumbs"), ".tiff", "")); - o->out_size = _film->size (); - o->apply_crop = false; - o->decode_audio = false; - o->decode_video_frequency = 128; - - shared_ptr j (new ThumbsJob (s, o, _film->log(), shared_ptr ())); - j->Finished.connect (sigc::mem_fun (_film, &Film::update_thumbs_post_gui)); - JobManager::instance()->add (j); -} - void FilmViewer::setup_visibility () {