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: