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
This commit is contained in:
tchernobog 2009-12-30 23:36:01 +00:00
parent 1220e1be16
commit bce427d022
12 changed files with 419 additions and 421 deletions

View File

@ -352,7 +352,7 @@ sgpemv2_CPPFLAGS = \
-DLOCALEDIR="\"$(localedir)\"" \ -DLOCALEDIR="\"$(localedir)\"" \
-DSHAREDIR="\"$(sharedir)\"" \ -DSHAREDIR="\"$(sharedir)\"" \
-DUIDIR="\"$(uidir)\"" \ -DUIDIR="\"$(uidir)\"" \
$(CAIRO_CFLAGS) \ $(CAIROMM_CFLAGS) \
$(GTKMM_CFLAGS) \ $(GTKMM_CFLAGS) \
$(LIBGLADEMM_CFLAGS) \ $(LIBGLADEMM_CFLAGS) \
$(GTHREAD_CFLAGS) $(GTHREAD_CFLAGS)
@ -362,7 +362,7 @@ sgpemv2_LDFLAGS = \
-Wl,-rpath -Wl,"$(pkglibdir)" -Wl,-rpath -Wl,"$(pkglibdir)"
sgpemv2_LDADD = \ sgpemv2_LDADD = \
src/backend/libbackend.la \ src/backend/libbackend.la \
$(CAIRO_LIBS) \ $(CAIROMM_LIBS) \
$(GTKMM_LIBS) \ $(GTKMM_LIBS) \
$(GTHREAD_LIBS) $(GTHREAD_LIBS)
@ -530,11 +530,11 @@ src_testsuite_test_key_file_SOURCES = \
src_testsuite_test_cairo_widget_CPPFLAGS = \ src_testsuite_test_cairo_widget_CPPFLAGS = \
-I@top_srcdir@/src \ -I@top_srcdir@/src \
-I@top_srcdir@/src/backend \ -I@top_srcdir@/src/backend \
$(CAIRO_CFLAGS) \ $(CAIROMM_CFLAGS) \
$(GTKMM_CFLAGS) \ $(GTKMM_CFLAGS) \
$(GLIBMM_CFLAGS) $(GLIBMM_CFLAGS)
src_testsuite_test_cairo_widget_LDFLAGS = \ src_testsuite_test_cairo_widget_LDFLAGS = \
$(CAIRO_LIBS) \ $(CAIROMM_LIBS) \
$(GTKMM_LIBS) \ $(GTKMM_LIBS) \
$(GLIBMM_LIBS) $(GLIBMM_LIBS)
src_testsuite_test_cairo_widget_SOURCES = \ src_testsuite_test_cairo_widget_SOURCES = \
@ -545,14 +545,14 @@ src_testsuite_test_cairo_widget_SOURCES = \
src_testsuite_test_simulation_widget_CPPFLAGS = \ src_testsuite_test_simulation_widget_CPPFLAGS = \
-I@top_srcdir@/src \ -I@top_srcdir@/src \
-I@top_srcdir@/src/backend \ -I@top_srcdir@/src/backend \
$(CAIRO_CFLAGS) \ $(CAIROMM_CFLAGS) \
$(GTKMM_CFLAGS) \ $(GTKMM_CFLAGS) \
$(GLIBMM_CFLAGS) \ $(GLIBMM_CFLAGS) \
$(GTHREAD_CFLAGS) $(GTHREAD_CFLAGS)
src_testsuite_test_simulation_widget_LDFLAGS = \ src_testsuite_test_simulation_widget_LDFLAGS = \
src/backend/libbackend.la \ src/backend/libbackend.la \
-Wl,-rpath -Wl,"$(pkglibdir)" \ -Wl,-rpath -Wl,"$(pkglibdir)" \
$(CAIRO_LIBS) \ $(CAIROMM_LIBS) \
$(GTKMM_LIBS) \ $(GTKMM_LIBS) \
$(GLIBMM_LIBS) \ $(GLIBMM_LIBS) \
$(GTHREAD_LIBS) $(GTHREAD_LIBS)
@ -565,14 +565,14 @@ src_testsuite_test_simulation_widget_SOURCES = \
src_testsuite_test_holt_widget_CPPFLAGS = \ src_testsuite_test_holt_widget_CPPFLAGS = \
-I@top_srcdir@/src \ -I@top_srcdir@/src \
-I@top_srcdir@/src/backend \ -I@top_srcdir@/src/backend \
$(CAIRO_CFLAGS) \ $(CAIROMM_CFLAGS) \
$(GTKMM_CFLAGS) \ $(GTKMM_CFLAGS) \
$(GLIBMM_CFLAGS) \ $(GLIBMM_CFLAGS) \
$(GTHREAD_CFLAGS) $(GTHREAD_CFLAGS)
src_testsuite_test_holt_widget_LDFLAGS = \ src_testsuite_test_holt_widget_LDFLAGS = \
src/backend/libbackend.la \ src/backend/libbackend.la \
-Wl,-rpath -Wl,"$(pkglibdir)" \ -Wl,-rpath -Wl,"$(pkglibdir)" \
$(CAIRO_LIBS) \ $(CAIROMM_LIBS) \
$(GTKMM_LIBS) \ $(GTKMM_LIBS) \
$(GLIBMM_LIBS) \ $(GLIBMM_LIBS) \
$(GTHREAD_LIBS) $(GTHREAD_LIBS)

4
TODO Normal file
View File

@ -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

View File

