def window_focus(self, window_id, focus): if not focus: if window_id == sdl2.SDL_GetWindowID(self.tile1.window): self.tile1.reset_hover() elif window_id == sdl2.SDL_GetWindowID(self.tile2.window): self.tile2.reset_hover() elif window_id == sdl2.SDL_GetWindowID(self.sprite.window): self.sprite.reset_hover() elif window_id == sdl2.SDL_GetWindowID(self.tile.window): self.tile.reset_hover()
def mouse(self, click, window_id, x, y): # The marked tile mt = NO_TILE # Forward mouse event to appropriate handlers if window_id == sdl2.SDL_GetWindowID(self.tile1.window): mt = self.tile1.mouse(click, window_id, x, y) elif window_id == sdl2.SDL_GetWindowID(self.tile2.window): mt = self.tile2.mouse(click, window_id, x, y) elif window_id == sdl2.SDL_GetWindowID(self.sprite.window): mt = self.sprite.mouse(click, window_id, x, y) elif window_id == sdl2.SDL_GetWindowID(self.tile.window): mt = self.tile.mouse(click, window_id, x, y) else: # Game window # TODO: Detect which sprites, tiles, etc. is below cursor and highlight in other views print(click, window_id, x, y) # Test if there is a new marked tile if mt != NO_TILE: self.marked_tile = mt # Reset selection on other windows if window_id != sdl2.SDL_GetWindowID(self.tile1.window): self.tile1.reset_mouse() if window_id != sdl2.SDL_GetWindowID(self.tile2.window): self.tile2.reset_mouse() if window_id != sdl2.SDL_GetWindowID(self.sprite.window): self.sprite.reset_mouse() if window_id != sdl2.SDL_GetWindowID(self.tile.window): self.tile.reset_mouse()
def writerChildFunction(qTo, qFrom, windowSize=[200, 200], windowPosition=[0, 0]): import sdl2 import sdl2.ext import sys import time try: import appnope appnope.nope() except: pass sdl2.SDL_Init(sdl2.SDL_INIT_VIDEO) window = sdl2.ext.Window("writer", size=windowSize, position=windowPosition, flags=sdl2.SDL_WINDOW_SHOWN) windowID = sdl2.SDL_GetWindowID(window.window) windowSurf = sdl2.SDL_GetWindowSurface(window.window) sdl2.ext.fill(windowSurf.contents, sdl2.pixels.SDL_Color(r=255, g=255, b=255, a=255)) window.refresh() for i in range(10): sdl2.SDL_PumpEvents() #to show the windows files = {} def exitSafely(): try: for index, fileObj in files.items(): fileObj.close() # gpg -r "Michael Lawrence <*****@*****.**>" -e mac.txt except: pass sys.exit() while True: if not qTo.empty(): message = qTo.get() if message == 'quit': exitSafely() elif message[0] == 'newFile': files[message[1]] = open(message[2], 'w') elif message[0] == 'write': files[message[1]].write(message[2] + '\n') else: time.sleep(1) sdl2.SDL_PumpEvents() for event in sdl2.ext.get_events(): if event.type == sdl2.SDL_WINDOWEVENT: if (event.window.event == sdl2.SDL_WINDOWEVENT_CLOSE): exitSafely()
def stimDisplayMirrorChildFunction(qTo, qFrom, windowSize=[1920 / 2, 1080 / 2], windowPosition=[0, 0]): import sdl2 import sdl2.ext import sys import time from PIL import Image #for image manipulation try: import appnope appnope.nope() except: pass sdl2.SDL_Init(sdl2.SDL_INIT_VIDEO) window = sdl2.ext.Window("mirror", size=windowSize, position=windowPosition, flags=sdl2.SDL_WINDOW_SHOWN) windowID = sdl2.SDL_GetWindowID(window.window) windowSurf = sdl2.SDL_GetWindowSurface(window.window) windowArray = sdl2.ext.pixels3d(windowSurf.contents) sdl2.ext.fill(windowSurf.contents, sdl2.pixels.SDL_Color(r=255, g=255, b=255, a=255)) window.refresh() for i in range(10): sdl2.SDL_PumpEvents() #to show the windows def exitSafely(): sys.exit() while True: if not qTo.empty(): message = qTo.get() if message == 'quit': exitSafely() elif message[0] == 'frame': # print ['q',time.time()-message[3]] #time spent in queue res = message[1] buffer = message[2] image = Image.fromstring(mode="RGB", size=res, data=buffer) image = image.transpose(Image.ROTATE_270) # start = time.time() # image.thumbnail([res[1]/2,res[0]/2],Image.LANCZOS) # print ['resize',time.time()-start] windowArray[:, :, 0:3] = image window.refresh() sdl2.SDL_PumpEvents() for event in sdl2.ext.get_events(): if event.type == sdl2.SDL_WINDOWEVENT: if (event.window.event == sdl2.SDL_WINDOWEVENT_CLOSE): exitSafely()
def __init__(self, *args, **kwargs): BaseCanvasBackend.__init__(self, *args) p = self._process_backend_kwargs(kwargs) self._initialized = False # Deal with config _set_config(p.context.config) # Deal with context p.context.shared.add_ref('sdl2', self) if p.context.shared.ref is self: share = None else: other = p.context.shared.ref share = other._id.window, other._native_context sdl2.SDL_GL_MakeCurrent(*share) sdl2.SDL_GL_SetAttribute(sdl2.SDL_GL_SHARE_WITH_CURRENT_CONTEXT, 1) sdl2.SDL_GL_SetSwapInterval(1 if p.vsync else 0) flags = sdl2.SDL_WINDOW_OPENGL flags |= sdl2.SDL_WINDOW_SHOWN # start out shown flags |= sdl2.SDL_WINDOW_ALLOW_HIGHDPI flags |= sdl2.SDL_WINDOW_RESIZABLE if p.resizable else 0 flags |= sdl2.SDL_WINDOW_BORDERLESS if not p.decorate else 0 if p.fullscreen is not False: self._fullscreen = True if p.fullscreen is not True: logger.warning('Cannot specify monitor number for SDL2 ' 'fullscreen, using default') flags |= sdl2.SDL_WINDOW_FULLSCREEN_DESKTOP else: self._fullscreen = False self._mods = list() if p.position is None: position = [sdl2.SDL_WINDOWPOS_UNDEFINED] * 2 else: position = None self._id = sdl2.ext.Window(p.title, p.size, position, flags) if not self._id.window: raise RuntimeError('Could not create window') if share is None: self._native_context = sdl2.SDL_GL_CreateContext(self._id.window) else: self._native_context = sdl2.SDL_GL_CreateContext(share[0]) self._sdl_id = sdl2.SDL_GetWindowID(self._id.window) _VP_SDL2_ALL_WINDOWS[self._sdl_id] = self # Init self._initialized = True self._needs_draw = False self._vispy_canvas.set_current() self._vispy_canvas.events.initialize() if not p.show: self._vispy_set_visible(False)
def __init__(self, *args, **kwargs): BaseCanvasBackend.__init__(self, *args) title, size, position, show, vsync, resize, dec, fs, parent, context, \ = self._process_backend_kwargs(kwargs) self._initialized = False # Deal with context if not context.istaken: context.take('sdl2', self) _set_config(context.config) share = None elif context.istaken == 'sdl2': other = context.backend_canvas share = other._id.window, other._native_context sdl2.SDL_GL_MakeCurrent(*share) sdl2.SDL_GL_SetAttribute(sdl2.SDL_GL_SHARE_WITH_CURRENT_CONTEXT, 1) else: raise RuntimeError('Different backends cannot share a context.') sdl2.SDL_GL_SetSwapInterval(1 if vsync else 0) flags = sdl2.SDL_WINDOW_OPENGL flags |= sdl2.SDL_WINDOW_SHOWN # start out shown flags |= sdl2.SDL_WINDOW_ALLOW_HIGHDPI flags |= sdl2.SDL_WINDOW_RESIZABLE if resize else 0 flags |= sdl2.SDL_WINDOW_BORDERLESS if not dec else 0 if fs is not False: self._fullscreen = True if fs is not True: logger.warning('Cannot specify monitor number for SDL2 ' 'fullscreen, using default') flags |= sdl2.SDL_WINDOW_FULLSCREEN_DESKTOP else: self._fullscreen = False self._mods = list() if position is None: position = [sdl2.SDL_WINDOWPOS_UNDEFINED] * 2 self._id = sdl2.ext.Window(title, size, position, flags) if not self._id.window: raise RuntimeError('Could not create window') if share is None: self._native_context = sdl2.SDL_GL_CreateContext(self._id.window) else: self._native_context = sdl2.SDL_GL_CreateContext(share[0]) self._sdl_id = sdl2.SDL_GetWindowID(self._id.window) _VP_SDL2_ALL_WINDOWS[self._sdl_id] = self # Init self._initialized = True self._needs_draw = False self._vispy_set_current() self._vispy_canvas.events.initialize() if not show: self._vispy_set_visible(False)
def __init__( self, width=256, height=256, title=None, visible=True, aspect=None, decoration=True, fullscreen=False, config=None, context=None, color=(0,0,0,1)): """ """ window.Window.__init__(self, width=width, height=height, title=title, visible=visible, aspect=aspect, decoration=decoration, fullscreen=fullscreen, config=config, context=context, color=color) if config is None: config = configuration.Configuration() set_configuration(config) flags = sdl2.SDL_WINDOW_SHOWN # flags |= sdl2.SDL_WINDOW_ALLOW_HIGHDPI flags |= sdl2.SDL_WINDOW_RESIZABLE flags |= sdl2.SDL_WINDOW_OPENGL if visible: flags |= sdl2.SDL_WINDOW_SHOWN else: flags |= SDL_WINDOW_HIDDEN if not decoration: flags |= sdl2.SDL_WINDOW_BORDERLESS self._native_window = sdl2.SDL_CreateWindow(self._title, sdl2.SDL_WINDOWPOS_UNDEFINED, sdl2.SDL_WINDOWPOS_UNDEFINED, width, height, flags) self._native_context = sdl2.SDL_GL_CreateContext(self._native_window) self._native_id = sdl2.SDL_GetWindowID(self._native_window) sdl2.SDL_GL_SetSwapInterval(0) # OSX: check framebuffer size / window size. On retina display, they # can be different so we try to correct window size such as having # the framebuffer size of the right size # w,h = ctypes.c_int(),ctypes.c_int() # sdl2.SDL_GL_GetDrawableSize(self._native_window, w, h) # w,h = w.value(), h.value() # if w != width or h!= height: # width = width/2 # height= height/2 # sdl2.SDL_SetWindowSize(self._native_window, int(width), int(height)) self._height = height self._width = width __windows__[self._native_id] = self
def prepare(): App.running = True App.num_displays = sdl2.SDL_GetNumVideoDisplays() logger.info(f"Number of displays: {App.num_displays}") for display in range(0, App.num_displays): rect = sdl2.SDL_Rect() sdl2.SDL_GetDisplayBounds(display, rect) border_width = rect.w * App.BORDER_WIDTH_PERCENT / 100 border_height = rect.h * App.BORDER_WIDTH_PERCENT / 100 window = sdl2.SDL_CreateWindow( f"{display}".encode("ascii"), 0, 0, int(rect.w - 2 * border_width), int(rect.h - 2 * border_height), int(sdl2.SDL_WINDOW_BORDERLESS), ) window_id = sdl2.SDL_GetWindowID(window) renderer = sdl2.SDL_CreateRenderer(window, -1, 0) sdl2.SDL_SetRenderDrawColor(renderer, 30, 30, 30, 255) sdl2.SDL_ShowWindow(window) sdl2.SDL_SetWindowPosition(window, int(rect.x + border_width), int(rect.y + border_height)) scale_factor = (100 - 2 * App.BORDER_WIDTH_PERCENT) / 100 internal_rect = sdl2.SDL_Rect( int(rect.x * scale_factor), int(rect.y * scale_factor), int(rect.w * scale_factor), int(rect.h * scale_factor), ) App.windows.append({ "rect": rect, "internal_rect": internal_rect, "window_id": window_id, "window": window, "renderer": renderer, }) Events.add_listener(*App.handle_window_leave) Events.add_listener(*App.handle_window_close) Events.add_listener(*App.handle_q)
def multi_run(ns): windows_by_id = {} # winid -> Numm for n in ns: if hasattr(n, "_win"): # print n, 'window-id', sdl2.SDL_GetWindowID(n._win.window) windows_by_id[sdl2.SDL_GetWindowID(n._win.window)] = n if hasattr(n, "init"): n.init() while True: for ev in sdl2.ext.get_events(): if hasattr(ev, "window") and ev.window.windowID in windows_by_id: windows_by_id[ev.window.windowID]._handle_event(ev) else: # print "ev not handled by either window", ev, dir(ev) pass for n in ns: n._update_av()
def __init__(self, pyboy, mb, pyboy_argv, *, scale, title, width, height, pos_x, pos_y): super().__init__(pyboy, mb, pyboy_argv) self.scale = scale self.width, self.height = width, height self.base_title = title self.hover_x = -1 self.hover_y = -1 self._window = sdl2.SDL_CreateWindow( self.base_title.encode("utf8"), pos_x, pos_y, width * scale, height * scale, sdl2.SDL_WINDOW_RESIZABLE ) self.window_id = sdl2.SDL_GetWindowID(self._window) self.buf, self.buf0, self.buf_p = make_buffer(width, height) self._sdlrenderer = sdl2.SDL_CreateRenderer(self._window, -1, sdl2.SDL_RENDERER_ACCELERATED) self._sdltexturebuffer = sdl2.SDL_CreateTexture( self._sdlrenderer, sdl2.SDL_PIXELFORMAT_RGBA8888, sdl2.SDL_TEXTUREACCESS_STATIC, width, height )
def __init__(self, width=256, height=256, title=None, visible=True, decoration=True, fullscreen=False, config=None, context=None): """ """ window.Window.__init__(self, width, height, title, visible, decoration, fullscreen, config, context) if config is None: config = configuration.Configuration() set_configuration(config) flags = sdl2.SDL_WINDOW_SHOWN flags |= sdl2.SDL_WINDOW_ALLOW_HIGHDPI flags |= sdl2.SDL_WINDOW_RESIZABLE flags |= sdl2.SDL_WINDOW_OPENGL if visible: flags |= sdl2.SDL_WINDOW_SHOWN else: flags |= SDL_WINDOW_HIDDEN if not decoration: flags |= sdl2.SDL_WINDOW_BORDERLESS self._native_window = sdl2.SDL_CreateWindow( self._title, sdl2.SDL_WINDOWPOS_UNDEFINED, sdl2.SDL_WINDOWPOS_UNDEFINED, width, height, flags) self._native_context = sdl2.SDL_GL_CreateContext(self._native_window) self._native_id = sdl2.SDL_GetWindowID(self._native_window) sdl2.SDL_GL_SetSwapInterval(0) __windows__[self._native_id] = self
def labjackChildFunction(qTo, qFrom, windowSize=[200, 200], windowPosition=[0, 0]): import sdl2 import sdl2.ext import sys import time try: import appnope appnope.nope() except: pass sdl2.SDL_Init(sdl2.SDL_INIT_VIDEO) window = sdl2.ext.Window("labjack", size=windowSize, position=windowPosition, flags=sdl2.SDL_WINDOW_SHOWN) windowID = sdl2.SDL_GetWindowID(window.window) windowSurf = sdl2.SDL_GetWindowSurface(window.window) sdl2.ext.fill(windowSurf.contents, sdl2.pixels.SDL_Color(r=255, g=255, b=255, a=255)) window.refresh() for i in range(10): sdl2.SDL_PumpEvents() #to show the windows import u3 d = u3.U3() d.configU3() d.getCalibrationData() d.configAnalog(u3.FIO0) checkForNextZeroTime = False checkForTrialNextZeroTime = False def exitSafely(): d.close() sys.exit() sendTriggers = False while True: if sendTriggers: if not checkForNextZeroTime: temp = d.getAIN(0) # print temp if temp > .5: #photosensor surpasses criterion d.getFeedback(u3.BitStateWrite(IONumber=8, State=1)) nextZeroTime = time.time( ) + .010 #wait 10ms before setting the state back to zero, giving the amp time to pick it up checkForNextZeroTime = True else: if time.time() >= nextZeroTime: #time to turn the bit back off d.getFeedback(u3.BitStateWrite(IONumber=8, State=0)) checkForNextZeroTime = False if checkForTrialNextZeroTime: if time.time() >= trialNextZeroTime: d.getFeedback(u3.BitStateWrite(IONumber=9, State=0)) checkForTrialNextZeroTime = False if not qTo.empty(): message = qTo.get() if message == 'quit': exitSafely() elif message == 'trialDone': sendTriggers = False checkForTrialNextZeroTime = False checkForNextZeroTime = False d.getFeedback(u3.BitStateWrite( IONumber=8, State=0)) #should be zero, but just in case... d.getFeedback(u3.BitStateWrite( IONumber=9, State=0)) #should be zero, but just in case... elif message == 'trialStart': sendTriggers = True d.getFeedback(u3.BitStateWrite(IONumber=9, State=1)) trialNextZeroTime = time.time( ) + .010 #wait 10ms before setting the state back to zero, giving the amp time to pick it up checkForTrialNextZeroTime = True sdl2.SDL_PumpEvents() for event in sdl2.ext.get_events(): if event.type == sdl2.SDL_WINDOWEVENT: if (event.window.event == sdl2.SDL_WINDOWEVENT_CLOSE): exitSafely()
def eyelinkChildFunction(qTo, qFrom, windowSize=[200, 200], windowPosition=[0, 0], stimDisplayRes=[1920, 1080], calibrationDisplaySize=[1920, 1080], calibrationDotSize=10, eyelinkIp='100.1.1.1', edfFileName='temp.edf', edfPath='./_Data/temp.edf', saccadeSoundFile='_Stimuli/stop.wav', blinkSoundFile='_Stimuli/stop.wav'): import sdl2 import sdl2.ext import math import OpenGL.GL as gl import sdl2.sdlmixer import pylink import numpy import sys import shutil import subprocess import time import os import array from PIL import Image from PIL import ImageDraw try: import appnope appnope.nope() except: pass byteify = lambda x, enc: x.encode(enc) sdl2.SDL_Init(sdl2.SDL_INIT_VIDEO) window = sdl2.ext.Window("eyelink", size=windowSize, position=windowPosition, flags=sdl2.SDL_WINDOW_SHOWN) windowID = sdl2.SDL_GetWindowID(window.window) windowSurf = sdl2.SDL_GetWindowSurface(window.window) sdl2.ext.fill(windowSurf.contents, sdl2.pixels.SDL_Color(r=0, g=0, b=0, a=255)) window.refresh() for i in range(10): sdl2.SDL_PumpEvents() #to show the windows sdl2.SDL_Init(sdl2.SDL_INIT_AUDIO) sdl2.sdlmixer.Mix_OpenAudio(44100, sdl2.sdlmixer.MIX_DEFAULT_FORMAT, 2, 1024) class Sound: def __init__(self, fileName): self.sample = sdl2.sdlmixer.Mix_LoadWAV( sdl2.ext.compat.byteify(fileName, "utf-8")) self.started = False def play(self): self.channel = sdl2.sdlmixer.Mix_PlayChannel(-1, self.sample, 0) self.started = True def stillPlaying(self): if self.started: if sdl2.sdlmixer.Mix_Playing(self.channel): return True else: self.started = False return False else: return False saccadeSound = Sound(saccadeSoundFile) blinkSound = Sound(blinkSoundFile) def exitSafely(): if 'eyelink' in locals(): if eyelink.isRecording() == 0: eyelink.stopRecording() eyelink.setOfflineMode() eyelink.closeDataFile() eyelink.receiveDataFile(edfFileName, 'temp.edf') eyelink.close() if os.path.isfile('temp.edf'): shutil.move('temp.edf', edfPath) # if os.path.isfile(edfPath): # subprocess.call('./edf2asc -y ./'+edfPath,shell=True) sys.exit( ) #process gets hung here if called when showing images from eyelink pylink.setDriftCorrectSounds('off', 'off', 'off') pylink.setCalibrationSounds('off', 'off', 'off') edfPath = './_Data/temp.edf' #temporary default location, to be changed later when ID is established done = False while not done: try: # print '\neyelink: Attempting to connect to eyelink (check that wifi is off!)' eyelink = pylink.EyeLink(eyelinkIp) done = True except: while not qTo.empty(): message = qTo.get() if message == 'quit': exitSafely() else: qTo.put(message) # print 'eyelink: connected' eyelink.sendCommand( 'select_parser_configuration 0' ) # 0--> standard (cognitive); 1--> sensitive (psychophysical) # eyelink.sendCommand('sample_rate 500') eyelink.setLinkEventFilter("SACCADE,BLINK,FIXATION,LEFT,RIGHT") eyelink.openDataFile(edfFileName) eyelink.sendCommand( "screen_pixel_coords = %d %d %d %d" % (stimDisplayRes[0] / 2 - calibrationDisplaySize[0] / 2, stimDisplayRes[1] / 2 - calibrationDisplaySize[1] / 2, stimDisplayRes[0] / 2 + calibrationDisplaySize[0] / 2, stimDisplayRes[1] / 2 + calibrationDisplaySize[1] / 2)) eyelink.sendMessage("DISPLAY_COORDS 0 0 %d %d" % (stimDisplayRes[0], stimDisplayRes[1])) eyelink.sendCommand("saccade_velocity_threshold = 60") eyelink.sendCommand("saccade_acceleration_threshold = 19500") class EyeLinkCoreGraphicsPySDL2(pylink.EyeLinkCustomDisplay): def __init__(self): # self.__target_beep__ = Sound('_Stimuli/type.wav') # self.__target_beep__done__ = Sound('qbeep.wav') # self.__target_beep__error__ = Sound('error.wav') if sys.byteorder == 'little': self.byteorder = 1 else: self.byteorder = 0 self.imagebuffer = array.array('I') self.pal = None self.__img__ = None def record_abort_hide(self): pass def play_beep(self, beepid): pass # if beepid == pylink.DC_TARG_BEEP or beepid == pylink.CAL_TARG_BEEP: # self.__target_beep__.play() # elif beepid == pylink.CAL_ERR_BEEP or beepid == pylink.DC_ERR_BEEP: # self.__target_beep__error__.play() # else:# CAL_GOOD_BEEP or DC_GOOD_BEEP # self.__target_beep__done__.play() def clear_cal_display(self): # # print 'clear_cal_display' qFrom.put('clearCalDisplay') def setup_cal_display(self): # # print 'setup_cal_display' qFrom.put('setupCalDisplay') def exit_cal_display(self): # # print 'exit_cal_display' qFrom.put('exitCalDisplay') def erase_cal_target(self): # # print 'erase_cal_target' qFrom.put('eraseCalTarget') def draw_cal_target(self, x, y): # # print 'draw_cal_target' qFrom.put(['drawCalTarget', x, y]) def setup_image_display(self, width, height): # # print 'eyelink: setup_image_display' self.img_size = (width, height) return (0) def exit_image_display(self): # # print 'eyelink: exit_image_display' pass def image_title(self, text): # # print 'eyelink: image_title' pass def set_image_palette(self, r, g, b): # # print 'eyelink: set_image_palette' self.imagebuffer = array.array('I') sz = len(r) i = 0 self.pal = [] while i < sz: rf = int(b[i]) gf = int(g[i]) bf = int(r[i]) if self.byteorder: self.pal.append((rf << 16) | (gf << 8) | (bf)) else: self.pal.append( (bf << 24) | (gf << 16) | (rf << 8)) #for mac i = i + 1 def draw_image_line(self, width, line, totlines, buff): # # print 'eyelink: draw_image_line' i = 0 while i < width: if buff[i] >= len(self.pal): buff[i] = len(self.pal) - 1 self.imagebuffer.append(self.pal[buff[i] & 0x000000FF]) i = i + 1 if line == totlines: img = Image.fromstring('RGBX', (width, totlines), self.imagebuffer.tostring()) img = img.convert('RGBA') self.__img__ = img.copy() self.__draw__ = ImageDraw.Draw(self.__img__) self.draw_cross_hair( ) #inherited method, calls draw_line and draw_losenge qFrom.put([ 'image', numpy.array( self.__img__.resize([ self.__img__.size[0] * 4, self.__img__.size[1] * 4 ], Image.BICUBIC)) ]) self.__img__ = None self.__draw__ = None self.imagebuffer = array.array('I') def getColorFromIndex(self, colorindex): if colorindex == pylink.CR_HAIR_COLOR: return (255, 255, 255, 255) elif colorindex == pylink.PUPIL_HAIR_COLOR: return (255, 255, 255, 255) elif colorindex == pylink.PUPIL_BOX_COLOR: return (0, 255, 0, 255) elif colorindex == pylink.SEARCH_LIMIT_BOX_COLOR: return (255, 0, 0, 255) elif colorindex == pylink.MOUSE_CURSOR_COLOR: return (255, 0, 0, 255) else: return (0, 0, 0, 0) def draw_line(self, x1, y1, x2, y2, colorindex): # # print 'eyelink: draw_line' if x1 < 0: x1 = 0 if x2 < 0: x2 = 0 if y1 < 0: y1 = 0 if y2 < 0: y2 = 0 if x1 > self.img_size[0]: x1 = self.img_size[0] if x2 > self.img_size[0]: x2 = self.img_size[0] if y1 > self.img_size[1]: y1 = self.img_size[1] if y2 > self.img_size[1]: y2 = self.img_size[1] imr = self.__img__.size x1 = int((float(x1) / float(self.img_size[0])) * imr[0]) x2 = int((float(x2) / float(self.img_size[0])) * imr[0]) y1 = int((float(y1) / float(self.img_size[1])) * imr[1]) y2 = int((float(y2) / float(self.img_size[1])) * imr[1]) color = self.getColorFromIndex(colorindex) self.__draw__.line([(x1, y1), (x2, y2)], fill=color) return 0 def draw_lozenge(self, x, y, width, height, colorindex): # # print 'eyelink: draw_lozenge' color = self.getColorFromIndex(colorindex) imr = self.__img__.size x = int((float(x) / float(self.img_size[0])) * imr[0]) width = int((float(width) / float(self.img_size[0])) * imr[0]) y = int((float(y) / float(self.img_size[1])) * imr[1]) height = int((float(height) / float(self.img_size[1])) * imr[1]) if width > height: rad = height / 2 self.__draw__.line([(x + rad, y), (x + width - rad, y)], fill=color) self.__draw__.line([(x + rad, y + height), (x + width - rad, y + height)], fill=color) clip = (x, y, x + height, y + height) self.__draw__.arc(clip, 90, 270, fill=color) clip = ((x + width - height), y, x + width, y + height) self.__draw__.arc(clip, 270, 90, fill=color) else: rad = width / 2 self.__draw__.line([(x, y + rad), (x, y + height - rad)], fill=color) self.__draw__.line([(x + width, y + rad), (x + width, y + height - rad)], fill=color) clip = (x, y, x + width, y + width) self.__draw__.arc(clip, 180, 360, fill=color) clip = (x, y + height - width, x + width, y + height) self.__draw__.arc(clip, 360, 180, fill=color) return 0 def get_mouse_state(self): # pos = pygame.mouse.get_pos() # state = pygame.mouse.get_pressed() # return (pos,state[0]) pass def get_input_key(self): ky = [] while not qTo.empty(): message = qTo.get() # print 'eyelink: ' # print message if message == 'button': ky.append( pylink.KeyInput(32, 0) ) #button translated to space keypress (for drift correct) # if message=='quit': # # print 'received message to exit' # exitSafely() # el elif message[0] == 'keycode': keysym = message[1] keycode = keysym.sym if keycode == sdl2.SDLK_F1: keycode = pylink.F1_KEY elif keycode == sdl2.SDLK_F2: keycode = pylink.F2_KEY elif keycode == sdl2.SDLK_F3: keycode = pylink.F3_KEY elif keycode == sdl2.SDLK_F4: keycode = pylink.F4_KEY elif keycode == sdl2.SDLK_F5: keycode = pylink.F5_KEY elif keycode == sdl2.SDLK_F6: keycode = pylink.F6_KEY elif keycode == sdl2.SDLK_F7: keycode = pylink.F7_KEY elif keycode == sdl2.SDLK_F8: keycode = pylink.F8_KEY elif keycode == sdl2.SDLK_F9: keycode = pylink.F9_KEY elif keycode == sdl2.SDLK_F10: keycode = pylink.F10_KEY elif keycode == sdl2.SDLK_PAGEUP: keycode = pylink.PAGE_UP elif keycode == sdl2.SDLK_PAGEDOWN: keycode = pylink.PAGE_DOWN elif keycode == sdl2.SDLK_UP: keycode = pylink.CURS_UP elif keycode == sdl2.SDLK_DOWN: keycode = pylink.CURS_DOWN elif keycode == sdl2.SDLK_LEFT: keycode = pylink.CURS_LEFT elif keycode == sdl2.SDLK_RIGHT: keycode = pylink.CURS_RIGHT elif keycode == sdl2.SDLK_BACKSPACE: keycode = ord('\b') elif keycode == sdl2.SDLK_RETURN: keycode = pylink.ENTER_KEY elif keycode == sdl2.SDLK_ESCAPE: keycode = pylink.ESC_KEY elif keycode == sdl2.SDLK_TAB: keycode = ord('\t') elif keycode == pylink.JUNK_KEY: keycode = 0 ky.append(pylink.KeyInput(keycode, keysym.mod)) return ky customDisplay = EyeLinkCoreGraphicsPySDL2() pylink.openGraphicsEx(customDisplay) newGazeTarget = False gazeTarget = numpy.array(calibrationDisplaySize) / 2.0 gazeTargetCriterion = calibrationDotSize doSounds = False reportSaccades = False reportBlinks = False lastMessageTime = time.time() lastStartBlinkTime = time.time() while True: sdl2.SDL_PumpEvents() for event in sdl2.ext.get_events(): if event.type == sdl2.SDL_WINDOWEVENT: if (event.window.event == sdl2.SDL_WINDOWEVENT_CLOSE): exitSafely() if not qTo.empty(): message = qTo.get() if message == 'quit': exitSafely() elif message[0] == 'edfPath': edfPath = message[1] elif message[0] == 'doSounds': doSounds = message[1] elif message[0] == 'reportSaccades': reportSaccades = message[1] elif message[0] == 'reportBlinks': reportBlinks = message[1] elif message[0] == 'sendMessage': eyelink.sendMessage(message[1]) elif message[0] == 'doDriftCorrect': # print 'eyelink: drift correct requested' if eyelink.isRecording() == 0: eyelink.stopRecording() try: location = message[1] error = eyelink.doDriftCorrect(location[0], location[1], 0, 1) # print error # print 'eyelink: drift correct attempted' if error != 27: qFrom.put('driftCorrectComplete') else: qFrom.put('doCalibration') except: qFrom.put('doCalibration') elif message == 'startRecording': # print 'eyelink: received message to begin recording' eyelink.startRecording( 1, 1, 1, 1 ) #this retuns immediately takes 10-30ms to actually kick in on the tracker while not (eyelink.isRecording() == 0): pass # print eyelink.isRecording() qFrom.put('recordingStarted') elif message[0] == 'newGazeTarget': # # print message newGazeTarget = True gazeTarget = numpy.array(message[1]) gazeTargetCriterion = numpy.array(message[2]) # # print message # # print 'waiting for gaze confirmation' elif message[0] == 'acceptTrigger': eyelink.accept_trigger() elif message == 'doCalibration': doSounds = False if eyelink.isRecording() == 0: eyelink.stopRecording() eyelink.doTrackerSetup() # # print 'calComplete' qFrom.put('calibrationComplete') if eyelink.isRecording( ) == 0: #stupid, I know, but eyelink.isRecording() returns 0 if it *is* indeed recording! eyeData = eyelink.getNextData() # if eyeData==pylink.SAMPLE_TYPE: # eyeSample = eyelink.getFloatData() # gaze = None # if eyeSample.isRightSample(): # gaze = eyeSample.getRightEye().getGaze() # elif eyeSample.isLeftSample(): # gaze = eyeSample.getLeftEye().getGaze() # if gaze!=None: # if gaze[0]!=-32768.0: # gazeDistFromGazeTarget = numpy.linalg.norm(numpy.array(gaze)-gazeTarget) # if newGazeTarget: # if gazeDistFromGazeTarget<gazeTargetCriterion: # # print ['gazeTargetMet',gaze,gazeTargetCriterion,gazeTarget,gazeDistFromGazeTarget] # qFrom.put(['gazeTargetMet',gazeTarget]) # newGazeTarget = False # else: # qFrom.put(['gazeTargetNotMet',gazeTarget]) # # print ['gazeTargetNotMet',gaze,gazeTarget,gazeDistFromGazeTarget,gazeTargetCriterion] if eyeData == pylink.ENDSACC: eyeSample = eyelink.getFloatData() gazeStartTime = eyeSample.getStartTime() gazeStart = eyeSample.getStartGaze() gazeEnd = eyeSample.getEndGaze() # # print ['eyelink: saccade',gazeStart,gazeEnd] if (gazeStart[0] != -32768.0) & (gazeEnd[0] != -32768.0): gazeDistFromGazeTarget = numpy.linalg.norm( numpy.array(gazeEnd) - gazeTarget) if gazeDistFromGazeTarget < 1000: if newGazeTarget: # # print [gazeDistFromGazeTarget,gazeTargetCriterion,gazeTarget,gazeEnd] if gazeDistFromGazeTarget < gazeTargetCriterion: # # print ['gazeTargetMet',gazeEnd,gazeTargetCriterion,gazeTarget,gazeDistFromGazeTarget] qFrom.put([ 'gazeTargetMet', gazeTarget, gazeStartTime ]) newGazeTarget = False # # print 'gazeTargetMet' elif gazeDistFromGazeTarget > gazeTargetCriterion: if reportSaccades: qFrom.put(['gazeTargetLost', gazeTarget]) # # print ['gazeTargetLost',gazeTarget] if (not saccadeSound.stillPlaying()) and ( not blinkSound.stillPlaying()): if doSounds: saccadeSound.play() elif eyeData == pylink.STARTBLINK: # lastStartBlinkTime = time.time() # elif eyeData==pylink.ENDBLINK: # if (time.time()-lastStartBlinkTime)>.1: if reportBlinks: qFrom.put('blink') # # print 'eyelink: blink' if (not saccadeSound.stillPlaying()) and ( not blinkSound.stillPlaying()): if doSounds: #blinkSound.play() qFrom.put('blink')
def __init__(self, app, title, view, width=640, height=480, resize=True, border=True, pack=False): self.app = app self.pack = pack self.needs_layout = True self.needs_render = True flags = sdl2.SDL_WINDOW_ALLOW_HIGHDPI if resize: flags |= sdl2.SDL_WINDOW_RESIZABLE if not border: flags |= sdl2.SDL_WINDOW_BORDERLESS self.win = sdl2.SDL_CreateWindow( title.encode("utf-8"), sdl2.SDL_WINDOWPOS_CENTERED, sdl2.SDL_WINDOWPOS_CENTERED, int(width * app.win_scale), int(height * app.win_scale), flags, ) self.id = sdl2.SDL_GetWindowID(self.win) self.renderer = sdl2.SDL_CreateRenderer(self.win, -1, sdl2.SDL_RENDERER_ACCELERATED) self.view = view self.view._window = self self.view.env.theme.prepare(self.renderer) self.hover = None self.menu = None self.background = self.view.env.theme.config["background"] # self.view.dump() # Which view is currently tracking mouse events (i.e. was clicked but not released yet) self.tracking = None # Which view has keyboard focus. self.focus = None # List of running animations. self.animations = [] # Listen for events self.app.listen(sdl2.SDL_MOUSEBUTTONDOWN, "button", self.mousedown, check=self.check_window) self.app.listen(sdl2.SDL_MOUSEBUTTONUP, "button", self.mouseup) self.app.listen(sdl2.SDL_MOUSEMOTION, "motion", self.mousemotion, check=self.check_window) self.app.listen(sdl2.SDL_MOUSEWHEEL, "wheel", self.mousewheel, check=self.check_window) self.app.listen(sdl2.SDL_WINDOWEVENT, "window", self.window_event, check=self.check_window) self.app.listen(sdl2.SDL_KEYDOWN, "key", self.key_event, check=self.check_window) self.app.listen(sdl2.SDL_KEYUP, "key", self.key_event, check=self.check_window) self.app.listen(sdl2.SDL_TEXTINPUT, "text", self.text_event, check=self.check_window)
def stamperChildFunction(qTo, qFrom, windowSize=[200, 200], windowPosition=[0, 0], windowColor=[255, 255, 255], doBorder=True): import sdl2 import sdl2.ext import sys import time try: import appnope appnope.nope() except: pass sdl2.SDL_Init(sdl2.SDL_INIT_TIMER) timeFreq = 1.0 / sdl2.SDL_GetPerformanceFrequency() sdl2.SDL_Init(sdl2.SDL_INIT_VIDEO) if doBorder: flags = sdl2.SDL_WINDOW_SHOWN else: flags = sdl2.SDL_WINDOW_BORDERLESS | sdl2.SDL_WINDOW_SHOWN window = sdl2.ext.Window("pyStamper", size=windowSize, position=windowPosition, flags=flags) windowID = sdl2.SDL_GetWindowID(window.window) windowSurf = sdl2.SDL_GetWindowSurface(window.window) red = sdl2.pixels.SDL_Color(r=255, g=0, b=0, a=255) green = sdl2.pixels.SDL_Color(r=0, g=255, b=0, a=255) black = sdl2.pixels.SDL_Color(r=0, g=0, b=0, a=255) white = sdl2.pixels.SDL_Color(r=255, g=255, b=255, a=255) if doBorder: sdl2.ext.fill(windowSurf.contents, green) else: sdl2.ext.fill( windowSurf.contents, sdl2.pixels.SDL_Color(r=windowColor[0], g=windowColor[1], b=windowColor[2], a=255)) window.refresh() for i in range(10): sdl2.SDL_PumpEvents() #to show the windows sdl2.SDL_Init( sdl2.SDL_INIT_JOYSTICK) #uncomment if you want joystick input sdl2.SDL_JoystickOpen(0) #uncomment if you want joystick input lostFocus = True lostColors = [red, black, red, white] lastRefreshTime = time.time() while True: if lostFocus and doBorder: if time.time() > (lastRefreshTime + (2.0 / 60)): sdl2.ext.fill(windowSurf.contents, lostColors[0]) window.refresh() lostColors.append(lostColors.pop(0)) lastRefreshTime = time.time() sdl2.SDL_PumpEvents() if not qTo.empty(): message = qTo.get() if message == 'quit': sys.exit() elif message == 'raise': sdl2.SDL_RaiseWindow(window.window) for event in sdl2.ext.get_events(): if event.type == sdl2.SDL_WINDOWEVENT: if event.window.windowID == windowID: if (event.window.event == sdl2.SDL_WINDOWEVENT_CLOSE): qFrom.put({ 'type': 'key', 'time': event.window.timestamp * timeFreq, 'value': 'escape' }) sys.exit() elif event.window.event == sdl2.SDL_WINDOWEVENT_FOCUS_LOST: lostFocus = True elif event.window.event == sdl2.SDL_WINDOWEVENT_FOCUS_GAINED: lostFocus = False if doBorder: sdl2.ext.fill(windowSurf.contents, green) window.refresh() else: message = {} if event.type == sdl2.SDL_KEYDOWN: message['type'] = 'key' message['time'] = event.key.timestamp * timeFreq message['value'] = sdl2.SDL_GetKeyName( event.key.keysym.sym).lower() message['keysym'] = event.key.keysym qFrom.put(message) elif event.type == sdl2.SDL_JOYAXISMOTION: message['type'] = 'axis' message['axis'] = event.jaxis.axis message['time'] = event.jaxis.timestamp * timeFreq message['value'] = event.jaxis.value qFrom.put(message) elif event.type == sdl2.SDL_JOYBUTTONDOWN: message['type'] = 'button' message['time'] = event.jbutton.timestamp * timeFreq message['value'] = event.jbutton.button qFrom.put(message)