#!/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 <Return> {
    .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 <ButtonPress-1> { 
  # 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 <B1-Motion> { 
  .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

