gloss-mc/modules/video_player/elements/cover_viewer.py

346 lines
16 KiB
Python
Raw Normal View History

2007-11-19 03:38:15 -08:00
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
2007-11-19 03:38:15 -08:00
class coverViewer(clutter.Group):
scaleFactor = 1.4
inactiveOpacity = 150
covers_size_percent = 0.90 #This is the percentage of the total group size that the covers will take
detailBox_height = 160 #Needs a percent
update_details = False
2007-11-19 03:38:15 -08:00
def __init__(self, glossMgr, width, height, rows, columns):
2007-11-19 03:38:15 -08:00
clutter.Group.__init__(self)
self.glossMgr = glossMgr
self.stage = glossMgr.stage
2007-11-19 03:38:15 -08:00
self.videoLibrary = []
self.textureLibrary = []
self.folderLibrary = []
2007-11-19 03:38:15 -08:00
self.covers_group = clutter.Group()
self.covers_width = int(width * self.covers_size_percent)
self.covers_height = int(height * self.covers_size_percent)
2007-11-19 03:38:15 -08:00
self.num_visible_rows = rows
self.num_columns = columns
self.cover_size = int(self.covers_width / self.num_columns) #A cover will be cover_size * cover_size (X * Y)
#The viewer actually sits within another group that clips its size
self.covers_group_clip = clutter.Group()
self.covers_group_clip.add(self.covers_group)
#Nasty hack to get around centering problem
self.covers_group.set_position(int(self.cover_size/2), int(self.cover_size/2))
#And setup the clip size and position
scale_amount = int(self.cover_size * self.scaleFactor - self.cover_size)
clip_width = (self.cover_size*columns) + scale_amount #Width is the cover size by the number of colums, plus the additional amount required for scaling
clip_height = (self.cover_size*rows) + scale_amount
self.covers_group_clip.set_clip(-(scale_amount/2), -(scale_amount/2), clip_width, clip_height)
#self.current_video_details = video_details_group(self.covers_width)
self.num_covers = 0
self.cover_gap = 1
#Setup input queue controller
self.input_queue = InputQueue()
self.input_queue.set_action(InputQueue.NORTH, self.move_up)
self.input_queue.set_action(InputQueue.SOUTH, self.move_down)
self.input_queue.set_action(InputQueue.EAST, self.move_right)
self.input_queue.set_action(InputQueue.WEST, self.move_left)
2007-11-19 03:38:15 -08:00
#Setup the current min and max viewable rows
self.min_visible_rows = 0
self.max_visible_rows = self.num_visible_rows
self.currentSelection = 0
self.add(self.covers_group_clip)
covers_x = int(width * (1-self.covers_size_percent)/2)
covers_y = int(height * (1-self.covers_size_percent)/2)
#self.covers_group.set_position(covers_x, covers_y)
#self.covers_group.set_depth(1) #self.cover_size)
2007-11-19 03:38:15 -08:00
self.covers_group.show()
self.covers_group_clip.show()
2007-11-19 03:38:15 -08:00
2007-12-11 02:50:45 -08:00
def add_video(self, video):
2007-11-19 03:38:15 -08:00
self.videoLibrary.append(video)
tempTexture = cover_item(self.glossMgr, video, None, self.cover_size)
self.add_texture_group(tempTexture)
def add_folder(self, folder_name):
tempTexture = cover_item(self.glossMgr, None, folder_name, self.cover_size)
self.folderLibrary.append(folder_name)
self.add_texture_group(tempTexture)
2007-11-19 03:38:15 -08:00
def add_texture_group(self, tempGroup):
tempGroup.set_opacity(self.inactiveOpacity)
2007-11-19 03:38:15 -08:00
#tempGroup.set_position( (self.num_covers * self.cover_size), 0)
tempGroup.set_depth(1)
2007-11-19 03:38:15 -08:00
self.textureLibrary.append(tempGroup)
2007-11-19 03:38:15 -08:00
x = (self.num_covers % self.num_columns) * self.cover_size + ( (self.num_covers % self.num_columns) * self.cover_gap)
y = (self.cover_gap + self.cover_size) * (self.num_covers/self.num_columns)
#x = (self.num_covers % self.num_columns) * (self.cover_size * 1.5) + ( (self.num_covers % self.num_columns) * self.cover_gap)
#y = (self.cover_gap + (self.cover_size*1.5)) * (self.num_covers/self.num_columns)
tempGroup.set_position(x, y)
2007-11-19 03:38:15 -08:00
#If we're past the maximum rows, make the pics invistible
if self.num_covers > (self.num_columns * self.num_visible_rows)-1:
tempGroup.set_opacity(0)
2007-11-19 03:38:15 -08:00
else:
self.covers_group.add(tempGroup)
2007-11-19 03:38:15 -08:00
tempGroup.show()
2007-11-19 03:38:15 -08:00
self.num_covers = self.num_covers +1
2007-11-19 03:38:15 -08:00
def select_item(self, incomingItem, outgoingItem):
self.timeline = clutter.Timeline(10,35)
self.input_queue.set_timeline(self.timeline)
numFolders = len(self.folderLibrary)
if incomingItem >= numFolders:
incomingItemVideo = incomingItem - numFolders
2007-11-19 03:38:15 -08:00
#Check if the cover is currently not visible
rolling = False
if incomingItem > (self.num_columns * self.max_visible_rows-1):
self.rollViewer(True, self.timeline)
rolling = True
if incomingItem < (self.num_columns * self.min_visible_rows):
self.rollViewer(False, self.timeline)
rolling = True
outgoingTexture = self.textureLibrary[outgoingItem]
incomingTexture = self.textureLibrary[incomingItem]
alpha = clutter.Alpha(self.timeline, clutter.smoothstep_inc_func)# clutter.ramp_inc_func)
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)
2007-11-19 03:38:15 -08:00
#If we're performing a roll (See above) then the incoming opacity should start at 0 rather than the normal inactive opacity
if rolling:
self.behaviourNew_opacity = clutter.BehaviourOpacity(opacity_start=0, opacity_end=255, alpha=alpha)
2007-11-19 03:38:15 -08:00
else:
self.behaviourNew_opacity = clutter.BehaviourOpacity(opacity_start=self.inactiveOpacity, opacity_end=255, alpha=alpha)
2007-11-19 03:38:15 -08:00
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)
2007-11-19 03:38:15 -08:00
(x, y) = incomingTexture.get_position()
(x, y) = self.covers_group.get_position()
anchor_x = incomingTexture.get_width()/2
anchor_y = incomingTexture.get_height()/2
#self.covers_group.set_anchor_point(anchor_x, anchor_y)
#incomingTexture.set_anchor_point(anchor_x, anchor_y)
2007-11-19 03:38:15 -08:00
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)
#Set gravities
(x, y) = outgoingTexture.get_position()
anchor_x = outgoingTexture.get_width()/2
anchor_y = outgoingTexture.get_height()/2
#outgoingTexture.set_anchor_point(anchor_x, anchor_y)
#incomingTexture.set_anchor_point_from_gravity(clutter.GRAVITY_CENTER)
#outgoingTexture.set_anchor_point_from_gravity(clutter.GRAVITY_CENTER)
2007-11-19 03:38:15 -08:00
self.currentSelection = incomingItem
self.timeline.start()
def select_first(self):
2007-11-19 03:38:15 -08:00
self.timeline = clutter.Timeline(20,80)
self.input_queue.set_timeline(self.timeline)
"""
if not len(self.folderLibrary) == 0:
pass
else:
self.current_video_details.set_video(self.videoLibrary[0], self.timeline)
"""
2007-11-19 03:38:15 -08:00
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)
2007-11-19 03:38:15 -08:00
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(10,35)
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()
2007-11-19 03:38:15 -08:00
#This moves the visible row of covers up and down
# moveUp: True if the covers are to come up, false if they're to go down
def rollViewer(self, moveUp, timeline):
if moveUp:
new_y = self.covers_group.get_y() - self.cover_size
self.max_visible_rows = self.max_visible_rows + 1
self.min_visible_rows = self.min_visible_rows + 1
#Define the row of covers that now needs to disapear / appear
min_outgoing = (self.min_visible_rows-1) * self.num_columns
max_outgoing = min_outgoing + self.num_columns
min_incoming = (self.max_visible_rows-1) * self.num_columns
max_incoming = min_incoming + self.num_columns
#Quick check to make sure that max_incoming isn't greater than the max number of images (This occurs when the final row is incomplete)
if max_incoming > self.num_covers:
max_incoming = min_incoming + (self.num_covers % self.num_columns)
else:
new_y = self.covers_group.get_y() + self.cover_size
self.max_visible_rows = self.max_visible_rows - 1
self.min_visible_rows = self.min_visible_rows - 1
#Define the row of covers that now needs to disapear / appear
min_incoming = (self.min_visible_rows) * self.num_columns
max_incoming = min_incoming + self.num_columns
min_outgoing = (self.max_visible_rows) * self.num_columns
max_outgoing = min_outgoing + self.num_columns
#Quick check to make sure that max_outgoing isn't greater than the max number of images (This occurs when the final row is incomplete)
if max_outgoing > self.num_covers:
max_outgoing = min_outgoing + (self.num_covers % self.num_columns)
#Need to add the new row to the group
self.addIncomingRow(min_incoming, max_incoming)
#And set the outgoing row to remove after the timeline finishes
self.timeline.connect('completed', self.removeOutgoingRow, min_outgoing, max_outgoing)
knots = (\
(self.covers_group.get_x(), self.covers_group.get_y()),\
(self.covers_group.get_x(), new_y) \
)
alpha = clutter.Alpha(timeline, clutter.ramp_inc_func)
self.behaviour_path = clutter.BehaviourPath(alpha, knots)
self.behaviour_incoming = clutter.BehaviourOpacity(opacity_start=0, opacity_end=self.inactiveOpacity, alpha=alpha)
self.behaviour_outgoing = clutter.BehaviourOpacity(opacity_start=self.inactiveOpacity, opacity_end=0, alpha=alpha)
2007-11-19 03:38:15 -08:00
self.behaviour_path.apply(self.covers_group)
#Also need to change a few opacities - This is really messy, but works
for i in range(min_outgoing, max_outgoing):
self.behaviour_outgoing.apply(self.textureLibrary[i])
for i in range(min_incoming, max_incoming):
self.behaviour_incoming.apply(self.textureLibrary[i])
#These next two functions add and remove visible rows when the viewer rolls
2007-11-19 03:38:15 -08:00
def removeOutgoingRow(self, timeline, min, max):
for i in range(min, max):
self.covers_group.remove(self.textureLibrary[i])
def addIncomingRow(self, min, max):
for i in range(min, max):
self.covers_group.add(self.textureLibrary[i])
self.textureLibrary[i].set_opacity(0)
2007-11-19 03:38:15 -08:00
self.textureLibrary[i].show()
def get_current_item(self):
return self.textureLibrary[self.currentSelection]
def get_current_video(self):
if self.textureLibrary[self.currentSelection].isFolder:
return None #self.folderLibrary[(self.currentSelection-len(self.folderLibrary))]
else:
return self.videoLibrary[(self.currentSelection-len(self.folderLibrary))]
def get_item_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
2007-11-19 03:38:15 -08:00
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_covers-1):
newItem = self.currentSelection + 1
self.move_common(newItem)
def move_up(self):
#Check if we're already on the top row
if not (self.currentSelection < self.num_columns):
newItem = self.currentSelection - self.num_columns
self.move_common(newItem)
def move_down(self):
#Check if we're already on the bottom row
if not (self.currentSelection > (len(self.textureLibrary)-1 - self.num_columns)):
newItem = self.currentSelection + self.num_columns
self.move_common(newItem)
def move_common(self, newItem):
2007-11-19 03:38:15 -08:00
#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)
if self.update_details:
if not self.textureLibrary[self.currentSelection].isFolder:
self.details_group.set_video_bare(self.videoLibrary[self.currentSelection])
self.update_details = False
else:
self.details_group.set_folder(self.folderLibrary[(self.currentSelection-len(self.folderLibrary))])
#self.details_group.clear()