Pluggable modules now complete.

This commit is contained in:
noisymime 2007-11-19 11:38:15 +00:00
parent 34b46395d1
commit 77bc6a25af
13 changed files with 425 additions and 391 deletions

View File

@ -70,8 +70,8 @@ class Menu:
menu_x = (self.stage.get_width()-self.itemGroup.get_width())/2
self.itemGroup.set_position(menu_x, menu_y)
self.displayPosition = (menu_x, menu_y)
print "Original Group size: " + str(self.itemGroup.get_width())
print "Starting at : " + str(menu_x) + ":" + str(menu_y)
#print "Original Group size: " + str(self.itemGroup.get_width())
#print "Starting at : " + str(menu_x) + ":" + str(menu_y)
#The display position is the x, y coords of where the menu is when it is active
def get_display_position(self):
@ -299,7 +299,8 @@ class ListItem (clutter.Label):
label_x = 0 #x #self.stage.get_width() - label_width - 50
label_y = y #self.stage.get_height() - label_height
self.set_position(0, y)
self.addImage(imagePath, True)
if not (imagePath == "" or imagePath is None):
self.addImage(imagePath, True)
#Add textures group and hide it
self.menu.getMenuGroup().add(self.itemTexturesGroup)

BIN
Menu.pyc

Binary file not shown.

View File

@ -147,6 +147,12 @@ class MenuMgr:
def get_current_menu(self):
return self.currentMenu
def go_up_x_levels(self, num_levels):
for i in range(1, num_levels):
if len(self.menuHistory)>1:
self.transition_fade_zoom(self.menuHistory.pop(), self.menuHistory[-1])
self.currentMenu = self.menuHistory[-1]
class MenuSelector(clutter.Texture):
x_offset = -50

Binary file not shown.

View File

@ -8,6 +8,7 @@ class VideoController:
self.stage = stage
self.overlay = None
self.blackdrop = None
# Primary video texture & sink definition
self.video_texture = clutter.cluttergst.VideoTexture()
self.video_sink = clutter.cluttergst.VideoSink(self.video_texture)
@ -48,7 +49,9 @@ class VideoController:
self.isPlaying = True
return self.video_texture
#This handles any messages that are sent accross the playbin
#Currently the only message being checked for it a "codec not found"
def on_bus_message(self, bus, message):
t = message.type
@ -69,6 +72,7 @@ class VideoController:
def stop_video(self):
if self.video_texture.get_playing():
self.isPlaying = False
self.player.stop_video()
self.player = None
self.video_texture.set_playing(False)
@ -77,13 +81,13 @@ class VideoController:
alpha = clutter.Alpha(timeline, clutter.ramp_inc_func)
self.behaviour = clutter.BehaviourOpacity(alpha, 255,0)
self.behaviour.apply(self.video_texture)
#behaviour.apply(self.blackdrop)
self.behaviour.apply(self.blackdrop)
timeline.start()
def end_video_event(self, data):
self.stage.remove(self.video_texture)
# self.stage.remove(self.blackdrop)
self.stage.remove(self.blackdrop)
self.blackdrop = None
def customBin(self):

View File

