class Canvas(Surface, MouseWheelHandler): def __init__(self, size, buffered): Surface.__init__(self, size) MouseWheelHandler.__init__(self, True) if isinstance(buffered, bool): self._bufferedimage = buffered else: self._bufferedimage = True try: if self.impl.canvasContext: self._isCanvas = True except: self._isCanvas = False self._bufferedimage = False if self._bufferedimage: self.surface = Surface(size) else: self.surface = self self.images = {} self.image_list = [] self.callback = None self.time = Time() self.event = pyjsdl.event self.addMouseListener(self) self.addMouseWheelListener(self) self.addKeyboardListener(self) self.sinkEvents(Event.ONMOUSEDOWN | Event.ONMOUSEUP| Event.ONMOUSEMOVE | Event.ONMOUSEOUT | Event.ONMOUSEWHEEL | Event.ONKEYDOWN | Event.ONKEYPRESS | Event.ONKEYUP) self.modKey = pyjsdl.event.modKey self.specialKey = pyjsdl.event.specialKey self._repaint = False self._rect_list = [] self._rect_len = 0 self._rect_num = 0 self._framerate = 0 self._frametime = 0 self._canvas_init() self.initialized = False def _canvas_init(self): global _canvas, _ctx, _img, _wnd _canvas = self _ctx = self.impl.canvasContext _img = self.surface.canvas _wnd = requestAnimationFrameInit() def onMouseMove(self, sender, x, y): event = DOM.eventGetCurrentEvent() event.pos = (x, y) self.event.mouseMove['x'], self.event.mouseMove['y'] = x, y self.event._updateQueue(event) def onMouseDown(self, sender, x, y): event = DOM.eventGetCurrentEvent() event.pos = (x, y) self.event.mousePress[event.button] = True self.event._updateQueue(event) def onMouseUp(self, sender, x, y): event = DOM.eventGetCurrentEvent() event.pos = (x, y) self.event.mousePress[event.button] = False self.event._updateQueue(event) def onMouseLeave(self, sender): self.event.mousePress[0], self.event.mousePress[1], self.event.mousePress[2] = False, False, False self.event.mouseMove['x'], self.event.mouseMove['y'] = -1, -1 self.event.mouseMoveRel['x'], self.event.mouseMoveRel['y'] = None, None for keycode in self.modKey: if self.event.keyPress[keycode]: self.event.keyPress[keycode] = False def onMouseWheel(self, sender, velocity): event = DOM.eventGetCurrentEvent() if event.type == 'mousewheel': #TODO: update for changes in mousewheel implementation if hasattr(event, 'wheelDeltaX'): self.onMouseWheel = self._onMouseWheel self._onMouseWheel(sender, velocity) else: self.onMouseWheel = self._onMouseWheelY DOM.eventGetMouseWheelVelocityY = eventGetMouseWheelVelocityY self._onMouseWheelY(sender, eventGetMouseWheelVelocityY(event)) else: #DOMMouseScroll self.onMouseWheel = self._onMouseScroll self._onMouseScroll(sender, velocity) def _onMouseWheel(self, sender, velocity): event = DOM.eventGetCurrentEvent() if not event.wheelDeltaX: if velocity < 0: button = 4 events = velocity / -3 else: button = 5 events = velocity / 3 else: if velocity < 0: button = 6 events = velocity / -3 else: button = 7 events = velocity / 3 event.btn = button event.pos = (self.event.mouseMove['x'], self.event.mouseMove['y']) for evt in range(events): self.event._updateQueue(event) def _onMouseWheelY(self, sender, velocity): event = DOM.eventGetCurrentEvent() if velocity < 0: button = 4 events = velocity / -3 else: button = 5 events = velocity / 3 event.btn = button event.pos = (self.event.mouseMove['x'], self.event.mouseMove['y']) for evt in range(events): self.event._updateQueue(event) def _onMouseScroll(self, sender, velocity): event = DOM.eventGetCurrentEvent() if velocity > 1 or velocity < -1: if velocity < 0: button = 4 else: button = 5 else: if velocity < 0: button = 6 else: button = 7 event.btn = button event.pos = (self.event.mouseMove['x'], self.event.mouseMove['y']) self.event._updateQueue(event) def onKeyDown(self, sender, keycode, modifiers): if keycode in self.modKey: event = DOM.eventGetCurrentEvent() self.event.keyPress[keycode] = True self.event._updateQueue(event) DOM.eventPreventDefault(event) elif keycode in self.specialKey: event = DOM.eventGetCurrentEvent() self.event._updateQueue(event) DOM.eventPreventDefault(event) def onKeyPress(self, sender, keycode, modifiers): event = DOM.eventGetCurrentEvent() if not (event.keyCode and event.keyCode in self.specialKey): self.event._updateQueue(event) DOM.eventPreventDefault(event) def onKeyUp(self, sender, keycode, modifiers): event = DOM.eventGetCurrentEvent() if keycode in self.modKey: self.event.keyPress[keycode] = False self.event._updateQueue(event) def resize(self, width, height): Surface.resize(self, width, height) if self._bufferedimage: self.surface.resize(width, height) self.surface._display._surface_rect = self.surface.get_rect() def set_callback(self, cb): if not hasattr(cb, 'run'): self.callback = Callback(cb) else: self.callback = cb def load_images(self, images): if images: image_list = [] for image in images: if isinstance(image, str): image_list.append(image) self.image_list.append(image) else: name = image[0] if isinstance(image[1], str): data = image[1] else: data = base64.b64encode(image[1].getvalue()) if not data.startswith('data:'): ext = name.strip().split('.')[-1] data = "data:%s;base64,%s" %(ext, data) #data:[<mediatype>][;base64],<data> image_list.append(data) self.image_list.append(name) loadImages(image_list, self) else: self.start() def onImagesLoaded(self, images): for i, image in enumerate(self.image_list): self.images[image] = images[i].getElement() self.start() def start(self): if not self.initialized: self.initialized = True _wnd.requestAnimationFrame(run) self.time.timeout(0, self) def stop(self): global run run = lambda ts: None self.run = lambda: None def _get_rect(self): if self._rect_num < self._rect_len: return self._rect_list[self._rect_num] else: self._rect_list.append(Rect(0,0,0,0)) self._rect_len += 1 return self._rect_list[self._rect_num] def run(self): if not self._repaint: self.callback.run() self._repaint = True self.time.timeout(0, self)
class Canvas(Surface, MouseWheelHandler): def __init__(self, size, buffered): Surface.__init__(self, size) MouseWheelHandler.__init__(self, True) if isinstance(buffered, bool): self._bufferedimage = buffered else: self._bufferedimage = True try: if self.impl.canvasContext: self._isCanvas = True except: self._isCanvas = False self._bufferedimage = False if self._bufferedimage: self.surface = Surface(size) else: self.surface = self self.images = {} self.image_list = [] self.callback = None self.time = Time() self.event = pyjsdl.event self.addMouseListener(self) self.addMouseWheelListener(self) self.addKeyboardListener(self) self.sinkEvents(Event.ONMOUSEDOWN | Event.ONMOUSEUP | Event.ONMOUSEMOVE | Event.ONMOUSEOUT | Event.ONMOUSEWHEEL | Event.ONKEYDOWN | Event.ONKEYPRESS | Event.ONKEYUP) self.modKey = pyjsdl.event.modKey self.specialKey = pyjsdl.event.specialKey self.event._initiate_touch_listener(self) self._touch_callback = self.event.touchlistener.callback self._repaint = False self._rect_list = [] self._rect_len = 0 self._rect_num = 0 self._framerate = 0 self._frametime = 0 self._canvas_init() self.initialized = False def _canvas_init(self): global _canvas, _ctx, _img, _wnd _canvas = self _ctx = self.impl.canvasContext _img = self.surface.canvas _wnd = requestAnimationFrameInit() def onMouseMove(self, sender, x, y): event = DOM.eventGetCurrentEvent() event.pos = (x, y) self.event.mouseMove['x'], self.event.mouseMove['y'] = x, y self.event._updateQueue(event) def onMouseDown(self, sender, x, y): event = DOM.eventGetCurrentEvent() event.pos = (x, y) self.event.mousePress[event.button] = True self.event._updateQueue(event) def onMouseUp(self, sender, x, y): event = DOM.eventGetCurrentEvent() event.pos = (x, y) self.event.mousePress[event.button] = False self.event._updateQueue(event) def onMouseLeave(self, sender): self.event.mousePress[0], self.event.mousePress[ 1], self.event.mousePress[2] = False, False, False self.event.mouseMove['x'], self.event.mouseMove['y'] = -1, -1 self.event.mouseMoveRel['x'], self.event.mouseMoveRel['y'] = None, None for keycode in self.modKey: if self.event.keyPress[keycode]: self.event.keyPress[keycode] = False def onMouseWheel(self, sender, velocity): event = DOM.eventGetCurrentEvent() if event.type == 'mousewheel': #TODO: update for changes in mousewheel implementation if hasattr(event, 'wheelDeltaX'): self.onMouseWheel = self._onMouseWheel self._onMouseWheel(sender, velocity) else: self.onMouseWheel = self._onMouseWheelY DOM.eventGetMouseWheelVelocityY = eventGetMouseWheelVelocityY self._onMouseWheelY(sender, eventGetMouseWheelVelocityY(event)) else: #DOMMouseScroll self.onMouseWheel = self._onMouseScroll self._onMouseScroll(sender, velocity) def _onMouseWheel(self, sender, velocity): event = DOM.eventGetCurrentEvent() if not event.wheelDeltaX: if velocity < 0: button = 4 events = velocity / -3 else: button = 5 events = velocity / 3 else: if velocity < 0: button = 6 events = velocity / -3 else: button = 7 events = velocity / 3 event.btn = button event.pos = (self.event.mouseMove['x'], self.event.mouseMove['y']) for evt in range(events): self.event._updateQueue(event) def _onMouseWheelY(self, sender, velocity): event = DOM.eventGetCurrentEvent() if velocity < 0: button = 4 events = velocity / -3 else: button = 5 events = velocity / 3 event.btn = button event.pos = (self.event.mouseMove['x'], self.event.mouseMove['y']) for evt in range(events): self.event._updateQueue(event) def _onMouseScroll(self, sender, velocity): event = DOM.eventGetCurrentEvent() if velocity > 1 or velocity < -1: if velocity < 0: button = 4 else: button = 5 else: if velocity < 0: button = 6 else: button = 7 event.btn = button event.pos = (self.event.mouseMove['x'], self.event.mouseMove['y']) self.event._updateQueue(event) def onKeyDown(self, sender, keycode, modifiers): if keycode in self.modKey: event = DOM.eventGetCurrentEvent() self.event.keyPress[keycode] = True self.event._updateQueue(event) DOM.eventPreventDefault(event) elif keycode in self.specialKey: event = DOM.eventGetCurrentEvent() self.event._updateQueue(event) DOM.eventPreventDefault(event) def onKeyPress(self, sender, keycode, modifiers): event = DOM.eventGetCurrentEvent() if not (event.keyCode and event.keyCode in self.specialKey): self.event._updateQueue(event) DOM.eventPreventDefault(event) def onKeyUp(self, sender, keycode, modifiers): event = DOM.eventGetCurrentEvent() if keycode in self.modKey: self.event.keyPress[keycode] = False self.event._updateQueue(event) def onTouchInitiate(self, event): self.event.touchlistener.activate() for callback in self._touch_callback: if hasattr(callback, 'onTouchInitiate'): callback.onTouchInitiate(event) self.onTouchStart(event) def onTouchStart(self, event): for callback in self._touch_callback: callback.onTouchStart(event) def onTouchEnd(self, event): for callback in self._touch_callback: callback.onTouchEnd(event) def onTouchMove(self, event): for callback in self._touch_callback: callback.onTouchMove(event) def onTouchCancel(self, event): for callback in self._touch_callback: callback.onTouchCancel(event) def resize(self, width, height): Surface.resize(self, width, height) if self._bufferedimage: self.surface.resize(width, height) self.surface._display._surface_rect = self.surface.get_rect() def set_callback(self, cb): if not hasattr(cb, 'run'): self.callback = Callback(cb) else: self.callback = cb def load_images(self, images): if images: image_list = [] for image in images: if isinstance(image, str): image_list.append(image) self.image_list.append(image) else: name = image[0] if isinstance(image[1], str): data = image[1] else: data = base64.b64encode(image[1].getvalue()) if not data.startswith('data:'): ext = name.strip().split('.')[-1] data = "data:%s;base64,%s" % (ext, data) #data:[<mediatype>][;base64],<data> image_list.append(data) self.image_list.append(name) loadImages(image_list, self) else: self.start() def onImagesLoaded(self, images): for i, image in enumerate(self.image_list): self.images[image] = images[i].getElement() self.start() def start(self): if not self.initialized: self.initialized = True _wnd.requestAnimationFrame(run) self.time.timeout(0, self) def stop(self): global run run = lambda ts: None self.run = lambda: None def _get_rect(self): if self._rect_num < self._rect_len: return self._rect_list[self._rect_num] else: self._rect_list.append(Rect(0, 0, 0, 0)) self._rect_len += 1 return self._rect_list[self._rect_num] def run(self): if not self._repaint: self.callback.run() self._repaint = True self.time.timeout(0, self)
class Canvas(Surface): def __init__(self, size, buffered): Surface.__init__(self, size) if isinstance(buffered, bool): self._bufferedimage = buffered else: self._bufferedimage = True try: if self.impl.canvasContext: self._isCanvas = True except: self._isCanvas = False self._bufferedimage = False if self._bufferedimage: self.surface = Surface(size) else: self.surface = self self.images = {} self.image_list = [] self.callback = None self.time = Time() self.event = env.event self.addMouseListener(self) self.addKeyEventListener(self) self.sinkEvents(Event.ONMOUSEDOWN | Event.ONMOUSEUP | Event.ONMOUSEMOVE | Event.ONMOUSEOUT | Event.ONMOUSEWHEEL | Event.ONKEYDOWN | Event.ONKEYPRESS | Event.ONKEYUP) self.onContextMenu = None self.preventContextMenu() self.evt = self.event.eventObj self.modKey = self.event.modKey self.specialKey = self.event.specialKey self.modKeyCode = self.event.modKeyCode self.specialKeyCode = self.event.specialKeyCode self.keyRepeat = self.event.keyRepeat self.keyHeld = self.event.keyHeld self.mouse_entered = True self.event._initiate_touch_listener(self) self._touch_callback = self.event.touchlistener.callback self._rect_list = [] self._rect_len = 0 self._rect_num = 0 self._framerate = 0 self._frametime = 0 self._rendertime = self.time.time() self._pause = False self._canvas_init() self.initialized = False def _canvas_init(self): global _canvas, _ctx, _img, _wnd _canvas = self _ctx = self.impl.canvasContext _img = self.surface.canvas _wnd = requestAnimationFrameInit() def onMouseMove(self, sender, x, y): event = DOM.eventGetCurrentEvent() if event.type in self.event.events: if not self.mouse_entered: self.event.mouseMovePre['x'] = self.event.mouseMove['x'] self.event.mouseMovePre['y'] = self.event.mouseMove['y'] else: self.event.mouseMovePre['x'] = x self.event.mouseMovePre['y'] = y self.mouse_entered = False self.event._updateQueue(self.evt[event.type](event, x, y)) self.event.mouseMove['x'] = x self.event.mouseMove['y'] = y def onMouseDown(self, sender, x, y): event = DOM.eventGetCurrentEvent() if event.type in self.event.events: self.event._updateQueue(self.evt[event.type](event, x, y)) self.event.mousePress[event.button] = True def onMouseUp(self, sender, x, y): event = DOM.eventGetCurrentEvent() if event.type in self.event.events: self.event._updateQueue(self.evt[event.type](event, x, y)) self.event.mousePress[event.button] = False def onMouseEnter(self, sender): self.mouse_entered = True def onMouseLeave(self, sender): self.event.mousePress[0] = False self.event.mousePress[1] = False self.event.mousePress[2] = False self.event.mouseMove['x'] = -1 self.event.mouseMove['y'] = -1 self.event.mouseMoveRel['x'] = None self.event.mouseMoveRel['y'] = None for keycode in self.modKeyCode: if self.event.keyPress[keycode]: self.event.keyPress[keycode] = False def onMouseWheel(self, event): if event.type in self.event.events: r = self.canvas.getBoundingClientRect() x = event.clientX - round(r.left) y = event.clientY - round(r.top) self.event._updateQueue(self.evt[event.type](event, x, y)) DOM.eventPreventDefault(event) def onKeyEvent(self, event): self.removeKeyEventListener(self) self.addKeyboardListener(self) DOM.currentEvent = event if hasattr(event, 'key') and hasattr(event, 'code'): self.onKeyDown(self, event.key, 0) else: self.event._set_key_event() self.onKeyDown = self._onKeyDown self.onKeyUp = self._onKeyUp self.onKeyPress = self._onKeyPress keycode = event.which or event.keyCode or 0 self._onKeyDown(self, keycode, 0) def onKeyDown(self, sender, keycode, mods): event = DOM.eventGetCurrentEvent() if event.key in self.modKey: self.event.keyPress[self.modKey[event.key]] = True if event.type in self.event.events: if not self._isPaused(event.key): self.event._updateQueue(self.evt[event.type](event)) DOM.eventPreventDefault(event) def onKeyUp(self, sender, keycode, mods): event = DOM.eventGetCurrentEvent() if event.key in self.modKey: self.event.keyPress[self.modKey[event.key]] = False if event.key in self.keyHeld: self.keyHeld[event.key]['pressed'] = False if event.type in self.event.events: self.event._updateQueue(self.evt[event.type](event)) def _onKeyDown(self, sender, keycode, mods): event = DOM.eventGetCurrentEvent() if keycode in self.modKeyCode: self.event.keyPress[keycode] = True if event.type in self.event.events: if not self._isPaused(keycode): self.event.keyCode = keycode if keycode in self.specialKeyCode: self.event._updateQueue(self.evt[event.type](event, keycode)) DOM.eventPreventDefault(event) else: DOM.eventPreventDefault(event) def _onKeyUp(self, sender, keycode, mods): event = DOM.eventGetCurrentEvent() if keycode in self.modKeyCode: self.event.keyPress[keycode] = False if keycode in self.keyHeld: self.keyHeld[keycode]['pressed'] = False if event.type in self.event.events: self.event._updateQueue(self.evt[event.type](event, keycode)) def _onKeyPress(self, sender, keycode, mods): event = DOM.eventGetCurrentEvent() if event.type in self.event.events: self.event.keyPressCode[self.event.keyCode] = keycode self.event._updateQueue(self.evt[event.type](event, keycode)) event.preventDefault() def _isPaused(self, keycode): if keycode not in self.keyHeld: self.keyHeld[keycode] = { 'pressed': False, 'delay': False, 'time': 0 } key = self.keyHeld[keycode] if not key['pressed']: key['pressed'] = True paused = False if self.keyRepeat[0]: key['delay'] = True key['time'] = self.time.time() else: paused = True if self.keyRepeat[0]: time = self.time.time() if key['delay']: if time - key['time'] > self.keyRepeat[0]: key['time'] = time key['delay'] = False paused = False elif time - key['time'] > self.keyRepeat[1]: key['time'] = time paused = False return paused def onTouchInitiate(self, event): self.event.touchlistener.activate() for callback in self._touch_callback: if hasattr(callback, 'onTouchInitiate'): callback.onTouchInitiate(event) self.onTouchStart(event) def onTouchStart(self, event): for callback in self._touch_callback: callback.onTouchStart(event) def onTouchEnd(self, event): for callback in self._touch_callback: callback.onTouchEnd(event) def onTouchMove(self, event): for callback in self._touch_callback: callback.onTouchMove(event) def onTouchCancel(self, event): for callback in self._touch_callback: callback.onTouchCancel(event) def preventContextMenu(self, setting=True): """ Control contextmenu event. Optional bool setting to prevent event, default to True. """ if setting: if self.onContextMenu: return element = self.getElement() self.onContextMenu = lambda event: event.preventDefault() element.addEventListener('contextmenu', self.onContextMenu) else: if not self.onContextMenu: return element = self.getElement() element.removeEventListener('contextmenu', self.onContextMenu) self.onContextMenu = None def resize(self, width, height): Surface.resize(self, width, height) if self._bufferedimage: self.surface.resize(width, height) self.surface._display._surface_rect = self.surface.get_rect() def set_callback(self, cb): if not hasattr(cb, 'run'): self.callback = Callback(cb) else: self.callback = cb def load_images(self, images): if images: image_list = [] for image in images: if isinstance(image, str): image_list.append(image) self.image_list.append(image) else: name = image[0] if isinstance(image[1], str): data = image[1] else: data = base64.b64encode(image[1].getvalue()) if not data.startswith('data:'): ext = name.strip().split('.')[-1] data = "data:%s;base64,%s" % (ext, data) #data:[<mediatype>][;base64],<data> image_list.append(data) self.image_list.append(name) loadImages(image_list, self) else: self.start() def onImagesLoaded(self, images): for i, image in enumerate(self.image_list): self.images[image] = images[i].getElement() self.start() def start(self): if not self.initialized: self.initialized = True _wnd.requestAnimationFrame(run) def stop(self): global run run = lambda ts: None self.run = lambda: None def _get_rect(self): if self._rect_num < self._rect_len: return self._rect_list[self._rect_num] else: self._rect_list.append(Rect(0, 0, 0, 0)) self._rect_len += 1 return self._rect_list[self._rect_num] def update(self, timestamp): if not self._framerate: self._frametime = timestamp - self._rendertime self.run() else: self._frametime += timestamp - self._rendertime if self._frametime > self._framerate: self.run() self._frametime = 0 self._rendertime = timestamp def render(self): while self._rect_num: rect = self._rect_list[self._rect_num - 1] x, y, width, height = rect.x, rect.y, rect.width, rect.height _ctx.drawImage(_img, x, y, width, height, x, y, width, height) self._rect_num -= 1 def run(self): self.callback.run()