 3D Modelling with VPython
			3D Modelling with VPython
		Lesson 8 - Events
In this lesson we look at mouse and keyboard events and how VPython reports them.
		
Objectives
By the end of the lesson the student should be able to:
- Understand how create a label containing text.
 
- Understand how to detect keyboard and mouse events.
- Understand how to define a function.
- Understand how to bind a function to an event.
- Understand how to bind an event to an object through a function.
- How to look for multiple keys being down.
Timings
		Teaching: 40 min
		Exercises: 20 min 
        
Description
Glowscript VPython can detect many mouse and keyboard events:
			mousedown
			mouseup
			mouseclick
			mouseleave
			mouseenter
			mousemove
 
			keydown
			keyup
			keypress
			Note: There is currently no way in GlowScript to handle right button or middle button events.
		
Events in VPython are controlled by scene.
		The scene is everything within the graphics window which is not a shape, such as the width and height of the graphics window,
		the background colour and lighting, the camera position and the degree of zoom.
		Lesson 11 will look at the scene in more detail.
The program
The code below displays two labels which are updated through keyboard and mouse events.
			# Define two labels with default texts
			txt = label(pos=vector(0,6,0), text='No keys pressed', align='center',height=36, color=color.green)
			txt2 = label(pos=vector(0,-3,0), text='Nothing pressed', align='center',height=36, color=color.green)
			
			# Define a function that is called when a key or mouse is pressed
			def getevent(ev):
			 k = keysdown() # a list of keys that are down
			
			#Define an "if" statement to 'look for' mouse events
			 if ev.event == 'mousedown':
			  txt.text='You mousedowned at\n' + ev.pos
			  txt.color=color.yellow  
			 else if ev.event == 'mouseup':
			  txt.text='Nothing clicked'
			  txt.color=color.red
			
			#Define an "if" statement to 'look for' keyboard events
			  txt2.text='You are holding down\n'  + k
			 else if ev.event == 'keydown':
			  txt.text='You pressed\n' + ev.key
			  txt.color=color.red
			  txt2.text='You are holding down\n'  + k
			
			#Define an "if" statement to 'look for' key events and reset text label back to default
			 if  ev.event == 'keyup':
			  txt.text='No keys pressed'
			  txt2.text='Nothing pressed'
			  txt2.color=color.green
			
			#Tell the "scene" to use the getevent function whenever a key or mouse is pressed
			scene.bind("mousedown", getevent)
			scene.bind("mouseup", getevent)
			scene.bind("keydown", getevent)
			scene.bind("keyup", getevent)
			
			#Tell the "scene" which events to respond to
			scene.waitfor('mousedown mouseup keydown keyup ')
		
Things to note
The last line of the program asks the scene to wait for the specified events.
			A function getevent(ev) is defined and it is bound to the event by the scene.bind() method.
			Now when the scene is clicked or a key is pressed, the getevent function is fired. When it is fired it passes the event data to the function via the ev variable.
			VPython keeps track of which keys are down using the keysdown() function, which returns a list of all the keys which are pressed.
			The getevent function then filters the event recieved and alters the text in the label accordingly.
			The ev variable in getevent is user defined. For example it could be 'e' or 'evt' or 'zxpw', but will contain the event data.
			Essentially think of the ev variable as a place where VPython 'puts' the details of the event.
			Here we use ev.event and ev.key, but there are more, such as ev.type, ev.ctrl, ev.shift, 
			ev.alt and ev.which.
Note: Keys with multiletter names are 'backspace', 'caps lock', 'tab', 'shift', 'ctrl', 'alt', 'pageup', 'pagedown', 'end', 'home', 'left', 'up', 'right', 'down', 'insert', 'delete', 'break', and the function keys 'f1' through 'f10'.
Exercise 1
					Copy the program above and do the following:
					Modify the program to make the word 'HELLO!' appear in the bottom label in magenta, when the user presses 'ctrl'+ 'alt' + shift.
				
				 
                            # Define two labels with default textsSolution to Exercise 1
			
                            txt = label(pos=vector(0,6,0), text='No keys pressed', align='center',height=36, color=color.green)
                            txt2 = label(pos=vector(0,-3,0), text='Nothing pressed', align='center',height=36, color=color.green)
                            
                            # Define a function that is called when a key or mouse is pressed
                            def getevent(ev):
                              k = keysdown() # a list of keys that are down
                            
                            #Define an "if" statement to 'look for' mouse events
                              if ev.event == 'mousedown':
                                txt.text='You mousedowned at\n' + ev.pos
                                txt.color=color.yellow
                              else if ev.event == 'mouseup':
                                txt.text='Nothing clicked'
                                txt.color=color.red
                                txt2.text='You are holding down\n' + k
                            
                            #Define an "if" statement to 'look for' keyboard events 
 
                              else if ev.event == 'keydown':
                                txt.text='You pressed\n' + ev.key
                                txt.color=color.red
                                txt2.text='You are holding down\n' + k
                              
                            #Define an "if" statement to 'look for' ctrl, alt and shift keys
                               if'ctrl' in k and 'alt' in k and 'shift' in k: # solution
                                 txt2.text='HELLO!'
                                 txt2.color=color.magenta
                               else:
                                 txt2.text='You are holding down\n' + k
                            
                            #Define an "if" statement to 'look for' key events and reset text label back to default
                              if ev.event == 'keyup':
                                txt.text='No keys pressed'
                                txt2.text='Nothing pressed'
                                txt2.color=color.green
                            
                            #Tell the "scene" to use the getevent function whenever a key or mouse is pressed
                            scene.bind("mousedown", getevent)
                            scene.bind("mouseup", getevent)
                            scene.bind("keydown", getevent)
                            scene.bind("keyup", getevent)
                            
                            #Tell the "scene" which events to respond to
                            scene.waitfor('mousedown mouseup keydown keyup ')
						
Conclusion
You should now be able to:
			 Create a label containing text.
			 Detect keyboard and mouse events.
			 Define a function.
			 Bind a function to an event.
			 Bind an event to an object through a function.
			 Look for multiple keys being down.