@ -57,9 +57,10 @@ AM_GNU_GETTEXT([external])
AM_GNU_GETTEXT_VERSION([0.17]) AM_GNU_GETTEXT_VERSION([0.17])
dnl various requisites dnl various requisites
SIGCPP_VERSION=2.0.10 SIGCPP_VERSION=2.0.18
GTKMM_VERSION=2.12.1 GLIBMM_VERSION=2.22.0
CAIRO_VERSION=1.0.0 GTKMM_VERSION=2.18.0
CAIROMM_VERSION=1.8.0
dnl c++ compiler and flags dnl c++ compiler and flags
AC_PROG_CXX 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]) AC_MSG_ERROR([You may need to update your pkg-config installation])
fi fi
PKG_CHECK_MODULES([CAIRO], PKG_CHECK_MODULES([CAIROMM],
[cairo >= $CAIRO_VERSION], [cairomm-1.0 >= $CAIROMM_VERSION],
:, AC_MSG_ERROR([$CAIRO_PKG_ERRORS])) :, AC_MSG_ERROR([$CAIROMM_PKG_ERRORS]))
PKG_CHECK_MODULES([GTHREAD], PKG_CHECK_MODULES([GTHREAD],
[gthread-2.0 >= $GTKMM_VERSION], [gthread-2.0 >= $GTKMM_VERSION],
:, AC_MSG_ERROR([$GTHREAD_PKG_ERRORS])) :, AC_MSG_ERROR([$GTHREAD_PKG_ERRORS]))
@ -119,7 +120,7 @@ PKG_CHECK_MODULES([SIGCPP],
[sigc++-2.0 >= $SIGCPP_VERSION], [sigc++-2.0 >= $SIGCPP_VERSION],
:, AC_MSG_ERROR([$SIGCPP_PKG_ERRORS])) :, AC_MSG_ERROR([$SIGCPP_PKG_ERRORS]))
PKG_CHECK_MODULES([GLIBMM], PKG_CHECK_MODULES([GLIBMM],
[glibmm-2.4 >= $GTKMM_VERSION], [glibmm-2.4 >= $GLIBMM_VERSION],
:, AC_MSG_ERROR([$GLIBMM_PKG_ERRORS])) :, AC_MSG_ERROR([$GLIBMM_PKG_ERRORS]))
PKG_CHECK_MODULES([GTKMM], PKG_CHECK_MODULES([GTKMM],
[gtkmm-2.4 >= $GTKMM_VERSION], [gtkmm-2.4 >= $GTKMM_VERSION],

View File

@ -29,7 +29,7 @@
using namespace sgpem; using namespace sgpem;
CairoElements::CairoElements(cairo_t* const ctx) CairoElements::CairoElements(const Cairo::RefPtr<Cairo::Context>& ctx)
: _ctx(ctx) : _ctx(ctx)
{ {
} }
@ -38,7 +38,8 @@ CairoElements::CairoElements(cairo_t* const ctx)
void void
CairoElements::draw_3dsphere(const Point& center, float radius, const Color& cl) 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& x = center.x;
const float& y = center.y; const float& y = center.y;
const float& r = cl.r; 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; const float& b = cl.b;
// Draw initial sphere perimeter // Draw initial sphere perimeter
cairo_save(cr); _ctx->save();
cairo_new_path(cr); _ctx->begin_new_path();
cairo_arc(cr, x, y, radius, 0, 2*M_PI); _ctx->arc(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); RefPtr<Gradient> grad = RadialGradient::create(x, y, radius, x, y, radius - .15);
cairo_pattern_add_color_stop_rgba(grad, 1, r, g, b, 1); grad->add_color_stop_rgba(0, r - .2, g - .2, b - .2, 1);
cairo_set_source(cr, grad); grad->add_color_stop_rgba(1, r, g, b, 1);
cairo_fill_preserve(cr); _ctx->set_source(grad);
cairo_pattern_destroy(grad); _ctx->fill_preserve();
cairo_set_source_rgba(cr, 0, 0, 0, 1);
cairo_set_line_width(cr, radius * .01); _ctx->set_source_rgba(0, 0, 0, 1);
cairo_stroke(cr); _ctx->set_line_width(radius * .01);
cairo_restore(cr); _ctx->stroke();
_ctx->restore();
// Internal gradient // Internal gradient
cairo_save(cr); _ctx->save();
grad = cairo_pattern_create_linear(x, y, x, y + radius); grad = LinearGradient::create(x, y, x, y + radius);
cairo_pattern_add_color_stop_rgba(grad, 1, r - .4, g - .4, b - .4, 1); grad->add_color_stop_rgba(1, r - .4, g - .4, b - .4, 1);
cairo_pattern_add_color_stop_rgba(grad, 0, r, g, b, .7); grad->add_color_stop_rgba(0, r, g, b, .7);
cairo_set_source(cr, grad); _ctx->set_source(grad);
cairo_translate(cr, x*.2, (y + radius*8 / 9) * 1 / 3); _ctx->translate(x*.2, (y + radius*8 / 9) * 1 / 3);
cairo_scale(cr, .8, 2. / 3); _ctx->scale(.8, 2. / 3);
cairo_arc(cr, x, y, radius, 0, 2*M_PI); _ctx->arc(x, y, radius, 0, 2*M_PI);
cairo_fill(cr); _ctx->fill();
cairo_pattern_destroy(grad); _ctx->restore();
cairo_restore(cr);
// Internal glow // Internal glow
cairo_save(cr); _ctx->save();
grad = cairo_pattern_create_linear(x, y - radius, x, y); grad = LinearGradient::create(x, y - radius, x, y);
cairo_pattern_add_color_stop_rgba(grad, 0, 1, 1, 1, .9); grad->add_color_stop_rgba(0, 1, 1, 1, .9);
cairo_pattern_add_color_stop_rgba(grad, 1, 1, 1, 1, .2); grad->add_color_stop_rgba(1, 1, 1, 1, .2);
cairo_set_source(cr, grad); _ctx->set_source(grad);
cairo_translate(cr, x * .2, (y - radius*8 / 9) * 1 / 3); _ctx->translate(x * .2, (y - radius*8 / 9) * 1 / 3);
cairo_scale(cr, .8, 2. / 3); _ctx->scale(.8, 2. / 3);
cairo_arc(cr, x, y, radius, 0, 2*M_PI); _ctx->arc(x, y, radius, 0, 2*M_PI);
cairo_fill(cr); _ctx->fill();
cairo_pattern_destroy(grad); _ctx->restore();
cairo_restore(cr);
} }
void void
CairoElements::draw_3dcube(const Rectangle& area, const Color& cl, CairoElements::draw_3dcube(const Rectangle& area, const Color& cl,
const float x_percent, const float y_percent) const float x_percent, const float y_percent)
{ {
cairo_t*& cr = _ctx; using namespace Cairo;
const float& x0 = area.x0; const float& x0 = area.x0;
const float& y0 = area.y0; const float& y0 = area.y0;
const float& w = area.w; 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& g = cl.b;
const float& b = cl.b; const float& b = cl.b;
cairo_save(cr); _ctx->save();
cairo_set_line_join(cr, CAIRO_LINE_JOIN_ROUND); _ctx->set_line_join(LINE_JOIN_ROUND);
// Front side of the cube: // Front side of the cube:
cairo_rectangle(cr, _ctx->rectangle(x0, y0 + (1 - y_percent) * h,
x0, y0 + (1 - y_percent) * h,
w * x_percent, h * y_percent); w * x_percent, h * y_percent);
cairo_set_source_rgb(cr, r, g, b); _ctx->set_source_rgb(r, g, b);
cairo_fill_preserve(cr); _ctx->fill_preserve();
cairo_set_source_rgb(cr, 0, 0, 0); _ctx->set_source_rgb(0, 0, 0);
cairo_stroke(cr); _ctx->stroke();
// ``Upper'' visible cube side: // ``Upper'' visible cube side:
cairo_new_path(cr); _ctx->begin_new_path();
cairo_move_to(cr, x0, y0 + (1 - y_percent) * h); _ctx->move_to(x0, y0 + (1 - y_percent) * h);
cairo_line_to(cr, x0 + (1 - x_percent) * w, y0); _ctx->line_to(x0 + (1 - x_percent) * w, y0);
cairo_line_to(cr, x0 + w, y0); _ctx->line_to(x0 + w, y0);
cairo_line_to(cr, x0 + w * x_percent, y0 + (1 - y_percent) * h); _ctx->line_to(x0 + w * x_percent, y0 + (1 - y_percent) * h);
cairo_close_path(cr); _ctx->close_path();
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->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: // ``Right'' visible cube side:
cairo_new_path(cr); _ctx->begin_new_path();
cairo_move_to(cr, x0 + w * x_percent, y0 + (1 - y_percent) * h); _ctx->move_to(x0 + w * x_percent, y0 + (1 - y_percent) * h);
cairo_line_to(cr, x0 + w, y0); _ctx->line_to(x0 + w, y0);
cairo_line_to(cr, x0 + w, y0 + y_percent * h); _ctx->line_to(x0 + w, y0 + y_percent * h);
cairo_line_to(cr, x0 + w * x_percent, y0 + h); _ctx->line_to(x0 + w * x_percent, y0 + h);
cairo_close_path(cr); _ctx->close_path();
cairo_set_source_rgb(cr, r - 0.4, g - 0.4, b - 0.4); _ctx->set_source_rgb(r - 0.4, g - 0.4, b - 0.4);
cairo_fill_preserve(cr); _ctx->fill_preserve();
cairo_set_source_rgb(cr, 0, 0, 0); _ctx->set_source_rgb(0, 0, 0);
cairo_stroke(cr); _ctx->stroke();
cairo_restore(cr); _ctx->restore();
} }
void void
CairoElements::draw_container(const Rectangle& area) CairoElements::draw_container(const Rectangle& area)
{ {
cairo_t*& cr = _ctx; using namespace Cairo;
const float& x0 = area.x0; const float& x0 = area.x0;
const float& y0 = area.y0; const float& y0 = area.y0;
const float& w = area.w; const float& w = area.w;
@ -155,67 +155,68 @@ CairoElements::draw_container(const Rectangle& area)
const double corner_radius = 0.05; const double corner_radius = 0.05;
cairo_save(cr); _ctx->save();
cairo_new_path(cr); _ctx->begin_new_path();
cairo_move_to(cr, x0 + corner_radius, y0); _ctx->move_to(x0 + corner_radius, y0);
// NW -> NE // NW -> NE
cairo_line_to(cr, x0 + w - corner_radius, y0); _ctx->line_to(x0 + w - corner_radius, y0);
cairo_curve_to(cr, x0 + w, y0, x0 + w, y0, x0 + w, y0 + corner_radius); _ctx->curve_to(x0 + w, y0, x0 + w, y0, x0 + w, y0 + corner_radius);
// NE -> SE // NE -> SE
cairo_line_to(cr, x0 + w, y0 + h - corner_radius); _ctx->line_to(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->curve_to(x0 + w, y0 + h, x0 + w, y0 + h, x0 + w - corner_radius, y0 + h);
// SE -> SW // SE -> SW
cairo_line_to(cr, x0 + corner_radius, y0 + h); _ctx->line_to(x0 + corner_radius, y0 + h);
cairo_curve_to(cr, x0, y0 + h, x0, y0 + h, x0, y0 + h - corner_radius); _ctx->curve_to(x0, y0 + h, x0, y0 + h, x0, y0 + h - corner_radius);
// SW -> NW // SW -> NW
cairo_line_to(cr, x0, y0 + corner_radius); _ctx->line_to(x0, y0 + corner_radius);
cairo_curve_to(cr, x0, y0, x0, y0, x0 + corner_radius, y0); _ctx->curve_to(x0, y0, x0, y0, x0 + corner_radius, y0);
cairo_close_path(cr); _ctx->close_path();
cairo_set_source_rgb(cr, 1, 1, 0.9); _ctx->set_source_rgb(1, 1, 0.9);
cairo_fill_preserve(cr); _ctx->fill_preserve();
cairo_set_line_width(cr, .005); _ctx->set_line_width(.005);
cairo_set_source_rgb(cr, 0, 0, 0); _ctx->set_source_rgb(0, 0, 0);
cairo_stroke(cr); _ctx->stroke();
cairo_restore(cr); _ctx->restore();
} }
void void
CairoElements::draw_expandable(const Rectangle& area, bool expanded) CairoElements::draw_expandable(const Rectangle& area, bool expanded)
{ {
cairo_t*& cr = _ctx; using namespace Cairo;
const float& x0 = area.x0; const float& x0 = area.x0;
const float& y0 = area.y0; const float& y0 = area.y0;
const float& w = area.w; const float& w = area.w;
const float& h = area.h; const float& h = area.h;
cairo_save(cr); _ctx->save();
cairo_set_line_width(cr, .005); _ctx->set_line_width(.005);
cairo_set_source_rgb(cr, 1, 1, 1); _ctx->set_source_rgb(1, 1, 1);
cairo_new_path(cr); _ctx->begin_new_path();
cairo_rectangle(cr, x0, y0, w, h); _ctx->rectangle(x0, y0, w, h);
cairo_set_source_rgb(cr, 1, 1, 1); _ctx->set_source_rgb(1, 1, 1);
cairo_fill_preserve(cr); _ctx->fill_preserve();
cairo_set_source_rgb(cr, 0, 0, 0); _ctx->set_source_rgb(0, 0, 0);
cairo_stroke(cr); _ctx->stroke();
cairo_move_to(cr, x0 + w / 10, y0 + h / 2); _ctx->move_to(x0 + w / 10, y0 + h / 2);
cairo_line_to(cr, x0 + w*9 / 10, y0 + h / 2); _ctx->line_to(x0 + w*9 / 10, y0 + h / 2);
cairo_stroke(cr); _ctx->stroke();
if (!expanded) if (!expanded) // The "-" becomes a "+"
{ {
cairo_move_to(cr, x0 + w / 2, y0 + h / 10); _ctx->move_to(x0 + w / 2, y0 + h / 10);
cairo_line_to(cr, x0 + w / 2, y0 + h*9 / 10); _ctx->line_to(x0 + w / 2, y0 + h*9 / 10);
cairo_stroke(cr); _ctx->stroke();
} }
cairo_restore(cr); _ctx->restore();
} }

View File

@ -21,11 +21,7 @@
#ifndef CAIRO_ELEMENTS_HH #ifndef CAIRO_ELEMENTS_HH
#define CAIRO_ELEMENTS_HH 1 #define CAIRO_ELEMENTS_HH 1
#include <cairomm/context.h>
#include <sgpemv2/thread.hh>
#include <sgpemv2/process.hh>
#include <cairo.h>
namespace sgpem namespace sgpem
{ {
@ -61,7 +57,7 @@ namespace sgpem
class CairoElements class CairoElements
{ {
public: public:
CairoElements(cairo_t* const ctx); CairoElements(const Cairo::RefPtr<Cairo::Context>& ctx);
void draw_3dsphere(const Point& center, float radius, const Color& cl); 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); 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); void draw_expandable(const Rectangle& area, bool expanded = false);
private: private:
cairo_t* _ctx; Cairo::RefPtr<Cairo::Context> _ctx;
}; };
} //~ namespace sgpem } //~ namespace sgpem

