Dirk Meyer wrote:
Hi,

[EMAIL PROTECTED] wrote:

freevo-weather
===============

REQUIREMENTS: freevo 1.5 (or current cvs)

A mythtv-style enhanced weather plugin. This plugin allows you to
track the weather at multiple locations.


This plugin is a great and small plugin example. I don't want to
integrate in Freevo because this way, a plugin writer can easily see
what is needed to write a plugin.

If you want to draw something on the skin (mail reader plugin?), this
is the perfect example on how to do that.


Dischi



Hello! I tried the weather plugin and I think it's great. Although the plugin required me to update to python 2.3 because of the datetime module (it was about time I did though :).

There is a bug when drawing the screens today and extended forecast
when having set OSD_OVERSCAN values. See:
 - http://www.matrise.net/~viggo/freevo/weather/ext_forecast.jpg
 - http://www.matrise.net/~viggo/freevo/weather/today_forecast.jpg

It would be interesting to do something like this for the mailreader.
I did some work on the gui last week, and while it's not pretty yet,
this is what it looks like atm.
 - http://www.matrise.net/~viggo/freevo/weather/newreader.jpg

It doesn't use the <content> area, but it uses the <view> area, and gets
the sizerects to draw a scrollable surface in. The text background is
transparent, so scrolling is seemless to the view area. And it now also
draws image attachments to the surface. I would like to draw this on a
seperate surface in the future (toggle between text and image).

I would think that the weather approach would be a more elegant
solution to this. But would it be possible to scroll the text
both vertical and horizontal? I haven't taken a good look at the
write_text method yet.

I would like to get some ideas on how to do it better than it is today.
I attached the gui if someone wants to take a look.

.viggo
#if 0 /*
# -----------------------------------------------------------------------
# TextReader.py - a scrollable textreader
# Author: Viggo Fredriksen <[EMAIL PROTECTED]>
# Notes:
#  :The sizes of the reader is determined by the
#   skins <reader> <view layout
#  :Should this be split up into two things:
#   - one part in skins/main/TextArea.py
#   - one part in gui/TextReader.py
#     -> How to do this correctly?
# Todo:
#  - Cleanup frame width/height/padding
#  - Check bug: ... on other box
# -----------------------------------------------------------------------
# Freevo - A Home Theater PC framework
# Copyright (C) 2002 Krister Lagerstrom, et al. 
# Please see the file freevo/Docs/CREDITS for a complete list of authors.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of MER-
# CHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
# Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# ----------------------------------------------------------------------- */
#endif

import rc, skin, pygame
from gui import Scrollbar, Color, Container, AlertBox
from event import *

skin = skin.get_singleton()
skin.register('reader', ('screen', 'title', 'view', 'info', 'plugin'))

