Hello there,

well, just to help the people who come after me, here is the solution I
did. It's a bit dirty, sorry for that. Anyways, it loads the file
base.png in the same folder and puts it on a 800x650 window with
transparency and XShape clipping:

import sys
import gobject
import pango
import pygtk
import gtk
from gtk import gdk
import cairo
# import Images
import gobject

class pngtranswin:
        def __init__(self):
                self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
                
                self.window.set_decorated(0)
                self.window.set_default_size(800, 650)
                
                self.window.set_events(gtk.gdk.ALL_EVENTS_MASK)
                
                # Initialize colors, alpha transparency         
                self.window.set_app_paintable(1)
                self.gtk_screen = self.window.get_screen()
                colormap = self.gtk_screen.get_rgba_colormap()
                if colormap == None:
                        colormap = self.gtk_screen.get_rgb_colormap()
                gtk.widget_set_default_colormap(colormap)
                if not self.window.is_composited():
                        self.supports_alpha = False
                else:
                        self.supports_alpha = True
                
                self.w,self.h = self.window.get_size()
                
                self.window.connect("expose_event", self.expose)
                self.window.connect("destroy", gtk.main_quit)
                

        def expose (self, widget, event):
                self.ctx = self.window.window.cairo_create()
                # set a clip region for the expose event, XShape stuff
                self.ctx.save()
                if self.supports_alpha == False:
                        self.ctx.set_source_rgb(1, 1, 1)
                else:
                        self.ctx.set_source_rgba(1, 1, 1,0)
                self.ctx.set_operator (cairo.OPERATOR_SOURCE)
                self.ctx.paint()
                self.ctx.restore()
                self.ctx.rectangle(event.area.x, event.area.y,
                                event.area.width, event.area.height)
                self.ctx.clip()
                self.draw_image(self.ctx,0,0,'base.png')

        def setup(self):
                # Set menu background image
                self.background =  gtk.Image()
                self.frame = gtk.Fixed()
                self.window.add (self.frame)
                
                # Set window shape from alpha mask of background image
                w,h = self.window.get_size()
                if w==0: w = 800
                if h==0: h = 650
                self.w = w
                self.h = h
                self.pixmap = gtk.gdk.Pixmap (None, w, h, 1)
                ctx = self.pixmap.cairo_create()
                # todo: modify picture source
                #self.bgpb = gtk.gdk.pixbuf_new_from_file('base.png')
                ctx.save()
                ctx.set_source_rgba(1, 1, 1,0)
                ctx.set_operator (cairo.OPERATOR_SOURCE)
                ctx.paint()
                ctx.restore()
                self.draw_image(ctx,0,0,'base.png')
                
                if self.window.is_composited():
                        ctx.rectangle(0,0,w,h)
                        ctx.fill()                      
                        self.window.input_shape_combine_mask(self.pixmap,0,0)
                else:
                        self.window.shape_combine_mask(self.pixmap, 0, 0)

        def draw_image(self,ctx,x,y, pix):
                """Draws a picture from specified path with a certain width and
height"""

                ctx.save()
                ctx.translate(x, y)     
                pixbuf = gtk.gdk.pixbuf_new_from_file(pix)
                format = cairo.FORMAT_RGB24
                if pixbuf.get_has_alpha():
                        format = cairo.FORMAT_ARGB32
                #if Images.flip != None:
                #       pixbuf = pixbuf.flip(Images.flip)
        
                iw = pixbuf.get_width()
                ih = pixbuf.get_height()
                image = cairo.ImageSurface(format, iw, ih)
                image = ctx.set_source_pixbuf(pixbuf, 0, 0)
                
                ctx.paint()
                puxbuf = None
                image = None
                ctx.restore()
                ctx.clip()

        def show_window(self):
                self.window.show_all()
                while gtk.events_pending():
                        gtk.main_iteration()
                self.window.present()
                self.window.grab_focus()
                self.p = 1

if __name__ == "__main__":
        m = pngtranswin()
        m.setup()
        m.show_window()
        gtk.main()

Ok, you can see that it is a bit prototype state, but works. Any
functional comments?

~ Seth


On Sat, 2009-01-03 at 11:48 +0100, Pietro Battiston wrote:
> Il giorno mer, 31/12/2008 alle 01.22 +0100, Sebastian Bartos ha scritto:
> > Hello there,
> > 
> > I'm working on a little app here that uses cairo and a transparent png
> > for nifty window design (kind of like widgets/screenlets, no border,
> > transparency, etc.)
> > 
> > Now I try to figure out how to tell the XShape extension to take the
> > fully transparent parts of the window and cut them away (really
> > irregular borders).
> > 
> > Any ideas?
> > 
> > Thanks
> > Seth Kriticos
> 
> 
> I once tried it, please look if this does what you want (and eventually
> do it in some less chaotic way! It was really just a proof of concept):
> 
> -----------------------------------------------------------------------
> 
> 
> import gtk, gobject
> 
> 
> N,M=200,200
> 
> drag_icon_xpm = [
> str(N)+" "+str(M)+" 1 1",
> "       c None"]+[' '*N]*M
> 
> 
> w = gtk.Window()
> 
> 
> def apply_mask():
>     p = gtk.gdk.pixmap_create_from_xpm_d(w.window , None,
> drag_icon_xpm)[1]
>     r=p.cairo_create()
>     r.arc(N/2, M/2, min(N,M)/2, .0001, 0)
>     r.fill()
>     w.shape_combine_mask(p, 0, 0)
>     w.set_decorated(False)
>     return
>     
>     
> b=gtk.Button("Click me,\n stupid")
> w.add(b)
> b.connect('released', gtk.main_quit)
> w.set_size_request(200,200)
> w.show_all()
> 
> gobject.timeout_add(1, apply_mask)
> 
> gtk.main()
> 
-- 
Sebastian Bartos, <seth.kriti...@googlemail.com>
keyserevr: pgp.mit.edu

Attachment: signature.asc
Description: This is a digitally signed message part

_______________________________________________
pygtk mailing list   pygtk@daa.com.au
http://www.daa.com.au/mailman/listinfo/pygtk
Read the PyGTK FAQ: http://faq.pygtk.org/

Reply via email to