|
- /* EventMap Widget
- * Copyleft (C) 2001 David Griffiths <dave@pawfal.org>
- *
- * 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 <FL/fl_draw.h>
- #include <FL/Fl_Window.h>
- #include <FL/x.H>
- #include <stdio.h>
-
- 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<y()+h(); n+=m_GridSizeY)
- {
- fl_color(LINE_COLOUR);
- fl_line(x(),n,x()+w(),n);
-
- // do black key bg
- if (m_Type==MELODY_MAP)
- {
- int cm = c%12;
- if (cm==1 || cm==3 || cm==6 || cm==8 || cm==10)
- {
- fl_color(BLACK_KEY_COL);
- fl_rectf(x(),n,w(),m_GridSizeY);
- }
- }
- c++;
- }
- }
-
- // draw the bar markers
- if (m_DrawBeats)
- {
- float BarLength=m_BarLength*(float)m_PixelsPerSec;
- float BeatLength=BarLength/(float)m_BeatsBar;
-
- float n=x();
- while (n<x()+w())
- {
- fl_color(LINE_COLOUR);
- fl_line((int)n,y(),(int)n,y()+h());
- if (m_Type==MELODY_MAP)
- {
- fl_line((int)n-1,y(),(int)n-1,y()+h());
- }
-
- if (m_Type!=ARRANGE_MAP)
- {
- // draw the beat markers
- float m=n;
- while(m<n+BarLength)
- {
- fl_color(LINE_COLOUR);
- fl_line((int)m,y(),(int)m,y()+h());
- m+=BeatLength;
- }
- }
- n+=BarLength;
- }
- }
-
- if (m_Type==ARRANGE_MAP)
- {
- fl_color(FL_BLACK);
-
- int StartPixels=(int)(m_StartLoop*(float)m_PixelsPerSec)+x();
- int EndPixels=(int)(m_EndLoop*(float)m_PixelsPerSec)+x();
-
- //fl_line(StartPixels,y()+15,StartPixels,y()+h());
- fl_line(EndPixels,y()+15,EndPixels,y()+h());
- }
-
- for (int i=children(); i--;) {
- Fl_Widget& o = **a++;
- draw_child(o);
- draw_outside_label(o);
- }
-
- SetFirstUpdate();
- }
-
- int Fl_EventMap::handle(int event)
- {
- if (!Fl_Group::handle(event) && event==FL_PUSH)
- {
- if (m_Type!=ARRANGE_MAP)
- {
- AddEvent(Fl::event_x(),Fl::event_y(),20, Fl_SEvent::NO_TYPE);
- }
- }
-
- for (map<int,Fl_SEvent*>::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<EventInfo> EventVec;
- for (map<int,Fl_SEvent*>::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<int,Fl_SEvent*>::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<Left+Width)
- {
- #if !__APPLE__
- XSetFunction(fl_display,fl_gc,GXxor);
- XSetForeground(fl_display, fl_gc, 0xff00ffff);
- if (!m_FirstUpdate) fl_line(m_LastPos,Top,m_LastPos,Depth);
- fl_line(DrawPos,Top,DrawPos,Depth);
- XSetFunction(fl_display,fl_gc,GXcopy);
- #endif
- m_LastPos=DrawPos;
- }
- }
- m_FirstUpdate=false;
- }
-
- vector<EventInfo> Fl_EventMap::GetEvents(float Time)
- {
- SetTime(Time);
-
- vector<EventInfo> EventVec;
- for (map<int,Fl_SEvent*>::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<int,Fl_SEvent*>::iterator i=m_EventMap.find(NewEvent->GetID());
- if (i!=m_EventMap.end())
- {
- cerr<<"Event ID not unique, not added!"<<endl;
- delete NewEvent;
- return -1;
- }
-
- add(NewEvent);
-
- // can only build the menus after adding to the parent, as the features in the
- // menu depend on which callbacks have been filled out by the parent.
- NewEvent->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<int,Fl_SEvent*>::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<int,Fl_SEvent*>::iterator i=m_EventMap.find(ID);
- if (i==m_EventMap.end())
- {
- cerr<<"Event ID not found to delete"<<endl;
- return;
- }
-
- Fl_SEvent *e=i->second;
- remove(e);
- m_EventMap.erase(i);
- delete(e);
-
- cerr<<"removed "<<ID<<endl;
- }
-
- Fl_SEvent *Fl_EventMap::GetEvent(int ID)
- {
- map<int,Fl_SEvent*>::iterator i=m_EventMap.find(ID);
- if (i==m_EventMap.end())
- {
- cerr<<"Event ID not found"<<endl;
- return NULL;
- }
-
- return m_EventMap[ID];
- }
-
- void Fl_EventMap::SetEventLength(int ID, float l)
- {
- Fl_SEvent *e=GetEvent(ID);
- if(e) e->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<int,Fl_SEvent*>::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"<<endl;
- s>>(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<Num; n++)
- {
- s>>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<<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<<" ";
-
- s<<o.m_EventMap.size()<<" ";
-
- for (map<int,Fl_SEvent*>::iterator i=o.m_EventMap.begin();
- i!=o.m_EventMap.end(); i++)
- {
- s<<i->second->GetStartTime()<<" "<<i->second->GetGroup()<<" "<<
- i->second->GetLengthTime()<<" "<<(int)(i->second->GetType())<<" ";
- }
- s<<endl;
-
- return s;
- }
|