add prof sigusr1 feature, tweak amdgup tooltip, fix colorpicker handle_new_color...
[goodguy/cinelerra.git] / cinelerra-5.1 / 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 void 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 }
83
84 int Patch::save(FileXML *xml)
85 {
86         xml->tag.set_title("PATCH");
87         xml->append_tag();
88
89         if(play)
90         {
91                 xml->tag.set_title("PLAY");
92                 xml->append_tag();
93                 xml->tag.set_title("/PLAY");
94                 xml->append_tag();
95         }
96
97         if(record)
98         {
99                 xml->tag.set_title("RECORD");
100                 xml->append_tag();
101                 xml->tag.set_title("/RECORD");
102                 xml->append_tag();
103         }
104
105         if(automate)
106         {
107                 xml->tag.set_title("AUTO");
108                 xml->append_tag();
109                 xml->tag.set_title("/AUTO");
110                 xml->append_tag();
111         }
112
113         if(draw)
114         {
115                 xml->tag.set_title("DRAW");
116                 xml->append_tag();
117                 xml->tag.set_title("/DRAW");
118                 xml->append_tag();
119         }
120
121         xml->tag.set_title("TITLE");
122         xml->append_tag();
123         xml->append_text(title);
124         xml->tag.set_title("/TITLE");
125         xml->append_tag();
126
127
128         xml->tag.set_title("/PATCH");
129         xml->append_tag();
130         xml->append_newline();
131         return 0;
132 }
133
134 int Patch::load(FileXML *xml)
135 {
136         int result = 0;
137         play = record = automate = draw = 0;    // defaults
138
139         do{
140                 result = xml->read_tag();
141
142                 if(!result)
143                 {
144                         if(xml->tag.title_is("/PATCH"))
145                         {
146                                 result = 1;
147                         }
148                         else
149                         if(xml->tag.title_is("PLAY"))
150                         {
151                                 play = 1;
152                         }
153                         else
154                         if(xml->tag.title_is("RECORD"))
155                         {
156                                 record = 1;
157                         }
158                         else
159                         if(xml->tag.title_is("AUTO"))
160                         {
161                                 automate = 1;
162                         }
163                         else
164                         if(xml->tag.title_is("DRAW"))
165                         {
166                                 draw = 1;
167                         }
168                         else
169                         if(xml->tag.title_is("TITLE"))
170                         {
171                                 strcpy(title, xml->read_text());
172                         }
173                 }
174         }while(!result);
175
176         if(mwindow->gui)
177         {
178                 playpatch->update(play);
179                 recordpatch->update(record);
180                 autopatch->update(automate);
181                 drawpatch->update(draw);
182                 title_text->update(title);
183         }
184         return 0;
185 }
186
187 int Patch::set_pixel(int pixel)
188 {         // must be top of track for track zoom
189         this->pixel = pixel;
190         if(mwindow->gui)
191         {
192                 if(mwindow->session->tracks_vertical)
193                 {
194                         pixel += 3;
195                         playpatch->reposition_window(pixel + PATCH_PLAY, playpatch->get_y());
196                         recordpatch->reposition_window(pixel + PATCH_REC, recordpatch->get_y());
197                         autopatch->reposition_window(pixel + PATCH_AUTO, autopatch->get_y());
198                         title_text->reposition_window(pixel, title_text->get_y());
199                         drawpatch->reposition_window(pixel + PATCH_DRAW, drawpatch->get_y());
200                 }
201                 else
202                 {
203                         playpatch->reposition_window(playpatch->get_x(), pixel + PATCH_ROW2);
204                         recordpatch->reposition_window(recordpatch->get_x(), pixel + PATCH_ROW2);
205                         autopatch->reposition_window(autopatch->get_x(), pixel + PATCH_ROW2);
206                         drawpatch->reposition_window(drawpatch->get_x(), pixel + PATCH_ROW2);
207                         title_text->reposition_window(title_text->get_x(), pixel + 3);
208                 }
209         }
210         return 0;
211 }
212
213 int Patch::set_title(char *new_title)
214 {
215         strcpy(title, new_title);
216         title_text->update(new_title);
217         return 0;
218 }
219
220 int Patch::flip_vertical()
221 {
222         if(mwindow->gui)
223         {
224                 if(mwindow->session->tracks_vertical)
225                 {
226                         playpatch->reposition_window(playpatch->get_x(), PATCH_ROW2);
227                         recordpatch->reposition_window(recordpatch->get_x(), PATCH_ROW2);
228                         autopatch->reposition_window(autopatch->get_x(), PATCH_ROW2);
229                         drawpatch->reposition_window(drawpatch->get_x(), PATCH_ROW2);
230                         title_text->reposition_window(title_text->get_x(), 3);
231                 }
232                 else
233                 {
234                         playpatch->reposition_window(PATCH_PLAY, playpatch->get_y());
235                         recordpatch->reposition_window(PATCH_REC, recordpatch->get_y());
236                         autopatch->reposition_window(PATCH_AUTO, autopatch->get_y());
237                         drawpatch->reposition_window(PATCH_DRAW, drawpatch->get_y());
238                         title_text->reposition_window(PATCH_TITLE, title_text->get_y());
239                 }
240                 set_pixel(pixel);
241         }
242         return 0;
243 }
244
245
246 int Patch::pixelmovement(int distance)
247 {
248         if(mwindow->gui)
249         {
250                 pixel -= distance;
251                 set_pixel(pixel);
252         }
253         return 0;
254 }
255
256 Module* Patch::get_module()    // return corresponding module from console
257 {
258 //      return mwindow->console->modules->module_number(patches->number_of(this));
259 }
260
261 PlayPatchOld::PlayPatchOld(MWindow *mwindow, Patch *patch, int x, int y)
262  : BC_Toggle(x + PATCH_PLAY,
263         y + PATCH_ROW2,
264         mwindow->theme->playpatch_data,
265         1,
266         "",
267         1,
268         0,
269         0)
270 {
271         this->patch = patch;
272         patches = patch->patches;
273 }
274
275
276 int PlayPatchOld::handle_event()
277 {
278 // get the total selected before this event
279         if(shift_down())
280         {
281                 int total_selected = patches->plays_selected();
282
283                 if(total_selected == 0)
284                 {
285 // nothing previously selected
286                         patches->select_all_play();
287                 }
288                 else
289                 if(total_selected == 1)
290                 {
291                         if(patch->play)
292                         {
293 // this patch was previously the only one on
294                                 patches->select_all_play();
295                         }
296                         else
297                         {
298 // another patch was previously the only one on
299                                 patches->deselect_all_play();
300                                 patch->play = 1;
301                         }
302                 }
303                 else
304                 if(total_selected > 1)
305                 {
306                         patches->deselect_all_play();
307                         patch->play = 1;
308                 }
309
310                 update(patch->play);
311         }
312         else
313         {
314                 patch->play = get_value();
315         }
316         patches->button_down = 1;
317         patches->reconfigure_trigger = 1;
318         patches->new_status = get_value();
319         return 1;
320 }
321
322 int PlayPatchOld::button_release()
323 {
324         return 0;
325 }
326
327 int PlayPatchOld::cursor_moved_over()
328 {
329         if(patches->button_down && patches->new_status != get_value())
330         {
331                 update(patches->new_status);
332                 patch->play = get_value();
333                 return 1;
334         }
335         return 0;
336 }
337
338 RecordPatchOld::RecordPatchOld(MWindow *mwindow, Patch *patch, int x, int y)
339  : BC_Toggle(x + PATCH_REC,
340         y + PATCH_ROW2,
341         mwindow->theme->recordpatch_data,
342         1,
343         "",
344         1,
345         0,
346         0)
347 {
348         this->patch = patch;
349         patches = patch->patches;
350 }
351
352 int RecordPatchOld::handle_event()
353 {
354 // get the total selected before this event
355         if(shift_down())
356         {
357                 int total_selected = patches->records_selected();
358
359                 if(total_selected == 0)
360                 {
361 // nothing previously selected
362                         patches->select_all_record();
363                 }
364                 else
365                 if(total_selected == 1)
366                 {
367                         if(patch->record)
368                         {
369 // this patch was previously the only one on
370                                 patches->select_all_record();
371                         }
372                         else
373                         {
374 // another patch was previously the only one on
375                                 patches->deselect_all_record();
376                                 patch->record = 1;
377                         }
378                 }
379                 else
380                 if(total_selected > 1)
381                 {
382                         patches->deselect_all_record();
383                         patch->record = 1;
384                 }
385
386                 update(patch->record);
387         }
388         else
389         {
390                 patch->record = get_value();
391         }
392         patches->button_down = 1;
393         patches->new_status = get_value();
394         return 1;
395 }
396
397 int RecordPatchOld::button_release()
398 {
399         //if(patches->button_down)
400         //{
401         //      patches->button_down = 0;
402 // restart the playback
403                 //patches->mwindow->start_reconfigure(1);
404                 //patches->mwindow->stop_reconfigure(1);
405         //}
406         return 0;
407 }
408
409 int RecordPatchOld::cursor_moved_over()
410 {
411         if(patches->button_down && patches->new_status != get_value())
412         {
413                 update(patches->new_status);
414                 patch->record = get_value();
415                 return 1;
416         }
417         return 0;
418 }
419
420 TitlePatchOld::TitlePatchOld(MWindow *mwindow, Patch *patch, char *text, int x, int y)
421  : BC_TextBox(x, y + PATCH_TITLE, 124, 1, text, 0)
422 {
423         this->patch = patch;
424         patches = patch->patches;
425         module = 0;
426 }
427
428 int TitlePatchOld::handle_event()
429 {
430         if(!module) module = patch->get_module();
431         module->set_title(get_text());
432         strcpy(patch->title, get_text());
433         return 1;
434 }
435
436 DrawPatchOld::DrawPatchOld(MWindow *mwindow, Patch *patch, int x, int y)
437  : BC_Toggle(x + PATCH_DRAW,
438         y + PATCH_ROW2,
439         mwindow->theme->drawpatch_data,
440         1,
441         "",
442         1,
443         0,
444         0)
445 {
446         this->patch = patch;
447         this->patches = patch->patches;
448 }
449
450 int DrawPatchOld::handle_event()
451 {
452 // get the total selected before this event
453         if(shift_down())
454         {
455                 int total_selected = patches->draws_selected();
456
457                 if(total_selected == 0)
458                 {
459 // nothing previously selected
460                         patches->select_all_draw();
461                 }
462                 else
463                 if(total_selected == 1)
464                 {
465                         if(patch->draw)
466                         {
467 // this patch was previously the only one on
468                                 patches->select_all_draw();
469                         }
470                         else
471                         {
472 // another patch was previously the only one on
473                                 patches->deselect_all_draw();
474                                 patch->draw = 1;
475                         }
476                 }
477                 else
478                 if(total_selected > 1)
479                 {
480                         patches->deselect_all_draw();
481                         patch->draw = 1;
482                 }
483
484                 update(patch->draw);
485         }
486         else
487         {
488                 patch->draw = get_value();
489         }
490         patches->button_down = 1;
491         patches->new_status = get_value();
492         return 1;
493 }
494
495 int DrawPatchOld::cursor_moved_over()
496 {
497         if(patches->button_down && patches->new_status != get_value())
498         {
499                 update(patches->new_status);
500                 patch->draw = get_value();
501         return 1;
502         }
503         return 0;
504 }