View File

@ -75,11 +75,11 @@ CairoWidget::get_scaling_mode() const
void void
CairoWidget::on_realize() CairoWidget::on_realize()
{ {
if (is_realized()) return;
Gtk::Widget::on_realize(); Gtk::Widget::on_realize();
ensure_style(); ensure_style();
if (!_ref_gdk_window) return;
GdkWindowAttr attributes; GdkWindowAttr attributes;
memset(&attributes, 0, sizeof(attributes)); memset(&attributes, 0, sizeof(attributes));
@ -90,30 +90,29 @@ CairoWidget::on_realize()
attributes.width = alloc.get_width(); attributes.width = alloc.get_width();
attributes.height = alloc.get_height(); attributes.height = alloc.get_height();
attributes.wclass = GDK_INPUT_OUTPUT; 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.window_type = GDK_WINDOW_CHILD;
attributes.visual = get_visual()->gobj();
attributes.colormap = get_colormap()->gobj();
_client_w = alloc.get_width(); _client_w = alloc.get_width();
_client_h = alloc.get_height(); _client_h = alloc.get_height();
static const gint attributes_mask = Gdk::WA_X | Gdk::WA_Y | Gdk::WA_WMCLASS static const gint attributes_mask = Gdk::WA_X | Gdk::WA_Y;
| Gdk::WA_VISUAL | Gdk::WA_COLORMAP;
Glib::RefPtr<Gdk::Window> window = Gdk::Window::create(get_parent_window(), _ref_gdk_window = Gdk::Window::create(get_window(),
&attributes, &attributes,
attributes_mask); attributes_mask);
unset_flags(Gtk::NO_WINDOW); unset_flags(Gtk::NO_WINDOW);
set_window(window); set_window(_ref_gdk_window);
window->set_user_data(gobj()); _ref_gdk_window->set_user_data(gobj());
}
void
Glib::RefPtr<Gtk::Style> style = get_style (); CairoWidget::on_unrealize()
style = style->attach (window); {
style->set_background(window, Gtk::STATE_ACTIVE); _ref_gdk_window.clear();
Gtk::Widget::on_unrealize();
} }
/* /*
@ -124,19 +123,17 @@ CairoWidget::on_size_allocate(const Gtk::Allocation& allocation)
{ {
set_allocation(allocation); set_allocation(allocation);
if (is_realized()) 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 get_window()->move_resize(allocation.get_x(), allocation.get_y(),
_client_w = allocation.get_width(); allocation.get_width(), allocation.get_height());
_client_h = allocation.get_height();
// the widget must be redrawn // the widget's dimension are saved for futher use
_need_redraw = true; _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 bool
CairoWidget::on_expose_event(GdkEventExpose* event) CairoWidget::on_expose_event(GdkEventExpose* event)
{ {
if (!_ref_gdk_window) return true;
if (event == NULL || event->count > 0) if (event == NULL || event->count > 0)
return false; return false;
@ -173,14 +172,14 @@ CairoWidget::on_expose_event(GdkEventExpose* event)
// the widget must be redrawn if // the widget must be redrawn if
// - there's an explicit request(_need_redraw) // - there's an explicit request(_need_redraw)
// - the size is changed // - 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 // reset flag, set values with actual size
_need_redraw = false; _need_redraw = false;
_client_w = actual_w; _client_w = actual_w;
_client_h = actual_h; _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 // If the pixmap buffer size isn't enough
// it must be allocated or reallocated. // it must be allocated or reallocated.
// Here is used a lazy technique: // Here is used a lazy technique:
@ -195,7 +194,7 @@ CairoWidget::on_expose_event(GdkEventExpose* event)
_pixmap_h = (size_t) (_client_h*1.2); _pixmap_h = (size_t) (_client_h*1.2);
// allocate the pixmap // 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", NULL, (GtkWidget*)this->gobj(), "through",
0, 0, _client_w, _client_h); 0, 0, _client_w, _client_h);
// here the cairo context is creted // here the cairo context is created
cairo_t* ctx = gdk_cairo_create(_buf->gobj()); Cairo::RefPtr<Cairo::Context> ctx = _buf->create_cairo_context();
// Determine the final drawing dimensions // Determine the final drawing dimensions
// before to start drawing // before to start drawing
@ -218,13 +217,11 @@ CairoWidget::on_expose_event(GdkEventExpose* event)
// calculate and apply scale factors // calculate and apply scale factors
calc_scale_factors(); calc_scale_factors();
cairo_scale(ctx, _scale_x, _scale_y); ctx->scale(_scale_x, _scale_y);
// do the drawing... // do the drawing...
draw_widget(ctx); draw_widget(ctx);
// bye bye context
cairo_destroy(ctx);
} // ~ if(_need_redraw || actual_w!=_client_w || actual_h!=_client_h) } // ~ if(_need_redraw || actual_w!=_client_w || actual_h!=_client_h)
// Now the in-memory picture is placed on screen // 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 // Use double buffering or we're CPU-dead
// Copy from the buffer to the screen // Copy from the buffer to the screen
if (_buf) 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.x, event->area.y, event->area.x, event->area.y,
event->area.width, event->area.height); event->area.width, event->area.height);
@ -251,7 +248,7 @@ CairoWidget::calc_scale_factors()
// //
// "desired_size" here is how big can fin in window // "desired_size" here is how big can fin in window
// "effective_size" is how big the application produce // "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 // there are two possible scale factors x and y
_scale_x = (double)_client_w/(double)_draw_w; _scale_x = (double)_client_w/(double)_draw_w;
@ -265,6 +262,7 @@ CairoWidget::calc_scale_factors()
// doesn't scale // doesn't scale
_scale_x = _scale_y = 1.0; _scale_x = _scale_y = 1.0;
break; break;
case scaling_to_w: case scaling_to_w:
// scale to fit in width // scale to fit in width
// x and y take the same x value // x and y take the same x value
@ -280,7 +278,7 @@ CairoWidget::calc_scale_factors()
case scaling_min: case scaling_min:
// scale to fit always in window // scale to fit always in window
// x and y take the same minimum value // x and y take the same minimum value
if(_scale_x<=_scale_y) if(_scale_x <= _scale_y)
_scale_y = _scale_x; _scale_y = _scale_x;
else else
_scale_x = _scale_y; _scale_x = _scale_y;
@ -289,7 +287,7 @@ CairoWidget::calc_scale_factors()
case scaling_max: case scaling_max:
// scale to fit never in window // scale to fit never in window
// x and y take the same mxiimum value // x and y take the same mxiimum value
if(_scale_x>=_scale_y) if(_scale_x >= _scale_y)
_scale_y = _scale_x; _scale_y = _scale_x;
else else
_scale_x = _scale_y; _scale_x = _scale_y;
@ -335,14 +333,14 @@ CairoWidget::resize_redraw()
if(_buf) if(_buf)
{ {
cairo_t* ctx = gdk_cairo_create(_buf->gobj()); Cairo::RefPtr<Cairo::Context> ctx = _buf->create_cairo_context();
if(ctx) if(ctx)
{ {
// Determine the final drawing dimensions before to start drawing // Determine the final drawing dimensions before to start drawing
_draw_w = _draw_h = 0; // default no scaling _draw_w = _draw_h = 0; // default no scaling
calc_drawing_size(ctx, _draw_w, _draw_h); calc_drawing_size(ctx, _draw_w, _draw_h);
cairo_destroy(ctx); ctx.clear();
calc_scale_factors(); calc_scale_factors();
@ -367,7 +365,7 @@ CairoWidget::resize_redraw()
Derived classes can reimplement it or not as desired. Derived classes can reimplement it or not as desired.
*/ */
void void
CairoWidget::calc_drawing_size(cairo_t* /* ctx */, size_t& /* width */, size_t& /*height*/) CairoWidget::calc_drawing_size(Cairo::RefPtr<Cairo::Context>& /* ctx */, size_t& /* width */, size_t& /*height*/)
{ {
} }

