#!/usr/X11/bin/wish -f # This is the code for draw.tcl, a simple Tcl/Tk # drawing program featured in the December 94 # issue of _Linux_Journal_. # # You may have to change the first line of this # file to reflect the path to `wish' on your system. # # (c) 1994 Matt Welsh, mdw@sunsite.unc.edu # This code is placed under the GNU General Public # License. ################################################## # Global variables. Used to keep track of # objects and positions. set orig_x 0 set orig_y 0 set bump 0 ################################################## # This function is invoked by the "Save Postscript" # menu option. It pops up a dialog box asking for # a filename. It then saves a PostScript image of # the Canvas widget to the named file. proc get_ps {} { # Create a new "toplevel" widget for the # dialog box toplevel .ask -class dialog # Tell the window manager what title to use # for the new window wm title .ask "Save PostScript..." # Create two frame widgets. A frame is used # to group widgets together. frame .ask.top -bd 3 -relief groove frame .ask.bottom -bd 1 pack .ask.top .ask.bottom -side top -fill both # A label and entry widget in the top frame label .ask.top.l -text "Save PostScript to file:" entry .ask.top.e -relief sunken -width 30 \ -textvariable fname pack .ask.top.l -side left pack .ask.top.e -side left -padx 1m -pady 1m # When return is pressed in the entry widget, # save the postscript to the file, and destroy # the dialog box. bind .ask.top.e { .c postscript -colormode color -file $fname destroy .ask } ################################################## # Two buttons, "Okay" and "Cancel", for the # bottom frame. When "Okay" is pressed, save # the PostScript as above. When "Cancel" is # pressed, just destroy the dialog box. button .ask.bottom.okay -text "Okay" -command { .c postscript -file $fname destroy .ask } button .ask.bottom.cancel -text "Cancel" -command { destroy .ask } # Pack the buttons into the frame. pack .ask.bottom.okay .ask.bottom.cancel \ -side left -padx 1m -pady 1m -expand 1 # Confine keyboard and mouse events to the # dialog window grab set .ask } ################################################## # All right, now we create the various widgets # used by the application. # First, create a frame to act as the menu bar. frame .mbar -relief groove -bd 3 pack .mbar -side top -expand yes -fill x # Create three menu items---"File", "Object", and # "Color" menubutton .mbar.file -text "File" -underline 0 \ -menu .mbar.file.menu menubutton .mbar.obj -text "Object" -underline 0 \ -menu .mbar.obj.menu menubutton .mbar.color -text "Color" -underline 0 \ -menu .mbar.color.menu pack .mbar.file .mbar.obj .mbar.color -side left # Create the file menu, and add the "Save Postscript" # and "Quit" items to it. menu .mbar.file.menu .mbar.file.menu add command -label \ "Save Postscript..." -command { get_ps } .mbar.file.menu add command -label "Quit" \ -command { exit } # Create the object menu, and add two radiobutton # entries to it. These entries set the object_type # variable. menu .mbar.obj.menu .mbar.obj.menu add radiobutton -label "Ovals" \ -variable object_type -value oval .mbar.obj.menu add radiobutton -label "Rectangles" \ -variable object_type -value rect ################################################## # Create the color menu, and add items to it. menu .mbar.color.menu .mbar.color.menu add radiobutton -background red \ -label "Red" -variable thecolor -value red .mbar.color.menu add radiobutton -background blue \ -label "Blue" -variable thecolor -value blue .mbar.color.menu add radiobutton -background green \ -label "Green" -variable thecolor -value green .mbar.color.menu add radiobutton -background orange \ -label "Orange" -variable thecolor -value orange # Enable keyboard shortcuts for this menubar. tk_menuBar .mbar .mbar.file .mbar.obj .mbar.color focus .mbar # Create a canvas and pack it in canvas .c pack .c -side top # When button-1 is pressed in the canvas, create # an object of type $object_type. bind .c { # Within event bindings, %x and %y refer to # the event location (i.e., where the button # press occurred). set orig_x %x set orig_y %y # Create an oval. "thecolor" is a global # variable indicating the color to use---it is # set by the Color menu. set theitem [ .c create $object_type %x %y %x %y -fill $thecolor ] } # When we drag button 1, delete the current object # and replace it. This allows us to "resize" the # object as we draw it. bind .c { .c delete $theitem set theitem [ .c create $object_type $orig_x $orig_y %x %y -fill $thecolor ] } # Turn on ovals and red, by invoking the first item # in the object and color menus. .mbar.obj.menu invoke 0 .mbar.color.menu invoke 0