From 7ab45c099d247d9c95d5725c7d0e27cd41095ff3 Mon Sep 17 00:00:00 2001 From: Valeriy Kamyshniy Date: Wed, 28 May 2014 08:49:09 -0500 Subject: [PATCH] [Summary] Implementing zoom faders for tool bar [git-p4: depot-paths = "//Abdaw/dev_main/tracks/": change = 464239] --- .../icons/horizontal_zoom_fader_face.png | Bin 0 -> 1329 bytes gtk2_ardour/icons/tool_waveform_zoom.png | Bin 637 -> 493 bytes .../icons/tool_waveform_zoom_active.png | Bin 710 -> 515 bytes .../icons/tool_waveform_zoom_prelight.png | Bin 666 -> 314 bytes ..._face.png => vertical_zoom_fader_face.png} | Bin 1137 -> 1277 bytes gtk2_ardour/ui/editor_window.xml | 17 ++ gtk2_ardour/ui/session_dialog.xml | 10 - gtk2_ardour/waves_ui.cc | 19 +- libs/gtkmm2ext/fader.cc | 185 ++++++++++++++---- libs/gtkmm2ext/gtkmm2ext/fader.h | 2 + 10 files changed, 181 insertions(+), 52 deletions(-) create mode 100644 gtk2_ardour/icons/horizontal_zoom_fader_face.png rename gtk2_ardour/icons/{zoom_fader_face.png => vertical_zoom_fader_face.png} (70%) diff --git a/gtk2_ardour/icons/horizontal_zoom_fader_face.png b/gtk2_ardour/icons/horizontal_zoom_fader_face.png new file mode 100644 index 0000000000000000000000000000000000000000..37e503c07180fc7b39bd973cba5631a3c831ad82 GIT binary patch literal 1329 zcmbVMeP|nH7{8+H>PjJ9hihx0w<`=QP40a!UzeljmgKS|CF$BUb1m56_41}U+q;W* zSCf=YL1%1>;9xSQ(}67=-5={d@PkcsIMA|!LIqvHt>~Z(S9E`@qRx%^UfWdvDEq^M z_ul7u?)g36&y9AphpV>KZy^YxDjE?I_-@0ezM>qzZ3kwH_$o6J;Q%rHZNo2^dA#2r z_Y=hVw=3_9n=t=GHqv7d#8%TfWee%XJQmiOp>DHFOPe`SM}$A6^&v8 ztEiPA9?QtdZnHZc<0MUSh?b5cuVgWrAX<0jv!XPBOtKI4%PLRZ`Rp=9$|;`O?~a3b zHi$BEWLQUC!|h3FctG-{s9n#Jt$7X`P>?B-d1X*FxI9m-*yS*7iD`;lQ85R2YBi|t zcn2BObVRxxz%Bs~Bt0$%bOE2s*FrJ?0va+j@Y*5Z++Geqa_yn8H$9c+62hJ}Uzp>m zjA>>$n$G2Nj-1n>>HReH`Fu2BXoj(44ZBfLO)+m*ji!xNZhtx&jRbY9HT&;e*gvGQ8cHp~S2H;fInjbtH<=mavfAzi}#NH>+h zxOR_rWGUikxV^fJn<5Shnlz*!)r<-}g}*pbatfD-1rT~&z{>y+3!#q*0Dk~r)(6<2 z*Hf~w5teZWStkSm!5i>E7;*;u&=q1~fbj|;$UBco->V3*qg$+#%VswJ@+w3@GgbophJ+M{ayVcvKM&TxfZUY!yad{PDT4_}2d3H#Uzvy^|Un9qFUSkC#ZM zdG&d{`(|&?`1HVokLs@T6Ok*o(i4Z5XC`iUPR1TIN54G#eg2#I>(0wY zdKokp%l7U2kZ(wyYJ2zIPUf!y`TUW_Tr3rW)txb6TTS&>g0M0fhej1nmQmdw*R?L_t(YOWl@@ZG$ing>l3V=}x4nfCc!e0-b^#%1=tRXquH+ z1F9pw%8&=OWJs!h(v#0;bAEA*g~+n3v;F`g2m)gxU1$DVHdMq^3>wqbB1TwKpt)l$ zY6PimTbLhfLlf5&S`=yZ9nsbQG!g~@%DB%=%MJ*am~rYI=3i~Eh(cjvZNkvgm?KNM$q59`Zp_*YU--a Z`UddTHFyPVq!0iA002ovPDHLkV1fZFwl)9& delta 525 zcmV+o0`mRs1N{V$dw=aoL_t(YOYN0iO9DX@hF?=r{8-cwL>G#>E%3s^pswoH{*eEw zenXL&8U=afMM|QGg6OK5AI&+<(zXPvX4J(#H#2jbne(2HSsmGIc8-4l3+Z;da`|^` z$nnpyg_yC0n6VV%a5&@)aJ$`dCJt__HwMewHX{)polYlIRe$AqC=`Mc4Dy_Cxm@si zz3_NE(y~03LXycOd_EuM^EuQ+f}L$|ZLy7rMx!`Nr*U?Aij(7GgoVgeuoOZL_xJXo zC<^?606UGxJs~3>UCZlSy;#_42MHZL;x&9hzW=+5*L@3JQ`VV>zf#jM$r0w z&JK;^w>QjYGx_UR7Rm@6?u(0p;-%hoO&TZkE3h?##P1b7FyR@ZQ}4#edE P00008rN5?62zf-=%JN5DRwz<*)|!8lB)a%3hF=#h~a}dEVJZ%8~`u66Ulm+Wb6xtW( zXT0o7wWEffv$Lv01LG;tc=5~wsWuz#IF(pYNK1&u z4^QrlRF$-J)qizOk|dEee=)Y7K9>g15hfR-Dp6>E?{=Ec6wAf#Q6-Aoj&;%J;Pz#! zY+s`K?LBqvAUtRCEbB_;JBIgxmZzyzM=5_NBeT4p;d2pm*W@4Xy3GTz`}sgG?-vk~ zhx~etkQjLQ(v#P7S2qs4=@8=&f1yDm=TO^(*criv_bUh3m!28e?1(7}+BMT40*YMo cb$VLz1N!ou0gP_WIRF3v07*qoM6N<$f+|bZ7XSbN delta 630 zcmV-+0*U>D1jYrBTYmyoNklzu#jSq4&x)3tIptWHy!N!_7nFcGIZ~v42w+V#iU4APB3LoQ;~s ze2OGV+^Y?aLINGTm{k-RhkAm{_qVrUr_aZHil!*g-EO#DE`FtY9EF@dHVCh-qfoTa zA3T8OrY0Qj>%%s^ncd&t)rAWuPvFw|vluyZ3jQ7KEPB-6ZX z!-&UmVu7(B#_w1(mM8t@qSS<2YoN@fK-nclz zY;I)*DoH_!EEx;rP)W+xBW9X-@ai=pQG<-=OrVpbR8v(dQ_=5qbalD{ek~jK!rTOicbjYGDCyK77Qj zN27=*Q+(DcKO@t)H#Uyjqfgg}pv)(e>x!T_cFjJ&ANOC5v*HYNcHqvFXRJGncmlts zXYeHyLT{t0L6#+iNvGU>F^2FQEzs(4Oiin&g{47}W%LBP@rgu)hFB(lR{IzK500sc zv04D~`8>XbrkGDdOpCCVI0`B4BdIN~c+0Bo4s%1>w;Jj~?9_$W*&;%K-%TCe4V%U! QIsgCw07*qoM6N<$f;5Uah5!Hn diff --git a/gtk2_ardour/icons/tool_waveform_zoom_prelight.png b/gtk2_ardour/icons/tool_waveform_zoom_prelight.png index 5e1b5d83a2e1219ba04853aaee6a084e899cb4b8..a216e719676afff71e9e674f195d1833f6fc141d 100644 GIT binary patch delta 231 zcmVuiQr(3L_{n? zgVOkyfK-qbDGihMVY0vY+#>J3UlfpteH>qrlEpPpF*9!@yI@CBBVJ(c8HMZPU^lBI zI6~*8eHiiQTN);n5sS=$L!^N@R3a3O%&H<9%!s&SceinP_TEF)8iui&FoLZsg^v}- hq1@rxh1uEwd;rcO|Gm1I22ub3002ovPDHLkV1h)4YTy6> delta 586 zcmV-Q0=50R0-6PoTYmy6NklA3d{sR-0C?aT55}R-VA*EVqkQTT5(J!pK&K#$vEKPQc5V+{GyO}d* zcXr-6bIwT5p1*K#2_PYwZiw#15fJT#(-z{UEyRtd5J{4R1%D_?hp^bdz}c?B^KbpJ zUTWo_jGH6Z$?l0p(cRTWHYXSiA{-7Q6bcDX>v#&8nw&(WvlEW(;Ks->O?GQ^lzg1Q zfqvYdox%L0hj?)BE_#{B(;!dG%q~=_Rna}ko$+y~kqC6t#O<*$3=hT87mGnNbQTF2 zbJNo#if^H!D1V3#4lo-yENE~X|A)5c$@=ukV`^))8f`(HU#u^&i;HQ7X<1lHB=A!! z{L8bRXg508Khobb)NjPMkke2sm1qH6Fu$*;D)|>*zM{5~b1mOexeSACsbR5)wbi2| z*tRX+9>-Ti_+Z^IaFta`JBiWJ_z=Fa zi0}~ezC(M(|AS{lxCoB@+eT(@k8B>|y8ol5miBL{Q4GJ0x0000DNk~Le0000=0000Q2nGNE01#fvhOr^e1AqBR zL_t(oNA1@!4uVh&fZ;wCAYo!6Q7(Xj8=GE?8!{^kBPU>EAZYq5IvC#T;Gk*0#I)78 z{81B4(=>NbUN+P?j&!Om0Zrwhp_nujlZIl_P)w{)aU9bomp4=tMQ}Nv?Uc+LswfHw z!_ZF2oT1V*h5c@4cbs@jwHeA71Ak>%()ENlJ};5}g<<-7sJ3ls`#*JE)Aq?3D$jEW zg7>#`Sr!{CGIP^>(96Cg&$=B|Q>ig;E-dO+zthC?*ZXq@h><9#fP_s}O#c N002ovPDHLkV1kt0g|+|y delta 174 zcmey%`H@4hGr-TCmrII^fq{Y7)59eQNLvH36bBoS + + + - diff --git a/gtk2_ardour/waves_ui.cc b/gtk2_ardour/waves_ui.cc index 2d9dc4e03e..89c1d095e8 100644 --- a/gtk2_ardour/waves_ui.cc +++ b/gtk2_ardour/waves_ui.cc @@ -88,21 +88,24 @@ WavesUI::create_widget (const XMLNode& definition, const XMLNodeMap& styles, Wid dbg_msg("Fader's handlesource NOT SPECIFIED!"); throw std::exception(); } + std::string active_handle_image = xml_property (definition, "activehandlesource", styles, handle_image); + if (handle_image.empty()) { + dbg_msg("Fader's handlesource NOT SPECIFIED!"); + throw std::exception(); + } std::string adjustment_id = xml_property (definition, "adjustment", styles, ""); if (adjustment_id.empty()) { dbg_msg("Fader's adjustment_id NOT SPECIFIED!"); throw std::exception(); } + int minposx = xml_property (definition, "minposx", styles, -1); + int minposy = xml_property (definition, "minposy", styles, -1); + int maxposx = xml_property (definition, "maxposx", styles, minposx); + int maxposy = xml_property (definition, "maxposy", styles, minposy); Gtk::Adjustment& adjustment = named_widgets.get_adjustment(adjustment_id.c_str()); - child = manage (new Gtkmm2ext::Fader(adjustment, - face_image, - handle_image, - xml_property (definition, "minposx", styles, -1), - xml_property (definition, "minposy", styles, -1), - xml_property (definition, "maxposx", styles, -1), - xml_property (definition, "maxposy", styles, -1))); + child = manage (new Gtkmm2ext::Fader(adjustment, face_image, handle_image, active_handle_image, minposx, minposy, maxposx, maxposy)); } else if (widget_type == "ADJUSTMENT") { - dbg_msg("Creating ADJUSTMENT"); + //dbg_msg("Creating ADJUSTMENT"); double min_value = xml_property (definition, "minvalue", styles, 0.0); double max_value = xml_property (definition, "maxvalue", styles, 100.0); double initial_value = xml_property (definition, "initialvalue", styles, min_value); diff --git a/libs/gtkmm2ext/fader.cc b/libs/gtkmm2ext/fader.cc index 3b58102f0d..83241cae69 100755 --- a/libs/gtkmm2ext/fader.cc +++ b/libs/gtkmm2ext/fader.cc @@ -40,9 +40,33 @@ using namespace std; #define CORNER_OFFSET 1 #define FADER_RESERVE 5 + +static void get_closest_point_on_line(double xa, double ya, double xb, double yb, double xp, double yp, double& xl, double& yl ) +{ + // Finding the vector from A to B + // This step can be combined with the next + double a_to_b_x = xb - xa; + double a_to_b_y = yb - yb; + + // The vector perpendicular to a_to_b; + // This step can also be combined with the next + double perpendicular_x = -a_to_b_y; + double perpendicular_y = a_to_b_x; + + // Finding Q, the point "in the right direction" + // If you want a mess, you can also combine this + // with the next step. + double xq = xp + perpendicular_x; + double yq = yp + perpendicular_y; + + xl = ((xa*yb - ya*xb)*(xp - xq) - (xa-xb)*(xp*yq - yp*xq)) / ((xa - xb)*(yp-yq) - (ya - yb)*(yp-yq)); + yl = ((xa*yb - ya*xb)*(yp - yq) - (ya-yb)*(xp*yq - yp*xq)) / ((xa - xb)*(yp-yq) - (ya - yb)*(yp-yq)); +} + Fader::Fader (Gtk::Adjustment& adj, const std::string& face_image_file, const std::string& handle_image_file, + const std::string& active_handle_image_file, int min_pos_x, int min_pos_y, int max_pos_x, @@ -53,6 +77,7 @@ Fader::Fader (Gtk::Adjustment& adj, , _max_pos_x (max_pos_x) , _max_pos_y (max_pos_y) , _default_value (adjustment.get_value()) + , _dragging (false) { PBD::Searchpath spath(ARDOUR::ardour_data_search_path()); @@ -71,6 +96,11 @@ Fader::Fader (Gtk::Adjustment& adj, } else { throw failed_constructor(); } + if (PBD::find_file_in_search_path (spath, active_handle_image_file, data_file_path)) { + _active_handle_pixbuf = Gdk::Pixbuf::create_from_file (data_file_path); + } else { + throw failed_constructor(); + } update_unity_position (); @@ -98,10 +128,17 @@ Fader::on_expose_event (GdkEventExpose* ev) get_handle_position (_last_drawn_x, _last_drawn_y); cairo_rectangle (cr, 0, 0, get_width(), get_height()); - gdk_cairo_set_source_pixbuf (cr, - _handle_pixbuf->gobj(), - _last_drawn_x - _handle_pixbuf->get_width()/2.0, - _last_drawn_y - _handle_pixbuf->get_height()/2.0); + if (_dragging) { + gdk_cairo_set_source_pixbuf (cr, + _active_handle_pixbuf->gobj(), + _last_drawn_x - _active_handle_pixbuf->get_width()/2.0, + _last_drawn_y - _active_handle_pixbuf->get_height()/2.0); + } else { + gdk_cairo_set_source_pixbuf (cr, + _handle_pixbuf->gobj(), + _last_drawn_x - _handle_pixbuf->get_width()/2.0, + _last_drawn_y - _handle_pixbuf->get_height()/2.0); + } cairo_fill (cr); return true; @@ -132,11 +169,35 @@ Fader::on_button_press_event (GdkEventButton* ev) return false; } + double hx; + double hy; + get_handle_position (hx, hy); + + double hw = _handle_pixbuf->get_width(); + double hh = _handle_pixbuf->get_height(); + + if ((ev->x < (hx - hw/2)) || (ev->x > (hx + hw/2)) || (ev->y < (hy - hh/2)) || (ev->y > (hy + hh/2))) { + return false; + } + + double ev_pos_x; + double ev_pos_y; + + get_closest_point_on_line(_min_pos_x, _min_pos_y, + _max_pos_x, _max_pos_y, + ev->x, ev->y, + ev_pos_x, ev_pos_y ); + _grab_loc_x = ev_pos_x; + _grab_loc_y = ev_pos_y; + add_modal_grab (); - _grab_start_x = _grab_loc_x = ev->x; - _grab_start_y = _grab_loc_y = ev->y; + + _grab_start_x = _grab_loc_x = ev_pos_x; + _grab_start_y = _grab_loc_y = ev_pos_y; + _grab_window = ev->window; _dragging = true; + gdk_pointer_grab(ev->window,false, GdkEventMask (Gdk::POINTER_MOTION_MASK | Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_RELEASE_MASK), NULL, @@ -146,6 +207,8 @@ Fader::on_button_press_event (GdkEventButton* ev) if (ev->button == 2) { set_adjustment_from_event (ev); } + + queue_draw(); return true; } @@ -153,6 +216,62 @@ Fader::on_button_press_event (GdkEventButton* ev) bool Fader::on_button_release_event (GdkEventButton* ev) { + if (_dragging) { //temp + remove_modal_grab(); + _dragging = false; + gdk_pointer_ungrab (GDK_CURRENT_TIME); + queue_draw (); + } + /* + double const ev_pos_x = ev->x; + double const ev_posyx = ev->y; + + switch (ev->button) { + case 1: + if (dragging) { + remove_modal_grab(); + dragging = false; + gdk_pointer_ungrab (GDK_CURRENT_TIME); + + if (!_hovering) { + Keyboard::magic_widget_drop_focus(); + queue_draw (); + } + + if ((ev_pos_x == grab_start_x) && (ev_pos_y == grab_start_y)) { + + // no motion - just a click + if (ev->state & Keyboard::TertiaryModifier) { + adjustment.set_value (_default_value); + } else if (ev->state & Keyboard::GainFineScaleModifier) { + adjustment.set_value (adjustment.get_lower()); + } else if ((_orien == VERT && ev_pos < display_span()) || (_orien == HORIZ && ev_pos > display_span())) { + // above the current display height, remember X Window coords + adjustment.set_value (adjustment.get_value() + adjustment.get_step_increment()); + } else { + adjustment.set_value (adjustment.get_value() - adjustment.get_step_increment()); + } + } + return true; + } + break; + + case 2: + if (dragging) { + remove_modal_grab(); + dragging = false; + set_adjustment_from_event (ev); + gdk_pointer_ungrab (GDK_CURRENT_TIME); + return true; + } + break; + + default: + break; + } +*/ + return false; + /* double const ev_pos = (_orien == VERT) ? ev->y : ev->x; @@ -241,42 +360,40 @@ Fader::on_scroll_event (GdkEventScroll* ev) bool Fader::on_motion_notify_event (GdkEventMotion* ev) { - /* if (_dragging) { - double scale = 1.0; - double const ev_pos = (_orien == VERT) ? ev->y : ev->x; + double ev_pos_x; + double ev_pos_y; - if (ev->window != grab_window) { - grab_loc = ev_pos; - grab_window = ev->window; + get_closest_point_on_line(_min_pos_x, _min_pos_y, + _max_pos_x, _max_pos_y, + ev->x, ev->y, + ev_pos_x, ev_pos_y ); + + if (((_min_pos_x != _max_pos_x) && + ((ev_pos_x < _min_pos_x) && (ev_pos_x < _max_pos_x) || + (ev_pos_x > _max_pos_x) && (ev_pos_x > _min_pos_x))) || + ((_min_pos_x != _max_pos_x) && + ((ev_pos_y < _min_pos_x) && (ev_pos_y < _max_pos_y) || + (ev_pos_y > _max_pos_x) && (ev_pos_y > _min_pos_y)))) { + return true; + } + + _grab_loc_x = ev_pos_x; + _grab_loc_y = ev_pos_y; + + if (ev->window != _grab_window) { + _grab_window = ev->window; return true; } - if (ev->state & Keyboard::GainFineScaleModifier) { - if (ev->state & Keyboard::GainExtraFineScaleModifier) { - scale = 0.05; - } else { - scale = 0.1; - } - } + double const fract = sqrt((ev_pos_x - _min_pos_x) * (ev_pos_x - _min_pos_x) + + (ev_pos_y - _min_pos_y) * (ev_pos_y - _min_pos_y)) / + sqrt((_max_pos_x - _min_pos_x) * (_max_pos_x - _min_pos_x) + + (_max_pos_y - _min_pos_y) * (_max_pos_y - _min_pos_y)); - double const delta = ev_pos - grab_loc; - grab_loc = ev_pos; - - double fract = (delta / span); - - fract = min (1.0, fract); - fract = max (-1.0, fract); - - // X Window is top->bottom for 0..Y - if (_orien == VERT) { - fract = -fract; - } - - adjustment.set_value (adjustment.get_value() + scale * fract * (adjustment.get_upper() - adjustment.get_lower())); + adjustment.set_value (adjustment.get_lower() + (adjustment.get_upper() - adjustment.get_lower()) * fract); } -*/ return true; } diff --git a/libs/gtkmm2ext/gtkmm2ext/fader.h b/libs/gtkmm2ext/gtkmm2ext/fader.h index 48cdc6d00c..2eeed75de5 100755 --- a/libs/gtkmm2ext/gtkmm2ext/fader.h +++ b/libs/gtkmm2ext/gtkmm2ext/fader.h @@ -37,6 +37,7 @@ class LIBGTKMM2EXT_API Fader : public Gtk::DrawingArea Fader (Gtk::Adjustment& adjustment, const std::string& face_image_file, const std::string& handle_image_file, + const std::string& active_handle_image_file, int min_pos_x, int min_pos_y, int max_pos_x, @@ -62,6 +63,7 @@ class LIBGTKMM2EXT_API Fader : public Gtk::DrawingArea private: Glib::RefPtr _handle_pixbuf; + Glib::RefPtr _active_handle_pixbuf; Glib::RefPtr _face_pixbuf; Gtk::Adjustment& adjustment; int _min_pos_x;