- More work on image row

- Added default image system
This commit is contained in:
noisymime 2008-03-21 00:08:38 +00:00
parent 00198d9618
commit 6f17098b62
10 changed files with 142 additions and 104 deletions

View File

@ -15,9 +15,8 @@ class Backend:
#Returns a list of artist objects
def get_artists(self):
#Generate some SQL to retrieve videos that were in the final_file_list
#Load the videos into the cover viewer
sql = "SELECT * FROM music_artists"
sql = "SELECT * FROM music_artists ORDER BY artist_name"
if self.music_player.glossMgr.debug: print "Music Artist SQL: " + sql
results = self.dbMgr.run_sql(sql)

View File

@ -20,16 +20,18 @@ class MusicObjectRow(ImageRow):
for i in range(start, end):
object = self.objectLibrary[i]
print "loading: " + object.name
#print "loading: " + object.name
pixbuf = object.get_image()
time.sleep(self.music_player.sleep_time)
tmpImage = clutter.Texture()
if pixbuf == object.PENDING_DOWNLOAD:
#Get the temporary image
object.get_default_image()
tmpImage = ImageFrame(None, self.image_size, use_reflection = True, quality = ImageFrame.QUALITY_FAST) #clutter.Texture()
object.connect("image-found", self.set_image_cb, object, tmpImage)
elif not pixbuf is None:
#If we're performing this loading as a seperate thread, we need to lock the Clutter threads
if as_thread: clutter.threads_enter()
tmpImage = ImageFrame(pixbuf, self.image_size, use_reflection=False)
tmpImage = ImageFrame(pixbuf, self.image_size, use_reflection=True, quality = ImageFrame.QUALITY_FAST)
if as_thread: clutter.threads_leave()
self.add_texture_group(tmpImage)

View File

@ -48,8 +48,8 @@ class artist(MusicObject):
try:
pixbuf = gtk.gdk.pixbuf_new_from_file(filename)
except gobject.GError, e:
print "Music_Player: Attempted to open file '%s', but it does not exist" % (filename)
return None
print "Music_Player: Attempted to open file '%s', but it does not exist. Using defualt image." % (filename)
return self.get_default_image()
return pixbuf
#If self.image is a eqaul to 'unset', means the column exists but that the image entry is blank, we should try to find one
@ -62,8 +62,12 @@ class artist(MusicObject):
def get_image_from_lastFM(self, thread_data):
pixbuf = self.music_player.lastFM.get_artist_image(self.name)
if not pixbuf is None: self.save_image(pixbuf)
return pixbuf
if not pixbuf is None:
self.save_image(pixbuf)
return pixbuf
else:
#We have failed to find an image
return None
#Saves an image (pixbuf) to file and updates the Myth db
def save_image(self, pixbuf):
@ -94,4 +98,8 @@ class artist(MusicObject):
self.image = filename_short
#Let off a signal to say the image is ready
self.emit("image-found")
self.emit("image-found")
#Returns the pixbuf of the default artist image
def get_default_image(self):
return self.music_player.default_artist_cover

View File

@ -66,12 +66,15 @@ class song:
tag.link(filename)
images = tag.getImages()
for img in images:
#print "Image Mine Type: " + str(img.mimeType)
data = img.imageData
loader = gtk.gdk.PixbufLoader()
loader.write(data)
loader.close()
return loader.get_pixbuf()
for img in images:
try:
#print "Image Mine Type: " + str(img.mimeType)
data = img.imageData
loader = gtk.gdk.PixbufLoader()
loader.write(data)
loader.close()
return loader.get_pixbuf()
except gobject.GError:
if self.music_player.glossMgr.debug:
print "Music_Player: Found image in ID3 for song '%s' but could not load it" % (self.filename)

View File

