The latest version of this document can be found at www.broad.ology.org.uk/amiga/proaction/02_Adding_A_Gadget.html
1: #!python 2: # 3: ################################################################ 4: # 5: # Anatomy of a ProAction Application. 6: # 7: # 02_Adding_A_Gadget.py 8: # 9: # Add a top level layout 10: # Add a Gadget To That Layout 11: # Handle The Gadget Being Pressed 12: # 13: ################################################################ 14: # 15: # 16: 17: import sys 18: import os 19: import arexx 20: 21: class Application: 22: 23: def __init__(self): 24: 25: self.PORTNAME = "TestScript" 26: self.UNIQUE = True 27: 28: # 29: # HandleInput() receives commands at the ARexx port and acts accordingly. 30: # They may be commands from ProAction (the CLOSE command in this example) 31: # Or they maybe commands from other ARexx based scripts etc. 32: # 33: 34: def HandleInput(pyport,guikey): 35: 36: global app 37: 38: # Loop until die becomes non zero 39: die = 0 40: while die == 0: 41: # Wait for a message to arrive at our Port 42: pyport.wait() 43: # Get the first message (but there may be more than one) 44: msg = pyport.getmsg() 45: # Loop until all queued messages are processed 46: while msg: 47: cmd = msg.msg 48: msg.reply() 49: if cmd == "QUIT": 50: die = 1 51: break 52: elif cmd[:5] == "CLOSE": 53: # Window Close Button Pressed 54: die = 1 55: break 56: elif cmd[:8] == "GADGETUP": 57: # The format of this command is 58: # GADGETUP GUIID guikey GADGETID gid CODE code 59: # We uses the split() method of the python string object to neatly parse this. 60: # The value lguikey would allow us to deal with multiple GUI windows. 61: (dummy,dummy,lguikey,dummy,gid,dummy,code) = cmd.split() 62: if gid == app.ok_gid: 63: die = 1 64: print "OK Pressed" 65: else: 66: print cmd 67: msg = pyport.getmsg() 68: 69: 70: def DoGUI(pubscreen): 71: 72: global app 73: 74: 75: # Our script needs an incoming ARexx port to receive messages from 76: # ProAction. We create this using the arexx modules Port method 77: # Which returns a Port object 78: 79: 80: 81: pyport = arexx.Port(app.PORTNAME) 82: if pyport: 83: if app.UNIQUE: 84: if pyport.name != app.PORTNAME: 85: ErrorExit("ARexx Port " + app.PORTNAME + " already Exists!") 86: 87: # First we'll build our window.class tagslist 88: # Python can't use send StemVars at the moment so we'll 89: # use the TAGSTRING tecnique throughout. 90: 91: wintags = "" 92: wintags += "WA_Width,300," 93: wintags += "WA_Height,100," 94: wintags += "WA_DragBar,1," 95: wintags += "WA_DepthGadget,1," 96: wintags += "WA_SizeGadget,1," 97: wintags += "WA_CloseGadget,1," 98: wintags += "WA_Title,"+ sys.argv[0] + "," 99: wintags += "WA_PubScreenFallBack,1," 100: wintags += "WA_PubScreenName," + pubscreen + "," 101: wintags += "WINDOW_Position,WPOS_CENTERSCREEN," 102: wintags += "WA_Activate,1," 103: wintags += "TAG_DONE" 104: 105: # Now a taglist to define our top level layout.gadget 106: 107: layouttags = "" 108: layouttags += "LAYOUT_Orientation,LAYOUT_ORIENT_VERT," 109: layouttags += "TAG_DONE" 110: 111: 112: (rc,rc2,guikey) = arexx.dorexx("PROACTION","CREATEGUI PORTNAME " + pyport.name + " TAGSTRING "" + wintags + """) 113: if rc == 0: 114: # we can now build our GUI here; 115: 116: # firstly we add the top level layout gadget, we use a special command 117: # ADDLAYOUT to do this, which in combination with ENDLAYOUT manages nesting 118: # of complex layout trees for us. 119: 120: (rc,rc2,current_layout_gid) = arexx.dorexx("PROACTION","ADDLAYOUT GUIID " + guikey + " TAGSTRING "" + layouttags + """) 121: 122: # Now we add a button gadget. The ADDGADGET function adds the 123: # gadget to the currently active layout. We save the resulting ID 124: # in our Application class object app. 125: 126: (rc,rc2,app.ok_gid) = arexx.dorexx("PROACTION","ADDGADGET GUIID " + guikey + " GADGETCLASS "button.gadget" TAGSTRING "GA_Text,_OK,GA_RelVerify,1,TAG_DONE"") 127: 128: # End of top level layout. 129: (rc,rc2,current_layout_gid) = arexx.dorexx("PROACTION","ENDLAYOUT GUIID " + guikey ) 130: 131: # Open our Window. 132: 133: (rc,rc2,result) = arexx.dorexx("PROACTION","OPENGUIWINDOW GUIID " + guikey) 134: 135: # Handle events at the ARexx port. 136: HandleInput(pyport,guikey) 137: 138: # All done now shutdown the GUI 139: 140: arexx.dorexx("PROACTION","DESTROYGUI GUIID " + guikey) 141: else: # pyport 142: ErrorExit("Couldn't create our ARexx port") 143: 144: # 145: # ErrorExit() throws up an RequestChoice notification to indicate 146: # a critical error. 147: # 148: 149: def ErrorExit(msg): 150: # Build our command as a string. 151: # We can use sys.argv[0] for the script name to make thsi more reusable. 152: command = "RequestChoice TYPE "ERROR" "" + sys.argv[0] + "" "" + msg + "" "OK" >NIL:" 153: # Call the command via the os.system() 154: os.system(command) 155: exit() 156: 157: # 158: # The support GetPorts() returns a list of public MsgPorts 159: # as a string 160: # 161: 162: 163: def GetPorts(): 164: # Depending on the version of python we may have a useful 165: # function that retuns just what we need, so we use the try 166: # except syntax to test. 167: 168: try: 169: ports = os.getports() 170: ports = " ".join(ports) 171: except AttributeError: 172: # The getports function wasn't present so we call the REXX 173: # equivalent. 174: (rc,rc2,ports) = arexx.dorexx("REXX","return show('P')") 175: if rc != 0: 176: # We couldn't even call REXX somwthing serioiusly up here 177: # Bail out with a requester. 178: ErrorExit("Couldn't Find ARexx!") 179: return ports 180: 181: 182: # Now we need to check that ProAction is present an available to us, 183: # So first get a list of active ports 184: 185: ports = GetPorts() 186: 187: # Then check for ProActions port which will be "PROACTION". 188: # Port names are case sensitive. 189: 190: if -1 == ports.find("PROACTION"): 191: # No ProAction start it 192: os.system("RUN >"T:proactionpid" *>NIL: APPDIR:PROACTION") 193: os.system("C:WaitForPort PROACTION") 194: # Now check again 195: ports = GetPorts() 196: if -1 == ports.find("PROACTION"): 197: # Still not there :-( 198: ErrorExit("Unable to start or find ProAction GUIServer") 199: 200: 201: # Okay we should be good to go now 202: # Initialise our aplication 203: 204: app = Application(); 205: 206: DoGUI("Workbench") 207: