Add zoom-all button.
authorCarl Hetherington <cth@carlh.net>
Tue, 3 Jul 2018 23:51:31 +0000 (00:51 +0100)
committerCarl Hetherington <cth@carlh.net>
Tue, 3 Jul 2018 23:51:31 +0000 (00:51 +0100)
15 files changed:
graphics/src/zoom_all.svg [new file with mode: 0644]
graphics/update
graphics/web/favicon-128x128.png
graphics/web/favicon-16x16.png
graphics/web/favicon-32x32.png
graphics/web/favicon-64x64.png
graphics/wscript
graphics/zoom_all.png [new file with mode: 0644]
src/wx/timeline.cc
src/wx/timeline.h
src/wx/timeline_content_view.cc
src/wx/timeline_dialog.cc
src/wx/timeline_dialog.h
src/wx/timeline_labels_view.cc
src/wx/timeline_time_axis_view.cc

diff --git a/graphics/src/zoom_all.svg b/graphics/src/zoom_all.svg
new file mode 100644 (file)
index 0000000..a1b253a
--- /dev/null
@@ -0,0 +1,81 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="35mm"
+   height="35mm"
+   viewBox="0 0 35.000001 35"
+   version="1.1"
+   id="svg8"
+   inkscape:version="0.92.3 (2405546, 2018-03-11)"
+   sodipodi:docname="zoom_all.svg">
+  <defs
+     id="defs2" />
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="2.8284272"
+     inkscape:cx="51.216883"
+     inkscape:cy="46.646647"
+     inkscape:document-units="mm"
+     inkscape:current-layer="layer1"
+     showgrid="false"
+     fit-margin-top="0"
+     fit-margin-left="0"
+     fit-margin-right="0"
+     fit-margin-bottom="0"
+     inkscape:window-width="1680"
+     inkscape:window-height="995"
+     inkscape:window-x="0"
+     inkscape:window-y="27"
+     inkscape:window-maximized="1" />
+  <metadata
+     id="metadata5">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     id="layer1"
+     transform="translate(-6.3144683,15.262769)">
+    <path
+       style="opacity:1;vector-effect:none;fill:#f2f2f2;fill-opacity:1;stroke:#000000;stroke-width:1.10000002;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-end:none"
+       d="M 21.219999,2.4159489 37.174851,18.351868 c 0.739437,0.413423 1.494454,0.785898 2.673133,0.04548 0.773585,-1.191683 0.420947,-1.927565 0,-2.635791 L 23.821002,-0.29718512 c -6.5e-5,-0.06848 -1.360739,1.61587802 -2.601003,2.71313402 z"
+       id="path5828-3"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="cccccc" />
+    <ellipse
+       style="opacity:1;vector-effect:none;fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:2.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-end:none"
+       id="path5809"
+       cx="20.144106"
+       cy="-1.0881108"
+       rx="12.398235"
+       ry="12.398153" />
+    <rect
+       style="opacity:1;vector-effect:none;fill:#cccccc;fill-opacity:1;stroke:#666666;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-end:none"
+       id="rect5806"
+       width="17.96051"
+       height="10.196332"
+       x="11.163851"
+       y="-6.1862769" />
+  </g>
+</svg>
index 9c14f2157f62bb3f31965ef3c2efc2c263efb956..50923fc69b2ef31a23d0a7ae7264f9c1272a6e20 100755 (executable)
@@ -66,8 +66,9 @@ else
     $INKSCAPE splash.png src/splash.svg -w 400 -h 300
 
     # Timeline toolbar icons (all platforms)
-    $INKSCAPE select.png src/select.svg -w 24 -h 24
-    $INKSCAPE zoom.png src/zoom.svg -w 24 -h 24
+    for i in select zoom zoom_all; do
+        $INKSCAPE $i.png src/$i.svg -w 24 -h 24
+    done
 
     # favicon
     mkdir -p web