@ -60,31 +60,14 @@ class MainApp:
#Update splash status msg
self.splashScreen.set_msg("Creating menus")
menu1 = Menu(self.menuMgr)
menu1.addItem("TV", "ui/dvd.png")
menu1.addItem("Slideshow", "ui/gallery.png")
menu1.addItem("Videos", "ui/videos.png")
menu1.addItem("Link", "ui/link.png")
menu1.addItem("DVD", "ui/dvd.png")
menu1.addItem("nothing", "ui/dvd.png")
menu1.addItem("nothing", "ui/dvd.png")
menu1.addItem("nothing", "ui/dvd.png")
MainMenu = Menu(self.menuMgr)
#menu1.addItem("nothing", "ui/dvd.png")
#menu1.addItem("nothing", "ui/dvd.png")
#menu1.addItem("nothing", "ui/dvd.png")
#menu1.setListFont('Tahoma 42')
menu1.setMenuPositionByName("center")
self.menu1 = menu1
self.menu2 = Menu(self.menuMgr)
self.menu2.addItem("Nothing", "ui/dvd.png")
self.menu2.addItem("Link", "ui/gallery.png")
self.menu2.addItem("blah3", "ui/game.png")
self.menu2.addItem("blah4", "ui/music.png")
self.menu2.addItem("blah", "ui/dvd.png")
self.menu2.addItem("blah2", "ui/dvd.png")
self.menu2.addItem("blah3", "ui/dvd.png")
self.menu2.addItem("blah4", "ui/dvd.png")
#self.menu2.setListFont('Tahoma 42')
self.menu2.setMenuPositionByName("center")
MainMenu.setMenuPositionByName("center")
#self.MainMenu = menu
#Update splash status msg
@ -93,35 +76,19 @@ class MainApp:
self.dbMgr = mythDB()
#Update splash status msg
self.splashScreen.set_msg("Loading gallery")
self.mySlideshow = modules[0].Slideshow(self.menuMgr, self.dbMgr)
#Update splash status msg
self.splashScreen.set_msg("Loading videos")
self.vidPlayer = modules[2].VideoPlayer(self.stage, self.dbMgr)
#Update splash status msg
self.splashScreen.set_msg("Setting up TV player")
self.tvPlayer = modules[1].TVPlayer(self.stage, self.dbMgr)
#Update splash status msg
self.splashScreen.set_msg("Setting up DVD player")
self.dvdPlayer = modules[3].DvdPlayer(self.stage)
#Update splash status msg
self.splashScreen.set_msg("Setting up Music player")
self.musicPlayer = modules[4].MusicPlayer(self.stage)
menu1.getItem(0).setAction(self.tvPlayer)
#menu1.getItem(1).setAction(self.mySlideshow)
menu1.getItem(1).setAction(self.mySlideshow.generateMenu())
menu1.getItem(2).setAction(self.vidPlayer)
menu1.getItem(3).setAction(self.menu2)
menu1.getItem(4).setAction(self.dvdPlayer)
self.menu2.getItem(1).setAction(self.menu1)
for mods in modules:
title = mods.Module.title
image_uri = "ui/"+mods.Module.menu_image
self.splashScreen.set_msg("Loading "+title)
tempMod = mods.Module(self.menuMgr, self.dbMgr)
temp_menu_item = MainMenu.addItem(title, image_uri)
temp_menu_item.setAction(tempMod.action())
self.splashScreen.remove()
self.stage.connect('key-press-event', self.menuMgr.on_key_press_event)
self.menu1.display()
self.menu1.selectFirst(True)
MainMenu.display()
MainMenu.selectFirst(True)
return False
#print self.menuMgr.get_selector_bar().get_abs_position()

View File

@ -2,15 +2,19 @@ import clutter
from clutter import cluttergst
from VideoController import VideoController
class DvdPlayer:
class Module:
title = "DVD"
menu_image = "dvd.png"
def __init__(self, Stage):
self.stage = Stage
def __init__(self, MenuMgr, dbMgr):
self.stage = MenuMgr.get_stage()
self.paused = False
self.isPlaying = False
self.overlay = None
#Action to take when menu item is selected
def action(self):
return self
def on_key_press_event (self, stage, event):
if self.isPlaying:

View File

@ -3,14 +3,20 @@ import gtk
import clutter
import eyeD3
class MusicPlayer():
class Module():
title = "Music"
menu_image = "dvd.png"
def __init__(self, stage):
self.stage = stage
def __init__(self, MenuMgr, dbMgr):
self.stage = MenuMgr.get_stage()
self.cover_viewer = coverViewer(self.stage)
self.is_playing = False
#Action to take when menu item is selected
def action(self):
return self
def on_key_press_event (self, stage, event):
if event.keyval == clutter.keysyms.p:
if self.paused:

View File

