aboutsummaryrefslogtreecommitdiff
path: root/pd/tcl/pd_menus.tcl
diff options
context:
space:
mode:
Diffstat (limited to 'pd/tcl/pd_menus.tcl')
-rw-r--r--pd/tcl/pd_menus.tcl447
1 files changed, 280 insertions, 167 deletions
diff --git a/pd/tcl/pd_menus.tcl b/pd/tcl/pd_menus.tcl
index 99b6be94..fc617dfa 100644
--- a/pd/tcl/pd_menus.tcl
+++ b/pd/tcl/pd_menus.tcl
@@ -4,33 +4,18 @@
package provide pd_menus 0.1
package require pd_menucommands
-package require Tk
-#package require tile
-## replace Tk widgets with Ttk widgets on 8.5
-#namespace import -force ttk::*
# TODO figure out Undo/Redo/Cut/Copy/Paste state changes for menus
-# TODO figure out parent window/window list for Window menu
-# TODO what is the Tcl package constructor or init()?
-# TODO $::pd_menus::menubar or .menubar globally?
# since there is one menubar that is used for all windows, the menu -commands
# use {} quotes so that $::focused_window is interpreted when the menu item
# is called, not when the command is mapped to the menu item. This is the
# opposite of the 'bind' commands in pd_bindings.tcl
-
-# ------------------------------------------------------------------------------
-# global variables
-
-# TODO this should properly be inside the pd_menus namespace, now it is global
-namespace import ::pd_menucommands::*
-
namespace eval ::pd_menus:: {
variable accelerator
variable menubar ".menubar"
- variable current_toplevel ".pdwindow"
-
+
namespace export create_menubar
namespace export configure_for_pdwindow
namespace export configure_for_canvas
@@ -52,32 +37,33 @@ proc ::pd_menus::create_menubar {} {
}
menu $menubar
set menulist "file edit put find media window help"
- if { $::windowingsystem eq "aqua" } {create_apple_menu $menubar}
- # FIXME why does the following (if uncommented) kill my menubar?
- # if { $::windowingsystem eq "win32" } {create_system_menu $menubar}
foreach mymenu $menulist {
menu $menubar.$mymenu
$menubar add cascade -label [_ [string totitle $mymenu]] \
-menu $menubar.$mymenu
- [format build_%s_menu $mymenu] $menubar.$mymenu .
- if {$::windowingsystem eq "win32"} {
- # fix menu font size on Windows with tk scaling = 1
- $menubar.$mymenu configure -font menufont
- }
+ [format build_%s_menu $mymenu] $menubar.$mymenu
}
+ if {$::windowingsystem eq "aqua"} {create_apple_menu $menubar}
+ if {$::windowingsystem eq "win32"} {create_system_menu $menubar}
+ . configure -menu $menubar
}
proc ::pd_menus::configure_for_pdwindow {} {
variable menubar
# these are meaningless for the Pd window, so disable them
- set file_items_to_disable {"Save" "Save As..." "Print..." "Close"}
- foreach menuitem $file_items_to_disable {
- $menubar.file entryconfigure [_ $menuitem] -state disabled
- }
- set edit_items_to_disable {"Undo" "Redo" "Duplicate" "Tidy Up" "Edit Mode"}
- foreach menuitem $edit_items_to_disable {
- $menubar.edit entryconfigure [_ $menuitem] -state disabled
- }
+ # File menu
+ $menubar.file entryconfigure [_ "Save"] -state disabled
+ $menubar.file entryconfigure [_ "Save As..."] -state disabled
+ $menubar.file entryconfigure [_ "Print..."] -state disabled
+ $menubar.file entryconfigure [_ "Close"] -state disabled
+ # Edit menu
+ $menubar.edit entryconfigure [_ "Duplicate"] -state disabled
+ $menubar.edit entryconfigure [_ "Tidy Up"] -state disabled
+ $menubar.edit entryconfigure [_ "Edit Mode"] -state disabled
+ pdtk_canvas_editmode .pdwindow 0
+ # Undo/Redo change names, they need to have the asterisk (*) after
+ $menubar.edit entryconfigure 0 -state disabled -label [_ "Undo"]
+ $menubar.edit entryconfigure 1 -state disabled -label [_ "Redo"]
# disable everything on the Put menu
for {set i 0} {$i <= [$menubar.put index end]} {incr i} {
# catch errors that happen when trying to disable separators
@@ -87,32 +73,45 @@ proc ::pd_menus::configure_for_pdwindow {} {
proc ::pd_menus::configure_for_canvas {mytoplevel} {
variable menubar
- set file_items_to_disable {"Save" "Save As..." "Print..." "Close"}
- foreach menuitem $file_items_to_disable {
- $menubar.file entryconfigure [_ $menuitem] -state normal
- }
- set edit_items_to_disable {"Undo" "Redo" "Duplicate" "Tidy Up" "Edit Mode"}
- foreach menuitem $edit_items_to_disable {
- $menubar.edit entryconfigure [_ $menuitem] -state normal
- }
+ # File menu
+ $menubar.file entryconfigure [_ "Save"] -state normal
+ $menubar.file entryconfigure [_ "Save As..."] -state normal
+ $menubar.file entryconfigure [_ "Print..."] -state normal
+ $menubar.file entryconfigure [_ "Close"] -state normal
+ # Edit menu
+ $menubar.edit entryconfigure [_ "Duplicate"] -state normal
+ $menubar.edit entryconfigure [_ "Tidy Up"] -state normal
+ $menubar.edit entryconfigure [_ "Edit Mode"] -state normal
+ pdtk_canvas_editmode $mytoplevel $::editmode($mytoplevel)
+ # Put menu
for {set i 0} {$i <= [$menubar.put index end]} {incr i} {
# catch errors that happen when trying to disable separators
- catch {$menubar.put entryconfigure $i -state normal }
+ if {[$menubar.put type $i] ne "separator"} {
+ $menubar.put entryconfigure $i -state normal
+ }
}
- # TODO set "Edit Mode" state using editmode($mytoplevel)
+ update_undo_on_menu $mytoplevel
}
proc ::pd_menus::configure_for_dialog {mytoplevel} {
variable menubar
- # these are meaningless for the dialog panels, so disable them
- set file_items_to_disable {"Save" "Save As..." "Print..." "Close"}
- foreach menuitem $file_items_to_disable {
- $menubar.file entryconfigure [_ $menuitem] -state disabled
- }
- set edit_items_to_disable {"Undo" "Redo" "Duplicate" "Tidy Up" "Edit Mode"}
- foreach menuitem $edit_items_to_disable {
- $menubar.edit entryconfigure [_ $menuitem] -state disabled
+ # these are meaningless for the dialog panels, so disable them except for
+ # the ones that make senes in the Find dialog panel
+ # File menu
+ if {$mytoplevel ne ".find"} {
+ $menubar.file entryconfigure [_ "Save"] -state disabled
+ $menubar.file entryconfigure [_ "Save As..."] -state disabled
+ $menubar.file entryconfigure [_ "Print..."] -state disabled
}
+ $menubar.file entryconfigure [_ "Close"] -state disabled
+ # Edit menu
+ $menubar.edit entryconfigure [_ "Duplicate"] -state disabled
+ $menubar.edit entryconfigure [_ "Tidy Up"] -state disabled
+ $menubar.edit entryconfigure [_ "Edit Mode"] -state disabled
+ pdtk_canvas_editmode $mytoplevel 0
+ # Undo/Redo change names, they need to have the asterisk (*) after
+ $menubar.edit entryconfigure 0 -state disabled -label [_ "Undo"]
+ $menubar.edit entryconfigure 1 -state disabled -label [_ "Redo"]
# disable everything on the Put menu
for {set i 0} {$i <= [$menubar.put index end]} {incr i} {
# catch errors that happen when trying to disable separators
@@ -123,19 +122,20 @@ proc ::pd_menus::configure_for_dialog {mytoplevel} {
# ------------------------------------------------------------------------------
# menu building functions
-proc ::pd_menus::build_file_menu {mymenu mytoplevel} {
+proc ::pd_menus::build_file_menu {mymenu} {
+ # run the platform-specific build_file_menu_* procs first, the config them
[format build_file_menu_%s $::windowingsystem] $mymenu
$mymenu entryconfigure [_ "New"] -command {menu_new}
$mymenu entryconfigure [_ "Open"] -command {menu_open}
- $mymenu entryconfigure [_ "Save"] -command {pdsend "$::focused_window menusave"}
- $mymenu entryconfigure [_ "Save As..."] -command {pdsend "$::focused_window menusaveas"}
- #$mymenu entryconfigure [_ "Revert*"] -command {menu_revert $current_toplevel}
- $mymenu entryconfigure [_ "Close"] -command {pdsend "$::focused_window menuclose 0"}
- $mymenu entryconfigure [_ "Message"] -command {menu_message_dialog}
+ $mymenu entryconfigure [_ "Save"] -command {menu_send $::focused_window menusave}
+ $mymenu entryconfigure [_ "Save As..."] -command {menu_send $::focused_window menusaveas}
+ #$mymenu entryconfigure [_ "Revert*"] -command {menu_revert $::focused_window}
+ $mymenu entryconfigure [_ "Close"] -command {menu_send_float $::focused_window menuclose 0}
+ $mymenu entryconfigure [_ "Message..."] -command {menu_message_dialog}
$mymenu entryconfigure [_ "Print..."] -command {menu_print $::focused_window}
}
-proc ::pd_menus::build_edit_menu {mymenu mytoplevel} {
+proc ::pd_menus::build_edit_menu {mymenu} {
variable accelerator
$mymenu add command -label [_ "Undo"] -accelerator "$accelerator+Z" \
-command {menu_undo $::focused_window}
@@ -143,165 +143,186 @@ proc ::pd_menus::build_edit_menu {mymenu mytoplevel} {
-command {menu_redo $::focused_window}
$mymenu add separator
$mymenu add command -label [_ "Cut"] -accelerator "$accelerator+X" \
- -command {pdsend "$::focused_window cut"}
+ -command {menu_send $::focused_window cut}
$mymenu add command -label [_ "Copy"] -accelerator "$accelerator+C" \
- -command {pdsend "$::focused_window copy"}
+ -command {menu_send $::focused_window copy}
$mymenu add command -label [_ "Paste"] -accelerator "$accelerator+V" \
- -command {pdsend "$::focused_window paste"}
+ -command {menu_send $::focused_window paste}
$mymenu add command -label [_ "Duplicate"] -accelerator "$accelerator+D" \
- -command {pdsend "$::focused_window duplicate"}
+ -command {menu_send $::focused_window duplicate}
$mymenu add command -label [_ "Select All"] -accelerator "$accelerator+A" \
- -command {pdsend "$::focused_window selectall"}
+ -command {menu_send $::focused_window selectall}
$mymenu add separator
if {$::windowingsystem eq "aqua"} {
- $mymenu add command -label [_ "Text Editor"] \
- -command {menu_texteditor $::focused_window}
+# $mymenu add command -label [_ "Text Editor"] \
+# -command {menu_texteditor}
$mymenu add command -label [_ "Font"] -accelerator "$accelerator+T" \
- -command {menu_font_dialog $::focused_window}
+ -command {menu_font_dialog}
} else {
- $mymenu add command -label [_ "Text Editor"] -accelerator "$accelerator+T"\
- -command {menu_texteditor $::focused_window}
+# $mymenu add command -label [_ "Text Editor"] -accelerator "$accelerator+T"\
+# -command {menu_texteditor}
$mymenu add command -label [_ "Font"] \
- -command {menu_font_dialog $::focused_window}
+ -command {menu_font_dialog}
}
$mymenu add command -label [_ "Tidy Up"] \
- -command {pdsend "$::focused_window tidy"}
- $mymenu add command -label [_ "Toggle Console"] -accelerator "Shift+$accelerator+R" \
- -command {.controls.switches.console invoke}
- $mymenu add command -label [_ "Clear Console"] -accelerator "Shift+$accelerator+L" \
- -command {menu_clear_console}
+ -command {menu_send $::focused_window tidy}
+ $mymenu add command -label [_ "Clear Console"] \
+ -accelerator "Shift+$accelerator+L" -command {menu_clear_console}
$mymenu add separator
- #TODO madness! how to do set the state of the check box without invoking the menu!
+ #TODO madness! how to set the state of the check box without invoking the menu!
$mymenu add check -label [_ "Edit Mode"] -accelerator "$accelerator+E" \
- -selectcolor grey85 \
- -command {pdsend "$::focused_window editmode 0"}
- #if { ! [catch {console hide}]} {
- # TODO set up menu item to show/hide the Tcl/Tk console, if it available
- #}
-
- if {$::windowingsystem ne "aqua"} {
- $mymenu add separator
- $mymenu add command -label [_ "Preferences"] \
- -command {menu_preferences_dialog}
- }
+ -selectcolor grey85 -variable ::editmode_button \
+ -command {menu_editmode $::editmode_button}
}
-proc ::pd_menus::build_put_menu {mymenu mytoplevel} {
+proc ::pd_menus::build_put_menu {mymenu} {
variable accelerator
+ # The trailing 0 in menu_send_float basically means leave the object box
+ # sticking to the mouse cursor. The iemguis alway do that when created
+ # from the menu, as defined in canvas_iemguis()
$mymenu add command -label [_ "Object"] -accelerator "$accelerator+1" \
- -command {pdsend "$::focused_window obj 0"}
+ -command {menu_send_float $::focused_window obj 0}
$mymenu add command -label [_ "Message"] -accelerator "$accelerator+2" \
- -command {pdsend "$::focused_window msg 0"}
+ -command {menu_send_float $::focused_window msg 0}
$mymenu add command -label [_ "Number"] -accelerator "$accelerator+3" \
- -command {pdsend "$::focused_window floatatom 0"}
+ -command {menu_send_float $::focused_window floatatom 0}
$mymenu add command -label [_ "Symbol"] -accelerator "$accelerator+4" \
- -command {pdsend "$::focused_window symbolatom 0"}
+ -command {menu_send_float $::focused_window symbolatom 0}
$mymenu add command -label [_ "Comment"] -accelerator "$accelerator+5" \
- -command {pdsend "$::focused_window text 0"}
+ -command {menu_send_float $::focused_window text 0}
$mymenu add separator
$mymenu add command -label [_ "Bang"] -accelerator "Shift+$accelerator+B" \
- -command {pdsend "$::focused_window bng 0"}
+ -command {menu_send $::focused_window bng}
$mymenu add command -label [_ "Toggle"] -accelerator "Shift+$accelerator+T" \
- -command {pdsend "$::focused_window toggle 0"}
+ -command {menu_send $::focused_window toggle}
$mymenu add command -label [_ "Number2"] -accelerator "Shift+$accelerator+N" \
- -command {pdsend "$::focused_window numbox 0"}
+ -command {menu_send $::focused_window numbox}
$mymenu add command -label [_ "Vslider"] -accelerator "Shift+$accelerator+V" \
- -command {pdsend "$::focused_window vslider 0"}
+ -command {menu_send $::focused_window vslider}
$mymenu add command -label [_ "Hslider"] -accelerator "Shift+$accelerator+H" \
- -command {pdsend "$::focused_window hslider 0"}
+ -command {menu_send $::focused_window hslider}
$mymenu add command -label [_ "Vradio"] -accelerator "Shift+$accelerator+D" \
- -command {pdsend "$::focused_window vradio 0"}
+ -command {menu_send $::focused_window vradio}
$mymenu add command -label [_ "Hradio"] -accelerator "Shift+$accelerator+I" \
- -command {pdsend "$::focused_window hradio 0"}
+ -command {menu_send $::focused_window hradio}
$mymenu add command -label [_ "VU Meter"] -accelerator "Shift+$accelerator+U"\
- -command {pdsend "$::focused_window vumeter 0"}
+ -command {menu_send $::focused_window vumeter}
$mymenu add command -label [_ "Canvas"] -accelerator "Shift+$accelerator+C" \
- -command {pdsend "$::focused_window mycnv 0"}
+ -command {menu_send $::focused_window mycnv}
$mymenu add separator
- $mymenu add command -label [_ "Graph"] -command {pdsend "$::focused_window graph"}
- $mymenu add command -label [_ "Array"] -command {pdsend "$::focused_window menuarray"}
+ $mymenu add command -label [_ "Graph"] -command {menu_send $::focused_window graph}
+ $mymenu add command -label [_ "Array"] -command {menu_send $::focused_window menuarray}
}
-proc ::pd_menus::build_find_menu {mymenu mytoplevel} {
+proc ::pd_menus::build_find_menu {mymenu} {
variable accelerator
$mymenu add command -label [_ "Find..."] -accelerator "$accelerator+F" \
- -command {::dialog_find::menu_find_dialog $::focused_window}
+ -command {menu_find_dialog}
$mymenu add command -label [_ "Find Again"] -accelerator "$accelerator+G" \
- -command {pdsend "$::focused_window findagain"}
+ -command {menu_send $::focused_window findagain}
$mymenu add command -label [_ "Find Last Error"] \
- -command {pdsend "$::focused_window finderror"}
+ -command {pdsend {pd finderror}}
}
-proc ::pd_menus::build_media_menu {mymenu mytoplevel} {
+proc ::pd_menus::build_media_menu {mymenu} {
variable accelerator
$mymenu add radiobutton -label [_ "DSP On"] -accelerator "$accelerator+/" \
-variable ::dsp -value 1 -command {pdsend "pd dsp 1"}
$mymenu add radiobutton -label [_ "DSP Off"] -accelerator "$accelerator+." \
-variable ::dsp -value 0 -command {pdsend "pd dsp 0"}
+
$mymenu add separator
+ $mymenu add command -label [_ "Test Audio and MIDI..."] \
+ -command {menu_doc_open doc/7.stuff/tools testtone.pd}
+ $mymenu add command -label [_ "Load Meter"] \
+ -command {menu_doc_open doc/7.stuff/tools load-meter.pd}
- set audioapi_list_length [llength $::audioapi_list]
- for {set x 0} {$x<$audioapi_list_length} {incr x} {
- # pdtk_post "audio [lindex [lindex $::audioapi_list $x] 0]"
- $mymenu add radiobutton -label [lindex [lindex $::audioapi_list $x] 0] \
+ set audio_apilist_length [llength $::audio_apilist]
+ if {$audio_apilist_length > 0} {$mymenu add separator}
+ for {set x 0} {$x<$audio_apilist_length} {incr x} {
+ $mymenu add radiobutton -label [lindex [lindex $::audio_apilist $x] 0] \
-command {menu_audio 0} -variable ::pd_whichapi \
- -value [lindex [lindex $::audioapi_list $x] 1]\
+ -value [lindex [lindex $::audio_apilist $x] 1]\
-command {pdsend "pd audio-setapi $::pd_whichapi"}
}
- if {$audioapi_list_length > 0} {$mymenu add separator}
-
- set midiapi_list_length [llength $::midiapi_list]
- for {set x 0} {$x<$midiapi_list_length} {incr x} {
- # pdtk_post "midi [lindex [lindex $::midiapi_list $x] 0]"
- $mymenu add radiobutton -label [lindex [lindex $::midiapi_list $x] 0] \
+
+ set midi_apilist_length [llength $::midi_apilist]
+ if {$midi_apilist_length > 0} {$mymenu add separator}
+ for {set x 0} {$x<$midi_apilist_length} {incr x} {
+ $mymenu add radiobutton -label [lindex [lindex $::midi_apilist $x] 0] \
-command {menu_midi 0} -variable ::pd_whichmidiapi \
- -value [lindex [lindex $::midiapi_list $x] 1]\
+ -value [lindex [lindex $::midi_apilist $x] 1]\
-command {pdsend "pd midi-setapi $::pd_whichmidiapi"}
}
- if {$midiapi_list_length > 0} {$mymenu add separator}
-
if {$::windowingsystem ne "aqua"} {
- $mymenu add command -label [_ "Audio settings..."] \
- -command {pdsend "pd audio-properties"}
- $mymenu add command -label [_ "MIDI settings..."] \
- -command {pdsend "pd midi-properties"}
$mymenu add separator
+ create_preferences_menu $mymenu.preferences
+ $mymenu add cascade -label [_ "Preferences"] -menu $mymenu.preferences
}
- $mymenu add command -label [_ "Test Audio and MIDI..."] \
- -command {menu_doc_open doc/7.stuff/tools testtone.pd}
- $mymenu add command -label [_ "Load Meter"] \
- -command {menu_doc_open doc/7.stuff/tools load-meter.pd}
}
-proc ::pd_menus::build_window_menu {mymenu mytoplevel} {
+proc ::pd_menus::build_window_menu {mymenu} {
variable accelerator
if {$::windowingsystem eq "aqua"} {
- $mymenu add command -label [_ "Minimize"] -command {menu_minimize .} \
- -accelerator "$accelerator+M"
- $mymenu add command -label [_ "Zoom"] -command {menu_zoom .}
+ $mymenu add command -label [_ "Minimize"] -accelerator "$accelerator+M"\
+ -command {menu_minimize $::focused_window}
+ $mymenu add command -label [_ "Zoom"] \
+ -command {menu_maximize $::focused_window}
$mymenu add separator
+ $mymenu add command -label [_ "Bring All to Front"] \
+ -command {menu_bringalltofront}
+ } else {
+ $mymenu add command -label [_ "Next Window"] \
+ -command {menu_raisenextwindow} \
+ -accelerator [_ "$accelerator+Page Down"]
+ $mymenu add command -label [_ "Previous Window"] \
+ -command {menu_raisepreviouswindow} \
+ -accelerator [_ "$accelerator+Page Up"]
}
- $mymenu add command -label [_ "Parent Window"] \
- -command {pdsend "$::focused_window findparent"}
+ $mymenu add separator
$mymenu add command -label [_ "Pd window"] -command {menu_raise_pdwindow} \
-accelerator "$accelerator+R"
+ $mymenu add command -label [_ "Parent Window"] \
+ -command {menu_send $::focused_window findparent}
$mymenu add separator
- if {$::windowingsystem eq "aqua"} {
- $mymenu add command -label [_ "Bring All to Front"] \
- -command {menu_bringalltofront}
- $mymenu add separator
- }
}
-proc ::pd_menus::build_help_menu {mymenu mytoplevel} {
+proc ::pd_menus::build_help_menu {mymenu} {
if {$::windowingsystem ne "aqua"} {
- $mymenu add command -label [_ "About Pd"] \
- -command {menu_doc_open doc/1.manual 1.introduction.txt}
+ $mymenu add command -label [_ "About Pd"] -command {menu_aboutpd}
}
$mymenu add command -label [_ "HTML Manual..."] \
-command {menu_doc_open doc/1.manual index.htm}
$mymenu add command -label [_ "Browser..."] \
- -command {placeholder menu_helpbrowser \$help_top_directory}
+ -command {menu_helpbrowser}
+ $mymenu add separator
+ $mymenu add command -label [_ "puredata.info"] \
+ -command {menu_openfile {http://puredata.info}}
+ $mymenu add command -label [_ "Report a bug"] -command {menu_openfile \
+ {http://sourceforge.net/tracker/?func=add&group_id=55736&atid=478070}}
+ $mymenu add separator
+ $mymenu add command -label [_ "Tcl prompt"] -command \
+ {::pdwindow::create_tcl_entry}
+
+}
+
+#------------------------------------------------------------------------------#
+# undo/redo menu items
+
+proc ::pd_menus::update_undo_on_menu {mytoplevel} {
+ variable menubar
+ if {$mytoplevel eq $::undo_toplevel && $::undo_action ne "no"} {
+ $menubar.edit entryconfigure 0 -state normal \
+ -label [_ "Undo $::undo_action"]
+ } else {
+ $menubar.edit entryconfigure 0 -state disabled -label [_ "Undo"]
+ }
+ if {$mytoplevel eq $::undo_toplevel && $::redo_action ne "no"} {
+ $menubar.edit entryconfigure 1 -state normal \
+ -label [_ "Redo $::redo_action"]
+ } else {
+ $menubar.edit entryconfigure 1 -state disabled -label [_ "Redo"]
+ }
}
# ------------------------------------------------------------------------------
@@ -323,14 +344,14 @@ proc ::pd_menus::clear_recentfiles_menu {} {
proc ::pd_menus::update_openrecent_menu_aqua {mymenu} {
if {! [winfo exists $mymenu]} {menu $mymenu}
$mymenu delete 0 end
- foreach filename $::recentfiles_list {
- puts "creating menu item for $filename"
- $mymenu add command -label [file tail $filename] \
- -command "open_file $filename"
- }
$mymenu add separator
$mymenu add command -label [_ "Clear Menu"] \
-command "::pd_menus::clear_recentfiles_menu"
+ # newest need to be on top, but the list in oldest first, so insert
+ foreach filename $::recentfiles_list {
+ $mymenu insert 0 command -label [file tail $filename] \
+ -command "open_file {$filename}"
+ }
}
# this expects to be run on the File menu, and to insert above the last separator
@@ -345,12 +366,98 @@ proc ::pd_menus::update_recentfiles_on_menu {mymenu} {
if {$top_separator < [expr $bottom_separator-1]} {
$mymenu delete [expr $top_separator+1] [expr $bottom_separator-1]
}
- set i 0
foreach filename $::recentfiles_list {
- $mymenu insert [expr $top_separator+$i+1] command \
- -label [file tail $filename] -command "open_file $filename"
- incr i
+ $mymenu insert [expr $top_separator+1] command \
+ -label [file tail $filename] -command "open_file {$filename}"
+ }
+}
+
+
+# ------------------------------------------------------------------------------
+# lots of crazy recursion to update the Window menu
+
+# find the first parent patch that has a mapped window
+proc ::pd_menus::find_mapped_parent {parentlist} {
+ if {[llength $parentlist] == 0} {return "none"}
+ set firstparent [lindex $parentlist 0]
+ if {[winfo exists $firstparent]} {
+ return $firstparent
+ } elseif {[llength $parentlist] > 1} {
+ return [find_mapped_parent [lrange $parentlist 1 end]]
+ } else {
+ # we must be the first menu item to be inserted
+ return "none"
+ }
+}
+
+# find the first parent patch that has a mapped window
+proc ::pd_menus::insert_into_menu {mymenu entry parent} {
+ set insertat [$mymenu index end]
+ for {set i 0} {$i <= [$mymenu index end]} {incr i} {
+ if {[$mymenu type $i] ne "command"} {continue}
+ set currentcommand [$mymenu entrycget $i -command]
+ if {$currentcommand eq "raise $entry"} {return} ;# it exists already
+ if {$currentcommand eq "raise $parent"} {
+ set insertat $i
+ }
+ }
+ incr insertat
+ set label ""
+ for {set i 0} {$i < [llength $::parentwindows($entry)]} {incr i} {
+ append label " "
}
+ append label $::windowname($entry)
+ $mymenu insert $insertat command -label $label -command "raise $entry"
+}
+
+# recurse through a list of parent windows and add to the menu
+proc ::pd_menus::add_list_to_menu {mymenu window parentlist} {
+ if {[llength $parentlist] == 0} {
+ insert_into_menu $mymenu $window {}
+ } else {
+ set entry [lindex $parentlist end]
+ if {[winfo exists $entry]} {
+ insert_into_menu $mymenu $entry \
+ [find_mapped_parent $::parentwindows($entry)]
+ }
+ }
+ if {[llength $parentlist] > 1} {
+ add_list_to_menu $mymenu $window [lrange $parentlist 0 end-1]
+ }
+}
+
+# update the list of windows on the Window menu. This expects run on the
+# Window menu, and to insert below the last separator
+proc ::pd_menus::update_window_menu {} {
+ set mymenu $::patch_menubar.window
+ # find the last separator and delete everything after that
+ for {set i 0} {$i <= [$mymenu index end]} {incr i} {
+ if {[$mymenu type $i] eq "separator"} {
+ set deleteat $i
+ }
+ }
+ $mymenu delete $deleteat end
+ $mymenu add separator
+ foreach window [array names ::parentwindows] {
+ set parentlist $::parentwindows($window)
+ add_list_to_menu $mymenu $window $parentlist
+ insert_into_menu $mymenu $window [find_mapped_parent $parentlist]
+ }
+}
+
+# ------------------------------------------------------------------------------
+# submenu for Preferences, now used on all platforms
+
+proc ::pd_menus::create_preferences_menu {mymenu} {
+ menu $mymenu
+ $mymenu add command -label [_ "Path..."] \
+ -command {pdsend "pd start-path-dialog"}
+ $mymenu add command -label [_ "Startup..."] \
+ -command {pdsend "pd start-startup-dialog"}
+ $mymenu add command -label [_ "Audio Settings..."] \
+ -command {pdsend "pd audio-properties"}
+ $mymenu add command -label [_ "MIDI Settings..."] \
+ -command {pdsend "pd midi-properties"}
}
# ------------------------------------------------------------------------------
@@ -360,16 +467,14 @@ proc ::pd_menus::update_recentfiles_on_menu {mymenu} {
proc ::pd_menus::create_apple_menu {mymenu} {
# TODO this should open a Pd patch called about.pd
menu $mymenu.apple
- $mymenu.apple add command -label [_ "About Pd"] \
- -command {menu_doc_open doc/1.manual 1.introduction.txt}
- $mymenu add cascade -label "Apple" -menu $mymenu.apple
+ $mymenu.apple add command -label [_ "About Pd"] -command {menu_aboutpd}
$mymenu.apple add separator
- # starting in 8.4.14, this is created automatically
- set patchlevel [split [info patchlevel] .]
- if {[lindex $patchlevel 1] < 5 && [lindex $patchlevel 2] < 14} {
- $mymenu.apple add command -label [_ "Preferences..."] \
- -command {menu_preferences_dialog" -accelerator "Cmd+,}
- }
+ create_preferences_menu $mymenu.apple.preferences
+ $mymenu.apple add cascade -label [_ "Preferences"] \
+ -menu $mymenu.apple.preferences
+ # this needs to be last for things to function properly
+ $mymenu add cascade -label "Apple" -menu $mymenu.apple
+
}
proc ::pd_menus::build_file_menu_aqua {mymenu} {
@@ -385,7 +490,7 @@ proc ::pd_menus::build_file_menu_aqua {mymenu} {
#$mymenu add command -label [_ "Save All"]
#$mymenu add command -label [_ "Revert to Saved"]
$mymenu add separator
- $mymenu add command -label [_ "Message"]
+ $mymenu add command -label [_ "Message..."]
$mymenu add separator
$mymenu add command -label [_ "Print..."] -accelerator "$accelerator+P"
}
@@ -412,7 +517,7 @@ proc ::pd_menus::build_file_menu_x11 {mymenu} {
$mymenu add command -label [_ "Save As..."] -accelerator "Shift+$accelerator+S"
# $mymenu add command -label "Revert"
$mymenu add separator
- $mymenu add command -label [_ "Message"] -accelerator "$accelerator+M"
+ $mymenu add command -label [_ "Message..."] -accelerator "$accelerator+M"
$mymenu add command -label [_ "Print..."] -accelerator "$accelerator+P"
$mymenu add separator
# the recent files get inserted in here by update_recentfiles_on_menu
@@ -436,10 +541,16 @@ proc ::pd_menus::build_window_menu_x11 {mymenu} {
# menu building functions for Windows/Win32
# for Windows only
-proc ::pd_menus::create_system_menu {mymenu} {
- $mymenu add cascade -menu [menu $mymenu.system]
+proc ::pd_menus::create_system_menu {mymenubar} {
+ set mymenu $mymenubar.system
+ $mymenubar add cascade -label System -menu $mymenu
+ menu $mymenu -tearoff 0
+ # placeholders
+ $mymenu add command -label [_ "Edit Mode"] -command "::pdwindow::verbose 0 systemmenu"
# TODO add Close, Minimize, etc and whatever else is on the little menu
# that is on the top left corner of the window frame
+ # http://wiki.tcl.tk/1006
+ # TODO add Edit Mode here
}
proc ::pd_menus::build_file_menu_win32 {mymenu} {
@@ -451,7 +562,9 @@ proc ::pd_menus::build_file_menu_win32 {mymenu} {
$mymenu add command -label [_ "Save As..."] -accelerator "Shift+$accelerator+S"
# $mymenu add command -label "Revert"
$mymenu add separator
- $mymenu add command -label [_ "Message"] -accelerator "$accelerator+M"
+ $mymenu add command -label [_ "Message..."] -accelerator "$accelerator+M"
+ create_preferences_menu $mymenu.preferences
+ $mymenu add cascade -label [_ "Preferences"] -menu $mymenu.preferences
$mymenu add command -label [_ "Print..."] -accelerator "$accelerator+P"
$mymenu add separator
# the recent files get inserted in here by update_recentfiles_on_menu