- Added smooth handling of protocol version failure
- Further work on music display
This commit is contained in:
parent
e18cc38867
commit
62edc69faf
25
GlossMgr.py
25
GlossMgr.py
|
@ -120,22 +120,27 @@ class GlossMgr:
|
|||
if not self.currentPlugin == None:
|
||||
#Plugins on_key_press_event should return true if the plugin is finishing
|
||||
if self.currentPlugin.on_key_press_event(stage, event):
|
||||
self.currentPlugin.stop()
|
||||
self.currentPlugin = None
|
||||
|
||||
timeline_stop = clutter.Timeline(10,30)
|
||||
alpha = clutter.Alpha(timeline_stop, clutter.ramp_inc_func)
|
||||
self.stop_behaviour = clutter.BehaviourOpacity(opacity_start=0, opacity_end=255, alpha=alpha)
|
||||
self.currentMenu.set_opacity(0)
|
||||
self.currentMenu.show()
|
||||
self.stop_behaviour.apply(self.currentMenu)
|
||||
timeline_stop.start()
|
||||
self.kill_plugin()
|
||||
#If there's no plugin running, go back one in the menu list (Providing we're not already at the first item.
|
||||
else:
|
||||
if len(self.menuHistory)>1:
|
||||
self.transition.do_transition(self.menuHistory.pop(), self.menuHistory[-1])
|
||||
self.currentMenu = self.menuHistory[-1]
|
||||
#print event.hardware_keycode
|
||||
|
||||
#Kills any currently running plugin/s
|
||||
def kill_plugin(self):
|
||||
if not self.currentPlugin is None:
|
||||
self.currentPlugin.stop()
|
||||
self.currentPlugin = None
|
||||
|
||||
timeline_stop = clutter.Timeline(10,30)
|
||||
alpha = clutter.Alpha(timeline_stop, clutter.ramp_inc_func)
|
||||
self.stop_behaviour = clutter.BehaviourOpacity(opacity_start=0, opacity_end=255, alpha=alpha)
|
||||
self.currentMenu.set_opacity(0)
|
||||
self.currentMenu.show()
|
||||
self.stop_behaviour.apply(self.currentMenu)
|
||||
timeline_stop.start()
|
||||
|
||||
def get_current_menu(self):
|
||||
return self.currentMenu
|
||||
|
|
|
@ -6,6 +6,7 @@ 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
|
||||
from ui_elements.label_list import LabelList
|
||||
|
||||
class Module:
|
||||
title = "Music"
|
||||
|
@ -79,10 +80,12 @@ class Module:
|
|||
#Just a little test code
|
||||
artist = self.artistImageRow.get_current_object()
|
||||
albums = self.backend.get_albums_by_artistID(artist.artistID)
|
||||
name_string = ""
|
||||
self.list1.clear()
|
||||
for album in albums:
|
||||
name_string += album.name
|
||||
self.tmpLabel.set_text(name_string)
|
||||
self.list1.add_item(album.name)
|
||||
#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)
|
||||
|
@ -112,12 +115,17 @@ class Module:
|
|||
self.backdrop_behaviour.apply(self.artistImageRow)
|
||||
|
||||
#Just a nasty temp label for outputting stuff
|
||||
self.list1 = LabelList(5)
|
||||
self.list1.set_position(self.stage.get_width()/2, 350)
|
||||
self.stage.add(self.list1)
|
||||
"""
|
||||
self.tmpLabel = clutter.Label()
|
||||
self.tmpLabel.set_color(clutter.color_parse('White'))
|
||||
self.tmpLabel.set_position(0, 350)
|
||||
self.tmpLabel.set_text("Test")
|
||||
self.tmpLabel.show()
|
||||
self.stage.add(self.tmpLabel)
|
||||
"""
|
||||
|
||||
#The preview img
|
||||
self.main_img = ImageFrame(None, 300, True) #clutter.Texture()
|
||||
|
|
|
@ -77,7 +77,9 @@ class MythBackendConnection(threading.Thread):
|
|||
|
||||
if not result == protRecvString:
|
||||
#Protocol Version check failed
|
||||
raise RuntimeError, "Myth Protocol version failure. Aborting."
|
||||
backend_protocol = result.rsplit("[]:[]")[1]
|
||||
err_string = "Myth Protocol version failure. This client uses protocol %s however backend is using %s." % (self.protocolVersion, backend_protocol)
|
||||
raise RuntimeError(err_string)
|
||||
|
||||
#Perform the mandatory ANN
|
||||
ANNstring = "ANN Playback " + self.localhost_name + " 0"
|
||||
|
@ -214,7 +216,8 @@ class MythBackendConnection(threading.Thread):
|
|||
result = self.receive_reply(self.msg_sock)
|
||||
if not result == protRecvString:
|
||||
#Protocol Version check failed
|
||||
raise RuntimeError, "Myth Protocol version failure. Aborting."
|
||||
return
|
||||
|
||||
|
||||
#Perform the mandatory ANN (The 1 at the end says that we want to receive all messages from the server)
|
||||
ANNstring = "ANN Monitor " + self.localhost_name + " 1"
|
||||
|
|
|
@ -38,10 +38,10 @@ class Module:
|
|||
def action(self):
|
||||
return self
|
||||
|
||||
def begin(self, menuMgr):
|
||||
self.menuMgr = menuMgr
|
||||
def begin(self, glossMgr):
|
||||
self.glossMgr = glossMgr
|
||||
#self.buffer_file_reader = open("test.mpg","r")
|
||||
menuMgr.get_selector_bar().set_spinner(True)
|
||||
glossMgr.get_selector_bar().set_spinner(True)
|
||||
self.loading_scr = SplashScr(self.stage)
|
||||
self.loading_scr.set_msg("Starting TV...")
|
||||
self.loading_scr.backdrop.set_opacity(180)
|
||||
|
@ -49,14 +49,22 @@ class Module:
|
|||
|
||||
|
||||
(self.server, self.port) = self.dbMgr.get_backend_server()
|
||||
self.myConn = MythBackendConnection(self, self.server, self.port)
|
||||
try:
|
||||
self.myConn = MythBackendConnection(self, self.server, self.port)
|
||||
except RuntimeError, e:
|
||||
self.loading_scr.remove_elegant()
|
||||
glossMgr.get_selector_bar().set_spinner(False)
|
||||
self.glossMgr.display_msg("Error", str(e.args[0]))
|
||||
glossMgr.kill_plugin()
|
||||
return
|
||||
|
||||
self.videoController.connect("playing", self.complete_change)
|
||||
self.myConn.start()
|
||||
|
||||
self.isRunning = True
|
||||
|
||||
def begin_playback(self, fd):#buffer_file):
|
||||
self.menuMgr.get_selector_bar().set_spinner(False)
|
||||
self.glossMgr.get_selector_bar().set_spinner(False)
|
||||
|
||||
#uri = "file://" + os.getcwd() +"/" + buffer_file
|
||||
#f = open(os.getcwd() +"/" + buffer_file, 'r')
|
||||
|
|
|
@ -1,58 +1,122 @@
|
|||
import clutter
|
||||
import pango
|
||||
from InputQueue import InputQueue
|
||||
|
||||
class LabelList(clutter.Group):
|
||||
DIRECTION_UP, DIRECTION_DOWN = range(2)
|
||||
|
||||
def __init__(self):
|
||||
fps = 35
|
||||
frames = 25
|
||||
|
||||
#Default font
|
||||
font_string = "Tahoma 30"
|
||||
item_gap = 0
|
||||
|
||||
def __init__(self, length):
|
||||
clutter.Group.__init__(self)
|
||||
self.items = []
|
||||
|
||||
#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.selected = 0
|
||||
self.displayMin = 0 #The number of menu items that will be shown at a time
|
||||
self.displayMax = length
|
||||
self.displaySize = self.displayMax - self.displayMin
|
||||
|
||||
def on_key_press_event (self, event):
|
||||
self.input_queue.input(event)
|
||||
return self.timeline
|
||||
|
||||
def add_item(self, itemLabel):
|
||||
if len(self.items) == 0:
|
||||
#Perform a cheap hack to figure out the height of a label
|
||||
tempLabel = clutter.Label()
|
||||
tempLabel.set_font_name(self.font_string)
|
||||
tempLabel.set_text("S")
|
||||
|
||||
self.label_height = tempLabel.get_height()
|
||||
label_width = 0
|
||||
|
||||
label_y = len(self.items) * (self.label_height + self.item_gap)
|
||||
|
||||
newItem = ListItem(self.font_string, itemLabel)
|
||||
newItem.set_position(0, label_y)
|
||||
newItem.show()
|
||||
self.items.append(newItem)
|
||||
|
||||
self.add(newItem)
|
||||
return newItem
|
||||
|
||||
#Removes all items from the list
|
||||
def clear(self):
|
||||
for item in self.items:
|
||||
self.remove(item)
|
||||
item = None
|
||||
self.items = []
|
||||
|
||||
|
||||
def display(self):
|
||||
if self.displayMax > len(self.items):
|
||||
self.displayMax = len(self.items)
|
||||
self.displaySize = self.displayMax - self.displayMin
|
||||
|
||||
#for i in range(self.displaySize):
|
||||
# self.menuItems[i].show()
|
||||
|
||||
self.show()
|
||||
|
||||
def move_selection(self, direction):
|
||||
|
||||
#Check if we're at the first item in the list
|
||||
if (self.selected) != 0:
|
||||
self.timeline = clutter.Timeline (15,85)
|
||||
self.input_queue.set_timeline(self.timeline)
|
||||
#self.timeline.connect('completed', self.completeMove)
|
||||
|
||||
if not self.moveQueue == 0:
|
||||
self.selected = self.selected -1 #+ self.moveQueue
|
||||
self.moveQueue = self.moveQueue + 1 # 0
|
||||
if self.selected < 0:
|
||||
self.selected = 0
|
||||
|
||||
if direction == self.DIRECTION_DOWN:
|
||||
#Check if we're at the last item in the list
|
||||
if (self.selected) == (len(self.menuItems)-1):
|
||||
return
|
||||
else:
|
||||
self.selected = self.selected+1
|
||||
elif direction == self.DIRECTION_UP:
|
||||
#Check if we're at the first / last item in the list
|
||||
if (self.selected) == 0:
|
||||
return
|
||||
else:
|
||||
self.selected = self.selected-1
|
||||
|
||||
#This horrible loop does all the scaling
|
||||
#This includes, the selected item and the ones on either side of it
|
||||
for i in range(len(self.menuItems)):
|
||||
#print str(i)
|
||||
if i == self.selected:
|
||||
self.menuItems[i].scaleLabel(0, self.timeline)
|
||||
elif (i == self.selected-1) and (i >= self.displayMin):
|
||||
self.menuItems[i].scaleLabel(1, self.timeline)
|
||||
elif (i == self.selected+1) and (i <= self.displayMax-1):
|
||||
self.menuItems[i].scaleLabel(1, self.timeline)
|
||||
else:
|
||||
self.menuItems[i].scaleLabel(2, self.timeline)
|
||||
|
||||
#Do the transition of the menu graphic
|
||||
#If there's no transition set (Would have been set in the theme) then the item is simply show
|
||||
if not self.menu_item_transition is None:
|
||||
self.menu_item_transition.backward(self.timeline, self.menuItems[self.selected+1].itemTexturesGroup, self.menuItems[self.selected].itemTexturesGroup)
|
||||
else:
|
||||
self.menuItems[self.selected].itemTexturesGroup.show()
|
||||
|
||||
#Check we're at the top of the viewable list
|
||||
if self.selected < (self.displayMin):
|
||||
#If yes, move the menu, leave the selection bar where is
|
||||
#self.menuItems[self.selected].set_opacity(0)
|
||||
#self.menuItems[self.selected].show()
|
||||
self.rollMenu( self.menuItems[self.selected], self.menuItems[self.selected+self.displaySize], self.timeline)
|
||||
else:
|
||||
#move the selection bar
|
||||
self.glossMgr.get_selector_bar().selectItem(self.menuItems[self.selected], self.timeline)
|
||||
|
||||
self.timeline = clutter.Timeline (self.frames, self.fps)
|
||||
self.input_queue.set_timeline(self.timeline)
|
||||
|
||||
self.timeline.start()
|
||||
|
||||
#This horrible loop does all the scaling
|
||||
#This includes, the selected item and the ones on either side of it
|
||||
for i in range(len(self.items)):
|
||||
#print str(i)
|
||||
if i == self.selected:
|
||||
self.items[i].scaleLabel(ListItem.SCALE_FULL, self.timeline)
|
||||
elif (i == self.selected-1) and (i >= self.displayMin):
|
||||
self.items[i].scaleLabel(ListItem.SCALE_MEDIUM, self.timeline)
|
||||
elif (i == self.selected+1) and (i <= self.displayMax-1):
|
||||
self.items[i].scaleLabel(ListItem.SCALE_MEDIUM, self.timeline)
|
||||
else:
|
||||
self.items[i].scaleLabel(ListItem.SCALE_None, self.timeline)
|
||||
|
||||
#Check we're at the top of the viewable list
|
||||
if self.selected < (self.displayMin):
|
||||
#If yes, move the menu, leave the selection bar where is
|
||||
#self.menuItems[self.selected].set_opacity(0)
|
||||
#self.menuItems[self.selected].show()
|
||||
self.rollList( self.menuItems[self.selected], self.menuItems[self.selected+self.displaySize], self.timeline)
|
||||
else:
|
||||
#move the selection bar
|
||||
self.glossMgr.get_selector_bar().selectItem(self.menuItems[self.selected], self.timeline)
|
||||
|
||||
self.timeline.start()
|
||||
|
||||
def move_up(self):
|
||||
self.move_selection(self.DIRECTION_UP)
|
||||
|
||||
def move_down(self):
|
||||
self.move_selection(self.DIRECTION_DOWN)
|
||||
|
||||
def selectFirst(self, moveBar):
|
||||
if self.timeline.is_playing:
|
||||
|
@ -60,13 +124,13 @@ class LabelList(clutter.Group):
|
|||
|
||||
self.timeline = clutter.Timeline(1, 75)
|
||||
self.selected = 0
|
||||
for i in range(0,len(self.menuItems)):
|
||||
for i in range(0,len(self.items)):
|
||||
if i == 0:
|
||||
self.menuItems[i].scaleLabel(0, self.timeline)
|
||||
self.items[i].scaleLabel(ListItem.SCALE_FULL, self.timeline)
|
||||
elif i == 1:
|
||||
self.menuItems[i].scaleLabel(1, self.timeline)
|
||||
self.items[i].scaleLabel(ListItem.SCALE_MEDIUM, self.timeline)
|
||||
else:
|
||||
self.menuItems[i].scaleLabel(2, self.timeline)
|
||||
self.items[i].scaleLabel(ListItem.SCALE_NONE, self.timeline)
|
||||
|
||||
#Show the current menu item's graphic
|
||||
self.menuItems[self.selected].itemTexturesGroup.show()
|
||||
|
@ -78,7 +142,7 @@ class LabelList(clutter.Group):
|
|||
|
||||
#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 rollMenu(self, incomingMenuItem, outgoingMenuItem, timeline):
|
||||
def rollList(self, incomingMenuItem, outgoingMenuItem, timeline):
|
||||
print "Rolling: " + incomingMenuItem.data + "<------" + outgoingMenuItem.data
|
||||
(group_x, group_y) = self.itemGroup.get_abs_position()
|
||||
(bar_x, bar_y) = self.glossMgr.get_selector_bar().get_abs_position() # incomingMenuItem.get_menu().getMenuMgr().
|
||||
|
@ -121,7 +185,7 @@ class LabelList(clutter.Group):
|
|||
self.behaviour2.apply(outgoingMenuItem)
|
||||
|
||||
|
||||
class SimpleListItem(clutter.group):
|
||||
class ListItem(clutter.Group):
|
||||
SCALE_NONE, SCALE_MEDIUM, SCALE_FULL = range(3)
|
||||
|
||||
#Default values for zoom and opacity
|
||||
|
@ -131,42 +195,31 @@ class SimpleListItem(clutter.group):
|
|||
scale_step_full = 1
|
||||
scale_step_medium = 0.5
|
||||
scale_step_none = 0.4
|
||||
|
||||
#Default font
|
||||
font_string = "Tahoma 30"
|
||||
|
||||
label_left = clutter.Label()
|
||||
label_right = clutter.Label()
|
||||
|
||||
def __init__ (self, font, label_left = "", label_right = "", y):
|
||||
def __init__ (self, font, label_left = "", label_right = ""):
|
||||
clutter.Group.__init__ (self) #, menu, itemLabel, y)
|
||||
self.glossMgr = menu.getGlossMgr()
|
||||
#self.menu = menu
|
||||
#self.stage = glossMgr.get_stage()
|
||||
|
||||
#ItemTexturesGroup is what shows any images / reflections associated with the item
|
||||
#self.itemTexturesGroup = clutter.Group()
|
||||
#self.itemTexturesGroup.set_position(menu.menu_image_x, menu.menu_image_y)
|
||||
self.label_left = clutter.Label()
|
||||
self.label_right = clutter.Label()
|
||||
|
||||
|
||||
#setup the label
|
||||
"""
|
||||
font = menu.font
|
||||
self.set_font_name(font)
|
||||
self.set_text(itemLabel)
|
||||
#setup the label/s
|
||||
self.add(self.label_left)
|
||||
self.label_left.show()
|
||||
self.label_left.set_font_name(font)
|
||||
self.label_left.set_text(label_left)
|
||||
self.color = clutter.Color(0xff, 0xff, 0xff, 0xdd)
|
||||
self.set_color(self.color)
|
||||
self.label_left.set_color(self.color)
|
||||
self.currentOpacity = 255
|
||||
self.data = itemLabel #By default the items data is simply its label
|
||||
self.data = label_left #By default the items data is simply its label
|
||||
|
||||
#The width is the length of the selector bar minus its offset
|
||||
width = self.glossMgr.get_selector_bar().get_width() + self.glossMgr.get_selector_bar().get_x_offset()
|
||||
self.set_width(width)
|
||||
#width = self.glossMgr.get_selector_bar().get_width() + self.glossMgr.get_selector_bar().get_x_offset()
|
||||
#self.set_width(width)
|
||||
|
||||
self.label_left.set_ellipsize(pango.ELLIPSIZE_END)
|
||||
|
||||
self.set_ellipsize(pango.ELLIPSIZE_END)
|
||||
"""
|
||||
#Text is actually scaled down in 'regular' position so that it doesn't get jaggies when zoomed in
|
||||
self.set_scale(self.zoomLevel, self.zoomLevel)
|
||||
#self.set_scale(self.zoomLevel, self.zoomLevel)
|
||||
self.currentZoom = 0
|
||||
|
||||
"""
|
||||
|
@ -174,10 +227,6 @@ class SimpleListItem(clutter.group):
|
|||
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)
|
||||
|
||||
#Add textures group and mark whether or not the textures are currently on the stage
|
||||
self.itemTexturesGroup.show_all()
|
||||
self.onStage = False
|
||||
"""
|
||||
|
||||
def scaleLabel(self, level, timeline):
|
||||
|
@ -217,14 +266,6 @@ class SimpleListItem(clutter.group):
|
|||
|
||||
def get_zoom_level(self):
|
||||
return self.zoomLevel
|
||||
|
||||
|
||||
def add_image_from_path(self, path, x, y):
|
||||
self.tempTexture = clutter.Texture()
|
||||
pixbuf = gtk.gdk.pixbuf_new_from_file(path)
|
||||
tempTexture.set_pixbuf(pixbuf)
|
||||
|
||||
self.add_image_from_texture(tempTexture, x, y)
|
||||
|
||||
def set_data(self, data):
|
||||
self.data = data
|
||||
|
|
Loading…
Reference in New Issue