Module albow.core.ui.AlbowEventLoop
Source code
from typing import List
import sys
import logging
from pygame.event import Event
from pygame.locals import MOUSEBUTTONDOWN
from pygame.locals import MOUSEBUTTONUP
from pygame.locals import MOUSEMOTION
from pygame.locals import K_ESCAPE
from pygame.locals import KMOD_CTRL
from pygame.locals import KMOD_SHIFT
from pygame.locals import KEYDOWN
from pygame.locals import KEYUP
from pygame.locals import USEREVENT
from pygame.locals import QUIT
from albow.core.Scheduler import Scheduler
from albow.core.CoreUtilities import CoreUtilities
from albow.core.ui.Widget import Widget
from albow.core.ui.RootWidget import RootWidget
from albow.core.ui.EventLoopParams import EventLoopParams
from albow.media.MusicUtilities import MusicUtilities
class AlbowEventLoop:
    MUSIC_END_EVENT = USEREVENT + 1
    """
    API consumer user events **MUST** start there events after this one
    """
    DOUBLE_CLICK_TIME = 300
    """
    Time is in milliseconds
    """
    def __init__(self, containingWidget: Widget, modalWidget: Widget):
        self.logger = logging.getLogger(__name__)
        self.modal_widget = modalWidget
        self.containingWidget = containingWidget
    def processEvents(self, eventList: List[Event], relativeMode: bool, deferDrawing: bool, eventLoopParams: EventLoopParams) -> EventLoopParams:
        self.logger.debug(f"Events to process: {len(eventList)}")
        use_sleep = eventLoopParams.use_sleep
        relative_pause = eventLoopParams.relative_pause
        do_draw = eventLoopParams.do_draw
        relative_warmup = eventLoopParams.relative_warmup
        last_click_time = eventLoopParams.last_click_time
        num_clicks = eventLoopParams.num_clicks
        for event in eventList:
            t = Scheduler.timestamp()
            event.dict['time'] = t
            event.dict['local'] = getattr(event, 'pos', (0, 0))
            eventType = event.type
            if eventType == QUIT:
                self.quit()
            elif eventType == MOUSEBUTTONDOWN:
                # print "RootWidget: MOUSEBUTTONDOWN: setting do_draw" ###
                do_draw = True
                if t - last_click_time <= AlbowEventLoop.DOUBLE_CLICK_TIME:
                    num_clicks += 1
                else:
                    num_clicks = 1
                last_click_time = t
                event.dict['num_clicks'] = num_clicks
                CoreUtilities.add_modifiers(event)
                RootWidget.last_mouse_event = event
                self.logger.debug(f"num_clicks: '{num_clicks}' -- t: '{t}' -- last_click_time: '{last_click_time}'")
                if relativeMode:
                    event.dict['local'] = (0, 0)
                    if relative_pause:
                        relative_pause = False
                    else:
                        #  modal_widget.dispatch_key('mouse_down', event)
                        mouse_widget = self.modal_widget.get_focus()
                        RootWidget.clicked_widget = mouse_widget
                        RootWidget.last_mouse_event_handler = mouse_widget
                        mouse_widget.handle_event('mouse_down', event)
                else:
                    mouse_widget = self.containingWidget.find_widget(event.pos)
                    if not mouse_widget.is_inside(self.modal_widget):
                        mouse_widget = self.modal_widget
                    RootWidget.clicked_widget = mouse_widget
                    RootWidget.last_mouse_event_handler = mouse_widget
                    mouse_widget.notify_attention_loss()
                    mouse_widget.handle_mouse('mouse_down', event)
            elif eventType == MOUSEMOTION:
                CoreUtilities.add_modifiers(event)
                RootWidget.last_mouse_event = event
                if relativeMode:
                    event.dict['local'] = (0, 0)
                    if not relative_pause:
                        if relative_warmup:
                            relative_warmup -= 1
                        else:
                            #  modal_widget.dispatch_key('mouse_delta', event)
                            mouse_widget = RootWidget.clicked_widget or self.modal_widget.get_focus()
                            RootWidget.last_mouse_event_handler = mouse_widget
                            mouse_widget.handle_event('mouse_delta', event)
                else:
                    mouse_widget = self.containingWidget.find_widget(event.pos)  # Do this in else branch?
                    if RootWidget.clicked_widget:
                        RootWidget.last_mouse_event_handler = mouse_widget  # Should this be clicked_widget?
                        RootWidget.clicked_widget.handle_mouse('mouse_drag', event)
                    else:
                        if not mouse_widget.is_inside(self.modal_widget):
                            mouse_widget = self.modal_widget
                        RootWidget.last_mouse_event_handler = mouse_widget
                        mouse_widget.handle_mouse('mouse_move', event)
            elif eventType == MOUSEBUTTONUP:
                CoreUtilities.add_modifiers(event)
                RootWidget.last_mouse_event = event
                do_draw = True
                if relativeMode:
                    event.dict['local'] = (0, 0)
                    if not relative_pause:
                        if RootWidget.clicked_widget:
                            mouse_widget = RootWidget.clicked_widget
                            RootWidget.clicked_widget = None
                        else:
                            mouse_widget = self.modal_widget.get_focus()
                        RootWidget.last_mouse_event_handler = mouse_widget
                        mouse_widget.handle_event('mouse_up', event)
                else:
                    if RootWidget.clicked_widget:
                        RootWidget.last_mouse_event_handler = RootWidget.clicked_widget
                        RootWidget.clicked_widget = None
                        RootWidget.last_mouse_event_handler.handle_mouse('mouse_up', event)
            elif eventType == KEYDOWN:
                key = event.key
                if key == K_ESCAPE and relativeMode and event.mod & KMOD_CTRL and event.mod & KMOD_SHIFT:
                    relative_pause = True
                elif relative_pause:
                    relative_pause = False
                else:
                    CoreUtilities.set_modifier(key, True)
                    do_draw = True
                    self.send_key(self.modal_widget, 'key_down', event)
                    if RootWidget.last_mouse_event_handler:
                        event.dict['pos'] = RootWidget.last_mouse_event.pos
                        event.dict['local'] = RootWidget.last_mouse_event.local
                        RootWidget.last_mouse_event_handler.setup_cursor(event)
            elif eventType == KEYUP:
                key = event.key
                CoreUtilities.set_modifier(key, False)
                do_draw = True
                self.send_key(self.modal_widget, 'key_up', event)
                if RootWidget.last_mouse_event_handler:
                    event.dict['pos'] = RootWidget.last_mouse_event.pos
                    event.dict['local'] = RootWidget.last_mouse_event.local
                    RootWidget.last_mouse_event_handler.setup_cursor(event)
            elif eventType == AlbowEventLoop.MUSIC_END_EVENT:
                self.music_end()
            elif eventType == USEREVENT:
                if deferDrawing and not use_sleep:
                    RootWidget.ourTimerEvent = event
            else:
                #
                # Maybe someone has registered some user events handler
                #
                userEventCallList = RootWidget.getUserEventList()
                for cb in userEventCallList:
                    if cb.userEvent == eventType:
                        self.logger.debug(f"API User eventType: {eventType}")
                        cb.func(event)
        retEventLoopParams: EventLoopParams = EventLoopParams(use_sleep=use_sleep,
                                                              relative_pause=relative_pause,
                                                              do_draw=do_draw,
                                                              relative_warmup=relative_warmup,
                                                              last_click_time=last_click_time,
                                                              num_clicks=num_clicks)
        return retEventLoopParams
    def send_key(self, theWidget: Widget, theName: str, theEvent: Event):
        CoreUtilities.add_modifiers(theEvent)
        theWidget.dispatch_key(theName, theEvent)
    def music_end(self):
        MusicUtilities.music_end()
    def quit(self):
        #
        # call quit handler
        sys.exit()Classes
