- Further work on image_row

- Cleaned up input in music player
- Found source of race case in music players image row (IO bound my mysql query). Not yet fixed.
This commit is contained in:
noisymime 2008-03-26 22:31:52 +00:00
parent f30268f9e9
commit a264a2c5f2
7 changed files with 127 additions and 41 deletions

View File

@ -1,4 +1,5 @@
import clutter
import gobject
#########################################################
# The input queue controls fast user input by queing up
@ -6,10 +7,20 @@ import clutter
# are complete
#########################################################
class InputQueue:
class InputQueue(gobject.GObject):
NORTH, EAST, SOUTH, WEST = range(4)
#Setup signals
__gsignals__ = {
"queue-flushed": (
gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, []),
"entering-queue": (
gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, [])
}
def __init__(self):
gobject.GObject.__init__(self)
self.queue_north = 0
self.queue_east = 0
self.queue_south = 0
@ -33,6 +44,8 @@ class InputQueue:
return True
self.emit("entering-queue")
if event.keyval == clutter.keysyms.Left:
self.queue_west = self.queue_west + 1
return True
@ -76,6 +89,8 @@ class InputQueue:
self.queue_west = 0
self.queue_north = 0
self.emit("queue-flushed")
def is_in_queue(self):
if (self.queue_north > 0) or (self.queue_south > 0) or (self.queue_east > 0) or (self.queue_west > 0):
return True

View File

@ -12,32 +12,43 @@ class MusicObjectRow(ImageRow):
self.sleep = False
self.objectLibrary = []
self.timeline = None
def add_object(self, object):
self.objectLibrary.append(object)
def load_image_range(self, start, end, as_thread = False, thread_data = None):
#External timeline can be set by other objects as a form of 'lock'. If external timeline is running, thread will be paused
self.external_timeline = None
for i in range(start, end):
object = self.objectLibrary[i]
print "loading: " + object.name
pixbuf = object.get_image()
#If there is currently motion, we need to pause this work
if self.sleep:
self.timeline.connect('completed', self.restart_cb)
time.sleep(self.music_player.sleep_time)
while self.should_sleep():
time.sleep(0.1)
#if self.sleep:
#self.timeline.connect('completed', self.restart_cb)
#time.sleep(self.music_player.sleep_time)
if as_thread: clutter.threads_enter()
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()
pixbuf = object.get_default_image()
tmpImage = ImageFrame(pixbuf, 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=True, quality = ImageFrame.QUALITY_FAST)
if as_thread: clutter.threads_leave()
else:
pixbuf = object.get_default_image()
tmpImage = ImageFrame(pixbuf, self.image_size, use_reflection = True, quality = ImageFrame.QUALITY_FAST) #clutter.Texture()
if as_thread: clutter.threads_leave()
self.add_texture_group(tmpImage)
@ -59,6 +70,21 @@ class MusicObjectRow(ImageRow):
def restart_cb(self, data):
self.sleep = True
def should_sleep(self):
ret_val = False
#if self.sleep:
# return True
if not self.external_timeline is None:
if self.external_timeline.is_playing():
ret_val = True
if not self.timeline is None:
if self.timeline.is_playing():
ret_val = True
return ret_val
def get_current_object(self):
return self.objectLibrary[self.currentSelection]

View File

@ -14,6 +14,8 @@ class Module:
title = "Music"
num_columns = 6
sleep_time = 0.3
delay = 1
def __init__(self, glossMgr, dbMgr):
self.stage = glossMgr.get_stage()
@ -80,26 +82,24 @@ class Module:
if (event.keyval == clutter.keysyms.Left) or (event.keyval == clutter.keysyms.Right):
duration = float(MusicObjectRow.frames) / float(MusicObjectRow.fps)
self.artistImageRow.input_queue.input(event)
self.artistImageRow.input_queue.connect("queue-flushed", self.load_albums)
self.artistImageRow.sleep = True
#Just a little test code
artist = self.artistImageRow.get_current_object()
albums = self.backend.get_albums_by_artistID(artist.artistID)
self.list1.clear()
for album in albums:
tmpItem = self.list1.add_item(album.name)
tmpItem.connect("selected", self.process_songlist_from_album, album)
#name_string += album.name
self.list1.display()
#self.tmpLabel.set_text(name_string)
pixbuf = albums[0].get_image()
if not pixbuf is None:
self.main_img.set_pixbuf(pixbuf)
elif (event.keyval == clutter.keysyms.Down):
self.list1.select_first_elegant()
self.current_context = self.CONTEXT_LIST1
elif self.current_context == self.CONTEXT_LIST1:
if (event.keyval == clutter.keysyms.Down) or (event.keyval == clutter.keysyms.Up):
if (event.keyval == clutter.keysyms.Up):
#If we're at the top of the list already, we change focus bar to the image_row
if self.list1.selected == 0:
self.list1.select_none_elegant()
self.current_context = self.CONTEXT_ROW
else:
self.list1.input_queue.input(event)
elif (event.keyval == clutter.keysyms.Down):
self.list1.input_queue.input(event)
#Fills self.list2 with songs from an album
@ -110,6 +110,27 @@ class Module:
for song in songs:
tmpItem = self.list2.add_item(song.name)
self.list2.display()
#Simple delay
def start_delay(self, function, args):
gobject.timeout_add((self.delay * 1000), function, args)
#Loads albums into List1
def load_albums(self, queue):
#Just a little test code
return
artist = self.artistImageRow.get_current_object()
albums = self.backend.get_albums_by_artistID(artist.artistID)
self.list1.clear()
for album in albums:
tmpItem = self.list1.add_item(album.name)
tmpItem.connect("selected", self.process_songlist_from_album, album)
#name_string += album.name
self.list1.display()
#self.tmpLabel.set_text(name_string)
pixbuf = albums[0].get_image()
if not pixbuf is None:
self.main_img.set_pixbuf(pixbuf)
def begin(self, glossMgr):

