[cairo] Some questions...

Jonathon Jongsma jonathon.jongsma at gmail.com
Sat Jul 14 15:06:34 PDT 2007


On 7/14/07, Loïc Faure-Lacroix <loicfl at gmail.com> wrote:
> I'm working with gtkmm + cairomm
>
> I don't know if its a bug or not.
>
> I do override the expose-event function of my window.
> But now anything added over my window isn't rendered except drawing area
> that their on_expose_event is overrided too.
>
> it's like if the window was rendering over everything.
>
> My main goal is to make a borderless window with rounded corner.
> And a custom skin for the widgets.
>
> I can use a custom skin with Gtk::RC rc(" myfile.gtkrc");
> But my last and only problem is to make a window that doesn't render over
> every widget...
> I done that with gtk+ and cairo.
> But i don't exactly understand why in cairomm it doesn't work.
>
> here is what i want to do with cairomm...
> http://img54.imageshack.us/img54/6558/steambm1.png
>
> -----------------------------------CairoWindow.cc--------------------------------------------------
> #include "cairo-window.h"
> #include "cairo.h"
>
> CairoWindow::CairoWindow(){
>     this->on_screen_changed(this->get_screen());
> }
> CairoWindow::~CairoWindow(){}
>
> bool CairoWindow::on_expose_event(GdkEventExpose* event){
>   Glib::RefPtr<Gdk::Window> window = get_window();
>   if(window)
>   {
>     Gtk::Allocation allocation = get_allocation();
>     const int width = allocation.get_width();
>     const int height = allocation.get_height ();
>
>     Cairo::RefPtr<Cairo::Context> cr = window->create_cairo_context();
>
>     cr->set_source_rgba(0.0, 0.0, 0.0, 0.0);
>     cr->set_operator(Cairo::OPERATOR_SOURCE );
>     cr->rectangle(event-> area.x, event->area.y,
>             event->area.width, event->area.height);
>
>     cr->clip();
>
>     cr->save();
>     cr->paint();
>
>     int distance = 10;
>
>
>     cr->set_source_rgba( 0.27f, 0.27f, 0.27f,1);
>
>     cr->move_to(distance,0);
>     cr->line_to(width-distance,0);
>     cr->curve_to(width-distance,0, width, 0, width,distance);
>     cr->line_to(width,height-distance);
>
> cr->curve_to(width,height-distance,width,height,width-distance,height);
>     cr->line_to(distance,height);
>     cr->curve_to(distance,height,0,height,0,height -
> distance);
>     cr->line_to(0,distance);
>     cr->curve_to(0,distance,0,0,distance,0);
>     cr->fill();
>
>     cr->set_source_rgba(0.35f, 0.42f, 0.31f,1);
>     cr->move_to(distance,0);
>     cr->line_to(width-distance,0);
>     cr->curve_to(width-distance,0, width, 0, width,distance);
>     cr->line_to(width, distance * 3);
>     cr->line_to(0, distance * 3);
>     cr->line_to(0, distance);
>     cr->curve_to(0,distance, 0, 0, distance,0);
>     /*cairo_curve_to(cr,0, height - 5, 0, height, 5,height);
>     cairo_line_to(cr,0, height);
>     cairo_line_to(cr,width,height);
>     cairo_line_to(cr,width,0);*/
>
>     /*cairo_arc(cr, width / 2, height / 2, (width < height ? width : height)
> / 2 - 8 , 0, 2 * 3.14 );*/
>     cr->fill();
>     cr->stroke();
>     cr->restore();
>   }
> }
>
> void CairoWindow::on_screen_changed( const Glib::RefPtr<Gdk::Screen>&
> previous_screen ){
>     const Glib::RefPtr<Gdk::Screen> screen = this->get_screen();
>     const Glib::RefPtr<Gdk::Colormap> colormap =
> screen->get_rgba_colormap();
>
>     if(colormap){
>         std::cout << "Screen support alpha channel";
>     }else{
>         std::cout << "Screen support alpha channel";
>     }
>     this->set_colormap(colormap);
> };
>
> ----------------------------------------------------------------------------------------------------------
> ------------------------------------------CairoWindow.h--------------------------------------------
> #ifndef GTKMM_CAIRO_WINDOW_H
> #define GTKMM_CAIRO_WINDOW_H
>
> #include <gtkmm/window.h>
> #include <iostream>
>
> class CairoWindow : public Gtk::Window
> {
>     public:
>         CairoWindow();
>         virtual ~CairoWindow();
>
>     protected:
>         //Override default signal handler:
>        virtual bool on_expose_event(GdkEventExpose* event);
>         virtual void on_screen_changed( const Glib::RefPtr<Gdk::Screen>&
> previous_screen);
> };
>
> #endif // GTKMM_EXAMPLE_CLOCK_H
>
> -----------------------------------------------------------------------------------------------------------
>
> I may be missing something but i believe this is fairly simple

Disclaimer: I don't know if I fully understand what your problem is,
and I haven't tested any of the following, but hopefully it's helpful.

When you are over-riding a virtual function, you are replacing the
default handler with the one that you provide.  Therefore, if you want
to do your custom action *in addition to* the standard one, you should
call the inherited class's virtual function, e.g.:

bool CairoWindow::on_expose_event(GdkEventExpose* event){
  Gtk::Window::on_expose_event(event); // IMPORTANT
  // the rest of your function
}

The reason you did it without problem in GTK+ / cairo was probably
because you weren't overriding the standard signal handler, you were
just connecting your handler to the expose event signal.  The
equivalent to doing it this way in gtkmm is something like the
following:

win->signal_expose_event ().connect (sigc::mem_fun(*this,
&CairoWindow::expose_handler))

(assuming you have defined the function CairoWindow::expose_handler())

This is different from overriding the virtual function since it
connects an additional slot instead of replacing the default slot.

Hope that helps.

p.s. if this advice doesn't help, I think this is probably a gtkmm
usage issue rather than an issue with cairomm, so you may get better
help on the gtkmm list
-- 
jonner


More information about the cairo mailing list