From f07a469603298049d12e1af9deda4ad830362e58 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Mon, 2 Jul 2018 15:57:55 +0100 Subject: [PATCH] Basic zoom. --- graphics/linux/128/dcpomatic2.png | Bin 24162 -> 24162 bytes graphics/linux/16/dcpomatic2.png | Bin 1947 -> 1947 bytes graphics/linux/22/dcpomatic2.png | Bin 2374 -> 2374 bytes graphics/linux/256/dcpomatic2.png | Bin 70196 -> 70196 bytes graphics/linux/32/dcpomatic2.png | Bin 3712 -> 3712 bytes graphics/linux/48/dcpomatic2.png | Bin 6377 -> 6377 bytes graphics/linux/512/dcpomatic2.png | Bin 232417 -> 232417 bytes graphics/linux/64/dcpomatic2.png | Bin 9357 -> 9357 bytes .../osx/dcpomatic2.iconset/icon_128x128.png | Bin 24162 -> 24162 bytes .../dcpomatic2.iconset/icon_128x128@2x.png | Bin 24162 -> 24162 bytes .../osx/dcpomatic2.iconset/icon_16x16.png | Bin 1947 -> 1947 bytes .../osx/dcpomatic2.iconset/icon_16x16@2x.png | Bin 1947 -> 1947 bytes .../osx/dcpomatic2.iconset/icon_256x256.png | Bin 70196 -> 70196 bytes .../dcpomatic2.iconset/icon_256x256@2x.png | Bin 70196 -> 70196 bytes .../osx/dcpomatic2.iconset/icon_32x32.png | Bin 3712 -> 3712 bytes .../osx/dcpomatic2.iconset/icon_32x32@2x.png | Bin 3712 -> 3712 bytes .../osx/dcpomatic2.iconset/icon_512x512.png | Bin 232417 -> 232417 bytes .../dcpomatic2.iconset/icon_512x512@2x.png | Bin 232417 -> 232417 bytes graphics/select.png | Bin 0 -> 965 bytes graphics/splash.png | Bin 39249 -> 37899 bytes graphics/src/select.svg | 74 +++++++++ graphics/src/zoom.svg | 74 +++++++++ graphics/update | 4 + graphics/web/favicon-128x128.png | Bin 25054 -> 25054 bytes graphics/web/favicon-16x16.png | Bin 1977 -> 1977 bytes graphics/web/favicon-256x256.png | Bin 70289 -> 70289 bytes graphics/web/favicon-32x32.png | Bin 3755 -> 3755 bytes graphics/web/favicon-64x64.png | Bin 9595 -> 9595 bytes graphics/web/logo.png | Bin 22500 -> 22500 bytes graphics/wscript | 2 + graphics/zoom.png | Bin 0 -> 743 bytes src/wx/timeline.cc | 144 ++++++++++++++++-- src/wx/timeline.h | 26 +++- src/wx/timeline_dialog.cc | 25 ++- src/wx/timeline_dialog.h | 1 + 35 files changed, 328 insertions(+), 22 deletions(-) create mode 100644 graphics/select.png create mode 100644 graphics/src/select.svg create mode 100644 graphics/src/zoom.svg create mode 100644 graphics/zoom.png diff --git a/graphics/linux/128/dcpomatic2.png b/graphics/linux/128/dcpomatic2.png index 002c8a43aa5aa763c00ed3f783ff6a0d67c01712..928669ef528e658cbfe7e15537990576b310ba05 100644 GIT binary patch delta 87 zcmaE~hw;%K#tp9+xgIexiSkOTimPjE{=%3XEoGr=V5n nykTHqP%UwdC`m~yNwvz&PsvQHWH2%?#IB+EnM%Oq+iV8_F>)JZ delta 103 zcmbQuKbwDp2P@Y@9yt*mQ-N@9?#)50c8uQUx`sx&#s(oq2395}R;I?<1_o9J1~q$G n1Q-|?R7+eVN>UO_Qmu0HQ!>*k8H@}Jv1{OcuxHKW+iV8_9+MkP diff --git a/graphics/linux/22/dcpomatic2.png b/graphics/linux/22/dcpomatic2.png index 7564c87a2dc524ecd913e97b65cff81c3f459120..b572be179b77ddaf002b4c760f6fdd18f164f938 100644 GIT binary patch delta 103 zcmX>mbWCW&D@LwIj7*}u(yHR>8k@f`y0dv(=o%R68W@Eb8Cn?{TN#;a8yHv_7%=Ug o^M-+eLAAs+q9i4;B-JW6KP5A*lEKKp5W9xrXDR`c+c*vY0Lknew*UYD delta 103 zcmX>mbWCW&D@Lw|JaQsBrUK#I+?&5Jy0dwk>lzyA8XJTd8CaQ^SeY7Y8yHv_7}V@# o5ny0oP%UwdC`m~yNwvz&PsvQHWH2%?#IAw&!Jajf+c*vY0JjYsp8x;= diff --git a/graphics/linux/256/dcpomatic2.png b/graphics/linux/256/dcpomatic2.png index 0cb634e1eba53381768e00df7ab24d61f6331e43..82cbe2d5fc4ac0cb48317830c046fecc36ce92a6 100644 GIT binary patch delta 110 zcmdn8gk{STmJP2MxgIexiSkOTimPihe_`DIg^|&e-`hghz);t~D8$In%Fx)#$XwgN vz{Rc?MtW?ChKk%1w04ZIKbteIXS$anw%-3T8S diff --git a/graphics/linux/32/dcpomatic2.png b/graphics/linux/32/dcpomatic2.png index edfbbb7439e889e32c3af28463133af4f9b28c11..1b2f450be738285eb43dd16e695ef55f9f991df5 100644 GIT binary patch delta 85 zcmZpWZIIpYijnIPBa UyqVn3D~?0D_?b$;8k@f`z7qAe&^0jBH82V>GPE)@wlXr;HZZU delta 103 zcmaE9_|kC0D@Lw|JaQsBrUK#I+?&5Jz7q8|*EKZKH8uz_GO#i+u`)H*HZZUGPE)@ jwlXr;HZZU nykTHqP%UwdC`m~yNwvz&PsvQHWH2%?#IB+EnM%Oqv&shm=sF#D delta 103 zcmeD6?DgF6ijnIfkDQ2(sX#b4_vSB*eTv@Zx`sx&#s(oq2395}R;I?<1_o9J1~q$G n1Q-|?R7+eVN>UO_Qmu0HQ!>*k8H@}Jv1{OcuxHKWv&shm)mt53 diff --git a/graphics/osx/dcpomatic2.iconset/icon_128x128.png b/graphics/osx/dcpomatic2.iconset/icon_128x128.png index 002c8a43aa5aa763c00ed3f783ff6a0d67c01712..928669ef528e658cbfe7e15537990576b310ba05 100644 GIT binary patch delta 87 zcmaE~hw;%K#tp9+xgIexiSkOTimPjE{=%3XEoGr=V5n nykTHqP%UwdC`m~yNwvz&PsvQHWH2%?#IB+EnM%Oq+iV8_F>)JZ delta 103 zcmbQuKbwDp2P@Y@9yt*mQ-N@9?#)50c8uQUx`sx&#s(oq2395}R;I?<1_o9J1~q$G n1Q-|?R7+eVN>UO_Qmu0HQ!>*k8H@}Jv1{OcuxHKW+iV8_9+MkP diff --git a/graphics/osx/dcpomatic2.iconset/icon_16x16@2x.png b/graphics/osx/dcpomatic2.iconset/icon_16x16@2x.png index eb295c31db171b9b0ecf310daff50f1f35fe0384..433c6c567138b8463dd719e7dcda75b76c01bdee 100644 GIT binary patch delta 103 zcmbQuKbwDp2P@YjMkY~SX;pD`jm<% nykTHqP%UwdC`m~yNwvz&PsvQHWH2%?#IB+EnM%Oq+iV8_F>)JZ delta 103 zcmbQuKbwDp2P@Y@9yt*mQ-N@9?#)50c8uQUx`sx&#s(oq2395}R;I?<1_o9J1~q$G n1Q-|?R7+eVN>UO_Qmu0HQ!>*k8H@}Jv1{OcuxHKW+iV8_9+MkP diff --git a/graphics/osx/dcpomatic2.iconset/icon_256x256.png b/graphics/osx/dcpomatic2.iconset/icon_256x256.png index 0cb634e1eba53381768e00df7ab24d61f6331e43..82cbe2d5fc4ac0cb48317830c046fecc36ce92a6 100644 GIT binary patch delta 110 zcmdn8gk{STmJP2MxgIexiSkOTimPihe_`DIg^|&e-`hghz);t~D8$In%Fx)#$XwgN vz{Rc?MtW?ChKk%1w04ZIKbteIXS$anw%-3T8S diff --git a/graphics/osx/dcpomatic2.iconset/icon_256x256@2x.png b/graphics/osx/dcpomatic2.iconset/icon_256x256@2x.png index 0cb634e1eba53381768e00df7ab24d61f6331e43..82cbe2d5fc4ac0cb48317830c046fecc36ce92a6 100644 GIT binary patch delta 110 zcmdn8gk{STmJP2MxgIexiSkOTimPihe_`DIg^|&e-`hghz);t~D8$In%Fx)#$XwgN vz{Rc?MtW?ChKk%1w04ZIKbteIXS$anw%-3T8S diff --git a/graphics/osx/dcpomatic2.iconset/icon_32x32.png b/graphics/osx/dcpomatic2.iconset/icon_32x32.png index edfbbb7439e889e32c3af28463133af4f9b28c11..1b2f450be738285eb43dd16e695ef55f9f991df5 100644 GIT binary patch delta 85 zcmZpWZIIpYijnIPBa UyqVn3D~?0D_?b$; UyqVn3D~?0D_?b$;GPE)@ jwlXr;HZZUGPE)@ jwlXr;HZZU7gL4MWMa)u*KfQgY3;)dnpRuj1Hnbw8V)Kk3uPyM0N`!P1BYIW#_Q9OB~~@&T2B5 zWaihyZa}lith(C=!|r9wn2>8`XkkSxBW)l~^pM9vvNRD~d7+;O{FX08nXeZob{q)APRH z?|<&>a3CBGJBNpdeZ9TCH&s>rT-Wt4bzRRrPMHtEM74u$JqlRL{27??|M8Q+pY?Q0#;X7^+Y0ZTq>1*%;)pp zp~0HF&K?+s@$)?YVMj-Y)6Sr&sR`ZP-R{xR(YHdO&k$9NT=RXCo+lW_hm?gt7e$8gH4aH|?XQ64D)8p}Y0i4=3 zQg>VS_xESw@p#>}TUuH&RaG_T=H?)ZVwmH&G=PR_8?B?1$z+a;#p1b#J3Bjw$Kx4E zk{+zAtdt^=h(i>`FwgTTJCnL-X=%APH8oX|B#Bn9NFc8 literal 0 HcmV?d00001 diff --git a/graphics/splash.png b/graphics/splash.png index f14760948737e30a5615bfe44d7dbc1af0943afe..29b69a45c44b24bd6fb14510ba2b7c52bfa3e027 100644 GIT binary patch delta 21099 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 Hw>$p@I+UtS diff --git a/graphics/src/select.svg b/graphics/src/select.svg new file mode 100644 index 000000000..0ebba99c6 --- /dev/null +++ b/graphics/src/select.svg @@ -0,0 +1,74 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + diff --git a/graphics/src/zoom.svg b/graphics/src/zoom.svg new file mode 100644 index 000000000..26e4c36b7 --- /dev/null +++ b/graphics/src/zoom.svg @@ -0,0 +1,74 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + diff --git a/graphics/update b/graphics/update index e33e9a8b5..9c14f2157 100755 --- a/graphics/update +++ b/graphics/update @@ -65,6 +65,10 @@ else # Splash screen (all platforms) $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 + # favicon mkdir -p web convert src/web.png -resize 256x256 -transparent white web/favicon-256x256.png diff --git a/graphics/web/favicon-128x128.png b/graphics/web/favicon-128x128.png index 073162d09cd6738235d8010be5f8e5ff06718150..bc58be5941951f8110c57238c136fee765a36547 100644 GIT binary patch delta 80 zcmcb2nDO3W#tp9-IoTQcwRz`7=5F2mh4E3GxVf%@VThrrm5H&Hp|Q4sp_PHb&X|_z TliwytVUs(-Xrnz@F7W^WRht=H delta 80 zcmcb2nDO3W#tp9-Iaztcco?shH|*T}h4E3GxT&t8QHYU|m7$T9fuXj6p_PHbaubgE TliwytVUxR-xj}idT;c%$RwxKl9j delta 99 zcmdnVzmtDMIx8nDj~EZ*wep6Yn+sSS89hvO4UIyKjI0cetPBjb4GgUe43?X4%x7R= nP%UwdC`m~yNwvz&PsvQHWH2%?w9qxcqTyQR2Ia{=*$w~zNG==j diff --git a/graphics/web/favicon-256x256.png b/graphics/web/favicon-256x256.png index 7a26e4a988398f05a7e70521521138fecf66fb1b..9a2e8bd03f3895f771ab8f891c5c2a464a611d12 100644 GIT binary patch delta 93 zcmbQZlx5;lmJP2MxgIexiSkOTimPihe_`DIg^_U*zm$cpfuXK}QHYVDm7%efk-4^k dft7&))9yKMrY{g=6vrW7{7fZa`b9y;0|4pU8c_fM delta 93 zcmbQZlx5;lmJP2MxgPS!iRhRLgmZH@e_`DIg^_U*zm&PIp^>h!L5Puom5GU!sj;?! dft7(l&0ZFP=?erI#c{~ diff --git a/graphics/web/favicon-64x64.png b/graphics/web/favicon-64x64.png index 680867f7b1d2daf458862accad7e0a1bab2c9d70..7537c82203f2074d58ca8e26e889e076112dd9d3 100644 GIT binary patch delta 78 zcmezE_1kO1Yer6XMt*JHd6BtWH-BNQR}weZH82b@G_^7@wlXxGJSHF RiWD}v6O1<6lXt5e0087R7sLPn delta 78 zcmezE_1kO1Yer619x)!qYvm0)H-BNQR}weXH8ct_GO{u>vNAB#HZZg@Fj#KFF@JKG RiWD}vYndCAC+}7{0088}7&rg` diff --git a/graphics/web/logo.png b/graphics/web/logo.png index 97b8fdcd88bbdfa8f2ef9428e486f3170a2fcb79..2170aff8b24e46a759c92e82df3e0edc8c900988 100644 GIT binary patch delta 105 zcmaE|p7F_g#tp9+xgIexiSkOTimPjE{=)b)#M?sGz);t~D8$In%Fx)#$XwgNz{Rc?MtW?ChKk%1w04ZIKbteLD5egFWQE*|gz diff --git a/graphics/wscript b/graphics/wscript index 23c3d56ea..1be119783 100644 --- a/graphics/wscript +++ b/graphics/wscript @@ -30,3 +30,5 @@ def build(bld): if not bld.env.TARGET_WINDOWS: 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', 'select.png') diff --git a/graphics/zoom.png b/graphics/zoom.png new file mode 100644 index 0000000000000000000000000000000000000000..d7dbd6bb92a31ed3a2815153e30330cd55690223 GIT binary patch literal 743 zcmV?P)gYN1hN6oT}c9X3s^w^Gc52LxK)k(k%)LAqJx8jIyX0` zySux3babRUJ3BfvGou3o0}7~!6o3bn$R7h5i^c5v`nm?Oy1J^yn9>R#mLtCl6yx!@ zJw84Tl$Xe6vl@%VtcZBP?I3wrM0V=y>+Rm&URm-I+uPe33WY4N0f=AV9-yP6qZP?Z z3=a>N4*!l{;2EG>TU%8H*4EZafhoU0y0Nj*T5GEcTwGjeI2^XXoBzo}K)d5OBI3J+ zfz;L2(c0Py;P?f;=W;o%%6>^MmjiJ90$)#0Pvzv~q$+tPli}>_On{7EAZ4v(adEM# zz{0{p>GGZ5oOTiU5s$}hp-`ykfX~m*H5!dt5pjX*K`$~1==k_}MS+o#kgBTgohnn)xp zpxxcwdU$xK^YinC&d$z_aw6A&=OR)Bw56rR_V@Se(9n?f_4R3UbF<~wui67%IF56$ zva(WiT~}vkXY-EZlobKE2~3H|XA#L?O7kM}33v+JxSZE!jM=X?@+VCJ_i7diqRkld z<*&$xT1VQAG5hIs+Pbc*)6>)Wj*gDWS_XbcmX?<6^767qqtREj4gj=8B9WJoNaQ`x Z^%Dr(seWATdm;b;002ovPDHLkV1h6VT#5hy literal 0 HcmV?d00001 diff --git a/src/wx/timeline.cc b/src/wx/timeline.cc index 04db5c628..42fb9187f 100644 --- a/src/wx/timeline.cc +++ b/src/wx/timeline.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2013-2016 Carl Hetherington + Copyright (C) 2013-2018 Carl Hetherington This file is part of DCP-o-matic. @@ -45,6 +45,7 @@ using std::list; using std::cout; +using std::min; using std::max; using boost::shared_ptr; using boost::weak_ptr; @@ -53,7 +54,7 @@ using boost::bind; using boost::optional; Timeline::Timeline (wxWindow* parent, ContentPanel* cp, shared_ptr film) - : wxPanel (parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxFULL_REPAINT_ON_RESIZE) + : wxScrolledCanvas (parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxFULL_REPAINT_ON_RESIZE) , _content_panel (cp) , _film (film) , _time_axis_view (new TimelineTimeAxisView (*this, 64)) @@ -65,6 +66,9 @@ Timeline::Timeline (wxWindow* parent, ContentPanel* cp, shared_ptr film) , _first_move (false) , _menu (this) , _snap (true) + , _tool (SELECT) + , _x_scroll_rate (16) + , _y_scroll_rate (16) { #ifndef __WXOSX__ SetDoubleBuffered (true); @@ -79,31 +83,41 @@ Timeline::Timeline (wxWindow* parent, ContentPanel* cp, shared_ptr film) film_changed (Film::CONTENT); - SetMinSize (wxSize (640, tracks() * track_height() + 96)); + SetMinSize (wxSize (640, 4 * track_height() + 96)); _tracks_position = Position (_labels_view->bbox().width, 32); _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 (0.01, static_cast(640 - tracks_position().x * 2) / film->length().seconds ()); + + setup_scrollbars (); + EnableScrolling (true, true); } void Timeline::paint () { wxPaintDC dc (this); + DoPrepareDC (dc); wxGraphicsContext* gc = wxGraphicsContext::Create (dc); if (!gc) { return; } + int vsx, vsy; + GetViewStart (&vsx, &vsy); + gc->Translate (-vsx * _x_scroll_rate, -vsy * _y_scroll_rate); + gc->SetAntialiasMode (wxANTIALIAS_DEFAULT); BOOST_FOREACH (shared_ptr i, _views) { shared_ptr ic = dynamic_pointer_cast (i); - /* Find areas of overlap */ + /* Find areas of overlap with other content views, so that we can plot them */ list > overlaps; BOOST_FOREACH (shared_ptr j, _views) { shared_ptr jc = dynamic_pointer_cast (j); @@ -121,6 +135,19 @@ Timeline::paint () i->paint (gc, overlaps); } + if (_zoom_point) { + /* Translate back as _down_point and _zoom_point do not take scroll into account */ + gc->Translate (vsx * _x_scroll_rate, vsy * _y_scroll_rate); + gc->SetPen (*wxBLACK_PEN); + gc->SetBrush (*wxTRANSPARENT_BRUSH); + gc->DrawRectangle ( + min (_down_point.x, _zoom_point->x), + min (_down_point.y, _zoom_point->y), + fabs (_down_point.x - _zoom_point->x), + fabs (_down_point.y - _zoom_point->y) + ); + } + delete gc; } @@ -167,7 +194,7 @@ Timeline::recreate_views () } assign_tracks (); - setup_pixels_per_second (); + setup_scrollbars (); Refresh (); } @@ -179,7 +206,7 @@ Timeline::film_content_changed (int property, bool frequent) if (property == AudioContentProperty::STREAMS) { recreate_views (); } else if (!frequent) { - setup_pixels_per_second (); + setup_scrollbars (); Refresh (); } } @@ -322,14 +349,14 @@ Timeline::tracks () const } void -Timeline::setup_pixels_per_second () +Timeline::setup_scrollbars () { shared_ptr film = _film.lock (); - if (!film || film->length() == DCPTime ()) { + if (!film || !_pixels_per_second) { return; } - - _pixels_per_second = static_cast(width() - tracks_position().x * 2) / film->length().seconds (); + SetVirtualSize (*_pixels_per_second * film->length().seconds(), tracks() * track_height() + 96); + SetScrollRate (_x_scroll_rate, _y_scroll_rate); } shared_ptr @@ -352,6 +379,22 @@ Timeline::event_to_view (wxMouseEvent& ev) void Timeline::left_down (wxMouseEvent& ev) +{ + _left_down = true; + _down_point = ev.GetPosition (); + + switch (_tool) { + case SELECT: + left_down_select (ev); + break; + case ZOOM: + /* Nothing to do */ + break; + } +} + +void +Timeline::left_down_select (wxMouseEvent& ev) { shared_ptr view = event_to_view (ev); shared_ptr content_view = dynamic_pointer_cast (view); @@ -378,8 +421,6 @@ Timeline::left_down (wxMouseEvent& ev) content_view->set_selected (!content_view->selected ()); } - _left_down = true; - _down_point = ev.GetPosition (); _first_move = false; if (_down_view) { @@ -410,6 +451,19 @@ Timeline::left_up (wxMouseEvent& ev) { _left_down = false; + switch (_tool) { + case SELECT: + left_up_select (ev); + break; + case ZOOM: + left_up_zoom (ev); + break; + } +} + +void +Timeline::left_up_select (wxMouseEvent& ev) +{ if (_down_view) { _down_view->content()->set_change_signals_frequent (false); } @@ -419,15 +473,51 @@ Timeline::left_up (wxMouseEvent& ev) /* Clear up up the stuff we don't do during drag */ assign_tracks (); - setup_pixels_per_second (); + setup_scrollbars (); Refresh (); _start_snaps.clear (); _end_snaps.clear (); } +void +Timeline::left_up_zoom (wxMouseEvent& ev) +{ + _zoom_point = ev.GetPosition (); + + int vsx, vsy; + GetViewStart (&vsx, &vsy); + + wxPoint top_left(min(_down_point.x, _zoom_point->x), min(_down_point.y, _zoom_point->y)); + wxPoint bottom_right(max(_down_point.x, _zoom_point->x), max(_down_point.y, _zoom_point->y)); + + DCPTime time_left = DCPTime::from_seconds((top_left.x + vsx - _tracks_position.x) / *_pixels_per_second); + DCPTime time_right = DCPTime::from_seconds((bottom_right.x + vsx - _tracks_position.x) / *_pixels_per_second); + _pixels_per_second = GetSize().GetWidth() / (time_right.seconds() - time_left.seconds()); + cout << "Zoom range " << to_string(time_left) << " " << to_string(time_right) << " " << *_pixels_per_second << "\n"; + setup_scrollbars (); + Scroll (time_left.seconds() * *_pixels_per_second / _x_scroll_rate, wxDefaultCoord); + cout << "Offset " << (time_left.seconds() * *_pixels_per_second / _x_scroll_rate) << "\n"; + + _zoom_point = optional (); + Refresh (); +} + void Timeline::mouse_moved (wxMouseEvent& ev) +{ + switch (_tool) { + case SELECT: + mouse_moved_select (ev); + break; + case ZOOM: + mouse_moved_zoom (ev); + break; + } +} + +void +Timeline::mouse_moved_select (wxMouseEvent& ev) { if (!_left_down) { return; @@ -436,8 +526,34 @@ Timeline::mouse_moved (wxMouseEvent& ev) set_position_from_event (ev); } +void +Timeline::mouse_moved_zoom (wxMouseEvent& ev) +{ + if (!_left_down) { + return; + } + + _zoom_point = ev.GetPosition (); + Refresh (); +} + void Timeline::right_down (wxMouseEvent& ev) +{ + switch (_tool) { + case SELECT: + right_down_select (ev); + break; + case ZOOM: + /* Zoom out */ + _pixels_per_second = *_pixels_per_second / 2; + setup_scrollbars (); + break; + } +} + +void +Timeline::right_down_select (wxMouseEvent& ev) { shared_ptr view = event_to_view (ev); shared_ptr cv = dynamic_pointer_cast (view); @@ -542,7 +658,7 @@ Timeline::film () const void Timeline::resized () { - setup_pixels_per_second (); + setup_scrollbars (); } void diff --git a/src/wx/timeline.h b/src/wx/timeline.h index c8424541e..375a837a8 100644 --- a/src/wx/timeline.h +++ b/src/wx/timeline.h @@ -35,7 +35,7 @@ class TimelineTimeAxisView; class TimelineReelsView; class TimelineLabelsView; -class Timeline : public wxPanel +class Timeline : public wxScrolledCanvas { public: Timeline (wxWindow *, ContentPanel *, boost::shared_ptr); @@ -45,7 +45,7 @@ public: void force_redraw (dcpomatic::Rect const &); int width () const { - return GetSize().GetWidth (); + return GetVirtualSize().GetWidth (); } int track_height () const { @@ -62,8 +62,6 @@ public: int tracks () const; - void setup_pixels_per_second (); - void set_snap (bool s) { _snap = s; } @@ -74,12 +72,27 @@ public: void set_selection (ContentList selection); + enum Tool { + SELECT, + ZOOM + }; + + void set_tool (Tool t) { + _tool = t; + } + private: void paint (); void left_down (wxMouseEvent &); + void left_down_select (wxMouseEvent &); void left_up (wxMouseEvent &); + void left_up_select (wxMouseEvent &); + void left_up_zoom (wxMouseEvent &); void right_down (wxMouseEvent &); + void right_down_select (wxMouseEvent &); void mouse_moved (wxMouseEvent &); + void mouse_moved_select (wxMouseEvent &); + void mouse_moved_zoom (wxMouseEvent &); void film_changed (Film::Property); void film_content_changed (int, bool frequent); void resized (); @@ -87,6 +100,7 @@ private: void set_position_from_event (wxMouseEvent &); void clear_selection (); void recreate_views (); + void setup_scrollbars (); boost::shared_ptr event_to_view (wxMouseEvent &); TimelineContentViewList selected_views () const; @@ -103,6 +117,7 @@ private: boost::optional _pixels_per_second; bool _left_down; wxPoint _down_point; + boost::optional _zoom_point; boost::shared_ptr _down_view; DCPTime _down_view_position; bool _first_move; @@ -111,6 +126,9 @@ private: std::list _start_snaps; std::list _end_snaps; Position _tracks_position; + Tool _tool; + int _x_scroll_rate; + int _y_scroll_rate; boost::signals2::scoped_connection _film_changed_connection; boost::signals2::scoped_connection _film_content_changed_connection; diff --git a/src/wx/timeline_dialog.cc b/src/wx/timeline_dialog.cc index 36ca0ff7b..dd28f9c23 100644 --- a/src/wx/timeline_dialog.cc +++ b/src/wx/timeline_dialog.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2013-2016 Carl Hetherington + Copyright (C) 2013-2018 Carl Hetherington This file is part of DCP-o-matic. @@ -18,14 +18,15 @@ */ -#include -#include -#include "lib/playlist.h" #include "film_editor.h" #include "timeline_dialog.h" #include "wx_util.h" #include "content_panel.h" +#include "lib/playlist.h" +#include "lib/cross.h" +#include #include +#include using std::list; using std::cout; @@ -57,6 +58,16 @@ TimelineDialog::TimelineDialog (ContentPanel* cp, shared_ptr film) 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); +#endif + toolbar->AddRadioTool ((int) Timeline::SELECT, _("Select"), select); + toolbar->AddRadioTool ((int) Timeline::ZOOM, _("Zoom"), zoom); + controls->Add (toolbar); + toolbar->Bind (wxEVT_TOOL, bind (&TimelineDialog::tool_changed, this, _1)); sizer->Add (controls, 0, wxALL, 12); sizer->Add (&_timeline, 1, wxEXPAND | wxALL, 12); @@ -115,3 +126,9 @@ TimelineDialog::set_selection (ContentList selection) { _timeline.set_selection (selection); } + +void +TimelineDialog::tool_changed (wxCommandEvent& ev) +{ + _timeline.set_tool ((Timeline::Tool) ev.GetId()); +} diff --git a/src/wx/timeline_dialog.h b/src/wx/timeline_dialog.h index c970b3b41..dc583a9f0 100644 --- a/src/wx/timeline_dialog.h +++ b/src/wx/timeline_dialog.h @@ -36,6 +36,7 @@ private: void snap_toggled (); void sequence_toggled (); void film_changed (Film::Property); + void tool_changed (wxCommandEvent& id); boost::weak_ptr _film; Timeline _timeline; -- 2.30.2