from Tkinter import *

# some vocabulary to keep from getting confused. This terminology 
# is something I cooked up for this file, but follows the man pages 
# pretty closely
# 
# 
# 
#       This is a MENUBUTTON
#       V
# +-------------+
# |             |
# 
# +------------++------------++------------+
# |            ||            ||            |
# |  File      ||  Edit      || Options    |   <-------- the MENUBAR
# |            ||            ||            |
# +------------++------------++------------+
# | New...         |
# | Open...        |
# | Print          |
# |                |  <-------- This is a MENU. The lines of text in the menu are
# |                |                            MENU ENTRIES
# |                +---------------+
# | Open Files >   | file1         |               
# |                | file2         |
# |                | another file  | <------ this cascading part is also a MENU
# +----------------|               |
#                  |               |
#                  |               |
#                  |               |
#                  +---------------+



# some miscellaneous callbacks
def new_file():
    print "opening new file"


def open_file():
    print "opening OLD file"

def print_something():
    print "picked a menu item"



anchovies = 0

def print_anchovies():
    global anchovies
    anchovies = not anchovies
    print "anchovies?", anchovies

def makeCommandMenu():
    # make menu button 
    Command_button = Menubutton(mBar, {'text': 'Simple Button Commands', 
				    'underline': 0,
				    Pack: {'side': 'left', 
					   'padx': '2m'}})
    
    # make the pulldown part of the File menu. The parameter passed is the master.
    # we attach it to the button as a python attribute called "menu" by convention.
    # hopefully this isn't too confusing...
    Command_button.menu = Menu(Command_button)
    

    # just to be cute, let's disable the undo option:
    Command_button.menu.add('command', {"label" : "Undo"} )
    # undo is the 0th entry...
    Command_button.menu.entryconfig(0, {"state" : "disabled"})

    Command_button.menu.add('command', {'label': 'New...',

				     'underline': 0, 
				     'command' : new_file})
    
    
    Command_button.menu.add('command', {'label': 'Open...', 
				     'underline': 0, 
				     'command' : open_file})

    Command_button.menu.add('command', {'label': 'Different Font', 
					'underline': 0, 
					'font' : '-*-helvetica-*-r-*-*-*-180-*-*-*-*-*-*', 
					'command' : print_something})
    
    # we can make bitmaps be menu entries too. File format is X11 bitmap.
    # if you use XV, save it under X11 bitmap format. duh-uh.,..
#    Command_button.menu.add('command', {'bitmap' : '@/home/mjc4y/ftp/tcl/tk3.6/library/demos/bitmaps/face'})
    Command_button.menu.add('command', {'bitmap' : '@/home/mjc4y/dilbert/project.status.is.doomed.last.panel.bm'})
    
    # this is just a line
    Command_button.menu.add('separator')

    # change the color
    Command_button.menu.add('command', {'label': 'Quit', 
					'underline': 0, 
					'background' : 'red', 
					'activebackground' : 'green', 
					'command': 'exit'})
    
    
    # set up a pointer from the file menubutton back to the file menu
    Command_button['menu'] = Command_button.menu

    return Command_button



def makeCascadeMenu():
    # make menu button 
    Cascade_button = Menubutton(mBar, {'text': 'Cascading Menus', 
				       'underline': 0,
				       Pack: {'side': 'left', 
					      'padx': '2m'}})
    
    # the primary pulldown
    Cascade_button.menu = Menu(Cascade_button)

    # this is the menu that cascades from the primary pulldown....
    Cascade_button.menu.choices = Menu(Cascade_button.menu)

    # ...and this is a menu that cascades from that.
    Cascade_button.menu.choices.wierdones = Menu(Cascade_button.menu.choices)

    # then you define the menus from the deepest level on up.
    Cascade_button.menu.choices.wierdones.add('command', {'label' : 'avacado'})
    Cascade_button.menu.choices.wierdones.add('command', {'label' : 'belgian endive'})
    Cascade_button.menu.choices.wierdones.add('command', {'label' : 'beefaroni'})

    # definition of the menu one level up...
    Cascade_button.menu.choices.add('command', {'label' : 'Chocolate'})
    Cascade_button.menu.choices.add('command', {'label' : 'Vanilla'})
    Cascade_button.menu.choices.add('command', {'label' : 'TuttiFruiti'})
    Cascade_button.menu.choices.add('command', {'label' : 'WopBopaLoopBapABopBamBoom'})
    Cascade_button.menu.choices.add('command', {'label' : 'Rocky Road'})
    Cascade_button.menu.choices.add('command', {'label' : 'BubbleGum'})
    Cascade_button.menu.choices.add('cascade', {'label' : 'Wierd Flavors', 
						'menu'  : Cascade_button.menu.choices.wierdones})

    # and finally, the definition for the top level
    Cascade_button.menu.add('cascade', {'label' : 'more choices', 
					'menu' : Cascade_button.menu.choices})


    Cascade_button['menu'] = Cascade_button.menu

    return Cascade_button

