示例#1
0
    def calc_geometry(self, object, copy_object=0):
        """
        calculate the real values of the object (e.g. content) based
        on the geometry of the area
        """
        if copy_object:
            object = copy.copy(object)

        font_h = 0

        if isinstance(object.width, types.TupleType):
            object.width = int(eval_attr(object.width, self.area_val.width))

        if isinstance(object.height, types.TupleType):
            object.height = int(eval_attr(object.height, self.area_val.height))

        object.x += self.area_val.x
        object.y += self.area_val.y

        if not object.width:
            object.width = self.area_val.width

        if not object.height:
            object.height = self.area_val.height

        if object.width + object.x > self.area_val.width + self.area_val.x:
            object.width = self.area_val.width - object.x

        if object.height + object.y > self.area_val.height + self.area_val.y:
            object.height = self.area_val.height + self.area_val.y - object.y

        return object
示例#2
0
    def calc_geometry(self, object, copy_object=0):
        """
        calculate the real values of the object (e.g. content) based
        on the geometry of the area
        """
        if copy_object:
            object = copy.copy(object)

        font_h=0

        if isinstance(object.width, types.TupleType):
            object.width = int(eval_attr(object.width, self.area_val.width))

        if isinstance(object.height, types.TupleType):
            object.height = int(eval_attr(object.height, self.area_val.height))

        object.x += self.area_val.x
        object.y += self.area_val.y

        if not object.width:
            object.width = self.area_val.width

        if not object.height:
            object.height = self.area_val.height

        if object.width + object.x > self.area_val.width + self.area_val.x:
            object.width = self.area_val.width - object.x

        if object.height + object.y > self.area_val.height + self.area_val.y:
            object.height = self.area_val.height + self.area_val.y - object.y

        return object
示例#3
0
    def _draw(self):
        """
        The actual internal draw function.

        """
        _debug_('Window::_draw %s' % self, 2)

        if not self.width or not self.height:
            raise TypeError, 'Not all needed variables set.'

        cheight = self.content.height
        self.content.layout()

        # resize when content changed the height because of the layout()
        if self.content.height - cheight > 0:
            self.height += self.content.height - cheight

        self.surface = self.osd.Surface(self.get_size()).convert_alpha()
        self.surface.fill((0, 0, 0, 0))

        for o in self.background_layout:
            if o[0] == 'rectangle':
                r = copy.deepcopy(o[1])
                r.width = eval_attr(r.width, self.get_size()[0])
                r.height = eval_attr(r.height, self.get_size()[1])
                if not r.width:
                    r.width = self.get_size()[0]
                if not r.height:
                    r.height = self.get_size()[1]
                if r.x + r.width > self.get_size()[0]:
                    r.width = self.get_size()[0] - r.x
                if r.y + r.height > self.get_size()[1]:
                    r.height = self.get_size()[1] - r.y
                self.osd.drawroundbox(r.x, r.y, r.x + r.width, r.y + r.height,
                                      r.bgcolor, r.size, r.color, r.radius,
                                      self.surface)

        self.get_selected_child = self.content.get_selected_child
        if not self.content.parent:
            print '******************************************************************'
            print 'Error: content has no parent, fixing...'
            print 'If you can reproduce this error message, please send a'
            print 'mail with the subject \'[Freevo-Bugreport] GUI\' to'
            print '[email protected].'
            print '******************************************************************'
            self.content.parent = self

        if not self.parent:
            print '******************************************************************'
            print 'Error: window has no parent, not showing...'
            print 'If you can reproduce this error message, please send a'
            print 'mail with the subject \'[Freevo-Bugreport] GUI\' to'
            print '[email protected].'
            print '******************************************************************'
            return

        self.content.surface = self.content.get_surface()
        self.content.draw()
        self.blit_parent()
示例#4
0
    def _draw(self):
        """
        The actual internal draw function.

        """
        logger.log( 9, 'Window::_draw %s', self)

        if not self.width or not self.height:
            raise TypeError, 'Not all needed variables set.'

        cheight = self.content.height
        self.content.layout()

        # resize when content changed the height because of the layout()
        if self.content.height - cheight > 0:
            self.height += self.content.height - cheight

        self.surface = self.osd.Surface(self.get_size()).convert_alpha()
        self.surface.fill((0,0,0,0))

        for o in self.background_layout:
            if o[0] == 'rectangle':
                r = copy.deepcopy(o[1])
                r.width  = eval_attr(r.width,  self.get_size()[0])
                r.height = eval_attr(r.height, self.get_size()[1])
                if not r.width:
                    r.width  = self.get_size()[0]
                if not r.height:
                    r.height = self.get_size()[1]
                if r.x + r.width > self.get_size()[0]:
                    r.width = self.get_size()[0] - r.x
                if r.y + r.height > self.get_size()[1]:
                    r.height = self.get_size()[1] - r.y
                self.osd.drawroundbox(r.x, r.y, r.x+r.width, r.y+r.height,
                                      r.bgcolor, r.size, r.color, r.radius,
                                      self.surface)

        self.get_selected_child = self.content.get_selected_child
        if not self.content.parent:
            print '******************************************************************'
            print 'Error: content has no parent, fixing...'
            print 'If you can reproduce this error message, please send a bug report'
            print 'to the freevo-devel list'
            print '******************************************************************'
            self.content.parent = self

        if not self.parent:
            print '******************************************************************'
            print 'Error: window has no parent, not showing...'
            print 'If you can reproduce this error message, please send a bug report'
            print 'to the freevo-devel list'
            print '******************************************************************'
            return

        self.content.surface = self.content.get_surface()
        self.content.draw()
        self.blit_parent()
        self.osd.update()
示例#5
0
    def update_content(self):
        """
        update the listing area
        """
        menuw = self.menuw
        settings = self.settings
        layout = self.layout
        area = self.area_val
        content = self.calc_geometry(layout.content, copy_object=True)

        if not hasattr(menuw, "scrollable_text"):
            return

        scrollable_text = menuw.scrollable_text

        if self.scrollable_text != scrollable_text:

            scrollable_text.layout(content.width, content.height, content.font)
            self.scrollable_text = scrollable_text

        page = scrollable_text.get_page()

        if not len(page):
            return

        y = 0
        for line in page:
            self.drawstring(line, content.font, content, content.x, content.y + y, mode="hard")
            y += content.font.height

        # print arrow:
        try:
            if scrollable_text.more_lines_up() and area.images["uparrow"]:
                self.drawimage(area.images["uparrow"].filename, area.images["uparrow"])

            if (scrollable_text.more_lines_down() or scrollable_text.more_lines_up()) and area.images["scrollbar"]:
                offset, total_lines, lines_per_page = scrollable_text.get_page_details()
                v = copy.copy(area.images["scrollbar"])
                if isinstance(area.images["scrollbar"].height, types.TupleType):
                    v.height = eval_attr(v.height, content.height)
                v.y += int(float(v.height) * (float(offset) / float(total_lines)))
                h = int(float(v.height) * (float(lines_per_page) / float(total_lines)))
                v.height = min(v.height, h)
                self.drawimage(area.images["scrollbar"].filename, v)

            if scrollable_text.more_lines_down() and area.images["downarrow"]:
                if isinstance(area.images["downarrow"].y, types.TupleType):
                    v = copy.copy(area.images["downarrow"])
                    v.y = eval_attr(v.y, content.y + content.height)
                else:
                    v = area.images["downarrow"]
                self.drawimage(area.images["downarrow"].filename, v)
        except:
            # empty menu / missing images
            pass
