class TransitionFactoryTest(EntertainerTest): '''Test for entertainerlib.gui.transitions.factory''' def setUp(self): '''Set up the test''' EntertainerTest.setUp(self) # Not testing the callback because it is used by the transitions only # so just provide None self.factory = TransitionFactory(None) def tearDown(self): '''Clean up after the test''' EntertainerTest.tearDown(self) def test_create(self): '''Test correct TransitionFactory initialization''' self.assertTrue(isinstance(self.factory, TransitionFactory)) def test__generate_slide(self): '''Test _generate_slide returns a Slide transition''' transition = self.factory._generate_slide() self.assertTrue(isinstance(transition, Slide)) def test__generate_no_effect(self): '''Test _generate_no_effect returns a NoEffect transition''' transition = self.factory._generate_no_effect() self.assertTrue(isinstance(transition, NoEffect)) def test__generate_fade(self): '''Test _generate_fade returns a Fade transition''' transition = self.factory._generate_fade() self.assertTrue(isinstance(transition, Fade)) def test__generate_zoom_and_fade(self): '''Test _generate_zoom_and_fade returns a ZoomAndFade transition''' transition = self.factory._generate_zoom_and_fade() self.assertTrue(isinstance(transition, ZoomAndFade)) def test_generate_transition(self): '''Test that generate_transition returns all the proper types''' values_to_test = { 'Crossfade' : Fade, 'No effect' : NoEffect, 'Slide' : Slide, 'Zoom and fade' : ZoomAndFade } # Test all possible transitions for key in values_to_test.keys(): self.config.write_content_value('General', 'transition_effect', key) self.config.update_configuration() transition = self.factory.generate_transition() self.assertTrue(isinstance(transition, values_to_test[key])) # Test the path when the user doesn't have effects self.config.write_content_value('General', 'show_effects', 'False') self.config.update_configuration() transition = self.factory.generate_transition() self.assertTrue(isinstance(transition, NoEffect))
class TransitionFactoryTest(EntertainerTest): '''Test for entertainerlib.gui.transitions.factory''' def setUp(self): '''Set up the test''' EntertainerTest.setUp(self) # Not testing the callback because it is used by the transitions only # so just provide None self.factory = TransitionFactory(None) def tearDown(self): '''Clean up after the test''' EntertainerTest.tearDown(self) def test_create(self): '''Test correct TransitionFactory initialization''' self.assertTrue(isinstance(self.factory, TransitionFactory)) def test__generate_slide(self): '''Test _generate_slide returns a Slide transition''' transition = self.factory._generate_slide() self.assertTrue(isinstance(transition, Slide)) def test__generate_no_effect(self): '''Test _generate_no_effect returns a NoEffect transition''' transition = self.factory._generate_no_effect() self.assertTrue(isinstance(transition, NoEffect)) def test__generate_fade(self): '''Test _generate_fade returns a Fade transition''' transition = self.factory._generate_fade() self.assertTrue(isinstance(transition, Fade)) def test__generate_zoom_and_fade(self): '''Test _generate_zoom_and_fade returns a ZoomAndFade transition''' transition = self.factory._generate_zoom_and_fade() self.assertTrue(isinstance(transition, ZoomAndFade)) def test_generate_transition(self): '''Test that generate_transition returns all the proper types''' values_to_test = { 'Crossfade': Fade, 'No effect': NoEffect, 'Slide': Slide, 'Zoom and fade': ZoomAndFade } # Test all possible transitions for key in values_to_test.keys(): self.config.write_content_value('General', 'transition_effect', key) self.config.update_configuration() transition = self.factory.generate_transition() self.assertTrue(isinstance(transition, values_to_test[key])) # Test the path when the user doesn't have effects self.config.write_content_value('General', 'show_effects', 'False') self.config.update_configuration() transition = self.factory.generate_transition() self.assertTrue(isinstance(transition, NoEffect))
def __init__(self, image_library, music_library, video_library, quit_client_callback): self.quit_client_callback = quit_client_callback self.config = Configuration() # Store the dimensions in case users want to return to window mode self.old_width = self.config.stage_width self.old_height = self.config.stage_height self.logger = Logger().getLogger("client.gui.UserInterface") self.window = gtk.Window() self.window.connect("destroy", self.destroy_callback) self.window.set_title("Entertainer") # Set the window icon icon_theme = gtk.icon_theme_get_default() try: icon = icon_theme.load_icon("entertainer", 48, 0) self.window.set_icon(icon) except gobject.GError: # Must not be installed from a package, get icon from the branch file_dir = os.path.dirname(__file__) icon_path = os.path.join(file_dir, "..", "..", "icons", "hicolor", "48x48", "apps", "entertainer.png") icon = gtk.gdk.pixbuf_new_from_file(icon_path) self.window.set_icon(icon) # cluttergtk.Embed contains the stage that is the canvas for the GUI embed = cluttergtk.Embed() # Enforce a minimum size to prevent weird widget bugs embed.set_size_request(self.config.stage_width, self.config.stage_height) self.window.add(embed) # The embed widget must be realized before you can get the stage. embed.realize() self.stage = embed.get_stage() self._hide_cursor_timeout_key = None self.stage.connect("key-press-event", self.handle_keyboard_event) self.stage.connect("motion-event", self._handle_motion_event) self.stage.set_color(self.config.theme.get_color("background")) self.stage.set_size(self.config.stage_width, self.config.stage_height) self.stage.set_title("Entertainer") if self.config.start_in_fullscreen: self._fullscreen() self.is_fullscreen = True else: self.is_fullscreen = False # Initialize Screen history (allows user to navigate "back") self.history = ScreenHistory(self._remove_from_stage) self.player = MediaPlayer(self.stage, self.config.stage_width, self.config.stage_height) self.player.connect("volume-changed", self._on_volume_changed) # Initialize menu overlay texture self.is_overlay = False self.menu_overlay = MenuOverlay(self.config.theme) self.menu_overlay.set_opacity(0) self.menu_overlay.set_size(self.config.stage_width, self.config.stage_height) self.stage.add(self.menu_overlay) self.volume_indicator = VolumeIndicator() self.stage.add(self.volume_indicator) self.volume_indicator.connect("hiding", self._on_volume_indicator_hiding) self.fade_screen_timeline = clutter.Timeline(200) alpha = clutter.Alpha(self.fade_screen_timeline, clutter.EASE_IN_OUT_SINE) self.fade_screen_behaviour = clutter.BehaviourOpacity(255, 0, alpha) # Transition object. Handles effects between screen changes. transition_factory = TransitionFactory(self._remove_from_stage) self.transition = transition_factory.generate_transition() # Screen factory to create new screens self.screen_factory = ScreenFactory( image_library, music_library, video_library, self.player, self.move_to_new_screen, self.move_to_previous_screen, ) def default_key_to_user_event(): """Return the default user event provided by an unmapped keyboard event.""" return UserEvent.DEFAULT_EVENT # Dictionary for keyboard event handling self.key_to_user_event = defaultdict( default_key_to_user_event, { clutter.keysyms.Return: UserEvent.NAVIGATE_SELECT, clutter.keysyms.Up: UserEvent.NAVIGATE_UP, clutter.keysyms.Down: UserEvent.NAVIGATE_DOWN, clutter.keysyms.Left: UserEvent.NAVIGATE_LEFT, clutter.keysyms.Right: UserEvent.NAVIGATE_RIGHT, clutter.keysyms.BackSpace: UserEvent.NAVIGATE_BACK, clutter.keysyms.h: UserEvent.NAVIGATE_HOME, clutter.keysyms.w: UserEvent.NAVIGATE_FIRST_PAGE, clutter.keysyms.e: UserEvent.NAVIGATE_PREVIOUS_PAGE, clutter.keysyms.r: UserEvent.NAVIGATE_NEXT_PAGE, clutter.keysyms.t: UserEvent.NAVIGATE_LAST_PAGE, clutter.keysyms.f: UserEvent.TOGGLE_FULLSCREEN, clutter.keysyms.p: UserEvent.PLAYER_PLAY_PAUSE, clutter.keysyms.s: UserEvent.PLAYER_STOP, clutter.keysyms._1: UserEvent.USE_ASPECT_RATIO_1, clutter.keysyms._2: UserEvent.USE_ASPECT_RATIO_2, clutter.keysyms._3: UserEvent.USE_ASPECT_RATIO_3, clutter.keysyms._4: UserEvent.USE_ASPECT_RATIO_4, clutter.keysyms.x: UserEvent.PLAYER_SKIP_BACKWARD, clutter.keysyms.c: UserEvent.PLAYER_SKIP_FORWARD, clutter.keysyms.z: UserEvent.PLAYER_PREVIOUS, clutter.keysyms.v: UserEvent.PLAYER_NEXT, clutter.keysyms.m: UserEvent.PLAYER_VOLUME_UP, clutter.keysyms.l: UserEvent.PLAYER_VOLUME_DOWN, clutter.keysyms.q: UserEvent.QUIT, clutter.keysyms.Escape: UserEvent.QUIT, }, ) self.event_handlers = { UserEvent.DEFAULT_EVENT: self._handle_default, UserEvent.NAVIGATE_SELECT: self._handle_default, UserEvent.NAVIGATE_UP: self._handle_default, UserEvent.NAVIGATE_DOWN: self._handle_default, UserEvent.NAVIGATE_LEFT: self._handle_default, UserEvent.NAVIGATE_RIGHT: self._handle_default, UserEvent.NAVIGATE_BACK: self._handle_navigate_back, UserEvent.NAVIGATE_HOME: self._handle_navigate_home, UserEvent.NAVIGATE_FIRST_PAGE: self._handle_default, UserEvent.NAVIGATE_PREVIOUS_PAGE: self._handle_default, UserEvent.NAVIGATE_NEXT_PAGE: self._handle_default, UserEvent.NAVIGATE_LAST_PAGE: self._handle_default, UserEvent.TOGGLE_FULLSCREEN: self._handle_toggle_fullscreen, UserEvent.PLAYER_PLAY_PAUSE: self._handle_player_play_pause, UserEvent.PLAYER_STOP: self._handle_player_stop, UserEvent.USE_ASPECT_RATIO_1: self._handle_aspect_ratio, UserEvent.USE_ASPECT_RATIO_2: self._handle_aspect_ratio, UserEvent.USE_ASPECT_RATIO_3: self._handle_aspect_ratio, UserEvent.USE_ASPECT_RATIO_4: self._handle_aspect_ratio, UserEvent.PLAYER_SKIP_BACKWARD: self._handle_player_skip_backward, UserEvent.PLAYER_SKIP_FORWARD: self._handle_player_skip_forward, UserEvent.PLAYER_PREVIOUS: self._handle_player_previous, UserEvent.PLAYER_NEXT: self._handle_player_next, UserEvent.PLAYER_VOLUME_UP: self._handle_player_volume_up, UserEvent.PLAYER_VOLUME_DOWN: self._handle_player_volume_down, UserEvent.QUIT: self._handle_quit_client, } self.logger.debug("Frontend GUI initialized succesfully")
def __init__(self, image_library, music_library, video_library, quit_client_callback): self.quit_client_callback = quit_client_callback self.config = Configuration() # Store the dimensions in case users want to return to window mode self.old_width = self.config.stage_width self.old_height = self.config.stage_height self.logger = Logger().getLogger('client.gui.UserInterface') self.window = gtk.Window() self.window.connect('destroy', self.destroy_callback) self.window.set_title('Entertainer') # Set the window icon icon_theme = gtk.icon_theme_get_default() try: icon = icon_theme.load_icon('entertainer', 48, 0) self.window.set_icon(icon) except gobject.GError: # Must not be installed from a package, get icon from the branch file_dir = os.path.dirname(__file__) icon_path = os.path.join(file_dir, '..', '..', 'icons', 'hicolor', '48x48', 'apps', 'entertainer.png') icon = gtk.gdk.pixbuf_new_from_file(icon_path) self.window.set_icon(icon) # cluttergtk.Embed contains the stage that is the canvas for the GUI embed = cluttergtk.Embed() # Enforce a minimum size to prevent weird widget bugs embed.set_size_request( self.config.stage_width, self.config.stage_height) self.window.add(embed) # The embed widget must be realized before you can get the stage. embed.realize() self.stage = embed.get_stage() self._hide_cursor_timeout_key = None self.stage.connect('key-press-event', self.handle_keyboard_event) self.stage.connect('motion-event', self._handle_motion_event) self.stage.set_color(self.config.theme.get_color("background")) self.stage.set_size(self.config.stage_width, self.config.stage_height) self.stage.set_title("Entertainer") if self.config.start_in_fullscreen: self._fullscreen() self.is_fullscreen = True else: self.is_fullscreen = False # Initialize Screen history (allows user to navigate "back") self.history = ScreenHistory(self._remove_from_stage) self.player = MediaPlayer(self.stage, self.config.stage_width, self.config.stage_height) self.player.connect('volume-changed', self._on_volume_changed) # Initialize menu overlay texture self.is_overlay = False self.menu_overlay = MenuOverlay(self.config.theme) self.menu_overlay.set_opacity(0) self.menu_overlay.set_size( self.config.stage_width, self.config.stage_height) self.stage.add(self.menu_overlay) self.volume_indicator = VolumeIndicator() self.stage.add(self.volume_indicator) self.volume_indicator.connect('hiding', self._on_volume_indicator_hiding) self.fade_screen_timeline = clutter.Timeline(200) alpha = clutter.Alpha(self.fade_screen_timeline, clutter.EASE_IN_OUT_SINE) self.fade_screen_behaviour = clutter.BehaviourOpacity(255, 0, alpha) # Transition object. Handles effects between screen changes. transition_factory = TransitionFactory(self._remove_from_stage) self.transition = transition_factory.generate_transition() # Screen factory to create new screens self.screen_factory = ScreenFactory( image_library, music_library, video_library, self.player, self.move_to_new_screen, self.move_to_previous_screen) def default_key_to_user_event(): '''Return the default user event provided by an unmapped keyboard event.''' return UserEvent.DEFAULT_EVENT # Dictionary for keyboard event handling self.key_to_user_event = defaultdict(default_key_to_user_event, { clutter.keysyms.Return : UserEvent.NAVIGATE_SELECT, clutter.keysyms.Up : UserEvent.NAVIGATE_UP, clutter.keysyms.Down : UserEvent.NAVIGATE_DOWN, clutter.keysyms.Left : UserEvent.NAVIGATE_LEFT, clutter.keysyms.Right : UserEvent.NAVIGATE_RIGHT, clutter.keysyms.BackSpace : UserEvent.NAVIGATE_BACK, clutter.keysyms.h : UserEvent.NAVIGATE_HOME, clutter.keysyms.w : UserEvent.NAVIGATE_FIRST_PAGE, clutter.keysyms.e : UserEvent.NAVIGATE_PREVIOUS_PAGE, clutter.keysyms.r : UserEvent.NAVIGATE_NEXT_PAGE, clutter.keysyms.t : UserEvent.NAVIGATE_LAST_PAGE, clutter.keysyms.f : UserEvent.TOGGLE_FULLSCREEN, clutter.keysyms.p : UserEvent.PLAYER_PLAY_PAUSE, clutter.keysyms.s : UserEvent.PLAYER_STOP, clutter.keysyms._1 : UserEvent.USE_ASPECT_RATIO_1, clutter.keysyms._2 : UserEvent.USE_ASPECT_RATIO_2, clutter.keysyms._3 : UserEvent.USE_ASPECT_RATIO_3, clutter.keysyms._4 : UserEvent.USE_ASPECT_RATIO_4, clutter.keysyms.x : UserEvent.PLAYER_SKIP_BACKWARD, clutter.keysyms.c : UserEvent.PLAYER_SKIP_FORWARD, clutter.keysyms.z : UserEvent.PLAYER_PREVIOUS, clutter.keysyms.v : UserEvent.PLAYER_NEXT, clutter.keysyms.m : UserEvent.PLAYER_VOLUME_UP, clutter.keysyms.l : UserEvent.PLAYER_VOLUME_DOWN, clutter.keysyms.q : UserEvent.QUIT, clutter.keysyms.Escape : UserEvent.QUIT }) self.event_handlers = { UserEvent.DEFAULT_EVENT : self._handle_default, UserEvent.NAVIGATE_SELECT : self._handle_default, UserEvent.NAVIGATE_UP : self._handle_default, UserEvent.NAVIGATE_DOWN : self._handle_default, UserEvent.NAVIGATE_LEFT : self._handle_default, UserEvent.NAVIGATE_RIGHT : self._handle_default, UserEvent.NAVIGATE_BACK : self._handle_navigate_back, UserEvent.NAVIGATE_HOME : self._handle_navigate_home, UserEvent.NAVIGATE_FIRST_PAGE : self._handle_default, UserEvent.NAVIGATE_PREVIOUS_PAGE : self._handle_default, UserEvent.NAVIGATE_NEXT_PAGE : self._handle_default, UserEvent.NAVIGATE_LAST_PAGE : self._handle_default, UserEvent.TOGGLE_FULLSCREEN : self._handle_toggle_fullscreen, UserEvent.PLAYER_PLAY_PAUSE : self._handle_player_play_pause, UserEvent.PLAYER_STOP : self._handle_player_stop, UserEvent.USE_ASPECT_RATIO_1 : self._handle_aspect_ratio, UserEvent.USE_ASPECT_RATIO_2 : self._handle_aspect_ratio, UserEvent.USE_ASPECT_RATIO_3 : self._handle_aspect_ratio, UserEvent.USE_ASPECT_RATIO_4 : self._handle_aspect_ratio, UserEvent.PLAYER_SKIP_BACKWARD : self._handle_player_skip_backward, UserEvent.PLAYER_SKIP_FORWARD : self._handle_player_skip_forward, UserEvent.PLAYER_PREVIOUS : self._handle_player_previous, UserEvent.PLAYER_NEXT : self._handle_player_next, UserEvent.PLAYER_VOLUME_UP : self._handle_player_volume_up, UserEvent.PLAYER_VOLUME_DOWN : self._handle_player_volume_down, UserEvent.QUIT : self._handle_quit_client } self.logger.debug("Frontend GUI initialized succesfully")