Hi,

On Wed, Dec 23, 2009 at 5:28 PM, Brent Chiodo <bchi...@gmail.com> wrote:
> Hi,
>
> The code I've been looking at is a fairly simple widget in Extras called
> countdown-home. 95% of it is "fluff" and has nothing to do with this problem
> so I've attached a working Python Desktop Widget (very simple, just a couple
> gtk.Label's). countdown-home is available from here:
>
> http://repository.maemo.org/extras/pool/fremantle/free/source/c/countdown-home/
>
> (I tried attaching the C file, but the list said it was too big).
>
> If you could try to translate the cairo code from coundown-home into the
> Python example, that would be awesome!

I didn't translate the code above, but the simpler example Marc sent
(example_clock_widget), because it was just easier to experiment with
(and I will probably add to the examples section on the PyMaemo wiki
page).

But from this translation experiment, I noticed a few points you must
be aware when implementing python widgets using cairo:

* Use do_expose_event() and do_realize() methods instead of realize()
and screen_changed() ones you used (just rename "def expose(self,
widget, event)" to "def do_expose_event(self, event)" and "def
screen_changed(self, widget)" to "def do_realize(self)"

* Remember to call hildondesktop.HomePluginItem.do_realize(self) at
the end of your do_realize() implementation (**very important**). This
is needed because hildondesktop has its own internal implementation
that must be called.

The code is attached. Merry Christmas :)

PS: I didn't translate the settings dialog part yet. Will do so later.

Regards,
-- 
Anderson Lizardo
OpenBossa Labs - INdT
Manaus - Brazil
# Example based on C code from:
# https://garage.maemo.org/svn/maemoexamples/trunk/example_desktop_widget/src/example_clock_desktop_widget.c

import math
import time
import sys

import gtk
import glib
import cairo
import hildon
import hildondesktop

def on_timeout(widget):
    widget.time = time.localtime()

    if not widget.window:
        return True

    region = widget.window.get_clip_region()
    if not region:
        return True

    widget.window.invalidate_region(region, True)
    widget.window.process_updates(True)

    return True

def on_destroy(object):
    glib.source_remove(object.timeout_handler)

def on_button_press_event(widget, event):
    text = "Current Time: %s" % time.asctime(widget.time)
    hildon.hildon_banner_show_information(widget, "", text)

    return True

class HelloHomePlugin(hildondesktop.HomePluginItem):
    def __init__(self):
        hildondesktop.HomePluginItem.__init__(self)
        self.timeout_handler = glib.timeout_add(1000, on_timeout, self)

        self.color = gtk.gdk.color_parse("white")
        self.time = time.localtime()

        mask = self.get_events() | gtk.gdk.BUTTON_PRESS_MASK
        self.set_events(mask)

        self.connect("button-press-event", on_button_press_event)

        # TODO: add settings dialog
        #self.set_settings(True)
        #self.connect("show-settings", on_show_settings)

        # FIXME: is there any equivalent of the "dispose" callback?
        self.connect("destroy", on_destroy)

    def _draw(self, cr):
        cr.set_source_rgba(1.0, 1.0, 1.0, 0.0)
        cr.set_operator(cairo.OPERATOR_SOURCE)
        cr.paint()

        x = self.allocation.width / 2
        y = self.allocation.height / 2
        radius = min(x, y) - 5

        cr.arc(x, y, radius, 0, 2 * math.pi)
        cr.set_source_rgb(self.color.red / 65535, self.color.green / 65535, self.color.blue / 65535)
        cr.fill_preserve()
        cr.set_source_rgb(0, 0, 0)
        cr.stroke()

        for i in range(0, 12):
            inset = 0
            cr.save()
            if i % 3 == 0:
                inset = 0.2 * radius
            else:
                inset = 0.1 * radius
                cr.set_line_width(0.5 * cr.get_line_width())
            cr.move_to(x + (radius - inset) * math.cos(i * math.pi / 6),
                       y + (radius - inset) * math.sin(i * math.pi / 6))
            cr.line_to(x + radius * math.cos(i * math.pi / 6),
                       y + radius * math.sin(i * math.pi / 6))
            cr.stroke()
            cr.restore()

            hours, minutes, seconds = self.time[3:6]

            cr.save()
            cr.set_line_width(2.5 * cr.get_line_width())
            cr.move_to(x, y)
            cr.line_to(x + radius / 2 * math.sin(math.pi / 6 * hours + math.pi / 360 * minutes),
                       y + radius / 2 * -math.cos(math.pi / 6 * hours + math.pi / 360 * minutes))
            cr.stroke()
            cr.restore()

            cr.move_to(x, y)
            cr.line_to(x + radius * 0.75 * math.sin(math.pi / 30 * minutes),
                       y + radius * 0.75 * -math.cos(math.pi / 30 * minutes))
            cr.stroke()

            cr.save()
            cr.set_source_rgb(1, 0, 0)
            cr.move_to(x, y)
            cr.line_to(x + radius * 0.7 * math.sin(math.pi / 30 * seconds),
                       y + radius * 0.7 * -math.cos(math.pi / 30 * seconds))
            cr.stroke()
            cr.restore()

    def do_expose_event(self, event):
        cr = self.window.cairo_create()

        cr.rectangle(event.area.x, event.area.y,
                     event.area.width, event.area.height)
        cr.clip()

        self._draw(cr)

    def do_realize(self):
        screen = self.get_screen()
        self.set_colormap(screen.get_rgba_colormap())
        self.set_app_paintable(True)
        hildondesktop.HomePluginItem.do_realize(self)

hd_plugin_type = HelloHomePlugin

if __name__ == "__main__":
    import gobject
    gobject.type_register(hd_plugin_type)
    obj = gobject.new(hd_plugin_type, plugin_id="plugin_id")
    obj.show_all()
    gtk.main()
_______________________________________________
maemo-developers mailing list
maemo-developers@maemo.org
https://lists.maemo.org/mailman/listinfo/maemo-developers

Reply via email to