View File

@ -21,8 +21,7 @@
#ifndef CAIRO_WIDGET_HH #ifndef CAIRO_WIDGET_HH
#define CAIRO_WIDGET_HH 1 #define CAIRO_WIDGET_HH 1
#include <cairo.h> #include <cairomm/context.h>
#include <gtkmm/drawingarea.h>
#include <gtkmm/widget.h> #include <gtkmm/widget.h>
#include <gdkmm/pixmap.h> #include <gdkmm/pixmap.h>
@ -141,7 +140,7 @@ namespace sgpem
/** /**
* \brief Widgets size type. * \brief Widgets size type.
*/ */
typedef unsigned int size_t; typedef guint size_t;
// implementation of fundamental widget's method // implementation of fundamental widget's method
/** /**
@ -152,6 +151,7 @@ namespace sgpem
* See gtkmm documentation for more informations. * See gtkmm documentation for more informations.
*/ */
virtual void on_realize(); virtual void on_realize();
virtual void on_unrealize(); // doesn't need to be documented.
/** /**
* \brief Implements standard widget's on_size_allocate() mehtod. * \brief Implements standard widget's on_size_allocate() mehtod.
@ -193,7 +193,7 @@ namespace sgpem
* draw in the widgets client area. * draw in the widgets client area.
* See cairo documentation for more informations. * See cairo documentation for more informations.
*/ */
virtual void draw_widget(cairo_t* ctx) = 0; virtual void draw_widget(Cairo::RefPtr<Cairo::Context>& ctx) = 0;
/** /**
* \brief Method to calculate widget dimensions. * \brief Method to calculate widget dimensions.
@ -201,7 +201,7 @@ namespace sgpem
* The user should implement this method to allow scaling factors calculation. * The user should implement this method to allow scaling factors calculation.
* Is necessary if scaling is needed/used. * 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<Cairo::Context>& ctx, size_t& width, size_t& height);
// with this method CairoWidget tells the needed widget dimensions // with this method CairoWidget tells the needed widget dimensions
/** /**
@ -232,48 +232,48 @@ namespace sgpem
/** /**
* \brief Calculated width of drawing. * \brief Calculated width of drawing.
*/ */
mutable size_t _draw_w; size_t _draw_w;
/** /**
* \brief Calculated height of drawing. * \brief Calculated height of drawing.
*/ */
mutable size_t _draw_h; size_t _draw_h;
private: private:
/** /**
* \brief Client area width of widget. * \brief Client area width of widget.
*/ */
mutable size_t _client_w; size_t _client_w;
/** /**
* \brief Client area height of widget. * \brief Client area height of widget.
*/ */
mutable size_t _client_h; size_t _client_h;
/** /**
* \brief Client area width of pixmap. * \brief Client area width of pixmap.
*/ */
mutable size_t _pixmap_w; size_t _pixmap_w;
/** /**
* \brief Client area width of pixmap. * \brief Client area width of pixmap.
*/ */
mutable size_t _pixmap_h; size_t _pixmap_h;
/** /**
* \brief Cairo x scale factor. * \brief Cairo x scale factor.
*/ */
mutable double _scale_x; double _scale_x;
/** /**
* \brief Cairo y scale factor. * \brief Cairo y scale factor.
*/ */
mutable double _scale_y; double _scale_y;
/** /**
* \brief Flag to signal require redrawing. * \brief Flag to signal require redrawing.
*/ */
mutable bool _need_redraw; bool _need_redraw;
/** /**
* \brief Actual scaling mode. * \brief Actual scaling mode.
@ -284,6 +284,11 @@ namespace sgpem
* \brief Offscreen pixmap used for double-buffering. * \brief Offscreen pixmap used for double-buffering.
*/ */
Glib::RefPtr<Gdk::Pixmap> _buf; Glib::RefPtr<Gdk::Pixmap> _buf;
/**
*
*/
Glib::RefPtr<Gdk::Window> _ref_gdk_window;
}; };
} //~ namespace sgpem } //~ namespace sgpem

View File

