File Coverage

blib/lib/Audio/Nama/Graphical.pm
Criterion Covered Total %
statement 21 607 3.4
branch 0 150 0.0
condition 0 16 0.0
subroutine 7 96 7.2
pod 0 3 0.0
total 28 872 3.2


line stmt bran cond sub pod time code
1             # ------------ Graphical User Interface ------------
2              
3             package Audio::Nama::Graphical; ## gui routines
4 1     1   5 use Modern::Perl; use Carp;
  1     1   2  
  1         7  
  1         109  
  1         2  
  1         69  
5             our $VERSION = 1.071;
6 1     1   4 use Audio::Nama::Globals qw($text);
  1         2  
  1         81  
7              
8 1     1   7 use Module::Load::Conditional qw(can_load);
  1         9  
  1         50  
9 1     1   5 use Audio::Nama::Assign qw(:all);
  1         2  
  1         139  
10 1     1   6 use Audio::Nama::Util qw(colonize);
  1         2  
  1         41  
11 1     1   5 no warnings 'uninitialized';
  1         2  
  1         12680  
12              
13             our @ISA = 'Audio::Nama'; ## default to root class
14             # widgets
15              
16             ## The following methods belong to the Graphical interface class
17              
18 0     0 0   sub hello {"make a window";}
19             sub loop {
20             package Audio::Nama;
21 0     0 0   $text->{term_attribs}->{already_prompted} = 0;
22 0           $text->{term}->tkRunning(1);
23 0           while (1) {
24 0           my ($user_input) = $text->{term}->readline($prompt) ;
25 0           Audio::Nama::process_line( $user_input );
26             }
27             }
28              
29 0     0 0   sub initialize_tk { can_load( modules => { Tk => undef } ) }
30              
31             # the following graphical methods are placed in the root namespace
32             # allowing access to root namespace variables
33             # with a package path
34              
35             package Audio::Nama;
36             # gui handling
37              
38             # in the $gui variable, keys with leading _underscore
39             # indicate variables
40             #
41             # $gui->{_project_name} # scalar/array/hash var
42             # $gui->{mw} # Tk objects (widgets, frames, etc.)
43              
44             sub init_gui {
45              
46 0     0     logsub("&init_gui");
47              
48 0           init_palettefields(); # keys only
49              
50              
51             ### Tk root window
52              
53             # Tk main window
54 0           $gui->{mw} = MainWindow->new;
55 0           get_saved_colors();
56 0           $gui->{mw}->optionAdd('*font', 'Helvetica 12');
57 0           $gui->{mw}->optionAdd('*BorderWidth' => 1);
58 0           $gui->{mw}->title("Ecasound/Nama");
59 0           $gui->{mw}->deiconify;
60              
61             ### init effect window
62              
63 0           $gui->{ew} = $gui->{mw}->Toplevel;
64 0           $gui->{ew}->title("Effect Window");
65 0           $gui->{ew}->deiconify;
66             # $gui->{ew}->withdraw;
67              
68             ### Exit via Ctrl-C
69              
70 0     0     $gui->{mw}->bind('' => sub { exit } );
  0            
71 0     0     $gui->{ew}->bind('' => sub { exit } );
  0            
72              
73             ## Press SPACE to start/stop transport
74              
75 0           $gui->{mw}->bind('' => \&toggle_transport);
76 0           $gui->{ew}->bind('' => \&toggle_transport);
77            
78 0           $gui->{canvas} = $gui->{ew}->Scrolled('Canvas')->pack;
79             $gui->{canvas}->configure(
80 0           scrollregion =>[2,2,10000,10000],
81             -width => 1200,
82             -height => 700,
83             );
84 0           $gui->{fx_frame} = $gui->{canvas}->Frame;
85             my $id = $gui->{canvas}->createWindow(30,30, -window => $gui->{fx_frame},
86 0           -anchor => 'nw');
87              
88 0           $gui->{project_head} = $gui->{mw}->Label->pack(-fill => 'both');
89              
90             $gui->{time_frame} = $gui->{mw}->Frame(
91             # -borderwidth => 20,
92             # -relief => 'groove',
93 0           )->pack(
94             -side => 'bottom',
95             -fill => 'both',
96             );
97             $gui->{mark_frame} = $gui->{time_frame}->Frame->pack(
98 0           -side => 'bottom',
99             -fill => 'both');
100             $gui->{seek_frame} = $gui->{time_frame}->Frame->pack(
101 0           -side => 'bottom',
102             -fill => 'both');
103 0           $gui->{transport_frame} = $gui->{mw}->Frame->pack(-side => 'bottom', -fill => 'both');
104             # $oid_frame = $gui->{mw}->Frame->pack(-side => 'bottom', -fill => 'both');
105 0           $gui->{clock_frame} = $gui->{mw}->Frame->pack(-side => 'bottom', -fill => 'both');
106             #$gui->{group_frame} = $gui->{mw}->Frame->pack(-side => 'bottom', -fill => 'both');
107 0           my $track_canvas = $gui->{mw}->Scrolled('Canvas')->pack(-side => 'bottom', -fill => 'both');
108 0           $track_canvas->configure(
109             -scrollregion =>[2,2,400,9600],
110             -width => 400,
111             -height => 400,
112             );
113 0           $gui->{track_frame} = $track_canvas->Frame; # ->pack(-fill => 'both');
114             #$gui->{track_frame} = $gui->{mw}->Frame;
115             my $id2 = $track_canvas->createWindow(0,0,
116             -window => $gui->{track_frame},
117 0           -anchor => 'nw');
118             #$gui->{group_label} = $gui->{group_frame}->Menubutton(-text => "GROUP",
119             # -tearoff => 0,
120             # -width => 13)->pack(-side => 'left');
121            
122 0           $gui->{add_frame} = $gui->{mw}->Frame->pack(-side => 'bottom', -fill => 'both');
123 0           $gui->{perl_frame} = $gui->{mw}->Frame->pack(-side => 'bottom', -fill => 'both');
124 0           $gui->{iam_frame} = $gui->{mw}->Frame->pack(-side => 'bottom', -fill => 'both');
125 0           $gui->{load_frame} = $gui->{mw}->Frame->pack(-side => 'bottom', -fill => 'both');
126             # my $blank = $gui->{mw}->Label->pack(-side => 'left');
127              
128              
129              
130             $gui->{project_label} = $gui->{load_frame}->Label(
131 0           -text => " Project name: "
132             )->pack(-side => 'left');
133             $gui->{project_entry} = $gui->{load_frame}->Entry(
134             -textvariable => \$gui->{_project_name},
135 0           -width => 25
136             )->pack(-side => 'left');
137              
138 0           $gui->{load_project} = $gui->{load_frame}->Button->pack(-side => 'left');;
139 0           $gui->{new_project} = $gui->{load_frame}->Button->pack(-side => 'left');;
140 0           $gui->{quit} = $gui->{load_frame}->Button->pack(-side => 'left');
141 0           $gui->{save_project} = $gui->{load_frame}->Button->pack(-side => 'left');
142             $gui->{savefile_entry} = $gui->{load_frame}->Entry(
143             -textvariable => \$gui->{_save_id},
144 0           -width => 15
145             )->pack(-side => 'left');
146 0           $gui->{load_savefile} = $gui->{load_frame}->Button->pack(-side => 'left');
147 0           $gui->{palette} = $gui->{load_frame}->Menubutton(-tearoff => 0)
148             ->pack( -side => 'left');
149 0           $gui->{nama_palette} = $gui->{load_frame}->Menubutton(-tearoff => 0)
150             ->pack( -side => 'left');
151             $gui->{add_track}->{label} = $gui->{add_frame}->Label(
152 0           -text => "New track name: ")->pack(-side => 'left');
153             $gui->{add_track}->{text_entry} = $gui->{add_frame}->Entry(
154             -textvariable => \$gui->{_track_name},
155 0           -width => 12
156             )->pack(-side => 'left');
157             $gui->{add_track}->{rec_label} = $gui->{add_frame}->Label(
158 0           -text => "Input channel or client:"
159             )->pack(-side => 'left');
160             $gui->{add_track}->{rec_text} = $gui->{add_frame}->Entry(
161             -textvariable => \$gui->{_chr},
162 0           -width => 10
163             )->pack(-side => 'left');
164 0           $gui->{add_track}->{add_mono} = $gui->{add_frame}->Button->pack(-side => 'left');;
165 0           $gui->{add_track}->{add_stereo} = $gui->{add_frame}->Button->pack(-side => 'left');;
166              
167             $gui->{load_project}->configure(
168             -text => 'Load',
169             -command => sub{ load_project(
170 0     0     name => remove_spaces($gui->{_project_name}),
171 0           )});
172             $gui->{new_project}->configure(
173             -text => 'Create',
174             -command => sub{ load_project(
175 0     0     name => remove_spaces($gui->{_project_name}),
176 0           create => 1)});
177             $gui->{save_project}->configure(
178             -text => 'Save settings',
179             -command => #sub { print "save_id: $gui->{_save_id}\n" });
180 0     0     sub {save_state($gui->{_save_id}) });
  0            
181             $gui->{load_savefile}->configure(
182             -text => 'Recall settings',
183             -command => sub {load_project (name => $project->{name}, # current project
184 0     0     settings => $gui->{_save_id})},
185 0           );
186             $gui->{quit}->configure(-text => "Quit",
187             -command => sub {
188 0 0   0     return if transport_running();
189 0           save_state($gui->{_save_id});
190 0           pager("Exiting... \n");
191             #$text->{term}->tkRunning(0);
192             #$gui->{ew}->destroy;
193             #$gui->{mw}->destroy;
194             #Audio::Nama::process_command('quit');
195 0           exit;
196 0           });
197             $gui->{palette}->configure(
198 0           -text => 'Palette',
199             -relief => 'raised',
200             );
201             $gui->{nama_palette}->configure(
202 0           -text => 'Nama palette',
203             -relief => 'raised',
204             );
205              
206 0           my @color_items = map { [ 'command' => $_,
207             -command => colorset('mw', $_ ) ]
208 0           } @{$gui->{_palette_fields}};
  0            
209 0           $gui->{palette}->AddItems( @color_items);
210              
211 0           @color_items = map { [ 'command' => $_,
212             -command => namaset( $_ ) ]
213 0           } @{$gui->{_nama_fields}};
  0            
214              
215             $gui->{add_track}->{add_mono}->configure(
216             -text => 'Add Mono Track',
217             -command => sub {
218 0 0   0     return if $gui->{_track_name} =~ /^\s*$/;
219 0           add_track(remove_spaces($gui->{_track_name})) }
220 0           );
221             $gui->{add_track}->{add_stereo}->configure(
222             -text => 'Add Stereo Track',
223             -command => sub {
224 0 0   0     return if $gui->{_track_name} =~ /^\s*$/;
225 0           add_track(remove_spaces($gui->{_track_name}));
226 0           process_command('stereo');
227 0           });
228              
229 0           my @labels =
230             qw(Track Name Version Status Source Send Volume Mute Unity Pan Center Effects);
231 0           my @widgets;
232 0           map{ push @widgets, $gui->{track_frame}->Label(-text => $_) } @labels;
  0            
233 0           $widgets[0]->grid(@widgets[1..$#widgets]);
234              
235              
236             }
237              
238             sub transport_gui {
239 0     0     my $ui = shift;
240 0           logsub("&transport_gui");
241              
242             $gui->{engine_label} = $gui->{transport_frame}->Label(
243 0           -text => 'TRANSPORT',
244             -width => 12,
245             )->pack(-side => 'left');;
246 0           $gui->{engine_start} = $gui->{transport_frame}->Button->pack(-side => 'left');
247 0           $gui->{engine_stop} = $gui->{transport_frame}->Button->pack(-side => 'left');
248              
249             $gui->{engine_stop}->configure(-text => "Stop",
250             -command => sub {
251 0     0     stop_transport();
252             }
253 0           );
254             $gui->{engine_start}->configure(
255             -text => "Start",
256             -command => sub {
257 0 0   0     return if transport_running();
258 0           my $color = engine_mode_color();
259 0           $ui->project_label_configure(-background => $color);
260 0           start_transport();
261 0           });
262              
263             #preview_button();
264             #mastering_button();
265              
266             }
267             sub time_gui {
268 0     0     my $ui = shift;
269 0           logsub("&time_gui");
270              
271             my $time_label = $gui->{clock_frame}->Label(
272 0           -text => 'TIME',
273             -width => 12);
274             #print "bg: $gui->{_nama_palette}->{ClockBackground}, fg:$gui->{_nama_palette}->{ClockForeground}\n";
275             $gui->{clock} = $gui->{clock_frame}->Label(
276             -text => '0:00',
277             -width => 8,
278             -background => $gui->{_nama_palette}->{ClockBackground},
279             -foreground => $gui->{_nama_palette}->{ClockForeground},
280 0           );
281             my $length_label = $gui->{clock_frame}->Label(
282 0           -text => 'LENGTH',
283             -width => 10,
284             );
285             $gui->{setup_length} = $gui->{clock_frame}->Label(
286             # -width => 8,
287 0           );
288              
289 0           for my $w ($time_label, $gui->{clock}, $length_label, $gui->{setup_length}) {
290 0           $w->pack(-side => 'left');
291             }
292              
293             $gui->{mark_frame} = $gui->{time_frame}->Frame->pack(
294 0           -side => 'bottom',
295             -fill => 'both');
296             $gui->{seek_frame} = $gui->{time_frame}->Frame->pack(
297 0           -side => 'bottom',
298             -fill => 'both');
299             # jump
300              
301 0           my $jump_label = $gui->{seek_frame}->Label(-text => q(JUMP), -width => 12);
302 0           my @pluses = (1, 5, 10, 30, 60);
303 0           my @minuses = map{ - $_ } reverse @pluses;
  0            
304 0           my @fw = map{ my $d = $_; $gui->{seek_frame}->Button(
  0            
305             -text => $d,
306 0     0     -command => sub { jump($d) },
307             )
308 0           } @pluses ;
309 0           my @rew = map{ my $d = $_; $gui->{seek_frame}->Button(
  0            
310             -text => $d,
311 0     0     -command => sub { jump($d) },
312             )
313 0           } @minuses ;
314             my $beg = $gui->{seek_frame}->Button(
315 0           -text => 'Beg',
316             -command => \&to_start,
317             );
318             my $end = $gui->{seek_frame}->Button(
319 0           -text => 'End',
320             -command => \&to_end,
321             );
322              
323             $gui->{seek_unit} = $gui->{seek_frame}->Button(
324 0           -text => 'Sec',
325             );
326 0           for my $w($jump_label, @rew, $beg, $gui->{seek_unit}, $end, @fw){
327 0           $w->pack(-side => 'left')
328             }
329              
330 0     0     $gui->{seek_unit}->configure (-command => sub { &toggle_unit; &show_unit });
  0            
  0            
331              
332             # Marks
333            
334             my $mark_label = $gui->{mark_frame}->Label(
335 0           -text => q(MARK),
336             -width => 12,
337             )->pack(-side => 'left');
338            
339             my $drop_mark = $gui->{mark_frame}->Button(
340 0           -text => 'Place',
341             -command => \&drop_mark,
342             )->pack(-side => 'left');
343            
344             $gui->{mark_remove} = $gui->{mark_frame}->Button(
345 0           -text => 'Remove',
346             -command => \&arm_mark_toggle,
347             )->pack(-side => 'left');
348              
349             }
350             sub toggle_unit {
351 0 0   0     if ($gui->{_seek_unit} == 1){
352 0           $gui->{_seek_unit} = 60;
353            
354 0           } else{ $gui->{_seek_unit} = 1; }
355             }
356             sub show_unit { $gui->{seek_unit}->configure(
357 0 0   0     -text => ($gui->{_seek_unit} == 1 ? 'Sec' : 'Min')
358             )}
359              
360             sub paint_button {
361 0     0     my $ui = shift;
362 0           my ($button, $color) = @_;
363 0           $button->configure(-background => $color,
364             -activebackground => $color);
365             }
366              
367             sub engine_mode_color {
368 0 0   0     if ( user_rec_tracks() ){
    0          
    0          
369             $gui->{_nama_palette}->{RecBackground} # live recording
370 0           } elsif ( Audio::Nama::ChainSetup::really_recording() ){
371             $gui->{_nama_palette}->{Mixdown} # mixdown only
372 0           } elsif ( user_mon_tracks() ){
373 0           $gui->{_nama_palette}->{Play}; # just playback
374 0           } else { $gui->{_old_bg} }
375             }
376 0     0     sub user_rec_tracks { some_user_tracks(REC) }
377 0     0     sub user_mon_tracks { some_user_tracks(PLAY) }
378              
379             sub some_user_tracks {
380 0     0     my $which = shift;
381 0           my @user_tracks = Audio::Nama::audio_tracks();
382 0           splice @user_tracks, 0, 2; # drop Master and Mixdown tracks
383 0 0         return unless @user_tracks;
384 0           my @selected_user_tracks = grep { $_->rec_status eq $which } @user_tracks;
  0            
385 0 0         return unless @selected_user_tracks;
386 0           map{ $_->n } @selected_user_tracks;
  0            
387             }
388              
389             sub flash_ready {
390              
391 0     0     my $color = engine_mode_color();
392 0           logpkg(__FILE__,__LINE__,'debug', "flash color: $color");
393 0           $ui->length_display(-background => $color);
394 0 0         $ui->project_label_configure(-background => $color) unless $mode->{preview};
395 0           $project->{events}->{heartbeat} = AE::timer(5, 0, \&reset_engine_mode_color_display);
396             }
397             sub reset_engine_mode_color_display { $ui->project_label_configure(
398             -background => $gui->{_nama_palette}->{OffBackground} )
399 0     0     }
400 0     0     sub set_engine_mode_color_display { $ui->project_label_configure(-background => engine_mode_color()) }
401             sub group_gui {
402 0     0     my $ui = shift;
403 0           my $group = $bn{Main};
404 0           my $dummy = $gui->{track_frame}->Label(-text => ' ');
405             $gui->{group_label} = $gui->{track_frame}->Label(
406             -text => "G R O U P",
407             -foreground => $gui->{_nama_palette}->{GroupForeground},
408             -background => $gui->{_nama_palette}->{GroupBackground},
409              
410 0           );
411             $gui->{group_version} = $gui->{track_frame}->Menubutton(
412             -text => q( ),
413             -tearoff => 0,
414             -foreground => $gui->{_nama_palette}->{GroupForeground},
415             -background => $gui->{_nama_palette}->{GroupBackground},
416 0           );
417             $gui->{group_rw} = $gui->{track_frame}->Menubutton(
418             -text => $group->rw,
419             -tearoff => 0,
420             -foreground => $gui->{_nama_palette}->{GroupForeground},
421             -background => $gui->{_nama_palette}->{GroupBackground},
422 0           );
423              
424              
425            
426             $gui->{group_rw}->AddItems([
427             'command' => MON,
428             -background => $gui->{_old_bg},
429             -command => sub {
430 0 0   0     return if Audio::Nama::eval_iam("engine-status") eq 'running';
431 0           $group->set(rw => MON);
432 0           $gui->{group_rw}->configure(-text => MON);
433 0           refresh();
434 0           Audio::Nama::reconfigure_engine()
435             }
436             ],[
437             'command' => OFF,
438             -background => $gui->{_old_bg},
439             -command => sub {
440 0 0   0     return if Audio::Nama::eval_iam("engine-status") eq 'running';
441 0           $group->set(rw => OFF);
442 0           $gui->{group_rw}->configure(-text => OFF);
443 0           refresh();
444 0           Audio::Nama::reconfigure_engine()
445             }
446 0           ]);
447 0           $dummy->grid($gui->{group_label}, $gui->{group_version}, $gui->{group_rw});
448             #$ui->global_version_buttons;
449              
450             }
451             sub global_version_buttons {
452 0     0     my $version = $gui->{group_version};
453 0 0         $version and map { $_->destroy } $version->children;
  0            
454            
455             logpkg(__FILE__,__LINE__,'debug', "making global version buttons range: " ,
456 0           join ' ',1..$bn{Main}->last);
457              
458             $version->radiobutton(
459              
460             -label => (''),
461             -value => 0,
462             -command => sub {
463 0     0     $bn{Main}->set(version => 0);
464 0           $version->configure(-text => " ");
465 0           Audio::Nama::reconfigure_engine();
466 0           refresh();
467             }
468 0           );
469              
470 0           for my $v (1..$bn{Main}->last) {
471              
472             # the highest version number of all tracks in the
473             # $bn{Main} group
474            
475 0           my @user_track_indices = grep { $_ > 2 } map {$_->n} Audio::Nama::audio_tracks();
  0            
  0            
476            
477 0 0         next unless grep{ grep{ $v == $_ } @{ $ti{$_}->versions } }
  0            
  0            
  0            
478             @user_track_indices;
479            
480              
481             $version->radiobutton(
482              
483             -label => ($v ? $v : ''),
484             -value => $v,
485             -command => sub {
486 0     0     $bn{Main}->set(version => $v);
487 0           $version->configure(-text => $v);
488 0           Audio::Nama::reconfigure_engine();
489 0           refresh();
490             }
491              
492 0 0         );
493             }
494             }
495             sub track_gui {
496 0     0     logsub("&track_gui");
497 0           my $ui = shift;
498 0           my $n = shift;
499 0 0         return if $ti{$n}->hide;
500            
501 0           logpkg(__FILE__,__LINE__,'debug', "found index: $n");
502             my @rw_items = @_ ? @_ : (
503             [ 'command' => "REC",
504             -foreground => 'red',
505             -command => sub {
506 0 0   0     return if Audio::Nama::eval_iam("engine-status") eq 'running';
507 0           $ti{$n}->set(rw => "REC");
508            
509 0           $ui->refresh_track($n);
510             #refresh_group();
511 0           Audio::Nama::reconfigure_engine();
512             }],
513             [ 'command' => "PLAY",
514             -command => sub {
515 0 0   0     return if Audio::Nama::eval_iam("engine-status") eq 'running';
516 0           $ti{$n}->set(rw => "PLAY");
517 0           $ui->refresh_track($n);
518             #refresh_group();
519 0           Audio::Nama::reconfigure_engine();
520             }],
521             [ 'command' => "MON",
522             -foreground => 'red',
523             -command => sub {
524 0 0   0     return if Audio::Nama::eval_iam("engine-status") eq 'running';
525 0           $ti{$n}->set(rw => "MON");
526            
527 0           $ui->refresh_track($n);
528             #refresh_group();
529 0           Audio::Nama::reconfigure_engine();
530             }],
531             [ 'command' => "OFF",
532             -command => sub {
533 0 0   0     return if Audio::Nama::eval_iam("engine-status") eq 'running';
534 0           $ti{$n}->set(rw => "OFF");
535 0           $ui->refresh_track($n);
536             #refresh_group();
537 0           Audio::Nama::reconfigure_engine();
538 0 0         }],
539             );
540 0           my ($number, $name, $version, $rw, $ch_r, $ch_m, $vol, $mute, $solo, $unity, $pan, $center);
541 0           $number = $gui->{track_frame}->Label(-text => $n,
542             -justify => 'left');
543 0           my $stub = " ";
544 0           $stub .= $ti{$n}->version;
545             $name = $gui->{track_frame}->Label(
546 0           -text => $ti{$n}->name,
547             -justify => 'left');
548             $version = $gui->{track_frame}->Menubutton(
549 0           -text => $stub,
550             # -relief => 'sunken',
551             -tearoff => 0);
552 0           my @versions = '';
553             #push @versions, @{$ti{$n}->versions} if @{$ti{$n}->versions};
554 0           my $ref = ref $ti{$n}->versions ;
555             $ref =~ /ARRAY/ and
556 0 0 0       push (@versions, @{$ti{$n}->versions}) or
  0            
557             croak "chain $n, found unexpectedly $ref\n";;
558 0           my $indicator;
559 0           for my $v (@versions) {
560             $version->radiobutton(
561             -label => $v,
562             -value => $v,
563             -variable => \$indicator,
564             -command =>
565             sub {
566 0     0     $ti{$n}->set( version => $v );
567 0 0         return if $ti{$n}->rec_status eq "REC";
568 0           $version->configure( -text=> $ti{$n}->current_version );
569 0           Audio::Nama::reconfigure_engine();
570             }
571 0           );
572             }
573              
574             $ch_r = $gui->{track_frame}->Menubutton(
575             # -relief => 'groove',
576 0           -tearoff => 0,
577             );
578 0           my @range;
579 0 0         push @range, 1..$config->{soundcard_channels} if $n > 2; # exclude Master/Mixdown
580            
581 0           for my $v (@range) {
582             $ch_r->radiobutton(
583             -label => $v,
584             -value => $v,
585             -command => sub {
586 0 0   0     return if Audio::Nama::eval_iam("engine-status") eq 'running';
587             # $ti{$n}->set(rw => REC);
588 0           $ti{$n}->source($v);
589 0           $ui->refresh_track($n) }
590             )
591 0           }
592 0           @range = ();
593              
594 0 0         push @range, "off" if $n > 2;
595 0 0         push @range, 1..$config->{soundcard_channels} if $n != 2; # exclude Mixdown
596              
597             $ch_m = $gui->{track_frame}->Menubutton(
598 0           -tearoff => 0,
599             # -relief => 'groove',
600             );
601 0           for my $v (@range) {
602             $ch_m->radiobutton(
603             -label => $v,
604             -value => $v,
605             -command => sub {
606 0 0   0     return if Audio::Nama::eval_iam("engine-status") eq 'running';
607 0           local $this_track = $ti{$n};
608 0 0         if( $v eq 'off' )
609 0           { process_command('nosend') }
610 0           else { $this_track->set_send($v) }
611 0           $ui->refresh_track($n);
612 0           Audio::Nama::reconfigure_engine();
613             }
614             )
615 0           }
616             $rw = $gui->{track_frame}->Menubutton(
617 0           -text => $ti{$n}->rw,
618             -tearoff => 0,
619             # -relief => 'groove',
620             );
621 0           map{$rw->AddItems($_)} @rw_items;
  0            
622              
623            
624 0           my $p_num = 0; # needed when using parameter controllers
625             # Volume
626            
627 0 0         if ( Audio::Nama::need_vol_pan($ti{$n}->name, "vol") ){
628              
629 0           my $vol_id = $ti{$n}->vol;
630              
631 0           logpkg(__FILE__,__LINE__,'debug', "vol effect_id: $vol_id");
632             my %p = ( parent => \$gui->{track_frame},
633 0           chain => $n,
634             type => 'ea',
635             id => $vol_id,
636             p_num => $p_num,
637             length => 300,
638             );
639              
640              
641 0     0     logpkg(__FILE__,__LINE__,'debug',sub{my %q = %p; delete $q{parent}; print
  0            
  0            
642 0           "=============\n%p\n",json_out(\%q)});
643              
644 0           $vol = make_scale ( \%p );
645             # Mute
646              
647             $mute = $gui->{track_frame}->Button(
648             -command => sub {
649 0     0     my $FX = fxn($vol_id);
650 0 0 0       if ( $FX->params->[0] != $config->{mute_level}->{$FX->type}
651             and $FX->params->[0] != $config->{fade_out_level}->{$FX->type}
652             ) { # non-zero volume
653 0           $ti{$n}->mute;
654 0           $mute->configure(-background => $gui->{_nama_palette}->{Mute});
655             }
656             else {
657 0           $ti{$n}->unmute;
658             $mute->configure(-background => $gui->{_nama_palette}->{OffBackground})
659 0           }
660             }
661 0           );
662              
663             # Unity
664              
665             $unity = $gui->{track_frame}->Button(
666             -command => sub {
667 0     0     my $FX = fxn($vol_id);
668             Audio::Nama::update_effect(
669             $vol_id,
670             0,
671 0           $config->{unity_level}->{$FX->type});
672             }
673 0           );
674             } else {
675              
676 0           $vol = $gui->{track_frame}->Label;
677 0           $mute = $gui->{track_frame}->Label;
678 0           $unity = $gui->{track_frame}->Label;
679              
680             }
681              
682 0 0         if ( Audio::Nama::need_vol_pan($ti{$n}->name, "pan") ){
683            
684             # Pan
685            
686 0           my $pan_id = $ti{$n}->pan;
687            
688 0           logpkg(__FILE__,__LINE__,'debug', "pan effect_id: $pan_id");
689 0           $p_num = 0; # first parameter
690             my %q = ( parent => \$gui->{track_frame},
691 0           chain => $n,
692             type => 'epp',
693             id => $pan_id,
694             p_num => $p_num,
695             );
696             # logpkg(__FILE__,__LINE__,'debug',sub{ my %q = %p; delete $q{parent}; print "x=============\n%p\n",json_out(\%q) });
697 0           $pan = make_scale ( \%q );
698              
699             # Center
700              
701             $center = $gui->{track_frame}->Button(
702             -command => sub {
703 0     0     Audio::Nama::update_effect($pan_id, 0, 50);
704             }
705 0           );
706             } else {
707              
708 0           $pan = $gui->{track_frame}->Label;
709 0           $center = $gui->{track_frame}->Label;
710             }
711            
712 0           my $effects = $gui->{fx_frame}->Frame->pack(-fill => 'both');;
713              
714             # effects, held by track_widget->n->effects is the frame for
715             # all effects of the track
716              
717 0           @{ $gui->{tracks}->{$n} }{qw(name version rw ch_r ch_m mute effects)}
  0            
718             = ($name, $version, $rw, $ch_r, $ch_m, $mute, \$effects);#a ref to the object
719             #logpkg(__FILE__,__LINE__,'debug', "=============$gui->{tracks}\n",sub{json_out($gui->{tracks})});
720             my $independent_effects_frame
721 0           = ${ $gui->{tracks}->{$n}->{effects} }->Frame->pack(-fill => 'x');
  0            
722              
723              
724             my $controllers_frame
725 0           = ${ $gui->{tracks}->{$n}->{effects} }->Frame->pack(-fill => 'x');
  0            
726            
727             # parents are the independent effects
728             # children are controllers for various paramters
729              
730 0           $gui->{tracks}->{$n}->{parents} = $independent_effects_frame;
731              
732 0           $gui->{tracks}->{$n}->{children} = $controllers_frame;
733            
734             $independent_effects_frame
735 0           ->Label(-text => uc $ti{$n}->name )->pack(-side => 'left');
736              
737             #logpkg(__FILE__,__LINE__,'debug',"Number: $n"),MainLoop if $n == 2;
738 0           my @tags = qw( EF P1 P2 L1 L2 L3 L4 );
739             my @starts = ( $fx_cache->{split}->{cop}{a},
740             $fx_cache->{split}->{preset}{a},
741             $fx_cache->{split}->{preset}{b},
742             $fx_cache->{split}->{ladspa}{a},
743             $fx_cache->{split}->{ladspa}{b},
744             $fx_cache->{split}->{ladspa}{c},
745             $fx_cache->{split}->{ladspa}{d},
746 0           );
747             my @ends = ( $fx_cache->{split}->{cop}{z},
748             $fx_cache->{split}->{preset}{b},
749             $fx_cache->{split}->{preset}{z},
750             $fx_cache->{split}->{ladspa}{b}-1,
751             $fx_cache->{split}->{ladspa}{c}-1,
752             $fx_cache->{split}->{ladspa}{d}-1,
753             $fx_cache->{split}->{ladspa}{z},
754 0           );
755 0           my @add_effect;
756              
757 0           map{push @add_effect, effect_button($n, shift @tags, shift @starts, shift @ends)} 1..@tags;
  0            
758            
759 0           $number->grid($name, $version, $rw, $ch_r, $ch_m, $vol, $mute, $unity, $pan, $center, @add_effect);
760              
761             $gui->{tracks_remove}->{$n} = [
762 0           grep{ $_ } (
  0            
763             $number,
764             $name,
765             $version,
766             $rw,
767             $ch_r,
768             $ch_m,
769             $vol,
770             $mute,
771             $unity,
772             $pan,
773             $center,
774             @add_effect,
775             $effects,
776             )
777             ];
778              
779 0           $ui->refresh_track($n);
780              
781             }
782              
783             sub remove_track_gui {
784 0     0     my $ui = shift;
785 0           my $n = shift;
786 0           logsub("&remove_track_gui");
787 0 0         return unless $gui->{tracks_remove}->{$n};
788 0           map {$_->destroy } @{ $gui->{tracks_remove}->{$n} };
  0            
  0            
789 0           delete $gui->{tracks_remove}->{$n};
790 0           delete $gui->{tracks}->{$n};
791             }
792              
793             sub paint_mute_buttons {
794             map{ $gui->{tracks}->{$_}{mute}->configure(
795             -background => $gui->{_nama_palette}->{Mute},
796              
797 0           )} grep { $ti{$_}->old_vol_level}# muted tracks
  0            
798 0     0     map { $_->n } Audio::Nama::audio_tracks(); # track numbers
  0            
799             }
800              
801             sub create_master_and_mix_tracks {
802 0     0     logsub("&create_master_and_mix_tracks");
803              
804              
805             my @rw_items = (
806             [ 'command' => "MON",
807             -command => sub {
808 0 0   0     return if Audio::Nama::eval_iam("engine-status") eq 'running';
809 0           $tn{Master}->set(rw => "MON");
810 0           $ui->refresh_track($tn{Master}->n);
811             }],
812             [ 'command' => "OFF",
813             -command => sub {
814 0 0   0     return if Audio::Nama::eval_iam("engine-status") eq 'running';
815 0           $tn{Master}->set(rw => "OFF");
816 0           $ui->refresh_track($tn{Master}->n);
817 0           }],
818             );
819              
820 0           $ui->track_gui( $tn{Master}->n, @rw_items );
821              
822 0           $ui->track_gui( $tn{Mixdown}->n);
823              
824             #$ui->group_gui('Main');
825             }
826              
827             sub update_version_button {
828 0     0     my $ui = shift;
829 0           my ($n, $v) = @_;
830 0 0         carp ("no version provided \n") if ! $v;
831 0           my $w = $gui->{tracks}->{$n}->{version};
832             $w->radiobutton(
833             -label => $v,
834             -value => $v,
835             -command =>
836             sub { $gui->{tracks}->{$n}->{version}->configure(-text=>$v)
837 0 0   0     unless $ti{$n}->rec_status eq "REC" }
838 0           );
839             }
840              
841             sub add_effect_gui {
842 0     0     logsub("&add_effect_gui");
843 0           my $ui = shift;
844 0           my %p = %{shift()};
  0            
845             my ($n,$code,$id,$parent,$parameter) =
846 0           @p{qw(chain type id parent parameter)};
847 0           my $i = $fx_cache->{full_label_to_index}->{$code};
848 0           my $FX = fxn($id);
849              
850 0     0     logpkg(__FILE__,__LINE__,'debug', sub{json_out(\%p)});
  0            
851              
852 0           logpkg(__FILE__,__LINE__,'debug', "id: $id, parent: $parent");
853             # $id is determined by effect_init, which will return the
854             # existing id if supplied
855              
856             # check display format, may be 'scale' 'field' or 'hidden'
857            
858 0           my $display_type = $FX->display; # individual setting
859 0 0         defined $display_type or $display_type = $fx_cache->{registry}->[$i]->{display}; # template
860 0           logpkg(__FILE__,__LINE__,'debug', "display type: $display_type");
861              
862 0 0         return if $display_type eq q(hidden);
863              
864 0           my $frame ;
865 0 0         if ( ! $parent ){ # independent effect
866             $frame = $gui->{tracks}->{$n}->{parents}->Frame->pack(
867 0           -side => 'left',
868             -anchor => 'nw',)
869             } else { # controller
870             $frame = $gui->{tracks}->{$n}->{children}->Frame->pack(
871 0           -side => 'top',
872             -anchor => 'nw')
873             }
874              
875 0           $gui->{fx}->{$id} = $frame;
876             # we need a separate frame so title can be long
877              
878             # here add menu items for Add Controller, and Remove
879              
880             my $parentage = $fx_cache->{registry}->[
881             $fx_cache->{full_label_to_index}->{$FX->type}
882 0           ]->{name};
883 0 0         $parentage and $parentage .= " - ";
884 0           logpkg(__FILE__,__LINE__,'debug', "parentage: $parentage");
885             my $eff = $frame->Menubutton(
886 0           -text => $parentage. $fx_cache->{registry}->[$i]->{name}, -tearoff => 0,);
887              
888             $eff->AddItems([
889             'command' => "Remove",
890 0     0     -command => sub { remove_effect($id) }
891 0           ]);
892 0           $eff->grid();
893 0           my @labels;
894             my @sliders;
895              
896             # make widgets
897              
898 0           for my $p (0..$fx_cache->{registry}->[$i]->{count} - 1 ) {
899 0           my @items;
900             #logpkg(__FILE__,__LINE__,'debug', "p_first: $p_first, p_last: $p_last");
901 0           for my $j ($fx_cache->{split}->{ctrl}{a}..$fx_cache->{split}->{ctrl}{z}) {
902             push @items,
903             [ 'command' => $fx_cache->{registry}->[$j]->{name},
904             -command => sub { add_effect({
905             parent => $id,
906             chain => $n,
907             params => [ $p + 1 ],
908 0     0     type => $fx_cache->{registry}->[$j]->{code} }) }
909 0           ];
910              
911             }
912             push @labels, $frame->Menubutton(
913             -text => $fx_cache->{registry}->[$i]->{params}->[$p]->{name},
914 0           -menuitems => [@items],
915             -tearoff => 0,
916             );
917             logpkg(__FILE__,__LINE__,'debug', "parameter name: ",
918 0           $fx_cache->{registry}->[$i]->{params}->[$p]->{name});
919 0           my $v = # for argument vector
920             { parent => \$frame,
921             id => $id,
922             p_num => $p,
923             };
924 0           push @sliders,make_scale($v);
925             }
926              
927 0 0         if (@sliders) {
928              
929 0           $sliders[0]->grid(@sliders[1..$#sliders]);
930 0           $labels[0]->grid(@labels[1..$#labels]);
931             }
932             }
933              
934              
935             sub project_label_configure{
936 0     0     my $ui = shift;
937 0           $gui->{project_head}->configure( @_ ) }
938              
939             sub length_display{
940 0     0     my $ui = shift;
941 0           $gui->{setup_length}->configure(@_)};
942              
943             sub clock_config {
944 0     0     my $ui = shift;
945 0           $gui->{clock}->configure( @_ )}
946              
947 0     0     sub manifest { $gui->{ew}->deiconify() }
948              
949             sub destroy_widgets {
950              
951 0     0     map{ $_->destroy } map{ $_->children } $gui->{fx_frame};
  0            
  0            
952             #my @children = $gui->{group_frame}->children;
953             #map{ $_->destroy } @children[1..$#children];
954 0           my @children = $gui->{track_frame}->children;
955             # leave field labels (first row)
956 0           map{ $_->destroy } @children[11..$#children]; # fragile
  0            
957 0 0         %{$gui->{marks}} and map{ $_->destroy } values %{$gui->{marks}};
  0            
  0            
  0            
958             }
959             sub remove_effect_gui {
960 0     0     my $ui = shift;
961 0           logsub("&remove_effect_gui");
962 0           my $id = shift;
963 0           my $FX = fxn($id);
964 0           my $n = $FX->chain;
965 0           logpkg(__FILE__,__LINE__,'debug', "id: $id, chain: $n");
966              
967 0           logpkg(__FILE__,__LINE__,'debug', "i have widgets for these ids: ", join " ",keys %{$gui->{fx}});
  0            
968 0           logpkg(__FILE__,__LINE__,'debug', "preparing to destroy: $id");
969 0 0         return unless defined $gui->{fx}->{$id};
970 0           $gui->{fx}->{$id}->destroy();
971 0           delete $gui->{fx}->{$id};
972              
973             }
974              
975             sub effect_button {
976 0     0     logsub("&effect_button");
977 0           my ($n, $label, $start, $end) = @_;
978 0           logpkg(__FILE__,__LINE__,'debug', "chain $n label $label start $start end $end");
979 0           my @items;
980             my $widget;
981 0           my @indices = ($start..$end);
982 0 0 0       if ($start >= $fx_cache->{split}->{ladspa}{a} and $start <= $fx_cache->{split}->{ladspa}{z}){
983 0           @indices = ();
984 0           @indices = @{$fx_cache->{ladspa_sorted}}[$start..$end];
  0            
985 0           logpkg(__FILE__,__LINE__,'debug', "length sorted indices list: ",scalar @indices );
986 0           logpkg(__FILE__,__LINE__,'debug', "Indices: @indices");
987             }
988            
989 0           for my $j (@indices) {
990             push @items,
991             [ 'command' => "$fx_cache->{registry}->[$j]->{count} $fx_cache->{registry}->[$j]->{name}" ,
992             -command => sub {
993 0     0     add_effect( {chain => $n, type => $fx_cache->{registry}->[$j]->{code} } );
994 0           $gui->{ew}->deiconify; # display effects window
995             }
996 0           ];
997             }
998             $widget = $gui->{track_frame}->Menubutton(
999 0           -text => $label,
1000             -tearoff =>0,
1001             # -relief => 'raised',
1002             -menuitems => [@items],
1003             );
1004 0           $widget;
1005             }
1006              
1007             sub make_scale {
1008            
1009 0     0     logsub("&make_scale");
1010 0           my $ref = shift;
1011 0           my %p = %{$ref};
  0            
1012             # %p contains following:
1013             # id => operator id
1014             # parent => parent widget, i.e. the frame
1015             # p_num => parameter number, starting at 0
1016             # length => length widget # optional
1017 0           my $id = $p{id};
1018 0           my $FX = fxn($id);
1019 0           my $n = $FX->chain;
1020 0           my $code = $FX->type;
1021 0           my $p = $p{p_num};
1022 0           my $i = $fx_cache->{full_label_to_index}->{$code};
1023              
1024 0           logpkg(__FILE__,__LINE__,'debug', "id: $id code: $code");
1025            
1026              
1027             # check display format, may be text-field or hidden,
1028              
1029 0           logpkg(__FILE__,__LINE__,'debug',"i: $i code: $fx_cache->{registry}->[$i]->{code} display: $fx_cache->{registry}->[$i]->{display}");
1030 0           my $display_type = $FX->display;
1031 0 0         defined $display_type or $display_type = $fx_cache->{registry}->[$i]->{display};
1032 0           logpkg(__FILE__,__LINE__,'debug', "display type: $display_type");
1033 0 0         return if $display_type eq q(hidden);
1034              
1035              
1036 0           logpkg(__FILE__,__LINE__,'debug', "to: ", $fx_cache->{registry}->[$i]->{params}->[$p]->{end}) ;
1037 0           logpkg(__FILE__,__LINE__,'debug', "p: $p code: $code");
1038 0           logpkg(__FILE__,__LINE__,'debug', "is_log_scale: ".is_log_scale($i,$p));
1039              
1040             # set display type to individually specified value if it exists
1041             # otherwise to the default for the controller class
1042              
1043              
1044            
1045 0 0         if ($display_type eq q(scale) ) {
    0          
1046              
1047             # return scale type controller widgets
1048 0           my $frame = ${ $p{parent} }->Frame;
  0            
1049            
1050              
1051             #return ${ $p{parent} }->Scale(
1052            
1053 0           my $log_display;
1054            
1055             my $controller = $frame->Scale(
1056             -variable => \$FX->{params}->[$p],
1057             -orient => 'horizontal',
1058             -from => $fx_cache->{registry}->[$i]->{params}->[$p]->{begin},
1059             -to => $fx_cache->{registry}->[$i]->{params}->[$p]->{end},
1060             -resolution => resolution($i, $p),
1061             -width => 12,
1062             -length => $p{length} ? $p{length} : 100,
1063 0     0     -command => sub { Audio::Nama::_update_effect($id, $p, $FX->params->[$p]) },
1064 0 0         -state => $FX->is_read_only($p) ? 'disabled' : 'normal',
    0          
1065             );
1066              
1067             # auxiliary field for logarithmic display
1068 0 0         if ( is_log_scale($i, $p) )
1069             # or $code eq 'ea')
1070             {
1071             my $log_display = $frame->Label(
1072             -text => exp $fx_cache->{registry}->[$i]->{params}->[$p]->{default},
1073 0           -width => 5,
1074             );
1075             $controller->configure(
1076             -variable => \$FX->{params_log}->[$p],
1077             -command => sub {
1078 0     0     $FX->params->[$p] = exp $FX->params_log->[$p];
1079 0           Audio::Nama::_update_effect($id, $p, $FX->params->[$p]);
1080             $log_display->configure(
1081             -text =>
1082 0 0         $fx_cache->{registry}->[$i]->{params}->[$p]->{name} =~ /hz|frequency/i
1083             ? int $FX->params->[$p]
1084             : dn($FX->params->[$p], 1)
1085             );
1086             }
1087 0           );
1088 0           $log_display->grid($controller);
1089             }
1090 0           else { $controller->grid; }
1091              
1092 0           return $frame;
1093              
1094             }
1095              
1096             elsif ($display_type eq q(field) ){
1097              
1098             # then return field type controller widget
1099              
1100 0           return ${ $p{parent} }->Entry(
  0            
1101             -textvariable =>\$FX->params->[$p],
1102             -width => 6,
1103             # -command => sub { Audio::Nama::_update_effect($id, $p, $FX->params->[$p]) },
1104             # doesn't work with Entry widget
1105             );
1106              
1107             }
1108 0           else { croak "missing or unexpected display type: $display_type" }
1109              
1110             }
1111              
1112             sub is_log_scale {
1113 0     0     my ($i, $p) = @_;
1114 0           $fx_cache->{registry}->[$i]->{params}->[$p]->{hint} =~ /logarithm/
1115             }
1116             sub resolution {
1117 0     0     my ($i, $p) = @_;
1118 0           my $res = $fx_cache->{registry}->[$i]->{params}->[$p]->{resolution};
1119 0 0         return $res if $res;
1120 0           my $end = $fx_cache->{registry}->[$i]->{params}->[$p]->{end};
1121 0           my $beg = $fx_cache->{registry}->[$i]->{params}->[$p]->{begin};
1122 0 0         return 1 if abs($end - $beg) > 30;
1123 0           return abs($end - $beg)/100
1124             }
1125              
1126             sub arm_mark_toggle {
1127 0 0   0     if ($gui->{_markers_armed}) {
1128 0           $gui->{_markers_armed} = 0;
1129 0           $gui->{mark_remove}->configure( -background => $gui->{_nama_palette}->{OffBackground});
1130             } else{
1131 0           $gui->{_markers_armed} = 1;
1132 0           $gui->{mark_remove}->configure( -background => $gui->{_nama_palette}->{MarkArmed});
1133             }
1134             }
1135             sub marker {
1136 0     0     my $ui = shift;
1137 0           my $mark = shift; # Mark
1138 0           logpkg(__FILE__,__LINE__,'debug',"mark is ", ref $mark);
1139 0           my $pos = $mark->time;
1140 0           logpkg(__FILE__,__LINE__,'debug',$pos, " ", int $pos);
1141             $gui->{marks}->{$pos} = $gui->{mark_frame}->Button(
1142             -text => (join " ", colonize( int $pos ), $mark->name),
1143             -background => $gui->{_nama_palette}->{OffBackground},
1144 0     0     -command => sub { Audio::Nama::mark($mark) },
1145 0           )->pack(-side => 'left');
1146             }
1147              
1148             sub restore_time_marks {
1149 0     0     my $ui = shift;
1150 0           map{ $ui->marker($_) } Audio::Nama::Mark::all() ;
  0            
1151 0 0         $gui->{seek_unit}->configure( -text => $gui->{_seek_unit} == 1 ? q(Sec) : q(Min) )
1152             }
1153             sub destroy_marker {
1154 0     0     my $ui = shift;
1155 0           my $pos = shift;
1156 0           $gui->{marks}->{$pos}->destroy;
1157             }
1158              
1159              
1160             sub get_saved_colors {
1161 0     0     logsub("&get_saved_colors");
1162              
1163             # aliases
1164            
1165 0           $gui->{_old_bg} = $gui->{_palette}{mw}{background};
1166 0           $gui->{_old_abg} = $gui->{_palette}{mw}{activeBackground};
1167 0   0       $gui->{_old_bg} //= '#d915cc1bc3cf';
1168             #print "pb: $gui->{_palette}{mw}{background}\n";
1169              
1170              
1171 0           my $pal = $file->gui_palette;
1172 0 0         $pal .= '.json' unless $pal =~ /\.json$/;
1173 0           pager("pal $pal");
1174 0 0         $pal = -f $pal
1175             ? scalar read_file($pal)
1176             : get_data_section('default_palette_json');
1177 0           my $ref = decode($pal, 'json');
1178             #say "palette file",json_out($ref);
1179              
1180 0           assign_singletons({ data => $ref });
1181            
1182 0           $gui->{_old_abg} = $gui->{_palette}->{mw}{activeBackground};
1183 0 0         $gui->{_old_abg} = $gui->{project_head}->cget('-activebackground') unless $gui->{_old_abg};
1184             #print "1palette: \n", json_out( $gui->{_palette} );
1185             #print "\n1namapalette: \n", json_out($gui->{_nama_palette});
1186 0           my %setformat;
1187 0 0         map{ $setformat{$_} = $gui->{_palette}->{mw}{$_} if $gui->{_palette}->{mw}{$_} }
1188 0           keys %{$gui->{_palette}->{mw}};
  0            
1189             #print "\nsetformat: \n", json_out(\%setformat);
1190 0           $gui->{mw}->setPalette( %setformat );
1191             }
1192             sub colorset {
1193 0     0     my ($widgetid, $field) = @_;
1194             sub {
1195 0     0     my $widget = $gui->{$widgetid};
1196             #print "ancestor: $widgetid\n";
1197 0           my $new_color = colorchooser($field,$widget->cget("-$field"));
1198 0 0         if( defined $new_color ){
1199            
1200             # install color in palette listing
1201 0           $gui->{_palette}->{$widgetid}{$field} = $new_color;
1202              
1203             # set the color
1204 0           my @fields = ($field => $new_color);
1205 0 0         push (@fields, 'background', $widget->cget('-background'))
1206             unless $field eq 'background';
1207             #print "fields: @fields\n";
1208 0           $widget->setPalette( @fields );
1209             }
1210 0           };
1211             }
1212              
1213             sub namaset {
1214 0     0     my ($field) = @_;
1215             sub {
1216             #print "f: $field np: $gui->{_nama_palette}->{$field}\n";
1217 0     0     my $color = colorchooser($field,$gui->{_nama_palette}->{$field});
1218 0 0         if ($color){
1219             # install color in palette listing
1220 0           $gui->{_nama_palette}->{$field} = $color;
1221              
1222             # set those objects who are not
1223             # handled by refresh
1224 0           *rec = \$gui->{_nama_palette}->{RecBackground};
1225 0           *mon = \$gui->{_nama_palette}->{MonBackground};
1226 0           *off = \$gui->{_nama_palette}->{OffBackground};
1227              
1228             $gui->{clock}->configure(
1229             -background => $gui->{_nama_palette}->{ClockBackground},
1230             -foreground => $gui->{_nama_palette}->{ClockForeground},
1231 0           );
1232             $gui->{group_label}->configure(
1233             -background => $gui->{_nama_palette}->{GroupBackground},
1234             -foreground => $gui->{_nama_palette}->{GroupForeground},
1235 0           );
1236 0           refresh();
1237             }
1238             }
1239              
1240 0           }
1241              
1242             sub colorchooser {
1243 0     0     logsub("&colorchooser");
1244 0           my ($field, $initialcolor) = @_;
1245 0           logpkg(__FILE__,__LINE__,'debug', "field: $field, initial color: $initialcolor");
1246             my $new_color = $gui->{mw}->chooseColor(
1247 0           -title => $field,
1248             -initialcolor => $initialcolor,
1249             );
1250             #print "new color: $new_color\n";
1251 0           $new_color;
1252             }
1253             sub init_palettefields {
1254 0     0     @{$gui->{_palette_fields}} = qw[
  0            
1255             foreground
1256             background
1257             activeForeground
1258             activeBackground
1259             selectForeground
1260             selectBackground
1261             selectColor
1262             highlightColor
1263             highlightBackground
1264             disabledForeground
1265             insertBackground
1266             troughColor
1267             ];
1268              
1269 0           @{$gui->{_nama_fields}} = qw [
  0            
1270             RecForeground
1271             RecBackground
1272             MonForeground
1273             MonBackground
1274             OffForeground
1275             OffBackground
1276             ClockForeground
1277             ClockBackground
1278             Capture
1279             Play
1280             Mixdown
1281             GroupForeground
1282             GroupBackground
1283             SendForeground
1284             SendBackground
1285             SourceForeground
1286             SourceBackground
1287             Mute
1288             MarkArmed
1289             ];
1290             }
1291              
1292             sub save_palette {
1293 0     0     serialize (
1294             file => $file->gui_palette,
1295             format => 'json',
1296             vars => [ qw( $gui->{_palette} $gui->{_nama_palette} ) ],
1297             class => 'Audio::Nama')
1298             }
1299              
1300             ### end
1301              
1302              
1303              
1304             ## refresh functions
1305              
1306             sub set_widget_color {
1307 0     0     my ($widget, $status) = @_;
1308             my %rw_foreground = ( REC => $gui->{_nama_palette}->{RecForeground},
1309             PLAY => $gui->{_nama_palette}->{MonForeground},
1310             MON => $gui->{_nama_palette}->{MonForeground},
1311             OFF => $gui->{_nama_palette}->{OffForeground},
1312 0           );
1313              
1314             my %rw_background = ( REC => $gui->{_nama_palette}->{RecBackground},
1315             PLAY => $gui->{_nama_palette}->{MonBackground},
1316             MON => $gui->{_nama_palette}->{MonBackground},
1317 0           OFF => $gui->{_nama_palette}->{OffBackground});
1318              
1319 0           $widget->configure( -background => $rw_background{$status} );
1320 0           $widget->configure( -foreground => $rw_foreground{$status} );
1321             }
1322             sub refresh_group {
1323             # main group, in this case we want to skip null group
1324 0     0     logsub("&refresh_group");
1325            
1326            
1327 0           my $status;
1328 0 0         if ( grep{ $_->rec_status eq REC}
  0 0          
1329 0           map{ $tn{$_} }
1330             $bn{Main}->tracks ){
1331              
1332 0           $status = REC
1333              
1334 0           }elsif( grep{ $_->rec_status eq PLAY}
1335 0           map{ $tn{$_} }
1336             $bn{Main}->tracks ){
1337              
1338 0           $status = PLAY
1339              
1340             }else{
1341            
1342 0           $status = OFF }
1343              
1344 0           logit(__LINE__,'Audio::Nama::Refresh','debug', "group status: $status");
1345              
1346 0           set_widget_color($gui->{group_rw}, $status);
1347              
1348              
1349              
1350 0 0         croak "some crazy status |$status|\n" if $status !~ m/rec|mon|off/i;
1351             #logit(__LINE__,'Audio::Nama::Refresh','debug', "attempting to set $status color: ", $take_color{$status});
1352              
1353 0 0         set_widget_color( $gui->{group_rw}, $status) if $gui->{group_rw};
1354             }
1355             sub refresh_track {
1356            
1357 0     0     my $ui = shift;
1358 0           my $n = shift;
1359 0           logsub("&refresh_track");
1360            
1361 0           my $rec_status = $ti{$n}->rec_status;
1362 0           logit(__LINE__,'Audio::Nama::Refresh','debug', "track: $n rec_status: $rec_status");
1363              
1364 0 0         return unless $gui->{tracks}->{$n}; # hidden track
1365            
1366             # set the text for displayed fields
1367              
1368 0           $gui->{tracks}->{$n}->{rw}->configure(-text => $rec_status);
1369             $gui->{tracks}->{$n}->{ch_r}->configure( -text =>
1370             $n > 2
1371 0 0         ? $ti{$n}->source
1372             : q() );
1373 0           $gui->{tracks}->{$n}->{ch_m}->configure( -text => $ti{$n}->send);
1374 0   0       $gui->{tracks}->{$n}->{version}->configure(-text => $ti{$n}->current_version || "");
1375            
1376 0           map{ set_widget_color( $gui->{tracks}->{$n}->{$_},
  0            
1377             $rec_status)
1378             } qw(name rw );
1379            
1380             set_widget_color( $gui->{tracks}->{$n}->{ch_r},
1381            
1382 0 0 0       ($rec_status eq REC
1383             and $n > 2 )
1384             ? REC
1385             : OFF);
1386            
1387             set_widget_color( $gui->{tracks}->{$n}->{ch_m},
1388             $rec_status eq OFF
1389             ? OFF
1390 0 0         : $ti{$n}->send
    0          
1391             ? MON
1392             : OFF);
1393             }
1394              
1395             sub refresh {
1396 0     0     Audio::Nama::remove_riff_header_stubs();
1397             #$ui->refresh_group();
1398             #map{ $ui->refresh_track($_) } map{$_->n} grep{! $_->hide} Audio::Nama::audio_tracks();
1399             #map{ $ui->refresh_track($_) } grep{$remove_track_widget{$_} map{$_->n} Audio::Nama::audio_tracks();
1400 0           map{ $ui->refresh_track($_) } map{$_->n} Audio::Nama::audio_tracks();
  0            
  0            
1401             }
1402             ### end
1403              
1404              
1405             1;
1406              
1407             __END__