index bc58be5941951f8110c57238c136fee765a36547..415c7f7647f16f8fcaacc0ca421e6f54a91b5b22 100644 (file)
Binary files a/graphics/web/favicon-128x128.png and b/graphics/web/favicon-128x128.png differ
index 44dbdb713554682703c2a1d2e93db095bd15655c..0075ed7f60545f37b90fb32db9064b7647c4b02e 100644 (file)
Binary files a/graphics/web/favicon-16x16.png and b/graphics/web/favicon-16x16.png differ
index c65be6ff81688fc394fb804a7af8fde187f52b4e..11214f1ac957da38d7c66b3849e0020763018e2a 100644 (file)
Binary files a/graphics/web/favicon-32x32.png and b/graphics/web/favicon-32x32.png differ
index 7537c82203f2074d58ca8e26e889e076112dd9d3..8d968b9f7a509a60679e84e4ddc1ac8933ea9f22 100644 (file)
Binary files a/graphics/web/favicon-64x64.png and b/graphics/web/favicon-64x64.png differ
index 1be119783bfa092a26d5b9a289d995c721b87af1..7f88cd0692a81c7f0109f6a84092926e0b9fa30b 100644 (file)
@@ -31,4 +31,5 @@ def build(bld):
         bld.install_as('${PREFIX}/share/dcpomatic2/dcpomatic2_server_small.png', 'linux/16/dcpomatic2.png')
         bld.install_files('${PREFIX}/share/dcpomatic2', 'splash.png')
         bld.install_files('${PREFIX}/share/dcpomatic2', 'zoom.png')
+        bld.install_files('${PREFIX}/share/dcpomatic2', 'zoom_all.png')
         bld.install_files('${PREFIX}/share/dcpomatic2', 'select.png')
diff --git a/graphics/zoom_all.png b/graphics/zoom_all.png
new file mode 100644 (file)
index 0000000..74c719f
Binary files /dev/null and b/graphics/zoom_all.png differ
index 6fac627276e9468a848fc3abeeb8389dad3a92d3..a0bf50f05e527297a21f2dd805badc9c64a8be19 100644 (file)
@@ -55,7 +55,7 @@ using boost::optional;
 
 /* 3 hours in 640 pixels */
 double const Timeline::_minimum_pixels_per_second = 640.0 / (60 * 60 * 3);
-int const Timeline::_minimum_track_height = 16;
+int const Timeline::_minimum_pixels_per_track = 16;
 
 Timeline::Timeline (wxWindow* parent, ContentPanel* cp, shared_ptr<Film> film)
        : wxPanel (parent, wxID_ANY)
@@ -75,7 +75,7 @@ Timeline::Timeline (wxWindow* parent, ContentPanel* cp, shared_ptr<Film> film)
        , _tool (SELECT)
        , _x_scroll_rate (16)
        , _y_scroll_rate (16)
-       , _track_height (48)
+       , _pixels_per_track (48)
 {
 #ifndef __WXOSX__
        _labels_canvas->SetDoubleBuffered (true);
@@ -99,17 +99,23 @@ Timeline::Timeline (wxWindow* parent, ContentPanel* cp, shared_ptr<Film> film)
 
        film_changed (Film::CONTENT);
 
-       SetMinSize (wxSize (640, 4 * track_height() + 96));
+       SetMinSize (wxSize (640, 4 * pixels_per_track() + 96));
 
        _film_changed_connection = film->Changed.connect (bind (&Timeline::film_changed, this, _1));
        _film_content_changed_connection = film->ContentChanged.connect (bind (&Timeline::film_content_changed, this, _2, _3));
 
-       _pixels_per_second = max (_minimum_pixels_per_second, static_cast<double>(640) / film->length().seconds ());
+       set_pixels_per_second (static_cast<double>(640) / film->length().seconds ());
 
        setup_scrollbars ();
        _labels_canvas->ShowScrollbars (wxSHOW_SB_NEVER, wxSHOW_SB_NEVER);
 }
 
+void
+Timeline::set_pixels_per_second (double pps)
+{
+       _pixels_per_second = max (_minimum_pixels_per_second, pps);
+}
+
 void
 Timeline::paint_labels ()
 {
@@ -387,9 +393,9 @@ Timeline::setup_scrollbars ()
        if (!film || !_pixels_per_second) {
                return;
        }
-       _labels_canvas->SetVirtualSize (_labels_view->bbox().width, tracks() * track_height() + 96);
+       _labels_canvas->SetVirtualSize (_labels_view->bbox().width, tracks() * pixels_per_track() + 96);
        _labels_canvas->SetScrollRate (_x_scroll_rate, _y_scroll_rate);
-       _main_canvas->SetVirtualSize (*_pixels_per_second * film->length().seconds(), tracks() * track_height() + 96);
+       _main_canvas->SetVirtualSize (*_pixels_per_second * film->length().seconds(), tracks() * pixels_per_track() + 96);
        _main_canvas->SetScrollRate (_x_scroll_rate, _y_scroll_rate);
 }
 