View File

@ -6,25 +6,30 @@ from clutter.cluttercairo import CairoTexture
class Texture_Reflection (CairoTexture):
def __init__(self, origTexture, height = 0.5, opacity = 0.9):
def __init__(self, origTexture, reflection_height = 0.5, opacity = 0.9):
#clutter.Texture.__init__(self)
CairoTexture.__init__(self, origTexture.get_width(), origTexture.get_height())
#Connect to the textures pixbuf-change signal so the reflection will auto update
origTexture.connect("pixbuf-change", self.update_pixbuf)
self.reflection_height = reflection_height
self.opacity = opacity
if origTexture.get_pixbuf() is None:
return None
CairoTexture.__init__(self, origTexture.get_width(), origTexture.get_height())
#self.set_size(origTexture.get_width(), origTexture.get_height())
#self.set_pixbuf(origTexture.get_pixbuf())
self.update_pixbuf(origTexture)
def update_pixbuf(self, origTexture):
context = self.cairo_create()
ct = gtk.gdk.CairoContext(context)
self.gradient = cairo.LinearGradient(0, 0, 0, origTexture.get_pixbuf().get_height())
self.gradient.add_color_stop_rgba(1 - height, 1, 1, 1, 0)
self.gradient.add_color_stop_rgba(1, 0, 0, 0, opacity)
self.gradient.add_color_stop_rgba(1 - self.reflection_height, 1, 1, 1, 0)
self.gradient.add_color_stop_rgba(1, 0, 0, 0, self.opacity)
ct.set_source_pixbuf(origTexture.get_pixbuf(),0,0)
context.mask(self.gradient)
@ -53,7 +58,7 @@ class Texture_Reflection (CairoTexture):
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
@ -74,4 +79,5 @@ class Texture_Reflection (CairoTexture):
#Get/Set the location for it
(x, y) = origTexture.get_position()
self.set_position(x, y)
self.set_position(x, y)
"""

View File

@ -26,12 +26,7 @@ class ImageFrame(clutter.Group):
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
self.reflection = None
return
@ -79,4 +74,11 @@ class ImageFrame(clutter.Group):
pixbuf = self.resize_pixbuf(pixbuf)
self.main_pic.set_pixbuf(pixbuf)
self.main_pic.set_position(self.x, self.y)
self.main_pic.show()
self.main_pic.show()
if self.use_reflection:
self.reflection = Texture_Reflection(self.main_pic)
self.add(self.reflection)
self.reflection.show()
else:
self.reflection = None

View File

@ -93,8 +93,9 @@ 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-1):
if self.num_images > (self.num_columns-self.center):
tempGroup.set_opacity(0)
tempGroup.hide()
else:
self.images_group.add(tempGroup)
@ -129,6 +130,7 @@ class ImageRow(clutter.Group):
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)
@ -214,6 +216,8 @@ class ImageRow(clutter.Group):
def remove_item(self, timeline = None, itemNo = None):
self.textureLibrary[itemNo].set_opacity(0)
self.textureLibrary[itemNo].hide()
self.textureLibrary[itemNo].unrealize()
self.images_group.remove(self.textureLibrary[itemNo])

View File

@ -144,6 +144,18 @@ class LabelList(clutter.Group):
def select_first_elegant(self):
self.select_first(frames=self.frames, fps=self.fps)
def select_none(self, frames = 1, fps = 75):
self.timeline = clutter.Timeline(frames, fps)
self.input_queue.set_timeline(self.timeline)
self.selected = None
for i in range(0,len(self.items)):
self.items[i].scaleLabel(ListItem.SCALE_NONE, self.timeline)
self.timeline.start()
def select_none_elegant(self):
self.select_none(self.frames, self.fps)
#When the menu needs to display a new item from the top or bottom, it rolls
# The distance the menu moves is the distance (in pixels) between the incoming item and the selector bar
def rollList(self, incomingMenuItem, outgoingMenuItem, timeline):