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 19 #include "MixerPluginGUI.h" 20 #include <FL/fl_draw.H> 21 #include <FL/fl_draw.H> 22 23 using namespace std; 24 25 //////////////////////////////////////////// 26 27 MixerPluginGUI::MixerPluginGUI (int w, int h, MixerPlugin *o, ChannelHandler *ch, const HostInfo *Info) : 28 SpiralPluginGUI (w, h, o, ch) 29 { 30 m_GUIColour = (Fl_Color)Info->GUI_COLOUR; 31 for (int n=0; n<MAX_CHANNELS; n++) Numbers[n]=n; 32 m_MainPack = new Fl_Pack (0, 15, w, 100); 33 m_MainPack->type (FL_HORIZONTAL); 34 add (m_MainPack); 35 36 // start with four... 37 AddChan(); AddChan(); AddChan(); AddChan(); 38 39 m_Buttons = new Fl_Pack (0, 118, 62, 20); 40 m_Buttons->type (FL_HORIZONTAL); 41 add (m_Buttons); 42 43 m_Delete = new Fl_Button (2, 0, 20, 20, "-"); 44 m_Delete->user_data ((void*)(this)); 45 m_Delete->box (FL_PLASTIC_UP_BOX); 46 m_Delete->color (Info->GUI_COLOUR); 47 m_Delete->selection_color (Info->GUI_COLOUR); 48 m_Delete->callback ((Fl_Callback*)cb_Delete); 49 m_Buttons->add (m_Delete); 50 51 m_Add = new Fl_Button (22, 0, 20, 20, "+"); 52 m_Add->user_data ((void*)(this)); 53 m_Add->box (FL_PLASTIC_UP_BOX); 54 m_Add->color (Info->GUI_COLOUR); 55 m_Add->selection_color (Info->GUI_COLOUR); 56 m_Add->callback ((Fl_Callback*)cb_Add); 57 m_Buttons->add (m_Add); 58 59 m_PeakInd = new Fl_LED_Button (42, 0, 20, 20, ""); 60 m_Buttons->add (m_PeakInd); 61 } 62 63 void MixerPluginGUI::AddChan (bool SendData, bool ResizeIt) { 64 Fl_Slider *NewSlide = new Fl_Slider (0, 0, 20, 100, ""); 65 NewSlide->user_data ((void*)(this)); 66 NewSlide->type (FL_VERT_NICE_SLIDER); 67 NewSlide->selection_color (m_GUIColour); 68 NewSlide->box (FL_PLASTIC_DOWN_BOX); 69 NewSlide->labelsize (10); 70 NewSlide->maximum (2); 71 NewSlide->step (0.01); 72 NewSlide->value (1.0); 73 int num = (int)m_SlidVec.size(); 74 NewSlide->callback ((Fl_Callback*)cb_Chan, (void*)&Numbers[num]); 75 m_MainPack->add (NewSlide); 76 m_SlidVec.push_back (NewSlide); 77 if (SendData) { 78 m_GUICH->Set ("Num", ++num); 79 m_GUICH->SetCommand (MixerPlugin::SETNUM); 80 m_GUICH->Wait (); 81 m_GUICH->Set ("Num", num); 82 m_GUICH->Set ("Value", (float)(2.0f - NewSlide->value ())); 83 m_GUICH->SetCommand(MixerPlugin::SETCH); 84 m_GUICH->Wait (); 85 } 86 if (ResizeIt && num > 3) Resize (w()+20, h()); 87 } 88 89 void MixerPluginGUI::DeleteChan (bool SendData) { 90 vector<Fl_Slider*>::iterator i = m_SlidVec.end (); 91 i--; 92 m_MainPack->remove (*i); 93 delete *i; 94 m_SlidVec.erase (i); 95 int num = (int)m_SlidVec.size(); 96 if (SendData) { 97 m_GUICH->Set ("Num", num); 98 m_GUICH->SetCommand (MixerPlugin::SETNUM); 99 m_GUICH->Wait (); 100 } 101 if (num > 2) Resize (w()-20, h()); 102 } 103 104 void MixerPluginGUI::UpdateValues(SpiralPlugin *o) { 105 MixerPlugin *Plugin = (MixerPlugin *)o; 106 unsigned int chans = Plugin->GetChannels(); 107 while (chans < m_SlidVec.size()) DeleteChan (false); 108 while (chans > m_SlidVec.size()) AddChan (false, true); 109 for (unsigned int n=0; n<chans; n++) 110 m_SlidVec[n]->value (2.0f - Plugin->GetChannel (n)); 111 redraw(); 112 } 113 114 void MixerPluginGUI::Update () { 115 if (m_GUICH->GetBool ("Peak")) m_PeakInd->value (true); 116 } 117 118 inline void MixerPluginGUI::cb_Add_i (Fl_Button* o, void* v) { 119 m_PeakInd->value (false); 120 if ((int)m_SlidVec.size() < MAX_CHANNELS) AddChan (true, true); 121 } 122 123 void MixerPluginGUI::cb_Add (Fl_Button* o, void* v) { 124 ((MixerPluginGUI*)(o->user_data()))->cb_Add_i (o, v); 125 } 126 127 inline void MixerPluginGUI::cb_Delete_i (Fl_Button* o, void* v) { 128 m_PeakInd->value (false); 129 if (m_SlidVec.size() > 2) DeleteChan (); 130 } 131 132 void MixerPluginGUI::cb_Delete (Fl_Button* o, void* v) { 133 ((MixerPluginGUI*)(o->user_data()))->cb_Delete_i (o, v); 134 } 135 136 inline void MixerPluginGUI::cb_Chan_i (Fl_Slider* o, void* v) { 137 // This line works fine 138 // cerr << *(int*)(v) << endl << (float)(2.0f-o->value()) << endl; 139 // The segfault comes when you do any of the following - don't know why 140 m_PeakInd->value (false); 141 m_GUICH->Set("Num", (*(int*)(v))); 142 m_GUICH->Set("Value", (float)(2.0f-o->value())); 143 m_GUICH->SetCommand (MixerPlugin::SETCH); 144 } 145 146 void MixerPluginGUI::cb_Chan(Fl_Slider* o, void* v) { 147 // If you use user_data() instead of parent()->parent() you get a segfault - don't know why 148 ((MixerPluginGUI*)(o->parent()->parent()))->cb_Chan_i (o, v); 149 } 150 151 // you sometimes get a segfault on exit too - again - don't know why 152 153 const string MixerPluginGUI::GetHelpText (const string &loc){ 154 return string("") 155 + "A general purpose mixer.\n" 156 + "Useful for mixing CV values as well as mono audio\n" 157 + "signals.\n" 158 + "The LED indicates the the mixer output is at peak\n" 159 + "level, click on it, or change levels to reset it.\n" 160 + "Add up to 16 channels using the '+' button.\n" 161 + "Use the '-' button to remove unwanted channels.\n"; 162 } 163