/* EventMap Widget * Copyleft (C) 2001 David Griffiths * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "Fl_EventMap.h" #include #include #include #include static const int AREA_WIDTH = 1000; static const int AREA_HEIGHT = 1000; static const int BUTTON_COLOUR = 10; static const int EVENT_COLOUR = 0; int BG_COLOUR;// = 139; int BLACK_KEY_COL;// = 141; int LINE_COLOUR;// = 140; //////////////////////////////////////////////////////////////////// Fl_EventMap::Fl_EventMap(int x, int y, int ww, int h, const char* label) : Fl_Group(x,y,ww,h,label), m_Type(ARRANGE_MAP), m_Update(true), m_Zoom(1.0f), m_GridSizeX(0), m_GridSizeY(10), m_PixelsPerSec(100), m_NextID(0), m_StartLoop(1.0f), m_EndLoop(2.0f), m_Pos(0), m_LastPos(0), m_DrawBeats(true), m_BarLength(1), m_BeatsBar(4), m_FirstUpdate(true) { box(FL_FLAT_BOX); fl_color(0,100,161); BG_COLOUR=fl_color(); fl_color(0,90,150); BLACK_KEY_COL=fl_color(); fl_color(0,80,150); LINE_COLOUR=fl_color(); fl_color(200,200,200); // SpiralSound/Plugins/Widgets/Fl_EventMap.C:65: declaration of `w' shadows a parameter int w=fl_color(); fl_color(50,50,50); int b=fl_color(); // white/black keys for the melody m_KeyColMap[0] = w; m_KeyColMap[1] = b; m_KeyColMap[2] = w; m_KeyColMap[3] = b; m_KeyColMap[4] = w; m_KeyColMap[5] = w; m_KeyColMap[6] = b; m_KeyColMap[7] = w; m_KeyColMap[8] = b; m_KeyColMap[9] = w; m_KeyColMap[10] = b; m_KeyColMap[11] = w; } void Fl_EventMap::SetCallbacks(const EventCallbacks &s) { m_Callbacks.cb_NewEvent=s.cb_NewEvent; m_Callbacks.cb_EventDoubleClicked=s.cb_EventDoubleClicked; m_Callbacks.cb_CopyEvent=s.cb_CopyEvent; m_Callbacks.cb_CloneEvent=s.cb_CloneEvent; m_Callbacks.cb_InstanceEvent=s.cb_InstanceEvent; m_Callbacks.cb_MoveEvent=s.cb_MoveEvent; m_Callbacks.cb_EditEvent=s.cb_EditEvent; m_Callbacks.cb_DelEvent=s.cb_DelEvent; m_Callbacks.cb_RenameEvent=s.cb_RenameEvent; m_Callbacks.cb_Recolour=s.cb_Recolour; } void Fl_EventMap::CreateWindow() { show(); } void Fl_EventMap::draw() { Fl_Widget*const* a = array(); if (!(damage() & ~FL_DAMAGE_CHILD)) { for (int i=children(); i--;) update_child(**a++); return; } draw_box(); m_FirstUpdate=true; fl_color(BG_COLOUR); fl_rectf(x(),y(),w(),h()); // draw the section markers if (m_GridSizeY) { int c=0; // draw the snap points for (int n=y(); n::iterator i=m_EventMap.begin(); i!=m_EventMap.end(); i++) { Fl_SEvent *pEvent = i->second; if (pEvent->Killed()) { RemoveEvent(i->first); } } return event; } void Fl_EventMap::SetZoomLevel(float s) { m_Zoom=s; m_PixelsPerSec=int(100/m_Zoom); vector EventVec; for (map::iterator i=m_EventMap.begin(); i!=m_EventMap.end(); i++) { i->second->SetPixelsPerSec(m_PixelsPerSec); } redraw(); } void Fl_EventMap::SetSnapGap(float s) { m_GridSizeX=(int)(s*(float)m_PixelsPerSec); for (map::iterator i=m_EventMap.begin(); i!=m_EventMap.end(); i++) { i->second->SetSnapGap(s); } redraw(); } void Fl_EventMap::SetTime(float Time) { assert(m_PixelsPerSec!=0); Time -= m_TimeOffset; m_Pos = (int)(Time*m_PixelsPerSec); // line marker update // all in all, some orrible code... if (m_Update && window()->visible() && visible_r() && m_Pos!=m_LastPos) { window()->make_current(); int DrawPos=m_Pos+x(); int Left=parent()->x(); int Top=parent()->y(); int Width=parent()->w(); int Depth=parent()->h(); if (DrawPos>Left && DrawPos Fl_EventMap::GetEvents(float Time) { SetTime(Time); vector EventVec; for (map::iterator i=m_EventMap.begin(); i!=m_EventMap.end(); i++) { Fl_SEvent *pEvent = i->second; bool State=pEvent->UpdateState(Time); EventInfo::Type type=EventInfo::ON; if (pEvent->AtStart()) type=EventInfo::START; if (pEvent->AtEnd()) type=EventInfo::END; // Collect the events happening now, or just finished if(State || pEvent->AtEnd()) { EventVec.push_back(EventInfo(pEvent->GetID(),pEvent->GetGroup(), type,pEvent->GetStartTime())); } } return EventVec; } int Fl_EventMap::GetGroupFromY(int y) { return y/m_GridSizeY; } int Fl_EventMap::AddEventTime(float st, int g, float lt, Fl_SEvent::Type EType, bool CallBack) { int ex,ey,ew; ex=(int)(st*(float)m_PixelsPerSec)+x(); ew=(int)(lt*(float)m_PixelsPerSec); ey=g*m_GridSizeY+y(); return AddEvent(ex, ey, ew, EType, CallBack); } int Fl_EventMap::AddEvent(int x, int y, int w, Fl_SEvent::Type EType, bool CallBack) { Fl_SEvent *NewEvent; if (m_Type==PERCUSSION_MAP) { NewEvent = new Fl_CircEvent(x,y,w,m_GridSizeY); } else { NewEvent = new Fl_SEvent(x,y,w,m_GridSizeY); } if (m_Type==MELODY_MAP) NewEvent->LockResize(false); NewEvent->SetPixelsPerSec(m_PixelsPerSec, true); NewEvent->color(EVENT_COLOUR); NewEvent->labelsize(10); NewEvent->SetID(m_NextID++); NewEvent->SetType(EType); char Name[256]; if (m_Type==ARRANGE_MAP) { if(NewEvent->GetType()==Fl_SEvent::MELODY) sprintf(Name,"Melody %d",NewEvent->GetID()); if(NewEvent->GetType()==Fl_SEvent::PERCUSSION) sprintf(Name,"Percussion %d",NewEvent->GetID()); } else sprintf(Name,"This shouldnt be read!"); NewEvent->SetName(Name); NewEvent->SetGridX(m_GridSizeX); NewEvent->SetGridY(m_GridSizeY); map::iterator i=m_EventMap.find(NewEvent->GetID()); if (i!=m_EventMap.end()) { cerr<<"Event ID not unique, not added!"<BuildMenu(); NewEvent->SnapX(); NewEvent->SnapY(); NewEvent->SetPixelsPerSec(m_PixelsPerSec,true); m_EventMap[NewEvent->GetID()]=NewEvent; int pID = NewEvent->GetID(); if (m_Callbacks.cb_NewEvent && CallBack) m_Callbacks.cb_NewEvent(NewEvent,&pID); redraw(); return NewEvent->GetID(); } int Fl_EventMap::CopyEvent(int x, int y, int w, int ID, float LengthTime) { // make the new widget int NewID = AddEvent(x,y,w,m_EventMap[ID]->GetType(),false); // set the length of time exactly, as rounding // errors cause a reinit of the sample memory GetEvent(NewID)->SetLengthTime(LengthTime); //string Name="Copy of "+m_EventMap[ID]->GetName(); //GetEvent(NewID)->SetName(Name); GetEvent(NewID)->SetName(m_EventMap[ID]->GetName()); GetEvent(NewID)->SetColour(m_EventMap[ID]->GetColour()); GetEvent(NewID)->SetChannel(m_EventMap[ID]->GetChannel()); return NewID; } void Fl_EventMap::RemoveAllEvents() { for (map::iterator i=m_EventMap.begin(); i!=m_EventMap.end(); i++) { Fl_SEvent *e=i->second; remove(e); m_EventMap.erase(i); delete(e); } m_EventMap.clear(); m_NextID=0; redraw(); } void Fl_EventMap::RemoveEvent(int ID) { map::iterator i=m_EventMap.find(ID); if (i==m_EventMap.end()) { cerr<<"Event ID not found to delete"<second; remove(e); m_EventMap.erase(i); delete(e); cerr<<"removed "<::iterator i=m_EventMap.find(ID); if (i==m_EventMap.end()) { cerr<<"Event ID not found"<SetLengthTime(l); } void Fl_EventMap::CopyFrom(Fl_EventMap *Other) { m_Type = Other->m_Type; m_Zoom = Other->m_Zoom; m_GridSizeX = Other->m_GridSizeX; m_GridSizeY = Other->m_GridSizeY; m_PixelsPerSec = Other->m_PixelsPerSec; m_StartLoop = Other->m_StartLoop; m_EndLoop = Other->m_EndLoop; m_Pos = Other->m_Pos; m_LastPos = Other->m_LastPos; m_BarLength = Other->m_BarLength; m_BeatsBar = Other->m_BeatsBar; m_NextID = Other->m_NextID; for (map::iterator i=Other->m_EventMap.begin(); i!=Other->m_EventMap.end(); i++) { Fl_SEvent *NewEvent; if (m_Type==PERCUSSION_MAP) { NewEvent = new Fl_CircEvent(*(Fl_CircEvent*)i->second); } else { NewEvent = new Fl_SEvent(*i->second); } add(NewEvent); m_EventMap[NewEvent->GetID()]=NewEvent; } } ///////////////////////////////////////////////////// istream &operator>>(istream &s, Fl_EventMap &o) { string dummy; s>>dummy; if (dummy!="EventMap") cerr<<"Error in stream before Fl_EventMap"<>(int&)o.m_Type; s>>o.m_Zoom; s>>o.m_GridSizeX; s>>o.m_GridSizeY; s>>o.m_PixelsPerSec; s>>o.m_StartLoop; s>>o.m_EndLoop; s>>o.m_Pos; s>>o.m_LastPos; s>>o.m_BarLength; s>>o.m_BeatsBar; int Num; s>>Num; float st,lt; int g,t; for (int n=0; n>st>>g>>lt>>t; o.AddEventTime(st,g,lt,(Fl_SEvent::Type)(t), false); } return s; } ostream &operator<<(ostream &s, Fl_EventMap &o) { s<<"EventMap "; s<<(int)o.m_Type<<" "; s<::iterator i=o.m_EventMap.begin(); i!=o.m_EventMap.end(); i++) { s<second->GetStartTime()<<" "<second->GetGroup()<<" "<< i->second->GetLengthTime()<<" "<<(int)(i->second->GetType())<<" "; } s<