// src/schedulables_widget.cc - Copyright 2005, 2006, University // of Padova, dept. of Pure and Applied // Mathematics // // This file is part of SGPEMv2. // // This is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // SGPEMv2 is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with SGPEMv2; if not, write to the Free Software // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #include "cairo_elements.hh" #include "schedulables_widget.hh" #include "backend/history.hh" #include "backend/simulation.hh" #include #include #include using namespace sgpem; SchedulablesWidget::SchedulablesWidget() : Glib::ObjectBase("sgpem_CairoWidget"), Gtk::Widget(), _h(1), _buf(NULL) { // Register this observer: Simulation::get_instance().get_history().attach(*this); } SchedulablesWidget::~SchedulablesWidget() { Simulation::get_instance().get_history().detach(*this); } 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); // 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()); // do the drawing... draw_widget(ctx); cairo_scale(ctx, w, _h); // manually force an expose_event? cairo_destroy(ctx); } void SchedulablesWidget::draw_widget(cairo_t* ctx) { // NOTE: just to try CairoElements ce(ctx); Color red = { 1, 0, 0 }; Point center = { 25, 25 }; ce.draw_3dsphere(center, 25, red); } unsigned int SchedulablesWidget::calc_height(const History& history) const { // FIXME: write me 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; } 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) { 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; 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 if(_buf) get_window()->draw_drawable(Gdk::GC::create(get_window()), _buf, clip_area->get_x(), clip_area->get_y(), clip_area->get_x(), clip_area->get_y(), clip_area->get_width(), clip_area->get_height()); return true; } bool SchedulablesWidget::on_button_press_event(GdkEventButton* event) { // Not here. Yet. return false; }