[Ocemp-CVS] ocempgui/ocempgui/widgets Renderer.py, 1.61.2.15, 1.61.2.16 Style.py, 1.66.2.6, 1.66.2.
Status: Beta
Brought to you by:
marcusva
From: Marcus v. A. <mar...@us...> - 2006-11-20 15:23:14
|
Update of /cvsroot/ocemp/ocempgui/ocempgui/widgets In directory sc8-pr-cvs3.sourceforge.net:/tmp/cvs-serv20202/ocempgui/widgets Modified Files: Tag: rel_0_2 Renderer.py Style.py Log Message: Merged from HEAD: Improved docs. Added event based main loop to Renderer. Index: Style.py =================================================================== RCS file: /cvsroot/ocemp/ocempgui/ocempgui/widgets/Style.py,v retrieving revision 1.66.2.6 retrieving revision 1.66.2.7 diff -u -d -r1.66.2.6 -r1.66.2.7 --- Style.py 12 Sep 2006 19:59:55 -0000 1.66.2.6 +++ Style.py 20 Nov 2006 15:22:59 -0000 1.66.2.7 @@ -39,6 +39,25 @@ """WidgetStyle (dict=None) -> WidgetStyle A style dictionary that tracks changes of its items. + + The WidgetStyle dictionary class allows one to let a bound method be + executed, whenever a value of the dictionary changed. Additionally, + the WidgetStyle class supports recursive changes, so that a + WidgetStyle object within this WidgetStyle can escalate the value + change and so on. + + To set up the value change handler you can bind it using the + set_value_changed() method of the WidgetStyle class: + + style.set_value_changed (callback_method) + + This will cause it and all values of it, which are WidgetStyle + objects to invoke the callback_method on changes. + + To get the actually set value change handler, the + get_value_changed() method can be used: + + callback = style.get_value_changed () """ def __init__ (self, dict=None): # Notifier slot. Index: Renderer.py =================================================================== RCS file: /cvsroot/ocemp/ocempgui/ocempgui/widgets/Renderer.py,v retrieving revision 1.61.2.15 retrieving revision 1.61.2.16 diff -u -d -r1.61.2.15 -r1.61.2.16 --- Renderer.py 15 Nov 2006 19:38:28 -0000 1.61.2.15 +++ Renderer.py 20 Nov 2006 15:22:59 -0000 1.61.2.16 @@ -137,7 +137,7 @@ doc = "The layer id, the event manager operates on.") class Renderer (IIndexable): - """Renderer (title, width=1, height=1) -> Renderer + """Renderer () -> Renderer A render engine, which can deal with events and sprites. @@ -177,6 +177,27 @@ # window of 800x600 size. renderer.create_screen (800, 600) + When using only a part of the screen it is important to adjust the + Renderer's position, too, so that events, which require positional + arguments (such as mouse movements, etc), can be translated + correctly. This means, that when the Renderer's screen is blit a + certain offset (x, y), its topleft position should be set to (x, y) + as well: + + mainsurface.blit (renderer.screen, (10, 10)) + renderer.topleft = 10, 10 + + As the Renderer exposes the attributes of its bound 'rect' attribute + you can use the following attributes directly to modify its position: + + top, left, bottom, right, + topleft, bottomleft, topright, bottomright, + midtop, midleft, midbottom, midright, + center, centerx, centery, + size, width, height + + This however will NOT move the bound screen of the Renderer around. + If the create_creen() method is used, resizing events will be recognized and resize the display accordingly. The 'support_resize' attribute and set_support_resize() method can influence this @@ -202,15 +223,35 @@ renderer.set_color (100, 220, 100) The Renderer supports an update timer value (~ FPS setting), which - defaults to 40. That means, that the timer will cause the event - system to poll events 40 times a second, which is a good value for - most cases. On demand it can be adjusted using the 'timer' attribute - or set_timer() method. Be careful with it. Higher values will cause - higher CPU load. + defaults to 40. That means, that the timer will cause the default + event system to poll events 40 times a second, which is a good value + for most cases. On demand it can be adjusted using the 'timer' + attribute or set_timer() method. Be careful with it. Higher values + will cause higher CPU load. renderer.timer = 20 renderer.set_timer (100) + It also supports different polling modes for events. The first + polling mode relies on the timer value while the second uses an + event based polling system. This means, that the second mode will + completely ignore the timer value and instead wait for events to + occur on the event queue. While the first mode is suitable for most + FPS based applications and games, the latter one suits perfectly for + event based ones. + + Note however, that the events to occur _MUST_ occur on the pygame + event queue, not on those of the different EventManagers! + + The mode can be chosen by passing the Renderer.start() method an + optional boolean argument, that determins, which mode should be + used. True indicates the event based loop, False (the default) + indicates the timer based loop. + + Renderer.start () # Use the timer based polling. + Renderer.start (False) # Use the timer based polling. + Renderer.start (True) # Use the event based polling. + Keyboard navigation ------------------- The Renderer class implements keyboard navigation through the @@ -336,8 +377,7 @@ Renderer.x = 10 # Only x offset. Renderer.y = 10 # Only y offset. - This is necessary to let the Renderer correctly translate mouse - positions to its + See above for the necessity of it. Then you can send the events processed in your event loop to the Renderer and its objects via the distribute_events() method: @@ -919,12 +959,23 @@ if self.screen: display.flip () - def start (self): - """R.start () -> None + def start (self, wait=False): + """R.start (...) -> None Starts the main loop of the Renderer. + + Start the main loop of the Renderer. Currently two different + modes are supported: Timer based event polling and + distribution. This does not care about whether there are events + or not, but suspends the loop for the set timer value on each + run (known as FPS scaling). Event based polling and + distribution. This loop will only continue, if an event occurs + on the queue and wait otherwise. """ - self._loop () + if wait: + self._synced_loop () + else: + self._loop () def switch_index (self): """R.switch_index () -> None @@ -1239,11 +1290,12 @@ def _loop (self): """R._loop () -> None - The main event loop of the Renderer. + A main event loop, which uses a timer based polling. - Main event loop of the renderer. This loop hooks up on the - event loop of pygame and distributes all its event to the attached - objects. + Main event loop of the Renderer. This loop hooks up on the event + loop of pygame and distributes all its events to the attached + objects. It uses a timer based polling mechanism instead of + waiting for events. """ # Emit the tick event every 10 ms. PygameTime.set_timer (SIG_TICK, 10) @@ -1257,12 +1309,35 @@ events = event_get () if not self.distribute_events (*events): - return # QUIT event + return # QUIT event if self.timer > 0: delay (1000 / self.timer) if self.__layerinfo: self._show_layer_info () - + + def _synced_loop (self): + """R._synced_loop () -> None + + A main event loop, which uses an event based polling. + + Main event loop of the Renderer. This loop hooks up on the event + loop of pygame and distributes all its events to the attached + objects. It waits for an event to occur on the queues before it + does further processing. It ignores the Renderer.timer setting. + """ + # Emit the tick event every 10 ms. + PygameTime.set_timer (SIG_TICK, 10) + event_wait = event.wait + pump = event.pump + + while True: + pump () + # Get an event and distribute it. + if not self.distribute_events (event_wait ()): + return # QUIT event + if self.__layerinfo: + self._show_layer_info () + title = property (lambda self: self._title, lambda self, var: self.set_title (var), doc = "The title of the pygame window.") |