@@ -422,6 +428,7 @@ Timeline::left_down (wxMouseEvent& ev)
                left_down_select (ev);
                break;
        case ZOOM:
+       case ZOOM_ALL:
                /* Nothing to do */
                break;
        }
@@ -492,6 +499,8 @@ Timeline::left_up (wxMouseEvent& ev)
        case ZOOM:
                left_up_zoom (ev);
                break;
+       case ZOOM_ALL:
+               break;
        }
 }
 
@@ -532,20 +541,26 @@ Timeline::left_up_zoom (wxMouseEvent& ev)
 
        DCPTime const time_left = DCPTime::from_seconds((top_left.x + vsx) / *_pixels_per_second);
        DCPTime const time_right = DCPTime::from_seconds((bottom_right.x + vsx) / *_pixels_per_second);
-       _pixels_per_second = max (_minimum_pixels_per_second, double(GetSize().GetWidth()) / (time_right.seconds() - time_left.seconds()));
+       set_pixels_per_second (double(GetSize().GetWidth()) / (time_right.seconds() - time_left.seconds()));
 
-       double const tracks_top = double(top_left.y) / _track_height;
-       double const tracks_bottom = double(bottom_right.y) / _track_height;
-       _track_height = max(_minimum_track_height, int(lrint(GetSize().GetHeight() / (tracks_bottom - tracks_top))));
+       double const tracks_top = double(top_left.y) / _pixels_per_track;
+       double const tracks_bottom = double(bottom_right.y) / _pixels_per_track;
+       set_pixels_per_track (lrint(GetSize().GetHeight() / (tracks_bottom - tracks_top)));
 
        setup_scrollbars ();
-       _main_canvas->Scroll (time_left.seconds() * *_pixels_per_second / _x_scroll_rate, tracks_top * _track_height / _y_scroll_rate);
-       _labels_canvas->Scroll (0, tracks_top * _track_height / _y_scroll_rate);
+       _main_canvas->Scroll (time_left.seconds() * *_pixels_per_second / _x_scroll_rate, tracks_top * _pixels_per_track / _y_scroll_rate);
+       _labels_canvas->Scroll (0, tracks_top * _pixels_per_track / _y_scroll_rate);
 
        _zoom_point = optional<wxPoint> ();
        Refresh ();
 }
 
+void
+Timeline::set_pixels_per_track (int h)
+{
+       _pixels_per_track = max(_minimum_pixels_per_track, h);
+}
+
 void
 Timeline::mouse_moved (wxMouseEvent& ev)
 {
@@ -556,6 +571,8 @@ Timeline::mouse_moved (wxMouseEvent& ev)
        case ZOOM:
                mouse_moved_zoom (ev);
                break;
+       case ZOOM_ALL:
+               break;
        }
 }
 
@@ -589,11 +606,13 @@ Timeline::right_down (wxMouseEvent& ev)
                break;
        case ZOOM:
                /* Zoom out */
-               _pixels_per_second = max (_minimum_pixels_per_second, *_pixels_per_second / 2);
-               _track_height = max (_minimum_track_height, _track_height / 2);
+               set_pixels_per_second (*_pixels_per_second / 2);
+               set_pixels_per_track (_pixels_per_track / 2);
                setup_scrollbars ();
                Refresh ();
                break;
+       case ZOOM_ALL:
+               break;
        }
 }
 
@@ -776,3 +795,21 @@ Timeline::scrolled (wxScrollWinEvent& ev)
        }
        ev.Skip ();
 }
+
+void
+Timeline::tool_clicked (Tool t)
+{
+       switch (t) {
+       case ZOOM:
+       case SELECT:
+               _tool = t;
+               break;
+       case ZOOM_ALL:
+               shared_ptr<Film> film = _film.lock ();
+               DCPOMATIC_ASSERT (film);
+               set_pixels_per_second ((_main_canvas->GetSize().GetWidth() - 32) / film->length().seconds());
+               set_pixels_per_track ((_main_canvas->GetSize().GetHeight() - tracks_y_offset() - _time_axis_view->bbox().height - 32) / _tracks);
+               Refresh ();
+               break;
+       }
+}
index 7af770b5faecde87e39040f4f67e37a99d63562c..30f7061d42b24fb336496e32e0cfc1e883957c91 100644 (file)
@@ -46,8 +46,8 @@ public:
 
        int width () const;
 
