class PersonItem(PhotoContentItem): def __init__(self, person, themed=False, **kwargs): PhotoContentItem.__init__(self, **kwargs) self.person = person self.__themed = themed if themed: self.set_themed() model = DataModel(bigboard.globals.server_name) self.set_clickable(True) self.__photo = CanvasMugshotURLImage(scale_width=45, scale_height=45, border=1, border_color=0x000000ff) self.set_photo(self.__photo) self.__details_box = CanvasVBox() self.set_child(self.__details_box) nameklass = themed and ThemedText or hippo.CanvasText self.__name = nameklass(xalign=hippo.ALIGNMENT_START, yalign=hippo.ALIGNMENT_START, size_mode=hippo.CANVAS_SIZE_ELLIPSIZE_END) self.__details_box.append(self.__name) self.__presence_box = CanvasHBox(spacing=4) self.__details_box.append(self.__presence_box) self.__statuses = [] self.__status_box = CanvasHBox() self.__details_box.append(self.__status_box) self.connect('button-press-event', self.__handle_button_press) self.connect('button-release-event', self.__handle_button_release) self.__pressed = False self.__aim_icon = None self.__xmpp_icon = None self.__current_track = None self.__current_track_timeout = None if self.person.is_contact: try: user = self.person.resource.user except AttributeError: user = None if user: query = model.query_resource(user, "currentTrack +;currentTrackPlayTime") query.execute() user.connect(self.__update_current_track, 'currentTrack') user.connect(self.__update_current_track, 'currentTrackPlayTime') self.__update_current_track(user) self.person.connect('display-name-changed', self.__update) self.person.connect('icon-url-changed', self.__update) self.person.connect('aim-buddy-changed', self.__update_aim_buddy) self.person.connect('xmpp-buddy-changed', self.__update_xmpp_buddy) self.__update(self.person) self.__update_aim_buddy(self.person) self.__update_xmpp_buddy(self.person) def __update_color(self): if self.__pressed: self.set_property('background-color', 0x00000088) else: self.sync_prelight_color() def __handle_button_press(self, self2, event): if event.button != 1 or event.count != 1: return False self.__pressed = True self.__update_color() return False def __handle_button_release(self, self2, event): if event.button != 1: return False self.__pressed = False self.__update_color() return False def get_person(self): return self.person def set_size(self, size): if size == bigboard.stock.SIZE_BULL: self.set_child_visible(self.__details_box, True) self.__photo.set_property('xalign', hippo.ALIGNMENT_START) self.__photo.set_property('yalign', hippo.ALIGNMENT_START) else: self.set_child_visible(self.__details_box, False) self.__photo.set_property('xalign', hippo.ALIGNMENT_CENTER) self.__photo.set_property('yalign', hippo.ALIGNMENT_CENTER) def __update(self, person): self.__name.set_property("text", self.person.display_name) #+ " " + str(self.person._debug_rank)) self.__photo.set_url(self.person.icon_url) def __reset_im_status(self): buddies = self.person.aim_buddies + self.person.xmpp_buddies if len(buddies) > 0: sm = StatusMessage(themed=self.__themed) sm.set_buddies(buddies) self.__set_status(STATUS_IM, sm) def __update_aim_buddy(self, person): if person.aim_buddy: if not self.__aim_icon: self.__aim_icon = AimIcon(person.aim_buddy, theme_hints=(not self.__themed and 'notheme' or [])) self.__presence_box.append(self.__aim_icon) else: if self.__aim_icon: self.__aim_icon.destroy() self.__aim_icon = None self.__reset_im_status() def __update_xmpp_buddy(self, person): if person.xmpp_buddy: if not self.__xmpp_icon: self.__xmpp_icon = XMPPIcon(person.xmpp_buddy, theme_hints=(not self.__themed and 'notheme' or [])) self.__presence_box.append(self.__xmpp_icon) else: if self.__xmpp_icon: self.__xmpp_icon.destroy() self.__xmpp_icon = None self.__reset_im_status() def __timeout_track(self): self.__current_track_timeout = None self.__update_current_track(self.person.resource.user) return False def __update_current_track(self, user): try: current_track = user.currentTrack current_track_play_time = user.currentTrackPlayTime / 1000. except AttributeError: current_track = None current_track_play_time = -1 _logger.debug("current track %s" % str(current_track)) # current_track_play_time < 0, current_track != None might indicate stale # current_track data if current_track_play_time < 0: current_track = None if current_track != None: now = time.time() if current_track.duration < 0: endTime = current_track_play_time + 30 * 60 # Half hour else: endTime = current_track_play_time + current_track.duration / 1000. # msec => sec if now >= endTime: current_track = None if current_track != self.__current_track: self.__current_track = current_track if self.__current_track_timeout: gobject.source_remove(self.__current_track_timeout) if current_track != None: # We give 30 seconds of lee-way, so that the track is pretty reliably really stopped self.__current_track_timeout = gobject.timeout_add(int((endTime + 30 - now) * 1000), self.__timeout_track) if current_track != None: self.__set_status(STATUS_MUSIC, TrackItem(current_track)) else: self.__set_status(STATUS_MUSIC, None) def __set_status(self, type, contents): if len(self.__statuses) > 0: old_contents = self.__statuses[0][1] else: old_contents = None for i in range(0,len(self.__statuses)): (i_type,i_contents) = self.__statuses[i] if i_type == type: i_contents.destroy() del self.__statuses[i] if i == 0: old_contents = None break if old_contents != None: old_contents.set_visible(False) if contents != None: self.__statuses.insert(0, (type, contents)) self.__status_box.append(contents) if len(self.__statuses) > 0: new_contents = self.__statuses[0][1] new_contents.set_visible(True) def get_screen_coords(self): return self.get_context().translate_to_screen(self)
class AppDisplay(PhotoContentItem): __gsignals__ = { "title-clicked" : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, ()), } def __init__(self, app_location, app=None, **kwargs): if app_location == AppLocation.STOCK: kwargs['enable_theme'] = True PhotoContentItem.__init__(self, border_right=6, **kwargs) self.__app = None self.__description_mode = False self._logger = logging.getLogger('bigboard.AppDisplay') self.__photo = CanvasMugshotURLImage(scale_width=30, scale_height=30) self.set_photo(self.__photo) self.__box = CanvasVBox(spacing=2, border_right=4) sub_kwargs = {} if kwargs.has_key('color'): sub_kwargs['color'] = kwargs['color'] title_kwargs = dict(sub_kwargs) title_kwargs.update({'font': '14px', 'xalign': hippo.ALIGNMENT_START, 'size-mode': hippo.CANVAS_SIZE_ELLIPSIZE_END }) if app_location == AppLocation.STOCK: self.__title = ThemedLink(**title_kwargs) else: self.__title = ActionLink(**title_kwargs) self.__title.connect("activated", lambda t: self.emit("title-clicked")) subtitle_kwargs = {'font': '10px', 'xalign': hippo.ALIGNMENT_START, 'size-mode': hippo.CANVAS_SIZE_ELLIPSIZE_END } if app_location == AppLocation.STOCK: self.__subtitle = ThemedText(theme_hints=['subforeground'], **subtitle_kwargs) else: self.__subtitle = hippo.CanvasText(**subtitle_kwargs) self.__box.append(self.__title) self.__box.append(self.__subtitle) self.set_child(self.__box) self.__description = hippo.CanvasText(size_mode=hippo.CANVAS_SIZE_WRAP_WORD, **sub_kwargs) self.__box.append(self.__description) self.__photo.set_clickable(True) self.__box.set_clickable(True) self.__app_location = app_location if app: self.set_app(app) def set_description_mode(self, mode): self.__description_mode = mode self.__app_display_sync() def get_app(self): return self.__app def set_app(self, app): self.__app = app self.__app_display_sync() def __get_name(self): if self.__app is None: return "unknown" return self.__app.get_name() def __str__(self): return '<AppDisplay name="%s">' % (self.__get_name()) def __app_display_sync(self): if not self.__app: return self.__box.set_child_visible(self.__subtitle, not self.__description_mode) self.__box.set_child_visible(self.__description, self.__description_mode) self.__title.set_property("text", self.__app.get_name()) if self.__app.is_installed() or self.__app_location == AppLocation.DESCRIPTION_HEADER: self.__subtitle.set_property("text", self.__app.get_generic_name() or self.__app.get_tooltip() or self.__app.get_comment()) ## for now, install won't work if not connected elif self.__app_location == AppLocation.STOCK and globals.get_data_model().ready and globals.get_data_model().global_resource.online: self.__subtitle.set_property('text', "(Click to Install)") else: self.__subtitle.set_property('text', "(Not Installed)") self.__description.set_property("text", self.__app.get_description()) if self.__app.get_icon_url(): self.__photo.set_url(self.__app.get_icon_url()) else: pixbuf = self.__app.get_local_pixbuf() if pixbuf: self.__photo.set_property("image", hippo.cairo_surface_from_gdk_pixbuf(pixbuf)) def launch(self): self._logger.debug("launching app %s", self) self.__app.launch()
class AppDisplay(PhotoContentItem): __gsignals__ = { "title-clicked" : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, ()), } def __init__(self, app=None, **kwargs): PhotoContentItem.__init__(self, border_right=6, **kwargs) self.__app = None self.__description_mode = False self._logger = logging.getLogger('bigboard.AppDisplay') self.__photo = CanvasMugshotURLImage(scale_width=30, scale_height=30) self.set_photo(self.__photo) self.__box = CanvasVBox(spacing=2, border_right=4) sub_kwargs = {} if kwargs.has_key('color'): sub_kwargs['color'] = kwargs['color'] self.__title = ActionLink(font="14px",xalign=hippo.ALIGNMENT_START, size_mode=hippo.CANVAS_SIZE_ELLIPSIZE_END, **sub_kwargs) self.__title.connect("activated", lambda t: self.emit("title-clicked")) self.__subtitle = hippo.CanvasText(font="10px",xalign=hippo.ALIGNMENT_START, size_mode=hippo.CANVAS_SIZE_ELLIPSIZE_END) attrs = pango.AttrList() attrs.insert(pango.AttrForeground(0x6666, 0x6666, 0x6666, 0, 0xFFFF)) self.__subtitle.set_property("attributes", attrs) self.__box.append(self.__title) self.__box.append(self.__subtitle) self.set_child(self.__box) self.__description = hippo.CanvasText(size_mode=hippo.CANVAS_SIZE_WRAP_WORD, **sub_kwargs) self.__box.append(self.__description) if app: self.set_app(app) def set_description_mode(self, mode): self.__description_mode = mode self.__app_display_sync() def get_app(self): return self.__app def set_app(self, app): self.__app = app self.__app.connect("changed", lambda app: self.__app_display_sync()) self.__app_display_sync() def __get_name(self): if self.__app is None: return "unknown" return self.__app.get_name() def __str__(self): return '<AppDisplay name="%s">' % (self.__get_name()) # override def do_prelight(self): return self.__app.is_installed() def __app_display_sync(self): if not self.__app: return self.__box.set_child_visible(self.__subtitle, not self.__description_mode) self.__box.set_child_visible(self.__description, self.__description_mode) self.__photo.set_clickable(self.__app.is_installed()) self.__box.set_clickable(self.__app.is_installed()) self.__title.set_property("text", self.__app.get_name()) self.__subtitle.set_property("text", self.__app.get_generic_name() or self.__app.get_tooltip() or self.__app.get_comment()) self.__description.set_property("text", self.__app.get_description()) if self.__app.get_mugshot_app(): self.__photo.set_url(self.__app.get_mugshot_app().get_icon_url()) else: pixbuf = self.__app.get_local_pixbuf() if pixbuf: self.__photo.set_property("image", hippo.cairo_surface_from_gdk_pixbuf(pixbuf)) def launch(self): self._logger.debug("launching app %s", self) self.__app.launch()
class EntityItem(PhotoContentItem): def __init__(self, **kwargs): PhotoContentItem.__init__(self, **kwargs) self.__entity = None self.__photo = CanvasMugshotURLImage(scale_width=30, scale_height=30, border=1, border_color=0x000000ff) self.set_photo(self.__photo) self.__name = hippo.CanvasText(xalign=hippo.ALIGNMENT_FILL, yalign=hippo.ALIGNMENT_START, size_mode=hippo.CANVAS_SIZE_ELLIPSIZE_END) self.set_child(self.__name) self.connect('button-press-event', self.__handle_button_press) self.connect('button-release-event', self.__handle_button_release) self.__pressed = False def __update_color(self): if self.__pressed: self.set_property('background-color', 0x00000088) else: self.sync_prelight_color() def __handle_button_press(self, self2, event): if event.button != 1: return False self.__pressed = True self.__update_color() def __handle_button_release(self, self2, event): if event.button != 1: return False self.__pressed = False self.__update_color() def set_entity(self, entity): if self.__entity == entity: return self.__entity = entity self.__update() def get_guid(self): return self.__entity.get_guid() def get_entity(self): return self.__entity def set_size(self, size): if size == bigboard.stock.SIZE_BULL: self.set_child_visible(self.__name, True) self.__photo.set_property('xalign', hippo.ALIGNMENT_START) self.__photo.set_property('yalign', hippo.ALIGNMENT_START) else: self.set_child_visible(self.__name, False) self.__photo.set_property('xalign', hippo.ALIGNMENT_CENTER) self.__photo.set_property('yalign', hippo.ALIGNMENT_CENTER) def __update(self): if not self.__entity: return self.__name.set_property("text", self.__entity.get_name()) if self.__entity.get_photo_url(): self.__photo.set_url(self.__entity.get_photo_url()) def get_screen_coords(self): return self.get_context().translate_to_screen(self)