@ -9,14 +9,19 @@ from modules.myth_tv_player.MythBackendConn import MythBackendConnection
from Menu import Menu
from VideoController import VideoController
class TVPlayer:
class Module:
title = "TV"
menu_image = "dvd.png"
def __init__(self, stage, dbMgr):
self.videoController = VideoController(stage)
self.stage = stage
def __init__(self, MenuMgr, dbMgr):
self.stage = MenuMgr.get_stage()
self.videoController = VideoController(self.stage)
self.dbMgr = dbMgr
self.isRunning = False
#Action to take when menu item is selected
def action(self):
return self
def begin(self, menuMgr):
self.menuMgr = menuMgr

View File

@ -9,7 +9,10 @@ import gtk
import random
#import thread
class Slideshow:
class Module:
title = "Slideshow"
menu_image= "gallery.png"
image_file_types = ["jpg", "gif", "jpeg", "png", "bmp"]
sound_file_types = ["mp3", "wav", "ogg"] #possibly more supported by default?
imageDuration = 7 # In seconds
@ -28,6 +31,9 @@ class Slideshow:
#Load the base image directory. This is pulled from the myth db's settings table
self.baseDir = dbMgr.get_setting('GalleryDir')
def action(self):
return self.generateMenu()
def on_key_press_event (self, stage, event):
#print event.hardware_keycode
if event.keyval == clutter.keysyms.p:
@ -90,6 +96,10 @@ class Slideshow:
def begin(self, MenuMgr):
self.stage = self.MenuMgr.get_stage()
#Check for an empty baseDir, this means there are no slideshows or no db connection. We simply tell the menuMgr to go back a menu level when this occurs
if self.baseDir is None:
MenuMgr.go_up_x_levels(1)
return
#self.MenuMgr.get_selector_bar().set_spinner(True)
#self.stage.queue_redraw()
@ -326,6 +336,12 @@ class Slideshow:
tempMenu = Menu(self.MenuMgr)
#print self.baseDir
#This occurs when there are not slideshows or we could not connect to the db to establish baseDir
if self.baseDir is None:
tempItem = tempMenu.addItem("No slideshows available", "")
tempItem.setAction(self)
return
file_list = os.listdir(self.baseDir)
for directoryEntry in file_list:
@ -334,7 +350,7 @@ class Slideshow:
if not (len(os.listdir(subdir)) == 0):
imgPath = subdir + "/" + os.listdir(subdir)[0]
#print imgPath
tempItem = tempMenu.addItem(directoryEntry, "/home/josh/.mythtv/MythVideo/0088763.jpg")
tempItem = tempMenu.addItem(directoryEntry, "")
tempItem.setAction(self)

View File

