Drawing a GtkButton on a GdkPixmap on a GtkDrawingArea



Hello all,

        I'm having a really difficult time doing something I feel ought to be
rather easy.

        I'd like to draw arbitrary widgets surrounded by a colored border.  I
decided the best way to do this would be to layout the widgets normally
inside of a container (e.g. a VBox) then place them in a GtkFixed.  I
can catch the size-allocate for the fixed, and tell the child widgets to
resize accordingly.  I can even make sure they will have plenty of space
around them for the border, but whenever I try to actually place them
and the border (a GtkPixmap) into the fixed, the pixmap completely
covers the widgets!  I've tried adding them to the fixed in the opposite
order, etc...  

        Maybe the simple test code below will better illustrate what I'm
getting at...

        Suggestions?


Thanks,

Ian


import pygtk
import gtk


class App:
    
    def run(self):

        self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
        self.window.connect('destroy', self.on_window_destroy)    

        self.fixed = gtk.Fixed()
        self.fixed.set_size_request(400, 100)
        self.fixed.connect('size-allocate', self.on_fixed_size_allocate)

        self.button = gtk.Button('Click me')
        self.button.connect('clicked', self.on_button_clicked)

        self.darea = gtk.DrawingArea()
        self.darea.set_size_request(400, 100)
        self.darea.connect('configure-event',
self.on_drawing_area_configure_event)
        self.darea.connect('expose-event',
self.on_drawing_area_expose_event)

        self.pixmap = None

        #
        # if you comment out putting the darea in the fixed,
        # you can see the button is drawn/sized just right.
        # even reversing the order we ``put'' them in the fixed,
        # the drawing area will paint on top of the button!
        #
        
        self.fixed.put(self.darea, 0, 0)
        self.fixed.put(self.button, 30, 30)
        
        self.window.add(self.fixed)

        self.window.show_all()
        gtk.main()


    def on_fixed_size_allocate(self, widget, allocation):

        #
        # resize the darea/button to fit into the fixed (and thus the
toplevel window)
        #
        
        self.darea.set_size_request(allocation.width, allocation.height)
        self.button.set_size_request(allocation.width - 60,
allocation.height - 60)


    def on_drawing_area_configure_event(self, widget, event):

        #
        # paint a border into an offscreen buffer.  when the drawing
area
        # is ``exposed'' we'll smack this back onto the screen
        #
        
        if self.pixmap:
            del self.pixmap

        gc = self.darea.get_style().dark_gc[gtk.STATE_NORMAL]
        whitegc = self.darea.get_style().bg_gc[gtk.STATE_NORMAL]
            
        drawable = self.darea.window

        width, height = (widget.allocation.width,
widget.allocation.height)
           
        self.pixmap = gtk.gdk.Pixmap(drawable, width, height)
        self.pixmap.draw_rectangle(whitegc, True, 0, 0, width, height)
        self.pixmap.draw_rectangle(gc, True, 5, 5, width - 10, height -
10)

        
    def on_drawing_area_expose_event(self, widget, event):

        #
        # here we blit (?) the offscreen pixmap onto the screen
        # (ie we draw it to the darea's GdkWindow)
        #
        
        gc = self.darea.get_style().dark_gc[gtk.STATE_NORMAL]
        self.darea.window.draw_drawable(gc, self.pixmap, 0, 0, 0, 0, -1,
-1)
                      
        return True

    
    def on_button_clicked(self, widget):

        print 'click!'


    def on_window_destroy(self, widget):

        gtk.main_quit()



if __name__ == '__main__':
    
    app = App()
    app.run()




[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]