class TextReader(Container):
    """
    text      : text to render (uses soft drawstringframed)
    item      : item to associate it with (for info)
    imagelist : list of pairs of filenames and description text
    menuw     : pass this if you want to reload the menuwidget
                after the reader has finished
    fontname  : name of the skin font to use
    """
    def __init__(self, text=' ', item=None, imagelist=None, menuw=None, 
fontname='default'):

        ## init
        self.item              = item
        self.menuw             = menuw
        self.pictures          = []
        self.int_pad           = 5
        self.img_h             = 0
        self.x_scroll_interval = 25
        self.y_scroll_interval = 25
        self.v_x,self.v_y      = 0,0
        self.show_v_scrollbar  = 0
        self.show_h_scrollbar  = 0

        # draw the skin and get the View_Area sizes
        skin.draw('reader', self.item)
 
        self.font   = skin.get_font(fontname)
        area        = skin.areas['view'].area_val

        # the area we draw to
        self.left   = area.x
        self.top    = area.y
        self.width  = area.width
        self.height = area.height

        Container.__init__(self, 'frame', self.left, self.top,
                           self.width, self.height)
      
        ## Initialize drawing

        # get sizes for the text
        (x0,y0,x1,y1) = self.osd.drawstringframed(text, 0, 0, 10000,
                             10000, self.font, mode='soft', layer='')[1]
        self.s_h = y1-y0
        self.s_w = x1-x0

        if self.s_w<self.width:
            self.s_w = self.width

        # prepare images and surfaces
        if imagelist: self.set_images(imagelist)
        self.set_surface()

        # draw string to the surface
        self.osd.drawstringframed(text, 0, 0, self.s_w, self.s_h,
                                  self.font, mode='soft',
                                  layer=self.region_surface)
        
        # draw the pictures to the surface
        self.s_h += self.img_h
        if imagelist:
            self.draw_pictures(self.s_w, (y1-y0) + self.int_pad)

        ## Scrollbars
        self.v_scrollbar  = Scrollbar(self, 'vertical',bd_width=0)
        self.h_scrollbar  = Scrollbar(self, 'horizontal',bd_width=0)
        #def __init__(self, parent, orientation, thickness=10, left=None, top=None,
        #         width=None, height=None, bg_color=None, fg_color=None,
        #         border=None, bd_color=None, bd_width=1):
        self.add_child(self.v_scrollbar)
        self.add_child(self.h_scrollbar)

        if self.s_h>self.height:
            self.show_v_scrollbar = 1
        if self.s_w>self.width:
            self.show_h_scrollbar = 1

        self.max_x_offset = self.s_w - self.width
        self.max_y_offset = self.s_h - self.height


        ## setup rc and osd
        parent = self.osd.app_list[0]
        parent.add_child(self)
        self.parent = parent

        self.osd.add_app(self)
        rc.app(self)
        rc.set_context('input') 

    def set_surface(self):
        # get current snapshot of osd
        self.filler = pygame.Surface((10, 10), 0, 32)
        filler_c = Color((0,0,0,255))
        fc_c = filler_c.get_color_sdl()
        fc_a = filler_c.get_alpha()
        self.filler.fill(fc_c)
        self.filler.set_alpha(fc_a)

        self.snapshot = \
           self.osd.getsurface(self.left, self.top, 
                               self.width, self.height)

        # create a new transparent surface
        # - take the image height in consideration
        h = self.s_h + self.img_h
        if h<self.height:
            h = self.height
        self.region_surface = pygame.Surface((self.s_w, h),
                                             0, 32)
        self.region_surface.set_colorkey(0)

    def set_images(self, imglist=[]):
        """
        Create and transform picture surfaces
        Sets img_h to total height of the surfaces
        Note: Perhaps utilize Layouts?
        """
        max_width = self.s_w-self.int_pad
        
        for i in imglist:
            name = i[1]
            p = pygame.image.load(i[0]).convert_alpha()
            w = p.get_width()
            h = p.get_height()

            # handle pictures larger than width of surface
            if w>max_width:
                aspect = ( float(w) / float(h) )
                h = int( ( float(max_width) / aspect ) )
                p = pygame.transform.scale(p, (max_width, h))

            self.img_h += ( h + self.font.height )
            self.pictures += [ ( p, name ) ]

    def draw_pictures(self, width, height):
        offset = height + self.int_pad

        for p in self.pictures:
            # draw the filename
            (x0,y0,x1,y1) = self.osd.drawstringframed(p[1], 0, offset, width, -1,
                               self.font,align_h='left',
                               align_v='top', mode='hard',
                               layer=self.region_surface)[1]
            offset += (y1-y0)

            # blit the picture to the surface
            self.region_surface.blit(p[0], (0, offset) )
            offset += (p[0].get_height() + self.int_pad)

    def _draw(self, surface=None):
        if not self.width or not self.height or not self.region_surface:
            raise TypeError, 'Not all needed variables set.'
        
        rect = (self.v_x, self.v_y,
               self.width-2*self.int_pad,
               self.height-2*self.int_pad)
        self.surface = pygame.Surface((self.width, self.height), 0, 32)

        self.surface.blit(self.snapshot, (0, 0))
        self.surface.blit(self.region_surface, (self.int_pad, self.int_pad), rect)

        if self.show_v_scrollbar and self.v_scrollbar:
            self.v_scrollbar.draw()
        if self.show_h_scrollbar and self.h_scrollbar:
            self.h_scrollbar.draw()
        if self.show_v_scrollbar and self.show_h_scrollbar:
            self.surface.blit(self.filler,
                             (self.width-self.v_scrollbar.thickness,
                              self.height-self.h_scrollbar.thickness))


        self.blit_parent()

    def scroll(self, direction):
        if direction == INPUT_RIGHT:
            new_x = self.v_x + self.x_scroll_interval
            if new_x > self.max_x_offset:
                new_x = self.max_x_offset
            self.v_x = new_x
        elif direction == INPUT_LEFT:
            new_x = self.v_x - self.x_scroll_interval
            if new_x < 0:
                new_x = 0
            self.v_x = new_x
        elif direction == INPUT_DOWN:
            new_y = self.v_y + self.y_scroll_interval
            if new_y > self.max_y_offset:
                new_y = self.max_y_offset
            self.v_y = new_y
        elif direction == INPUT_UP:
            new_y = self.v_y - self.y_scroll_interval
            if new_y < 0:
                new_y = 0
            self.v_y = new_y

    def get_view_percent(self, orientation):
        if orientation == 'vertical':
            a = self.v_y * 100 / self.s_h 
            b = self.height * 100 / self.s_h 
            c = (self.s_h - (self.v_y + self.height)) * 100 / self.s_h 
        else:
            a = self.v_x * 100 / self.s_w 
            b = self.width * 100 / self.s_w 
            c = (self.s_w - (self.v_x + self.width)) * 100 / self.s_w 

        rem = 100 - a - b - c
        b = b + rem

        return (a, b, c)

    def eventhandler(self, event, menuw=None):
        if event in (INPUT_UP, INPUT_DOWN,INPUT_LEFT, INPUT_RIGHT):
            self.scroll(event)
            self.draw()
            self.osd.update(self.get_rect())
        elif event == INPUT_EXIT:
            self.destroy()
            rc.app(None)
            self.visible = 0
            if self.menuw:
                self.menuw.refresh(reload=1)
        return

Reply via email to