- class AlbowEventLoop (containingWidget, modalWidget)
- 
Source codeclass AlbowEventLoop: MUSIC_END_EVENT = USEREVENT + 1 """ API consumer user events **MUST** start there events after this one """ DOUBLE_CLICK_TIME = 300 """ Time is in milliseconds """ def __init__(self, containingWidget: Widget, modalWidget: Widget): self.logger = logging.getLogger(__name__) self.modal_widget = modalWidget self.containingWidget = containingWidget def processEvents(self, eventList: List[Event], relativeMode: bool, deferDrawing: bool, eventLoopParams: EventLoopParams) -> EventLoopParams: self.logger.debug(f"Events to process: {len(eventList)}") use_sleep = eventLoopParams.use_sleep relative_pause = eventLoopParams.relative_pause do_draw = eventLoopParams.do_draw relative_warmup = eventLoopParams.relative_warmup last_click_time = eventLoopParams.last_click_time num_clicks = eventLoopParams.num_clicks for event in eventList: t = Scheduler.timestamp() event.dict['time'] = t event.dict['local'] = getattr(event, 'pos', (0, 0)) eventType = event.type if eventType == QUIT: self.quit() elif eventType == MOUSEBUTTONDOWN: # print "RootWidget: MOUSEBUTTONDOWN: setting do_draw" ### do_draw = True if t - last_click_time <= AlbowEventLoop.DOUBLE_CLICK_TIME: num_clicks += 1 else: num_clicks = 1 last_click_time = t event.dict['num_clicks'] = num_clicks CoreUtilities.add_modifiers(event) RootWidget.last_mouse_event = event self.logger.debug(f"num_clicks: '{num_clicks}' -- t: '{t}' -- last_click_time: '{last_click_time}'") if relativeMode: event.dict['local'] = (0, 0) if relative_pause: relative_pause = False else: # modal_widget.dispatch_key('mouse_down', event) mouse_widget = self.modal_widget.get_focus() RootWidget.clicked_widget = mouse_widget RootWidget.last_mouse_event_handler = mouse_widget mouse_widget.handle_event('mouse_down', event) else: mouse_widget = self.containingWidget.find_widget(event.pos) if not mouse_widget.is_inside(self.modal_widget): mouse_widget = self.modal_widget RootWidget.clicked_widget = mouse_widget RootWidget.last_mouse_event_handler = mouse_widget mouse_widget.notify_attention_loss() mouse_widget.handle_mouse('mouse_down', event) elif eventType == MOUSEMOTION: CoreUtilities.add_modifiers(event) RootWidget.last_mouse_event = event if relativeMode: event.dict['local'] = (0, 0) if not relative_pause: if relative_warmup: relative_warmup -= 1 else: # modal_widget.dispatch_key('mouse_delta', event) mouse_widget = RootWidget.clicked_widget or self.modal_widget.get_focus() RootWidget.last_mouse_event_handler = mouse_widget mouse_widget.handle_event('mouse_delta', event) else: mouse_widget = self.containingWidget.find_widget(event.pos) # Do this in else branch? if RootWidget.clicked_widget: RootWidget.last_mouse_event_handler = mouse_widget # Should this be clicked_widget? RootWidget.clicked_widget.handle_mouse('mouse_drag', event) else: if not mouse_widget.is_inside(self.modal_widget): mouse_widget = self.modal_widget RootWidget.last_mouse_event_handler = mouse_widget mouse_widget.handle_mouse('mouse_move', event) elif eventType == MOUSEBUTTONUP: CoreUtilities.add_modifiers(event) RootWidget.last_mouse_event = event do_draw = True if relativeMode: event.dict['local'] = (0, 0) if not relative_pause: if RootWidget.clicked_widget: mouse_widget = RootWidget.clicked_widget RootWidget.clicked_widget = None else: mouse_widget = self.modal_widget.get_focus() RootWidget.last_mouse_event_handler = mouse_widget mouse_widget.handle_event('mouse_up', event) else: if RootWidget.clicked_widget: RootWidget.last_mouse_event_handler = RootWidget.clicked_widget RootWidget.clicked_widget = None RootWidget.last_mouse_event_handler.handle_mouse('mouse_up', event) elif eventType == KEYDOWN: key = event.key if key == K_ESCAPE and relativeMode and event.mod & KMOD_CTRL and event.mod & KMOD_SHIFT: relative_pause = True elif relative_pause: relative_pause = False else: CoreUtilities.set_modifier(key, True) do_draw = True self.send_key(self.modal_widget, 'key_down', event) if RootWidget.last_mouse_event_handler: event.dict['pos'] = RootWidget.last_mouse_event.pos event.dict['local'] = RootWidget.last_mouse_event.local RootWidget.last_mouse_event_handler.setup_cursor(event) elif eventType == KEYUP: key = event.key CoreUtilities.set_modifier(key, False) do_draw = True self.send_key(self.modal_widget, 'key_up', event) if RootWidget.last_mouse_event_handler: event.dict['pos'] = RootWidget.last_mouse_event.pos event.dict['local'] = RootWidget.last_mouse_event.local RootWidget.last_mouse_event_handler.setup_cursor(event) elif eventType == AlbowEventLoop.MUSIC_END_EVENT: self.music_end() elif eventType == USEREVENT: if deferDrawing and not use_sleep: RootWidget.ourTimerEvent = event else: # # Maybe someone has registered some user events handler # userEventCallList = RootWidget.getUserEventList() for cb in userEventCallList: if cb.userEvent == eventType: self.logger.debug(f"API User eventType: {eventType}") cb.func(event) retEventLoopParams: EventLoopParams = EventLoopParams(use_sleep=use_sleep, relative_pause=relative_pause, do_draw=do_draw, relative_warmup=relative_warmup, last_click_time=last_click_time, num_clicks=num_clicks) return retEventLoopParams def send_key(self, theWidget: Widget, theName: str, theEvent: Event): CoreUtilities.add_modifiers(theEvent) theWidget.dispatch_key(theName, theEvent) def music_end(self): MusicUtilities.music_end() def quit(self): # # call quit handler sys.exit()Class variables- var DOUBLE_CLICK_TIME
- 
Time is in milliseconds 
- var MUSIC_END_EVENT
- 
API consumer user events MUST start there events after this one 
 Methods- def music_end(self)
