Commit 8297d064 authored by Ivica Bukvic's avatar Ivica Bukvic
Browse files

*added Jonathan's new preferences dialog (needs further testing)

parent 82c15e73
package provide dialog_array 0.1
# todo: probably not a bad idea to unset these arrays
namespace eval ::dialog_array:: {
namespace export pdtk_array_dialog
namespace export pdtk_array_listview_new
namespace export pdtk_array_listview_fillpage
namespace export pdtk_array_listview_setpage
namespace export pdtk_array_listview_closeWindow
}
# global variables for the listview
array set pd_array_listview_entry {}
array set pd_array_listview_id {}
array set pd_array_listview_page {}
set pd_array_listview_pagesize 0
# this stores the state of the "save me" check button
array set saveme_button {}
# this stores the state of the "joc" check button
array set joc_button {}
# whether to hide the array name
array set hidename_button {}
# this stores the state of the "draw as" radio buttons
array set drawas_button {}
# border color for an element
array set pd_array_outlinecolor {}
# inner color for an element
array set pd_array_fillcolor {}
# this stores the state of the "in new graph"/"in last graph" radio buttons
# and the "delete array" checkbutton
array set otherflag_button {}
# TODO figure out how to escape $ args so sharptodollar() isn't needed
############ pdtk_array_dialog -- dialog window for arrays #########
# hack: this should just use ::pd_bindings::dialog_bindings from 0.43 API
proc ::dialog_array::dialog_bindings {mytoplevel dialogname} {
variable modifier
bind $mytoplevel <KeyPress-Escape> "dialog_${dialogname}::cancel $mytoplevel"
bind $mytoplevel <KeyPress-Return> "dialog_${dialogname}::ok $mytoplevel"
bind $mytoplevel <$::modifier-Key-w> "dialog_${dialogname}::cancel $mytoplevel"
# these aren't supported in the dialog, so alert the user, then break so
# that no other key bindings are run
bind $mytoplevel <$::modifier-Key-s> {bell; break}
bind $mytoplevel <$::modifier-Shift-Key-S> {bell; break}
bind $mytoplevel <$::modifier-Key-p> {bell; break}
wm protocol $mytoplevel WM_DELETE_WINDOW "dialog_${dialogname}::cancel $mytoplevel"
}
proc ::dialog_array::pdtk_array_listview_setpage {arrayName page} {
set ::pd_array_listview_page($arrayName) $page
}
proc ::dialog_array::listview_changepage {arrayName np} {
pdtk_array_listview_setpage \
$arrayName [expr $::pd_array_listview_page($arrayName) + $np]
pdtk_array_listview_fillpage $arrayName
}
proc ::dialog_array::pdtk_array_listview_fillpage {arrayName} {
set windowName [format ".%sArrayWindow" $arrayName]
set topItem [expr [lindex [$windowName.lb yview] 0] * \
[$windowName.lb size]]
if {[winfo exists $windowName]} {
set cmd "$::pd_array_listview_id($arrayName) \
arrayviewlistfillpage \
$::pd_array_listview_page($arrayName) \
$topItem"
pdsend $cmd
}
}
proc ::dialog_array::pdtk_array_listview_new {id arrayName page} {
set ::pd_array_listview_page($arrayName) $page
set ::pd_array_listview_id($arrayName) $id
set windowName [format ".%sArrayWindow" $arrayName]
if [winfo exists $windowName] then [destroy $windowName]
toplevel $windowName -class DialogWindow
wm group $windowName .
wm protocol $windowName WM_DELETE_WINDOW \
"::dialog_array::listview_close $id $arrayName"
wm title $windowName [concat $arrayName "(list view)"]
# FIXME
set font 12
set $windowName.lb [listbox $windowName.lb -height 20 -width 25\
-selectmode extended \
-relief solid -background white -borderwidth 1 \
-font [format {{%s} %d %s} $::font_family $font $::font_weight]\
-yscrollcommand "$windowName.lb.sb set"]
set $windowName.lb.sb [scrollbar $windowName.lb.sb \
-command "$windowName.lb yview" -orient vertical]
place configure $windowName.lb.sb -relheight 1 -relx 0.9 -relwidth 0.1
pack $windowName.lb -expand 1 -fill both
bind $windowName.lb <Double-ButtonPress-1> \
"::dialog_array::listview_edit $arrayName $page $font"
# handle copy/paste
switch -- $::windowingsystem {
"x11" {selection handle $windowName.lb \
"::dialog_array::listview_lbselection $arrayName"}
"win32" {bind $windowName.lb <ButtonPress-3> \
"::dialog_array::listview_popup $arrayName"}
}
set $windowName.prevBtn [button $windowName.prevBtn -text "<-" \
-command "::dialog_array::listview_changepage $arrayName -1"]
set $windowName.nextBtn [button $windowName.nextBtn -text "->" \
-command "::dialog_array::listview_changepage $arrayName 1"]
pack $windowName.prevBtn -side left -ipadx 20 -pady 10 -anchor s
pack $windowName.nextBtn -side right -ipadx 20 -pady 10 -anchor s
focus $windowName
}
proc ::dialog_array::listview_lbselection {arrayName off size} {
set windowName [format ".%sArrayWindow" $arrayName]
set itemNums [$windowName.lb curselection]
set cbString ""
for {set i 0} {$i < [expr [llength $itemNums] - 1]} {incr i} {
set listItem [$windowName.lb get [lindex $itemNums $i]]
append cbString [string range $listItem \
[expr [string first ") " $listItem] + 2] \
end]
append cbString "\n"
}
set listItem [$windowName.lb get [lindex $itemNums $i]]
append cbString [string range $listItem \
[expr [string first ") " $listItem] + 2] \
end]
set last $cbString
}
# Win32 uses a popup menu for copy/paste
proc ::dialog_array::listview_popup {arrayName} {
set windowName [format ".%sArrayWindow" $arrayName]
if [winfo exists $windowName.popup] then [destroy $windowName.popup]
menu $windowName.popup -tearoff false
$windowName.popup add command -label [_ "Copy"] \
-command "::dialog_array::listview_copy $arrayName; \
destroy $windowName.popup"
$windowName.popup add command -label [_ "Paste"] \
-command "::dialog_array::listview_paste $arrayName; \
destroy $windowName.popup"
tk_popup $windowName.popup [winfo pointerx $windowName] \
[winfo pointery $windowName] 0
}
proc ::dialog_array::listview_copy {arrayName} {
set windowName [format ".%sArrayWindow" $arrayName]
set itemNums [$windowName.lb curselection]
set cbString ""
for {set i 0} {$i < [expr [llength $itemNums] - 1]} {incr i} {
set listItem [$windowName.lb get [lindex $itemNums $i]]
append cbString [string range $listItem \
[expr [string first ") " $listItem] + 2] \
end]
append cbString "\n"
}
set listItem [$windowName.lb get [lindex $itemNums $i]]
append cbString [string range $listItem \
[expr [string first ") " $listItem] + 2] \
end]
clipboard clear
clipboard append $cbString
}
proc ::dialog_array::listview_paste {arrayName} {
set cbString [selection get -selection CLIPBOARD]
set lbName [format ".%sArrayWindow.lb" $arrayName]
set itemNum [lindex [$lbName curselection] 0]
set splitChars ", \n"
set itemString [split $cbString $splitChars]
set flag 1
for {set i 0; set counter 0} {$i < [llength $itemString]} {incr i} {
if {[lindex $itemString $i] ne {}} {
pdsend "$arrayName [expr $itemNum + \
[expr $counter + \
[expr $::pd_array_listview_pagesize \
* $::pd_array_listview_page($arrayName)]]] \
[lindex $itemString $i]"
incr counter
set flag 0
}
}
}
proc ::dialog_array::listview_edit {arrayName page font} {
set lbName [format ".%sArrayWindow.lb" $arrayName]
if {[winfo exists $lbName.entry]} {
::dialog_array::listview_update_entry \
$arrayName $::pd_array_listview_entry($arrayName)
unset ::pd_array_listview_entry($arrayName)
}
set itemNum [$lbName index active]
set ::pd_array_listview_entry($arrayName) $itemNum
set bbox [$lbName bbox $itemNum]
set y [expr [lindex $bbox 1] - 4]
set $lbName.entry [entry $lbName.entry \
-font [format {{%s} %d %s} $::font_family $font $::font_weight]]
$lbName.entry insert 0 []
place configure $lbName.entry -relx 0 -y $y -relwidth 1
lower $lbName.entry
focus $lbName.entry
bind $lbName.entry <Return> \
"::dialog_array::listview_update_entry $arrayName $itemNum;"
}
proc ::dialog_array::listview_update_entry {arrayName itemNum} {
set lbName [format ".%sArrayWindow.lb" $arrayName]
set splitChars ", \n"
set itemString [split [$lbName.entry get] $splitChars]
set flag 1
for {set i 0; set counter 0} {$i < [llength $itemString]} {incr i} {
if {[lindex $itemString $i] ne {}} {
pdsend "$arrayName [expr $itemNum + \
[expr $counter + \
[expr $::pd_array_listview_pagesize \
* $::pd_array_listview_page($arrayName)]]] \
[lindex $itemString $i]"
incr counter
set flag 0
}
}
pdtk_array_listview_fillpage $arrayName
destroy $lbName.entry
}
proc ::dialog_array::pdtk_array_listview_closeWindow {arrayName} {
set mytoplevel [format ".%sArrayWindow" $arrayName]
destroy $mytoplevel
}
proc ::dialog_array::listview_close {mytoplevel arrayName} {
pdtk_array_listview_closeWindow $arrayName
pdsend "$mytoplevel arrayviewclose"
}
proc ::dialog_array::apply {mytoplevel} {
# TODO figure out how to ditch this escaping mechanism
set mofo [$mytoplevel.name.entry get]
if {[string index $mofo 0] == "$"} {
set mofo [string replace $mofo 0 0 #] }
pdtk_post "drawas is $::drawas_button($mytoplevel)\n"
pdtk_post "full bajitas is \
[expr $::saveme_button($mytoplevel) + \
(2 * $::drawas_button($mytoplevel)) + \
(8 * $::hidename_button($mytoplevel)) + \
(16 * $::joc_button($mytoplevel))] \
\n"
pdtk_post "mytop fucking level is $mytoplevel\n"
pd "[concat $mytoplevel arraydialog \
$mofo \
[$mytoplevel.size.entry get] \
[expr $::saveme_button($mytoplevel) + \
(2 * $::drawas_button($mytoplevel)) + \
(8 * $::hidename_button($mytoplevel)) + \
(16 * $::joc_button($mytoplevel))] \
$::otherflag_button($mytoplevel) \
$::pd_array_fillcolor($mytoplevel) \
$::pd_array_outlinecolor($mytoplevel) \
\; ]"
}
proc ::dialog_array::openlistview {mytoplevel} {
pdsend "$mytoplevel arrayviewlistnew"
}
proc ::dialog_array::choosecolor {mytoplevel type} {
set colorp [format "::pd_array_%scolor(%s)" $type $mytoplevel]
if {[info exists $colorp]} {
set initcolor [set $colorp]
} else {
set initcolor "black"}
set tmp [tk_chooseColor -parent $mytoplevel -initialcolor $initcolor]
if {$tmp eq ""} {return} else {set $colorp $tmp}
}
proc ::dialog_array::update_colorpreview {color widget args} {
upvar #0 $color c
$widget configure -background $c -activebackground $c
}
proc ::dialog_array::update_drawas {mytoplevel outlineframe filllabel args} {
if {$::drawas_button($mytoplevel) == 3} {
pack $outlineframe -before $mytoplevel.colors.o -side top -anchor w
$filllabel configure -text "Outline color"
} else {
pack forget $outlineframe
$filllabel configure -text "Trace color"
}
}
proc ::dialog_array::cancel {mytoplevel} {
pd "[concat $mytoplevel cancel \;]"
}
proc ::dialog_array::ok {mytoplevel} {
::dialog_array::apply $mytoplevel
::dialog_array::cancel $mytoplevel
}
proc ::dialog_array::pdtk_array_dialog {mytoplevel name \
size flags newone fillcolor outlinecolor} {
if {[catch {
if {[winfo exists $mytoplevel]} {
wm deiconify $mytoplevel
raise $mytoplevel
} else {
create_dialog $mytoplevel $newone
}
} fid]} {pdtk_post "error: $fid\n"}
$mytoplevel.name.entry insert 0 $name
$mytoplevel.size.entry insert 0 $size
set ::saveme_button($mytoplevel) [expr $flags & 1]
set ::drawas_button($mytoplevel) [expr ( $flags & 6 ) >> 1]
set ::hidename_button($mytoplevel) [expr ( $flags & 8 ) >> 3]
set ::joc_button($mytoplevel) [expr ( $flags & 16) >> 4]
set ::otherflag_button($mytoplevel) 0
set ::pd_array_fillcolor($mytoplevel) $fillcolor
set ::pd_array_outlinecolor($mytoplevel) $outlinecolor
# pd -> tcl
# 2 * (int)(template_getfloat(template_findbyname(sc->sc_template), gensym("style"), x->x_scalar->sc_vec, 1)));
# tcl->pd
# int style = ((flags & 6) >> 1);
}
proc ::dialog_array::create_dialog {mytoplevel newone} {
toplevel $mytoplevel -class DialogWindow
wm title $mytoplevel [_ "Array Properties"]
wm group $mytoplevel .
wm resizable $mytoplevel 0 0
# wm transient $mytoplevel $::focused_window
$mytoplevel configure -menu $::dialog_menubar
$mytoplevel configure -padx 0 -pady 0
# bad hack... this should just be ::pd_bindings::
# from the 0.43 API
::dialog_array::dialog_bindings $mytoplevel "array"
frame $mytoplevel.name
pack $mytoplevel.name -side top
label $mytoplevel.name.label -text [_ "Name:"]
entry $mytoplevel.name.entry
pack $mytoplevel.name.label $mytoplevel.name.entry -anchor w
frame $mytoplevel.size
pack $mytoplevel.size -side top
label $mytoplevel.size.label -text [_ "Size:"]
entry $mytoplevel.size.entry
pack $mytoplevel.size.label $mytoplevel.size.entry -anchor w
frame $mytoplevel.flags
pack $mytoplevel.flags -side top -fill x -padx 20
checkbutton $mytoplevel.flags.saveme -text [_ "Save contents"] \
-variable ::saveme_button($mytoplevel)
pack $mytoplevel.flags.saveme -side top -anchor w
checkbutton $mytoplevel.flags.joc -text [_ "Jump on click"] \
-variable ::joc_button($mytoplevel) -anchor w
pack $mytoplevel.flags.joc -side top -anchor w
checkbutton $mytoplevel.flags.hidename -text [_ "Hide array name"] \
-variable ::hidename_button($mytoplevel) -anchor w
pack $mytoplevel.flags.hidename -side top -anchor w
labelframe $mytoplevel.drawas -text [_ "Draw as:"] -padx 20 -borderwidth 1
pack $mytoplevel.drawas -side top -fill x
radiobutton $mytoplevel.drawas.points -value 1 \
-variable ::drawas_button($mytoplevel) -text [_ "Points"]
radiobutton $mytoplevel.drawas.polygon -value 0 \
-variable ::drawas_button($mytoplevel) -text [_ "Polygon"]
radiobutton $mytoplevel.drawas.bezier -value 2 \
-variable ::drawas_button($mytoplevel) -text [_ "Bezier curve"]
radiobutton $mytoplevel.drawas.bargraph -value 3 \
-variable ::drawas_button($mytoplevel) -text [_ "Bargraph"]
pack $mytoplevel.drawas.points -side top -anchor w
pack $mytoplevel.drawas.polygon -side top -anchor w
pack $mytoplevel.drawas.bezier -side top -anchor w
pack $mytoplevel.drawas.bargraph -side top -anchor w
trace add variable ::drawas_button($mytoplevel) write \
"::dialog_array::update_drawas $mytoplevel $mytoplevel.colors.f \
$mytoplevel.colors.o.outlinecolor"
set fillp ::pd_array_fillcolor($mytoplevel)
set outlinep ::pd_array_outlinecolor($mytoplevel)
labelframe $mytoplevel.colors -text [_ "Colors:"] -padx 20 -pady 5 \
-borderwidth 1
pack $mytoplevel.colors -side top -fill both
frame $mytoplevel.colors.f
frame $mytoplevel.colors.o
pack $mytoplevel.colors.f -side top -anchor w
pack $mytoplevel.colors.o -side top -anchor w
set fillpreview $mytoplevel.colors.f.preview
set flabel [label $mytoplevel.colors.f.fillcolor -text [_ "Fill color"]]
set olabel \
[label $mytoplevel.colors.o.outlinecolor -text [_ "Outline color"]]
bind $flabel <Enter> "$flabel configure -foreground blue"
bind $flabel <Leave> "$flabel configure -foreground black"
bind $flabel <1> "::dialog_array::choosecolor $mytoplevel fill"
bind $olabel <Enter> "$olabel configure -foreground blue"
bind $olabel <Leave> "$olabel configure -foreground black"
bind $olabel <1> "::dialog_array::choosecolor $mytoplevel outline"
button $fillpreview -relief raised -padx 7 -pady 0 \
-command "::dialog_array::choosecolor $mytoplevel fill"
set outlinepreview $mytoplevel.colors.o.preview
button $outlinepreview -relief raised -padx 7 -pady 0 \
-command \
"::dialog_array::choosecolor $mytoplevel outline"
#automagically update the preview buttons when the variables are changed
trace add variable $fillp write \
"::dialog_array::update_colorpreview $fillp $fillpreview"
trace add variable $outlinep write \
"::dialog_array::update_colorpreview $outlinep $outlinepreview"
pack $mytoplevel.colors.f.fillcolor -side right -anchor w
pack $mytoplevel.colors.f.preview -side left -anchor e -padx 3
pack $mytoplevel.colors.o.outlinecolor -side right -anchor w
pack $mytoplevel.colors.o.preview -side left -anchor e -padx 3
if {$newone != 0} {
labelframe $mytoplevel.radio -text [_ "Put array into:"] -padx 20 -borderwidth 1
pack $mytoplevel.radio -side top -fill x
radiobutton $mytoplevel.radio.radio0 -value 0 \
-variable ::otherflag_button($mytoplevel) -text [_ "New graph"]
radiobutton $mytoplevel.radio.radio1 -value 1 \
-variable ::otherflag_button($mytoplevel) -text [_ "Last graph"]
pack $mytoplevel.radio.radio0 -side top -anchor w
pack $mytoplevel.radio.radio1 -side top -anchor w
} else {
checkbutton $mytoplevel.deletearray -text [_ "Delete array"] \
-variable ::otherflag_button($mytoplevel) -anchor w
pack $mytoplevel.deletearray -side top
}
# jsarlo
if {$newone == 0} {
button $mytoplevel.listview -text [_ "Open List View..."] \
-command "::dialog_array::openlistview $mytoplevel [$mytoplevel.name.entry get]"
pack $mytoplevel.listview -side top
}
# end jsarlo
frame $mytoplevel.buttonframe
pack $mytoplevel.buttonframe -side bottom -expand 1 -fill x -pady 2m
button $mytoplevel.buttonframe.cancel -text [_ "Cancel"] \
-command "::dialog_array::cancel $mytoplevel"
pack $mytoplevel.buttonframe.cancel -side left -expand 1 -fill x -padx 10
if {$newone == 0 && $::windowingsystem ne "aqua"} {
button $mytoplevel.buttonframe.apply -text [_ "Apply"] \
-command "::dialog_array::apply $mytoplevel"
pack $mytoplevel.buttonframe.apply -side left -expand 1 -fill x -padx 10
}
button $mytoplevel.buttonframe.ok -text [_ "OK"]\
-command "::dialog_array::ok $mytoplevel"
pack $mytoplevel.buttonframe.ok -side left -expand 1 -fill x -padx 10
}
package provide dialog_audio 0.1
namespace eval ::dialog_audio:: {
# namespace export pdtk_audio_dialog
}
# TODO this panel really needs some reworking, it works but the code is very
# unreadable. The panel could look a lot better too, like using menubuttons
# instead of regular buttons with tk_popup for pulldown menus.
# * make sure combobox is setting the device number
# * get focus order to do right
# * add "Close" button to prefs dialog
####################### audio dialog ##################3
proc ::dialog_audio::apply {mytoplevel} {
global audio_indev1 audio_indev2 audio_indev3 audio_indev4
global audio_inchan1 audio_inchan2 audio_inchan3 audio_inchan4
global audio_inenable1 audio_inenable2 audio_inenable3 audio_inenable4
global audio_outdev1 audio_outdev2 audio_outdev3 audio_outdev4
global audio_outchan1 audio_outchan2 audio_outchan3 audio_outchan4
global audio_outenable1 audio_outenable2 audio_outenable3 audio_outenable4
global audio_sr audio_advance audio_callback audio_blocksize
# Hackety hack! Rather than make this audio dialog code sane,
# which would be a larger project, I'm just making the user interface
# look more friendly. The global "enable" variables were used
# for checkbuttons; I simplified the interface by removing them and
# adding a "None" option to the device list. This means I have
# to parse the dev names for the string "None" and set the "enable"
# variables accordingly. I also assume "None" is the last value in the
# list.
foreach type {in out} {
foreach i {1 2 3 4} {
if {[set audio_${type}dev${i}] == \
[llength [set ::audio_${type}devlist]] ||
[set audio_${type}chan${i}] <= 0} {
set audio_${type}dev${i} 0
set audio_${type}enable${i} 0
set audio_${type}chan${i} 0
} else {
set audio_${type}enable${i} 1
}
}
}
pd [concat pd audio-dialog \
$audio_indev1 \
$audio_indev2 \
$audio_indev3 \
$audio_indev4 \
[expr $audio_inchan1 * ( $audio_inenable1 ? 1 : -1 ) ]\
[expr $audio_inchan2 * ( $audio_inenable2 ? 1 : -1 ) ]\
[expr $audio_inchan3 * ( $audio_inenable3 ? 1 : -1 ) ]\
[expr $audio_inchan4 * ( $audio_inenable4 ? 1 : -1 ) ]\
$audio_outdev1 \
$audio_outdev2 \
$audio_outdev3 \
$audio_outdev4 \
[expr $audio_outchan1 * ( $audio_outenable1 ? 1 : -1 ) ]\
[expr $audio_outchan2 * ( $audio_outenable2 ? 1 : -1 ) ]\
[expr $audio_outchan3 * ( $audio_outenable3 ? 1 : -1 ) ]\
[expr $audio_outchan4 * ( $audio_outenable4 ? 1 : -1 ) ]\
$audio_sr \
$audio_advance \
$audio_callback \
$audio_blocksize" \
\;]
# Pd always makes devices contiguous-- for example, if you only set
# device 1 and device 3 it will change device 3 to device 2.
# So we look for non-contiguous devices and request an update
# on connect so that the user doesn't see incorrect information
# in the GUI. This rebuilds part of the dialog window which causes
# a slight flicker-- otherwise I'd just do this everytime:
# pdsend "pd audio-properties $::audio_longform
foreach type {in out} {
set empty_dev 0
set aliased_dev 0
foreach i {1 2 3 4} {
set enabled [set audio_${type}enable$i]
if {$empty_dev && $enabled} {
set aliased_dev 1
break
} elseif {!$enabled} {incr empty_dev}
}
if {$aliased_dev} {
pd [concat pd audio-properties $::audio_longform \;]
break
}
}
pd [concat pd save-preferences \;]
}
proc ::dialog_audio::cancel {mytoplevel} {
# pdsend "$mytoplevel cancel"
}
proc ::dialog_audio::ok {mytoplevel} {
::dialog_audio::apply $mytoplevel
::dialog_audio::cancel $mytoplevel
}
proc ::dialog_audio::setapi {var - op} {
if {$op ne "write"} {return}
set name [set $var]
set index [lsearch -exact -index 0 $::pd_apilist $name]
set ::pd_whichapi [lindex $::pd_apilist $index 1]
pd [concat pd audio-setapi $::pd_whichapi \;]
}
proc ::dialog_audio::setlongform {widget} {
set state [set ::$widget]
if {$state == 0} {
# back to single devs
set extra_devs 0
foreach type {in out} {
foreach i {2 3 4} {
if { [set ::audio_${type}chan$i] > 0 &&
[set ::audio_${type}enable$i] > 0 } {
incr extra_devs
}
}
}
if {$extra_devs} {
set devices devices
if {$extra_devs == 1} {set devices device}
set continue [tk_messageBox -type yesno -message \
[_ "This will disconnect $extra_devs $devices. Continue?"] \
-default "no" -parent [winfo parent $widget] -icon question]
if {$continue eq "yes"} {
foreach type {in out} {
foreach i {2 3 4} {
set ::audio_${type}chan$i 0
set ::audio_${type}enable$i 0
}
}
::dialog_audio::apply [winfo parent $widget]
}
}
}
pd [concat pd audio-properties $state \;]
}
# start a dialog window to select audio devices and settings. "multi"
# is 0 if only one device is allowed; 1 if one apiece may be specified for
# input and output; and 2 if we can select multiple devices. "longform"
# (which only makes sense if "multi" is 2) asks us to make controls for
# opening several devices; if not, we get an extra button to turn longform
# on and restart the dialog.
proc ::dialog_audio::pdtk_audio_dialog {id \
indev1 indev2 indev3 indev4 \
inchan1 inchan2 inchan3 inchan4 \
outdev1 outdev2 outdev3 outdev4 \
outchan1 outchan2 outchan3 outchan4 sr advance multi callback \
longform blocksize} {
global audio_indev1 audio_indev2 audio_indev3 audio_indev4
global audio_inchan1 audio_inchan2 audio_inchan3 audio_inchan4
global audio_inenable1 audio_inenable2 audio_inenable3 audio_inenable4
global audio_outdev1 audio_outdev2 audio_outdev3 audio_outdev4
global audio_outchan1 audio_outchan2 audio_outchan3 audio_outchan4
global audio_outenable1 audio_outenable2 audio_outenable3 audio_outenable4
global audio_sr audio_advance audio_callback audio_blocksize
global audio_indevlist audio_outdevlist
global pd_indev pd_outdev
global audio_longform
set audio_inchan1 [expr ( $inchan1 > 0 ? $inchan1 : -$inchan1 ) ]
set audio_inenable1 [expr $inchan1 > 0 ]
set audio_inchan2 [expr ( $inchan2 > 0 ? $inchan2 : -$inchan2 ) ]
set audio_inenable2 [expr $inchan2 > 0 ]
set audio_inchan3 [expr ( $inchan3 > 0 ? $inchan3 : -$inchan3 ) ]