示例#6
0
    def __init__content__(self):
        x, y, width, height = self.content_layout.x, self.content_layout.y, \
                              self.content_layout.width, self.content_layout.height
        width  = eval_attr(width, self.width) or self.width
        height = eval_attr(height, self.height) or self.height

        self.content = Container('frame', x, y, width, height, vertical_expansion=1)
        GUIObject.add_child(self, self.content)

        # adjust left to content
        self.left += (self.width - width-x) / 2

        self.content.internal_h_align = Align.CENTER
        self.content.internal_v_align = Align.CENTER
示例#7
0
    def set_size(self, width, height):
        width -= self.width
        height -= self.height

        self.width += width
        self.height += height

        width, height = self.content_layout.width, self.content_layout.height
        self.content.width = eval_attr(width, self.width) or self.width
        self.content.height = eval_attr(height, self.height) or self.height

        self.left = self.osd.width / 2 - self.width / 2
        self.top = self.osd.height / 2 - self.height / 2

        # adjust left to content
        self.left += (self.width - self.content.width - self.content.left) / 2
示例#8
0
    def set_size(self, width, height):
        width  -= self.width
        height -= self.height

        self.width  += width
        self.height += height

        width, height = self.content_layout.width, self.content_layout.height
        self.content.width  = eval_attr(width,  self.width ) or self.width
        self.content.height = eval_attr(height, self.height) or self.height

        self.left = self.osd.width/2 - self.width/2
        self.top  = self.osd.height/2 - self.height/2

        # adjust left to content
        self.left += (self.width - self.content.width-self.content.left) / 2
    def update_content(self):
        """
        update the listing area
        """

        menuw = self.menuw
        settings = self.settings
        layout = self.layout
        area = self.area_val
        content = self.calc_geometry(layout.content, copy_object=True)

        if not hasattr(menuw, "scrollable_text"):
            return

        scrollable_text = menuw.scrollable_text

        if self.scrollable_text != scrollable_text:

            scrollable_text.layout(content.width, content.height, content.font)
            self.scrollable_text = scrollable_text

        page = scrollable_text.get_page()

        if not len(page):
            return

        y = 0
        for line in page:
            self.drawstring(line,
                            content.font,
                            content,
                            content.x,
                            content.y + y,
                            mode='hard')
            y += content.font.height

        # print arrow:
        try:
            if scrollable_text.more_lines_up() and area.images['uparrow']:
                self.drawimage(area.images['uparrow'].filename,
                               area.images['uparrow'])

            if scrollable_text.more_lines_down() and area.images['downarrow']:
                if isinstance(area.images['downarrow'].y, types.TupleType):
                    v = copy.copy(area.images['downarrow'])
                    v.y = eval_attr(v.y, content.y + content.height)
                else:
                    v = area.images['downarrow']
                self.drawimage(area.images['downarrow'].filename, v)
        except:
            # empty menu / missing images
            pass
示例#10
0
    def get_item_rectangle(self, rectangle, item_w, item_h):
        """
        calculates the values for a rectangle to fit item_w and item_h
        inside it.
        """
        r = copy.copy(rectangle)

        # get the x and y value, based on MAX
        if isinstance(r.x, types.TupleType):
            r.x = int(eval_attr(r.x, item_w))
        if isinstance(r.y, types.TupleType):
            r.y = int(eval_attr(r.y, item_h))

        # set rect width and height to something
        if not r.width:
            r.width = item_w

        if not r.height:
            r.height = item_h

        # calc width and height based on MAX settings
        if isinstance(r.width, types.TupleType):
            r.width = int(eval_attr(r.width, item_w))

        if isinstance(r.height, types.TupleType):
            r.height = int(eval_attr(r.height, item_h))

        # correct item_w and item_h to fit the rect
        item_w = max(item_w, r.width)
        item_h = max(item_h, r.height)
        if r.x < 0:
            item_w -= r.x
        if r.y < 0:
            item_h -= r.y

        # return needed width and height to fit original width and height
        # and the rectangle attributes
        return max(item_w, r.width), max(item_h, r.height), r
示例#11
0
    def get_item_rectangle(self, rectangle, item_w, item_h):
        """
        calculates the values for a rectangle to fit item_w and item_h
        inside it.
        """
        r = copy.copy(rectangle)

        # get the x and y value, based on MAX
        if isinstance(r.x, types.TupleType):
            r.x = int(eval_attr(r.x, item_w))
        if isinstance(r.y, types.TupleType):
            r.y = int(eval_attr(r.y, item_h))

        # set rect width and height to something
        if not r.width:
            r.width = item_w

        if not r.height:
            r.height = item_h

        # calc width and height based on MAX settings
        if isinstance(r.width, types.TupleType):
            r.width = int(eval_attr(r.width, item_w))

        if isinstance(r.height, types.TupleType):
            r.height = int(eval_attr(r.height, item_h))

        # correct item_w and item_h to fit the rect
        item_w = max(item_w, r.width)
        item_h = max(item_h, r.height)
        if r.x < 0:
            item_w -= r.x
        if r.y < 0:
            item_h -= r.y

        # return needed width and height to fit original width and height
        # and the rectangle attributes
        return max(item_w, r.width), max(item_h, r.height), r
