import pygtk import gtk import pygst import gst import gobject import pango import clutter import os from modules.video_player.elements.CoverItem import cover_item from InputQueue import InputQueue class ImageRow(clutter.Group): DIRECTION_LEFT, DIRECTION_RIGHT = range(2) scaleFactor = 1.4 inactiveOpacity = 150 images_size_percent = 1 #0.90 #This is the percentage of the total group size that the covers will take fps = 25 frames = 15 def __init__(self, glossMgr, width, height, columns): clutter.Group.__init__(self) self.glossMgr = glossMgr self.stage = glossMgr.stage self.textureLibrary = [] self.images_group = clutter.Group() self.images_width = int(width * self.images_size_percent) self.images_height = int(height * self.images_size_percent) #Columns must be an odd number if (columns % 2) == 0: columns += 1 self.num_columns = columns self.image_size = int(self.images_width / self.num_columns) #A cover will be cover_size * cover_size (X * Y) self.center = int(columns / 2) + 1 """ #The viewer actually sits within another group that clips its size self.images_group_clip = clutter.Group() self.images_group_clip.add(self.images_group) #Nasty hack to get around centering problem pos_x = int(self.image_size/2) + (self.image_size * (self.center-1)) self.images_group.set_position(pos_x, int(self.image_size/2)) #And setup the clip size and position scale_amount = int(self.image_size * self.scaleFactor - self.image_size) clip_width = (self.image_size*columns) + scale_amount #Width is the cover size by the number of colums, plus the additional amount required for scaling clip_height = (height) + scale_amount self.images_group_clip.set_clip(-(scale_amount/2), -(scale_amount/2), clip_width, clip_height) """ pos_x = int(self.image_size/2) + (self.image_size * (self.center-1)) self.images_group.set_position(pos_x, int(self.image_size/2)) #self.current_video_details = video_details_group(self.covers_width) self.num_images = 0 self.image_gap = 1 #Setup input queue controller self.input_queue = InputQueue() self.input_queue.set_action(InputQueue.EAST, self.move_right) self.input_queue.set_action(InputQueue.WEST, self.move_left) #Setup the current min and max viewable rows self.min_visible_columns = 0 self.max_visible_columns = columns self.currentSelection = 0 #self.add(self.images_group_clip) self.add(self.images_group) covers_x = int(width * (1-self.images_size_percent)/2) covers_y = int(height * (1-self.images_size_percent)/2) #self.images_group.set_position(covers_x, covers_y) #self.images_group.set_depth(1) #self.image_size) self.images_group.show() #self.images_group_clip.show() def add_texture_group(self, tempGroup): tempGroup.set_opacity(self.inactiveOpacity) #tempGroup.set_position( (self.num_covers * self.image_size), 0) tempGroup.set_depth(1) self.textureLibrary.append(tempGroup) x = self.num_images * self.image_size + ( self.num_images * self.image_gap) y = 0#(self.cover_gap + self.image_size) * (self.num_covers/self.num_columns) tempGroup.set_position(x, y) #If we're past the maximum rows, make the pics invistible if self.num_images > (self.num_columns-self.center): tempGroup.set_opacity(0) tempGroup.hide() else: self.images_group.add(tempGroup) #Set the gravity to the center gap = (self.image_size - tempGroup.get_width())/2 anchor_x = (self.image_size - self.image_gap)/2 gap = (self.image_size - tempGroup.get_height())/2 anchor_y = (self.image_size - self.image_gap)/2 tempGroup.set_anchor_point(anchor_x, anchor_y) tempGroup.show() self.num_images += 1 def select_item(self, incomingItem, outgoingItem): self.timeline = clutter.Timeline(self.frames, self.fps) alpha = clutter.Alpha(self.timeline, clutter.smoothstep_inc_func) self.input_queue.set_timeline(self.timeline) outgoingTexture = self.textureLibrary[outgoingItem] incomingTexture = self.textureLibrary[incomingItem] #Do the stuff for edge cases (ie the textures coming in and going out) if incomingItem > outgoingItem: direction = self.DIRECTION_RIGHT edge_texture_incoming_no = outgoingItem + (self.center) edge_texture_outgoing_no = outgoingItem - (self.center-1) else: direction = self.DIRECTION_LEFT edge_texture_incoming_no = outgoingItem - (self.center) edge_texture_outgoing_no = outgoingItem + (self.center-1) if (edge_texture_incoming_no < len(self.textureLibrary)) and (edge_texture_incoming_no >= 0): edge_texture_incoming = self.textureLibrary[edge_texture_incoming_no] edge_texture_incoming.show() self.images_group.add(edge_texture_incoming) self.behaviourEdgeIncomingOpacity = clutter.BehaviourOpacity(opacity_start=0, opacity_end=self.inactiveOpacity, alpha=alpha) self.behaviourEdgeIncomingOpacity.apply(edge_texture_incoming) if edge_texture_outgoing_no >= 0: edge_texture_outgoing = self.textureLibrary[edge_texture_outgoing_no] self.timeline.connect('completed', self.remove_item, edge_texture_outgoing_no) self.behaviourEdgeOutgoingOpacity = clutter.BehaviourOpacity(opacity_start=self.inactiveOpacity, opacity_end=0, alpha=alpha) self.behaviourEdgeOutgoingOpacity.apply(edge_texture_outgoing) #Now do the stuff for selecting the image in the middle self.behaviourNew_scale = clutter.BehaviourScale(x_scale_start=1, y_scale_start=1, x_scale_end=self.scaleFactor, y_scale_end=self.scaleFactor, alpha=alpha) #clutter.GRAVITY_CENTER) self.behaviourNew_z = clutter.BehaviourDepth(depth_start=1, depth_end=2, alpha=alpha) self.behaviourNew_opacity = clutter.BehaviourOpacity(opacity_start=self.inactiveOpacity, opacity_end=255, alpha=alpha) self.behaviourOld_scale = clutter.BehaviourScale(x_scale_start=self.scaleFactor, y_scale_start=self.scaleFactor, x_scale_end=1, y_scale_end=1, alpha=alpha) self.behaviourOld_z = clutter.BehaviourDepth(depth_start=2, depth_end=1, alpha=alpha) self.behaviourOld_opacity = clutter.BehaviourOpacity(opacity_start=255, opacity_end=self.inactiveOpacity, alpha=alpha) self.behaviourNew_scale.apply(incomingTexture) self.behaviourNew_z.apply(incomingTexture) self.behaviourNew_opacity.apply(incomingTexture) self.behaviourOld_scale.apply(outgoingTexture) self.behaviourOld_z.apply(outgoingTexture) self.behaviourOld_opacity.apply(outgoingTexture) #And finally, moving the whole thing left/right (x, y) = self.images_group.get_position() if direction == self.DIRECTION_RIGHT: (new_x, new_y) = ( (x-(self.image_size+self.image_gap)), y) else: (new_x, new_y) = ( (x+(self.image_size+self.image_gap)), y) knots = (\ (x, y),\ (new_x, new_y)\ ) self.behaviour_path = clutter.BehaviourPath(alpha, knots) self.behaviour_path.apply(self.images_group) self.currentSelection = incomingItem self.timeline.start() def select_first(self): #Sanity check if len(self.textureLibrary) == 0: return self.timeline = clutter.Timeline(self.frames, self.fps) self.input_queue.set_timeline(self.timeline) incomingItem = 0 incomingTexture = self.textureLibrary[incomingItem] alpha = clutter.Alpha(self.timeline, clutter.ramp_inc_func) #self.behaviourNew_scale = clutter.BehaviourScale(scale_start=1, scale_end=self.scaleFactor, alpha=alpha) self.behaviourNew_scale = clutter.BehaviourScale(x_scale_start=1, y_scale_start=1, x_scale_end=self.scaleFactor, y_scale_end=self.scaleFactor, alpha=alpha) self.behaviourNew_z = clutter.BehaviourDepth(depth_start=1, depth_end=2, alpha=alpha) self.behaviourNew_opacity = clutter.BehaviourOpacity(opacity_start=self.inactiveOpacity, opacity_end=255, alpha=alpha) self.behaviourNew_scale.apply(incomingTexture) self.behaviourNew_z.apply(incomingTexture) self.behaviourNew_opacity.apply(incomingTexture) self.currentSelection = incomingItem self.timeline.start() def select_none(self): if self.currentSelection is None: return self.timeline = clutter.Timeline(self.frames, self.fps) alpha = clutter.Alpha(self.timeline, clutter.smoothstep_inc_func) self.behaviourOld_scale = clutter.BehaviourScale(x_scale_start=self.scaleFactor, y_scale_start=self.scaleFactor, x_scale_end=1, y_scale_end=1, alpha=alpha) self.behaviourOld_z = clutter.BehaviourDepth(depth_start=2, depth_end=1, alpha=alpha) self.behaviourOld_opacity = clutter.BehaviourOpacity(opacity_start=255, opacity_end=self.inactiveOpacity, alpha=alpha) current_cover = self.textureLibrary[self.currentSelection] self.behaviourOld_scale.apply(current_cover) self.behaviourOld_z.apply(current_cover) self.behaviourOld_opacity.apply(current_cover) self.timeline.start() def remove_item(self, timeline = None, itemNo = None): self.textureLibrary[itemNo].set_opacity(0) self.textureLibrary[itemNo].hide() self.images_group.remove(self.textureLibrary[itemNo]) def get_current_texture(self): return self.textureLibrary[self.currentSelection] def get_current_item(self): return self.itemLibrary[(self.currentSelection-len(self.folderLibrary))] #Was get_item_x() def get_texture_x(self, itemNo): return self.textureLibrary[itemNo] def get_item_library(self): return self.textureLibrary def set_details_update(self, on_off, details): self.update_details = on_off self.details_group = details def on_key_press_event(self, event): self.input_queue.input(event) return self.timeline #These are the basic movement functions def move_left(self): #Make sure we're not already on the first cover if not self.currentSelection == 0: newItem = self.currentSelection - 1 self.move_common(newItem) def move_right(self): #This check makes sure that we're not on the last cover already if not self.currentSelection == (self.num_images-1): newItem = self.currentSelection + 1 self.move_common(newItem) def move_common(self, newItem): #Final sanity check if (newItem < 0) and (not newItem == None): newItem = self.currentSelection #If there is movement, make the scale happen if not newItem == None: self.select_item(newItem, self.currentSelection)