@ -21,20 +21,22 @@
#include "cairo_elements.hh" #include "cairo_elements.hh"
#include <sgpemv2/history.hh> #include "sgpemv2/history.hh"
#include <sgpemv2/schedulable.hh> #include "sgpemv2/schedulable.hh"
#include <sgpemv2/resource.hh> #include "sgpemv2/process.hh"
#include <sgpemv2/simulation.hh> #include "sgpemv2/resource.hh"
#include <sgpemv2/string_utils.hh> #include "sgpemv2/simulation.hh"
#include <sgpemv2/thread.hh> #include "sgpemv2/string_utils.hh"
#include "sgpemv2/thread.hh"
#include "holt_widget.hh" #include "holt_widget.hh"
#include <sgpemv2/templates/deletor.tcc> #include "sgpemv2/templates/deletor.tcc"
#include <sgpemv2/templates/sequences.tcc> #include "sgpemv2/templates/sequences.tcc"
#include <math.h> #include <cairomm/cairomm.h>
#include <cmath>
#include <cassert> #include <cassert>
#ifndef NDEBUG #ifndef NDEBUG
@ -104,7 +106,7 @@ HoltResource::~HoltResource()
{ {
} }
void HoltResource::draw(cairo_t *cr) void HoltResource::draw(Cairo::RefPtr<Cairo::Context>& cr)
{ {
static const Color white(1, 1, 1); static const Color white(1, 1, 1);
@ -114,43 +116,31 @@ void HoltResource::draw(cairo_t *cr)
CairoElements ce(cr); CairoElements ce(cr);
// outline // outline
cairo_set_source_rgb (cr, 0, 0, 0); cr->set_source_rgb (0, 0, 0);
// draw rectangle // draw rectangle
Rectangle area(_pos.real() - _radius, _pos.imag() - _radius, 2*_radius, 2*_radius); Rectangle area(_pos.real() - _radius, _pos.imag() - _radius, 2*_radius, 2*_radius);
ce.draw_3dcube(area, white, x_percent, y_percent); ce.draw_3dcube(area, white, x_percent, y_percent);
cr->save();
cairo_save(cr);
// clip text outside region // clip text outside region
/* cr->rectangle(_pos.real() - _radius,
cairo_rectangle(cr, _pos.imag() + _radius * (1 - 2.0 * y_percent),
_pos.real() - _radius, 2 * _radius * x_percent,
_pos.imag() - _radius, // _pos.imag() + _radius (1 - 2.0 * y_percent) 2 * _radius * y_percent);
2 * _radius * x_percent, cr->clip();
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);
// draw text // draw text
cairo_text_extents_t extents; Cairo::TextExtents extents;
cairo_text_extents(cr, _resource->get_name().c_str(), &extents); cr->get_text_extents(_resource->get_name(), extents);
double xpos = _pos.real() + _radius * (x_percent-1) - extents.width/2.0; double xpos = _pos.real() + _radius * (x_percent-1) - extents.width/2.0;
double ypos = _pos.imag() + _radius * (1 - y_percent); // + extents.height/2; 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 // left aligned if too large
if(xpos<_pos.real() - _radius) if(xpos<_pos.real() - _radius)
xpos = _pos.real() - _radius; xpos = _pos.real() - _radius;
cairo_move_to(cr, cr->move_to(xpos, ypos );
xpos, cr->show_text(_resource->get_name());
ypos );
cairo_show_text(cr, _resource->get_name().c_str());
// show used/total places // show used/total places
Glib::ustring used; Glib::ustring used;
@ -159,18 +149,16 @@ void HoltResource::draw(cairo_t *cr)
to_string<int>((int)_resource->get_places(), total); to_string<int>((int)_resource->get_places(), total);
Glib::ustring msg = used + "/" + 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; xpos = _pos.real() + _radius * (x_percent-1) - extents.width/2.0;
ypos = _pos.imag() + _radius * (1 - y_percent) + extents.height*2; ypos = _pos.imag() + _radius * (1 - y_percent) + extents.height*2;
cairo_move_to(cr, cr->move_to(xpos, ypos);
xpos, cr->show_text(msg);
ypos );
cairo_show_text(cr, msg.c_str());
// stroke all // stroke all
cairo_stroke (cr); cr->stroke();
cairo_restore(cr); cr->restore();
} }
Vec2 HoltResource::get_intersection_to(Vec2 pt) Vec2 HoltResource::get_intersection_to(Vec2 pt)
@ -224,14 +212,13 @@ HoltSchedulable::~HoltSchedulable()
{ {
} }
void HoltSchedulable::draw(cairo_t *cr) void HoltSchedulable::draw(Cairo::RefPtr<Cairo::Context>& cr)
{ {
static const Color red(1, 0, 0); static const Color red(1, 0, 0);
static const Color yellow(1, 0.8, 0); static const Color yellow(1, 0.8, 0);
static const Color green(0, 1, 0); static const Color green(0, 1, 0);
cr->save(); // save context state
cairo_save(cr); // save context state
const Point center(_pos.real(), _pos.imag()); const Point center(_pos.real(), _pos.imag());
const Color* color = &red; const Color* color = &red;
@ -259,22 +246,21 @@ void HoltSchedulable::draw(cairo_t *cr)
cel.draw_3dsphere(center, _radius, *color); cel.draw_3dsphere(center, _radius, *color);
// clip text outside region // clip text outside region
cairo_arc(cr, _pos.real(), _pos.imag(), _radius, 0, 2*M_PI); cr->arc(_pos.real(), _pos.imag(), _radius, 0, 2*M_PI);
cairo_clip(cr); cr->clip();
// draw text // draw text
cairo_text_extents_t extents; Cairo::TextExtents extents;
cairo_text_extents(cr, _schedulable->get_name().c_str(), &extents); cr->get_text_extents(_schedulable->get_name(), extents);
double text_width = extents.width; double text_width = extents.width;
if(text_width>_radius*2.0) if(text_width>_radius*2.0) text_width=_radius*2.0;
text_width=_radius*2.0; cr->move_to(_pos.real() - text_width/2, _pos.imag() + extents.height/2);
cairo_move_to(cr, _pos.real() - text_width/2, _pos.imag() + extents.height/2); cr->show_text(_schedulable->get_name());
cairo_show_text(cr, _schedulable->get_name().c_str());
// stroke all // 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) Vec2 HoltSchedulable::get_intersection_to(Vec2 pt)
@ -310,24 +296,24 @@ HoltRequest::~HoltRequest()
{ {
} }
void HoltRequest::draw(cairo_t *cr) void HoltRequest::draw(Cairo::RefPtr<Cairo::Context>& cr)
{ {
Vec2 resource = _hp->get_intersection_to(_hr->get_position()); Vec2 resource = _hp->get_intersection_to(_hr->get_position());
Vec2 schedulable = _hr->get_intersection_to(_hp->get_position()); Vec2 schedulable = _hr->get_intersection_to(_hp->get_position());
cairo_save(cr); cr->save();
switch(_state) switch(_state)
{ {
case Request::state_unallocable: case Request::state_unallocable:
// red // red
cairo_set_source_rgb(cr, 1, 0, 0); cr->set_source_rgb(1, 0, 0);
arrow(cr, schedulable, resource); arrow(cr, schedulable, resource);
break; break;
case Request::state_allocated: case Request::state_allocated:
// green // green
cairo_set_source_rgb(cr, 0, 1, 0); cr->set_source_rgb(0, 1, 0);
arrow(cr, resource, schedulable); arrow(cr, resource, schedulable);
break; break;
@ -339,27 +325,27 @@ void HoltRequest::draw(cairo_t *cr)
case Request::state_allocable: case Request::state_allocable:
// yellow // yellow
cairo_set_source_rgb(cr, 1, 0.7, 0); cr->set_source_rgb(1, 0.7, 0);
arrow(cr, schedulable, resource); arrow(cr, schedulable, resource);
break; break;
} }
// stroke all and restore status // stroke all and restore status
cairo_stroke (cr); cr->stroke();
cairo_restore(cr); cr->restore();
} }
void HoltRequest::arrow(cairo_t *cr, Vec2 first, Vec2 second) void HoltRequest::arrow(Cairo::RefPtr<Cairo::Context>& cr, Vec2 first, Vec2 second)
{ {
// option to draw the line a little translated // option to draw the line a little translated
// this allow to draw two counterflow arrows // this allow to draw two counterflow arrows
// without overlap // without overlap
bool traslate = true; bool traslate = true;
double line_width = cairo_get_line_width(cr); double line_width = cr->get_line_width();
if(traslate) if(traslate)
{ {
// if needed calc parallel versor of arrow // if needed calc parallel versor of arrow
Vec2 direction = second-first; Vec2 direction = second - first;
direction /= std::abs(direction); // set unary modulus direction /= std::abs(direction); // set unary modulus
// and rotate it 90 degrees // and rotate it 90 degrees
@ -373,12 +359,12 @@ void HoltRequest::arrow(cairo_t *cr, Vec2 first, Vec2 second)
} }
// draw main line // draw main line
cairo_move_to(cr, second.real(), second.imag()); cr->move_to(second.real(), second.imag());
cairo_line_to(cr, first.real(), first.imag()); cr->line_to(first.real(), first.imag());
// some calculation to draw arrowpoint... // some calculation to draw arrowpoint...
// take a short line parallel to main line // take a short line parallel to main line
Vec2 arrowside = second-first; Vec2 arrowside = second - first;
arrowside *= 5.0*line_width/std::abs(arrowside); arrowside *= 5.0*line_width/std::abs(arrowside);
// make a rotation component // make a rotation component
Vec2 deviation(5.0, 1.0); deviation /= std::abs(deviation); 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 side1 = arrowside * deviation;
Vec2 side2 = arrowside * conj(deviation); Vec2 side2 = arrowside * conj(deviation);
// draw one side // draw one side
cairo_move_to(cr, first.real(), first.imag()); cr->move_to(first.real(), first.imag());
cairo_line_to(cr, first.real()+side1.real(), first.imag()+side1.imag()); cr->line_to(first.real()+side1.real(), first.imag()+side1.imag());
// draw the other side // draw the other side
cairo_move_to(cr, first.real(), first.imag()); cr->move_to(first.real(), first.imag());
cairo_line_to(cr, first.real()+side2.real(), first.imag()+side2.imag()); cr->line_to(first.real()+side2.real(), first.imag()+side2.imag());
} }
@ -806,7 +792,7 @@ HoltWidget::acquire()
void void
HoltWidget::draw_widget(cairo_t* ctx) HoltWidget::draw_widget(Cairo::RefPtr<Cairo::Context>& ctx)
{ {
#ifndef NDEBUG #ifndef NDEBUG
std::cout << "HoltWidget::draw_widget" << endl; std::cout << "HoltWidget::draw_widget" << endl;
@ -819,18 +805,16 @@ HoltWidget::draw_widget(cairo_t* ctx)
if(_draw_w>0) if(_draw_w>0)
{ {
const History& hist = _simulation->get_history(); const History& hist = _simulation->get_history();
const unsigned int hist_front = hist.get_front() == 0 ? 0 : hist.get_front() - 1; const unsigned int hist_front = hist.get_front() == 0 ? 0 : hist.get_front() - 1;
cairo_text_extents_t extents; Cairo::TextExtents extents;
stringstream ss; stringstream ss;
ss << "T = " << hist_front; ss << "T = " << hist_front;
cairo_text_extents(ctx, ss.str().c_str(), &extents); ctx->get_text_extents(ss.str(), extents);
cairo_move_to(ctx, _draw_w/2 - extents.width/2.0, extents.height*2.0); ctx->move_to(_draw_w/2 - extents.width/2.0, extents.height*2.0);
cairo_show_text(ctx, ss.str().c_str()); ctx->show_text(ss.str());
cairo_stroke(ctx); ctx->stroke();
} }
// draw all resources // draw all resources
typedef HoltResources::const_iterator holt_res_iterator; typedef HoltResources::const_iterator holt_res_iterator;
holt_res_iterator riter = _holt_resources.begin(); holt_res_iterator riter = _holt_resources.begin();
@ -865,7 +849,7 @@ HoltWidget::draw_widget(cairo_t* ctx)
void void
HoltWidget::calc_drawing_size(cairo_t* ctx, size_t& width, size_t& height) HoltWidget::calc_drawing_size(Cairo::RefPtr<Cairo::Context>& ctx, size_t& width, size_t& height)
{ {
#ifndef NDEBUG #ifndef NDEBUG
cout << "Holt widget BEFORE calc_drawing_size width=" << width << " height=" << height << endl; 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; int max = _n_proc;
if(_n_res>_n_proc) if(_n_res>_n_proc)
max = _n_res; max = _n_res;
cairo_text_extents_t extents; Cairo::TextExtents extents;
static const Glib::ustring val("Process 999 Resource 999"); 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; _radius = extents.width/4.0;
switch(_arrange_mode) switch(_arrange_mode)

View File

@ -89,7 +89,7 @@ namespace sgpem
* *
* \param cr The cairo context to draw to. * \param cr The cairo context to draw to.
*/ */
virtual void draw(cairo_t *cr) = 0; virtual void draw(Cairo::RefPtr<Cairo::Context>& cr) = 0;
/** /**
* \brief Setter and getter method for position parameter. * \brief Setter and getter method for position parameter.
@ -195,7 +195,7 @@ namespace sgpem
* *
* \param cr Cairo context to draw to. * \param cr Cairo context to draw to.
*/ */
virtual void draw(cairo_t *cr); virtual void draw(Cairo::RefPtr<Cairo::Context>& cr);
/** /**
* \brief Computes point of intersection with edge. * \brief Computes point of intersection with edge.
@ -278,7 +278,7 @@ namespace sgpem
* *
* \param cr Cairo context to draw to. * \param cr Cairo context to draw to.
*/ */
virtual void draw(cairo_t *cr); virtual void draw(Cairo::RefPtr<Cairo::Context>& cr);
/** /**
* \brief Computes point of intersection with edge. * \brief Computes point of intersection with edge.
@ -336,7 +336,7 @@ namespace sgpem
* *
* \param cr Cairo context to draw to. * \param cr Cairo context to draw to.
*/ */
virtual void draw(cairo_t *cr); virtual void draw(Cairo::RefPtr<Cairo::Context>& cr);
private: private:
/** /**
@ -346,7 +346,7 @@ namespace sgpem
* \param first Starting point. * \param first Starting point.
* \param first Ending point. * \param first Ending point.
*/ */
virtual void arrow(cairo_t *cr, Vec2 first, Vec2 second); virtual void arrow(Cairo::RefPtr<Cairo::Context>& cr, Vec2 first, Vec2 second);
/** /**
* \brief Pointer to the referring schedulable. * \brief Pointer to the referring schedulable.
@ -490,7 +490,7 @@ namespace sgpem
* \param ctx the cairo context to draw to * \param ctx the cairo context to draw to
* \see CairoWidget for more. * \see CairoWidget for more.
*/ */
void draw_widget(cairo_t* ctx); void draw_widget(Cairo::RefPtr<Cairo::Context>& ctx);
/** /**
@ -500,7 +500,7 @@ namespace sgpem
* \param width the return parameter for desired width * \param width the return parameter for desired width
* \param height the return parameter for desired height * \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<Cairo::Context>& ctx, size_t& width, size_t& height);
// virtual void calc_widget_size(size_t& width, size_t& height); // virtual void calc_widget_size(size_t& width, size_t& height);

View File

@ -22,15 +22,19 @@
#include "simulation_widget.hh" #include "simulation_widget.hh"
#include "cairo_elements.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 <glibmm/refptr.h> #include <glibmm/refptr.h>
#include <gtkmm/action.h> #include <gtkmm/action.h>
#include <gtkmm/actiongroup.h> #include <gtkmm/actiongroup.h>
#include <gtkmm/menu.h> #include <gtkmm/menu.h>
#include <gtkmm/uimanager.h> #include <gtkmm/uimanager.h>
#include <sgpemv2/history.hh> #include <cairomm/matrix.h>
#include <sgpemv2/simulation.hh>
#include <sgpemv2/string_utils.hh>
#include <cassert> #include <cassert>
@ -42,7 +46,6 @@ using namespace sgpem;
using namespace Gtk; using namespace Gtk;
using namespace Glib; using namespace Glib;
SimulationWidget::SimulationWidget(Simulation& simulation) SimulationWidget::SimulationWidget(Simulation& simulation)
: Glib::ObjectBase("sgpem_SimulationWidget"), : Glib::ObjectBase("sgpem_SimulationWidget"),
SimulationObserver(), SimulationObserver(),
@ -60,35 +63,29 @@ SimulationWidget::SimulationWidget(Simulation& simulation)
// count_elements(); // count_elements();
// define top margin in y units // define top margin in y units
_yu_top_margin = 1.0; _yu_top_margin = 1.0;
// define left margin in x units // define left margin in x units
_xu_left_margin = 1.0; _xu_left_margin = 1.0;
// define graph left margin in x units // define graph left margin in x units
_xu_left_graph_margin = 11.0; _xu_left_graph_margin = 11.0;
// define process bar spacing in y units // define process bar spacing in y units
_yu_process_bar_spacing = 1.0; _yu_process_bar_spacing = 1.0;
// define process bar height in y units // define process bar height in y units
_yu_process_bar_height = 2.0; _yu_process_bar_height = 2.0;
// define thread bar spacing in y units // define thread bar spacing in y units
_yu_thread_bar_spacing = 0.5; _yu_thread_bar_spacing = 0.5;
// define thread bar height in y units // define thread bar height in y units
_yu_thread_bar_height = 1.0; _yu_thread_bar_height = 1.0;
_partial_redraw = false;
// _last_drawn = 0;
_ready_process_gradient = 0;
_running_process_gradient = 0;
_blocked_process_gradient = 0;
_partial_redraw = false;
_last_drawn = 0;
} }
@ -101,9 +98,20 @@ SimulationWidget::~SimulationWidget()
_simulation->detach(*this); _simulation->detach(*this);
} }
void
SimulationWidget::on_realize()
{
CairoWidget::on_realize();
// Register for receiving click events:
RefPtr<Gdk::Window> gdk_win = get_window();
gdk_win->set_events(gdk_win->get_events() | Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_RELEASE_MASK);
}
void void
SimulationWidget::update(const Simulation& /* changed_simulation */ ) SimulationWidget::update(const Simulation& /* changed_simulation */ )
{ {
// FIXME: DEPRECATED. Does nothing.
} }
void void
@ -132,12 +140,12 @@ SimulationWidget::set_show_threads(bool show)
void void
SimulationWidget::draw_widget(cairo_t* ctx) SimulationWidget::draw_widget(Cairo::RefPtr<Cairo::Context>& ctx)
{ {
if(_n_proc<1) // nothing to draw if(_n_proc<1) // nothing to draw
{ {
cairo_move_to(ctx, 2.0*_x_unit, 2.0*_y_unit); ctx->move_to(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->show_text(_("Nothing to see here... add some processes! Right-click on the Schedulables view in this window."));
return; return;
} }
@ -148,12 +156,12 @@ SimulationWidget::draw_widget(cairo_t* ctx)
void void
SimulationWidget::draw_names(cairo_t* ctx) SimulationWidget::draw_names(Cairo::RefPtr<Cairo::Context>& ctx)
{ {
// show processes (and thread) names... // show processes (and thread) names...
// useful constants // 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 top_margin = _yu_top_margin * _y_unit;
const double left_margin = _x_unit; const double left_margin = _x_unit;
const double left_graph_margin = _xu_left_graph_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 a rectangular clip region to cut long names
// - set the rectangle // - set the rectangle
cairo_rectangle(ctx, 0, top_margin, ctx->rectangle(0, top_margin,
left_graph_margin - left_margin, left_graph_margin - left_margin,
_n_proc*process_height + _n_thr*thread_height); _n_proc*process_height + _n_thr*thread_height);
// - set the clip region // - set the clip region
cairo_clip(ctx); ctx->clip();
// text start position: margin + half of text height // text start position: margin + half of text height
double ypos = top_margin + _y_unit / 2.0; 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 // move to bar center adding a white row before
ypos += process_bar_spacing + process_bar_height/2.0; 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 // 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 // calc position to next row skipping height of process bar
ypos += process_bar_height/2.0; ypos += process_bar_height/2.0;
@ -202,9 +210,9 @@ SimulationWidget::draw_names(cairo_t* ctx)
thr_iter++; thr_iter++;
// move to bar center adding white space as needed // move to bar center adding white space as needed
ypos += thread_height/2.0; 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 // 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 // calc position to next thread bar begin
ypos += thread_height/2.0; // height of thread bar ypos += thread_height/2.0; // height of thread bar
@ -216,11 +224,11 @@ SimulationWidget::draw_names(cairo_t* ctx)
} // ~ while(proc_iter!=processes.end()) } // ~ while(proc_iter!=processes.end())
// remove clip region // remove clip region
cairo_reset_clip(ctx); ctx->reset_clip();
} }
void void
SimulationWidget::draw_grid(cairo_t* ctx) SimulationWidget::draw_grid(Cairo::RefPtr<Cairo::Context>& ctx)
{ {
const History& hist = _simulation->get_history(); const History& hist = _simulation->get_history();
@ -243,8 +251,8 @@ SimulationWidget::draw_grid(cairo_t* ctx)
Process* p = (*proc_iter); Process* p = (*proc_iter);
proc_iter++; proc_iter++;
// draw one HOR line per process // draw one HOR line per process
cairo_move_to(ctx, left_graph_margin, ypos); ctx->move_to(left_graph_margin, ypos);
cairo_rel_line_to(ctx, graph_width, 0); ctx->rel_line_to(graph_width, 0);
// calc next line position // calc next line position
ypos += process_height; // skip a process heigh ypos += process_height; // skip a process heigh
@ -257,69 +265,69 @@ SimulationWidget::draw_grid(cairo_t* ctx)
} // ~ while(proc_iter!=processes.end()) } // ~ while(proc_iter!=processes.end())
// draw last HOR line // draw last HOR line
cairo_move_to(ctx, left_graph_margin, ypos); ctx->move_to(left_graph_margin, ypos);
cairo_rel_line_to(ctx, graph_width, 0); ctx->rel_line_to(graph_width, 0);
// - draw left VER line // - draw left VER line
cairo_move_to(ctx, left_graph_margin, top_margin); ctx->move_to(left_graph_margin, top_margin);
cairo_rel_line_to(ctx, 0, graph_height); ctx->rel_line_to(0, graph_height);
// right close the graph only if simulation stopped // right close the graph only if simulation stopped
if(_simulation->get_state()==Simulation::state_stopped) if(_simulation->get_state()==Simulation::state_stopped)
{ {
// - draw right VER line // - draw right VER line
cairo_move_to(ctx, left_graph_margin + graph_width, top_margin); ctx->move_to(left_graph_margin + graph_width, top_margin);
cairo_rel_line_to(ctx, 0, graph_height); ctx->rel_line_to(0, graph_height);
} }
// trace lines on output context // trace lines on output context
cairo_stroke(ctx); ctx->stroke();
// Draw a grey vertical line every fifth step // Draw a grey vertical line every fifth step
cairo_save(ctx); ctx->save();
cairo_set_line_width(ctx, 0.125 * cairo_get_line_width(ctx)); ctx->set_line_width(0.125 * ctx->get_line_width());
cairo_set_source_rgb(ctx, 0.3, 0.3, 0.3); ctx->set_source_rgb(0.3, 0.3, 0.3);
for(double step = _x_unit; step < graph_width - _x_unit; step += 5 * _x_unit) for(double step = _x_unit; step < graph_width - _x_unit; step += 5 * _x_unit)
{ {
cairo_new_path(ctx); ctx->begin_new_path();
cairo_move_to(ctx, left_graph_margin + step, top_margin); ctx->move_to(left_graph_margin + step, top_margin);
cairo_rel_line_to(ctx, 0, graph_height); ctx->rel_line_to(0, graph_height);
cairo_stroke(ctx); ctx->stroke();
} }
cairo_restore(ctx); ctx->restore();
// draw and write time line // draw and write time line
cairo_save(ctx); ctx->save();
cairo_set_source_rgb(ctx, 0, 0, 0); ctx->set_source_rgb(0, 0, 0);
cairo_set_line_width(ctx, 0.25*cairo_get_line_width(ctx)); ctx->set_line_width(0.25*ctx->get_line_width());
// "T" label // "T" label
cairo_move_to(ctx, left_graph_margin, ctx->move_to(left_graph_margin,
top_margin + graph_height + 2.0 * _y_unit); top_margin + graph_height + 2.0 * _y_unit);
cairo_show_text(ctx,"T"); ctx->show_text("T");
// ruler drawing cycle // ruler drawing cycle
for(unsigned int t=0; t<=hist_front; t++) for(unsigned int t=0; t<=hist_front; t++)
{ {
// tick // 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); top_margin + graph_height);
cairo_rel_line_to(ctx, 0, 0.5 * _y_unit); ctx->rel_line_to(0, 0.5 * _y_unit);
// value // value
Glib::ustring val; Glib::ustring val;
to_string<int>(t, val); to_string<int>(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); 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++) } // ~ for(int t=0; t<=pos; t++)
cairo_stroke(ctx); ctx->stroke();
cairo_restore(ctx); ctx->restore();
} }
void void
SimulationWidget::draw_bars(cairo_t* ctx) SimulationWidget::draw_bars(Cairo::RefPtr<Cairo::Context>& ctx)
{ {
// useful constants // useful constants
const History& hist = _simulation->get_history(); const History& hist = _simulation->get_history();
@ -408,53 +416,50 @@ SimulationWidget::draw_bars(cairo_t* ctx)
// draw single rectangle using gradients // draw single rectangle using gradients
void void
SimulationWidget::draw_instant_rect(cairo_t* ctx, double x, double y, SimulationWidget::draw_instant_rect(Cairo::RefPtr<Cairo::Context>& ctx, double x, double y,
double w, double h, Schedulable::state state) double w, double h, Schedulable::state state)
{ {
cairo_matrix_t matrix; using namespace Cairo;
switch(state) switch(state)
{ {
case Schedulable::state_running: case Schedulable::state_running:
cairo_save(ctx); ctx->save();
cairo_set_source(ctx, _running_process_gradient); ctx->set_source(_running_process_gradient);
// translate the gradient at desired position // translate the gradient at desired position
cairo_matrix_init_translate(&matrix, 0, -y); _running_process_gradient->set_matrix(translation_matrix(0, -y));
cairo_pattern_set_matrix (_running_process_gradient, &matrix);
// put the filled rectangle // put the filled rectangle
cairo_rectangle(ctx, x, y, w, h); ctx->rectangle(x, y, w, h);
cairo_fill(ctx); ctx->fill();
cairo_restore(ctx); ctx->restore();
break; break;
case Schedulable::state_ready: case Schedulable::state_ready:
cairo_save(ctx); ctx->save();
cairo_set_source(ctx, _ready_process_gradient); ctx->set_source(_ready_process_gradient);
// translate the gradient at desired position // translate the gradient at desired position
cairo_matrix_init_translate(&matrix, 0, -y); _ready_process_gradient->set_matrix(translation_matrix(0, -y));
cairo_pattern_set_matrix (_ready_process_gradient, &matrix);
// put the filled rectangle // put the filled rectangle
cairo_rectangle(ctx, x, y, w, h); ctx->rectangle(x, y, w, h);
cairo_fill(ctx); ctx->fill();
cairo_restore(ctx); ctx->restore();
break; break;
case Schedulable::state_blocked: case Schedulable::state_blocked:
cairo_save(ctx); ctx->save();
cairo_set_source(ctx, _blocked_process_gradient); ctx->set_source(_blocked_process_gradient);
// translate the gradient at desired position // translate the gradient at desired position
cairo_matrix_init_translate(&matrix, 0, -y); _blocked_process_gradient->set_matrix(translation_matrix(0, -y));
cairo_pattern_set_matrix (_blocked_process_gradient, &matrix);
// put the filled rectangle // put the filled rectangle
cairo_rectangle(ctx, x, y, w, h); ctx->rectangle(x, y, w, h);
cairo_fill(ctx); ctx->fill();
cairo_restore(ctx); ctx->restore();
break; break;
case Schedulable::state_future: case Schedulable::state_future:
@ -469,7 +474,7 @@ SimulationWidget::draw_instant_rect(cairo_t* ctx, double x, double y,
void void
SimulationWidget::calc_drawing_size(cairo_t* ctx, size_t& width, size_t& height) SimulationWidget::calc_drawing_size(Cairo::RefPtr<Cairo::Context>& ctx, size_t& width, size_t& height)
{ {
if(!_simulation) if(!_simulation)
return; 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(); int pos = _simulation->get_history().get_front();
// units are defined in terms of text dimensions // units are defined in terms of text dimensions
cairo_text_extents_t extents; Cairo::TextExtents extents;
Glib::ustring val("999"); Glib::ustring val("999");
cairo_text_extents(ctx, val.c_str(), &extents); ctx->get_text_extents(val, extents);
if(_x_unit<extents.width) if(_x_unit < extents.width)
_x_unit=extents.width; _x_unit = extents.width;
if(_y_unit<extents.height) if(_y_unit < extents.height)
_y_unit=extents.height; _y_unit = extents.height;
// left margin, labels, graph // left margin, labels, graph
width = (size_t)((_xu_left_graph_margin + 3.0 + pos) * _x_unit); width = (size_t)((_xu_left_graph_margin + 3.0 + pos) * _x_unit);
@ -509,7 +514,7 @@ SimulationWidget::count_elements()
{ {
_n_proc = _n_thr = 0; _n_proc = _n_thr = 0;
const History& hist = _simulation->get_history(); const History& hist = _simulation->get_history();
const Environment& env = hist.get_last_environment(); const Environment& env = hist.get_last_environment();
// count processes // count processes
@ -533,24 +538,25 @@ SimulationWidget::make_gradients()
{ {
// linear gradients are referred to 0, 0 // linear gradients are referred to 0, 0
// must be translated if used elsewhere // 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 // yellow
cairo_pattern_add_color_stop_rgb(_ready_process_gradient, 0.0, 1.00, 0.7, 0.0); _ready_process_gradient->add_color_stop_rgb(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); _ready_process_gradient->add_color_stop_rgb(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(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 // green
cairo_pattern_add_color_stop_rgb(_running_process_gradient, 0.0, 0.0, 0.8, 0.0); _running_process_gradient->add_color_stop_rgb(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); _running_process_gradient->add_color_stop_rgb(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(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 // red
cairo_pattern_add_color_stop_rgb(_blocked_process_gradient, 0.0, 0.85, 0.0, 0.0); _blocked_process_gradient->add_color_stop_rgb(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); _blocked_process_gradient->add_color_stop_rgb(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(1.0, 0.65, 0.0, 0.0);
} }
@ -656,3 +662,5 @@ SimulationWidget::_on_stretch_scaling()
resize_redraw(); resize_redraw();
// set_size_request (20, 20); // force container redimensioning // set_size_request (20, 20); // force container redimensioning
} }

View File

@ -21,12 +21,13 @@
#ifndef SIMULATION_WIDGET_HH #ifndef SIMULATION_WIDGET_HH
#define SIMULATION_WIDGET_HH 1 #define SIMULATION_WIDGET_HH 1
#include "cairo_widget.hh" #include "cairo_widget.hh"
#include <sgpemv2/history_observer.hh>
#include <sgpemv2/schedulable.hh> #include "sgpemv2/history_observer.hh"
#include <sgpemv2/simulation_observer.hh> #include "sgpemv2/schedulable.hh"
#include "sgpemv2/simulation_observer.hh"
#include <cairomm/pattern.h>
namespace sgpem namespace sgpem
{ {
@ -48,7 +49,7 @@ namespace sgpem
* *
* At the bottom of the graph there is a time line ruler. * 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. * to have an update signal (and related update) every simulation step.
* *
* \deprecated The class should implement only HistoryObserver * \deprecated The class should implement only HistoryObserver
@ -57,7 +58,7 @@ namespace sgpem
* \see HistoryObserver * \see HistoryObserver
*/ */
class SimulationWidget class SimulationWidget
: public SimulationObserver, public HistoryObserver, public CairoWidget : public SimulationObserver, public HistoryObserver, public CairoWidget
{ {
public: public:
/** /**
@ -77,7 +78,7 @@ namespace sgpem
/** /**
* \brief SimulationObserver's update method redefinition. * \brief SimulationObserver's update method redefinition.
* *
* Actually is a dummy method. * \deprecated Actually is a dummy method.
* *
* \param changed_simulation the observed Simulation * \param changed_simulation the observed Simulation
*/ */
@ -127,7 +128,7 @@ namespace sgpem
* \param ctx the cairo context to draw to * \param ctx the cairo context to draw to
* \see CairoWidget for more. * \see CairoWidget for more.
*/ */
void draw_widget(cairo_t* ctx); void draw_widget(Cairo::RefPtr<Cairo::Context>& ctx);
/** /**
* \brief calculated the needed drawing surface dimensions. * \brief calculated the needed drawing surface dimensions.
@ -136,8 +137,12 @@ namespace sgpem
* \param width the return parameter for desired width * \param width the return parameter for desired width
* \param height the return parameter for desired height * \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<Cairo::Context>& ctx, size_t& width, size_t& height);
/**
* \brief Adds the click events to the underlying Gdk::Window
*/
virtual void on_realize();
private: private:
@ -152,21 +157,21 @@ namespace sgpem
* *
* \param ctx the cairo context to draw to * \param ctx the cairo context to draw to
*/ */
void draw_names(cairo_t* ctx); void draw_names(Cairo::RefPtr<Cairo::Context>& ctx);
/** /**
* \brief Used internally by draw_widget to show the bars container grid. * \brief Used internally by draw_widget to show the bars container grid.
* *
* \param ctx the cairo context to draw to * \param ctx the cairo context to draw to
*/ */
void draw_grid(cairo_t* ctx); void draw_grid(Cairo::RefPtr<Cairo::Context>& ctx);
/** /**
* \brief Used internally by draw_widget to show processes/threads bars. * \brief Used internally by draw_widget to show processes/threads bars.
* *
* \param ctx the cairo context to draw to * \param ctx the cairo context to draw to
*/ */
void draw_bars(cairo_t* ctx); void draw_bars(Cairo::RefPtr<Cairo::Context>& ctx);
/** /**
* \brief Used internally by draw_widget to build the bars. * \brief Used internally by draw_widget to build the bars.
@ -178,7 +183,7 @@ namespace sgpem
* \param h height of rectangle * \param h height of rectangle
* \param state select the color to apply * \param state select the color to apply
*/ */
void draw_instant_rect(cairo_t* ctx, double x, double y, void draw_instant_rect(Cairo::RefPtr<Cairo::Context>& ctx, double x, double y,
double w, double h, sgpem::Schedulable::state state); double w, double h, sgpem::Schedulable::state state);
/** /**
@ -284,17 +289,17 @@ namespace sgpem
/** /**
* \brief Gradient used to draw ready processes/threads. * \brief Gradient used to draw ready processes/threads.
*/ */
cairo_pattern_t* _ready_process_gradient; Cairo::RefPtr<Cairo::Gradient> _ready_process_gradient;
/** /**
* \brief Gradient used to draw running processes/threads. * \brief Gradient used to draw running processes/threads.
*/ */
cairo_pattern_t* _running_process_gradient; Cairo::RefPtr<Cairo::Gradient> _running_process_gradient;
/** /**
* \brief Gradient used to draw blocked processes/threads. * \brief Gradient used to draw blocked processes/threads.
*/ */
cairo_pattern_t* _blocked_process_gradient; Cairo::RefPtr<Cairo::Gradient> _blocked_process_gradient;
/** /**
* Used to redraw partially the widget. * Used to redraw partially the widget.

View File

@ -56,10 +56,10 @@ namespace sgpem
protected: protected:
virtual bool on_button_press_event(GdkEventButton* event); virtual bool on_button_press_event(GdkEventButton* event);
void draw_widget(cairo_t* ctx); void draw_widget(Cairo::RefPtr<Cairo::Context>& ctx);
void change_scaling_mode(); 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<Cairo::Context>& ctx, size_t& width, size_t& height);
private: private:
int _desired_w; int _desired_w;
int _desired_h; int _desired_h;
@ -70,7 +70,7 @@ namespace sgpem
using namespace sgpem; using namespace sgpem;
TestWidget::TestWidget() TestWidget::TestWidget()
: Glib::ObjectBase("sgpem_TestWidget"), CairoWidget(), : Glib::ObjectBase("sgpem_TestWidget"), CairoWidget(),
_desired_w(200), _desired_h(300) _desired_w(200), _desired_h(300)
{ {
} }
@ -90,13 +90,13 @@ TestWidget::on_button_press_event(GdkEventButton*)
} }
void void
TestWidget::draw_widget(cairo_t* ctx) TestWidget::draw_widget(Cairo::RefPtr<Cairo::Context>& ctx)
{ {
// show line // show line
cairo_set_source_rgb(ctx, 0, 0, 0); ctx->set_source_rgb(0, 0, 0);
cairo_move_to(ctx, 0, 0); ctx->move_to(0, 0);
cairo_line_to(ctx, _desired_w, _desired_w); ctx->line_to(_desired_w, _desired_w);
cairo_stroke(ctx); ctx->stroke();
// NOTE: just to try // NOTE: just to try
CairoElements ce(ctx); CairoElements ce(ctx);
@ -138,20 +138,16 @@ TestWidget::draw_widget(cairo_t* ctx)
msg = "scaling_all = scale to stretch into client area"; msg = "scaling_all = scale to stretch into client area";
break; break;
} }
cairo_move_to(ctx, 10, 10); ctx->move_to(10, 10);
cairo_show_text(ctx,msg.c_str()); ctx->show_text(msg);
msg = "clic to change mode..."; msg = "clic to change mode...";
cairo_move_to(ctx, 10, 30); ctx->move_to(10, 30);
cairo_show_text(ctx,msg.c_str()); ctx->show_text(msg);
} }
void void
TestWidget::calc_drawing_size(cairo_t*, size_t& width, size_t& height) TestWidget::calc_drawing_size(Cairo::RefPtr<Cairo::Context>&, size_t& width, size_t& height)
{ {
width = _desired_w; width = _desired_w;
height = _desired_h; height = _desired_h;