From b76756c2a8274332a519e0b25f08d401150f881e Mon Sep 17 00:00:00 2001 From: tchernobog Date: Thu, 3 Aug 2006 11:16:16 +0000 Subject: [PATCH] - Add untested code to SchedulableWidget, manually inheriting from a raw Gtk::Widget and doing things by hand git-svn-id: svn://svn.gna.org/svn/sgpemv2/trunk@819 3ecf2c5c-341e-0410-92b4-d18e462d057c --- src/cairo_elements.hh | 2 +- src/schedulables_widget.cc | 87 ++++++++++++++++++++++++++------------ src/schedulables_widget.hh | 8 ++-- 3 files changed, 66 insertions(+), 31 deletions(-) diff --git a/src/cairo_elements.hh b/src/cairo_elements.hh index 8f69faf..a2a3830 100644 --- a/src/cairo_elements.hh +++ b/src/cairo_elements.hh @@ -26,7 +26,7 @@ #include "backend/thread.hh" #include "backend/process.hh" -#include +#include namespace sgpem { diff --git a/src/schedulables_widget.cc b/src/schedulables_widget.cc index 96aa7ed..9c3d2e2 100644 --- a/src/schedulables_widget.cc +++ b/src/schedulables_widget.cc @@ -24,6 +24,8 @@ #include "backend/history.hh" #include "backend/simulation.hh" +#include + #include #include @@ -31,12 +33,9 @@ using namespace sgpem; SchedulablesWidget::SchedulablesWidget() - : Gtk::DrawingArea(), _h(1), _buf(NULL) + : Glib::ObjectBase("sgpem_CairoWidget"), + Gtk::Widget(), _h(1), _buf(NULL) { - // Add other events we want to manage (as mouse clicks) - // when needed - add_events(Gdk::EXPOSURE_MASK); - // Register this observer: Simulation::get_instance().get_history().attach(*this); } @@ -51,17 +50,14 @@ SchedulablesWidget::~SchedulablesWidget() void SchedulablesWidget::update(const History& history) { + if(!is_realized()) + return; // Nowhere to draw to. + // Determine the final height before to start drawing unsigned int w = get_allocation().get_width(); _h = calc_height(history); - - // FIXME TO THE EXPERT: this assertion fails. - // is this important??? - assert(is_drawable()); - // FIXME : write me using double buffering - // PROBLEM : get_window() seems to return a null pointer!!! - // I read on the web that get_window() returns a null pointer + // get_window() returns a null pointer // if the widget has not been realized _buf = Gdk::Pixmap::create(get_window(), w, _h); cairo_t* ctx = gdk_cairo_create(_buf->gobj()); @@ -95,32 +91,72 @@ SchedulablesWidget::calc_height(const History& history) const return 400; } + +void +SchedulablesWidget::on_realize() +{ + set_flags(Gtk::REALIZED); + + // Add other events we want to manage (as mouse clicks) + // when needed + add_events(Gdk::EXPOSURE_MASK); + + GdkWindowAttr attributes; + + Gtk::Allocation alloc = get_allocation(); + + attributes.x = alloc.get_x(); + attributes.y = alloc.get_y(); + attributes.width = alloc.get_width(); + attributes.height = alloc.get_height(); + attributes.wclass = GDK_INPUT_OUTPUT; + attributes.visual = get_visual()->gobj(); + attributes.colormap = get_colormap()->gobj(); + + Glib::RefPtr window = Gdk::Window::create(get_parent_window(), + &attributes, + GDK_WA_X | GDK_WA_Y | GDK_WA_COLORMAP | + GDK_WA_VISUAL | GDK_WA_WMCLASS); + set_window(window); + // get_style()->attach(window); + window->set_user_data(gobj()); + get_style()->set_background(window, Gtk::STATE_ACTIVE); +} void SchedulablesWidget::on_size_request(Gtk::Requisition* requisition) { // FIXME: take correct measures, consider also using a viewport(?) *requisition = Gtk::Requisition(); - requisition->width = get_allocation().get_width(); - requisition->height = _h; + requisition->width = get_allocation().get_width(); + requisition->height = _h; +} + + +void +SchedulablesWidget::on_size_allocate(const Gtk::Allocation& allocation) +{ + set_allocation(allocation); + + if(is_realized()) + get_window()->move_resize(allocation.get_x(), allocation.get_y(), + allocation.get_width(), allocation.get_height()); } bool SchedulablesWidget::on_expose_event(GdkEventExpose* event) { - const Gtk::Allocation& allocation = get_allocation(); - int width = allocation.get_width(); - int height = allocation.get_height(); + if(!event || event->count > 0) + return false; + + // calculated dinamically: + set_size_request(get_allocation().get_width(), _h); // Clip to redraw only the smallest possible area std::auto_ptr clip_area; - if(event) - clip_area = std::auto_ptr(new Gdk::Rectangle(event->area.x, event->area.y, - event->area.width, event->area.height)); - - else - clip_area = std::auto_ptr(new Gdk::Rectangle(0, 0, width, height)); + clip_area = std::auto_ptr(new Gdk::Rectangle(event->area.x, event->area.y, + event->area.width, event->area.height)); // Use double buffering or we're CPU-dead // Copy from the buffer to the screen @@ -129,10 +165,7 @@ SchedulablesWidget::on_expose_event(GdkEventExpose* event) clip_area->get_x(), clip_area->get_y(), clip_area->get_x(), clip_area->get_y(), clip_area->get_width(), clip_area->get_height()); - - // calculated dinamically: - set_size_request(width, _h); - + return true; } diff --git a/src/schedulables_widget.hh b/src/schedulables_widget.hh index f3de0ec..9dd5a54 100644 --- a/src/schedulables_widget.hh +++ b/src/schedulables_widget.hh @@ -25,13 +25,13 @@ #include "backend/history_observer.hh" -#include -#include +#include +#include #include namespace sgpem { - class SchedulablesWidget : public Gtk::DrawingArea, public HistoryObserver + class SchedulablesWidget : public Gtk::Widget, public HistoryObserver { public: SchedulablesWidget(); @@ -40,6 +40,8 @@ namespace sgpem void update(const History& history); protected: + virtual void on_realize(); + virtual void on_size_allocate(const Gtk::Allocation& allocation); virtual void on_size_request(Gtk::Requisition* requisition); virtual bool on_expose_event(GdkEventExpose* event); virtual bool on_button_press_event(GdkEventButton* event);