@ -0,0 +1,327 @@
import pygtk
import gtk
import pygst
import gst
import gobject
import pango
import clutter
class coverViewer(clutter.Group):
scaleFactor = 1.4
inactiveOpacity = 150
def __init__(self, stage, width, height):
clutter.Group.__init__(self)
self.stage = stage
self.videoLibrary = []
self.textureLibrary = []
self.current_video_details = video_details_group(width)
self.covers_group = clutter.Group()
self.num_covers = 0
self.cover_gap = 1
self.num_visible_rows = 3
self.num_columns = 4
self.cover_size = int(width / self.num_columns) #200 #A cover will be cover_size * cover_size (X * Y)
#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)
self.covers_group.show()
#self.stage.add(self.current_video_description)
self.current_video_details.show()
self.current_video_details.show_all()
#Turns the description group off and on
def toggle_details(self):
if self.current_video_details.get_parent() == None:
self.add(self.current_video_details)
#Set the position of the details group
(pos_x, pos_y) = self.get_abs_position()
#The next two lines are horribly ugly, but all they do is position the details viewer in the middle of the gap between the bottom of the visible cover viewer and the bottom of the stage
viewer_lower_y = int(pos_y + (self.max_visible_rows * self.cover_size))
pos_y = viewer_lower_y# + int( (self.stage.get_height() - viewer_lower_y) / 2 - int(self.current_video_details.get_height()/2))
self.current_video_details.set_position(20, pos_y)
else:
self.stage.remove(self.current_video_details)
def add_video(self, video):
self.videoLibrary.append(video)
imagePath = video.getCoverfile()
tempTexture = clutter.Texture()
pixbuf = gtk.gdk.pixbuf_new_from_file(imagePath)
tempTexture.set_pixbuf(pixbuf)
xy_ratio = float(tempTexture.get_width()) / tempTexture.get_height()
width = int(self.cover_size * xy_ratio)
tempTexture.set_width(width)
tempTexture.set_height(self.cover_size)
tempTexture.set_opacity(self.inactiveOpacity)
tempTexture.set_position( (self.num_covers * self.cover_size), 0)
tempTexture.set_depth(1)
self.textureLibrary.append(tempTexture)
#x = (self.cover_gap + self.cover_size) * (self.num_covers/self.num_rows)
#y = (self.num_covers % self.num_rows) * self.cover_size + ( (self.num_covers % self.num_rows) * self.cover_gap)
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)
#Center the cover
if width < self.cover_size:
x = x + (self.cover_size - width)/2
tempTexture.set_position(x, y)
#If we're past the maximum rows, make the pics invistible
if self.num_covers > (self.num_columns * self.num_visible_rows)-1:
tempTexture.set_opacity(0)
else:
self.covers_group.add(tempTexture)
tempTexture.show()
self.num_covers = self.num_covers +1
def select_item(self, incomingItem, outgoingItem):
self.timeline = clutter.Timeline(10,35)
self.current_video_details.set_video(self.videoLibrary[incomingItem], self.timeline)
#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(alpha, 1, self.scaleFactor, clutter.GRAVITY_CENTER)
self.behaviourNew_z = clutter.BehaviourDepth(alpha, 1, 2)
#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(alpha, 0, 255)
else:
self.behaviourNew_opacity = clutter.BehaviourOpacity(alpha, self.inactiveOpacity, 255)
self.behaviourOld_scale = clutter.BehaviourScale(alpha, self.scaleFactor, 1, clutter.GRAVITY_CENTER)
self.behaviourOld_z = clutter.BehaviourDepth(alpha, 2, 1)
self.behaviourOld_opacity = clutter.BehaviourOpacity(alpha, 255, self.inactiveOpacity)
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)
self.currentSelection = incomingItem
self.timeline.start()
def select_first(self):
self.timeline = clutter.Timeline(20,80)
self.current_video_details.set_video(self.videoLibrary[0], self.timeline)
incomingItem = 0
incomingTexture = self.textureLibrary[incomingItem]
alpha = clutter.Alpha(self.timeline, clutter.ramp_inc_func)
self.behaviourNew_scale = clutter.BehaviourScale(alpha, 1, self.scaleFactor, clutter.GRAVITY_CENTER)
self.behaviourNew_z = clutter.BehaviourDepth(alpha, 1, 2)
self.behaviourNew_opacity = clutter.BehaviourOpacity(alpha, self.inactiveOpacity, 255)
self.behaviourNew_scale.apply(incomingTexture)
self.behaviourNew_z.apply(incomingTexture)
self.behaviourNew_opacity.apply(incomingTexture)
self.currentSelection = incomingItem
self.timeline.start()
#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(alpha, 0, self.inactiveOpacity)
self.behaviour_outgoing = clutter.BehaviourOpacity(alpha, self.inactiveOpacity, 0)
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])
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])
#xy_ratio = float(self.textureLibrary[i].get_width()) / self.textureLibrary[i].get_height()
#width = int(self.cover_size * xy_ratio)
#x = (i % self.num_columns) * self.cover_size + ( (i % self.num_columns) * self.cover_gap)
#y = (self.cover_gap + self.cover_size) * (i/self.num_columns)
#Center the cover
#if width < self.cover_size:
# x = x + (self.cover_size - width)/2
#self.textureLibrary[i].set_position(x, y)
self.textureLibrary[i].show()
def get_current_video(self):
return self.videoLibrary[self.currentSelection]
def on_key_press_event(self, event):
newItem = None
if event.keyval == clutter.keysyms.Left:
#Make sure we're not already on the first cover
if not self.currentSelection == 0:
newItem = self.currentSelection - 1
elif event.keyval == clutter.keysyms.Right:
#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
elif event.keyval == clutter.keysyms.Down:
#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
elif event.keyval == clutter.keysyms.Up:
#Check if we're already on the top row
if not (self.currentSelection < self.num_columns):
newItem = self.currentSelection - self.num_columns
#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)
class video_details_group(clutter.Group):
font = "Lucida Grande "
title_font_size = 30
main_font_size = 22
plot_font_size = 18
def __init__(self, desired_width):
clutter.Group.__init__(self)
self.width = desired_width
#Add the various labels
self.title = clutter.Label()
self.title.set_font_name(self.font + str(self.title_font_size))
self.title.set_color(clutter.color_parse('White'))
self.title.set_text("")
self.title.set_ellipsize(pango.ELLIPSIZE_END)
self.add(self.title)
#Not sure how to get the row height before the text is set :(
self.row_gap = self.title.get_height()
self.year = clutter.Label()
self.year.set_font_name(self.font + str(self.main_font_size))
self.year.set_color(clutter.color_parse('White'))
self.year.set_text("")
self.year.set_opacity(220)
self.year.set_ellipsize(pango.ELLIPSIZE_END)
self.year.set_position(0, self.row_gap)
self.add(self.year)
self.director = clutter.Label()
self.director.set_font_name(self.font + str(self.main_font_size))
self.director.set_color(clutter.color_parse('White'))
self.director.set_text("")
self.director.set_opacity(220)
self.director.set_ellipsize(pango.ELLIPSIZE_END)
self.director.set_position(int(self.year.get_width()), self.row_gap)
self.add(self.director)
self.plot = clutter.Label()
self.plot.set_font_name(self.font + str(self.plot_font_size))
self.plot.set_color(clutter.color_parse('White'))
self.plot.set_text("")
self.plot.set_opacity(220)
#self.plot.set_ellipsize(pango.ELLIPSIZE_END)
self.plot.set_position(0, int(self.row_gap*2))
self.add(self.plot)
self.show_all()
def set_video_bare(self,video):
self.timeline = clutter.Timeline(10,45)
self.set_video(video, self.timeline)
def set_video(self, video, timeline):
self.video = video
self.title.set_text(video.title)
self.title.set_width(self.width)
self.year.set_text("Year: " + str(video.year))
self.director.set_text(" Director: " + str(video.director))
self.director.set_position(int(self.year.get_width()), self.row_gap)
self.director.set_width(int(self.width - self.year.get_width()))
self.plot.set_text(video.plot)
self.plot.set_width(self.width)