def makeCheckbuttonMenu():
    global fred
    # make menu button 
    Checkbutton_button = Menubutton(mBar, {'text': 'Checkbutton Menus', 
					   'underline': 0,
					   Pack: {'side': 'left', 
					      'padx': '2m'}})
    
    # the primary pulldown
    Checkbutton_button.menu = Menu(Checkbutton_button)

    # and all the check buttons. Note that the "variable" "onvalue" and "offvalue" options
    # are not supported correctly at present. You have to do all your application 
    # work through the calback.
    Checkbutton_button.menu.add('checkbutton', {'label': 'Pepperoni'})
    Checkbutton_button.menu.add('checkbutton', {'label': 'Sausage'})
    Checkbutton_button.menu.add('checkbutton', {'label': 'Extra Cheese'})

    # so here's a callback
    Checkbutton_button.menu.add('checkbutton', {'label': 'Anchovy', 
						'command' : print_anchovies})

    # and start with anchovies selected to be on. Do this by 
    # calling invoke on this menu option. To refer to the "anchovy" menu
    # entry we need to know it's index. To do this, we use the index method
    # which takes arguments of several forms: 
    #
    # argument        what it does
    # -----------------------------------
    # a number        -- this is useless. 
    # "last"          -- last option in the menu
    # "none"          -- used with the activate command. see the man page on menus
    # "active"        -- the currently active menu option. A menu option is made active
    #                         with the 'activate' method
    # "@number"       -- where 'number' is an integer and is treated like a y coordinate in pixels
    # string pattern  -- this is the option used below, and attempts to match "labels" using the 
    #                    rules of Tcl_StringMatch
    Checkbutton_button.menu.invoke(Checkbutton_button.menu.index('Anchovy'))

    # set up a pointer from the file menubutton back to the file menu
    Checkbutton_button['menu'] = Checkbutton_button.menu

    return Checkbutton_button


def makeRadiobuttonMenu():
    # make menu button 
    Radiobutton_button = Menubutton(mBar, {'text': 'Radiobutton Menus', 
					   'underline': 0,
					   Pack: {'side': 'left', 
					      'padx': '2m'}})
    
    # the primary pulldown
    Radiobutton_button.menu = Menu(Radiobutton_button)

    # and all the Radio buttons. Note that the "variable" "onvalue" and "offvalue" options
    # are not supported correctly at present. You have to do all your application 
    # work through the calback.
    Radiobutton_button.menu.add('radiobutton', {'label': 'Republican'})
    Radiobutton_button.menu.add('radiobutton', {'label': 'Democrat'})
    Radiobutton_button.menu.add('radiobutton', {'label': 'Libertarian'})
    Radiobutton_button.menu.add('radiobutton', {'label': 'Commie'})
    Radiobutton_button.menu.add('radiobutton', {'label': 'Facist'})
    Radiobutton_button.menu.add('radiobutton', {'label': 'Labor Party'})
    Radiobutton_button.menu.add('radiobutton', {'label': 'Torie'})
    Radiobutton_button.menu.add('radiobutton', {'label': 'Independent'})
    Radiobutton_button.menu.add('radiobutton', {'label': 'Anarchist'})
    Radiobutton_button.menu.add('radiobutton', {'label': 'No Opinion'})

    # set up a pointer from the file menubutton back to the file menu
    Radiobutton_button['menu'] = Radiobutton_button.menu

    return Radiobutton_button


def makeDisabledMenu(): 
    Dummy_button = Menubutton(mBar, {'text': 'Dead Menu', 
				     'underline': 0,
				     Pack: {'side': 'left', 
					    'padx': '2m'}})

    # this is the standard way of turning off a whole menu
    Dummy_button["state"] = "disabled"
    return Dummy_button

#################################################
#### Main starts here ...
root = Tk()


# make a menu bar
mBar = Frame(root, {'relief': 'raised', 
		    'bd': 2,
		    Pack: {'side': 'top', 
			   'fill': 'x'}})

Command_button     = makeCommandMenu()
Cascade_button     = makeCascadeMenu()
Checkbutton_button = makeCheckbuttonMenu()
Radiobutton_button = makeRadiobuttonMenu()
NoMenu             = makeDisabledMenu()

# finally, install the buttons in the menu bar. 
# This allows for scanning from one menubutton to the next.
mBar.tk_menuBar(Command_button, Cascade_button, Checkbutton_button, Radiobutton_button, NoMenu)


root.title('menu demo')
root.iconname('menu demo')

root.mainloop()