-       int track_height () const {
-               return _track_height;
+       int pixels_per_track () const {
+               return _pixels_per_track;
        }
 
        boost::optional<double> pixels_per_second () const {
@@ -68,12 +68,11 @@ public:
 
        enum Tool {
                SELECT,
-               ZOOM
+               ZOOM,
+               ZOOM_ALL
        };
 
-       void set_tool (Tool t) {
-               _tool = t;
-       }
+       void tool_clicked (Tool t);
 
        int tracks_y_offset () const;
 
@@ -99,6 +98,8 @@ private:
        void recreate_views ();
        void setup_scrollbars ();
        void scrolled (wxScrollWinEvent& ev);
+       void set_pixels_per_second (double pps);
+       void set_pixels_per_track (int h);
 
        boost::shared_ptr<TimelineView> event_to_view (wxMouseEvent &);
        TimelineContentViewList selected_views () const;
@@ -128,10 +129,10 @@ private:
        Tool _tool;
        int _x_scroll_rate;
        int _y_scroll_rate;
-       int _track_height;
+       int _pixels_per_track;
 
        static double const _minimum_pixels_per_second;
-       static int const _minimum_track_height;
+       static int const _minimum_pixels_per_track;
 
        boost::signals2::scoped_connection _film_changed_connection;
        boost::signals2::scoped_connection _film_content_changed_connection;
index 1d0c1668f0a2840f490097d90165f1ee8ffce44d..88b50076af501cb6d567ebaf02e644c6624ba611 100644 (file)
@@ -51,7 +51,7 @@ TimelineContentView::bbox () const
                time_x (content->position ()),
                y_pos (_track.get()),
                content->length_after_trim().seconds() * _timeline.pixels_per_second().get_value_or(0),
-               _timeline.track_height()
+               _timeline.pixels_per_track()
                );
 }
 
@@ -148,7 +148,7 @@ TimelineContentView::do_paint (wxGraphicsContext* gc, list<dcpomatic::Rect<int>
        wxDouble name_leading;
        gc->SetFont (gc->CreateFont (*wxNORMAL_FONT, foreground_colour ()));
        gc->GetTextExtent (name, &name_width, &name_height, &name_descent, &name_leading);
-       gc->Clip (wxRegion (time_x (position), y_pos (_track.get()), len.seconds() * _timeline.pixels_per_second().get_value_or(0), _timeline.track_height()));
+       gc->Clip (wxRegion (time_x (position), y_pos (_track.get()), len.seconds() * _timeline.pixels_per_second().get_value_or(0), _timeline.pixels_per_track()));
        gc->DrawText (name, time_x (position) + 12, y_pos (_track.get() + 1) - name_height - 4);
        gc->ResetClip ();
 }
