From 11466cf5b35b28f091c716071dfb0a25873c21ff Mon Sep 17 00:00:00 2001 From: itsmattkc Date: Wed, 26 Dec 2018 21:16:15 +1100 Subject: [PATCH] implemented hand tool for moving content around --- icons/hand-disabled.png | Bin 0 -> 6400 bytes icons/hand.png | Bin 0 -> 6360 bytes icons/icons.qrc | 2 ++ mainwindow.cpp | 14 ++++++++- mainwindow.h | 2 ++ mainwindow.ui | 9 ++++++ panels/timeline.cpp | 68 +++++++++++++++++++++++----------------- panels/timeline.h | 9 ++++++ panels/timeline.ui | 16 ++++++++++ ui/keyframeview.cpp | 33 ++++++++++++++----- ui/keyframeview.h | 3 +- ui/timelinewidget.cpp | 24 ++++++++++++-- ui/timelinewidget.h | 2 ++ ui/viewerwidget.cpp | 11 ++++--- 14 files changed, 149 insertions(+), 44 deletions(-) create mode 100644 icons/hand-disabled.png create mode 100644 icons/hand.png diff --git a/icons/hand-disabled.png b/icons/hand-disabled.png new file mode 100644 index 0000000000000000000000000000000000000000..ec80df67acecd73ffcb9bfe150cb0d7c03aea76e GIT binary patch literal 6400 zcmV+b8UN;qP)U8P*7-ZbZ>KLZ*U+lnSp_Ufq@}0xwybFAi#%#fq@|}KQEO56)-X|e7nZL z$iTqBa9P*U#mSX{G{Bl%P*lRez;J+pfx##xwK$o9f#C}S14DXwNkIt%17i#W1A|CX zc0maP17iUL1A|C*NRTrF17iyV0~1e4YDEbH0|SF|enDkXW_m`6f}y3QrGjHhep0GJ zaAk2xYHqQDXI^rCQ9*uDVo7QW0|Nup4h9AW240u^5(W3f%sd4n162kpgNVo|1qcff zJ_s=cNG>fZg9jx8g8+j9g8_pBLjXe}Lp{R+hNBE`7{wV~7)u#fFy3PlV+vxLz;uCG zm^qSpA@ds+OO_6nTdaDlt*rOhEZL^9ePa)2-_4=K(Z%tFGm-NGmm}8}ZcXk5JW@PU zd4+f<@d@)yL(o<5icqT158+-B6_LH7;i6x}CW#w~Uy-Pgl#@Irl`kzV zeL|*8R$ca%T%Wv){2zs_iiJvgN^h0dsuZZ2sQy$tsNSU!s;Q*;LF<6_B%M@UD?LHI zSNcZ`78uqV#TeU~$eS{ozBIdFzSClfs*^S+dw;4dus<{M;#|MXC)T}S9v!D zcV!QCPhBq)ZyO(X-(bH4|NMaZz==UigLj2o41F2S6d@OB6%`R(5i>J(Puzn9wnW{e zu;hl6HK{k#IWjCVGqdJqU(99Cv(K+6*i`tgSi2;vbXD1#3jNBGs$DgVwO(~o>mN4i zHPtkqZIx>)Y(Ls5-Br|mx>vQYvH$Kwn@O`L|D75??eGkZnfg$5<;Xeg_o%+-I&+-3%01W^SH2RkDT>t<8AY({UO#lFTB>(_`g8%^e z{{R4h=>PzAFaQARU;qF*m;eA5Z<1fdMgRa6Vo5|nRCwC#oq3$i_5R1tImQelV;@Vh z6A?)!TgjeXO3JNNNL^H-blsL`3tCl{xRE8JZsPvj#2`y?rL<9+kS#*C5r$dM`TqWx zrZF>T`Mkg9e81=WJu{E@|DT!f=XpM#&-?xUyx#ARLv!R9cC}ba;fO5L{xXMc@x*a6 zlX!d)1mcSOW z3*gbnVm-qsS&S#VR+D997J{Rpk;xC-T8t;0R+?h8A=!9 z32e1lizfh{Y%=Mr8&F9Gu`Azr9uBdZ-e#^MyW+WlLjmCA*kZ2HxjMVB&C3tK!w#TD zF&_Wcf{RLceq}r^9pg9SE8ITDJjl#qJpQdM$CU77vxzIjqgQ37mv}1I-0Y@OF&=-` zpP!ZRXrwYom?|wnKQjD|d7eJSc>Gz90B-fAHl0SIv8%8$fZO5b^uN%`xSr;$RUu6QIbE;%Q_vzHOdKcr1QFIM1AgQI zM(Oh4TC+`n$HQ`kZPdjGQU!Q=*&9zKg{>l+wMwT#L2J+dM4Q`73eu{}cug?k?~Jtf z=GI1OCqKs^9g>ZPBnzhUA`=yU=}~+k!t;Q=@!Y6*qxmlyi^nc2$hm2x@U+61twi2n zI(>r*tiz6{g%1^4LHnMeI^wDSiKg;31qsLP92Jb2MsItcJsmir^r3(7Zyo4A5uH5? zsUI-rxkD-2mTQL?Z12sjui|Fm<`|WPzr=ccCc?9ZHUa&%w?%mN)5YF+I`WgU<2zWW zA1los(PSpmF`(b}v2sEuC+AVy-gs(qT=`?)6@F|5Hi%ZwIXVV7$eZ%1XvDoVw>O?B zf%BV8N743Hk0qkX)VL#nPWoDrFQ~DBtL=>^jt>RC)x)Cgtrp8flbOXo10-+zDk|r4 zx8o$cUno@Mc~R1`nPBW##cQ)XH~8%UBR(Y%muO_O$c(B5Bk{y?kKlv9=T5=c(X0}= z2ARzDJDsu26yf$TA%x{AVY*Q0E>NSLWU^r7%FGj%cm zAUbigQcw|Eop*$I=2Okjc=g#U8f`xV>@Njr#9Yz#c9TH+^PwLVw71P@t>4XU0Dp+^ z9HF88@s#5k(I-DHkeDnH;@RZqUbX~pkS4eOqqPPj1)=E$mMM>X8MB3(+cGZq zIa&i&2uGU~gv!W5N}WEUTg`)1R~$EnD>0dJx+#jUWDfqJOhvt+Z+WpD-ml zhbSM{9&agXBJ#9(bs`6ki~bxIeEd&JiTXI+7jAC<^x?VH;6K8V7E&>C@Hj|dt>EJ` zxX#D#{8Fn;qHt2j`e-3`4Zn!S$zZ&B&B)BaQ-`Ud2^gcWek!s~bfIvX2|m?$8N#jY zX0za!gC~~zL{spAf~+@6P)m>#=MVRBSw2;C4X3d`s5VL##N(t3zX~Q`AI$^m4(hU6 zG^uVnd-Vw8St#5jrZSN(8ONzfH8qXE7zf zZDdc8v!U^+SJ7ZI#WML^`;D&V_L%pFr!7eO z-}JE7i(BpFdC~ur&MY&;Q!02`v$0Spd7f0(atq~k{i#R!T`(1?EcTlkoxo{P)RX8X z6H!iBli;Dd+0SSA!ZY9J{o!iv*7c|Q@ug@gl70AEIcs~I&>?=+OB(YgQGKe$*E-wA zh8$0VpOi@|Tj`+VI_hd+j`<8jeQqUXMCxsgY+f(qaYb{F2(g<)of~_|@$~X5f6Cx< z8i+Gb<#|ph-dOB2aUacc(O4IGrO+5LLJ@r`W6g%+9gmZQ03V;uJZ=yllS33Mwev#B zc0Ts{NlOax6Wk+ecv_0S!eH_+FL{l6It#@cCm2&;jEA^B$0QJT(*} zg00*uYWUSym}k!97cTR%)j z+}=F&Df9yv}n9gDB6f; zig1iG+@J4y<7uI2H;X6Dy+{azr>&r*;zgP&Uo2D;PK?HyLLO5|-W0B$!}&V#HvOw7 zu%#NbNbpnw<#gcz5G?%-qBNvNiWgzkzl2Wl#Y^swD)FxPCvwz0Wt$ov7hRQaR6OkT zn_tdv&u~U~`b;daeqxv=^Z+#m{fRh+A)?f5Zs}H4YvFNFlSJi7$YeJy71KPO*e{%% zwFQ)A)x?!?>5Tc)|7*=A@!HAax$vAk{_vFGZ-Uss!-w3UbkQ5fR^bGlWLCasmP?8K zt`sKYz)3ub!c2Eg06ro-aQxqv)?~S;sn9&7CO}SRi0*1M+?=K7C4jCMy`PX1^S?nf zjfD3*d2K1LG#G;u2To!rPv!h~(*Csu4{}hjeoirq%M|{ZdxiHbIa+~U#Nxz39Fv5O zfrf|a4B!J{^>wcO;HPLfcq>C?>d}clbY~Qga6Omhh0y--T**AqW^jS~6%NsBStFjJ zELJm~YBc3xVct8(w)3M-I2!W|daK7tJRP{3u`FN{JNS)XN#;KcrdIA*=O0f=`V@G( zGmw4D@PNl?EVIPFe~k=&=4G(V4@D-zS zx6?p6w+g&03IQ|O#O(n-$H}8Y5n=8YWiFT;JIiAsUp3|F!#jM>aW75EJh=ISF~s3i zks&taE77)afy1;4;AHm^-q(cF+#!9+q6F3H%{=yTmQ0^NxAP>?o>D4!N-~n~g&(wr zPJRJ3;or8wb4dB+ER}WBfKjX_CBQ!5VL#)zTusDViwVMG)y?~UU-m4;6x|24+4ecD zLbh`1@+{wQR$-Gq%^Vu5;c-%x6~ZE=GbGW{j~Zd5z-14wZ5OmL^S5rQFn}cGd}A7) zQB7R}-;MRcSpNd+shKa@ztnmNpQs3*ZPoe0P{CZuU{(lP!+6+8EnKR2N^>Xcgn-gm zN*5o2Y7_oz6Fl=m5R|&;!5Yp8JkKoNp^l`0q%xiOS?Jnkvz#GbGjU~DAiT2)m(32k z<8BFtif8TwP*H-%Neo^2TG(1Eoo^V9!^hW#^n0D`bvMx z@RW`_8;w-<@i^TmhlA?kt~lYaOx_M+^}L}YiF=O4G|Ih_(}%}N115^sPtL+kWgXMG zkv6<*i?in~zwOEWSu?S!LBqpO49d&+>n)sjQHwP~A#C3AJ606Zkoz@tk6k7|&$!U%9|initMY2H*0iIWr;}Pde`lOMXj< z*N%rR^zx=~3La04^6S2KwRJQR&B#a{d4k8N?(IhqiiTlMW{WFk>}1;+D7xJ_CtNwF zd5xOhFaAT*&#j9N-KTx*7%vLuqMO(y@bhe1Xz*0vA)DNN>bsKrRB-2$EF611J$x5` zh6az5x_leK5zt-|6lbD=c;tutJ?9>(W|dJqtE1}7E_Q(@74z1zG;by|sqe4(P3U@w z-bhl!;_y&t{CiLS@cxMy$usxPyWCyfodN@hsQ-N z_Uo!Xvxm)8sF9PjvpvmZ@3D??jgsGu;P_{I!2a(|MQi6%+68X87Fs-a3tQgX%RN{b zU^*qwr5$0kio7wjc$zUkg2U5PzfT9a1TWBKvYe(WnY_^ADa(Tq9G+_Y-Osmo7x;lE zc~YrJI^<3I6WAHScy@d3C7)AqA?Zq=OnbFBD%5!5nH9l!JiO;M{%I}hZJNnK>Z@H+ zgc?s2x7bMLp-1<&tWY^te_`X<^r(?iYRL#|Tq0B!`H z&JljO9gH2|UNx86I6QIejNsf`a2I=vXejBPZ_MLl3nSb;(Cbv}Vu0*v17q-vk7#L# z{-n?xX|;nfcskpntk>+d^8>x5O)rhX6I;A`yeM*}Q%m}Wi7|MbY%T^;Kx+6MJ>)gs z#^5Q*YsE+k3EZoMw$-bCi`LPMKeE@(_jK1&qiPHu7uV}(M;XaJ+f*M9MTG^AgB#dg zjO8z%?F+i-YgBF&o_0zPG!+dy&1Aj3e2v0$m2Db=8J|AgKno+fzy}xkd>rvrr)qYR ziMoo14aMVRaj|oNhMSG5x&m|YOp5SJIW;@Q6aFd?!i6V>;l*&sU?r`B>1bsXo)X+u zcMU5vqbI^YQc$KK&YLmd?`r z?Tf61r*V;vdpzuCr2crvcswonr3mA>$fCTShE~LrAe6R7*4o*_z)(EOWE`HW_^1fS zJM*a-{Ms=RPaI2%tlDimeS$xCjK$+(p^mO*k+89yWQxAaH#6}#c(F+0$z&64Lp6uS z;c+q~qAPuT*$JKv`pptk@U$p`k&lPfvrQ#TYDYIE^8=x38hl!CKl+J-JuU?!gCERA@l;4lwMdKFj+PdQ$X=+nnT3iE_- zELaGSlLu_^KB@legU`4*^d6g8cpP+!=t`gCj0$ZU$80?Hcr$`^pl<~y(hWbJSnkvL zfTs1Mow=b=6oeCxgLV;GXS!c+Nussz)MIf3!uf*+M#C`&PaGp6u&k=3@o>z+S za?G&3;yRtV#s;C`!{gvio2%YVFxBWFG@N*@;yoL~Im?rwmU&nUPgw@rR92PAx1rXr zSr3nkQXH@$pmbKzjZ)!&Vj9P8k55=B$Svz_x{Xz`N5 zY#Lb=jTP|ZHmDfDhx}}^*eZ*eR>=-n8;^rnnlO%!Ic?e+I?7PDRC)st*ww7HTf`{Qxopei@U8P*7-ZbZ>KLZ*U+lnSp_Ufq@}0xwybFAi#%#fq@|}KQEO56)-X|e7nZL z$iTqBa9P*U#mSX{G{Bl%P*lRez;J+pfx##xwK$o9f#C}S14DXwNkIt%17i#W1A|CX zc0maP17iUL1A|C*NRTrF17iyV0~1e4YDEbH0|SF|enDkXW_m`6f}y3QrGjHhep0GJ zaAk2xYHqQDXI^rCQ9*uDVo7QW0|Nup4h9AW240u^5(W3f%sd4n162kpgNVo|1qcff zJ_s=cNG>fZg9jx8g8+j9g8_pBLjXe}Lp{R+hNBE`7{wV~7)u#fFy3PlV+vxLz;uCG zm^qSpA@ds+OO_6nTdaDlt*rOhEZL^9ePa)2-_4=K(Z%tFGm-NGmm}8}ZcXk5JW@PU zd4+f<@d@)yL(o<5icqT158+-B6_LH7;i6x}CW#w~Uy-Pgl#@Irl`kzV zeL|*8R$ca%T%Wv){2zs_iiJvgN^h0dsuZZ2sQy$tsNSU!s;Q*;LF<6_B%M@UD?LHI zSNcZ`78uqV#TeU~$eS{ozBIdFzSClfs*^S+dw;4dus<{M;#|MXC)T}S9v!D zcV!QCPhBq)ZyO(X-(bH4|NMaZz==UigLj2o41F2S6d@OB6%`R(5i>J(Puzn9wnW{e zu;hl6HK{k#IWjCVGqdJqU(99Cv(K+6*i`tgSi2;vbXD1#3jNBGs$DgVwO(~o>mN4i zHPtkqZIx>)Y(Ls5-Br|mx>vQYvH$Kwn@O`L|D75??eGkZnfg$5<;Xeg_o%+-I&+-3%01W^SH2RkDT>t<8AY({UO#lFTB>(_`g8%^e z{{R4h=>PzAFaQARU;qF*m;eA5Z<1fdMgRa6I!Q!9RCwC#oq2$bW!u2d?2L?k#5<9- zL?n%DC3|)$DPN^R>P00=ueU`DT2+>KBTGiTiTCp*23d+%N*kpK*&<{cVaBZI{JuY? zi8FJabMEUo&vKqKb3K3g!*%Alf6sm2*LGjG3zx&6c*;2b9W)>3{^<$a%tYSdN$%nX zB8Vu(6Dm(6Em^`5GB^WdvzqZ#rd%nWPUedBP^u{l}hp0|FmQ?`4p8r)-i;b zQatuPNh~E7Uy{oY+**pq&ZjI7kd3x%qBU^_E~BM*M9<~?hCj(>A#H>Hl}g;m5Qfo_ zo2XTaNA-zf9GUo+qs%5gh~J2&DQ~iwog5{b??~Z6%2BoyPvECEYw!fXlTR)kbpwiF z06V?(c{s=_dfGFKoQ3BG4x%E9xJKvf?8H_dAApDLOrTjQ9{*1>&MV>hm9a$X(BFiw zaBJv1z>HEn{-4$yRl<|cMlKU;ug(k~{#2p3*+rF7JpP`({EV7pFhCe8jiL`Zes!Ls zS1BHUPqzSO^~Exch9ce7SP{VNaPxX89{+n!rZS!{xJ?vfy@eA2b$(-YT-<5Vw&Tip zjxkxFxgrb63#juvRl^TYWg1YESQ4m8R8X4wDepay$1)O>HMe26g3es}h7X={Br}vL z%;z0aSkFR6(>f@P-Pw=2Y^9B|Sui4?yIU}Oo(m5=5hO91RqP`DuP+bMNzvtxT<}ZI z3h?Y) z&c{=i4>ZI6pU_RW-Y#qt;K}6`rPy06LzLzYzpug#2<9lS^RW`Vo;}0Qj`qgYJ9D%aW5U5ji(Gl19%V~7Sc$U z?n^~`kDK+1b8@e;&K#OsX&e}@GMXg;UvfVqbXjo8Y!%?~uuNeYjbs=Z0z5sOji-vj zQjyOZrCp)u)0Y2=7PpraN~%>n<;dxj{NlE9h(?vIev19h75jJDz45RcJ-!dj{+9r~WG%%GVT1 zIBw^NKxY;`oxS(8p#Ma)_bi}ZK%eIhrD$8B9Au!g7q{Mui-nt`R1toO zb@@z$XEm(?+HG%(@a&_Lv+=a&CuPHTps;?dEW1U6nMV77cH76w0iA-FM{Q^0N#dCD z%f2go*-ESz&7QNg53rFp=2MZzJv4PTo@jybn?`%l@>Z9{$mEUyb<)?0Y(ZGh)y~F~ zz=s0c>S59HR*R*g!OY{I0fM)^6)Wcom*Z5YClo64yeMedM4&rfF>Q9i41PO+#-{|u zC6LcTYfmj0uQHx{1TXwOcM5dJvQlIk73xYUondh8Kt+ebg=mx458 zj%aziNl^Rqp`R*fUyIQizl&Qx{t)3gOatfRslYR$SAJYjVzO9>XQQ9IY!q*hCBpNW z)kW~;)EW#IxTcvbRn~k7vxJM=QvRl?tv<_z+9n23WfVe{I=w_$%>&d>)SJju;ee)S z;)&o&;nMa8^0N7n z$WO^9Rnt$2XQl`>?6x)>YG#$_U_r@KK3^%jymN$$+k6r=bk$*{P}f3DU5=}@-Lt5PkA0yIL>r&VMwgfqWQnVkmzipHPRk$Db_?>sLi`PeDFllmqUV=|4AuOpTPUV z#qFOOmRn8!Bh<8j%He~@MN8HQUOtEGG`{nTpW37d2X(YY3$bhXMWiQ(v34{gGf(y9 zOc4#hD24e`nYE&X!YRgSR^#Oem$sX&hhrw5cp2y6j2%u z_65~ODFpFE(1~9K1F)B-0qYLxuu3$jZaVt32oqT#TqGx39c?okkBgR~DwrGw1gtx_ zMzo*7F^xVRSMr_Es2*Ym9CPtB5cxjvQo!Y{hH?#Ef$Y%mRoaSnFh~ar;gC~NKqAIe(+#Voo(phx$7xqxyr~UVyX!hhW zTEXbI3{T{re@s-+wfMJ**7!Uo2gpWt7a1Gysn4RpCW^=83*|RD+tp*UhZe<*g z(2jOA4GK~VVI|B;zkNI+X(tNlz{frcK_a+Ww6wt*>k|pS@x;=NR3ML293r26e8ha( z(@@Zz#yjsbRkZu;W`y6x@-9(+)597cW_1M5i~go;W?EZ3rHv<<4aHo^b7ZiFTd1h( z2Oi~j!BAwd$Zu$L9H&HHPl}I7Lh>#ZyaY- z5gqMCJq+Nu-S+``=ik*lf-T%DYWQ`fFwUIIFI?hd#UH~Nk)A9DdD)sVOc&-z4+ZRt zU?H9urYa3U7MtlRIy5y~xV(AjRqO+ZVxq9N#!Y`OL#B-|pbCqvZ_Dq`ExljSWy@w0 zmn*NzaomYiUMS{mBr;j3<23hsr8k}y7VYNoq+N*w-*{RJj#RuzW97ucrNV)M)x|8P z7~T}loK{;Hwp9zAgzg`rEgmfQ;RsRwi#pf@|A64O9 z@h5V`j>c@T2hMRUb4PY3o12WL%@%CbwvC*!gi^{4%p%trCt$>TY@cb?*SqWB+yZ{XoW zZcs|}Ca^^~Kqr{#b&4|MnmU1oP)4Gr2_J zkGWTvXDO%^=s`RYxJY24&@ccG)9A+s!qeA<@`Im4!@)o0s7hTr(2K5&;1RCp5?|>W z-)D2?iWY-R?pN4EuVuA(i1Jv)ST3b84-4bo1+tAFb;5zUCf(H&K_czAo6*c?Bis3n zUrFOX45U`^z0Q|{7EIVoBmV6eJO`C;&Qh5-^%=n`(gUmm9`-TD+aS?aT8nYQ zZPm^DesA_H!(`nXwbk-DEexAEb$FI&Krh`#!3dV zT+kZE!v<EF5qR~CqcdL%TWe+W4MTDH*o9se zM&9g^9OeZ*cWz{(*tAM3>OHFcRBx7uJ^q~xr*^T^qC<5BXRMYyUJmlWRU&J}R%#xp z)K_y$i+VvlMRDu`ImQgS7V(5yI|2{jnix#;mf+ouLNj?*U>OR#+2OJOUxW4F|RsYEt?jcQBF#!1-U@^6+_UG%yi`rP) zCE3gj0#13sO^z4#o&Ag|Ztu!+6i?~M*+2$+d7Lg(z(oylR~$Pem$!qMJ#Xj;;+|y@ z4U4Dbq_Ly%;`viBaWh!UG;X97?>b`ddCPBma(_<~aa99&_=y3&BL31XuNJF?g|HW< z?`y_GQQP<#R8BKjJrt&|a zGGl}{S36OT2(L{mjIkXT|57%e(_1SMqvs20$XhzrS7*ryT?vIZbj+N6jHasA2|PV` zVyVtv$7F8w$zdJ0swRqV(kisrruaL5r#Fu=j-SIC&q*eVM`e=uS29^bQ-7y*_1gAL znI6`7vUy*4eCwPn+{y&0X61B6$CuW=^ z+vqRK?wl3QoKw6;QlK^j!351a>8Sg3jvVDh!B}(=n*{Sz;u68&sl-DL$$jdP96lA~ zeA0xv*U?So@Mmy!D0TQYj6I+|v{W34`eMxwsa@wDT*5Y*XLX!9bBbj0q+;A!7Us=m z2KCgM-vpmgPYqi<9yTZ)Uo0z1^k?t^SF3g=3KmZl9@dp&aE9d3T_N^1M4&OBAGk&R z>_hOiT(#Jz>-3p3WQM{SIY~R)Q%nlv>llfrVC4;8|7Tmk{_l-NbLUgqNLsELf#+^v z%X?>;2P*;$r{ub{!;F-bHyVMb3G>3(Jmm6#nk# z-Mb3xz!N;FbV%A@JT6+YBaHFv^4Uwi;KYTbD}5SmrS(6?;7Md=7~}Eqo=^WLS=8G! zmj%?5_9Zn2Pc*kUsLVqyxhySq9ILOe@$50iYMy&C8IOxZ9c8P|nnCZ=g0fU3ntI&9 z9AVK%Hp^%r@9AsY>EpFw96c!TS=KR~t-4%r55F=*Pt#cA@H`_-NI7wdJFC+|&EZ3? z(sNOUadL}+&s{0RP3am-W!07 z#4|RmOGESrg=XtM?O-ULj*d9iYxUgufu8!CUK)ufzI65!le0{tmi{|TjBSavsg#G8 zxcQE5!JP3n5>E`Tl@cj3ccxIy*jBIlpI9Bu_``edd{5V)PIw!NCz9)Rw4)4Xn{A55 zMNzikad88?N~!#1vwcCQU>lVii>Hm!1x+PGPBAI?UcScSxymsO!ORbzuBVw9UEqWB zd_E5QQ>SWjg7LZz51Wc7f<>jq0pMnXysp3sJQKq_DW@hUc|z?3g0*uJIZKp=x67WzMpZ8IdJXR>*s%JT#VGikbXr3Hln7m-hDm>kU zSHFgvWV1x8eNiajxw1t2Js$Qk+z5ZiEIiHmr3B+S&q7~44MPV{OJQkic+H*N^f&fW zCZq9O#YZLB-q07D5P51P?gkep3DEgU`6xOpDE2JT5wf^+}&&j4&&VV-23VycxD|@_5Ur zB3--i#B-m{3p7LD+nHl@MS=BrT(k+(bEf-(Kav;uECZ0&@axSdkq|?M&IA-E;;UYC`Za4L?otjp|F&ocl4uuJvFO4rTv>#6^UH7kt znz-4j^Mdmb$5Vmnj<2}RW{y=(sMUB}-0ASDx8qE)&Iz?1&sDtVU^r)Z(!4T{P{323 zfetOJ%H>=0>eoUAPb6j7??6D=tfUKN?1f`K9v3dAIsHlNrLNPV;yqRLlW8@I+FXH#r`X)o*UTq(dl}(e~kS;i4JS zLofoD#V540J30^wcw%V6BzA^a-OWmpLv!X>jmJe4br{EiklBOI@`m|!($2x-!bL4c zvp)o?5ZvtKaeH#0p^V2xBK=v;QJeAXVHlOnJ)PrBJTA)9k!kF;(E(jg+tA%{?8Xy8 zG>sX{HqP15;w7C~Gz@(-_TedbYSNDn`Pt%Pt2}0eUUVQ7@wkYm5o7q6QrSJ;4S>+Eo(eR6H(RROcq%WCJHmtQ^?QWI9nb)NQp;#N#58 zB>FI(%^WrS=K8~|WDK>PgeBDQxNs3i4eIeQ^Z63U3c7$Xhhu!pdpt-oRh(c(hc=#q zS>&P-H}g23u$AA)*Rdmc@Q}-C*6=u;~oampP>w;AFXLmCt3t|`Ee;8tri-left.png tri-right.png tri-up.png + hand.png + hand-disabled.png diff --git a/mainwindow.cpp b/mainwindow.cpp index adc24850e..43a9d7cbe 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -607,7 +607,11 @@ void MainWindow::on_actionToggle_Snapping_triggered() void MainWindow::on_actionPointer_Tool_triggered() { - if (panel_timeline->focused()) panel_timeline->ui->toolArrowButton->click(); + if (panel_timeline->focused() + || panel_effect_controls->keyframe_focus() + || panel_footage_viewer->is_focused() + || panel_sequence_viewer->is_focused()) + panel_timeline->ui->toolArrowButton->click(); } void MainWindow::on_actionRazor_Tool_triggered() @@ -1061,3 +1065,11 @@ void MainWindow::on_actionMilliseconds_triggered() { void MainWindow::on_actionEnable_Hover_Focus_triggered() { config.hover_focus = !config.hover_focus; } + +void MainWindow::on_actionHand_Tool_triggered() { + if (panel_timeline->focused() + || panel_effect_controls->keyframe_focus() + || panel_footage_viewer->is_focused() + || panel_sequence_viewer->is_focused()) + panel_timeline->ui->toolHandButton->click(); +} diff --git a/mainwindow.h b/mainwindow.h index 048c30a7b..a1b380542 100644 --- a/mainwindow.h +++ b/mainwindow.h @@ -213,6 +213,8 @@ private slots: void on_actionEnable_Hover_Focus_triggered(); + void on_actionHand_Tool_triggered(); + private: Ui::MainWindow *ui; void setup_layout(bool reset); diff --git a/mainwindow.ui b/mainwindow.ui index 6533a2453..fe24d5e23 100644 --- a/mainwindow.ui +++ b/mainwindow.ui @@ -176,6 +176,7 @@ + @@ -948,6 +949,14 @@ F11 + + + Hand Tool + + + H + + diff --git a/panels/timeline.cpp b/panels/timeline.cpp index b4c1abf0c..33fd1c9b9 100644 --- a/panels/timeline.cpp +++ b/panels/timeline.cpp @@ -69,6 +69,8 @@ Timeline::Timeline(QWidget *parent) : transition_tool_proc(false), transition_tool_pre_clip(-1), transition_tool_post_clip(-1), + hand_moving(false), + block_repaints(false), ui(new Ui::Timeline), last_frame(0), scroll(0) @@ -102,6 +104,7 @@ Timeline::Timeline(QWidget *parent) : tool_buttons.append(ui->toolRollingButton); tool_buttons.append(ui->toolSlideButton); tool_buttons.append(ui->toolTransitionButton); + tool_buttons.append(ui->toolHandButton); ui->toolArrowButton->click(); @@ -420,42 +423,44 @@ bool Timeline::focused() { } void Timeline::repaint_timeline() { - bool draw = true; + if (!block_repaints) { + bool draw = true; - if (sequence != NULL - && !ui->horizontalScrollBar->isSliderDown() - && !ui->horizontalScrollBar->is_resizing() - && panel_sequence_viewer->playing - && !zoom_just_changed) { - // auto scroll - if (config.autoscroll == AUTOSCROLL_PAGE_SCROLL) { - int playhead_x = panel_timeline->getTimelineScreenPointFromFrame(sequence->playhead); - if (playhead_x < 0 || playhead_x > (ui->editAreas->width() - ui->videoScrollbar->width())) { - ui->horizontalScrollBar->setValue(getScreenPointFromFrame(zoom, sequence->playhead)); - draw = false; - } - } else if (config.autoscroll == AUTOSCROLL_SMOOTH_SCROLL) { - if (center_scroll_to_playhead(ui->horizontalScrollBar, zoom, sequence->playhead)) { - draw = false; + if (sequence != NULL + && !ui->horizontalScrollBar->isSliderDown() + && !ui->horizontalScrollBar->is_resizing() + && panel_sequence_viewer->playing + && !zoom_just_changed) { + // auto scroll + if (config.autoscroll == AUTOSCROLL_PAGE_SCROLL) { + int playhead_x = panel_timeline->getTimelineScreenPointFromFrame(sequence->playhead); + if (playhead_x < 0 || playhead_x > (ui->editAreas->width() - ui->videoScrollbar->width())) { + ui->horizontalScrollBar->setValue(getScreenPointFromFrame(zoom, sequence->playhead)); + draw = false; + } + } else if (config.autoscroll == AUTOSCROLL_SMOOTH_SCROLL) { + if (center_scroll_to_playhead(ui->horizontalScrollBar, zoom, sequence->playhead)) { + draw = false; + } } } - } - zoom_just_changed = false; + zoom_just_changed = false; - if (draw) { - ui->headers->update(); - ui->video_area->update(); - ui->audio_area->update(); + if (draw) { + ui->headers->update(); + ui->video_area->update(); + ui->audio_area->update(); - if (sequence != NULL) { - long sequenceEndFrame = sequence->getEndFrame(); + if (sequence != NULL) { + long sequenceEndFrame = sequence->getEndFrame(); - set_sb_max(); + set_sb_max(); - if (last_frame != sequence->playhead) { - ui->audio_monitor->update(); - last_frame = sequence->playhead; + if (last_frame != sequence->playhead) { + ui->audio_monitor->update(); + last_frame = sequence->playhead; + } } } } @@ -1605,3 +1610,10 @@ void move_clip(ComboAction* ca, Clip *c, long iin, long iout, long iclip_in, int } } } + +void Timeline::on_toolHandButton_clicked() { + decheck_tool_buttons(sender()); + ui->timeline_area->setCursor(Qt::OpenHandCursor); + tool = TIMELINE_TOOL_HAND; + creating = false; +} diff --git a/panels/timeline.h b/panels/timeline.h index a9633e723..d3ae3a7d1 100644 --- a/panels/timeline.h +++ b/panels/timeline.h @@ -185,6 +185,13 @@ public: const EffectMeta* transition_tool_meta; int transition_tool_side; + // hand tool variables + bool hand_moving; + int drag_x_start; + int drag_y_start; + + bool block_repaints; + Ui::Timeline *ui; void resizeEvent(QResizeEvent *event); @@ -227,6 +234,8 @@ private slots: void resize_move(double d); + void on_toolHandButton_clicked(); + private: void set_zoom_value(double v); QVector tool_buttons; diff --git a/panels/timeline.ui b/panels/timeline.ui index aadfdb639..03c6daf0b 100644 --- a/panels/timeline.ui +++ b/panels/timeline.ui @@ -194,6 +194,22 @@ + + + + + + + + :/icons/hand.png + :/icons/hand-disabled.png + + + + true + + + diff --git a/ui/keyframeview.cpp b/ui/keyframeview.cpp index 88d10713f..c46dcb0c2 100644 --- a/ui/keyframeview.cpp +++ b/ui/keyframeview.cpp @@ -34,7 +34,8 @@ KeyframeView::KeyframeView(QWidget *parent) : keys_selected(false), select_rect(false), x_scroll(0), - y_scroll(0) + y_scroll(0), + scroll_drag(false) { setFocusPolicy(Qt::ClickFocus); setMouseTracking(true); @@ -193,12 +194,20 @@ void KeyframeView::resize_move(double d) { header->update_zoom(header->get_zoom()*d); } -void KeyframeView::mousePressEvent(QMouseEvent *event) { +void KeyframeView::mousePressEvent(QMouseEvent *event) { + rect_select_x = event->x(); + rect_select_y = event->y(); + + if (panel_timeline->tool == TIMELINE_TOOL_HAND || event->buttons() & Qt::MiddleButton) { + scroll_drag = true; + return; + } + + int mouse_x = event->x() + x_scroll; + int mouse_y = event->y(); int row_index = -1; int keyframe_index = -1; long frame_diff = 0; - int mouse_x = event->x() + x_scroll; - int mouse_y = event->y(); long frame_min = getFrameFromScreenPoint(panel_effect_controls->zoom, mouse_x-KEYFRAME_SIZE); drag_frame_start = getFrameFromScreenPoint(panel_effect_controls->zoom, mouse_x); long frame_max = getFrameFromScreenPoint(panel_effect_controls->zoom, mouse_x+KEYFRAME_SIZE); @@ -235,9 +244,6 @@ void KeyframeView::mousePressEvent(QMouseEvent *event) { if (selected_rows.size() > 0) { keys_selected = true; - } else { - rect_select_x = event->x(); - rect_select_y = event->y(); } update(); @@ -248,7 +254,17 @@ void KeyframeView::mousePressEvent(QMouseEvent *event) { } void KeyframeView::mouseMoveEvent(QMouseEvent* event) { - if (mousedown) { + if (panel_timeline->tool == TIMELINE_TOOL_HAND) { + setCursor(Qt::OpenHandCursor); + } else { + unsetCursor(); + } + if (scroll_drag) { + panel_effect_controls->ui->horizontalScrollBar->setValue(panel_effect_controls->ui->horizontalScrollBar->value() + rect_select_x - event->pos().x()); + panel_effect_controls->ui->verticalScrollBar->setValue(panel_effect_controls->ui->verticalScrollBar->value() + rect_select_y - event->pos().y()); + rect_select_x = event->pos().x(); + rect_select_y = event->pos().y(); + } else if (mousedown) { int mouse_x = event->x() + x_scroll; if (keys_selected) { // move keyframes @@ -332,6 +348,7 @@ void KeyframeView::mouseReleaseEvent(QMouseEvent*) { select_rect = false; dragging = false; mousedown = false; + scroll_drag = false; panel_timeline->snapped = false; update(); } diff --git a/ui/keyframeview.h b/ui/keyframeview.h index e565d6e61..6c3a72f31 100644 --- a/ui/keyframeview.h +++ b/ui/keyframeview.h @@ -39,7 +39,8 @@ private: bool mousedown; bool dragging; bool keys_selected; - bool select_rect; + bool select_rect; + bool scroll_drag; bool keyframeIsSelected(EffectRow* row, int keyframe); diff --git a/ui/timelinewidget.cpp b/ui/timelinewidget.cpp index 0506995af..e96b87fc2 100644 --- a/ui/timelinewidget.cpp +++ b/ui/timelinewidget.cpp @@ -698,7 +698,12 @@ void TimelineWidget::mousePressEvent(QMouseEvent *event) { update_ui(false); } } - break; + break; + case TIMELINE_TOOL_HAND: + panel_timeline->hand_moving = true; + panel_timeline->drag_x_start = pos.x(); + panel_timeline->drag_y_start = pos.y(); + break; case TIMELINE_TOOL_EDIT: if (config.edit_tool_also_seeks) panel_sequence_viewer->seek(panel_timeline->drag_frame_start); panel_timeline->selecting = true; @@ -1134,6 +1139,7 @@ void TimelineWidget::mouseReleaseEvent(QMouseEvent *event) { panel_timeline->rect_select_proc = false; panel_timeline->transition_tool_init = false; panel_timeline->transition_tool_proc = false; + panel_timeline->hand_moving = false; pre_clips.clear(); post_clips.clear(); @@ -1630,6 +1636,16 @@ void TimelineWidget::mouseMoveEvent(QMouseEvent *event) { } else { panel_timeline->repaint_timeline(); } + } else if (panel_timeline->hand_moving) { + panel_timeline->block_repaints = true; + panel_timeline->ui->horizontalScrollBar->setValue(panel_timeline->ui->horizontalScrollBar->value() + panel_timeline->drag_x_start - event->pos().x()); + scrollBar->setValue(scrollBar->value() + panel_timeline->drag_y_start - event->pos().y()); + panel_timeline->block_repaints = false; + + panel_timeline->repaint_timeline(); + + panel_timeline->drag_x_start = event->pos().x(); + panel_timeline->drag_y_start = event->pos().y(); } else if (panel_timeline->moving_init) { if (track_resizing) { int diff = track_resize_mouse_cache - event->pos().y(); @@ -2603,7 +2619,11 @@ void TimelineWidget::paintEvent(QPaintEvent*) { p.setPen(Qt::gray); p.drawLine(cursor_x, cursor_y, cursor_x, cursor_y + panel_timeline->calculate_track_height(panel_timeline->cursor_track, -1)); } - } + } +} + +void TimelineWidget::resizeEvent(QResizeEvent *event) { + scrollBar->setPageStep(height()); } bool TimelineWidget::is_track_visible(int track) { diff --git a/ui/timelinewidget.h b/ui/timelinewidget.h index 20e4bfea9..63d7ee067 100644 --- a/ui/timelinewidget.h +++ b/ui/timelinewidget.h @@ -33,6 +33,8 @@ public: protected: void paintEvent(QPaintEvent*); + void resizeEvent(QResizeEvent *event); + void mouseDoubleClickEvent(QMouseEvent *event); void mousePressEvent(QMouseEvent *event); void mouseReleaseEvent(QMouseEvent *event); diff --git a/ui/viewerwidget.cpp b/ui/viewerwidget.cpp index 05156f77f..f84c27b6f 100644 --- a/ui/viewerwidget.cpp +++ b/ui/viewerwidget.cpp @@ -258,7 +258,7 @@ void ViewerWidget::move_gizmos(QMouseEvent *event, bool done) { void ViewerWidget::mousePressEvent(QMouseEvent* event) { if (waveform) { seek_from_click(event->x()); - } else if (event->buttons() & Qt::MiddleButton) { + } else if (event->buttons() & Qt::MiddleButton || panel_timeline->tool == TIMELINE_TOOL_HAND) { container->dragScrollPress(event->pos()); } else { drag_start_x = event->pos().x(); @@ -277,10 +277,14 @@ void ViewerWidget::mousePressEvent(QMouseEvent* event) { } void ViewerWidget::mouseMoveEvent(QMouseEvent* event) { + unsetCursor(); + if (panel_timeline->tool == TIMELINE_TOOL_HAND) { + setCursor(Qt::OpenHandCursor); + } if (dragging) { if (waveform) { seek_from_click(event->x()); - } else if (event->buttons() & Qt::MiddleButton) { + } else if (event->buttons() & Qt::MiddleButton || panel_timeline->tool == TIMELINE_TOOL_HAND) { container->dragScrollMove(event->pos()); } else if (gizmos == NULL) { QDrag* drag = new QDrag(this); @@ -293,7 +297,6 @@ void ViewerWidget::mouseMoveEvent(QMouseEvent* event) { move_gizmos(event, false); } } else { - unsetCursor(); EffectGizmo* g = get_gizmo_from_mouse(event->pos().x(), event->pos().y()); if (g != NULL) { if (g->get_cursor() > -1) { @@ -304,7 +307,7 @@ void ViewerWidget::mouseMoveEvent(QMouseEvent* event) { } void ViewerWidget::mouseReleaseEvent(QMouseEvent *event) { - move_gizmos(event, true); + if (dragging) move_gizmos(event, true); dragging = false; }