You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

367 lines
8.5KB

  1. /* SpiralPlugin
  2. * Copyleft (C) 2000 David Griffiths <dave@pawfal.org>
  3. *
  4. * This program is free software; you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License as published by
  6. * the Free Software Foundation; either version 2 of the License, or
  7. * (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program; if not, write to the Free Software
  16. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  17. */
  18. #include <stdio.h>
  19. #include "ComplexEnvelopePluginGUI.h"
  20. #include <FL/fl_draw.H>
  21. #include <FL/fl_draw.H>
  22. static const float TIMED_SLIDER_MAX = 3.0f;
  23. /////////////////////////////////////////////////////////////////////////
  24. Fl_Envelope::Fl_Handle::Fl_Handle(int x,int y, int w, int h, char *Name) :
  25. Fl_Widget(x,y,w,h,Name),
  26. m_DelMe(false),
  27. m_Changed(false),
  28. m_Coincident(false)
  29. {
  30. }
  31. Fl_Envelope::Fl_Handle::~Fl_Handle()
  32. {
  33. }
  34. int Fl_Envelope::Fl_Handle::handle(int event)
  35. {
  36. int Mousebutton=Fl::event_button();
  37. if (event==FL_DRAG && Mousebutton==1)
  38. {
  39. x(Fl::event_x()-(w()/2));
  40. y(Fl::event_y()-(h()/2));
  41. // restrict the movement to the parent's area
  42. if (x()<parent()->x()) x(parent()->x());
  43. if (x()>parent()->x()+parent()->w()-w()) x(parent()->x()+parent()->w()-w());
  44. if (y()<parent()->y()) y(parent()->y());
  45. if (y()>parent()->y()+parent()->h()-h()) y(parent()->y()+parent()->h()-h());
  46. m_Changed=true;
  47. parent()->redraw();
  48. redraw();
  49. }
  50. if (event==FL_PUSH && Mousebutton==3)
  51. {
  52. m_DelMe=true;
  53. }
  54. return 1;
  55. }
  56. void Fl_Envelope::Fl_Handle::draw()
  57. {
  58. if (m_Coincident)
  59. {
  60. fl_color(FL_BLACK);
  61. fl_rect(x(),y(),w()+1,h()+1);
  62. fl_line(x(),y(),x()+w(),y()+h());
  63. fl_line(x(),y()+h(),x()+w(),y());
  64. }
  65. else
  66. {
  67. fl_color(FL_RED);
  68. fl_arc( x(),y(),w()+1,h()+1,0,360);
  69. }
  70. }
  71. Fl_Envelope::Fl_Envelope(int x,int y, int w, int h, char *Name) :
  72. Fl_Group(x,y,w,h,Name),
  73. m_Length(1.0),
  74. m_Bezier(true)
  75. {
  76. m_Origin_x=x+10;
  77. m_Origin_y=y+h-10;
  78. // default setting
  79. Fl_Handle * newhandle = new Fl_Handle(28,20,10,10,"");
  80. m_HandleList.push_back(newhandle);
  81. add(newhandle);
  82. newhandle = new Fl_Handle(14,122,10,10,"");
  83. m_HandleList.push_back(newhandle);
  84. add(newhandle);
  85. newhandle = new Fl_Handle(48,63,10,10,"");
  86. m_HandleList.push_back(newhandle);
  87. add(newhandle);
  88. newhandle = new Fl_Handle(76,91,10,10,"");
  89. m_HandleList.push_back(newhandle);
  90. add(newhandle);
  91. newhandle = new Fl_Handle(131,86,10,10,"");
  92. m_HandleList.push_back(newhandle);
  93. add(newhandle);
  94. newhandle = new Fl_Handle(194,81,10,10,"");
  95. m_HandleList.push_back(newhandle);
  96. add(newhandle);
  97. newhandle = new Fl_Handle(294,131,10,10,"");
  98. m_HandleList.push_back(newhandle);
  99. add(newhandle);
  100. newhandle = new Fl_Handle(216,124 ,10,10,"");
  101. m_HandleList.push_back(newhandle);
  102. add(newhandle);
  103. show();
  104. }
  105. Fl_Envelope::~Fl_Envelope()
  106. {
  107. end();
  108. }
  109. int Fl_Envelope::handle(int event)
  110. {
  111. int ret=Fl_Group::handle(event);
  112. // search for deleted handles
  113. for(list<Fl_Handle*>::iterator i = m_HandleList.begin();
  114. i!=m_HandleList.end(); ++i)
  115. {
  116. // if it's been modified, update the env via the callback
  117. if ((*i)->Changed()) do_callback();
  118. if ((*i)->Deleted())
  119. {
  120. remove(*i);
  121. m_HandleList.erase(i);
  122. break; // one at a time
  123. }
  124. }
  125. if (!ret)
  126. {
  127. int Mousebutton=Fl::event_button();
  128. if (event==FL_PUSH && Mousebutton==2)
  129. {
  130. Fl_Handle * newhandle = new
  131. Fl_Handle(Fl::event_x()-5,Fl::event_y()-5,10,10,"");
  132. m_HandleList.push_back(newhandle);
  133. add(newhandle);
  134. }
  135. redraw();
  136. }
  137. return ret;
  138. }
  139. void Fl_Envelope::draw()
  140. {
  141. fl_push_clip(x(),y(),w()+1,h()+1);
  142. fl_color(FL_GRAY);
  143. fl_rectf(x(),y(),w()+1,h()+1);
  144. fl_color(FL_BLACK);
  145. fl_rect(x(),y(),w()+1,h()+1);
  146. fl_color(FL_WHITE);
  147. int last_x=m_Origin_x, last_y=m_Origin_y, closest=INT_MAX, dist;
  148. list<Fl_Handle*>::iterator ClosestHandle=m_HandleList.end();
  149. // draw second markers
  150. fl_color(150,150,150);
  151. for (int n=0; n<5; n++)
  152. {
  153. int p=(int)(m_Origin_x+(w()/m_Length*n));
  154. fl_line(p,y(),p,y()+h());
  155. }
  156. m_HandlePos.clear();
  157. m_HandlePos.push_back(Vec2(m_Origin_x,m_Origin_y));
  158. if (m_Bezier) AddToSpline(Vec2(m_Origin_x,m_Origin_y));
  159. for (unsigned int n=0; n<m_HandleList.size(); n++)
  160. {
  161. // slow - search through drawing line connecting handles from left to right
  162. for(list<Fl_Handle*>::iterator i = m_HandleList.begin();
  163. i!=m_HandleList.end(); ++i)
  164. {
  165. dist=(*i)->x()-last_x;
  166. if (dist>-5 && dist<closest)
  167. {
  168. closest=dist;
  169. ClosestHandle=i;
  170. }
  171. }
  172. if (ClosestHandle!=m_HandleList.end())
  173. {
  174. closest=INT_MAX;
  175. fl_color(FL_WHITE);
  176. fl_line(last_x,last_y,(*ClosestHandle)->x()+5,(*ClosestHandle)->y()+5);
  177. (*ClosestHandle)->SetIsCoincident(false);
  178. last_x=(*ClosestHandle)->x()+5;
  179. last_y=(*ClosestHandle)->y()+5;
  180. m_HandlePos.push_back(Vec2((*ClosestHandle)->x()+5,(*ClosestHandle)->y()+5));
  181. if (m_Bezier)
  182. {
  183. if (!(n%3)) (*ClosestHandle)->SetIsCoincident(true);
  184. AddToSpline(Vec2((*ClosestHandle)->x()+5,(*ClosestHandle)->y()+5));
  185. }
  186. }
  187. }
  188. if (m_Bezier)
  189. {
  190. vector<Vec2> BezierLineList;
  191. CalculateBezierSpline(&BezierLineList,10);
  192. vector<Vec2>::iterator bi=BezierLineList.begin();
  193. bi++;
  194. fl_color(FL_BLUE);
  195. for (;bi!=BezierLineList.end(); bi++)
  196. {
  197. fl_line((int)(bi-1)->x,(int)(bi-1)->y,(int)bi->x,(int)bi->y);
  198. }
  199. }
  200. fl_color(FL_BLACK);
  201. fl_line(m_Origin_x,m_Origin_y,m_Origin_x,y()+10);
  202. fl_line(m_Origin_x,m_Origin_y,x()+w()-10,m_Origin_y);
  203. Fl_Group::draw();
  204. fl_pop_clip();
  205. }
  206. void Fl_Envelope::Clear()
  207. {
  208. for(list<Fl_Handle*>::iterator i = m_HandleList.begin();
  209. i!=m_HandleList.end(); ++i)
  210. {
  211. remove(*i);
  212. }
  213. m_HandleList.clear();
  214. }
  215. vector<Vec2> Fl_Envelope::GetCVList()
  216. {
  217. vector<Vec2> m_CV;
  218. for(vector<Vec2>::iterator i = m_HandlePos.begin();
  219. i!=m_HandlePos.end(); ++i)
  220. {
  221. // convert to 0->1
  222. Vec2 vec((i->x-m_Origin_x)/(float)(w()-m_Origin_x),
  223. (m_Origin_y-i->y)/(float)(m_Origin_y-y()));
  224. m_CV.push_back(vec);
  225. }
  226. return m_CV;
  227. }
  228. void Fl_Envelope::SetCVList(const vector<Vec2> &CV)
  229. {
  230. Clear();
  231. for(vector<Vec2>::const_iterator i = CV.begin();
  232. i!=CV.end(); ++i)
  233. {
  234. int minx=m_Origin_x, width=w()-m_Origin_x;
  235. int miny=m_Origin_y, height=m_Origin_y-y();
  236. // convert from 0->1 screen coords
  237. Vec2 vec(minx+(i->x*width),
  238. miny-(i->y*height));
  239. Fl_Handle *nh = new Fl_Handle((int)vec.x,(int)vec.y,10,10,"");
  240. add(nh);
  241. m_HandleList.push_back(nh);
  242. }
  243. redraw();
  244. }
  245. /////////////////////////////////////////////////////////////////////////
  246. ComplexEnvelopePluginGUI::ComplexEnvelopePluginGUI(int w, int h,ComplexEnvelopePlugin *o,const HostInfo *Info) :
  247. SpiralPluginGUI(w,h,o)
  248. {
  249. m_Plugin=o;
  250. m_Type = new Fl_Button(15,h-35,100,20,"Bezier Curve");
  251. m_Type->type(1);
  252. m_Type->value(1);
  253. m_Type->labelsize(10);
  254. m_Type->callback((Fl_Callback*)cb_Type);
  255. m_Length = new Fl_Knob(w-60,h-55,40,40,"Length");
  256. m_Length->color(Info->GUI_COLOUR);
  257. m_Length->labelsize(10);
  258. m_Length->maximum(5);
  259. m_Length->step(0.001);
  260. m_Length->value(1);
  261. m_Length->callback((Fl_Callback*)cb_Length);
  262. m_TLength = new Fl_Output(w-130,h-45,60,20,"");
  263. m_TLength->value("1.0");
  264. m_Envelope = new Fl_Envelope(5,20,w-10,h-75,"");
  265. m_Envelope->callback((Fl_Callback*)cb_UpdateEnv);
  266. end();
  267. }
  268. void ComplexEnvelopePluginGUI::UpdateValues()
  269. {
  270. }
  271. inline void ComplexEnvelopePluginGUI::cb_UpdateEnv_i(Fl_Envelope *o, void* v)
  272. {
  273. m_Plugin->CVListToEnvelope(o->GetCVList());
  274. }
  275. void ComplexEnvelopePluginGUI::cb_UpdateEnv(Fl_Envelope* o, void* v)
  276. {((ComplexEnvelopePluginGUI*)(o->parent()))->cb_UpdateEnv_i(o,v);}
  277. inline void ComplexEnvelopePluginGUI::cb_Type_i(Fl_Button *o, void *v)
  278. {
  279. m_Envelope->SetBezier(o->value());
  280. m_Plugin->SetBezier(o->value());
  281. m_Envelope->redraw();
  282. }
  283. void ComplexEnvelopePluginGUI::cb_Type(Fl_Button *o, void *v)
  284. {((ComplexEnvelopePluginGUI*)(o->parent()))->cb_Type_i(o,v);}
  285. inline void ComplexEnvelopePluginGUI::cb_Length_i(Fl_Knob *o, void *v)
  286. {
  287. m_Plugin->SetLength(o->value());
  288. m_Envelope->SetLength(o->value());
  289. static char text[16];
  290. sprintf(text,"%f",o->value());
  291. m_TLength->value(text);
  292. m_Envelope->redraw();
  293. }
  294. void ComplexEnvelopePluginGUI::cb_Length(Fl_Knob *o, void *v)
  295. {((ComplexEnvelopePluginGUI*)(o->parent()))->cb_Length_i(o,v);}