示例#12
0
    def update_content(self):
        """
        update the listing area
        """
        menuw     = self.menuw
        menu      = self.menu
        settings  = self.settings
        layout    = self.layout
        area      = self.area_val
        content   = self.calc_geometry(layout.content, copy_object=True)

        cols, rows, hspace, vspace, hskip, vskip, width = \
              self.get_items_geometry(settings, menu, self.display_style)

        BOX_UNDER_ICON = self.xml_settings.box_under_icon

        if not len(menu.choices):
            val = content.types['default']
            self.drawstring(_('This directory is empty'), content.font, content)

        if content.align == 'center':
            item_x0 = content.x + (content.width - cols * hspace) / 2
        else:
            item_x0 = content.x

        if content.valign == 'center':
            item_y0 = content.y + (content.height - rows * vspace) / 2
        else:
            item_y0 = content.y

        current_col = 1

        if content.type == 'image':
            width  = hspace - content.spacing
            height = vspace - content.spacing

        last_tvs      = ('', 0)
        all_tvs       = True
        tvs_shortname = True

        anamorphic = self.xml_settings.anamorphic
    
        self.image_loaded = False
        remove_images = self.loading_images.keys()
        

        for choice in menuw.menu_items:

            if hasattr(choice, 'dirty'):
                choice.dirty = False

            items_geometry = self.last_get_items_geometry[1]

            # Widget Sizes
            wdg_x = 0
            wdg_y = 0
            wdg_w = items_geometry[2]
            wdg_h = items_geometry[3]

            if content.types.has_key('%s selected' % choice.type):
                s_val = content.types[ '%s selected' % choice.type ]
            else:
                s_val = content.types[ 'selected' ]

            if content.types.has_key(choice.type):
                n_val = content.types[ choice.type ]
            else:
                n_val = content.types['default']

            if choice == menu.selected:
                val = s_val
            else:
                val = n_val

            text = choice.name

            if not text:
                text = "unknown"

            type_image = None
            if hasattr(val, 'icon'):
                type_image = val.icon

            if not choice.icon and not type_image:
                if choice.type == 'dir' and choice.parent and \
                   choice.parent.type != 'mediamenu':
                    text = '%s' % text if (hasattr(choice, 'folder_fxd') or config.SKIN_HANDLES_DETAILS) else '[%s]' % text

            if content.type == 'text':
                x0 = item_x0
                y0 = item_y0
                icon_x = 0
                image = None
                align = val.align or content.align

                if choice != menu.selected and hasattr(choice, 'outicon') and \
                       choice.outicon:
                    image, w, h = self.loadimage(choice.outicon, (vspace-content.spacing, vspace-content.spacing))
                elif choice.icon:
                    image, w, h = self.loadimage(choice.icon, (vspace-content.spacing, vspace-content.spacing))
                if not image and type_image:
                    image, w, h = self.loadimage(settings.icon_dir + '/' + type_image,
                        (vspace-content.spacing, vspace-content.spacing))
                x_icon = 0
                if image:
                    mx = x0
                    icon_x = vspace
                    x_icon = icon_x
                    if align == 'right':
                        # know how many pixels to offset (dammed negative and max+X
                        # values in (x,y,width) from skin!)
                        r1 = r2 = None
                        if s_val.rectangle:
                            r1 = self.get_item_rectangle(s_val.rectangle,
                                                         width, s_val.font.h)[2]
                        if n_val.rectangle:
                            r2 = self.get_item_rectangle(n_val.rectangle,
                                                         width, n_val.font.h)[2]
                        min_rx = 0
                        max_rw = width
                        if r1:
                            min_rx = min(min_rx, r1.x)
                            max_rw = max(max_rw, r1.width)
                        if r2:
                            min_rx = min(min_rx, r2.x)
                            max_rw = max(max_rw, r2.width)

                        mx = x0 + width + hskip + (max_rw + min_rx - width) - icon_x
                        x_icon = 0
                    self.drawimage(image, (mx, y0))

                if val.rectangle:
                    r = self.get_item_rectangle(val.rectangle, width, val.font.h)[2]
                    wdg_x = x0 + hskip + r.x + x_icon - BOX_UNDER_ICON * x_icon
                    wdg_y = y0 + vskip + r.y
                    self.drawroundbox(x0 + hskip + r.x + x_icon - BOX_UNDER_ICON * x_icon,
                                      y0 + vskip + r.y,
                                      r.width - icon_x + BOX_UNDER_ICON * icon_x,
                                      r.height, r)

                # lets draw the image if present. This in 99% caes will be used for hihliting menu items
                # so no need for fancy sizing, just fill inn whole area
                if hasattr(val, 'fcontent'):
                    for i in val.fcontent:
                        if isinstance(i, xml_skin.FormatImg):
                            r = self.get_item_rectangle(i, width, val.font.h)[ 2 ]
                            wdg_x = x0 + hskip + r.x + x_icon - BOX_UNDER_ICON * x_icon
                            wdg_y = y0 + vskip + r.y
                            self.drawimage(i.src,
                                           (x0 + hskip + r.x + x_icon - BOX_UNDER_ICON * x_icon,
                                            y0 + vskip + r.y,
                                            r.width - icon_x + BOX_UNDER_ICON * icon_x,
                                            r.height))


                # special handling for tv shows
                if choice.type == 'video' and hasattr(choice,'tv_show') and \
                   choice.tv_show and (val.align=='left' or val.align=='') and \
                   (content.align=='left' or content.align=='') and not config.SKIN_HANDLES_DETAILS:
                    sn = choice.show_name

                    if last_tvs[0] == sn[0]:
                        tvs_w = last_tvs[1]
                    else:
                        season  = 0
                        episode = 0
                        for c in menu.choices:
                            if c.type == 'video' and hasattr(c,'tv_show') and \
                               c.tv_show and c.show_name[0] == sn[0]:
                                # do not use val.font.stringsize because this will
                                # add shadow and outline values we add later for the
                                # normal text again. So just use val.font.font.stringsize
                                stringsize = val.font.font.stringsize
                                season  = max(season, stringsize(c.show_name[1]))
                                episode = max(episode, stringsize(c.show_name[2]))
                                if tvs_shortname and not c.image:
                                    tvs_shortname = False
                            else:
                                all_tvs = False

                        if all_tvs and not tvs_shortname and len(menu.choices) > 5:
                            tvs_shortname = True

                        if all_tvs and tvs_shortname:
                            tvs_w = val.font.stringsize('x') + season + episode
                        else:
                            tvs_w = val.font.stringsize('%s x' % sn[0]) + season + episode
                        last_tvs = (sn[0], tvs_w)

                    wdg_x = x0 + hskip + icon_x + tvs_w
                    wdg_y = y0 + vskip
                    self.drawstring(' - %s' % sn[3], val.font, content,
                                    x=x0 + hskip + icon_x + tvs_w,
                                    y=y0 + vskip, width=width-icon_x-tvs_w, height=-1,
                                    align_h='left', dim=False, mode='hard')
                    self.drawstring(sn[2], val.font, content,
                                    x=x0 + hskip + icon_x + tvs_w - 100,
                                    y=y0 + vskip, width=100, height=-1,
                                    align_h='right', dim=False, mode='hard')
                    if all_tvs and tvs_shortname:
                        text = '%sx' % sn[1]
                    else:
                        text = '%s %sx' % (sn[0], sn[1])

                # if the menu has an attr table, the menu is a table. Each
                # item _must_ have that many tabs as the table needs!!!
                if hasattr(menu, 'table'):
                    table_x = x0 + hskip + x_icon
                    if hasattr(choice, 'table_fields'):
                        table_text = choice.table_fields
                    else:
                        table_text = text.split('\t')
                        
                    if len(table_text) < len(menu.table):
                        if not text.lower().find('playlist'):
                            # we only log error if this is a real item, not a playlist
                            logger.error('Menu item: %r doesn\'t have enough table entries!', menu)
                        table_text.extend([''] * (len(menu.table) - len(table_text)))

                    for i in range(len(menu.table)):
                        table_w = ((width-icon_x-len(table_text)*5)*menu.table[i]) / 100
                        if i != len(menu.table) - 1:
                            table_w += 5
                        x_mod = 0
                        if table_text[i].find('ICON_') == 0:
                            x_mod, table_text[i] = text_or_icon(settings, table_text[i],
                                                                table_x, table_w, val.font)
                            if not isinstance(table_text[i], basestring):
                                self.drawimage(table_text[i], (table_x + x_mod, y0 + vskip))
                                table_text[i] = ''

                        if table_text[i]:
                            wdg_x = table_x + x_mod
                            wdg_y = y0 + vskip
                            self.drawstring(table_text[i], val.font, content,
                                            x=table_x + x_mod,
                                            y=y0 + vskip, width=table_w, height=-1,
                                            align_h=val.align, mode='hard', dim=False)
                        table_x += table_w + 5

                else:
                    wdg_x = x0 + hskip + x_icon
                    wdg_y = y0 + vskip
                    self.drawstring(text, val.font, content, x=x0 + hskip + x_icon,
                                    y=y0 + vskip, width=width-icon_x, height=-1,
                                    align_h=val.align, mode='hard', dim=True)


            elif content.type == 'image' or content.type == 'image+text':
                rec_h = val.height
                if content.type == 'image+text':
                    rec_h += int(1.1 * val.font.h)

                if val.align == 'center':
                    x0 = item_x0 + (hspace - val.width) / 2
                else:
                    x0 = item_x0 + hskip

                if val.valign == 'center':
                    y0 = item_y0 + (vspace - rec_h) / 2
                else:
                    y0 = item_y0 + vskip

                if val.rectangle:
                    if content.type == 'image+text':
                        r = self.get_item_rectangle(val.rectangle, val.width,
                                                    max(rec_h, int(val.font.h * 1.1)))[2]
                    else:
                        r = self.get_item_rectangle(val.rectangle, val.width, rec_h)[2]
                    self.drawroundbox(x0 + r.x, y0 + r.y, r.width, r.height, r)


                image_key = generate_cache_key(settings, choice, val.width, val.height, True)

                if image_key in format_imagecache:
                    image, i_w, i_h = format_imagecache[image_key]

                    if image_key in remove_images:
                        # Make sure we remove the selected/unselected version
                        # from the cancel list.
                        for v in (s_val, n_val):
                            i_k = generate_cache_key(settings, choice, v.width, v.height, True)
                            if i_k in remove_images:
                                remove_images.remove(i_k)

                    addx = 0
                    addy = 0
                    if val.align == 'center' and i_w < val.width:
                        addx = (val.width - i_w) / 2

                    if val.align == 'right' and i_w < val.width:
                        addx = val.width - i_w

                    if val.valign == 'center' and i_h < val.height:
                        addy = (val.height - i_h) / 2

                    if val.valign == 'bottom' and i_h < val.height:
                        addy = val.height - i_h

                    wdg_x = x0 + addx
                    wdg_y = y0 + addy

                    self.drawimage(image, (x0 + addx, y0 + addy))
                    if val.shadow and val.shadow.visible and image.get_alpha() == None:
                        wdg_x = x0 + addx + val.shadow.x
                        wdg_y = y0 + addy + val.shadow.y
                        self.drawroundbox(x0 + addx + val.shadow.x,
                                          y0 + addy + val.shadow.y,
                                          image.get_width(), image.get_height(),
                                          (val.shadow.color, 0, 0, 0))

                else:
                    for v in (s_val, n_val):
                        image_key = generate_cache_key(settings, choice, v.width, v.height, True)
                        if image_key in remove_images:
                            remove_images.remove(image_key)
                        if image_key not in self.loading_images and image_key not in format_imagecache:
                            hp = choice == menu.selected
                            formatter = AsyncImageFormatter(settings, choice,
                                                            v.width, v.height,
                                                            True, anamorphic, hp, v == n_val)
                            formatter.connect(self.__image_loaded, image_key)
                            self.loading_images[image_key] = formatter

                    self.drawroundbox(x0, y0, val.width, val.height, (0, 1, 0xffffff, 0))


                if content.type == 'image+text':
                    wdg_x = x0
                    wdg_y = y0 + val.height

                    text = choice.list_name if hasattr(choice, 'list_name') else choice.name
                    self.drawstring(text, val.font, content, x=x0,
                                    y=y0 + val.height, width=val.width, height=-1,
                                    align_h=val.align, mode='hard', ellipses='', dim=False)

            else:
                print 'no support for content type %s' % content.type

            if current_col == cols:
                if content.align == 'center':
                    item_x0 = content.x + (content.width - cols * hspace) / 2
                else:
                    item_x0 = content.x
                item_y0 += vspace
                current_col = 1
            else:
                item_x0 += hspace
                current_col += 1

            choice.rect = pygame.Rect(wdg_x, wdg_y, wdg_w, wdg_h)

        # print arrow:
        try:
            if menuw.menu_items[0] != menu.choices[0] and area.images['uparrow']:
                self.drawimage(area.images['uparrow'].filename, area.images['uparrow'])
            if menuw.menu_items[-1] != menu.choices[-1] and area.images['downarrow']:
                if isinstance(area.images['downarrow'].y, types.TupleType):
                    v = copy.copy(area.images['downarrow'])
                    v.y = eval_attr(v.y, (item_y0-vskip))
                else:
                    v = area.images['downarrow']
                self.drawimage(area.images['downarrow'].filename, v)
        except:
            # empty menu / missing images
            pass

        for image_key in remove_images:
            if image_key in self.loading_images:
                self.loading_images[image_key].cancelled = True
                del self.loading_images[image_key]

        self.last_choices = (menu.selected, copy.copy(menuw.menu_items))
