initial commit
[goodguy/history.git] / cinelerra-5.0 / cinelerra / patch.C
1
2 /*
3  * CINELERRA
4  * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
5  * 
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  * 
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  * 
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  * 
20  */
21
22 #include "filexml.h"
23 #include "mwindow.h"
24 #include "module.h"
25 #include "modules.h"
26 #include "mwindowgui.h"
27 #include "patch.h"
28 #include "patchbay.h"
29 #include "mainsession.h"
30 #include "theme.h"
31 #include <string.h>
32
33 Patch::Patch(MWindow *mwindow, PatchBay *patchbay, int data_type) : ListItem<Patch>()
34 {
35         this->mwindow = mwindow;
36         this->patches = patchbay;
37         this->data_type = data_type;
38         record = play = automate = draw = 1;
39         title[0] = 0;
40 }
41
42 Patch::~Patch()
43 {
44         if(mwindow->gui)
45         {
46                 delete recordpatch;  
47                 delete playpatch;  
48                 delete autopatch;  
49                 delete drawpatch;
50                 delete title_text;  
51         }
52 }
53
54 int Patch::create_objects(char *text, int pixel)
55 {
56         int x, y;
57         this->pixel = pixel;
58         strcpy(title, text);
59         
60         if(mwindow->gui)
61         {
62                 if(mwindow->session->tracks_vertical)
63                 {
64                         //x = patches->gui->w - pixel - mwindow->zoom_track;
65                         x = pixel + 3;
66                         y = 0;
67                 }
68                 else
69                 {
70                         x = 3;
71                         y = pixel;
72                 }
73
74                 patches->add_subwindow(recordpatch = new RecordPatchOld(mwindow, this, x, y));
75                 patches->add_subwindow(playpatch = new PlayPatchOld(mwindow, this, x, y));
76                 patches->add_subwindow(title_text = new TitlePatchOld(mwindow, this, text, x, y));
77                 //patches->add_subwindow(autotitle = new BC_Title(x + PATCH_AUTO_TITLE, y + PATCH_ROW2, "A", SMALLFONT));
78                 //patches->add_subwindow(autopatch = new AutoPatchOld(mwindow, this, x, y));
79                 //patches->add_subwindow(drawtitle = new BC_Title(x + PATCH_DRAW_TITLE, y + PATCH_ROW2, "D", SMALLFONT));
80                 patches->add_subwindow(drawpatch = new DrawPatchOld(mwindow, this, x, y));
81         }
82         return 0;
83 }
84
85 int Patch::save(FileXML *xml)
86 {
87         xml->tag.set_title("PATCH");
88         xml->append_tag();
89
90         if(play)
91         {
92                 xml->tag.set_title("PLAY");
93                 xml->append_tag();
94         }
95         
96         if(record)  
97         {
98                 xml->tag.set_title("RECORD");
99                 xml->append_tag();
100         }
101         
102         if(automate)  
103         {
104                 xml->tag.set_title("AUTO");
105                 xml->append_tag();
106         }
107         
108         if(draw)  
109         {
110                 xml->tag.set_title("DRAW");
111                 xml->append_tag();
112         }
113         
114         xml->tag.set_title("TITLE");
115         xml->append_tag();
116         xml->append_text(title);
117         xml->tag.set_title("/TITLE");
118         xml->append_tag();
119         
120         
121         xml->tag.set_title("/PATCH");
122         xml->append_tag();
123         xml->append_newline();
124         return 0;
125 }
126
127 int Patch::load(FileXML *xml)
128 {
129         int result = 0; 
130         play = record = automate = draw = 0;    // defaults
131         
132         do{
133                 result = xml->read_tag();
134                 
135                 if(!result)
136                 {
137                         if(xml->tag.title_is("/PATCH"))
138                         {
139                                 result = 1;
140                         }
141                         else
142                         if(xml->tag.title_is("PLAY"))
143                         {
144                                 play = 1;
145                         }
146                         else
147                         if(xml->tag.title_is("RECORD"))
148                         {
149                                 record = 1;
150                         }
151                         else
152                         if(xml->tag.title_is("AUTO"))
153                         {
154                                 automate = 1;
155                         }
156                         else
157                         if(xml->tag.title_is("DRAW"))
158                         {
159                                 draw = 1;
160                         }
161                         else
162                         if(xml->tag.title_is("TITLE"))
163                         {
164                                 strcpy(title, xml->read_text());
165                         }
166                 }
167         }while(!result);
168         
169         if(mwindow->gui)
170         {
171                 playpatch->update(play);
172                 recordpatch->update(record);
173                 autopatch->update(automate);
174                 drawpatch->update(draw);
175                 title_text->update(title);
176         }
177         return 0;
178 }
179
180 int Patch::set_pixel(int pixel)
181 {         // must be top of track for track zoom
182         this->pixel = pixel;
183         if(mwindow->gui)
184         {
185                 if(mwindow->session->tracks_vertical)
186                 {
187                         pixel += 3;
188                         playpatch->reposition_window(pixel + PATCH_PLAY, playpatch->get_y());
189                         recordpatch->reposition_window(pixel + PATCH_REC, recordpatch->get_y());
190                         autopatch->reposition_window(pixel + PATCH_AUTO, autopatch->get_y());
191                         title_text->reposition_window(pixel, title_text->get_y());
192                         drawpatch->reposition_window(pixel + PATCH_DRAW, drawpatch->get_y());
193                 }
194                 else
195                 {
196                         playpatch->reposition_window(playpatch->get_x(), pixel + PATCH_ROW2);
197                         recordpatch->reposition_window(recordpatch->get_x(), pixel + PATCH_ROW2);
198                         autopatch->reposition_window(autopatch->get_x(), pixel + PATCH_ROW2);
199                         drawpatch->reposition_window(drawpatch->get_x(), pixel + PATCH_ROW2);
200                         title_text->reposition_window(title_text->get_x(), pixel + 3);
201                 }
202         }
203         return 0;
204 }
205
206 int Patch::set_title(char *new_title)
207 {
208         strcpy(title, new_title);
209         title_text->update(new_title);
210         return 0;
211 }
212
213 int Patch::flip_vertical()
214 {
215         if(mwindow->gui)
216         {
217                 if(mwindow->session->tracks_vertical)
218                 {
219                         playpatch->reposition_window(playpatch->get_x(), PATCH_ROW2);
220                         recordpatch->reposition_window(recordpatch->get_x(), PATCH_ROW2);
221                         autopatch->reposition_window(autopatch->get_x(), PATCH_ROW2);
222                         drawpatch->reposition_window(drawpatch->get_x(), PATCH_ROW2);
223                         title_text->reposition_window(title_text->get_x(), 3);
224                 }
225                 else
226                 {
227                         playpatch->reposition_window(PATCH_PLAY, playpatch->get_y());
228                         recordpatch->reposition_window(PATCH_REC, recordpatch->get_y());
229                         autopatch->reposition_window(PATCH_AUTO, autopatch->get_y());
230                         drawpatch->reposition_window(PATCH_DRAW, drawpatch->get_y());
231                         title_text->reposition_window(PATCH_TITLE, title_text->get_y());
232                 }
233                 set_pixel(pixel);
234         }
235         return 0;
236 }
237
238
239 int Patch::pixelmovement(int distance)
240 {
241         if(mwindow->gui)
242         {
243                 pixel -= distance;
244                 set_pixel(pixel);
245         }
246         return 0;
247 }
248
249 Module* Patch::get_module()    // return corresponding module from console
250 {
251 //      return mwindow->console->modules->module_number(patches->number_of(this));
252 }
253
254 PlayPatchOld::PlayPatchOld(MWindow *mwindow, Patch *patch, int x, int y)
255  : BC_Toggle(x + PATCH_PLAY, 
256         y + PATCH_ROW2, 
257         mwindow->theme->playpatch_data,
258         1,
259         "",
260         1,
261         0,
262         0)
263 {
264         this->patch = patch; 
265         patches = patch->patches; 
266 }
267
268
269 int PlayPatchOld::handle_event()
270 {
271 // get the total selected before this event
272         if(shift_down())
273         {
274                 int total_selected = patches->plays_selected();
275
276                 if(total_selected == 0)
277                 {
278 // nothing previously selected
279                         patches->select_all_play();
280                 }
281                 else
282                 if(total_selected == 1)
283                 {
284                         if(patch->play)
285                         {
286 // this patch was previously the only one on
287                                 patches->select_all_play();
288                         }
289                         else
290                         {
291 // another patch was previously the only one on
292                                 patches->deselect_all_play();
293                                 patch->play = 1;
294                         }
295                 }
296                 else
297                 if(total_selected > 1)
298                 {
299                         patches->deselect_all_play();
300                         patch->play = 1;
301                 }
302                 
303                 update(patch->play);
304         }
305         else
306         {
307                 patch->play = get_value();
308         }
309         patches->button_down = 1;
310         patches->reconfigure_trigger = 1;
311         patches->new_status = get_value();
312         return 1;
313 }
314
315 int PlayPatchOld::button_release()
316 {
317         return 0;
318 }
319
320 int PlayPatchOld::cursor_moved_over()
321 {
322         if(patches->button_down && patches->new_status != get_value())
323         {
324                 update(patches->new_status);
325                 patch->play = get_value();
326                 return 1;
327         }
328         return 0;
329 }
330
331 RecordPatchOld::RecordPatchOld(MWindow *mwindow, Patch *patch, int x, int y)
332  : BC_Toggle(x + PATCH_REC, 
333         y + PATCH_ROW2, 
334         mwindow->theme->recordpatch_data,
335         1,
336         "",
337         1,
338         0,
339         0)
340
341         this->patch = patch; 
342         patches = patch->patches; 
343 }
344
345 int RecordPatchOld::handle_event()
346 {
347 // get the total selected before this event
348         if(shift_down())
349         {
350                 int total_selected = patches->records_selected();
351
352                 if(total_selected == 0)
353                 {
354 // nothing previously selected
355                         patches->select_all_record();
356                 }
357                 else
358                 if(total_selected == 1)
359                 {
360                         if(patch->record)
361                         {
362 // this patch was previously the only one on
363                                 patches->select_all_record();
364                         }
365                         else
366                         {
367 // another patch was previously the only one on
368                                 patches->deselect_all_record();
369                                 patch->record = 1;
370                         }
371                 }
372                 else
373                 if(total_selected > 1)
374                 {
375                         patches->deselect_all_record();
376                         patch->record = 1;
377                 }
378                 
379                 update(patch->record);
380         }
381         else
382         {
383                 patch->record = get_value();
384         }
385         patches->button_down = 1;
386         patches->new_status = get_value();
387         return 1;
388 }
389
390 int RecordPatchOld::button_release()
391 {
392         //if(patches->button_down)
393         //{
394         //      patches->button_down = 0;
395 // restart the playback
396                 //patches->mwindow->start_reconfigure(1);
397                 //patches->mwindow->stop_reconfigure(1);
398         //}
399         return 0;
400 }
401
402 int RecordPatchOld::cursor_moved_over()
403 {
404         if(patches->button_down && patches->new_status != get_value()) 
405         {
406                 update(patches->new_status);
407                 patch->record = get_value();
408                 return 1;
409         }
410         return 0;
411 }
412
413 TitlePatchOld::TitlePatchOld(MWindow *mwindow, Patch *patch, char *text, int x, int y)
414  : BC_TextBox(x, y + PATCH_TITLE, 124, 1, text, 0)
415
416         this->patch = patch; 
417         patches = patch->patches; 
418         module = 0; 
419 }
420
421 int TitlePatchOld::handle_event()
422 {
423         if(!module) module = patch->get_module();
424         module->set_title(get_text());
425         strcpy(patch->title, get_text());
426         return 1;
427 }
428
429 DrawPatchOld::DrawPatchOld(MWindow *mwindow, Patch *patch, int x, int y)
430  : BC_Toggle(x + PATCH_DRAW, 
431         y + PATCH_ROW2, 
432         mwindow->theme->drawpatch_data,
433         1,
434         "",
435         1, 
436         0, 
437         0)
438
439         this->patch = patch; 
440         this->patches = patch->patches; 
441 }
442
443 int DrawPatchOld::handle_event()
444 {
445 // get the total selected before this event
446         if(shift_down())
447         {
448                 int total_selected = patches->draws_selected();
449
450                 if(total_selected == 0)
451                 {
452 // nothing previously selected
453                         patches->select_all_draw();
454                 }
455                 else
456                 if(total_selected == 1)
457                 {
458                         if(patch->draw)
459                         {
460 // this patch was previously the only one on
461                                 patches->select_all_draw();
462                         }
463                         else
464                         {
465 // another patch was previously the only one on
466                                 patches->deselect_all_draw();
467                                 patch->draw = 1;
468                         }
469                 }
470                 else
471                 if(total_selected > 1)
472                 {
473                         patches->deselect_all_draw();
474                         patch->draw = 1;
475                 }
476                 
477                 update(patch->draw);
478         }
479         else
480         {
481                 patch->draw = get_value();
482         }
483         patches->button_down = 1;
484         patches->new_status = get_value();
485         return 1;
486 }
487
488 int DrawPatchOld::cursor_moved_over()
489 {
490         if(patches->button_down && patches->new_status != get_value())
491         {
492                 update(patches->new_status);
493                 patch->draw = get_value();
494         return 1;
495         }
496         return 0;
497 }