@ -5,7 +5,7 @@ import thread, time
from modules.music_player.backends.myth_music import Backend
from modules.music_player.lastFM_interface import lastFM_interface
from modules.music_player.music_object_row import MusicObjectRow
from ui_elements.image_frame import ImageFrame
class Module:
title = "Music"
@ -38,6 +38,9 @@ class Module:
def setup_ui(self):
self.menu_image = self.glossMgr.themeMgr.get_texture("music_menu_image", None, None)
self.default_artist_cover = self.glossMgr.themeMgr.get_texture("music_default_artist_image", None, None).get_pixbuf()
#Get the images dir setting our of the DB
#But also creates the setting if it doesn't already exist
@ -68,7 +71,7 @@ class Module:
if (event.keyval == clutter.keysyms.Left) or (event.keyval == clutter.keysyms.Right):
#calculate a period of time the loading threads should sleep for when a timline is in progress
self.sleep_time = float(MusicObjectRow.frames) / float(MusicObjectRow.fps)
#self.sleep_time = float(MusicObjectRow.frames) / float(MusicObjectRow.fps)
self.artistImageRow.input_queue.input(event)
#Just a little test code
@ -115,8 +118,9 @@ class Module:
self.stage.add(self.tmpLabel)
#The preview img
self.main_img = clutter.Texture()
self.main_img.set_position(0, 400)
self.main_img = ImageFrame(None, 300, True) #clutter.Texture()
self.main_img.set_position(30, 400)
self.main_img.set_rotation(clutter.Y_AXIS, 45, self.main_img.get_width(), 0, 0)
self.main_img.show()
self.stage.add(self.main_img)

View File

@ -10,4 +10,8 @@
<y>0</y>
</position>
</texture>
<texture id="music_default_artist_image">
<image>music/default_cover.png</image>
</texture>
</gloss-theme>

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

View File

@ -5,13 +5,37 @@ class Texture_Reflection (clutter.Texture):
def __init__(self, origTexture):
clutter.Texture.__init__(self)
#Connect to the textures pixbuf-change signal so the reflection will auto update
origTexture.connect("pixbuf-change", self.update_pixbuf)
if origTexture.get_pixbuf() is None:
print "dsflkj"
return None
self.set_pixbuf(origTexture.get_pixbuf())
#Rotate the reflection based on any rotations to the master
ang_y = origTexture.get_rotation(clutter.Y_AXIS) #ryang()
self.set_rotation(clutter.Y_AXIS, ang_y[0], (origTexture.get_width()), 0, 0)
ang_x = origTexture.get_rotation(clutter.X_AXIS)
self.set_rotation(clutter.X_AXIS, ang_x[0], 0, (origTexture.get_height()), 0)
#ang_z = origTexture.get_rotation(clutter.Z_AXIS)
#self.set_rotation(clutter.Z_AXIS, ang_z[0], 0, 0, 0)
(w, h) = origTexture.get_size()
self.set_width(w)
self.set_height(h)
#Flip it upside down
self.set_rotation(clutter.X_AXIS, 180, 0, origTexture.get_height(), 0)
self.set_opacity(50)
#Get/Set the location for it
(x, y) = origTexture.get_position()
self.set_position(x, y)
def update_pixbuf(self, origTexture):
self.set_pixbuf(origTexture.get_pixbuf())
#Rotate the reflection based on any rotations to the master
ang_y = origTexture.get_rotation(clutter.Y_AXIS) #ryang()

View File

