package provide pdtk_canvas 0.1 package require pd_bindings namespace eval ::pdtk_canvas:: { } # TODO figure out weird frameless window when you open a graph #------------------------------------------------------------------------------# # canvas new/saveas proc pdtk_canvas_new {mytoplevel width height geometry editable} { # TODO check size of window toplevel $mytoplevel -width $width -height $height -class CanvasWindow wm group $mytoplevel . $mytoplevel configure -menu .menubar # TODO slide off screen windows into view wm geometry $mytoplevel $geometry if {$::windowingsystem eq "aqua"} { # no menubar, it can be small wm minsize $mytoplevel 50 20 } else { # leave room for the menubar wm minsize $mytoplevel 310 30 } set ::editmode($mytoplevel) $editable set mycanvas $mytoplevel.c canvas $mycanvas -width $width -height $height -background white \ -highlightthickness 0 # TODO add scrollbars here pack $mycanvas -side left -expand 1 -fill both ::pd_bindings::canvas_bindings $mytoplevel # give focus to the canvas so it gets the events rather than the window focus $mycanvas } proc pdtk_canvas_saveas {name initialfile initialdir} { if { ! [file isdirectory $initialdir]} {set initialdir $::env(HOME)} set filename [tk_getSaveFile -initialfile $initialfile -initialdir $initialdir \ -defaultextension .pd -filetypes $::filetypes] if {$filename eq ""} return; # they clicked cancel set extension [file extension $filename] set oldfilename $filename set filename [regsub -- "$extension$" $filename [string tolower $extension]] if { ! [regexp -- "\.(pd|pat|mxt)$" $filename]} { # we need the file extention even on Mac OS X set filename $filename.pd } # test again after downcasing and maybe adding a ".pd" on the end if {$filename ne $oldfilename && [file exists $filename]} { set answer [tk_messageBox -type okcancel -icon question -default cancel\ -message [_ "\"$filename\" already exists. Do you want to replace it?"]] if {$answer eq "cancel"} return; # they clicked cancel } set dirname [file dirname $filename] set basename [file tail $filename] pdsend "$name savetofile [enquote_path $basename] [enquote_path $dirname]" set ::pd_menucommands::menu_new_dir $dirname } #------------------------------------------------------------------------------# # mouse usage proc pdtk_canvas_motion {mycanvas x y mods} { set mytoplevel [winfo toplevel $mycanvas] pdsend "$mytoplevel motion [$mycanvas canvasx $x] [$mycanvas canvasy $y] $mods" } proc pdtk_canvas_mouse {mycanvas x y b f} { set mytoplevel [winfo toplevel $mycanvas] pdsend "$mytoplevel mouse [$mycanvas canvasx $x] [$mycanvas canvasy $y] $b $f" } proc pdtk_canvas_mouseup {mycanvas x y b} { set mytoplevel [winfo toplevel $mycanvas] pdsend "$mytoplevel mouseup [$mycanvas canvasx $x] [$mycanvas canvasy $y] $b" } proc pdtk_canvas_rightclick {mycanvas x y b} { set mytoplevel [winfo toplevel $mycanvas] pdsend "$mytoplevel mouse [$mycanvas canvasx $x] [$mycanvas canvasy $y] $b 8" } # on X11, button 2 pastes from X11 clipboard, so simulate normal paste actions proc pdtk_canvas_clickpaste {mycanvas x y b} { pdtk_canvas_mouse $mycanvas $x $y $b 0 pdtk_canvas_mouseup $mycanvas $x $y $b pdtk_pastetext } #------------------------------------------------------------------------------# # canvas popup menu # since there is one popup that is used for all canvas 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 same as the menubar in pd_menus.tcl but the opposite of the 'bind' # commands in pd_bindings.tcl proc ::pdtk_canvas::create_popup {} { if { ! [winfo exists .popup]} { # the popup menu for the canvas menu .popup -tearoff false .popup add command -label [_ "Properties"] \ -command {popup_action $::focused_window 0} .popup add command -label [_ "Open"] \ -command {popup_action $::focused_window 1} .popup add command -label [_ "Help"] \ -command {popup_action $::focused_window 2} } } proc popup_action {mytoplevel action} { pdsend "$mytoplevel done-popup $action $::popup_xpix $::popup_ypix" } proc pdtk_canvas_popup {mytoplevel xpix ypix hasproperties hasopen} { set ::popup_xpix $xpix set ::popup_ypix $ypix if {$hasproperties} { .popup entryconfigure [_ "Properties"] -state normal } else { .popup entryconfigure [_ "Properties"] -state disabled } if {$hasopen} { .popup entryconfigure [_ "Open"] -state normal } else { .popup entryconfigure [_ "Open"] -state disabled } set mycanvas "$mytoplevel.c" tk_popup .popup [expr $xpix + [winfo rootx $mycanvas]] \ [expr $ypix + [winfo rooty $mycanvas]] 0 } #------------------------------------------------------------------------------# # procs for canvas events # check or uncheck the "edit" menu item proc pdtk_canvas_editval {mytoplevel value} { set ::editmode($mytoplevel) $value # TODO figure how to change Edit Mode/Interact Mode text and have menu # enabling and disabling working still in pd_menus.tcl # if {$value == 0} { # $::pd_menus::menubar.edit entryconfigure [_ "Interact Mode"] -label [_ "Edit Mode"] # } else { # $::pd_menus::menubar.edit entryconfigure [_ "Edit Mode"] -label [_ "Interact Mode"] # } #$mytoplevel.menubar.edit entryconfigure [_ "Edit Mode"] -indicatoron $value # TODO make this work, probably with a proc in pd_menus, or maybe the menu # item can track the editmode variable } proc pdtk_undomenu {args} { # TODO make this work, probably with a proc in pd_menus puts "pdtk_undomenu $args" } proc pdtk_canvas_getscroll {mycanvas} { # TODO make this work # the C code still sends a .c canvas, so get the toplevel set mytoplevel [winfo toplevel $mycanvas] # puts stderr "pdtk_canvas_getscroll $mycanvas" }