示例#13
0
    def update_content(self):
        """
        update the listing area
        """
        menuw     = self.menuw
        menu      = self.menu
        settings  = self.settings
        layout    = self.layout
        area      = self.area_val
        content   = self.calc_geometry(layout.content, copy_object=True)

        to_listing = menu.table

        n_cols   = len(to_listing[0])-1
        col_time = 30

        font_h, label_width, label_txt_width, y0, num_rows, item_h, head_h = \
                self.get_items_geometry(settings, menu)[:-1]

        label_val, head_val, selected_val, default_val, scheduled_val, overlap_val,\
        past_val, current_val = self.all_vals

        leftarrow = None
        if area.images['leftarrow']:
            i = area.images['leftarrow']
            leftarrow, w, h = self.loadimage(i.filename, i)
            if leftarrow:
                leftarrow_size = (leftarrow.get_width(), leftarrow.get_height())

        rightarrow = None
        if area.images['rightarrow']:
            i = area.images['rightarrow']
            rightarrow, w, h = self.loadimage(i.filename, i)
            if rightarrow:
                rightarrow_size = (rightarrow.get_width(), rightarrow.get_height())


        x_contents = content.x + content.spacing
        y_contents = content.y + content.spacing

        w_contents = content.width  - 2 * content.spacing
        h_contents = content.height - 2 * content.spacing

        # Print the Date of the current list page
        dateformat = config.TV_DATE_FORMAT
        timeformat = config.TV_TIME_FORMAT
        if not timeformat:
            timeformat = '%H:%M'
        if not dateformat:
            dateformat = '%e-%b'

        r = Geometry( 0, 0, label_width, font_h )
        if label_val.rectangle:
            r = self.get_item_rectangle( label_val.rectangle, label_width, head_h )[ 2 ]
            pad_x = 0
            pad_y = 0
            if r.x < 0: pad_x = -1 * r.x
            if r.y < 0: pad_y = -1 * r.y

        x_contents += r.width
        y_contents += r.height
        w_contents -= r.width
        h_contents -= r.width

        # 1 sec = x pixels
        prop_1sec = float(w_contents) / float(n_cols * col_time * 60)
        col_size = prop_1sec * 1800 # 30 minutes

        ig = Geometry( 0, 0, col_size, head_h )
        if head_val.rectangle:
            ig, r2 = self.fit_item_in_rectangle( head_val.rectangle, col_size,
                                                 head_h, head_h )

        self.drawroundbox( x_contents - r.width, y_contents - r.height,
                           r.width+1, head_h+1, r )

        # use label padding for x; head padding for y
        self.drawstring( Unicode(time.strftime(dateformat, time.localtime(to_listing[0][1]))),
                         head_val.font, content,
                         x=( x_contents  - r.width + pad_x ),
                         y=( y_contents - r.height + ig.y ),
                         width=( r.width - 2 * pad_x ), height=-1,
                         align_v='center', align_h=head_val.align )

        # Print the time at the table's top
        x0 = x_contents
        ty0 = y_contents - r.height
        for i in range( n_cols ):
            self.drawroundbox(math.floor(x0), ty0,
                              math.floor( col_size + x0 ) - math.floor( x0 ) + 1,
                              head_h + 1, r2)

            self.drawstring(Unicode(time.strftime(timeformat, time.localtime(to_listing[0][i+1]))),
                            head_val.font, content,
                            x=( x0 + ig.x ), y=( ty0 + ig.y ),
                            width=ig.width, height=-1,
                            align_v='center', align_h=head_val.align)
            x0 += col_size

        # define start and stop time
        date = time.strftime("%x", time.localtime())
        start_time = to_listing[0][1]
        stop_time = to_listing[0][-1]
        stop_time += (col_time*60)
        now_time = time.time()

        # selected program:
        selected_prog = to_listing[1]

        for i in range(2,len(to_listing)):
            ty0 = y0
            tx0 = content.x

            logo_geo = [ tx0, ty0, label_width, font_h ]

            if label_val.rectangle:
                r = self.get_item_rectangle(label_val.rectangle, label_width, item_h)[2]
                if r.x < 0:
                    tx0 -= r.x
                if r.y < 0:
                    ty0 -= r.y

                val = default_val

                self.drawroundbox(tx0 + r.x, ty0 + r.y, r.width+1, item_h, r)
                logo_geo =[ tx0+r.x+r.size, ty0+r.y+r.size, r.width-2*r.size,
                            r.height-2*r.size ]


            channel_logo = config.TV_LOGOS + '/' + to_listing[i].id + '.png'
            if os.path.isfile(channel_logo):
                channel_logo, w, h = self.loadimage(channel_logo, (r.width+1-2*r.size, item_h-2*r.size))
            else:
                channel_logo = None

            if channel_logo:
                self.drawimage(channel_logo, (logo_geo[0], logo_geo[1]))
            else:
                self.drawstring(to_listing[i].displayname, label_val.font, content,
                                x=tx0, y=ty0, width=r.width+2*r.x, height=item_h)

            self.drawroundbox(tx0 + r.x, ty0 + r.y, r.width+1, item_h, r)

            if to_listing[i].programs:
                for prg in to_listing[i].programs:
                    flag_left   = 0
                    flag_right  = 0

                    if prg.start < start_time:
                        flag_left = 1
                        x0 = x_contents
                        t_start = start_time
                    else:
                        x0 = x_contents + int(float(prg.start-start_time) * prop_1sec)
                        t_start = prg.start

                    if prg.stop > stop_time:
                        flag_right = 1
                        w = w_contents + x_contents - x0
                        x1 = x_contents + w_contents
                    else:
                        w =  int( float(prg.stop - t_start) * prop_1sec )
                        x1 = x_contents + int(float(prg.stop-start_time) * prop_1sec)

                    if prg.title == selected_prog.title and \
                       prg.channel_id == selected_prog.channel_id and \
                       prg.start == selected_prog.start and \
                       prg.stop == selected_prog.stop:
                        val = selected_val
                    elif hasattr(prg, 'overlap') and prg.overlap:
                        val = overlap_val
                    elif hasattr(prg, 'scheduled') and prg.scheduled:
                        val = scheduled_val
                    elif now_time >= prg.start and now_time <= prg.stop:
                        val = current_val
                    elif now_time > prg.stop:
                        val = past_val
                    else:
                        val = default_val

                    font = val.font

                    try:
                        if prg.title == _('This channel has no data loaded'):
                            val = copy.copy(val)
                            val.align='center'
                    except UnicodeError:
                        pass

                    if x0 > x1:
                        break

                    # text positions
                    tx0 = x0
                    tx1 = x1
                    ty0 = y0

                    # calc the geometry values
                    ig = Geometry(0, 0, tx1-tx0+1, item_h)
                    if val.rectangle:
                        ig, r = self.fit_item_in_rectangle(val.rectangle, tx1-tx0+1,
                                                           item_h, font_h)
                        self.drawroundbox(tx0+r.x, ty0+r.y, r.width, item_h, r)

                    # draw left flag and reduce width and add to x0
                    if flag_left:
                        tx0      += leftarrow_size[0]
                        ig.width -= leftarrow_size[0]
                        if tx0 < tx1:
                            self.drawimage(leftarrow, (tx0-leftarrow_size[0], ty0 +\
                                                       (item_h-leftarrow_size[1])/2))

                    # draw right flag and reduce width and x1
                    if flag_right:
                        tx1      -= rightarrow_size[0]
                        ig.width -= rightarrow_size[0]
                        if tx0 < tx1:
                            self.drawimage(rightarrow,
                                           (tx1, ty0 + (item_h-rightarrow_size[1])/2))

                    # draw the text
                    if tx0 < tx1:
                        self.drawstring(prg.title, font, content, x=tx0+ig.x,
                                        y=ty0+ig.y, width=ig.width, height=ig.height,
                                        align_v='center', align_h = val.align)

            i += 1
            y0 += item_h - 1
        
        if  config.SKIN_GUIDE_SHOW_NOW_LINE and \
                start_time < now_time and now_time <= stop_time:
            tx = x_contents + int(float(now_time-start_time) * prop_1sec)
            ty = content.y + 1
            w = prop_1sec * 60
            self.drawroundbox(tx, ty, w, y0 - ty, (current_val.font.color,0,0,0))

        # print arrow:
        if menuw.display_up_arrow and area.images['uparrow']:
            self.drawimage(area.images['uparrow'].filename, area.images['uparrow'])
        if menuw.display_down_arrow and area.images['downarrow']:
            if isinstance(area.images['downarrow'].y, types.TupleType):
                v = copy.copy(area.images['downarrow'])
                v.y = eval_attr(v.y, y0)
            else:
                v = area.images['downarrow']
            self.drawimage(area.images['downarrow'].filename, v)
