#!/usr/bin/env python # ---------------------------------------------------------------------------- # pyglet # Copyright (c) 2006-2008 Alex Holkner # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # * Neither the name of pyglet nor the names of its # contributors may be used to endorse or promote products # derived from this software without specific prior written # permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS # FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE # COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. # ---------------------------------------------------------------------------- # [note: this is a modified portion of the pyglet example file media_player.py.] import sys from pyglet.gl import * import pyglet from pyglet.window import key from pyglet.event import EVENT_HANDLED def draw_rect(x, y, width, height): glBegin(GL_LINE_LOOP) glVertex2f(x, y) glVertex2f(x + width, y) glVertex2f(x + width, y + height) glVertex2f(x, y + height) glEnd() class Control(pyglet.event.EventDispatcher): x = y = 0 width = height = 10 relative = False ### bruce change event_types = list(pyglet.window.Window.event_types) # kluge? [bruce addition] def __init__(self, parent): super(Control, self).__init__() self.parent = parent def hit_test(self, x, y): return (self.x < x < self.x + self.width and self.y < y < self.y + self.height) def capture_events(self): pass ## self.parent.push_handlers(self) def release_events(self): pass ## self.parent.remove_handlers(self) class Button(Control): charged = False def draw(self): if self.charged: # i.e. running something [bks cmt] glColor3f(1, 0, 0) else: ## glColor3f(1, 1, 1) #bks, maybe not needed glColor3f(0, 0, 0) draw_rect(self.x, self.y, self.width, self.height) ## glColor3f(1, 1, 1) glColor3f(0, 0, 0) self.draw_label() def on_mouse_press(self, x, y, button, modifiers): self.capture_events() self.charged = True return EVENT_HANDLED #bruce def on_mouse_drag(self, x, y, dx, dy, buttons, modifiers): self.charged = self.hit_test(x, y) return EVENT_HANDLED #bruce def on_mouse_release(self, x, y, button, modifiers): self.release_events() if self.hit_test(x, y): self.dispatch_event('on_press') self.charged = False return EVENT_HANDLED #bruce Button.register_event_type('on_press') class TextButton(Button): def __init__(self, *args, **kwargs): super(TextButton, self).__init__(*args, **kwargs) self._text = pyglet.text.Label('', anchor_x = 'center', anchor_y = 'center', color = (0, 0, 0, 255) #bruce -- note that 255 is required, 1 doesn't work ) def draw_label(self): self._text.x = self.x + self.width / 2 self._text.y = self.y + self.height / 2 ## glColor3f(0, 0, 0) ### should not be needed; doesn't work anyway -- aha, Label has a color option [bruce] self._text.draw() def set_text(self, text): self._text.text = text text = property(lambda self: self._text.text, set_text) class Slider(Control): # not yet ported to this context THUMB_WIDTH = 6 THUMB_HEIGHT = 10 GROOVE_HEIGHT = 2 min = 0. # bks max = 100. # bks value = 50. #bks def draw(self): center_y = self.y + self.height / 2 draw_rect(self.x, center_y - self.GROOVE_HEIGHT / 2, self.width, self.GROOVE_HEIGHT) pos = self.x + self.value * self.width / (self.max - self.min) draw_rect(pos - self.THUMB_WIDTH / 2, center_y - self.THUMB_HEIGHT / 2, self.THUMB_WIDTH, self.THUMB_HEIGHT) def coordinate_to_value(self, x): return float(x - self.x) / self.width * (self.max - self.min) + self.min def on_mouse_press(self, x, y, button, modifiers): value = self.coordinate_to_value(x) self.capture_events() self.dispatch_event('on_begin_scroll') self.dispatch_event('on_change', value) return EVENT_HANDLED #bruce def on_mouse_drag(self, x, y, dx, dy, buttons, modifiers): value = min(max(self.coordinate_to_value(x), self.min), self.max) self.dispatch_event('on_change', value) return EVENT_HANDLED #bruce def on_mouse_release(self, x, y, button, modifiers): self.release_events() self.dispatch_event('on_end_scroll') return EVENT_HANDLED #bruce def on_change(self, value): #bks self.value = value return EVENT_HANDLED #bruce Slider.register_event_type('on_begin_scroll') Slider.register_event_type('on_end_scroll') Slider.register_event_type('on_change') # == test code (modified from the rest of the pyglet example, media_player.py) class PlayerWindow(pyglet.window.Window): GUI_WIDTH = 400 GUI_HEIGHT = 40 GUI_PADDING = 4 GUI_BUTTON_HEIGHT = 16 def __init__(self, player): super(PlayerWindow, self).__init__(caption = 'test controls', visible = False, resizable = True) self.player = player self.slider = Slider(self) self.slider.x = self.GUI_PADDING self.slider.y = self.GUI_PADDING * 2 + self.GUI_BUTTON_HEIGHT ## self.slider.on_begin_scroll = lambda: player.pause() ## self.slider.on_end_scroll = lambda: player.play() ## self.slider.on_change = lambda value: player.seek(value) self.play_pause_button = TextButton(self) self.play_pause_button.x = self.GUI_PADDING self.play_pause_button.y = self.GUI_PADDING self.play_pause_button.height = self.GUI_BUTTON_HEIGHT self.play_pause_button.width = 45 self.play_pause_button.on_press = self.on_play_pause win = self self.window_button = TextButton(self) self.window_button.x = self.play_pause_button.x + \ self.play_pause_button.width + self.GUI_PADDING self.window_button.y = self.GUI_PADDING self.window_button.height = self.GUI_BUTTON_HEIGHT self.window_button.width = 90 self.window_button.text = 'Windowed' self.window_button.on_press = lambda: win.set_fullscreen(False) self.controls = [ self.slider, self.play_pause_button, self.window_button, ] x = self.window_button.x + self.window_button.width + self.GUI_PADDING i = 0 for screen in self.display.get_screens(): screen_button = TextButton(self) screen_button.x = x screen_button.y = self.GUI_PADDING screen_button.height = self.GUI_BUTTON_HEIGHT screen_button.width = 80 screen_button.text = 'Screen %d' % (i + 1) screen_button.on_press = \ (lambda s: lambda: win.set_fullscreen(True, screen = s))(screen) self.controls.append(screen_button) i += 1 x += screen_button.width + self.GUI_PADDING def gui_update_state(self): if self.player.playing: self.play_pause_button.text = 'Pause' else: self.play_pause_button.text = 'Play' def set_default_video_size(self): '''Make the window size just big enough to show the current video and the GUI.''' width = self.GUI_WIDTH height = self.GUI_HEIGHT video_width, video_height = self.get_video_size() width = max(width, video_width) height += video_height self.set_size(int(width), int(height)) def on_resize(self, width, height): '''Position and size video image.''' super(PlayerWindow, self).on_resize(width, height) self.slider.width = width - self.GUI_PADDING * 2 height -= self.GUI_HEIGHT if height <= 0: return video_width, video_height = self.get_video_size() if video_width == 0 or video_height == 0: return display_aspect = width / float(height) video_aspect = video_width / float(video_height) if video_aspect > display_aspect: self.video_width = width self.video_height = width / video_aspect else: self.video_height = height self.video_width = height * video_aspect self.video_x = (width - self.video_width) / 2 self.video_y = (height - self.video_height) / 2 + self.GUI_HEIGHT def get_video_size(self): return 0, 0 def on_mouse_press(self, x, y, button, modifiers): for control in self.controls: if control.hit_test(x, y): control.on_mouse_press(x, y, button, modifiers) def on_key_press(self, symbol, modifiers): if symbol == key.SPACE: self.on_play_pause() elif symbol == key.ESCAPE: self.dispatch_event('on_close') def on_close(self): self.close() def on_play_pause(self): if self.player.playing: self.player.playing = False print "pause" else: self.player.playing = True print "play" self.gui_update_state() def on_draw(self): self.clear() ## self.slider.value = 17 ## self.player.time for control in self.controls: control.draw() def _test(): class _player(object): playing = False value = 50. def seek(self, value): self.value = value player = _player() ## pyglet.media.Player() window = PlayerWindow(player) window.gui_update_state() window.set_default_video_size() window.set_visible(True) window.gui_update_state() pyglet.app.run() if __name__ == '__main__': _test() # end