/* DeviceGUI composite Widget * Copyleft (C) 2002 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_DeviceGUI.h" #include "Fl_Canvas.h" #include "Fl_Canvas.h" #include "PawfalInput.h" #include "../../SpiralSynthModularInfo.h" int Fl_DeviceGUI::Numbers[512]; Fl_PortButton::Fl_PortButton(int x, int y, int w, int h, char *n) : Fl_Button(x,y,w,h,n) { m_ConnectionCount=0; } int Fl_PortButton::handle(int event) { if (event==FL_PUSH) { m_LastButton=Fl::event_button(); if (m_LastButton == 1) { if (m_Type==INPUT && value()) return 1; do_callback(); return 1; } if (m_LastButton == 3) { do_callback(); return 1; } } return 1; } Fl_DeviceGUI::Fl_DeviceGUI(const DeviceGUIInfo& Info, Fl_Group *PW, Fl_Pixmap *Icon, bool Terminal) : Fl_Group(Info.XPos, Info.YPos, Info.Width+(PortGroupWidth*2), Info.Height+TitleBarHeight, ""), m_PluginWindow(NULL), m_Icon(NULL), m_Name(Info.Name), m_ID(-1), m_DelMe(false), m_IsTerminal(Terminal), m_Minimised(true) { for (int n=0; n<512; n++) Numbers[n]=n; type(1); box((Fl_Boxtype)SpiralSynthModularInfo::GUIDEVICE_Box); labeltype(FL_ENGRAVED_LABEL); align(FL_ALIGN_TOP_LEFT|FL_ALIGN_INSIDE); color(SpiralSynthModularInfo::GUICOL_Device); m_Icon=Icon; m_MiniWidth=w(); m_MiniHeight=h(); m_DragBar = new Fl_DragBar(Info.XPos, Info.YPos, Info.Width+PortGroupWidth*2, TitleBarHeight, m_Name.c_str()); m_DragBar->labelsize(10); m_DragBar->type(Fl_DragBar::FLDRAG); m_DragBar->color(SpiralSynthModularInfo::GUICOL_Device); m_Menu = new Fl_Menu_Button(x(),y(),w(),h(),""); m_Menu->type(Fl_Menu_Button::POPUP3); m_Menu->textsize(8); m_Menu->add("rename", 0, (Fl_Callback*)cb_Rename,this); m_Menu->add("delete", 0, (Fl_Callback*)cb_Delete,this); int Centx=x()+w()/2; int Centy=y()+h()/2; m_IconButton = new Fl_Button(Centx-m_Icon->w()/2,Centy-m_Icon->h()/2,m_Icon->w(),m_Icon->h()); m_IconButton->box(FL_NO_BOX); if (m_Icon) m_IconButton->image(m_Icon); m_PluginWindow = PW; if (m_PluginWindow) { m_PluginWindow->hide(); add(m_PluginWindow); } resizable(NULL); //Add the input/output ports Setup(Info, true); } void Fl_DeviceGUI::Clear() { end(); } int Fl_DeviceGUI::handle(int event) { int t=Fl_Group::handle(event); if (m_IconButton->value()) { m_IconButton->value(false); if (m_PluginWindow && !m_DelMe) { if(!m_PluginWindow->visible()) { Maximise(); m_IconButton->hide(); } } } if (m_Minimised==false && !m_PluginWindow->visible()) { Minimise(); m_IconButton->show(); } return 1; } void Fl_DeviceGUI::Minimise() { m_Minimised=true; Resize(m_MiniWidth,m_MiniHeight); parent()->redraw(); } void Fl_DeviceGUI::Maximise() { m_Minimised=false; if (m_PluginWindow->h()+2>m_MiniHeight) { Resize(m_PluginWindow->w()+(PortGroupWidth*2)-5,m_PluginWindow->h()+2); } else { Resize(m_PluginWindow->w()+(PortGroupWidth*2)-5,m_MiniHeight); } m_PluginWindow->show(); m_IconButton->hide(); ((Fl_Canvas*)parent())->ToTop(this); } void Fl_DeviceGUI::Resize(int width, int height) { int oldw = w(); int oldh = h(); size(width,height); m_DragBar->size(width,m_DragBar->h()); for (int n=m_Info.NumInputs; n<(int)m_PortVec.size(); n++) { m_PortVec[n]->position(x()+width-8,m_PortVec[n]->y()); } position(x()+(oldw-w())/2,y()+(oldh-h())/2); int Centx=x()+w()/2; int Centy=y()+h()/2; m_IconButton->position(Centx-m_Icon->w()/2,Centy-m_Icon->h()/2); } void Fl_DeviceGUI::Setup(const DeviceGUIInfo& Info, bool FirstTime) { m_Info=Info; // Remove all current connections - it's the safest thing to do. if (parent() && !FirstTime) { ((Fl_Canvas*)(parent()))->ClearConnections(this); } // delete the current ports for(vector::iterator i=m_PortVec.begin(); i!=m_PortVec.end(); i++) { remove(*i); delete(*i); } m_PortVec.clear(); int InputX=x()+2; int OutputX=0; int StartY=y()+TitleBarHeight; int PortDist=10; int PortNum=0; m_MiniHeight=Info.Height+TitleBarHeight; bool Maximised = (m_PluginWindow && m_PluginWindow->visible()); if (!Maximised) { h(m_MiniHeight); OutputX=x()+PortGroupWidth+Info.Width+4; } else { OutputX=x()+w()-8; } for (int n=0; ntype(1); NewInput->SetType(Fl_PortButton::INPUT); NewInput->value(false); NewInput->box(FL_ROUNDED_BOX); Fl_Color col = (Fl_Color) WIRE_COL0; switch (Info.PortTypes[n]) { case 0: col = (Fl_Color) WIRE_COL0; break; case 1: col = (Fl_Color) WIRE_COL1; break; case 2: col = (Fl_Color) WIRE_COL2; break; case 3: col = (Fl_Color) WIRE_COL3; break; case 4: col = (Fl_Color) WIRE_COL4; break; default: col = (Fl_Color) WIRE_COL0; } NewInput->selection_color(col); NewInput->down_box(FL_ROUNDED_BOX); NewInput->tooltip(Info.PortTips[n].c_str()); NewInput->callback((Fl_Callback*)cb_Port,(void*)&Numbers[PortNum]); m_PortVec.push_back(NewInput); add(NewInput); PortNum++; } for (int n=0; ntype(1); NewOutput->SetType(Fl_PortButton::OUTPUT); NewOutput->value(false); NewOutput->box(FL_ROUNDED_BOX); Fl_Color col = (Fl_Color) WIRE_COL0; switch (Info.PortTypes[n+Info.NumInputs]) { case 0: col = (Fl_Color) WIRE_COL0; break; case 1: col = (Fl_Color) WIRE_COL1; break; case 2: col = (Fl_Color) WIRE_COL2; break; case 3: col = (Fl_Color) WIRE_COL3; break; case 4: col = (Fl_Color) WIRE_COL4; break; default: col = (Fl_Color) WIRE_COL0; } NewOutput->selection_color(col); NewOutput->down_box(FL_ROUNDED_BOX); NewOutput->tooltip(Info.PortTips[n+Info.NumInputs].c_str()); NewOutput->callback((Fl_Callback*)cb_Port,(void*)&Numbers[PortNum]); m_PortVec.push_back(NewOutput); add(NewOutput); PortNum++; } } bool Fl_DeviceGUI::AddConnection(int n) { if ( n < (int)m_PortVec.size() ) { m_PortVec[n]->Add(); m_PortVec[n]->value(1); redraw(); return true; } return false; } void Fl_DeviceGUI::RemoveConnection(int n) { m_PortVec[n]->Remove(); if (!m_PortVec[n]->GetCount()) { m_PortVec[n]->value(0); redraw(); } } inline void Fl_DeviceGUI::cb_Port_i(Fl_Button* o, void* v) { int Port=*(int*)(v); Fl_PortButton *PortButton = (Fl_PortButton *)o; PortType Pt; if (m_DelMe) return; // Find out if this is an input or an output. if (PortGetLastButton()==1) { ((Fl_Canvas*)(parent()))->PortClicked(this,Pt,Port,1); } else { ((Fl_Canvas*)(parent()))->PortClicked(this,Pt,Port,0); } } void Fl_DeviceGUI::cb_Port(Fl_Button* o, void* v) {((Fl_DeviceGUI*)(o->parent()))->cb_Port_i(o,v);} inline void Fl_DeviceGUI::cb_Rename_i(Fl_Menu_Button* o, void* v) { char name[256]; if (Pawfal_Input("Rename the module:",m_DragBar->label(),name)) { m_Name=name; m_DragBar->label(m_Name.c_str()); ((Fl_Canvas*)(parent()))->Rename(this); } } void Fl_DeviceGUI::cb_Rename(Fl_Menu_Button* o, void* v) {((Fl_DeviceGUI*)(o->parent()))->cb_Rename_i(o,v);} inline void Fl_DeviceGUI::cb_Delete_i(Fl_Menu_Button* o, void* v) { m_DelMe=true; } void Fl_DeviceGUI::cb_Delete(Fl_Menu_Button* o, void* v) {((Fl_DeviceGUI*)(o->parent()))->cb_Delete_i(o,v);}