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.

495 lines
11KB

  1. /* EventMap Widget
  2. * Copyleft (C) 2001 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 "Fl_EventMap.h"
  19. #include <FL/fl_draw.h>
  20. #include <FL/Fl_Window.h>
  21. #include <FL/x.H>
  22. #include <stdio.h>
  23. static const int AREA_WIDTH = 1000;
  24. static const int AREA_HEIGHT = 1000;
  25. static const int BUTTON_COLOUR = 10;
  26. static const int EVENT_COLOUR = 0;
  27. static const int BG_COLOUR = 139;
  28. static const int LINE_COLOUR = 140;
  29. ////////////////////////////////////////////////////////////////////
  30. Fl_EventMap::Fl_EventMap(int x, int y, int w, int h, const char* label) :
  31. Fl_Group(x,y,w,h,label),
  32. m_SeqPointer(NULL),
  33. m_Type(ARRANGE_MAP),
  34. m_Update(true),
  35. m_Zoom(1.0f),
  36. m_GridSizeX(0),
  37. m_GridSizeY(10),
  38. m_PixelsPerSec(100),
  39. m_NextID(0),
  40. m_StartLoop(1.0f),
  41. m_EndLoop(2.0f),
  42. m_Pos(0),
  43. m_LastPos(0),
  44. m_DrawBeats(false),
  45. m_BarLength(100),
  46. m_BeatsBar(8),
  47. cb_NewEvent(NULL),
  48. cb_RightMouse(NULL),
  49. cb_CopyEvent(NULL),
  50. m_FirstUpdate(true)
  51. {
  52. // white/black keys for the melody
  53. m_KeyColMap[0] = FL_YELLOW;
  54. m_KeyColMap[1] = FL_BLUE;
  55. m_KeyColMap[2] = FL_YELLOW;
  56. m_KeyColMap[3] = FL_BLUE;
  57. m_KeyColMap[4] = FL_YELLOW;
  58. m_KeyColMap[5] = FL_BLUE;
  59. m_KeyColMap[6] = FL_YELLOW;
  60. m_KeyColMap[7] = FL_YELLOW;
  61. m_KeyColMap[8] = FL_BLUE;
  62. m_KeyColMap[9] = FL_YELLOW;
  63. m_KeyColMap[10] = FL_BLUE;
  64. m_KeyColMap[11] = FL_YELLOW;
  65. }
  66. void Fl_EventMap::CreateWindow()
  67. {
  68. int yoff=0;
  69. //m_StartTri = new Fl_TriEvent(90, 5, 20, 10, "");
  70. //m_StartTri->LockY();
  71. //m_StartTri->SetResizeGrab(0);
  72. //m_StartTri->SetPixelsPerSec(m_PixelsPerSec,true);
  73. m_PosTri = new Fl_TriEvent(90, 5, 30, 20, "");
  74. m_PosTri->LockY();
  75. m_PosTri->SetResizeGrab(0);
  76. m_PosTri->SetPixelsPerSec(m_PixelsPerSec,true);
  77. m_EndTri = new Fl_TriEvent(50, 5, 20, 10, "");
  78. m_EndTri->LockY();
  79. m_EndTri->SetResizeGrab(0);
  80. m_EndTri->SetPixelsPerSec(m_PixelsPerSec,true);
  81. show();
  82. }
  83. void Fl_EventMap::draw()
  84. {
  85. clear_damage(FL_DAMAGE_ALL);
  86. fl_color(BG_COLOUR);
  87. fl_rectf(x(),y(),w(),h());
  88. // draw the section markers
  89. fl_color(LINE_COLOUR);
  90. if (m_GridSizeY)
  91. {
  92. // draw the snap points
  93. for (int n=y(); n<y()+h(); n+=m_GridSizeY)
  94. {
  95. fl_line(x(),n,x()+w(),n);
  96. }
  97. }
  98. // draw the bar markers
  99. if (m_DrawBeats)
  100. {
  101. int BarLengthPixels=(int)(m_BarLength*(float)m_PixelsPerSec);
  102. int BeatLengthPixels=(int)(BarLengthPixels/(float)m_BeatsBar);
  103. for (int n=x(); n<x()+w(); n+=BarLengthPixels)
  104. {
  105. fl_line(n,y(),n,y()+h());
  106. if (m_Type!=ARRANGE_MAP)
  107. {
  108. // draw the beat markers
  109. for (int m=n+1; m<n+BarLengthPixels; m+=BeatLengthPixels)
  110. {
  111. fl_line(m,y(),m,y()+h());
  112. }
  113. }
  114. }
  115. }
  116. if (m_Type==ARRANGE_MAP)
  117. {
  118. fl_color(FL_BLACK);
  119. //m_StartLoop=m_StartTri->GetStartTime();
  120. //m_EndLoop=m_EndTri->GetStartTime();
  121. int StartPixels=(int)(m_StartLoop*(float)m_PixelsPerSec)+x();
  122. int EndPixels=(int)(m_EndLoop*(float)m_PixelsPerSec)+x();
  123. fl_line(StartPixels,y()+15,StartPixels,y()+h());
  124. fl_line(EndPixels,y()+15,EndPixels,y()+h());
  125. }
  126. Fl_Group::draw();
  127. SetFirstUpdate();
  128. }
  129. int Fl_EventMap::handle(int event)
  130. {
  131. if (!Fl_Group::handle(event) && event==FL_PUSH)
  132. {
  133. if (m_Type!=ARRANGE_MAP)
  134. {
  135. AddEvent(Fl::event_x(),Fl::event_y(),20, Fl_SEvent::NO_TYPE);
  136. }
  137. }
  138. for (map<int,Fl_SEvent*>::iterator i=m_EventMap.begin();
  139. i!=m_EventMap.end(); i++)
  140. {
  141. Fl_SEvent *pEvent = i->second;
  142. if (pEvent->Killed())
  143. {
  144. RemoveEvent(i->first);
  145. }
  146. }
  147. return event;
  148. }
  149. void Fl_EventMap::SetZoomLevel(float s)
  150. {
  151. m_Zoom=s;
  152. m_PixelsPerSec=int(100/m_Zoom);
  153. vector<EventInfo> EventVec;
  154. for (map<int,Fl_SEvent*>::iterator i=m_EventMap.begin();
  155. i!=m_EventMap.end(); i++)
  156. {
  157. i->second->SetPixelsPerSec(m_PixelsPerSec);
  158. }
  159. //m_StartTri->SetPixelsPerSec(m_PixelsPerSec);
  160. m_EndTri->SetPixelsPerSec(m_PixelsPerSec);
  161. redraw();
  162. }
  163. void Fl_EventMap::SetSnapGap(float s)
  164. {
  165. m_GridSizeX=(int)(s*(float)m_PixelsPerSec);
  166. for (map<int,Fl_SEvent*>::iterator i=m_EventMap.begin();
  167. i!=m_EventMap.end(); i++)
  168. {
  169. i->second->SetSnapGap(s);
  170. }
  171. redraw();
  172. }
  173. vector<EventInfo> Fl_EventMap::GetEvents(float Time)
  174. {
  175. assert(m_PixelsPerSec!=0);
  176. m_Pos = (int)(Time*m_PixelsPerSec);
  177. // line marker update
  178. // all in all, some orrible code...
  179. if (m_Update && window()->visible() && m_Pos!=m_LastPos)
  180. {
  181. window()->make_current();
  182. int DrawPos=m_Pos+x();
  183. m_PosTri->resize(DrawPos,m_PosTri->y(),m_PosTri->w(),m_PosTri->h());
  184. redraw();
  185. /* if (DrawPos>m_ClipX && DrawPos<m_ClipX+m_ClipW)
  186. {
  187. XSetFunction(fl_display,fl_gc,GXxor);
  188. if (!m_FirstUpdate) fl_line(m_LastPos,15+m_ClipY,m_LastPos,m_ClipY+m_ClipH);
  189. fl_line(DrawPos,15+m_ClipY,DrawPos,m_ClipY+m_ClipH);
  190. XSetFunction(fl_display,fl_gc,GXcopy);
  191. m_LastPos=DrawPos;
  192. }*/
  193. //if (Last!=NULL) Last->make_current();
  194. }
  195. m_FirstUpdate=false;
  196. vector<EventInfo> EventVec;
  197. for (map<int,Fl_SEvent*>::iterator i=m_EventMap.begin();
  198. i!=m_EventMap.end(); i++)
  199. {
  200. Fl_SEvent *pEvent = i->second;
  201. bool State=pEvent->UpdateState(Time);
  202. EventInfo::Type type=EventInfo::ON;
  203. if (pEvent->AtStart()) type=EventInfo::START;
  204. if (pEvent->AtEnd()) type=EventInfo::END;
  205. // Collect the events happening now, or just finished
  206. if(State || pEvent->AtEnd())
  207. {
  208. EventVec.push_back(EventInfo(pEvent->GetID(),pEvent->GetGroup(),
  209. type,pEvent->GetStartTime()));
  210. }
  211. }
  212. return EventVec;
  213. }
  214. int Fl_EventMap::GetGroupFromY(int y)
  215. {
  216. return y/m_GridSizeY;
  217. }
  218. int Fl_EventMap::AddEventTime(float st, int g, float lt, Fl_SEvent::Type EType, bool CallBack)
  219. {
  220. int ex,ey,ew;
  221. ex=(int)(st*(float)m_PixelsPerSec)+x();
  222. ew=(int)(lt*(float)m_PixelsPerSec);
  223. ey=g*m_GridSizeY+y();
  224. return AddEvent(ex, ey, ew, EType, CallBack);
  225. }
  226. int Fl_EventMap::AddEvent(int x, int y, int w, Fl_SEvent::Type EType, bool CallBack)
  227. {
  228. Fl_SEvent *NewEvent;
  229. if (m_Type==PERCUSSION_MAP)
  230. {
  231. NewEvent = new Fl_CircEvent(x,y,w,m_GridSizeY);
  232. }
  233. else
  234. {
  235. NewEvent = new Fl_SEvent(x,y,w,m_GridSizeY);
  236. }
  237. if (m_Type==MELODY_MAP) NewEvent->LockResize(false);
  238. NewEvent->SetPixelsPerSec(m_PixelsPerSec, true);
  239. NewEvent->color(EVENT_COLOUR);
  240. NewEvent->labelsize(10);
  241. NewEvent->SetID(m_NextID++);
  242. NewEvent->SetType(EType);
  243. char Name[256];
  244. if (m_Type==ARRANGE_MAP)
  245. {
  246. if(NewEvent->GetType()==Fl_SEvent::MELODY)
  247. sprintf(Name,"Melody %d",NewEvent->GetID());
  248. if(NewEvent->GetType()==Fl_SEvent::PERCUSSION)
  249. sprintf(Name,"Percussion %d",NewEvent->GetID());
  250. }
  251. else sprintf(Name,"This shouldnt be read!");
  252. NewEvent->SetName(Name);
  253. NewEvent->SetGridX(m_GridSizeX);
  254. NewEvent->SetGridY(m_GridSizeY);
  255. map<int,Fl_SEvent*>::iterator i=m_EventMap.find(NewEvent->GetID());
  256. if (i!=m_EventMap.end())
  257. {
  258. cerr<<"Event ID not unique, not added!"<<endl;
  259. delete NewEvent;
  260. return -1;
  261. }
  262. add(NewEvent);
  263. NewEvent->SnapX();
  264. NewEvent->SnapY();
  265. NewEvent->SetPixelsPerSec(m_PixelsPerSec,true);
  266. m_EventMap[NewEvent->GetID()]=NewEvent;
  267. int ID = NewEvent->GetID();
  268. if (cb_NewEvent && CallBack) cb_NewEvent(NewEvent,&ID);
  269. redraw();
  270. return NewEvent->GetID();
  271. }
  272. void Fl_EventMap::CopyEvent(int x, int y, int w, int ID, float LengthTime)
  273. {
  274. // make the new widget
  275. int NewID = AddEvent(x,y,w,m_EventMap[ID]->GetType(),false);
  276. // set the length of time exactly, as rounding
  277. // errors cause a reinit of the sample memory
  278. GetEvent(NewID)->SetLengthTime(LengthTime);
  279. //string Name="Copy of "+m_EventMap[ID]->GetName();
  280. //GetEvent(NewID)->SetName(Name);
  281. GetEvent(NewID)->SetName(m_EventMap[ID]->GetName());
  282. if (cb_CopyEvent) cb_CopyEvent(GetEvent(NewID),&ID);
  283. }
  284. void Fl_EventMap::RemoveAllEvents()
  285. {
  286. for (map<int,Fl_SEvent*>::iterator i=m_EventMap.begin();
  287. i!=m_EventMap.end(); i++)
  288. {
  289. Fl_SEvent *e=i->second;
  290. remove(e);
  291. m_EventMap.erase(i);
  292. delete(e);
  293. }
  294. m_EventMap.clear();
  295. m_NextID=0;
  296. redraw();
  297. }
  298. void Fl_EventMap::RemoveEvent(int ID)
  299. {
  300. map<int,Fl_SEvent*>::iterator i=m_EventMap.find(ID);
  301. if (i==m_EventMap.end())
  302. {
  303. cerr<<"Event ID not found to delete"<<endl;
  304. return;
  305. }
  306. Fl_SEvent *e=i->second;
  307. remove(e);
  308. m_EventMap.erase(i);
  309. delete(e);
  310. }
  311. Fl_SEvent *Fl_EventMap::GetEvent(int ID)
  312. {
  313. map<int,Fl_SEvent*>::iterator i=m_EventMap.find(ID);
  314. if (i==m_EventMap.end())
  315. {
  316. cerr<<"Event ID not found"<<endl;
  317. return NULL;
  318. }
  319. return m_EventMap[ID];
  320. }
  321. void Fl_EventMap::SetEventLength(int ID, float l)
  322. {
  323. Fl_SEvent *e=GetEvent(ID);
  324. if(e) e->SetLengthTime(l);
  325. }
  326. void Fl_EventMap::CopyFrom(Fl_EventMap *Other)
  327. {
  328. m_Type = Other->m_Type;
  329. m_Zoom = Other->m_Zoom;
  330. m_GridSizeX = Other->m_GridSizeX;
  331. m_GridSizeY = Other->m_GridSizeY;
  332. m_PixelsPerSec = Other->m_PixelsPerSec;
  333. m_StartLoop = Other->m_StartLoop;
  334. m_EndLoop = Other->m_EndLoop;
  335. m_Pos = Other->m_Pos;
  336. m_LastPos = Other->m_LastPos;
  337. m_BarLength = Other->m_BarLength;
  338. m_BeatsBar = Other->m_BeatsBar;
  339. m_NextID = Other->m_NextID;
  340. for (map<int,Fl_SEvent*>::iterator i=Other->m_EventMap.begin();
  341. i!=Other->m_EventMap.end(); i++)
  342. {
  343. Fl_SEvent *NewEvent;
  344. if (m_Type==PERCUSSION_MAP)
  345. {
  346. NewEvent = new Fl_CircEvent(*(Fl_CircEvent*)i->second);
  347. }
  348. else
  349. {
  350. NewEvent = new Fl_SEvent(*i->second);
  351. }
  352. add(NewEvent);
  353. m_EventMap[NewEvent->GetID()]=NewEvent;
  354. }
  355. }
  356. /////////////////////////////////////////////////////
  357. istream &operator>>(istream &s, Fl_EventMap &o)
  358. {
  359. string dummy;
  360. s>>dummy;
  361. if (dummy!="EventMap") cerr<<"Error in stream before Fl_EventMap"<<endl;
  362. s>>(int&)o.m_Type;
  363. s>>o.m_Zoom;
  364. s>>o.m_GridSizeX;
  365. s>>o.m_GridSizeY;
  366. s>>o.m_PixelsPerSec;
  367. s>>o.m_StartLoop;
  368. s>>o.m_EndLoop;
  369. s>>o.m_Pos;
  370. s>>o.m_LastPos;
  371. s>>o.m_BarLength;
  372. s>>o.m_BeatsBar;
  373. int Num;
  374. s>>Num;
  375. float st,lt;
  376. int g,t;
  377. for (int n=0; n<Num; n++)
  378. {
  379. s>>st>>g>>lt>>t;
  380. o.AddEventTime(st,g,lt,(Fl_SEvent::Type)(t), false);
  381. }
  382. return s;
  383. }
  384. ostream &operator<<(ostream &s, Fl_EventMap &o)
  385. {
  386. s<<"EventMap ";
  387. s<<(int)o.m_Type<<" ";
  388. s<<o.m_Zoom<<" ";
  389. s<<o.m_GridSizeX<<" ";
  390. s<<o.m_GridSizeY<<" ";
  391. s<<o.m_PixelsPerSec<<" ";
  392. s<<o.m_StartLoop<<" ";
  393. s<<o.m_EndLoop<<" ";
  394. s<<o.m_Pos<<" ";
  395. s<<o.m_LastPos<<" ";
  396. s<<o.m_BarLength<<" ";
  397. s<<o.m_BeatsBar<<" ";
  398. s<<o.m_EventMap.size()<<" ";
  399. for (map<int,Fl_SEvent*>::iterator i=o.m_EventMap.begin();
  400. i!=o.m_EventMap.end(); i++)
  401. {
  402. s<<i->second->GetStartTime()<<" "<<i->second->GetGroup()<<" "<<
  403. i->second->GetLengthTime()<<" "<<(int)(i->second->GetType())<<" ";
  404. }
  405. s<<endl;
  406. return s;
  407. }