@ -6,41 +6,77 @@ import os
from ui_elements.ReflectionTexture import Texture_Reflection
class ImageFrame(clutter.Group):
QUALITY_FAST, QUALITY_NORMAL, QUALITY_SLOW = range(3)
quality = QUALITY_NORMAL
def __init__(self, pixbuf, img_size, use_reflection = False):
def __init__(self, pixbuf, img_size, use_reflection = False, quality = QUALITY_NORMAL):
clutter.Group.__init__(self)
self.width = img_size
self.height = img_size
self.img_size = img_size
self.use_reflection = use_reflection
self.quality = quality
self.main_pic = clutter.Texture()
#New method of resizing changes size of pixbuf rather than texture.... MUCH better performance :)
(x, y) = (0, 0)
if pixbuf.get_height() > pixbuf.get_width():
xy_ratio = float(pixbuf.get_width()) / pixbuf.get_height()
height = img_size
width = int(img_size * xy_ratio)
x = (img_size - width)/2
#x = int(cover_size / 2)
#x = x + (cover_size - width)
else:
xy_ratio = float(pixbuf.get_height()) / float(pixbuf.get_width())
width = img_size
height = int(img_size * xy_ratio)
y = (img_size - height)/2
#y = y + (cover_size - height)
pixbuf = pixbuf.scale_simple(width, height, gtk.gdk.INTERP_BILINEAR)
self.main_pic.set_pixbuf(pixbuf)
self.main_pic.show()
#If a reflection is desired, add it on
#pixbuf can be None, it just means that nothing appears initially
if pixbuf is None:
self.add(self.main_pic)
if use_reflection:
self.reflection = Texture_Reflection(self.main_pic)
self.add(self.reflection)
self.reflection.show()
else:
self.reflection = None
return
pixbuf = self.resize_pixbuf(pixbuf)
self.main_pic.set_pixbuf(pixbuf)
self.main_pic.set_position(self.x, self.y)
self.main_pic.show()
if use_reflection:
self.reflection = Texture_Reflection(self.main_pic)
self.add(self.reflection)
self.reflection.show()
else:
self.reflection = None
self.reflection = None
self.add(self.main_pic)
self.main_pic.set_position(x, y)
self.add(self.main_pic)
def resize_pixbuf(self, pixbuf):
#New method of resizing changes size of pixbuf rather than texture.... MUCH better performance :)
(self.x, self.y) = (0, 0)
if pixbuf.get_height() > pixbuf.get_width():
xy_ratio = float(pixbuf.get_width()) / pixbuf.get_height()
height = self.img_size
width = int(self.img_size * xy_ratio)
self.x = (self.img_size - width)/2
#x = int(cover_size / 2)
#x = x + (cover_size - width)
else:
xy_ratio = float(pixbuf.get_height()) / float(pixbuf.get_width())
width = self.img_size
height = int(self.img_size * xy_ratio)
self.y = (self.img_size - height)/2
#y = y + (cover_size - height)
#Set the conversion mode / quality
if self.quality == self.QUALITY_FAST: conversion_mode = gtk.gdk.INTERP_NEAREST #gtk.gdk.INTERP_TILES
elif self.quality == self.QUALITY_NORMAL: conversion_mode = gtk.gdk.INTERP_BILINEAR
elif self.quality == self.QUALITY_SLOW: conversion_mode = gtk.gdk.INTERP_HYPER
pixbuf = pixbuf.scale_simple(width, height, conversion_mode)
return pixbuf
def set_pixbuf(self, pixbuf):
pixbuf = self.resize_pixbuf(pixbuf)
self.main_pic.set_pixbuf(pixbuf)
self.main_pic.set_position(self.x, self.y)
self.main_pic.show()

View File

@ -14,7 +14,7 @@ class ImageRow(clutter.Group):
scaleFactor = 1.4
inactiveOpacity = 150
images_size_percent = 0.90 #This is the percentage of the total group size that the covers will take
images_size_percent = 1 #0.90 #This is the percentage of the total group size that the covers will take
fps = 35
frames = 25
@ -67,6 +67,7 @@ class ImageRow(clutter.Group):
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)
@ -89,7 +90,7 @@ class ImageRow(clutter.Group):
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):
if self.num_images > (self.num_columns-self.center-1):
tempGroup.set_opacity(0)
else:
self.images_group.add(tempGroup)
@ -109,22 +110,26 @@ class ImageRow(clutter.Group):
#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-1)
edge_texture_outgoing_no = outgoingItem - (self.center)
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):
edge_texture_incoming = self.textureLibrary[edge_texture_incoming_no]
self.images_group.add(edge_texture_incoming)
edge_texture_incoming = self.textureLibrary[edge_texture_incoming_no]
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.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)
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)
@ -197,55 +202,8 @@ class ImageRow(clutter.Group):
self.timeline.start()
#This moves the visible row of covers left and right
def rollViewer(self, direction, timeline):
if direction == self.DIRECTION_LEFT:
new_y = self.images_group.get_y() - self.image_size
self.max_visible_column += 1
self.min_visible_column += 1
#Define the row of image that now needs to disapear / appear
outgoing = self.min_visible_column - 1
incoming = self.max_visible_column - 1
#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 incoming > self.num_covers:
return None
elif direction == self.DIRECTION_RIGHT:
new_y = self.images_group.get_y() + self.image_size
self.max_visible_column -= 1
self.min_visible_column -= 1
#Define the row of covers that now needs to disapear / appear
outgoing = self.min_visible_column + 1
incoming = self.max_visible_column + 1
#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 outgoing > self.num_images:
return None
#Need to add the new image to the group
self.images_group.add(self.textureLibrary[incoming])
#And set the outgoing row to remove after the timeline finishes
self.timeline.connect('completed', self.removeItem, outgoing)
knots = (\
(self.images_group.get_x(), self.images_group.get_y()),\
(self.images_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)
self.behaviour_path.apply(self.images_group)
self.behaviour_outgoing.apply(self.textureLibrary[incoming])
self.behaviour_incoming.apply(self.textureLibrary[outgoing])
def remove_item(self, timeline = None, itemNo = None):
self.textureLibrary[itemNo].set_opacity(0)
self.images_group.remove(self.textureLibrary[itemNo])