def __init__(self, ticks_ps, *args, **kwargs):
super(Window, self).__init__(*args, **kwargs)
self.ticks_per_second = ticks_ps
# Whether or not the window exclusively captures the mouse.
self.set_exclusive_mouse(False)
# This call schedules the `update()` method to be called
# ticks_per_second. This is the main game event loop.
pyglet.clock.schedule_interval(self.update, 1.0 / self.ticks_per_second)
config_loader = ConfigurationLoader()
self.config_data = config_loader.load_configuration_file()
# Create the game state manager and set the first state
self.gamestatemanager = GameStateManager()
# This should be changed when we implement the MAINMENU game state
gs_running = GameStateRunning(self.config_data, height=self.height, width=self.width)
self.gamestatemanager.push(gs_running)
python类window()的实例源码
def on_key_release(self, key, modifiers):
"""This function is called when a key is released.
'key' is a constant indicating which key was pressed.
'modifiers' is a bitwise or of several constants indicating which
modifiers are active at the time of the press (ctrl, shift, capslock, etc.)
Constants are the ones from pyglet.window.key
"""
char = pyglet.window.key.symbol_string(key)
if char in self.keys_pressed:
self.keys_pressed.remove(char)
mech = self.battle.getTurnUnit()
if char == "P":
mech.sprite.resume()
def set_size(self, width, height):
if self._fullscreen:
raise WindowException('Cannot set size of fullscreen window.')
self._width = max(1, int(width))
self._height = max(1, int(height))
# Move frame origin down so that top-left corner of window doesn't move.
window_frame = self._nswindow.frame()
rect = self._nswindow.contentRectForFrameRect_(window_frame)
rect.origin.y += rect.size.height - self._height
rect.size.width = self._width
rect.size.height = self._height
new_frame = self._nswindow.frameRectForContentRect_(rect)
# The window background flashes when the frame size changes unless it's
# animated, but we can set the window's animationResizeTime to zero.
is_visible = self._nswindow.isVisible()
self._nswindow.setFrame_display_animate_(new_frame, True, is_visible)
def set_mouse_position(self, x, y, absolute=False):
if absolute:
# If absolute, then x, y is given in global display coordinates
# which sets (0,0) at top left corner of main display. It is possible
# to warp the mouse position to a point inside of another display.
quartz.CGWarpMouseCursorPosition(CGPoint(x,y))
else:
# Window-relative coordinates: (x, y) are given in window coords
# with (0,0) at bottom-left corner of window and y up. We find
# which display the window is in and then convert x, y into local
# display coords where (0,0) is now top-left of display and y down.
screenInfo = self._nswindow.screen().deviceDescription()
displayID = screenInfo.objectForKey_(get_NSString('NSScreenNumber'))
displayID = displayID.intValue()
displayBounds = quartz.CGDisplayBounds(displayID)
frame = self._nswindow.frame()
windowOrigin = frame.origin
x += windowOrigin.x
y = displayBounds.size.height - windowOrigin.y - y
quartz.CGDisplayMoveCursorToPoint(displayID, NSPoint(x,y))
def set_exclusive_keyboard(self, exclusive=True):
# http://developer.apple.com/mac/library/technotes/tn2002/tn2062.html
# http://developer.apple.com/library/mac/#technotes/KioskMode/
# BUG: System keys like F9 or command-tab are disabled, however
# pyglet also does not receive key press events for them.
# This flag is queried by window delegate to determine whether
# the quit menu item is active.
self._is_keyboard_exclusive = exclusive
if exclusive:
# "Be nice! Don't disable force-quit!"
# -- Patrick Swayze, Road House (1989)
options = NSApplicationPresentationHideDock | \
NSApplicationPresentationHideMenuBar | \
NSApplicationPresentationDisableProcessSwitching | \
NSApplicationPresentationDisableHideApplication
else:
options = NSApplicationPresentationDefault
NSApp = NSApplication.sharedApplication()
NSApp.setPresentationOptions_(options)
def _recreate(self, changes):
# If flipping to/from fullscreen, need to recreate the window. (This
# is the case with both override_redirect method and
# _NET_WM_STATE_FULLSCREEN).
#
# A possible improvement could be to just hide the top window,
# destroy the GLX window, and reshow it again when leaving fullscreen.
# This would prevent the floating window from being moved by the
# WM.
if ('fullscreen' in changes or 'resizable' in changes):
# clear out the GLX context
self.context.detach()
xlib.XDestroyWindow(self._x_display, self._window)
del self.display._window_map[self._window]
del self.display._window_map[self._view]
self._window = None
self._mapped = False
# TODO: detect state loss only by examining context share.
if 'context' in changes:
self._lost_context = True
self._lost_context_state = True
self._create()
def _event_button(self, ev):
x = ev.xbutton.x
y = self.height - ev.xbutton.y
button = 1 << (ev.xbutton.button - 1) # 1, 2, 3 -> 1, 2, 4
modifiers = self._translate_modifiers(ev.xbutton.state)
if ev.type == xlib.ButtonPress:
# override_redirect issue: manually activate this window if
# fullscreen.
if self._override_redirect and not self._active:
self.activate()
if ev.xbutton.button == 4:
self.dispatch_event('on_mouse_scroll', x, y, 0, 1)
elif ev.xbutton.button == 5:
self.dispatch_event('on_mouse_scroll', x, y, 0, -1)
elif ev.xbutton.button < len(self._mouse_buttons):
self._mouse_buttons[ev.xbutton.button] = True
self.dispatch_event('on_mouse_press',
x, y, button, modifiers)
else:
if ev.xbutton.button < 4:
self._mouse_buttons[ev.xbutton.button] = False
self.dispatch_event('on_mouse_release',
x, y, button, modifiers)
def _create_track_region(self):
self._remove_track_region()
# Create a tracking region for the content part of the window
# to receive enter/leave events.
track_id = MouseTrackingRegionID()
track_id.signature = DEFAULT_CREATOR_CODE
track_id.id = 1
self._track_ref = MouseTrackingRef()
self._track_region = carbon.NewRgn()
if self._fullscreen:
carbon.SetRectRgn(self._track_region,
self._view_x, self._view_y,
self._view_x + self._width, self._view_y + self._height)
options = kMouseTrackingOptionsGlobalClip
else:
carbon.GetWindowRegion(self._window,
kWindowContentRgn, self._track_region)
options = kMouseTrackingOptionsGlobalClip
carbon.CreateMouseTrackingRegion(self._window,
self._track_region, None, options,
track_id, None, None,
byref(self._track_ref))
def _on_mouse_wheel_moved(self, next_handler, ev, data):
x, y = self._get_mouse_position(ev)
y = self.height - y
axis = EventMouseWheelAxis()
carbon.GetEventParameter(ev, kEventParamMouseWheelAxis,
typeMouseWheelAxis, c_void_p(), sizeof(axis), c_void_p(),
byref(axis))
delta = c_long()
carbon.GetEventParameter(ev, kEventParamMouseWheelDelta,
typeSInt32, c_void_p(), sizeof(delta), c_void_p(),
byref(delta))
if axis.value == kEventMouseWheelAxisX:
self.dispatch_event('on_mouse_scroll',
x, y, delta.value, 0)
else:
self.dispatch_event('on_mouse_scroll',
x, y, 0, delta.value)
# _Don't_ call the next handler, which is application, as this then
# calls our window handler again.
#carbon.CallNextEventHandler(next_handler, ev)
return noErr
def set_exclusive_mouse(self, exclusive=True):
if self._exclusive_mouse == exclusive and \
self._exclusive_mouse_focus == self._has_focus:
return
if exclusive and self._has_focus:
# Move mouse to the center of the window.
self._reset_exclusive_mouse_screen()
x, y = self._exclusive_mouse_screen
self.set_mouse_position(x, y, absolute=True)
# Clip to client area, to prevent large mouse movements taking
# it outside the client area.
rect = RECT()
_user32.GetClientRect(self._view_hwnd, byref(rect))
_user32.MapWindowPoints(self._view_hwnd, HWND_DESKTOP,
byref(rect), 2)
_user32.ClipCursor(byref(rect))
else:
# Release clip
_user32.ClipCursor(None)
self._exclusive_mouse = exclusive
self._exclusive_mouse_focus = self._has_focus
self.set_mouse_platform_visible()
def draw(self, x, y):
"""Abstract render method.
The cursor should be drawn with the "hot" spot at the given
coordinates. The projection is set to the pyglet default (i.e.,
orthographic in window-space), however no other aspects of the
state can be assumed.
:Parameters:
`x` : int
X coordinate of the mouse pointer's hot spot.
`y` : int
Y coordinate of the mouse pointer's hot spot.
"""
raise NotImplementedError('abstract')
def _PlatformEventHandler(data):
"""Decorator for platform event handlers.
Apply giving the platform-specific data needed by the window to associate
the method with an event. See platform-specific subclasses of this
decorator for examples.
The following attributes are set on the function, which is returned
otherwise unchanged:
_platform_event
True
_platform_event_data
List of data applied to the function (permitting multiple decorators
on the same method).
"""
def _event_wrapper(f):
f._platform_event = True
if not hasattr(f, '_platform_event_data'):
f._platform_event_data = []
f._platform_event_data.append(data)
return f
return _event_wrapper
def on_resize(self, width, height):
"""A default resize event handler.
This default handler updates the GL viewport to cover the entire
window and sets the ``GL_PROJECTION`` matrix to be orthogonal in
window space. The bottom-left corner is (0, 0) and the top-right
corner is the width and height of the window in pixels.
Override this event handler with your own to create another
projection, for example in perspective.
"""
# XXX avoid GLException by not allowing 0 width or height.
width = max(1, width)
height = max(1, height)
gl.glViewport(0, 0, width, height)
gl.glMatrixMode(gl.GL_PROJECTION)
gl.glLoadIdentity()
gl.glOrtho(0, width, 0, height, -1, 1)
gl.glMatrixMode(gl.GL_MODELVIEW)
def close(self):
"""Close the window.
After closing the window, the GL context will be invalid. The
window instance cannot be reused once closed (see also `set_visible`).
The `pyglet.app.EventLoop.on_window_close` event is dispatched on
`pyglet.app.event_loop` when this method is called.
"""
from pyglet import app
if not self._context:
return
app.windows.remove(self)
self._context.destroy()
self._config = None
self._context = None
if app.event_loop:
app.event_loop.dispatch_event('on_window_close', self)
def set_minimum_size(self, width, height):
"""Set the minimum size of the window.
Once set, the user will not be able to resize the window smaller
than the given dimensions. There is no way to remove the
minimum size constraint on a window (but you could set it to 0,0).
The behaviour is undefined if the minimum size is set larger than
the current size of the window.
The window size does not include the border or title bar.
:Parameters:
`width` : int
Minimum width of the window, in pixels.
`height` : int
Minimum height of the window, in pixels.
"""
raise NotImplementedError('abstract')
def set_maximum_size(self, width, height):
"""Set the maximum size of the window.
Once set, the user will not be able to resize the window larger
than the given dimensions. There is no way to remove the
maximum size constraint on a window (but you could set it to a large
value).
The behaviour is undefined if the maximum size is set smaller than
the current size of the window.
The window size does not include the border or title bar.
:Parameters:
`width` : int
Maximum width of the window, in pixels.
`height` : int
Maximum height of the window, in pixels.
"""
raise NotImplementedError('abstract')
def set_size(self, width, height):
"""Resize the window.
The behaviour is undefined if the window is not resizable, or if
it is currently fullscreen.
The window size does not include the border or title bar.
:Parameters:
`width` : int
New width of the window, in pixels.
`height` : int
New height of the window, in pixels.
"""
raise NotImplementedError('abstract')
def set_vsync(self, vsync):
"""Enable or disable vertical sync control.
When enabled, this option ensures flips from the back to the front
buffer are performed only during the vertical retrace period of the
primary display. This can prevent "tearing" or flickering when
the buffer is updated in the middle of a video scan.
Note that LCD monitors have an analogous time in which they are not
reading from the video buffer; while it does not correspond to
a vertical retrace it has the same effect.
With multi-monitor systems the secondary monitor cannot be
synchronised to, so tearing and flicker cannot be avoided when the
window is positioned outside of the primary display. In this case
it may be advisable to forcibly reduce the framerate (for example,
using `pyglet.clock.set_fps_limit`).
:Parameters:
`vsync` : bool
If True, vsync is enabled, otherwise it is disabled.
"""
raise NotImplementedError('abstract')
def set_exclusive_mouse(self, exclusive=True):
"""Hide the mouse cursor and direct all mouse events to this
window.
When enabled, this feature prevents the mouse leaving the window. It
is useful for certain styles of games that require complete control of
the mouse. The position of the mouse as reported in subsequent events
is meaningless when exclusive mouse is enabled; you should only use
the relative motion parameters ``dx`` and ``dy``.
:Parameters:
`exclusive` : bool
If True, exclusive mouse is enabled, otherwise it is disabled.
"""
raise NotImplementedError('abstract')
def set_exclusive_keyboard(self, exclusive=True):
"""Prevent the user from switching away from this window using
keyboard accelerators.
When enabled, this feature disables certain operating-system specific
key combinations such as Alt+Tab (Command+Tab on OS X). This can be
useful in certain kiosk applications, it should be avoided in general
applications or games.
:Parameters:
`exclusive` : bool
If True, exclusive keyboard is enabled, otherwise it is
disabled.
"""
raise NotImplementedError('abstract')
def on_mouse_drag(x, y, dx, dy, buttons, modifiers):
"""The mouse was moved with one or more mouse buttons pressed.
This event will continue to be fired even if the mouse leaves
the window, so long as the drag buttons are continuously held down.
:Parameters:
`x` : int
Distance in pixels from the left edge of the window.
`y` : int
Distance in pixels from the bottom edge of the window.
`dx` : int
Relative X position from the previous mouse position.
`dy` : int
Relative Y position from the previous mouse position.
`buttons` : int
Bitwise combination of the mouse buttons currently pressed.
`modifiers` : int
Bitwise combination of any keyboard modifiers currently
active.
:event:
"""
def on_mouse_release(x, y, button, modifiers):
"""A mouse button was released.
:Parameters:
`x` : int
Distance in pixels from the left edge of the window.
`y` : int
Distance in pixels from the bottom edge of the window.
`button` : int
The mouse button that was released.
`modifiers` : int
Bitwise combination of any keyboard modifiers currently
active.
:event:
"""
def on_mouse_scroll(x, y, scroll_x, scroll_y):
"""The mouse wheel was scrolled.
Note that most mice have only a vertical scroll wheel, so
`scroll_x` is usually 0. An exception to this is the Apple Mighty
Mouse, which has a mouse ball in place of the wheel which allows
both `scroll_x` and `scroll_y` movement.
:Parameters:
`x` : int
Distance in pixels from the left edge of the window.
`y` : int
Distance in pixels from the bottom edge of the window.
`scroll_x` : int
Number of "clicks" towards the right (left if negative).
`scroll_y` : int
Number of "clicks" upwards (downwards if negative).
:event:
"""
def on_draw():
"""The window contents must be redrawn.
The `EventLoop` will dispatch this event when the window
should be redrawn. This will happen during idle time after
any window events and after any scheduled functions were called.
The window will already have the GL context, so there is no
need to call `switch_to`. The window's `flip` method will
be called after this event, so your event handler should not.
You should make no assumptions about the window contents when
this event is triggered; a resize or expose event may have
invalidated the framebuffer since the last time it was drawn.
:since: pyglet 1.1
:event:
"""
def draw(self):
"""Draw the label.
The OpenGL state is assumed to be at default values, except
that the MODELVIEW and PROJECTION matrices are ignored. At
the return of this method the matrix mode will be MODELVIEW.
"""
gl.glMatrixMode(gl.GL_MODELVIEW)
gl.glPushMatrix()
gl.glLoadIdentity()
gl.glMatrixMode(gl.GL_PROJECTION)
gl.glPushMatrix()
gl.glLoadIdentity()
gl.glOrtho(0, self.window.width, 0, self.window.height, -1, 1)
self.label.draw()
gl.glPopMatrix()
gl.glMatrixMode(gl.GL_MODELVIEW)
gl.glPopMatrix()
def dump_window():
'''Dump display, window, screen and default config info.'''
import pyglet.window
platform = pyglet.window.get_platform()
print('platform:', repr(platform))
display = platform.get_default_display()
print('display:', repr(display))
screens = display.get_screens()
for i, screen in enumerate(screens):
print('screens[%d]: %r' % (i, screen))
window = pyglet.window.Window(visible=False)
for key, value in window.config.get_gl_attributes():
print("config['%s'] = %r" % (key, value))
print('context:', repr(window.context))
_heading('window.context._info')
dump_gl(window.context)
window.close()
def set_size(self, width, height):
if self._fullscreen:
raise WindowException('Cannot set size of fullscreen window.')
self._width = max(1, int(width))
self._height = max(1, int(height))
# Move frame origin down so that top-left corner of window doesn't move.
window_frame = self._nswindow.frame()
rect = self._nswindow.contentRectForFrameRect_(window_frame)
rect.origin.y += rect.size.height - self._height
rect.size.width = self._width
rect.size.height = self._height
new_frame = self._nswindow.frameRectForContentRect_(rect)
# The window background flashes when the frame size changes unless it's
# animated, but we can set the window's animationResizeTime to zero.
is_visible = self._nswindow.isVisible()
self._nswindow.setFrame_display_animate_(new_frame, True, is_visible)
def set_mouse_position(self, x, y, absolute=False):
if absolute:
# If absolute, then x, y is given in global display coordinates
# which sets (0,0) at top left corner of main display. It is possible
# to warp the mouse position to a point inside of another display.
quartz.CGWarpMouseCursorPosition(CGPoint(x,y))
else:
# Window-relative coordinates: (x, y) are given in window coords
# with (0,0) at bottom-left corner of window and y up. We find
# which display the window is in and then convert x, y into local
# display coords where (0,0) is now top-left of display and y down.
screenInfo = self._nswindow.screen().deviceDescription()
displayID = screenInfo.objectForKey_(get_NSString('NSScreenNumber'))
displayID = displayID.intValue()
displayBounds = quartz.CGDisplayBounds(displayID)
frame = self._nswindow.frame()
windowOrigin = frame.origin
x += windowOrigin.x
y = displayBounds.size.height - windowOrigin.y - y
quartz.CGDisplayMoveCursorToPoint(displayID, NSPoint(x,y))
def set_exclusive_keyboard(self, exclusive=True):
# http://developer.apple.com/mac/library/technotes/tn2002/tn2062.html
# http://developer.apple.com/library/mac/#technotes/KioskMode/
# BUG: System keys like F9 or command-tab are disabled, however
# pyglet also does not receive key press events for them.
# This flag is queried by window delegate to determine whether
# the quit menu item is active.
self._is_keyboard_exclusive = exclusive
if exclusive:
# "Be nice! Don't disable force-quit!"
# -- Patrick Swayze, Road House (1989)
options = NSApplicationPresentationHideDock | \
NSApplicationPresentationHideMenuBar | \
NSApplicationPresentationDisableProcessSwitching | \
NSApplicationPresentationDisableHideApplication
else:
options = NSApplicationPresentationDefault
NSApp = NSApplication.sharedApplication()
NSApp.setPresentationOptions_(options)
def _recreate(self, changes):
# If flipping to/from fullscreen, need to recreate the window. (This
# is the case with both override_redirect method and
# _NET_WM_STATE_FULLSCREEN).
#
# A possible improvement could be to just hide the top window,
# destroy the GLX window, and reshow it again when leaving fullscreen.
# This would prevent the floating window from being moved by the
# WM.
if ('fullscreen' in changes or 'resizable' in changes):
# clear out the GLX context
self.context.detach()
xlib.XDestroyWindow(self._x_display, self._window)
del self.display._window_map[self._window]
del self.display._window_map[self._view]
self._window = None
self._mapped = False
# TODO: detect state loss only by examining context share.
if 'context' in changes:
self._lost_context = True
self._lost_context_state = True
self._create()