- 
Source codedef music_end(self): MusicUtilities.music_end()
- def processEvents(self, eventList, relativeMode, deferDrawing, eventLoopParams)
- 
Source codedef processEvents(self, eventList: List[Event], relativeMode: bool, deferDrawing: bool, eventLoopParams: EventLoopParams) -> EventLoopParams: self.logger.debug(f"Events to process: {len(eventList)}") use_sleep = eventLoopParams.use_sleep relative_pause = eventLoopParams.relative_pause do_draw = eventLoopParams.do_draw relative_warmup = eventLoopParams.relative_warmup last_click_time = eventLoopParams.last_click_time num_clicks = eventLoopParams.num_clicks for event in eventList: t = Scheduler.timestamp() event.dict['time'] = t event.dict['local'] = getattr(event, 'pos', (0, 0)) eventType = event.type if eventType == QUIT: self.quit() elif eventType == MOUSEBUTTONDOWN: # print "RootWidget: MOUSEBUTTONDOWN: setting do_draw" ### do_draw = True if t - last_click_time <= AlbowEventLoop.DOUBLE_CLICK_TIME: num_clicks += 1 else: num_clicks = 1 last_click_time = t event.dict['num_clicks'] = num_clicks CoreUtilities.add_modifiers(event) RootWidget.last_mouse_event = event self.logger.debug(f"num_clicks: '{num_clicks}' -- t: '{t}' -- last_click_time: '{last_click_time}'") if relativeMode: event.dict['local'] = (0, 0) if relative_pause: relative_pause = False else: # modal_widget.dispatch_key('mouse_down', event) mouse_widget = self.modal_widget.get_focus() RootWidget.clicked_widget = mouse_widget RootWidget.last_mouse_event_handler = mouse_widget mouse_widget.handle_event('mouse_down', event) else: mouse_widget = self.containingWidget.find_widget(event.pos) if not mouse_widget.is_inside(self.modal_widget): mouse_widget = self.modal_widget RootWidget.clicked_widget = mouse_widget RootWidget.last_mouse_event_handler = mouse_widget mouse_widget.notify_attention_loss() mouse_widget.handle_mouse('mouse_down', event) elif eventType == MOUSEMOTION: CoreUtilities.add_modifiers(event) RootWidget.last_mouse_event = event if relativeMode: event.dict['local'] = (0, 0) if not relative_pause: if relative_warmup: relative_warmup -= 1 else: # modal_widget.dispatch_key('mouse_delta', event) mouse_widget = RootWidget.clicked_widget or self.modal_widget.get_focus() RootWidget.last_mouse_event_handler = mouse_widget mouse_widget.handle_event('mouse_delta', event) else: mouse_widget = self.containingWidget.find_widget(event.pos) # Do this in else branch? if RootWidget.clicked_widget: RootWidget.last_mouse_event_handler = mouse_widget # Should this be clicked_widget? RootWidget.clicked_widget.handle_mouse('mouse_drag', event) else: if not mouse_widget.is_inside(self.modal_widget): mouse_widget = self.modal_widget RootWidget.last_mouse_event_handler = mouse_widget mouse_widget.handle_mouse('mouse_move', event) elif eventType == MOUSEBUTTONUP: CoreUtilities.add_modifiers(event) RootWidget.last_mouse_event = event do_draw = True if relativeMode: event.dict['local'] = (0, 0) if not relative_pause: if RootWidget.clicked_widget: mouse_widget = RootWidget.clicked_widget RootWidget.clicked_widget = None else: mouse_widget = self.modal_widget.get_focus() RootWidget.last_mouse_event_handler = mouse_widget mouse_widget.handle_event('mouse_up', event) else: if RootWidget.clicked_widget: RootWidget.last_mouse_event_handler = RootWidget.clicked_widget RootWidget.clicked_widget = None RootWidget.last_mouse_event_handler.handle_mouse('mouse_up', event) elif eventType == KEYDOWN: key = event.key if key == K_ESCAPE and relativeMode and event.mod & KMOD_CTRL and event.mod & KMOD_SHIFT: relative_pause = True elif relative_pause: relative_pause = False else: CoreUtilities.set_modifier(key, True) do_draw = True self.send_key(self.modal_widget, 'key_down', event) if RootWidget.last_mouse_event_handler: event.dict['pos'] = RootWidget.last_mouse_event.pos event.dict['local'] = RootWidget.last_mouse_event.local RootWidget.last_mouse_event_handler.setup_cursor(event) elif eventType == KEYUP: key = event.key CoreUtilities.set_modifier(key, False) do_draw = True self.send_key(self.modal_widget, 'key_up', event) if RootWidget.last_mouse_event_handler: event.dict['pos'] = RootWidget.last_mouse_event.pos event.dict['local'] = RootWidget.last_mouse_event.local RootWidget.last_mouse_event_handler.setup_cursor(event) elif eventType == AlbowEventLoop.MUSIC_END_EVENT: self.music_end() elif eventType == USEREVENT: if deferDrawing and not use_sleep: RootWidget.ourTimerEvent = event else: # # Maybe someone has registered some user events handler # userEventCallList = RootWidget.getUserEventList() for cb in userEventCallList: if cb.userEvent == eventType: self.logger.debug(f"API User eventType: {eventType}") cb.func(event) retEventLoopParams: EventLoopParams = EventLoopParams(use_sleep=use_sleep, relative_pause=relative_pause, do_draw=do_draw, relative_warmup=relative_warmup, last_click_time=last_click_time, num_clicks=num_clicks) return retEventLoopParams
- def quit(self)
- 
Source codedef quit(self): # # call quit handler sys.exit()
- def send_key(self, theWidget, theName, theEvent)
- 
Source codedef send_key(self, theWidget: Widget, theName: str, theEvent: Event): CoreUtilities.add_modifiers(theEvent) theWidget.dispatch_key(theName, theEvent)