@@ -156,7 +156,7 @@ TimelineContentView::do_paint (wxGraphicsContext* gc, list<dcpomatic::Rect<int>
 int
 TimelineContentView::y_pos (int t) const
 {
-       return t * _timeline.track_height() + _timeline.tracks_y_offset();
+       return t * _timeline.pixels_per_track() + _timeline.tracks_y_offset();
 }
 
 void
index dd28f9c234cfbd08af6ede7506b5d6dce6a8eef9..34706d6207c16fd223fae072119c38394654c0c1 100644 (file)
@@ -54,20 +54,23 @@ TimelineDialog::TimelineDialog (ContentPanel* cp, shared_ptr<Film> film)
        wxBoxSizer* sizer = new wxBoxSizer (wxVERTICAL);
 
        wxBoxSizer* controls = new wxBoxSizer (wxHORIZONTAL);
-       _snap = new wxCheckBox (this, wxID_ANY, _("Snap"));
-       controls->Add (_snap);
-       _sequence = new wxCheckBox (this, wxID_ANY, _("Keep video and subtitles in sequence"));
-       controls->Add (_sequence, 1, wxLEFT, 12);
-       wxToolBar* toolbar = new wxToolBar (this, wxID_ANY);
 
 #ifdef DCPOMATIC_LINUX
        wxBitmap select (wxString::Format (wxT ("%s/select.png"), std_to_wx (shared_path().string())), wxBITMAP_TYPE_PNG);
        wxBitmap zoom (wxString::Format (wxT ("%s/zoom.png"), std_to_wx (shared_path().string())), wxBITMAP_TYPE_PNG);
+       wxBitmap zoom_all (wxString::Format (wxT ("%s/zoom_all.png"), std_to_wx (shared_path().string())), wxBITMAP_TYPE_PNG);
 #endif
+       wxToolBar* toolbar = new wxToolBar (this, wxID_ANY);
        toolbar->AddRadioTool ((int) Timeline::SELECT, _("Select"), select);
        toolbar->AddRadioTool ((int) Timeline::ZOOM, _("Zoom"), zoom);
+       toolbar->AddTool ((int) Timeline::ZOOM_ALL, _("Zoom to whole project"), zoom_all);
        controls->Add (toolbar);
-       toolbar->Bind (wxEVT_TOOL, bind (&TimelineDialog::tool_changed, this, _1));
+       toolbar->Bind (wxEVT_TOOL, bind (&TimelineDialog::tool_clicked, this, _1));
+
+       _snap = new wxCheckBox (this, wxID_ANY, _("Snap"));
+       controls->Add (_snap);
+       _sequence = new wxCheckBox (this, wxID_ANY, _("Keep video and subtitles in sequence"));
+       controls->Add (_sequence, 1, wxLEFT, 12);
 
        sizer->Add (controls, 0, wxALL, 12);
        sizer->Add (&_timeline, 1, wxEXPAND | wxALL, 12);
@@ -128,7 +131,7 @@ TimelineDialog::set_selection (ContentList selection)
 }
 
 void
-TimelineDialog::tool_changed (wxCommandEvent& ev)
+TimelineDialog::tool_clicked (wxCommandEvent& ev)
 {
-       _timeline.set_tool ((Timeline::Tool) ev.GetId());
+       _timeline.tool_clicked ((Timeline::Tool) ev.GetId());
 }
index dc583a9f08ca35c32b73d4e6d6977dfffcd86633..0d91baf22d354ba6662a72bd6f2a925e6e94cfa7 100644 (file)
@@ -36,7 +36,7 @@ private:
        void snap_toggled ();
        void sequence_toggled ();
        void film_changed (Film::Property);
-       void tool_changed (wxCommandEvent& id);
+       void tool_clicked (wxCommandEvent& id);
 
        boost::weak_ptr<Film> _film;
        Timeline _timeline;
index 3fe315aaf3f4b5edbc11dcb3ba2c4544b41b22b0..3d0b4265173419e2cd55b9c6629ed355b4961edc 100644 (file)
@@ -55,13 +55,13 @@ TimelineLabelsView::TimelineLabelsView (Timeline& tl)
 dcpomatic::Rect<int>
 TimelineLabelsView::bbox () const
 {
-       return dcpomatic::Rect<int> (0, 0, _width, _timeline.tracks() * _timeline.track_height());
+       return dcpomatic::Rect<int> (0, 0, _width, _timeline.tracks() * _timeline.pixels_per_track());
 }
 
 void
 TimelineLabelsView::do_paint (wxGraphicsContext* gc, list<dcpomatic::Rect<int> >)
 {
-       int const h = _timeline.track_height ();
+       int const h = _timeline.pixels_per_track ();
        gc->SetFont (gc->CreateFont(wxNORMAL_FONT->Bold(), wxColour (0, 0, 0)));
 
        int fy = 0;
index 48157c9c53d3cd5f9d4949a93a1f3fc08191d51b..a31ed5cedd3f7265736ccf5bf5ba5c65a0253c83 100644 (file)
@@ -61,7 +61,7 @@ TimelineTimeAxisView::do_paint (wxGraphicsContext* gc, list<dcpomatic::Rect<int>
 
        double const mark_interval = calculate_mark_interval (rint (128 / pps));
 
-       int y = _y * _timeline.track_height() + 32;
+       int y = _y * _timeline.pixels_per_track() + 32;
 
        wxGraphicsPath path = gc->CreatePath ();
        path.MoveToPoint (0, y);