示例#14
0
    def update_content(self):
        """
        update the listing area
        """
        menuw = self.menuw
        menu = self.menu
        settings = self.settings
        layout = self.layout
        area = self.area_val
        content = self.calc_geometry(layout.content, copy_object=True)

        cols, rows, hspace, vspace, hskip, vskip, width = \
              self.get_items_geometry(settings, menu, self.display_style)

        BOX_UNDER_ICON = self.xml_settings.box_under_icon

        if not len(menu.choices):
            val = content.types['default']
            self.drawstring(_('This directory is empty'), content.font,
                            content)

        if content.align == 'center':
            item_x0 = content.x + (content.width - cols * hspace) / 2
        else:
            item_x0 = content.x

        if content.valign == 'center':
            item_y0 = content.y + (content.height - rows * vspace) / 2
        else:
            item_y0 = content.y

        current_col = 1

        if content.type == 'image':
            width = hspace - content.spacing
            height = vspace - content.spacing

        last_tvs = ('', 0)
        all_tvs = True
        tvs_shortname = True

        anamorphic = self.xml_settings.anamorphic

        self.image_loaded = False
        remove_images = self.loading_images.keys()

        for choice in menuw.menu_items:

            if hasattr(choice, 'dirty'):
                choice.dirty = False

            items_geometry = self.last_get_items_geometry[1]

            # Widget Sizes
            wdg_x = 0
            wdg_y = 0
            wdg_w = items_geometry[2]
            wdg_h = items_geometry[3]

            if content.types.has_key('%s selected' % choice.type):
                s_val = content.types['%s selected' % choice.type]
            else:
                s_val = content.types['selected']

            if content.types.has_key(choice.type):
                n_val = content.types[choice.type]
            else:
                n_val = content.types['default']

            if choice == menu.selected:
                val = s_val
            else:
                val = n_val

            text = choice.name
            if not text:
                text = "unknown"

            type_image = None
            if hasattr(val, 'icon'):
                type_image = val.icon

            if not choice.icon and not type_image:
                if choice.type == 'playlist':
                    text = 'PL: %s' % text

                if choice.type == 'dir' and choice.parent and \
                   choice.parent.type != 'mediamenu':
                    text = '[%s]' % text

            if content.type == 'text':
                x0 = item_x0
                y0 = item_y0
                icon_x = 0
                image = None
                align = val.align or content.align

                if choice != menu.selected and hasattr(choice, 'outicon') and \
                       choice.outicon:
                    image, w, h = self.loadimage(
                        choice.outicon,
                        (vspace - content.spacing, vspace - content.spacing))
                elif choice.icon:
                    image, w, h = self.loadimage(
                        choice.icon,
                        (vspace - content.spacing, vspace - content.spacing))
                if not image and type_image:
                    image, w, h = self.loadimage(
                        settings.icon_dir + '/' + type_image,
                        (vspace - content.spacing, vspace - content.spacing))
                x_icon = 0
                if image:
                    mx = x0
                    icon_x = vspace
                    x_icon = icon_x
                    if align == 'right':
                        # know how many pixels to offset (dammed negative and max+X
                        # values in (x,y,width) from skin!)
                        r1 = r2 = None
                        if s_val.rectangle:
                            r1 = self.get_item_rectangle(
                                s_val.rectangle, width, s_val.font.h)[2]
                        if n_val.rectangle:
                            r2 = self.get_item_rectangle(
                                n_val.rectangle, width, n_val.font.h)[2]
                        min_rx = 0
                        max_rw = width
                        if r1:
                            min_rx = min(min_rx, r1.x)
                            max_rw = max(max_rw, r1.width)
                        if r2:
                            min_rx = min(min_rx, r2.x)
                            max_rw = max(max_rw, r2.width)

                        mx = x0 + width + hskip + (max_rw + min_rx -
                                                   width) - icon_x
                        x_icon = 0
                    self.drawimage(image, (mx, y0))

                if val.rectangle:
                    r = self.get_item_rectangle(val.rectangle, width,
                                                val.font.h)[2]
                    wdg_x = x0 + hskip + r.x + x_icon - BOX_UNDER_ICON * x_icon
                    wdg_y = y0 + vskip + r.y
                    self.drawroundbox(
                        x0 + hskip + r.x + x_icon - BOX_UNDER_ICON * x_icon,
                        y0 + vskip + r.y,
                        r.width - icon_x + BOX_UNDER_ICON * icon_x, r.height,
                        r)

                # special handling for tv shows
                if choice.type == 'video' and hasattr(choice,'tv_show') and \
                   choice.tv_show and (val.align=='left' or val.align=='') and \
                   (content.align=='left' or content.align==''):
                    sn = choice.show_name

                    if last_tvs[0] == sn[0]:
                        tvs_w = last_tvs[1]
                    else:
                        season = 0
                        episode = 0
                        for c in menu.choices:
                            if c.type == 'video' and hasattr(c,'tv_show') and \
                               c.tv_show and c.show_name[0] == sn[0]:
                                # do not use val.font.stringsize because this will
                                # add shadow and outline values we add later for the
                                # normal text again. So just use val.font.font.stringsize
                                stringsize = val.font.font.stringsize
                                season = max(season,
                                             stringsize(c.show_name[1]))
                                episode = max(episode,
                                              stringsize(c.show_name[2]))
                                if tvs_shortname and not c.image:
                                    tvs_shortname = False
                            else:
                                all_tvs = False

                        if all_tvs and not tvs_shortname and len(
                                menu.choices) > 5:
                            tvs_shortname = True

                        if all_tvs and tvs_shortname:
                            tvs_w = val.font.stringsize('x') + season + episode
                        else:
                            tvs_w = val.font.stringsize(
                                '%s x' % sn[0]) + season + episode
                        last_tvs = (sn[0], tvs_w)

                    wdg_x = x0 + hskip + icon_x + tvs_w
                    wdg_y = y0 + vskip
                    self.drawstring(' - %s' % sn[3],
                                    val.font,
                                    content,
                                    x=x0 + hskip + icon_x + tvs_w,
                                    y=y0 + vskip,
                                    width=width - icon_x - tvs_w,
                                    height=-1,
                                    align_h='left',
                                    dim=False,
                                    mode='hard')
                    self.drawstring(sn[2],
                                    val.font,
                                    content,
                                    x=x0 + hskip + icon_x + tvs_w - 100,
                                    y=y0 + vskip,
                                    width=100,
                                    height=-1,
                                    align_h='right',
                                    dim=False,
                                    mode='hard')
                    if all_tvs and tvs_shortname:
                        text = '%sx' % sn[1]
                    else:
                        text = '%s %sx' % (sn[0], sn[1])

                # if the menu has an attr table, the menu is a table. Each
                # item _must_ have that many tabs as the table needs!!!
                if hasattr(menu, 'table'):
                    table_x = x0 + hskip + x_icon
                    if hasattr(choice, 'table_fields'):
                        table_text = choice.table_fields
                    else:
                        table_text = text.split('\t')

                    if len(table_text) < len(menu.table):
                        logger.error(
                            'Menu item: %r doesn\'t have enough table entries!'
                        )
                        table_text.extend([''] *
                                          (len(menu.table) - len(table_text)))

                    for i in range(len(menu.table)):
                        table_w = ((width - icon_x - len(table_text) * 5) *
                                   menu.table[i]) / 100
                        if i != len(menu.table) - 1:
                            table_w += 5
                        x_mod = 0
                        if table_text[i].find('ICON_') == 0:
                            x_mod, table_text[i] = text_or_icon(
                                settings, table_text[i], table_x, table_w,
                                val.font)
                            if not isinstance(table_text[i], basestring):
                                self.drawimage(table_text[i],
                                               (table_x + x_mod, y0 + vskip))
                                table_text[i] = ''

                        if table_text[i]:
                            wdg_x = table_x + x_mod
                            wdg_y = y0 + vskip
                            self.drawstring(table_text[i],
                                            val.font,
                                            content,
                                            x=table_x + x_mod,
                                            y=y0 + vskip,
                                            width=table_w,
                                            height=-1,
                                            align_h=val.align,
                                            mode='hard',
                                            dim=False)
                        table_x += table_w + 5

                else:
                    wdg_x = x0 + hskip + x_icon
                    wdg_y = y0 + vskip
                    self.drawstring(text,
                                    val.font,
                                    content,
                                    x=x0 + hskip + x_icon,
                                    y=y0 + vskip,
                                    width=width - icon_x,
                                    height=-1,
                                    align_h=val.align,
                                    mode='hard',
                                    dim=True)

            elif content.type == 'image' or content.type == 'image+text':
                rec_h = val.height
                if content.type == 'image+text':
                    rec_h += int(1.1 * val.font.h)

                if val.align == 'center':
                    x0 = item_x0 + (hspace - val.width) / 2
                else:
                    x0 = item_x0 + hskip

                if val.valign == 'center':
                    y0 = item_y0 + (vspace - rec_h) / 2
                else:
                    y0 = item_y0 + vskip

                if val.rectangle:
                    if content.type == 'image+text':
                        r = self.get_item_rectangle(
                            val.rectangle, val.width,
                            max(rec_h, int(val.font.h * 1.1)))[2]
                    else:
                        r = self.get_item_rectangle(val.rectangle, val.width,
                                                    rec_h)[2]
                    self.drawroundbox(x0 + r.x, y0 + r.y, r.width, r.height, r)

                image_key = generate_cache_key(settings, choice, val.width,
                                               val.height, True)

                if image_key in format_imagecache:
                    image, i_w, i_h = format_imagecache[image_key]

                    if image_key in remove_images:
                        # Make sure we remove the selected/unselected version
                        # from the cancel list.
                        for v in (s_val, n_val):
                            i_k = generate_cache_key(settings, choice, v.width,
                                                     v.height, True)
                            if i_k in remove_images:
                                remove_images.remove(i_k)

                    addx = 0
                    addy = 0
                    if val.align == 'center' and i_w < val.width:
                        addx = (val.width - i_w) / 2

                    if val.align == 'right' and i_w < val.width:
                        addx = val.width - i_w

                    if val.valign == 'center' and i_h < val.height:
                        addy = (val.height - i_h) / 2

                    if val.valign == 'bottom' and i_h < val.height:
                        addy = val.height - i_h

                    wdg_x = x0 + addx
                    wdg_y = y0 + addy

                    self.drawimage(image, (x0 + addx, y0 + addy))
                    if val.shadow and val.shadow.visible and image.get_alpha(
                    ) == None:
                        wdg_x = x0 + addx + val.shadow.x
                        wdg_y = y0 + addy + val.shadow.y
                        self.drawroundbox(x0 + addx + val.shadow.x,
                                          y0 + addy + val.shadow.y,
                                          image.get_width(),
                                          image.get_height(),
                                          (val.shadow.color, 0, 0, 0))

                else:
                    for v in (s_val, n_val):
                        image_key = generate_cache_key(settings, choice,
                                                       v.width, v.height, True)
                        if image_key in remove_images:
                            remove_images.remove(image_key)
                        if image_key not in self.loading_images and image_key not in format_imagecache:
                            hp = choice == menu.selected
                            formatter = AsyncImageFormatter(
                                settings, choice, v.width, v.height, True,
                                anamorphic, hp, v == n_val)
                            formatter.connect(self.__image_loaded, image_key)
                            self.loading_images[image_key] = formatter

                    self.drawroundbox(x0, y0, val.width, val.height,
                                      (0, 1, 0xffffff, 0))

                if content.type == 'image+text':
                    wdg_x = x0
                    wdg_y = y0 + val.height
                    self.drawstring(choice.name,
                                    val.font,
                                    content,
                                    x=x0,
                                    y=y0 + val.height,
                                    width=val.width,
                                    height=-1,
                                    align_h=val.align,
                                    mode='hard',
                                    ellipses='',
                                    dim=False)

            else:
                print 'no support for content type %s' % content.type

            if current_col == cols:
                if content.align == 'center':
                    item_x0 = content.x + (content.width - cols * hspace) / 2
                else:
                    item_x0 = content.x
                item_y0 += vspace
                current_col = 1
            else:
                item_x0 += hspace
                current_col += 1

            choice.rect = pygame.Rect(wdg_x, wdg_y, wdg_w, wdg_h)

        # print arrow:
        try:
            if menuw.menu_items[0] != menu.choices[0] and area.images[
                    'uparrow']:
                self.drawimage(area.images['uparrow'].filename,
                               area.images['uparrow'])
            if menuw.menu_items[-1] != menu.choices[-1] and area.images[
                    'downarrow']:
                if isinstance(area.images['downarrow'].y, types.TupleType):
                    v = copy.copy(area.images['downarrow'])
                    v.y = eval_attr(v.y, (item_y0 - vskip))
                else:
                    v = area.images['downarrow']
                self.drawimage(area.images['downarrow'].filename, v)
        except:
            # empty menu / missing images
            pass

        for image_key in remove_images:
            if image_key in self.loading_images:
                self.loading_images[image_key].cancelled = True
                del self.loading_images[image_key]

        self.last_choices = (menu.selected, copy.copy(menuw.menu_items))
