From bce427d0228559c23cb240096a27a9eea3070509 Mon Sep 17 00:00:00 2001 From: tchernobog Date: Wed, 30 Dec 2009 23:36:01 +0000 Subject: [PATCH] Port the code from Cairo to Cairo--. See the TODO files for bugs and things that require attention. The nasty bug that prevents visualization has been around for a while now, since Gtk+ reached 2.12, I think. Must be fixed. git-svn-id: svn://svn.gna.org/svn/sgpemv2/trunk@1349 3ecf2c5c-341e-0410-92b4-d18e462d057c --- Makefile.am | 16 +- TODO | 4 + configure.ac | 15 +- src/cairo_elements.cc | 211 +++++++++++++------------- src/cairo_elements.hh | 10 +- src/cairo_widget.cc | 82 +++++----- src/cairo_widget.hh | 35 +++-- src/holt_widget.cc | 152 +++++++++---------- src/holt_widget.hh | 14 +- src/simulation_widget.cc | 232 +++++++++++++++-------------- src/simulation_widget.hh | 39 ++--- src/testsuite/test-cairo_widget.cc | 30 ++-- 12 files changed, 419 insertions(+), 421 deletions(-) create mode 100644 TODO diff --git a/Makefile.am b/Makefile.am index 079fb53..e86fbe3 100644 --- a/Makefile.am +++ b/Makefile.am @@ -352,7 +352,7 @@ sgpemv2_CPPFLAGS = \ -DLOCALEDIR="\"$(localedir)\"" \ -DSHAREDIR="\"$(sharedir)\"" \ -DUIDIR="\"$(uidir)\"" \ - $(CAIRO_CFLAGS) \ + $(CAIROMM_CFLAGS) \ $(GTKMM_CFLAGS) \ $(LIBGLADEMM_CFLAGS) \ $(GTHREAD_CFLAGS) @@ -362,7 +362,7 @@ sgpemv2_LDFLAGS = \ -Wl,-rpath -Wl,"$(pkglibdir)" sgpemv2_LDADD = \ src/backend/libbackend.la \ - $(CAIRO_LIBS) \ + $(CAIROMM_LIBS) \ $(GTKMM_LIBS) \ $(GTHREAD_LIBS) @@ -530,11 +530,11 @@ src_testsuite_test_key_file_SOURCES = \ src_testsuite_test_cairo_widget_CPPFLAGS = \ -I@top_srcdir@/src \ -I@top_srcdir@/src/backend \ - $(CAIRO_CFLAGS) \ + $(CAIROMM_CFLAGS) \ $(GTKMM_CFLAGS) \ $(GLIBMM_CFLAGS) src_testsuite_test_cairo_widget_LDFLAGS = \ - $(CAIRO_LIBS) \ + $(CAIROMM_LIBS) \ $(GTKMM_LIBS) \ $(GLIBMM_LIBS) src_testsuite_test_cairo_widget_SOURCES = \ @@ -545,14 +545,14 @@ src_testsuite_test_cairo_widget_SOURCES = \ src_testsuite_test_simulation_widget_CPPFLAGS = \ -I@top_srcdir@/src \ -I@top_srcdir@/src/backend \ - $(CAIRO_CFLAGS) \ + $(CAIROMM_CFLAGS) \ $(GTKMM_CFLAGS) \ $(GLIBMM_CFLAGS) \ $(GTHREAD_CFLAGS) src_testsuite_test_simulation_widget_LDFLAGS = \ src/backend/libbackend.la \ -Wl,-rpath -Wl,"$(pkglibdir)" \ - $(CAIRO_LIBS) \ + $(CAIROMM_LIBS) \ $(GTKMM_LIBS) \ $(GLIBMM_LIBS) \ $(GTHREAD_LIBS) @@ -565,14 +565,14 @@ src_testsuite_test_simulation_widget_SOURCES = \ src_testsuite_test_holt_widget_CPPFLAGS = \ -I@top_srcdir@/src \ -I@top_srcdir@/src/backend \ - $(CAIRO_CFLAGS) \ + $(CAIROMM_CFLAGS) \ $(GTKMM_CFLAGS) \ $(GLIBMM_CFLAGS) \ $(GTHREAD_CFLAGS) src_testsuite_test_holt_widget_LDFLAGS = \ src/backend/libbackend.la \ -Wl,-rpath -Wl,"$(pkglibdir)" \ - $(CAIRO_LIBS) \ + $(CAIROMM_LIBS) \ $(GTKMM_LIBS) \ $(GLIBMM_LIBS) \ $(GTHREAD_LIBS) diff --git a/TODO b/TODO new file mode 100644 index 0000000..d033c8d --- /dev/null +++ b/TODO @@ -0,0 +1,4 @@ +- fix nasty bug that prevents all cairowidgets from showing up +- Check for simulationwidget deprecat. meth. +- check headers for #includes with <> instead of "" +- Report bug for presence of PKG, VERSION, etc. macros inside cairomm-config.h diff --git a/configure.ac b/configure.ac index 70fc814..e18fe34 100644 --- a/configure.ac +++ b/configure.ac @@ -57,9 +57,10 @@ AM_GNU_GETTEXT([external]) AM_GNU_GETTEXT_VERSION([0.17]) dnl various requisites -SIGCPP_VERSION=2.0.10 -GTKMM_VERSION=2.12.1 -CAIRO_VERSION=1.0.0 +SIGCPP_VERSION=2.0.18 +GLIBMM_VERSION=2.22.0 +GTKMM_VERSION=2.18.0 +CAIROMM_VERSION=1.8.0 dnl c++ compiler and flags AC_PROG_CXX @@ -109,9 +110,9 @@ if test -z "$PKG_CONFIG"; then AC_MSG_ERROR([You may need to update your pkg-config installation]) fi -PKG_CHECK_MODULES([CAIRO], - [cairo >= $CAIRO_VERSION], - :, AC_MSG_ERROR([$CAIRO_PKG_ERRORS])) +PKG_CHECK_MODULES([CAIROMM], + [cairomm-1.0 >= $CAIROMM_VERSION], + :, AC_MSG_ERROR([$CAIROMM_PKG_ERRORS])) PKG_CHECK_MODULES([GTHREAD], [gthread-2.0 >= $GTKMM_VERSION], :, AC_MSG_ERROR([$GTHREAD_PKG_ERRORS])) @@ -119,7 +120,7 @@ PKG_CHECK_MODULES([SIGCPP], [sigc++-2.0 >= $SIGCPP_VERSION], :, AC_MSG_ERROR([$SIGCPP_PKG_ERRORS])) PKG_CHECK_MODULES([GLIBMM], - [glibmm-2.4 >= $GTKMM_VERSION], + [glibmm-2.4 >= $GLIBMM_VERSION], :, AC_MSG_ERROR([$GLIBMM_PKG_ERRORS])) PKG_CHECK_MODULES([GTKMM], [gtkmm-2.4 >= $GTKMM_VERSION], diff --git a/src/cairo_elements.cc b/src/cairo_elements.cc index 2581f25..88f345a 100644 --- a/src/cairo_elements.cc +++ b/src/cairo_elements.cc @@ -29,7 +29,7 @@ using namespace sgpem; -CairoElements::CairoElements(cairo_t* const ctx) +CairoElements::CairoElements(const Cairo::RefPtr& ctx) : _ctx(ctx) { } @@ -38,7 +38,8 @@ CairoElements::CairoElements(cairo_t* const ctx) void CairoElements::draw_3dsphere(const Point& center, float radius, const Color& cl) { - cairo_t*& cr = _ctx; + using namespace Cairo; + const float& x = center.x; const float& y = center.y; const float& r = cl.r; @@ -46,52 +47,52 @@ CairoElements::draw_3dsphere(const Point& center, float radius, const Color& cl) const float& b = cl.b; // Draw initial sphere perimeter - cairo_save(cr); - cairo_new_path(cr); - cairo_arc(cr, x, y, radius, 0, 2*M_PI); - cairo_pattern_t* grad = cairo_pattern_create_radial(x, y, radius, x, y, radius - .15); - cairo_pattern_add_color_stop_rgba(grad, 0, r - .2, g - .2, b - .2, 1); - cairo_pattern_add_color_stop_rgba(grad, 1, r, g, b, 1); - cairo_set_source(cr, grad); - cairo_fill_preserve(cr); - cairo_pattern_destroy(grad); - cairo_set_source_rgba(cr, 0, 0, 0, 1); - cairo_set_line_width(cr, radius * .01); - cairo_stroke(cr); - cairo_restore(cr); + _ctx->save(); + _ctx->begin_new_path(); + _ctx->arc(x, y, radius, 0, 2*M_PI); + + RefPtr grad = RadialGradient::create(x, y, radius, x, y, radius - .15); + grad->add_color_stop_rgba(0, r - .2, g - .2, b - .2, 1); + grad->add_color_stop_rgba(1, r, g, b, 1); + _ctx->set_source(grad); + _ctx->fill_preserve(); + + _ctx->set_source_rgba(0, 0, 0, 1); + _ctx->set_line_width(radius * .01); + _ctx->stroke(); + _ctx->restore(); // Internal gradient - cairo_save(cr); - grad = cairo_pattern_create_linear(x, y, x, y + radius); - cairo_pattern_add_color_stop_rgba(grad, 1, r - .4, g - .4, b - .4, 1); - cairo_pattern_add_color_stop_rgba(grad, 0, r, g, b, .7); - cairo_set_source(cr, grad); - cairo_translate(cr, x*.2, (y + radius*8 / 9) * 1 / 3); - cairo_scale(cr, .8, 2. / 3); - cairo_arc(cr, x, y, radius, 0, 2*M_PI); - cairo_fill(cr); - cairo_pattern_destroy(grad); - cairo_restore(cr); + _ctx->save(); + grad = LinearGradient::create(x, y, x, y + radius); + grad->add_color_stop_rgba(1, r - .4, g - .4, b - .4, 1); + grad->add_color_stop_rgba(0, r, g, b, .7); + _ctx->set_source(grad); + _ctx->translate(x*.2, (y + radius*8 / 9) * 1 / 3); + _ctx->scale(.8, 2. / 3); + _ctx->arc(x, y, radius, 0, 2*M_PI); + _ctx->fill(); + _ctx->restore(); // Internal glow - cairo_save(cr); - grad = cairo_pattern_create_linear(x, y - radius, x, y); - cairo_pattern_add_color_stop_rgba(grad, 0, 1, 1, 1, .9); - cairo_pattern_add_color_stop_rgba(grad, 1, 1, 1, 1, .2); - cairo_set_source(cr, grad); - cairo_translate(cr, x * .2, (y - radius*8 / 9) * 1 / 3); - cairo_scale(cr, .8, 2. / 3); - cairo_arc(cr, x, y, radius, 0, 2*M_PI); - cairo_fill(cr); - cairo_pattern_destroy(grad); - cairo_restore(cr); + _ctx->save(); + grad = LinearGradient::create(x, y - radius, x, y); + grad->add_color_stop_rgba(0, 1, 1, 1, .9); + grad->add_color_stop_rgba(1, 1, 1, 1, .2); + _ctx->set_source(grad); + _ctx->translate(x * .2, (y - radius*8 / 9) * 1 / 3); + _ctx->scale(.8, 2. / 3); + _ctx->arc(x, y, radius, 0, 2*M_PI); + _ctx->fill(); + _ctx->restore(); } void CairoElements::draw_3dcube(const Rectangle& area, const Color& cl, const float x_percent, const float y_percent) { - cairo_t*& cr = _ctx; + using namespace Cairo; + const float& x0 = area.x0; const float& y0 = area.y0; const float& w = area.w; @@ -100,54 +101,53 @@ CairoElements::draw_3dcube(const Rectangle& area, const Color& cl, const float& g = cl.b; const float& b = cl.b; - cairo_save(cr); - cairo_set_line_join(cr, CAIRO_LINE_JOIN_ROUND); + _ctx->save(); + _ctx->set_line_join(LINE_JOIN_ROUND); // Front side of the cube: - cairo_rectangle(cr, - x0, y0 + (1 - y_percent) * h, + _ctx->rectangle(x0, y0 + (1 - y_percent) * h, w * x_percent, h * y_percent); - cairo_set_source_rgb(cr, r, g, b); - cairo_fill_preserve(cr); - cairo_set_source_rgb(cr, 0, 0, 0); - cairo_stroke(cr); + _ctx->set_source_rgb(r, g, b); + _ctx->fill_preserve(); + _ctx->set_source_rgb(0, 0, 0); + _ctx->stroke(); // ``Upper'' visible cube side: - cairo_new_path(cr); - cairo_move_to(cr, x0, y0 + (1 - y_percent) * h); - cairo_line_to(cr, x0 + (1 - x_percent) * w, y0); - cairo_line_to(cr, x0 + w, y0); - cairo_line_to(cr, x0 + w * x_percent, y0 + (1 - y_percent) * h); - cairo_close_path(cr); - - cairo_set_source_rgb(cr, r - 0.2, g - 0.2, b - 0.2); - cairo_fill_preserve(cr); - cairo_set_source_rgb(cr, 0, 0, 0); - cairo_stroke(cr); + _ctx->begin_new_path(); + _ctx->move_to(x0, y0 + (1 - y_percent) * h); + _ctx->line_to(x0 + (1 - x_percent) * w, y0); + _ctx->line_to(x0 + w, y0); + _ctx->line_to(x0 + w * x_percent, y0 + (1 - y_percent) * h); + _ctx->close_path(); + _ctx->set_source_rgb(r - 0.2, g - 0.2, b - 0.2); + _ctx->fill_preserve(); + _ctx->set_source_rgb(0, 0, 0); + _ctx->stroke(); // ``Right'' visible cube side: - cairo_new_path(cr); - cairo_move_to(cr, x0 + w * x_percent, y0 + (1 - y_percent) * h); - cairo_line_to(cr, x0 + w, y0); - cairo_line_to(cr, x0 + w, y0 + y_percent * h); - cairo_line_to(cr, x0 + w * x_percent, y0 + h); - cairo_close_path(cr); + _ctx->begin_new_path(); + _ctx->move_to(x0 + w * x_percent, y0 + (1 - y_percent) * h); + _ctx->line_to(x0 + w, y0); + _ctx->line_to(x0 + w, y0 + y_percent * h); + _ctx->line_to(x0 + w * x_percent, y0 + h); + _ctx->close_path(); - cairo_set_source_rgb(cr, r - 0.4, g - 0.4, b - 0.4); - cairo_fill_preserve(cr); - cairo_set_source_rgb(cr, 0, 0, 0); - cairo_stroke(cr); + _ctx->set_source_rgb(r - 0.4, g - 0.4, b - 0.4); + _ctx->fill_preserve(); + _ctx->set_source_rgb(0, 0, 0); + _ctx->stroke(); - cairo_restore(cr); + _ctx->restore(); } void CairoElements::draw_container(const Rectangle& area) { - cairo_t*& cr = _ctx; + using namespace Cairo; + const float& x0 = area.x0; const float& y0 = area.y0; const float& w = area.w; @@ -155,67 +155,68 @@ CairoElements::draw_container(const Rectangle& area) const double corner_radius = 0.05; - cairo_save(cr); - cairo_new_path(cr); - cairo_move_to(cr, x0 + corner_radius, y0); + _ctx->save(); + _ctx->begin_new_path(); + _ctx->move_to(x0 + corner_radius, y0); // NW -> NE - cairo_line_to(cr, x0 + w - corner_radius, y0); - cairo_curve_to(cr, x0 + w, y0, x0 + w, y0, x0 + w, y0 + corner_radius); + _ctx->line_to(x0 + w - corner_radius, y0); + _ctx->curve_to(x0 + w, y0, x0 + w, y0, x0 + w, y0 + corner_radius); // NE -> SE - cairo_line_to(cr, x0 + w, y0 + h - corner_radius); - cairo_curve_to(cr, x0 + w, y0 + h, x0 + w, y0 + h, x0 + w - corner_radius, y0 + h); + _ctx->line_to(x0 + w, y0 + h - corner_radius); + _ctx->curve_to(x0 + w, y0 + h, x0 + w, y0 + h, x0 + w - corner_radius, y0 + h); // SE -> SW - cairo_line_to(cr, x0 + corner_radius, y0 + h); - cairo_curve_to(cr, x0, y0 + h, x0, y0 + h, x0, y0 + h - corner_radius); + _ctx->line_to(x0 + corner_radius, y0 + h); + _ctx->curve_to(x0, y0 + h, x0, y0 + h, x0, y0 + h - corner_radius); // SW -> NW - cairo_line_to(cr, x0, y0 + corner_radius); - cairo_curve_to(cr, x0, y0, x0, y0, x0 + corner_radius, y0); - cairo_close_path(cr); + _ctx->line_to(x0, y0 + corner_radius); + _ctx->curve_to(x0, y0, x0, y0, x0 + corner_radius, y0); + _ctx->close_path(); - cairo_set_source_rgb(cr, 1, 1, 0.9); - cairo_fill_preserve(cr); + _ctx->set_source_rgb(1, 1, 0.9); + _ctx->fill_preserve(); - cairo_set_line_width(cr, .005); - cairo_set_source_rgb(cr, 0, 0, 0); + _ctx->set_line_width(.005); + _ctx->set_source_rgb(0, 0, 0); - cairo_stroke(cr); - cairo_restore(cr); + _ctx->stroke(); + _ctx->restore(); } void CairoElements::draw_expandable(const Rectangle& area, bool expanded) { - cairo_t*& cr = _ctx; + using namespace Cairo; + const float& x0 = area.x0; const float& y0 = area.y0; const float& w = area.w; const float& h = area.h; - cairo_save(cr); + _ctx->save(); - cairo_set_line_width(cr, .005); - cairo_set_source_rgb(cr, 1, 1, 1); + _ctx->set_line_width(.005); + _ctx->set_source_rgb(1, 1, 1); - cairo_new_path(cr); - cairo_rectangle(cr, x0, y0, w, h); - cairo_set_source_rgb(cr, 1, 1, 1); - cairo_fill_preserve(cr); - cairo_set_source_rgb(cr, 0, 0, 0); - cairo_stroke(cr); + _ctx->begin_new_path(); + _ctx->rectangle(x0, y0, w, h); + _ctx->set_source_rgb(1, 1, 1); + _ctx->fill_preserve(); + _ctx->set_source_rgb(0, 0, 0); + _ctx->stroke(); - cairo_move_to(cr, x0 + w / 10, y0 + h / 2); - cairo_line_to(cr, x0 + w*9 / 10, y0 + h / 2); - cairo_stroke(cr); + _ctx->move_to(x0 + w / 10, y0 + h / 2); + _ctx->line_to(x0 + w*9 / 10, y0 + h / 2); + _ctx->stroke(); - if (!expanded) + if (!expanded) // The "-" becomes a "+" { - cairo_move_to(cr, x0 + w / 2, y0 + h / 10); - cairo_line_to(cr, x0 + w / 2, y0 + h*9 / 10); - cairo_stroke(cr); + _ctx->move_to(x0 + w / 2, y0 + h / 10); + _ctx->line_to(x0 + w / 2, y0 + h*9 / 10); + _ctx->stroke(); } - cairo_restore(cr); + _ctx->restore(); } diff --git a/src/cairo_elements.hh b/src/cairo_elements.hh index e635bdf..a1a77fc 100644 --- a/src/cairo_elements.hh +++ b/src/cairo_elements.hh @@ -21,11 +21,7 @@ #ifndef CAIRO_ELEMENTS_HH #define CAIRO_ELEMENTS_HH 1 - -#include -#include - -#include +#include namespace sgpem { @@ -61,7 +57,7 @@ namespace sgpem class CairoElements { public: - CairoElements(cairo_t* const ctx); + CairoElements(const Cairo::RefPtr& ctx); void draw_3dsphere(const Point& center, float radius, const Color& cl); void draw_3dcube(const Rectangle& area, const Color& cl, const float x_percent, const float y_percent); @@ -69,7 +65,7 @@ namespace sgpem void draw_expandable(const Rectangle& area, bool expanded = false); private: - cairo_t* _ctx; + Cairo::RefPtr _ctx; }; } //~ namespace sgpem diff --git a/src/cairo_widget.cc b/src/cairo_widget.cc index 3fb3fab..034cd86 100644 --- a/src/cairo_widget.cc +++ b/src/cairo_widget.cc @@ -75,11 +75,11 @@ CairoWidget::get_scaling_mode() const void CairoWidget::on_realize() { - if (is_realized()) return; - Gtk::Widget::on_realize(); ensure_style(); + if (!_ref_gdk_window) return; + GdkWindowAttr attributes; memset(&attributes, 0, sizeof(attributes)); @@ -90,30 +90,29 @@ CairoWidget::on_realize() attributes.width = alloc.get_width(); attributes.height = alloc.get_height(); attributes.wclass = GDK_INPUT_OUTPUT; - attributes.event_mask = get_events() | GDK_EXPOSURE_MASK | GDK_ALL_EVENTS_MASK; + attributes.event_mask = get_events() | GDK_EXPOSURE_MASK; attributes.window_type = GDK_WINDOW_CHILD; - attributes.visual = get_visual()->gobj(); - attributes.colormap = get_colormap()->gobj(); _client_w = alloc.get_width(); _client_h = alloc.get_height(); - static const gint attributes_mask = Gdk::WA_X | Gdk::WA_Y | Gdk::WA_WMCLASS - | Gdk::WA_VISUAL | Gdk::WA_COLORMAP; + static const gint attributes_mask = Gdk::WA_X | Gdk::WA_Y; - Glib::RefPtr window = Gdk::Window::create(get_parent_window(), - &attributes, - attributes_mask); + _ref_gdk_window = Gdk::Window::create(get_window(), + &attributes, + attributes_mask); unset_flags(Gtk::NO_WINDOW); - set_window(window); - window->set_user_data(gobj()); + set_window(_ref_gdk_window); + _ref_gdk_window->set_user_data(gobj()); +} - - Glib::RefPtr style = get_style (); - style = style->attach (window); - style->set_background(window, Gtk::STATE_ACTIVE); +void +CairoWidget::on_unrealize() +{ + _ref_gdk_window.clear(); + Gtk::Widget::on_unrealize(); } /* @@ -124,19 +123,17 @@ CairoWidget::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()); + if (!_ref_gdk_window) return; + + get_window()->move_resize(allocation.get_x(), allocation.get_y(), + allocation.get_width(), allocation.get_height()); - // the widget's dimension are saved for futher use - _client_w = allocation.get_width(); - _client_h = allocation.get_height(); - - // the widget must be redrawn - _need_redraw = true; - } + // the widget's dimension are saved for futher use + _client_w = allocation.get_width(); + _client_h = allocation.get_height(); + // the widget must be redrawn + _need_redraw = true; } /* @@ -163,6 +160,8 @@ CairoWidget::on_size_request(Gtk::Requisition* requisition) bool CairoWidget::on_expose_event(GdkEventExpose* event) { + if (!_ref_gdk_window) return true; + if (event == NULL || event->count > 0) return false; @@ -173,14 +172,14 @@ CairoWidget::on_expose_event(GdkEventExpose* event) // the widget must be redrawn if // - there's an explicit request(_need_redraw) // - the size is changed - if(_need_redraw || actual_w!=_client_w || actual_h!=_client_h) + if(_need_redraw || actual_w != _client_w || actual_h != _client_h) { // reset flag, set values with actual size _need_redraw = false; _client_w = actual_w; _client_h = actual_h; - // The pixmap must be crated or no? + // The pixmap must be crated or not? // If the pixmap buffer size isn't enough // it must be allocated or reallocated. // Here is used a lazy technique: @@ -195,7 +194,7 @@ CairoWidget::on_expose_event(GdkEventExpose* event) _pixmap_h = (size_t) (_client_h*1.2); // allocate the pixmap - _buf = Gdk::Pixmap::create(get_window(), _pixmap_w, _pixmap_h); + _buf = Gdk::Pixmap::create(_ref_gdk_window, _pixmap_w, _pixmap_h); } @@ -208,8 +207,8 @@ CairoWidget::on_expose_event(GdkEventExpose* event) NULL, (GtkWidget*)this->gobj(), "through", 0, 0, _client_w, _client_h); - // here the cairo context is creted - cairo_t* ctx = gdk_cairo_create(_buf->gobj()); + // here the cairo context is created + Cairo::RefPtr ctx = _buf->create_cairo_context(); // Determine the final drawing dimensions // before to start drawing @@ -218,13 +217,11 @@ CairoWidget::on_expose_event(GdkEventExpose* event) // calculate and apply scale factors calc_scale_factors(); - cairo_scale(ctx, _scale_x, _scale_y); + ctx->scale(_scale_x, _scale_y); // do the drawing... draw_widget(ctx); - // bye bye context - cairo_destroy(ctx); } // ~ if(_need_redraw || actual_w!=_client_w || actual_h!=_client_h) // Now the in-memory picture is placed on screen @@ -233,7 +230,7 @@ CairoWidget::on_expose_event(GdkEventExpose* event) // Use double buffering or we're CPU-dead // Copy from the buffer to the screen if (_buf) - get_window()->draw_drawable(get_style()->get_black_gc(), _buf, + _ref_gdk_window->draw_drawable(get_style()->get_black_gc(), _buf, event->area.x, event->area.y, event->area.x, event->area.y, event->area.width, event->area.height); @@ -251,7 +248,7 @@ CairoWidget::calc_scale_factors() // // "desired_size" here is how big can fin in window // "effective_size" is how big the application produce - if(_scaling_mode!=scaling_none && _draw_w!=0 && _draw_h!=0) + if(_scaling_mode != scaling_none && _draw_w != 0 && _draw_h != 0) { // there are two possible scale factors x and y _scale_x = (double)_client_w/(double)_draw_w; @@ -265,6 +262,7 @@ CairoWidget::calc_scale_factors() // doesn't scale _scale_x = _scale_y = 1.0; break; + case scaling_to_w: // scale to fit in width // x and y take the same x value @@ -280,7 +278,7 @@ CairoWidget::calc_scale_factors() case scaling_min: // scale to fit always in window // x and y take the same minimum value - if(_scale_x<=_scale_y) + if(_scale_x <= _scale_y) _scale_y = _scale_x; else _scale_x = _scale_y; @@ -289,7 +287,7 @@ CairoWidget::calc_scale_factors() case scaling_max: // scale to fit never in window // x and y take the same mxiimum value - if(_scale_x>=_scale_y) + if(_scale_x >= _scale_y) _scale_y = _scale_x; else _scale_x = _scale_y; @@ -335,14 +333,14 @@ CairoWidget::resize_redraw() if(_buf) { - cairo_t* ctx = gdk_cairo_create(_buf->gobj()); + Cairo::RefPtr ctx = _buf->create_cairo_context(); if(ctx) { // Determine the final drawing dimensions before to start drawing _draw_w = _draw_h = 0; // default no scaling calc_drawing_size(ctx, _draw_w, _draw_h); - cairo_destroy(ctx); + ctx.clear(); calc_scale_factors(); @@ -367,7 +365,7 @@ CairoWidget::resize_redraw() Derived classes can reimplement it or not as desired. */ void -CairoWidget::calc_drawing_size(cairo_t* /* ctx */, size_t& /* width */, size_t& /*height*/) +CairoWidget::calc_drawing_size(Cairo::RefPtr& /* ctx */, size_t& /* width */, size_t& /*height*/) { } diff --git a/src/cairo_widget.hh b/src/cairo_widget.hh index afd01a4..76ffa40 100644 --- a/src/cairo_widget.hh +++ b/src/cairo_widget.hh @@ -21,8 +21,7 @@ #ifndef CAIRO_WIDGET_HH #define CAIRO_WIDGET_HH 1 -#include -#include +#include #include #include @@ -141,7 +140,7 @@ namespace sgpem /** * \brief Widgets size type. */ - typedef unsigned int size_t; + typedef guint size_t; // implementation of fundamental widget's method /** @@ -152,7 +151,8 @@ namespace sgpem * See gtkmm documentation for more informations. */ virtual void on_realize(); - + virtual void on_unrealize(); // doesn't need to be documented. + /** * \brief Implements standard widget's on_size_allocate() mehtod. * @@ -193,7 +193,7 @@ namespace sgpem * draw in the widgets client area. * See cairo documentation for more informations. */ - virtual void draw_widget(cairo_t* ctx) = 0; + virtual void draw_widget(Cairo::RefPtr& ctx) = 0; /** * \brief Method to calculate widget dimensions. @@ -201,7 +201,7 @@ namespace sgpem * The user should implement this method to allow scaling factors calculation. * Is necessary if scaling is needed/used. */ - virtual void calc_drawing_size(cairo_t* ctx, size_t& width, size_t& height); + virtual void calc_drawing_size(Cairo::RefPtr& ctx, size_t& width, size_t& height); // with this method CairoWidget tells the needed widget dimensions /** @@ -232,48 +232,48 @@ namespace sgpem /** * \brief Calculated width of drawing. */ - mutable size_t _draw_w; + size_t _draw_w; /** * \brief Calculated height of drawing. */ - mutable size_t _draw_h; + size_t _draw_h; private: /** * \brief Client area width of widget. */ - mutable size_t _client_w; + size_t _client_w; /** * \brief Client area height of widget. */ - mutable size_t _client_h; + size_t _client_h; /** * \brief Client area width of pixmap. */ - mutable size_t _pixmap_w; + size_t _pixmap_w; /** * \brief Client area width of pixmap. */ - mutable size_t _pixmap_h; + size_t _pixmap_h; /** * \brief Cairo x scale factor. */ - mutable double _scale_x; + double _scale_x; /** * \brief Cairo y scale factor. */ - mutable double _scale_y; + double _scale_y; /** * \brief Flag to signal require redrawing. */ - mutable bool _need_redraw; + bool _need_redraw; /** * \brief Actual scaling mode. @@ -284,6 +284,11 @@ namespace sgpem * \brief Offscreen pixmap used for double-buffering. */ Glib::RefPtr _buf; + + /** + * + */ + Glib::RefPtr _ref_gdk_window; }; } //~ namespace sgpem diff --git a/src/holt_widget.cc b/src/holt_widget.cc index 9c4b4cc..452ab2e 100644 --- a/src/holt_widget.cc +++ b/src/holt_widget.cc @@ -21,20 +21,22 @@ #include "cairo_elements.hh" -#include -#include -#include -#include -#include -#include +#include "sgpemv2/history.hh" +#include "sgpemv2/schedulable.hh" +#include "sgpemv2/process.hh" +#include "sgpemv2/resource.hh" +#include "sgpemv2/simulation.hh" +#include "sgpemv2/string_utils.hh" +#include "sgpemv2/thread.hh" #include "holt_widget.hh" -#include -#include +#include "sgpemv2/templates/deletor.tcc" +#include "sgpemv2/templates/sequences.tcc" -#include +#include +#include #include #ifndef NDEBUG @@ -104,7 +106,7 @@ HoltResource::~HoltResource() { } -void HoltResource::draw(cairo_t *cr) +void HoltResource::draw(Cairo::RefPtr& cr) { static const Color white(1, 1, 1); @@ -114,43 +116,31 @@ void HoltResource::draw(cairo_t *cr) CairoElements ce(cr); // outline - cairo_set_source_rgb (cr, 0, 0, 0); + cr->set_source_rgb (0, 0, 0); // draw rectangle Rectangle area(_pos.real() - _radius, _pos.imag() - _radius, 2*_radius, 2*_radius); ce.draw_3dcube(area, white, x_percent, y_percent); - - cairo_save(cr); + cr->save(); + // clip text outside region - /* - cairo_rectangle(cr, - _pos.real() - _radius, - _pos.imag() - _radius, // _pos.imag() + _radius (1 - 2.0 * y_percent) - 2 * _radius * x_percent, - 2 * _radius * y_percent); - */ - - cairo_rectangle(cr, - _pos.real() - _radius, - _pos.imag() + _radius * (1 - 2.0 * y_percent), - 2 * _radius * x_percent, - 2 * _radius * y_percent); - - cairo_clip(cr); + cr->rectangle(_pos.real() - _radius, + _pos.imag() + _radius * (1 - 2.0 * y_percent), + 2 * _radius * x_percent, + 2 * _radius * y_percent); + cr->clip(); + // draw text - cairo_text_extents_t extents; - cairo_text_extents(cr, _resource->get_name().c_str(), &extents); + Cairo::TextExtents extents; + cr->get_text_extents(_resource->get_name(), extents); double xpos = _pos.real() + _radius * (x_percent-1) - extents.width/2.0; double ypos = _pos.imag() + _radius * (1 - y_percent); // + extents.height/2; - // _pos.imag() + extents.height * ((1 - y_percent) / 2 + 0.5) // left aligned if too large if(xpos<_pos.real() - _radius) xpos = _pos.real() - _radius; - cairo_move_to(cr, - xpos, - ypos ); - cairo_show_text(cr, _resource->get_name().c_str()); + cr->move_to(xpos, ypos ); + cr->show_text(_resource->get_name()); // show used/total places Glib::ustring used; @@ -159,18 +149,16 @@ void HoltResource::draw(cairo_t *cr) to_string((int)_resource->get_places(), total); Glib::ustring msg = used + "/" + total; - cairo_text_extents(cr, msg.c_str(), &extents); + cr->get_text_extents(msg, extents); xpos = _pos.real() + _radius * (x_percent-1) - extents.width/2.0; ypos = _pos.imag() + _radius * (1 - y_percent) + extents.height*2; - cairo_move_to(cr, - xpos, - ypos ); - cairo_show_text(cr, msg.c_str()); + cr->move_to(xpos, ypos); + cr->show_text(msg); // stroke all - cairo_stroke (cr); + cr->stroke(); - cairo_restore(cr); + cr->restore(); } Vec2 HoltResource::get_intersection_to(Vec2 pt) @@ -224,14 +212,13 @@ HoltSchedulable::~HoltSchedulable() { } -void HoltSchedulable::draw(cairo_t *cr) +void HoltSchedulable::draw(Cairo::RefPtr& cr) { static const Color red(1, 0, 0); static const Color yellow(1, 0.8, 0); static const Color green(0, 1, 0); - - cairo_save(cr); // save context state + cr->save(); // save context state const Point center(_pos.real(), _pos.imag()); const Color* color = &red; @@ -259,22 +246,21 @@ void HoltSchedulable::draw(cairo_t *cr) cel.draw_3dsphere(center, _radius, *color); // clip text outside region - cairo_arc(cr, _pos.real(), _pos.imag(), _radius, 0, 2*M_PI); - cairo_clip(cr); + cr->arc(_pos.real(), _pos.imag(), _radius, 0, 2*M_PI); + cr->clip(); // draw text - cairo_text_extents_t extents; - cairo_text_extents(cr, _schedulable->get_name().c_str(), &extents); + Cairo::TextExtents extents; + cr->get_text_extents(_schedulable->get_name(), extents); double text_width = extents.width; - if(text_width>_radius*2.0) - text_width=_radius*2.0; - cairo_move_to(cr, _pos.real() - text_width/2, _pos.imag() + extents.height/2); - cairo_show_text(cr, _schedulable->get_name().c_str()); + if(text_width>_radius*2.0) text_width=_radius*2.0; + cr->move_to(_pos.real() - text_width/2, _pos.imag() + extents.height/2); + cr->show_text(_schedulable->get_name()); // stroke all - cairo_stroke (cr); + cr->stroke(); - cairo_restore(cr); // restore context state + cr->restore(); // restore context state } Vec2 HoltSchedulable::get_intersection_to(Vec2 pt) @@ -310,24 +296,24 @@ HoltRequest::~HoltRequest() { } -void HoltRequest::draw(cairo_t *cr) +void HoltRequest::draw(Cairo::RefPtr& cr) { Vec2 resource = _hp->get_intersection_to(_hr->get_position()); Vec2 schedulable = _hr->get_intersection_to(_hp->get_position()); - cairo_save(cr); + cr->save(); switch(_state) { case Request::state_unallocable: // red - cairo_set_source_rgb(cr, 1, 0, 0); + cr->set_source_rgb(1, 0, 0); arrow(cr, schedulable, resource); break; case Request::state_allocated: // green - cairo_set_source_rgb(cr, 0, 1, 0); + cr->set_source_rgb(0, 1, 0); arrow(cr, resource, schedulable); break; @@ -339,27 +325,27 @@ void HoltRequest::draw(cairo_t *cr) case Request::state_allocable: // yellow - cairo_set_source_rgb(cr, 1, 0.7, 0); + cr->set_source_rgb(1, 0.7, 0); arrow(cr, schedulable, resource); break; } // stroke all and restore status - cairo_stroke (cr); - cairo_restore(cr); + cr->stroke(); + cr->restore(); } -void HoltRequest::arrow(cairo_t *cr, Vec2 first, Vec2 second) +void HoltRequest::arrow(Cairo::RefPtr& cr, Vec2 first, Vec2 second) { // option to draw the line a little translated // this allow to draw two counterflow arrows // without overlap bool traslate = true; - double line_width = cairo_get_line_width(cr); + double line_width = cr->get_line_width(); if(traslate) { // if needed calc parallel versor of arrow - Vec2 direction = second-first; + Vec2 direction = second - first; direction /= std::abs(direction); // set unary modulus // and rotate it 90 degrees @@ -373,12 +359,12 @@ void HoltRequest::arrow(cairo_t *cr, Vec2 first, Vec2 second) } // draw main line - cairo_move_to(cr, second.real(), second.imag()); - cairo_line_to(cr, first.real(), first.imag()); + cr->move_to(second.real(), second.imag()); + cr->line_to(first.real(), first.imag()); // some calculation to draw arrowpoint... // take a short line parallel to main line - Vec2 arrowside = second-first; + Vec2 arrowside = second - first; arrowside *= 5.0*line_width/std::abs(arrowside); // make a rotation component Vec2 deviation(5.0, 1.0); deviation /= std::abs(deviation); @@ -386,11 +372,11 @@ void HoltRequest::arrow(cairo_t *cr, Vec2 first, Vec2 second) Vec2 side1 = arrowside * deviation; Vec2 side2 = arrowside * conj(deviation); // draw one side - cairo_move_to(cr, first.real(), first.imag()); - cairo_line_to(cr, first.real()+side1.real(), first.imag()+side1.imag()); + cr->move_to(first.real(), first.imag()); + cr->line_to(first.real()+side1.real(), first.imag()+side1.imag()); // draw the other side - cairo_move_to(cr, first.real(), first.imag()); - cairo_line_to(cr, first.real()+side2.real(), first.imag()+side2.imag()); + cr->move_to(first.real(), first.imag()); + cr->line_to(first.real()+side2.real(), first.imag()+side2.imag()); } @@ -806,7 +792,7 @@ HoltWidget::acquire() void -HoltWidget::draw_widget(cairo_t* ctx) +HoltWidget::draw_widget(Cairo::RefPtr& ctx) { #ifndef NDEBUG std::cout << "HoltWidget::draw_widget" << endl; @@ -819,18 +805,16 @@ HoltWidget::draw_widget(cairo_t* ctx) if(_draw_w>0) { const History& hist = _simulation->get_history(); - const unsigned int hist_front = hist.get_front() == 0 ? 0 : hist.get_front() - 1; - cairo_text_extents_t extents; + const unsigned int hist_front = hist.get_front() == 0 ? 0 : hist.get_front() - 1; + Cairo::TextExtents extents; stringstream ss; ss << "T = " << hist_front; - cairo_text_extents(ctx, ss.str().c_str(), &extents); - cairo_move_to(ctx, _draw_w/2 - extents.width/2.0, extents.height*2.0); - cairo_show_text(ctx, ss.str().c_str()); - cairo_stroke(ctx); + ctx->get_text_extents(ss.str(), extents); + ctx->move_to(_draw_w/2 - extents.width/2.0, extents.height*2.0); + ctx->show_text(ss.str()); + ctx->stroke(); } - - // draw all resources typedef HoltResources::const_iterator holt_res_iterator; holt_res_iterator riter = _holt_resources.begin(); @@ -865,7 +849,7 @@ HoltWidget::draw_widget(cairo_t* ctx) void -HoltWidget::calc_drawing_size(cairo_t* ctx, size_t& width, size_t& height) +HoltWidget::calc_drawing_size(Cairo::RefPtr& ctx, size_t& width, size_t& height) { #ifndef NDEBUG cout << "Holt widget BEFORE calc_drawing_size width=" << width << " height=" << height << endl; @@ -881,10 +865,10 @@ HoltWidget::calc_drawing_size(cairo_t* ctx, size_t& width, size_t& height) int max = _n_proc; if(_n_res>_n_proc) max = _n_res; - cairo_text_extents_t extents; + Cairo::TextExtents extents; static const Glib::ustring val("Process 999 Resource 999"); - cairo_text_extents(ctx, val.c_str(), &extents); + ctx->get_text_extents(val, extents); _radius = extents.width/4.0; switch(_arrange_mode) diff --git a/src/holt_widget.hh b/src/holt_widget.hh index 36b1d94..67d9ccc 100644 --- a/src/holt_widget.hh +++ b/src/holt_widget.hh @@ -89,7 +89,7 @@ namespace sgpem * * \param cr The cairo context to draw to. */ - virtual void draw(cairo_t *cr) = 0; + virtual void draw(Cairo::RefPtr& cr) = 0; /** * \brief Setter and getter method for position parameter. @@ -195,7 +195,7 @@ namespace sgpem * * \param cr Cairo context to draw to. */ - virtual void draw(cairo_t *cr); + virtual void draw(Cairo::RefPtr& cr); /** * \brief Computes point of intersection with edge. @@ -278,7 +278,7 @@ namespace sgpem * * \param cr Cairo context to draw to. */ - virtual void draw(cairo_t *cr); + virtual void draw(Cairo::RefPtr& cr); /** * \brief Computes point of intersection with edge. @@ -336,7 +336,7 @@ namespace sgpem * * \param cr Cairo context to draw to. */ - virtual void draw(cairo_t *cr); + virtual void draw(Cairo::RefPtr& cr); private: /** @@ -346,7 +346,7 @@ namespace sgpem * \param first Starting point. * \param first Ending point. */ - virtual void arrow(cairo_t *cr, Vec2 first, Vec2 second); + virtual void arrow(Cairo::RefPtr& cr, Vec2 first, Vec2 second); /** * \brief Pointer to the referring schedulable. @@ -490,7 +490,7 @@ namespace sgpem * \param ctx the cairo context to draw to * \see CairoWidget for more. */ - void draw_widget(cairo_t* ctx); + void draw_widget(Cairo::RefPtr& ctx); /** @@ -500,7 +500,7 @@ namespace sgpem * \param width the return parameter for desired width * \param height the return parameter for desired height */ - virtual void calc_drawing_size(cairo_t* ctx, size_t& width, size_t& height); + virtual void calc_drawing_size(Cairo::RefPtr& ctx, size_t& width, size_t& height); // virtual void calc_widget_size(size_t& width, size_t& height); diff --git a/src/simulation_widget.cc b/src/simulation_widget.cc index eefd3fb..cb3136d 100644 --- a/src/simulation_widget.cc +++ b/src/simulation_widget.cc @@ -22,15 +22,19 @@ #include "simulation_widget.hh" #include "cairo_elements.hh" +#include "sgpemv2/history.hh" +#include "sgpemv2/process.hh" +#include "sgpemv2/thread.hh" +#include "sgpemv2/simulation.hh" +#include "sgpemv2/string_utils.hh" + #include #include #include #include #include -#include -#include -#include +#include #include @@ -42,7 +46,6 @@ using namespace sgpem; using namespace Gtk; using namespace Glib; - SimulationWidget::SimulationWidget(Simulation& simulation) : Glib::ObjectBase("sgpem_SimulationWidget"), SimulationObserver(), @@ -51,7 +54,7 @@ SimulationWidget::SimulationWidget(Simulation& simulation) _simulation(&simulation), _x_unit(10), _y_unit(10), _n_proc(0), _n_thr(0) -{ +{ // Register this SimulationObserver: _simulation->attach(*this); @@ -60,35 +63,29 @@ SimulationWidget::SimulationWidget(Simulation& simulation) // count_elements(); - // define top margin in y units - _yu_top_margin = 1.0; + // define top margin in y units + _yu_top_margin = 1.0; - // define left margin in x units - _xu_left_margin = 1.0; + // define left margin in x units + _xu_left_margin = 1.0; - // define graph left margin in x units - _xu_left_graph_margin = 11.0; + // define graph left margin in x units + _xu_left_graph_margin = 11.0; - // define process bar spacing in y units - _yu_process_bar_spacing = 1.0; + // define process bar spacing in y units + _yu_process_bar_spacing = 1.0; - // define process bar height in y units - _yu_process_bar_height = 2.0; + // define process bar height in y units + _yu_process_bar_height = 2.0; - // define thread bar spacing in y units - _yu_thread_bar_spacing = 0.5; + // define thread bar spacing in y units + _yu_thread_bar_spacing = 0.5; - // define thread bar height in y units - _yu_thread_bar_height = 1.0; + // define thread bar height in y units + _yu_thread_bar_height = 1.0; - - // - _ready_process_gradient = 0; - _running_process_gradient = 0; - _blocked_process_gradient = 0; - - _partial_redraw = false; - _last_drawn = 0; + _partial_redraw = false; + _last_drawn = 0; } @@ -101,9 +98,20 @@ SimulationWidget::~SimulationWidget() _simulation->detach(*this); } +void +SimulationWidget::on_realize() +{ + CairoWidget::on_realize(); + + // Register for receiving click events: + RefPtr gdk_win = get_window(); + gdk_win->set_events(gdk_win->get_events() | Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_RELEASE_MASK); +} + void SimulationWidget::update(const Simulation& /* changed_simulation */ ) { + // FIXME: DEPRECATED. Does nothing. } void @@ -132,12 +140,12 @@ SimulationWidget::set_show_threads(bool show) void -SimulationWidget::draw_widget(cairo_t* ctx) +SimulationWidget::draw_widget(Cairo::RefPtr& ctx) { if(_n_proc<1) // nothing to draw { - cairo_move_to(ctx, 2.0*_x_unit, 2.0*_y_unit); - cairo_show_text(ctx, _("Nothing to see here... add some processes! Right-click on the Schedulables view in this window.")); + ctx->move_to(2.0*_x_unit, 2.0*_y_unit); + ctx->show_text(_("Nothing to see here... add some processes! Right-click on the Schedulables view in this window.")); return; } @@ -148,12 +156,12 @@ SimulationWidget::draw_widget(cairo_t* ctx) void -SimulationWidget::draw_names(cairo_t* ctx) +SimulationWidget::draw_names(Cairo::RefPtr& ctx) { // show processes (and thread) names... // useful constants - const History& hist = _simulation->get_history(); + const History& hist = _simulation->get_history(); const double top_margin = _yu_top_margin * _y_unit; const double left_margin = _x_unit; const double left_graph_margin = _xu_left_graph_margin * _x_unit; @@ -165,11 +173,11 @@ SimulationWidget::draw_names(cairo_t* ctx) // set a rectangular clip region to cut long names // - set the rectangle - cairo_rectangle(ctx, 0, top_margin, + ctx->rectangle(0, top_margin, left_graph_margin - left_margin, _n_proc*process_height + _n_thr*thread_height); // - set the clip region - cairo_clip(ctx); + ctx->clip(); // text start position: margin + half of text height double ypos = top_margin + _y_unit / 2.0; @@ -184,9 +192,9 @@ SimulationWidget::draw_names(cairo_t* ctx) // move to bar center adding a white row before ypos += process_bar_spacing + process_bar_height/2.0; - cairo_move_to(ctx, left_margin, ypos); + ctx->move_to(left_margin, ypos); // show process name - cairo_show_text(ctx,p->get_name().c_str()); + ctx->show_text(p->get_name()); // calc position to next row skipping height of process bar ypos += process_bar_height/2.0; @@ -202,9 +210,9 @@ SimulationWidget::draw_names(cairo_t* ctx) thr_iter++; // move to bar center adding white space as needed ypos += thread_height/2.0; - cairo_move_to(ctx, left_margin+_x_unit, ypos); + ctx->move_to(left_margin+_x_unit, ypos); // show thread name - cairo_show_text(ctx,t->get_name().c_str()); + ctx->show_text(t->get_name()); // calc position to next thread bar begin ypos += thread_height/2.0; // height of thread bar @@ -216,11 +224,11 @@ SimulationWidget::draw_names(cairo_t* ctx) } // ~ while(proc_iter!=processes.end()) // remove clip region - cairo_reset_clip(ctx); + ctx->reset_clip(); } void -SimulationWidget::draw_grid(cairo_t* ctx) +SimulationWidget::draw_grid(Cairo::RefPtr& ctx) { const History& hist = _simulation->get_history(); @@ -243,8 +251,8 @@ SimulationWidget::draw_grid(cairo_t* ctx) Process* p = (*proc_iter); proc_iter++; // draw one HOR line per process - cairo_move_to(ctx, left_graph_margin, ypos); - cairo_rel_line_to(ctx, graph_width, 0); + ctx->move_to(left_graph_margin, ypos); + ctx->rel_line_to(graph_width, 0); // calc next line position ypos += process_height; // skip a process heigh @@ -257,69 +265,69 @@ SimulationWidget::draw_grid(cairo_t* ctx) } // ~ while(proc_iter!=processes.end()) // draw last HOR line - cairo_move_to(ctx, left_graph_margin, ypos); - cairo_rel_line_to(ctx, graph_width, 0); + ctx->move_to(left_graph_margin, ypos); + ctx->rel_line_to(graph_width, 0); // - draw left VER line - cairo_move_to(ctx, left_graph_margin, top_margin); - cairo_rel_line_to(ctx, 0, graph_height); + ctx->move_to(left_graph_margin, top_margin); + ctx->rel_line_to(0, graph_height); // right close the graph only if simulation stopped if(_simulation->get_state()==Simulation::state_stopped) { // - draw right VER line - cairo_move_to(ctx, left_graph_margin + graph_width, top_margin); - cairo_rel_line_to(ctx, 0, graph_height); + ctx->move_to(left_graph_margin + graph_width, top_margin); + ctx->rel_line_to(0, graph_height); } // trace lines on output context - cairo_stroke(ctx); + ctx->stroke(); // Draw a grey vertical line every fifth step - cairo_save(ctx); - cairo_set_line_width(ctx, 0.125 * cairo_get_line_width(ctx)); - cairo_set_source_rgb(ctx, 0.3, 0.3, 0.3); + ctx->save(); + ctx->set_line_width(0.125 * ctx->get_line_width()); + ctx->set_source_rgb(0.3, 0.3, 0.3); for(double step = _x_unit; step < graph_width - _x_unit; step += 5 * _x_unit) { - cairo_new_path(ctx); - cairo_move_to(ctx, left_graph_margin + step, top_margin); - cairo_rel_line_to(ctx, 0, graph_height); - cairo_stroke(ctx); + ctx->begin_new_path(); + ctx->move_to(left_graph_margin + step, top_margin); + ctx->rel_line_to(0, graph_height); + ctx->stroke(); } - cairo_restore(ctx); + ctx->restore(); // draw and write time line - cairo_save(ctx); - cairo_set_source_rgb(ctx, 0, 0, 0); - cairo_set_line_width(ctx, 0.25*cairo_get_line_width(ctx)); + ctx->save(); + ctx->set_source_rgb(0, 0, 0); + ctx->set_line_width(0.25*ctx->get_line_width()); // "T" label - cairo_move_to(ctx, left_graph_margin, + ctx->move_to(left_graph_margin, top_margin + graph_height + 2.0 * _y_unit); - cairo_show_text(ctx,"T"); + ctx->show_text("T"); // ruler drawing cycle for(unsigned int t=0; t<=hist_front; t++) { // tick - cairo_move_to(ctx, left_graph_margin + (t+1)*_x_unit, + ctx->move_to(left_graph_margin + (t+1)*_x_unit, top_margin + graph_height); - cairo_rel_line_to(ctx, 0, 0.5 * _y_unit); + ctx->rel_line_to(0, 0.5 * _y_unit); // value Glib::ustring val; to_string(t, val); - cairo_move_to(ctx, left_graph_margin + (t+1)*_x_unit, + ctx->move_to(left_graph_margin + (t+1)*_x_unit, top_margin + graph_height + 2.0 * _y_unit); - cairo_show_text(ctx,val.c_str()); + ctx->show_text(val); } // ~ for(int t=0; t<=pos; t++) - cairo_stroke(ctx); - cairo_restore(ctx); + ctx->stroke(); + ctx->restore(); } void -SimulationWidget::draw_bars(cairo_t* ctx) +SimulationWidget::draw_bars(Cairo::RefPtr& ctx) { // useful constants const History& hist = _simulation->get_history(); @@ -408,53 +416,50 @@ SimulationWidget::draw_bars(cairo_t* ctx) // draw single rectangle using gradients void -SimulationWidget::draw_instant_rect(cairo_t* ctx, double x, double y, +SimulationWidget::draw_instant_rect(Cairo::RefPtr& ctx, double x, double y, double w, double h, Schedulable::state state) { - cairo_matrix_t matrix; + using namespace Cairo; switch(state) { case Schedulable::state_running: - cairo_save(ctx); - cairo_set_source(ctx, _running_process_gradient); + ctx->save(); + ctx->set_source(_running_process_gradient); // translate the gradient at desired position - cairo_matrix_init_translate(&matrix, 0, -y); - cairo_pattern_set_matrix (_running_process_gradient, &matrix); + _running_process_gradient->set_matrix(translation_matrix(0, -y)); // put the filled rectangle - cairo_rectangle(ctx, x, y, w, h); - cairo_fill(ctx); - cairo_restore(ctx); + ctx->rectangle(x, y, w, h); + ctx->fill(); + ctx->restore(); break; case Schedulable::state_ready: - cairo_save(ctx); - cairo_set_source(ctx, _ready_process_gradient); + ctx->save(); + ctx->set_source(_ready_process_gradient); // translate the gradient at desired position - cairo_matrix_init_translate(&matrix, 0, -y); - cairo_pattern_set_matrix (_ready_process_gradient, &matrix); + _ready_process_gradient->set_matrix(translation_matrix(0, -y)); // put the filled rectangle - cairo_rectangle(ctx, x, y, w, h); - cairo_fill(ctx); - cairo_restore(ctx); + ctx->rectangle(x, y, w, h); + ctx->fill(); + ctx->restore(); break; case Schedulable::state_blocked: - cairo_save(ctx); - cairo_set_source(ctx, _blocked_process_gradient); + ctx->save(); + ctx->set_source(_blocked_process_gradient); // translate the gradient at desired position - cairo_matrix_init_translate(&matrix, 0, -y); - cairo_pattern_set_matrix (_blocked_process_gradient, &matrix); + _blocked_process_gradient->set_matrix(translation_matrix(0, -y)); // put the filled rectangle - cairo_rectangle(ctx, x, y, w, h); - cairo_fill(ctx); - cairo_restore(ctx); + ctx->rectangle(x, y, w, h); + ctx->fill(); + ctx->restore(); break; case Schedulable::state_future: @@ -469,7 +474,7 @@ SimulationWidget::draw_instant_rect(cairo_t* ctx, double x, double y, void -SimulationWidget::calc_drawing_size(cairo_t* ctx, size_t& width, size_t& height) +SimulationWidget::calc_drawing_size(Cairo::RefPtr& ctx, size_t& width, size_t& height) { if(!_simulation) return; @@ -480,13 +485,13 @@ SimulationWidget::calc_drawing_size(cairo_t* ctx, size_t& width, size_t& height) int pos = _simulation->get_history().get_front(); // units are defined in terms of text dimensions - cairo_text_extents_t extents; + Cairo::TextExtents extents; Glib::ustring val("999"); - cairo_text_extents(ctx, val.c_str(), &extents); - if(_x_unitget_text_extents(val, extents); + if(_x_unit < extents.width) + _x_unit = extents.width; + if(_y_unit < extents.height) + _y_unit = extents.height; // left margin, labels, graph width = (size_t)((_xu_left_graph_margin + 3.0 + pos) * _x_unit); @@ -509,7 +514,7 @@ SimulationWidget::count_elements() { _n_proc = _n_thr = 0; - const History& hist = _simulation->get_history(); + const History& hist = _simulation->get_history(); const Environment& env = hist.get_last_environment(); // count processes @@ -533,24 +538,25 @@ SimulationWidget::make_gradients() { // linear gradients are referred to 0, 0 // must be translated if used elsewhere + using Cairo::LinearGradient; - _ready_process_gradient = cairo_pattern_create_linear(0, 0, 0, _yu_process_bar_height * _y_unit); + _ready_process_gradient = LinearGradient::create(0, 0, 0, _yu_process_bar_height * _y_unit); // yellow - cairo_pattern_add_color_stop_rgb(_ready_process_gradient, 0.0, 1.00, 0.7, 0.0); - cairo_pattern_add_color_stop_rgb(_ready_process_gradient, 0.3, 1.00, 0.9, 0.0); - cairo_pattern_add_color_stop_rgb(_ready_process_gradient, 1.0, 1.00, 0.7, 0.0); + _ready_process_gradient->add_color_stop_rgb(0.0, 1.00, 0.7, 0.0); + _ready_process_gradient->add_color_stop_rgb(0.3, 1.00, 0.9, 0.0); + _ready_process_gradient->add_color_stop_rgb(1.0, 1.00, 0.7, 0.0); - _running_process_gradient = cairo_pattern_create_linear(0, 0, 0, _yu_process_bar_height * _y_unit); + _running_process_gradient = LinearGradient::create(0, 0, 0, _yu_process_bar_height * _y_unit); // green - cairo_pattern_add_color_stop_rgb(_running_process_gradient, 0.0, 0.0, 0.8, 0.0); - cairo_pattern_add_color_stop_rgb(_running_process_gradient, 0.3, 0.0, 1.0, 0.0); - cairo_pattern_add_color_stop_rgb(_running_process_gradient, 1.0, 0.0, 0.65, 0.0); + _running_process_gradient->add_color_stop_rgb(0.0, 0.0, 0.8, 0.0); + _running_process_gradient->add_color_stop_rgb(0.3, 0.0, 1.0, 0.0); + _running_process_gradient->add_color_stop_rgb(1.0, 0.0, 0.65, 0.0); - _blocked_process_gradient = cairo_pattern_create_linear(0, 0, 0, _yu_process_bar_height * _y_unit); + _blocked_process_gradient = LinearGradient::create(0, 0, 0, _yu_process_bar_height * _y_unit); // red - cairo_pattern_add_color_stop_rgb(_blocked_process_gradient, 0.0, 0.85, 0.0, 0.0); - cairo_pattern_add_color_stop_rgb(_blocked_process_gradient, 0.3, 1.0, 0.5, 0.5); - cairo_pattern_add_color_stop_rgb(_blocked_process_gradient, 1.0, 0.65, 0.0, 0.0); + _blocked_process_gradient->add_color_stop_rgb(0.0, 0.85, 0.0, 0.0); + _blocked_process_gradient->add_color_stop_rgb(0.3, 1.0, 0.5, 0.5); + _blocked_process_gradient->add_color_stop_rgb(1.0, 0.65, 0.0, 0.0); } @@ -656,3 +662,5 @@ SimulationWidget::_on_stretch_scaling() resize_redraw(); // set_size_request (20, 20); // force container redimensioning } + + diff --git a/src/simulation_widget.hh b/src/simulation_widget.hh index 6580ec6..e9ab3b0 100644 --- a/src/simulation_widget.hh +++ b/src/simulation_widget.hh @@ -21,12 +21,13 @@ #ifndef SIMULATION_WIDGET_HH #define SIMULATION_WIDGET_HH 1 - - #include "cairo_widget.hh" -#include -#include -#include + +#include "sgpemv2/history_observer.hh" +#include "sgpemv2/schedulable.hh" +#include "sgpemv2/simulation_observer.hh" + +#include namespace sgpem { @@ -48,7 +49,7 @@ namespace sgpem * * At the bottom of the graph there is a time line ruler. * - * This class implemets a SimulationObserver and HistoryObserver + * This class implements a SimulationObserver and HistoryObserver * to have an update signal (and related update) every simulation step. * * \deprecated The class should implement only HistoryObserver @@ -57,7 +58,7 @@ namespace sgpem * \see HistoryObserver */ class SimulationWidget - : public SimulationObserver, public HistoryObserver, public CairoWidget + : public SimulationObserver, public HistoryObserver, public CairoWidget { public: /** @@ -77,7 +78,7 @@ namespace sgpem /** * \brief SimulationObserver's update method redefinition. * - * Actually is a dummy method. + * \deprecated Actually is a dummy method. * * \param changed_simulation the observed Simulation */ @@ -127,7 +128,7 @@ namespace sgpem * \param ctx the cairo context to draw to * \see CairoWidget for more. */ - void draw_widget(cairo_t* ctx); + void draw_widget(Cairo::RefPtr& ctx); /** * \brief calculated the needed drawing surface dimensions. @@ -136,8 +137,12 @@ namespace sgpem * \param width the return parameter for desired width * \param height the return parameter for desired height */ - virtual void calc_drawing_size(cairo_t* ctx, size_t& width, size_t& height); + virtual void calc_drawing_size(Cairo::RefPtr& ctx, size_t& width, size_t& height); + /** + * \brief Adds the click events to the underlying Gdk::Window + */ + virtual void on_realize(); private: @@ -152,21 +157,21 @@ namespace sgpem * * \param ctx the cairo context to draw to */ - void draw_names(cairo_t* ctx); + void draw_names(Cairo::RefPtr& ctx); /** * \brief Used internally by draw_widget to show the bars container grid. * * \param ctx the cairo context to draw to */ - void draw_grid(cairo_t* ctx); + void draw_grid(Cairo::RefPtr& ctx); /** * \brief Used internally by draw_widget to show processes/threads bars. * * \param ctx the cairo context to draw to */ - void draw_bars(cairo_t* ctx); + void draw_bars(Cairo::RefPtr& ctx); /** * \brief Used internally by draw_widget to build the bars. @@ -178,7 +183,7 @@ namespace sgpem * \param h height of rectangle * \param state select the color to apply */ - void draw_instant_rect(cairo_t* ctx, double x, double y, + void draw_instant_rect(Cairo::RefPtr& ctx, double x, double y, double w, double h, sgpem::Schedulable::state state); /** @@ -284,17 +289,17 @@ namespace sgpem /** * \brief Gradient used to draw ready processes/threads. */ - cairo_pattern_t* _ready_process_gradient; + Cairo::RefPtr _ready_process_gradient; /** * \brief Gradient used to draw running processes/threads. */ - cairo_pattern_t* _running_process_gradient; + Cairo::RefPtr _running_process_gradient; /** * \brief Gradient used to draw blocked processes/threads. */ - cairo_pattern_t* _blocked_process_gradient; + Cairo::RefPtr _blocked_process_gradient; /** * Used to redraw partially the widget. diff --git a/src/testsuite/test-cairo_widget.cc b/src/testsuite/test-cairo_widget.cc index e73a7c0..363c224 100644 --- a/src/testsuite/test-cairo_widget.cc +++ b/src/testsuite/test-cairo_widget.cc @@ -56,10 +56,10 @@ namespace sgpem protected: virtual bool on_button_press_event(GdkEventButton* event); - void draw_widget(cairo_t* ctx); + void draw_widget(Cairo::RefPtr& ctx); void change_scaling_mode(); - virtual void calc_drawing_size(cairo_t* ctx, size_t& width, size_t& height); + virtual void calc_drawing_size(Cairo::RefPtr& ctx, size_t& width, size_t& height); private: int _desired_w; int _desired_h; @@ -70,7 +70,7 @@ namespace sgpem using namespace sgpem; TestWidget::TestWidget() - : Glib::ObjectBase("sgpem_TestWidget"), CairoWidget(), + : Glib::ObjectBase("sgpem_TestWidget"), CairoWidget(), _desired_w(200), _desired_h(300) { } @@ -90,13 +90,13 @@ TestWidget::on_button_press_event(GdkEventButton*) } void -TestWidget::draw_widget(cairo_t* ctx) +TestWidget::draw_widget(Cairo::RefPtr& ctx) { // show line - cairo_set_source_rgb(ctx, 0, 0, 0); - cairo_move_to(ctx, 0, 0); - cairo_line_to(ctx, _desired_w, _desired_w); - cairo_stroke(ctx); + ctx->set_source_rgb(0, 0, 0); + ctx->move_to(0, 0); + ctx->line_to(_desired_w, _desired_w); + ctx->stroke(); // NOTE: just to try CairoElements ce(ctx); @@ -138,20 +138,16 @@ TestWidget::draw_widget(cairo_t* ctx) msg = "scaling_all = scale to stretch into client area"; break; } - cairo_move_to(ctx, 10, 10); - cairo_show_text(ctx,msg.c_str()); + ctx->move_to(10, 10); + ctx->show_text(msg); msg = "clic to change mode..."; - cairo_move_to(ctx, 10, 30); - cairo_show_text(ctx,msg.c_str()); - - - - + ctx->move_to(10, 30); + ctx->show_text(msg); } void -TestWidget::calc_drawing_size(cairo_t*, size_t& width, size_t& height) +TestWidget::calc_drawing_size(Cairo::RefPtr&, size_t& width, size_t& height) { width = _desired_w; height = _desired_h;