From: Kevin A. <ka...@us...> - 2004-04-30 00:00:02
|
Update of /cvsroot/pythoncard/PythonCard In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv28465 Modified Files: debug.py event.py model.py Log Message: added new background event binding and dispatch added hacks to MessageWatcher and EventQueue to support posting messages until we have an EventLog class added restore event (inverse of minimize) added singleItemExpandingSizerLayout method to background moved initialize event dispatch and bindWindowEvents to end of Background.__init__ to correct initialization bug with menus... Index: debug.py =================================================================== RCS file: /cvsroot/pythoncard/PythonCard/debug.py,v retrieving revision 1.124 retrieving revision 1.125 diff -C2 -d -r1.124 -r1.125 *** debug.py 25 Apr 2004 15:23:34 -0000 1.124 --- debug.py 29 Apr 2004 23:59:23 -0000 1.125 *************** *** 126,145 **** def eventOccurred(self, eventAdapter): ! evt = eventAdapter.getDispatchedEvent() ! eventName = evt.getName() ! sourceName = evt.getSource().name ! ! # KEA 2002-06-10 ! # displaying idle is a losing proposition ! # the act of displaying the idle event ends up ! # causing another idle event as the queue empties ! # with the wxSTC or at least that is what I think was ! # happening ! if eventName == event.IdleEvent.name: ! # print eventAdapter.getEventWasUsed(), eventName, sourceName ! return ! ! used = eventAdapter.getEventWasUsed() if used: eventText = eventName + ' : ' + sourceName --- 126,152 ---- def eventOccurred(self, eventAdapter): ! if isinstance(eventAdapter, tuple): ! # new way hack to stay compatible with one arg _notifyEventListeners ! eventName, sourceName, used = eventAdapter ! if eventName == event.IdleEvent.name: ! return ! else: ! # old way ! evt = eventAdapter.getDispatchedEvent() ! eventName = evt.getName() ! sourceName = evt.getSource().name ! evt = None + # KEA 2002-06-10 + # displaying idle is a losing proposition + # the act of displaying the idle event ends up + # causing another idle event as the queue empties + # with the wxSTC or at least that is what I think was + # happening + if eventName == event.IdleEvent.name: + # print eventAdapter.getEventWasUsed(), eventName, sourceName + return + used = eventAdapter.getEventWasUsed() + if used: eventText = eventName + ' : ' + sourceName Index: model.py =================================================================== RCS file: /cvsroot/pythoncard/PythonCard/model.py,v retrieving revision 1.160 retrieving revision 1.161 diff -C2 -d -r1.160 -r1.161 *** model.py 27 Apr 2004 06:07:48 -0000 1.160 --- model.py 29 Apr 2004 23:59:23 -0000 1.161 *************** *** 378,381 **** --- 378,383 ---- self._handlers = {} self._parseHandlers() + if False: + print "Scriptable init", self._handlers.keys() def _parseHandlers(self): *************** *** 506,510 **** ! class Background( event.Changeable, Scriptable, wx.Frame, event.EventSource): """ A window that contains Widgets. --- 508,513 ---- ! ##class Background( event.Changeable, Scriptable, wx.Frame, event.EventSource): ! class Background(Scriptable, wx.Frame, event.EventSource): """ A window that contains Widgets. *************** *** 515,519 **** Initialize this instance. """ ! event.Changeable.__init__( self ) Scriptable.__init__(self, aStack) event.EventSource.__init__(self) --- 518,522 ---- Initialize this instance. """ ! ## event.Changeable.__init__( self ) Scriptable.__init__(self, aStack) event.EventSource.__init__(self) *************** *** 527,531 **** self.menuBar = None self.statusBar = None ! self.dispatch = event.EventDispatch(self, self) self._exiting = False --- 530,534 ---- self.menuBar = None self.statusBar = None ! ## self.dispatch = event.EventDispatch(self, self) self._exiting = False *************** *** 549,565 **** style | wx.NO_FULL_REPAINT_ON_RESIZE, aBgRsrc.name) - - # RDS 2004-04-14 - # Post the Background initialization event. - - self.EVT_OPEN_BACKGROUND_TYPE = wx.NewEventType() - self.id = wx.NewId() - self.Connect( self.GetId(), -1, - self.EVT_OPEN_BACKGROUND_TYPE, - self._dispatchOpenBackground ) - evt = wx.PyCommandEvent( self.EVT_OPEN_BACKGROUND_TYPE, self.GetId() ) - wx.PostEvent( self, evt ) - EVT_LATENT_BACKGROUNDBIND(self, self.OnLatentBackgroundBind) - wx.PostEvent(self, wxLatentBackgroundBindEvent()) self._initLayout(aBgRsrc.components) --- 552,555 ---- *************** *** 583,588 **** wx.EVT_MENU_HIGHLIGHT_ALL(self, self.menuHighlight) - self._bindWindowEvents() - if aParent is None: self.stack.app.SetTopWindow(self) --- 573,576 ---- *************** *** 593,606 **** self.Show(True) ! def _dispatchOpenBackground( self, evt ) : ! # KEA 2002-06-10 ! # don't need this dispatch since dispatch is already ! # bound in the background ! ##self.event.eventOccurred( event.InitializationEvent( self.scriptable ) ) ! self.dispatch.eventOccurred( event.InitializationEvent( self ) ) ! def OnLatentBackgroundBind(self, evt): ! self.wxRegistry = {event.IdleEvent:(wx.EVT_IDLE, wx.wxEVT_IDLE), event.MoveEvent:(wx.EVT_MOVE, wx.wxEVT_MOVE), event.SizeEvent:(wx.EVT_SIZE, wx.wxEVT_SIZE), --- 581,655 ---- self.Show(True) + # RDS 2004-04-14 + # Post the Background initialization event. ! self.EVT_OPEN_BACKGROUND_TYPE = wx.NewEventType() ! self.id = wx.NewId() ! self.Connect(self.GetId(), -1, ! self.EVT_OPEN_BACKGROUND_TYPE, ! self.on_initialize) ! #self._dispatchOpenBackground ) ! evt = wx.PyCommandEvent(self.EVT_OPEN_BACKGROUND_TYPE, self.GetId()) ! evt.target = self ! wx.PostEvent(self, evt) ! EVT_LATENT_BACKGROUNDBIND(self, self.OnLatentBackgroundBind) ! wx.PostEvent(self, wxLatentBackgroundBindEvent()) ! # for some reason the Message Watcher isn't a listener yet ! # so calling eventOccurred2 doesn't do anything ! #print event.EventQueue()._impl._listeners ! #event.EventQueue()._impl.eventOccurred2('initialize', self.name) ! ! self._bindWindowEvents() ! ! ! def on_initialize(self, evt): ! # override in subclass ! pass ! ! def on_close(self, evt): ! # override in subclass ! evt.Skip() ! ! def singleItemExpandingSizerLayout(self): ! """Convenience method for backgrounds with only a ! single component on the background where the component ! should expand with the background as in an editor. ! Call from within the on_initialize event handler.""" ! ! self.sizer = wx.BoxSizer(wx.VERTICAL) ! name = self.components.order[0] ! self.sizer.Add(self.components[name], True, wx.EXPAND) ! self.sizer.Fit(self) ! self.sizer.SetSizeHints(self) ! self.panel.SetSizer(self.sizer) ! self.panel.Layout() ! ! ## def _dispatchOpenBackground( self, evt ) : ! ## # KEA 2002-06-10 ! ## # don't need this dispatch since dispatch is already ! ## # bound in the background ! ## ##self.event.eventOccurred( event.InitializationEvent( self.scriptable ) ) ! ## self.dispatch.eventOccurred( event.InitializationEvent( self ) ) ! ! ! # KEA 2004-04-28 ! # experimental alternative implementation of ! # OnLatentBackgroundBind and _dispatch ! ! def OnLatentBackgroundBind(self, evt): ! if self.stack.app.mw: ! bindUnusedEvents = True ! else: ! bindUnusedEvents = False ! ! self.eventIdToHandler = {} ! ! # this is actually slightly evil because dictionary keys ! # are supposed to be immutable, but you can change classes ! # and the same class imported into a different namespace ! # would be different, so for now I just made this a local variable ! # which is probably okay compared to keeping a reference around in self ! wxRegistry = {event.IdleEvent:(wx.EVT_IDLE, wx.wxEVT_IDLE), event.MoveEvent:(wx.EVT_MOVE, wx.wxEVT_MOVE), event.SizeEvent:(wx.EVT_SIZE, wx.wxEVT_SIZE), *************** *** 609,624 **** event.ActivateEvent:(wx.EVT_ACTIVATE, wx.wxEVT_ACTIVATE), event.CloseEvent:(wx.EVT_CLOSE, wx.wxEVT_CLOSE_WINDOW)} - # can't have ActivatEvent or CloseEvent - # since during a close the event listeners are destroyed - #event.ActivateEvent:(wx.EVT_ACTIVATE, wx.wxEVT_ACTIVATE), self.wxEventIdMap = {} ! for key in self.wxRegistry: ! value = self.wxRegistry[key] self.wxEventIdMap[value[1]] = key ! for eventClass in self.wxRegistry: ! wxFunction = self.wxRegistry[eventClass][0] ! wxFunction(self, self._dispatch) def _dispatch(self, aWxEvent): --- 658,727 ---- event.ActivateEvent:(wx.EVT_ACTIVATE, wx.wxEVT_ACTIVATE), event.CloseEvent:(wx.EVT_CLOSE, wx.wxEVT_CLOSE_WINDOW)} self.wxEventIdMap = {} ! for key in wxRegistry: ! value = wxRegistry[key] self.wxEventIdMap[value[1]] = key ! # helper variable to simplify test for whether to bind virtual events ! boundEvents = [] ! ! # once we aren't using a registry this will be a bit easier to ! # decipher compared to having to index into wxRegistry ! for eventClass in wxRegistry: ! handler = self.findHandler('on_' + eventClass.name) ! if handler or bindUnusedEvents: ! # only bind events that have an event handler ! # in this scenario unused events are never bound ! # which is more efficient, but the Message Watcher needs ! # to be changed ! # alternatively we can bind everything and then in _dispatch ! # if there isn't a match in eventIdToHandler then we know ! # the event isn't used and we can set used to False ! # the complication would be that we probably have to have to ! # always call Skip() which may or may not be a hassle with components ! self.Bind(wxRegistry[eventClass][0], self._dispatch) ! boundEvents.append(eventClass) ! if handler: ! if 0: ! print "binding", eventClass.name, handler._name, wxRegistry[eventClass][1] ! self.eventIdToHandler[wxRegistry[eventClass][1]] = handler ! # deactivate is a special case ! # as far as wxPython is concerned it is an activate event ! # so if we've already bound that to _dispatch we don't want ! # to bind it twice ! # if we have an on_deactivate event handler though we need to record ! # that separately for dispatch in eventIdToHandler ! # we'll have the same issue with other "virtual" events like mouseDrag ! handler = self.findHandler('on_' + event.DeactivateEvent.name) ! if handler or bindUnusedEvents: ! if not event.ActivateEvent in boundEvents: ! self.Bind(wxRegistry[event.ActivateEvent][0], self._dispatch) ! if handler: ! # there is no such thing as a deactivate event id, so just use the name ! self.eventIdToHandler[event.DeactivateEvent.name] = handler ! handler = self.findHandler('on_' + event.RestoreEvent.name) ! # now do the same kind of thing for restore ! if handler or bindUnusedEvents: ! if not event.MinimizeEvent in boundEvents: ! self.Bind(wxRegistry[event.MinimizeEvent][0], self._dispatch) ! if handler: ! self.eventIdToHandler[event.RestoreEvent.name] = handler ! ! if 0: ! print "\nboundEvents:" ! for evt in boundEvents: ! print " ", evt.name ! print "\n\n" ! print "\nself.eventIdToHandler:" ! for id in self.eventIdToHandler: ! print " ", id, self.eventIdToHandler[id]._function ! print "\n\n" ! ! # is this cleanup necessary ! # it would be a pain to have to ! # do this everywhere ! handler = None ! boundEvents = None def _dispatch(self, aWxEvent): *************** *** 630,633 **** --- 733,737 ---- except: pass + eventName = None if eventType == wx.wxEVT_MOVE: aWxEvent.position = tuple(aWxEvent.GetPosition()) *************** *** 635,687 **** aWxEvent.size = tuple(aWxEvent.GetSize()) elif eventType == wx.wxEVT_ICONIZE: ! aWxEvent.minimized = aWxEvent.Iconized() elif eventType == wx.wxEVT_MAXIMIZE: aWxEvent.maximized = aWxEvent.target.IsMaximized() ! ! evt = None ! #if aWxEvent in [wx.wxEVT_IDLE]: ! if eventType in self.wxEventIdMap: ! evt = self.wxEventIdMap[eventType](self) ! if evt.__class__ is event.ActivateEvent and not aWxEvent.GetActive(): ! evt = event.DeactivateEvent(self) ! evt._nativeEvent = aWxEvent ! # KEA 2004-04-24 ! # need to verify that this logic always works and doesn't do ! # the wrong thing for child windows and main windows with and without ! # an on_close handler ! if evt is not None: ! if self._exiting: ! # Don't display messages when quitting the app ! # the Message Watcher may no longer exist ! # and will cause Python to crash. ! try: ! event.EventQueue().removeListener(self.stack.app.mw) ! except: ! # already removed Message Watcher or it is not in use ! pass ! return ! self._notifyEventListeners(evt) ! if not evt.getUsed(): ! aWxEvent.Skip() ! ! # KEA 2004-04-26 ! # attempt to remove circular references ! # to cleanup background event memory leaks ! evt._nativeEvent.target = evt._nativeEvent.eventObject = None ! evt._nativeEvent = None ! evt._source = evt.target = None if 0: ! print evt ! evt = None ! #print " ", str(self.GetParent()).split(';')[0] ! #print " ", evt.getUsed(), str(aWxEvent.GetSkipped()).split(';')[0] ! #print " ", str(aWxEvent).split(';')[0], str(aWxEvent.GetEventObject()).split(';')[0] ! # KEA 2002-07-01 ! # If we have a close event and the user code called ! # Skip() then we really are closing if this is the main app window. if eventType == wx.wxEVT_CLOSE_WINDOW and aWxEvent.GetSkipped() and self.GetParent() is None: self._exiting = True --- 739,790 ---- aWxEvent.size = tuple(aWxEvent.GetSize()) elif eventType == wx.wxEVT_ICONIZE: ! #aWxEvent.minimized = aWxEvent.Iconized() ! minimized = aWxEvent.Iconized() ! if not minimized: ! eventType = event.RestoreEvent.name ! eventName = event.RestoreEvent.name elif eventType == wx.wxEVT_MAXIMIZE: aWxEvent.maximized = aWxEvent.target.IsMaximized() ! elif eventType == wx.wxEVT_ACTIVATE and not aWxEvent.GetActive(): ! eventType = event.DeactivateEvent.name ! eventName = event.DeactivateEvent.name ! if not eventName: ! eventName = self.wxEventIdMap[eventType].name ! if self._exiting: ! # Don't display messages when quitting the app ! # the Message Watcher may no longer exist ! # and will cause Python to crash. ! try: ! event.EventQueue().removeListener(self.stack.app.mw) ! except: ! # already removed Message Watcher or it is not in use ! pass ! ! # it shouldn't be possible to be in _dispatch for an event ! # that wasn't bound above, but just in case... ! handler = self.eventIdToHandler.get(eventType, None) ! if handler: ! event.EventQueue()._impl.eventOccurred2(eventName, self.name, True) if 0: ! print "dispatching", handler._name ! # make a lowercase alias ! aWxEvent.skip = aWxEvent.Skip ! # this is what is in event.py ! # aHandler.getFunction()( aOwner, self.getSource(), self ) ! handler.getFunction()(self, aWxEvent) ! # do we have to clean up this alias? ! aWxEvent.skip = None ! # how about this local reference to handler? ! handler = None ! # this check is done here because there is always an on_close handler defined ! # in the Background class if eventType == wx.wxEVT_CLOSE_WINDOW and aWxEvent.GetSkipped() and self.GetParent() is None: self._exiting = True + else: + event.EventQueue()._impl.eventOccurred2(eventName, self.name, False) + # hopefully this is all we need to do for "unused events" + aWxEvent.Skip() Index: event.py =================================================================== RCS file: /cvsroot/pythoncard/PythonCard/event.py,v retrieving revision 1.55 retrieving revision 1.56 diff -C2 -d -r1.55 -r1.56 *** event.py 27 Apr 2004 17:22:28 -0000 1.55 --- event.py 29 Apr 2004 23:59:23 -0000 1.56 *************** *** 374,377 **** --- 374,380 ---- name = 'minimize' + class RestoreEvent(Event): + name = 'restore' + class MaximizeEvent(Event): name = 'maximize' *************** *** 680,683 **** --- 683,689 ---- self._notifyEventListeners( aEvent ) + def eventOccurred2(self, eventName, sourceName, used): + self._notifyEventListeners((eventName, sourceName, used)) + def __init__( self ) : if EventQueue._impl is None : |