示例#15
0
    def update_content(self):
        """
        update the listing area
        """

        menuw = self.menuw
        menu = self.menu
        settings = self.settings
        layout = self.layout
        area = self.area_val
        content = self.calc_geometry(layout.content, copy_object=True)

        to_listing = menu.table

        n_cols = len(to_listing[0]) - 1
        col_time = 30

        font_h, label_width, label_txt_width, y0, num_rows, item_h, head_h = \
                self.get_items_geometry(settings, menu)[:-1]

        label_val, head_val, selected_val, default_val, scheduled_val, overlap_val,\
        past_val, current_val = self.all_vals

        leftarrow = None
        if area.images['leftarrow']:
            i = area.images['leftarrow']
            leftarrow = self.loadimage(i.filename, i)
            if leftarrow:
                leftarrow_size = (leftarrow.get_width(),
                                  leftarrow.get_height())

        rightarrow = None
        if area.images['rightarrow']:
            i = area.images['rightarrow']
            rightarrow = self.loadimage(i.filename, i)
            if rightarrow:
                rightarrow_size = (rightarrow.get_width(),
                                   rightarrow.get_height())

        x_contents = content.x + content.spacing
        y_contents = content.y + content.spacing

        w_contents = content.width - 2 * content.spacing
        h_contents = content.height - 2 * content.spacing

        # Print the Date of the current list page
        dateformat = config.TV_DATE_FORMAT
        timeformat = config.TV_TIME_FORMAT
        if not timeformat:
            timeformat = '%H:%M'
        if not dateformat:
            dateformat = '%e-%b'

        r = Geometry(0, 0, label_width, font_h)
        if label_val.rectangle:
            r = self.get_item_rectangle(label_val.rectangle, label_width,
                                        head_h)[2]
            pad_x = 0
            pad_y = 0
            if r.x < 0: pad_x = -1 * r.x
            if r.y < 0: pad_y = -1 * r.y

        x_contents += r.width
        y_contents += r.height
        w_contents -= r.width
        h_contents -= r.width

        # 1 sec = x pixels
        prop_1sec = float(w_contents) / float(n_cols * col_time * 60)
        col_size = prop_1sec * 1800  # 30 minutes

        ig = Geometry(0, 0, col_size, head_h)
        if head_val.rectangle:
            ig, r2 = self.fit_item_in_rectangle(head_val.rectangle, col_size,
                                                head_h, head_h)

        self.drawroundbox(x_contents - r.width, y_contents - r.height,
                          r.width + 1, head_h + 1, r)

        # use label padding for x; head padding for y
        self.drawstring(Unicode(
            time.strftime(dateformat, time.localtime(to_listing[0][1]))),
                        head_val.font,
                        content,
                        x=(x_contents - r.width + pad_x),
                        y=(y_contents - r.height + ig.y),
                        width=(r.width - 2 * pad_x),
                        height=-1,
                        align_v='center',
                        align_h=head_val.align)

        # Print the time at the table's top
        x0 = x_contents
        ty0 = y_contents - r.height
        for i in range(n_cols):
            self.drawroundbox(math.floor(x0), ty0,
                              math.floor(col_size + x0) - math.floor(x0) + 1,
                              head_h + 1, r2)

            self.drawstring(Unicode(
                time.strftime(timeformat,
                              time.localtime(to_listing[0][i + 1]))),
                            head_val.font,
                            content,
                            x=(x0 + ig.x),
                            y=(ty0 + ig.y),
                            width=ig.width,
                            height=-1,
                            align_v='center',
                            align_h=head_val.align)
            x0 += col_size

        # define start and stop time
        date = time.strftime("%x", time.localtime())
        start_time = to_listing[0][1]
        stop_time = to_listing[0][-1]
        stop_time += (col_time * 60)
        now_time = time.time()

        # selected program:
        selected_prog = to_listing[1]

        for i in range(2, len(to_listing)):
            ty0 = y0
            tx0 = content.x

            logo_geo = [tx0, ty0, label_width, font_h]

            if label_val.rectangle:
                r = self.get_item_rectangle(label_val.rectangle, label_width,
                                            item_h)[2]
                if r.x < 0:
                    tx0 -= r.x
                if r.y < 0:
                    ty0 -= r.y

                val = default_val

                self.drawroundbox(tx0 + r.x, ty0 + r.y, r.width + 1, item_h, r)
                logo_geo = [
                    tx0 + r.x + r.size, ty0 + r.y + r.size,
                    r.width - 2 * r.size, r.height - 2 * r.size
                ]

            channel_logo = config.TV_LOGOS + '/' + to_listing[i].id + '.png'
            if os.path.isfile(channel_logo):
                channel_logo = self.loadimage(
                    channel_logo,
                    (r.width + 1 - 2 * r.size, item_h - 2 * r.size))
            else:
                channel_logo = None

            if channel_logo:
                self.drawimage(channel_logo, (logo_geo[0], logo_geo[1]))
            else:
                self.drawstring(to_listing[i].displayname,
                                label_val.font,
                                content,
                                x=tx0,
                                y=ty0,
                                width=r.width + 2 * r.x,
                                height=item_h)

            self.drawroundbox(tx0 + r.x, ty0 + r.y, r.width + 1, item_h, r)

            if to_listing[i].programs:
                for prg in to_listing[i].programs:
                    flag_left = 0
                    flag_right = 0

                    if prg.start < start_time:
                        flag_left = 1
                        x0 = x_contents
                        t_start = start_time
                    else:
                        x0 = x_contents + int(
                            float(prg.start - start_time) * prop_1sec)
                        t_start = prg.start

                    if prg.stop > stop_time:
                        flag_right = 1
                        w = w_contents + x_contents - x0
                        x1 = x_contents + w_contents
                    else:
                        w = int(float(prg.stop - t_start) * prop_1sec)
                        x1 = x_contents + int(
                            float(prg.stop - start_time) * prop_1sec)

                    if prg.title == selected_prog.title and \
                       prg.channel_id == selected_prog.channel_id and \
                       prg.start == selected_prog.start and \
                       prg.stop == selected_prog.stop:
                        val = selected_val
                    elif prg.overlap:
                        val = overlap_val
                    elif prg.scheduled:
                        val = scheduled_val
                    elif now_time >= prg.start and now_time <= prg.stop:
                        val = current_val
                    elif now_time > prg.stop:
                        val = past_val
                    else:
                        val = default_val

                    font = val.font

                    try:
                        if prg.title == _('This channel has no data loaded'):
                            val = copy.copy(val)
                            val.align = 'center'
                    except UnicodeError:
                        pass

                    if x0 > x1:
                        break

                    # text positions
                    tx0 = x0
                    tx1 = x1
                    ty0 = y0

                    # calc the geometry values
                    ig = Geometry(0, 0, tx1 - tx0 + 1, item_h)
                    if val.rectangle:
                        ig, r = self.fit_item_in_rectangle(
                            val.rectangle, tx1 - tx0 + 1, item_h, font_h)
                        self.drawroundbox(tx0 + r.x, ty0 + r.y, r.width,
                                          item_h, r)

                    # draw left flag and reduce width and add to x0
                    if flag_left:
                        tx0 += leftarrow_size[0]
                        ig.width -= leftarrow_size[0]
                        if tx0 < tx1:
                            self.drawimage(leftarrow, (tx0-leftarrow_size[0], ty0 +\
                                                       (item_h-leftarrow_size[1])/2))

                    # draw right flag and reduce width and x1
                    if flag_right:
                        tx1 -= rightarrow_size[0]
                        ig.width -= rightarrow_size[0]
                        if tx0 < tx1:
                            self.drawimage(rightarrow,
                                           (tx1, ty0 +
                                            (item_h - rightarrow_size[1]) / 2))

                    # draw the text
                    if tx0 < tx1:
                        self.drawstring(prg.title,
                                        font,
                                        content,
                                        x=tx0 + ig.x,
                                        y=ty0 + ig.y,
                                        width=ig.width,
                                        height=ig.height,
                                        align_v='center',
                                        align_h=val.align)

            i += 1
            y0 += item_h - 1

        # print arrow:
        if menuw.display_up_arrow and area.images['uparrow']:
            self.drawimage(area.images['uparrow'].filename,
                           area.images['uparrow'])
        if menuw.display_down_arrow and area.images['downarrow']:
            if isinstance(area.images['downarrow'].y, types.TupleType):
                v = copy.copy(area.images['downarrow'])
                v.y = eval_attr(v.y, y0)
            else:
                v = area.images['downarrow']
            self.drawimage(area.images['downarrow'].filename, v)