Package teamwork :: Package widgets :: Package PsychGUI :: Package AgentWindow :: Module AgentWindow
[hide private]
[frames] | no frames]

Source Code for Module teamwork.widgets.PsychGUI.AgentWindow.AgentWindow

  1  import copy 
  2  import string 
  3  from Tkinter import * 
  4  import tkMessageBox 
  5  import Pmw 
  6  from teamwork.agent.RecursiveAgent import RecursiveAgent 
  7  from teamwork.agent.GoalBased import GoalBasedAgent 
  8  from teamwork.agent.stereotypes import Stereotyper 
  9  from teamwork.widgets.MultiWin import InnerWindow 
 10  from PropertyPane import PropertyFrame 
 11  from StatePane import StateFrame 
 12  from GoalPane import GoalFrame 
 13  from BeliefPane import BeliefFrame 
 14  from MentalModelPane import MentalModelFrame 
 15  from PolicyPane import PolicyFrame 
 16  from ActionPane import ActionFrame 
 17  from ActionEditor import ActionEditor 
 18  from MessagePane import MessageFrame 
 19  from ObservationPane import ObservationFrame 
 20  from RelationshipPane import RelationFrame 
 21  from teamwork.widgets.images import getPILImage 
 22   
23 -class AgentWin(Pmw.MegaArchetype):
24 """Widget for displaying an agent 25 26 The following panes have separate widgets: 27 - L{General<PropertyFrame>} 28 - L{State<StateFrame>} 29 - L{Actions<ActionFrame>} 30 - L{Goals<GoalFrame>} 31 - L{Observations<ObservationFrame>} 32 - L{Beliefs<BeliefFrame>} 33 - L{Mental Models<MentalModelFrame>} 34 - L{Policy<PolicyFrame>} 35 - L{Messages<MessageFrame>} 36 - L{Relationships<RelationshipPane>} 37 """ 38 39 agtHeight = 700 40 agtWidth = 750 41
42 - def __init__(self, frame, **kw):
43 44 self.paneSpecs = \ 45 {'General': {'type': 'General','widget': PropertyFrame, 46 'image':getPILImage('icons/home.png')}, 47 'State': {'type': 'State','widget': StateFrame,'tag':'S', 48 'image': getPILImage('icons/globe-green.png')}, 49 'Actions': {'type': 'Actions','widget': ActionFrame,'tag':'A', 50 'image': getPILImage('icons/hammer-screwdriver.png')}, 51 'Goals': {'type': 'Goals','widget': GoalFrame,'tag':'R', 52 'image': getPILImage('icons/trophy.png')}, 53 'Observations': {'type': 'Observations','widget': ObservationFrame, 54 'image': getPILImage('icons/binocular.png')}, 55 'Beliefs': {'type': 'Beliefs','widget': BeliefFrame, 56 'image':getPILImage('icons/users.png')}, 57 'Policy': {'type': 'Policy','widget': PolicyFrame,'tag':'P', 58 'image': getPILImage('icons/traffic-light.png')}, 59 'Messages': {'type': 'Messages','widget': MessageFrame, 60 'image':getPILImage('icons/balloon.png')}, 61 'Relationships': {'type': 'Relationships','widget': RelationFrame, 62 'image':getPILImage('icons/chain.png')}, 63 'Mental Models': {'type': 'Mental Models', 64 'widget': MentalModelFrame}, 65 } 66 optiondefs = ( 67 ('entity', None, Pmw.INITOPT), 68 ('society',{},Pmw.INITOPT), 69 ('x', 0, Pmw.INITOPT), 70 ('y', 0, Pmw.INITOPT), 71 ('balloon',None, Pmw.INITOPT), 72 ('actCmd',lambda x,y:{},Pmw.INITOPT), 73 ('msgCmd',lambda v,w,x,y,z: {},Pmw.INITOPT), 74 ('policyCmd',None,Pmw.INITOPT), 75 ('hypoCmd',None,Pmw.INITOPT), 76 ('stepCmd',None,Pmw.INITOPT), 77 ('valueCmd',None,Pmw.INITOPT), 78 ('abstract',None,Pmw.INITOPT), 79 ('expert',0,self.setExpert), 80 ('beta',False,Pmw.INITOPT), 81 ('destroycommand',None,Pmw.INITOPT), 82 # Flag for whether we should create an entire InnerWindow 83 ('window',True,Pmw.INITOPT), 84 ) 85 self.defineoptions(kw,optiondefs) 86 Pmw.MegaArchetype.__init__(self,frame) 87 # Determine which panes are relevant 88 self.panes = [self.paneSpecs['General'], 89 self.paneSpecs['State']] 90 if self['abstract'] or len(self['entity'].actions.getOptions()) > 0: 91 self.panes.append(self.paneSpecs['Actions']) 92 if isinstance(self['entity'],GoalBasedAgent): 93 self.panes.append(self.paneSpecs['Goals']) 94 self.panes.append(self.paneSpecs['Observations']) 95 if not self['abstract'] and not self['entity'].parent: 96 self.panes.append(self.paneSpecs['Beliefs']) 97 if not self['abstract'] and len(self['entity'].actions.getOptions()) > 0: 98 self.panes.append(self.paneSpecs['Policy']) 99 if not self['abstract']: 100 self.panes.append(self.paneSpecs['Messages']) 101 self.panes.append(self.paneSpecs['Relationships']) 102 # Save belief widgets 103 self.policywidgets = {} 104 self.bstatewidgets = {} 105 if self['window']: 106 self.win = InnerWindow(parent = frame, title = self['entity'].name, 107 height = self.agtHeight, width = self.agtWidth, 108 x = self['x'], y = self['y'], 109 destroycommand=self['destroycommand']) 110 container = self.win.component('frame') 111 else: 112 self.win = None 113 container = frame 114 # Create all of the separate panes 115 notebook = self.createcomponent('notebook',(), None, Pmw.NoteBook, 116 (container,),raisecommand=self.selectPage, 117 ) 118 notebook.pack(fill='both',expand='yes') 119 for entry in self.panes: 120 self.create_pane(self['entity'], notebook, entry) 121 self.selectPage(self.panes[0]['type']) 122 self.initialiseoptions()
123
124 - def setExpert(self,entity=None):
125 if not entity: 126 entity = self['entity'] 127 for component in self.components(): 128 if self.componentgroup(component) == 'Pane': 129 self.component(component).configure(expert=self['expert']) 130 if not self['abstract'] and len(entity.actions.getOptions()) > 0: 131 # Generic models don't have polices, nor do agents 132 # with no actions 133 self.setExpertPane(entity,'Policy','Messages') 134 if isinstance(entity,Stereotyper) and \ 135 len(entity.getEntities()) > 0 and self['beta']: 136 # ...only those agents with mental models and theory 137 # of mind 138 self.setExpertPane(entity,'Mental Models','Policy')
139
140 - def setExpertPane(self,entity,pane,before):
141 notebook = self.component('notebook') 142 if self['expert']: 143 spec = self.paneSpecs[pane] 144 try: 145 tag = spec['tag'] 146 except KeyError: 147 tag = spec['type'] 148 if not tag in notebook.pagenames(): 149 page = notebook.insert(tag,before=before) 150 self.create_pane(entity,notebook,spec,page) 151 elif pane in notebook.pagenames(): 152 if entity.parent: 153 self.destroycomponent('%s %s' % \ 154 (entity.ancestry(),pane)) 155 else: 156 self.destroycomponent(pane) 157 notebook.delete(pane)
158
159 - def applyPolicy(self,entity):
160 """Display's the hypothetical result of the entity's policy""" 161 if entity.parent: 162 widget = self.component('%s Actions' % (entity.ancestry())) 163 else: 164 widget = self.component('Actions') 165 options = widget.getActions() 166 if len(options) == 0: 167 tkMessageBox.showerror('Agent Action Error','The agent has no allowable actions! Please go to the Action pane and select at least one possible choice.') 168 else: 169 self['hypoCmd'](entity,options)
170
171 - def stepEntity(self):
172 """Performs the policy-selected action of the given entity""" 173 widget = self.component('Actions') 174 options = widget.getActions() 175 if len(options) == 0: 176 tkMessageBox.showerror('Agent Action Error','The agent has no allowable actions! Please go to the Action pane and select at least one possible choices.') 177 else: 178 self['stepCmd'](self['entity'],options)
179
180 - def value(self,entity):
181 """Performs the policy-selected action of the given entity""" 182 self['valueCmd'](entity)
183
184 - def actEntity(self,action):
185 result = self['actCmd']({self['entity'].name:action})
186
187 - def create_pane(self, entity, notebook, pane, page=None):
188 if entity.parent: 189 label = '%s %s' % (entity.ancestry(),pane['type']) 190 else: 191 label = pane['type'] 192 if pane.has_key('tag'): 193 tab = pane['tag'] 194 else: 195 tab = pane['type'] 196 # Access notebook page 197 if page is None: 198 try: 199 page = notebook.add(tab,tab_text='',tab_image=pane['image']) 200 except KeyError: 201 page = notebook.add(tab) 202 if self['balloon']: 203 self['balloon'].bind(self.component('notebook').tab(tab),pane['type']) 204 # Generate page content 205 try: 206 frame = self.component(label) 207 except KeyError: 208 frame = self.createcomponent(label,(),'Pane',pane['widget'],(page,), 209 balloon=self['balloon'], 210 entity=entity, 211 society=self['society'], 212 expert=self['expert'], 213 generic=self['abstract']) 214 # Do some specialized configuration 215 if isinstance(frame,Pmw.ScrolledFrame): 216 frame.configure(horizflex='expand') 217 if pane['type'] == 'General': 218 frame.configure(step=self.stepEntity,policy=self.applyPolicy, 219 valueCmd=self['valueCmd']) 220 elif pane['type'] == 'State': 221 for feature in entity.getStateFeatures(): 222 cmd = lambda widget=frame,f=feature:widget.set(f) 223 if entity.parent: 224 self.bstatewidgets[entity.ancestry()+' '+feature] = cmd 225 elif pane['type'] == 'Actions': 226 if not self['abstract']: 227 # Cannot actually perform action in generic society 228 frame.configure(command=self.actEntity) 229 elif pane['type'] == 'Goals': 230 if not self['abstract']: 231 frame.configure(society=None) 232 frame.recreate_goals() 233 elif pane['type'] == 'Policy': 234 if entity.parent: 235 widget = self.component('%s Actions' % (entity.ancestry())) 236 else: 237 widget = self.component('Actions') 238 frame.configure(actions=widget,command=self['policyCmd']) 239 elif pane['type'] == 'Beliefs': 240 frame.configure(window=self.__class__) 241 elif pane['type'] == 'Messages': 242 frame.configure(send=self['msgCmd']) 243 frame.pack(expand='yes',fill='both')
244
245 - def update(self):
246 self.recreate_state() 247 if 'Actions' in self.components(): 248 self.component('Actions').drawActions() 249 if 'Goals' in self.components(): 250 self.component('Goals').recreate_goals() 251 self.recreate_mental() 252 self.component('Relationships').update()
253
254 - def recreate_mental(self):
255 try: 256 frame = self.component('Mental Models') 257 except KeyError: 258 frame = None 259 if frame: 260 frame.recreate_mental()
261
262 - def recreate_state(self):
263 self.component('State').update() 264 for key in self.bstatewidgets.keys(): 265 apply(self.bstatewidgets[key],())
266
267 - def selectPage(self,page):
268 palette = Pmw.Color.getdefaultpalette(self.interior()) 269 widget = self.component('notebook') 270 for name in filter(lambda n:widget.componentgroup(n) == 'Page', 271 widget.components()): 272 if name == page: 273 widget.tab(name).configure(fg=palette['selectForeground'], 274 bg=palette['selectBackground']) 275 else: 276 widget.tab(name).configure(fg=palette['activeForeground'], 277 bg=palette['activeBackground']) 278 if page == 'Actions' and self['abstract']: 279 self.component('Actions_type_entry').focus_set() 280 elif page == 'State' and self['abstract']: 281 self.component('State_new_entry').focus_set() 282 elif page == 'General': 283 try: 284 self.component('General_description_text').focus_set() 285 except KeyError: 286 # Probably haven't rendered this pane yet 287 pass
288 ## elif page == 'Relationships' and self['abstract']: 289 ## self.component('Relationships_Relationship Name_entry').focus_set() 290 291
292 - def selectBeliefPage(self,page):
293 if page == 'Policy' and len(self.activeBelief.policy.attributes) > 0: 294 widget = self.component('%s Policy' % \ 295 (self.activeBelief.ancestry())) 296 widget.displayPolicy()
297
298 - def setState(self,state='normal'):
299 """Sets the state of all of the agent editing widgets 300 - NORMAL: enables all of the widgets 301 - DISABLED: disables all of the widgets 302 """ 303 for pane in self.panes: 304 if pane['type'] == 'General': 305 try: 306 widget = self.component('%s Run Box' % (self['entity'].ancestry())) 307 widget.configure(Button_state=state) 308 except KeyError: 309 pass 310 ## widget.component('hypo').configure(state=state) 311 elif pane['type'] in ['State','Actions','Goals']: 312 try: 313 widget = self.component(pane['type']) 314 widget.setState(state) 315 except KeyError: 316 pass 317 elif pane['type'] == 'Mental Models': 318 if len(self['entity'].getEntities()) > 0: 319 try: 320 widget = self.component('%s Lock Models' % \ 321 (self['entity'].ancestry())) 322 except KeyError: 323 continue 324 widget.configure(state=state) 325 for other in self['entity'].getEntityBeliefs(): 326 widget = self.component('%s Mental Models' % \ 327 (other.ancestry())) 328 if state == DISABLED: 329 widget.disable() 330 elif self['entity'].modelChange: 331 widget.enable()
332
333 - def renameEntity(self,old,new):
334 """ 335 @param old: the current name of the entity 336 @param new: the new name of the entity 337 @type old,new: str 338 """ 339 if self.win and self['entity'].name == new: 340 self.win.configure(title=new) 341 self.component('Relationships').renameEntity(old,new) 342 if self.component('Actions_object').get() == old: 343 self.component('Actions_object').selectitem(0) 344 self.update()
345