Hey Milosz:
Thanks very much for the detailed informaion about expose_event. And the
describtion about "Graphics" in Mono is very helpful too. :)
Now i know that when handling the expose_event, we should create a
"Context" every time . It is like that when we handle the WM_PAINT msg on
micro windows, we should call "BeginPaint" to get the DC ervey time. I think
they have the same strategy.
BTW, I prefer GtkMM to MFC.
Now thanks everyone who replys my message, and i get what i want , just as
following code shows:
#include <gtkmm/drawingarea.h>
#include <gtkmm/main.h>
#include <gtkmm/window.h>
#include <cairomm/context.h>
#include <iostream>
class MyArea : public Gtk::DrawingArea
{
public:
MyArea();
virtual ~MyArea();
protected:
//Override default signal handler:
virtual bool on_expose_event(GdkEventExpose* event);
virtual bool on_button_press_event (GdkEventButton* event);
private:
Cairo::RefPtr<Cairo::Context> cr_;
};
MyArea::MyArea()
{
add_events(Gdk::BUTTON_PRESS_MASK);
}
MyArea::~MyArea()
{
}
bool MyArea::on_button_press_event(GdkEventButton* event)
{
if(!cr_){
Glib::RefPtr<Gdk::Window> window = get_window();
cr_ = window->create_cairo_context();
}
cr_->move_to(0, 0);
cr_->line_to(event->x, event->y);
cr_->stroke();
}
bool MyArea::on_expose_event(GdkEventExpose* event)
{
Glib::RefPtr<Gdk::Window> window = get_window();
Cairo::RefPtr<Cairo::Context> cr = window->create_cairo_context();
cr->set_line_width(10.0);
cr->move_to(0, 0);
cr->line_to(100, 100);
cr->stroke();
return true;
}
int main(int argc, char** argv)
{
Gtk::Main kit(argc, argv);
Gtk::Window win;
win.set_title("DrawingArea");
MyArea area;
win.add(area);
area.show();
Gtk::Main::run(win);
return 0;
}
2008/12/4 Milosz Derezynski <[EMAIL PROTECTED]>
>
>
> 2008/12/4 BC Zhu <[EMAIL PROTECTED]>
>
>> Cairo::RefPtr<Cairo::Context> cr = window->create_cairo_context();//
>> The above sentence indicate me that cr is an smart pointer , so i can
>> keep it as a class memeber or pass it as an argument to anthoer function, if
>> this i can used it anywhere, and doesn't need to call "
>> get_window()->create_cairo_context()" again and again. May be "
>> get_window()->create_cairo_context()" is a cheap action, but according to
>> the rule "DONOT REPEAT YOURSELF", i think its better to creat it one time,
>> and use it any where.
>>
>
> Hey BC,
>
> Generally this rule is right, but I do think that there are implications
> with widget window double buffering.
>
> From the GTK+ FAQ at library.gnome.org (
> http://library.gnome.org/devel/gtk/stable/gtk-question-index.html):
>
> "If you create a cairo context outside the expose handler, it is backed by
> the GDK window itself, not the double-buffering pixmap."
>
> Now this isn't an exact response to what you are asking, but what this
> implies to me is that the specific drawable you create the cairo context for
> in the expose handler is not guaranteed to be the same thing that you need
> to draw in the next call of expose, and so forth.
>
> Also, this example for Cairo in Mono (yes, it is Mono, but the relevant
> point is not about Mono, but the way Cairo/Gtk+ interaction works)
> clearly states that reusing the same Cairo Context (in the example it's of
> class type Cairo.Graphics) over multiple calls of expose will not work:
> "Don't try to keep Graphics across multiple expose events, this will not
> work due to double-buffering."
>
>
> M.
>
>
>>
>> 2008/12/3 Milosz Derezynski <[EMAIL PROTECTED]>
>>
>> It does not seem neccessary to create 2 separate Cairo Contexts:
>>>
>>> class MyArea : public Gtk::DrawingArea
>>> {
>>> public:
>>> virtual ~MyArea();
>>> protected:
>>> //Override default signal handler:
>>> virtual bool on_expose_event(
>>>
>>>> GdkEventExpose* event);
>>>> };
>>>> MyArea::MyArea()
>>>> {
>>>> }
>>>> MyArea::~MyArea()
>>>> {
>>>> }
>>>> bool MyArea::on_expose_event(GdkEventExpose* event)
>>>> {
>>>> // This is where we draw on the window
>>>> Cairo::RefPtr<Cairo::Context> cr = window->create_cairo_context();
>>>> cr->set_line_width(10.0);
>>>> cr->move_to(0, 0);
>>>> cr->line_to(100, 100);
>>>> cr->stroke();
>>>> return true;
>>>> }
>>>>
>>>
>>> This will work equally well. Is there any specific reason why you want to
>>> keep the surface member in the class and use it the way you wrote it in the
>>> preceding mail?
>>>
>>> M.
>>>
>>>
>>> 2008/12/3 BC Zhu <[EMAIL PROTECTED]>
>>>
>>>> Now i am using Gtkmm. I want to maintain a reference to Cairo::Context
>>>> or Cairo::Surface, so i can draw something on it anywhere.
>>>> I am trying to do this , but failed.
>>>> With following code , i am trying to keep a reference to
>>>> Cairo:::Surface,but when on_expose_event was called secondly , it will
>>>> fail.
>>>> And i have tried to maintain a reference to Cairo::Context too, but
>>>> failed either.
>>>> Could some body give me an advice?
>>>> Thanks in advance!
>>>>
>>>>
>>>> class MyArea : public Gtk::DrawingArea
>>>> {
>>>> public:
>>>> virtual ~MyArea();
>>>> protected:
>>>> //Override default signal handler:
>>>> virtual bool on_expose_event(GdkEventExpose* event);
>>>> private:
>>>> Cairo::RefPtr<Cairo::Surface> surf_;
>>>> };
>>>> MyArea::MyArea()
>>>> {
>>>> }
>>>> MyArea::~MyArea()
>>>> {
>>>> }
>>>> bool MyArea::on_expose_event(GdkEventExpose* event)
>>>> {
>>>> // This is where we draw on the window
>>>> if(!surf_){
>>>> Glib::RefPtr<Gdk::Window> window = get_window();
>>>> Cairo::RefPtr<Cairo::Context> cr =
>>>> window->create_cairo_context();
>>>> surf_ = cr->get_target();
>>>> }
>>>> Cairo::RefPtr<Cairo::Context> cr = Cairo::Context::create(surf_);
>>>> cr->set_line_width(10.0);
>>>> cr->move_to(0, 0);
>>>> cr->line_to(100, 100);
>>>> cr->stroke();
>>>> return true;
>>>> }
>>>>
>>>>
>>>> --
>>>> Best Regards
>>>> Bicen.Zhu
>>>>
>>>> _______________________________________________
>>>> gtkmm-list mailing list
>>>> [email protected]
>>>> http://mail.gnome.org/mailman/listinfo/gtkmm-list
>>>>
>>>>
>>>
>>>
>>> --
>>> Please note that according to the German law on data retention,
>>> information on every electronic information exchange with me is
>>> retained for a period of six months.
>>> [Bitte beachten Sie, dass dem Gesetz zur Vorratsdatenspeicherung zufolge
>>> jeder elektronische Kontakt mit mir sechs Monate lang gespeichert wird.]
>>>
>>
>>
>>
>> --
>> Best Regards
>> Bicen.Zhu
>>
>
>
>
> --
> Please note that according to the German law on data retention,
> information on every electronic information exchange with me is
> retained for a period of six months.
> [Bitte beachten Sie, dass dem Gesetz zur Vorratsdatenspeicherung zufolge
> jeder elektronische Kontakt mit mir sechs Monate lang gespeichert wird.]
>
--
Best Regards
Bicen.Zhu
_______________________________________________
gtkmm-list mailing list
[email protected]
http://mail.gnome.org/mailman/listinfo/gtkmm-list