View File

@ -7,13 +7,16 @@ import pango
import clutter
from clutter import cluttergst
from VideoController import VideoController
from modules.video_player.cover_viewer import coverViewer
class VideoPlayer():
class Module():
title = "Videos"
menu_image= "videos.png"
def __init__(self, stage, dbMgr):
self.stage = stage
def __init__(self, MenuMgr, dbMgr):
self.stage = MenuMgr.get_stage()
self.cover_viewer = coverViewer(self.stage, 800, 600)
self.videoController = VideoController(stage)
self.videoController = VideoController(self.stage)
self.is_playing = False
#This block can be moved to begin() but causes a performance hit when loading the module *shrug*
@ -27,7 +30,9 @@ class VideoPlayer():
tempVideo.importFromMythObject(record)
self.cover_viewer.add_video(tempVideo)
#Action to take when menu item is selected
def action(self):
return self
def on_key_press_event (self, stage, event):
if self.is_playing:
@ -120,6 +125,16 @@ class VideoPlayer():
self.is_playing = False
timeline = clutter.Timeline(15, 25)
self.cover_viewer.set_opacity(0)
alpha = clutter.Alpha(timeline, clutter.ramp_inc_func)
self.behaviour = clutter.BehaviourOpacity(alpha, 0,255)
self.behaviour.apply(self.cover_viewer)
self.stage.add(self.cover_viewer)
self.cover_viewer.show()
timeline.start()
def pause(self):
pass
@ -153,321 +168,4 @@ class videoItem():
def getCoverfile(self):
return self.coverfile
class coverViewer(clutter.Group):
scaleFactor = 1.4
inactiveOpacity = 150
def __init__(self, stage, width, height):
clutter.Group.__init__(self)
self.stage = stage
self.videoLibrary = []
self.textureLibrary = []
self.current_video_details = video_details_group(width)
self.covers_group = clutter.Group()
self.num_covers = 0
self.cover_gap = 1
self.num_visible_rows = 3
self.num_columns = 4
self.cover_size = int(width / self.num_columns) #200 #A cover will be cover_size * cover_size (X * Y)
#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)
self.covers_group.show()
#self.stage.add(self.current_video_description)
self.current_video_details.show()
self.current_video_details.show_all()
#Turns the description group off and on
def toggle_details(self):
if self.current_video_details.get_parent() == None:
self.add(self.current_video_details)
#Set the position of the details group
(pos_x, pos_y) = self.get_abs_position()
#The next two lines are horribly ugly, but all they do is position the details viewer in the middle of the gap between the bottom of the visible cover viewer and the bottom of the stage
viewer_lower_y = int(pos_y + (self.max_visible_rows * self.cover_size))
pos_y = viewer_lower_y# + int( (self.stage.get_height() - viewer_lower_y) / 2 - int(self.current_video_details.get_height()/2))
self.current_video_details.set_position(20, pos_y)
else:
self.stage.remove(self.current_video_details)
def add_video(self, video):
self.videoLibrary.append(video)
imagePath = video.getCoverfile()
tempTexture = clutter.Texture()
pixbuf = gtk.gdk.pixbuf_new_from_file(imagePath)
tempTexture.set_pixbuf(pixbuf)
xy_ratio = float(tempTexture.get_width()) / tempTexture.get_height()
width = int(self.cover_size * xy_ratio)
tempTexture.set_width(width)
tempTexture.set_height(self.cover_size)
tempTexture.set_opacity(self.inactiveOpacity)
tempTexture.set_position( (self.num_covers * self.cover_size), 0)
tempTexture.set_depth(1)
self.textureLibrary.append(tempTexture)
#x = (self.cover_gap + self.cover_size) * (self.num_covers/self.num_rows)
#y = (self.num_covers % self.num_rows) * self.cover_size + ( (self.num_covers % self.num_rows) * self.cover_gap)
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)
#Center the cover
if width < self.cover_size:
x = x + (self.cover_size - width)/2
tempTexture.set_position(x, y)
#If we're past the maximum rows, make the pics invistible
if self.num_covers > (self.num_columns * self.num_visible_rows)-1:
tempTexture.set_opacity(0)
else:
self.covers_group.add(tempTexture)
tempTexture.show()
self.num_covers = self.num_covers +1
def select_item(self, incomingItem, outgoingItem):
self.timeline = clutter.Timeline(10,35)
self.current_video_details.set_video(self.videoLibrary[incomingItem], self.timeline)
#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(alpha, 1, self.scaleFactor, clutter.GRAVITY_CENTER)
self.behaviourNew_z = clutter.BehaviourDepth(alpha, 1, 2)
#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(alpha, 0, 255)
else:
self.behaviourNew_opacity = clutter.BehaviourOpacity(alpha, self.inactiveOpacity, 255)
self.behaviourOld_scale = clutter.BehaviourScale(alpha, self.scaleFactor, 1, clutter.GRAVITY_CENTER)
self.behaviourOld_z = clutter.BehaviourDepth(alpha, 2, 1)
self.behaviourOld_opacity = clutter.BehaviourOpacity(alpha, 255, self.inactiveOpacity)
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)
self.currentSelection = incomingItem
self.timeline.start()
def select_first(self):
self.timeline = clutter.Timeline(20,80)
self.current_video_details.set_video(self.videoLibrary[0], self.timeline)
incomingItem = 0
incomingTexture = self.textureLibrary[incomingItem]
alpha = clutter.Alpha(self.timeline, clutter.ramp_inc_func)
self.behaviourNew_scale = clutter.BehaviourScale(alpha, 1, self.scaleFactor, clutter.GRAVITY_CENTER)
self.behaviourNew_z = clutter.BehaviourDepth(alpha, 1, 2)
self.behaviourNew_opacity = clutter.BehaviourOpacity(alpha, self.inactiveOpacity, 255)
self.behaviourNew_scale.apply(incomingTexture)
self.behaviourNew_z.apply(incomingTexture)
self.behaviourNew_opacity.apply(incomingTexture)
self.currentSelection = incomingItem
self.timeline.start()
#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(alpha, 0, self.inactiveOpacity)
self.behaviour_outgoing = clutter.BehaviourOpacity(alpha, self.inactiveOpacity, 0)
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])
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])
xy_ratio = float(self.textureLibrary[i].get_width()) / self.textureLibrary[i].get_height()
width = int(self.cover_size * xy_ratio)
x = (i % self.num_columns) * self.cover_size + ( (i % self.num_columns) * self.cover_gap)
y = (self.cover_gap + self.cover_size) * (i/self.num_columns)
#Center the cover
if width < self.cover_size:
x = x + (self.cover_size - width)/2
self.textureLibrary[i].set_position(x, y)
self.textureLibrary[i].show()
def get_current_video(self):
return self.videoLibrary[self.currentSelection]
def on_key_press_event(self, event):
newItem = None
if event.keyval == clutter.keysyms.Left:
#Make sure we're not already on the first cover
if not self.currentSelection == 0:
newItem = self.currentSelection - 1
elif event.keyval == clutter.keysyms.Right:
#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
elif event.keyval == clutter.keysyms.Down:
#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
elif event.keyval == clutter.keysyms.Up:
#Check if we're already on the top row
if not (self.currentSelection < self.num_columns):
newItem = self.currentSelection - self.num_columns
#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)
class video_details_group(clutter.Group):
font = "Lucida Grande "
title_font_size = 30
main_font_size = 22
plot_font_size = 18
def __init__(self, desired_width):
clutter.Group.__init__(self)
self.width = desired_width
#Add the various labels
self.title = clutter.Label()
self.title.set_font_name(self.font + str(self.title_font_size))
self.title.set_color(clutter.color_parse('White'))
self.title.set_text("")
self.title.set_ellipsize(pango.ELLIPSIZE_END)
self.add(self.title)
#Not sure how to get the row height before the text is set :(
self.row_gap = self.title.get_height()
self.year = clutter.Label()
self.year.set_font_name(self.font + str(self.main_font_size))
self.year.set_color(clutter.color_parse('White'))
self.year.set_text("")
self.year.set_opacity(220)
self.year.set_ellipsize(pango.ELLIPSIZE_END)
self.year.set_position(0, self.row_gap)
self.add(self.year)
self.director = clutter.Label()
self.director.set_font_name(self.font + str(self.main_font_size))
self.director.set_color(clutter.color_parse('White'))
self.director.set_text("")
self.director.set_opacity(220)
self.director.set_ellipsize(pango.ELLIPSIZE_END)
self.director.set_position(int(self.year.get_width()), self.row_gap)
self.add(self.director)
self.plot = clutter.Label()
self.plot.set_font_name(self.font + str(self.plot_font_size))
self.plot.set_color(clutter.color_parse('White'))
self.plot.set_text("")
self.plot.set_opacity(220)
#self.plot.set_ellipsize(pango.ELLIPSIZE_END)
self.plot.set_position(0, int(self.row_gap*2))
self.add(self.plot)
self.show_all()
def set_video_bare(self,video):
self.timeline = clutter.Timeline(10,45)
self.set_video(video, self.timeline)
def set_video(self, video, timeline):
self.video = video
self.title.set_text(video.title)
self.title.set_width(self.width)
self.year.set_text("Year: " + str(video.year))
self.director.set_text(" Director: " + str(video.director))
self.director.set_position(int(self.year.get_width()), self.row_gap)
self.director.set_width(int(self.width - self.year.get_width()))
self.plot.set_text(video.plot)
self.plot.set_width(self.width)