22#include "graph_viewport.h"
24#include "gvplugin_skillgui_papyrus.h"
36 Cairo::RefPtr<Cairo::SolidPattern> bp = Cairo::SolidPattern::create_rgb(1, 1, 1);
37 Papyrus::Paint::pointer pp = Papyrus::Paint::create(bp);
39 Papyrus::Canvas::pointer c = canvas();
40 c->set_scroll_anchor(Papyrus::SCROLL_ANCHOR_TOP_LEFT);
41 c->set_background(pp);
43 affine_ = Papyrus::AffineController::create();
45 translator_ = Papyrus::Translator::create();
46 add_controller(translator_);
54 bbw_ = bbh_ = pad_x_ = pad_y_ = 0.0;
55 translation_x_ = translation_y_ = 0.0;
59 Gtk::Window *w =
dynamic_cast<Gtk::Window *
>(get_toplevel());
61 fcd_ =
new Gtk::FileChooserDialog(*w,
"Save Graph", Gtk::FILE_CHOOSER_ACTION_SAVE);
62 fcd_->set_transient_for(*w);
64 fcd_ =
new Gtk::FileChooserDialog(
"Save Graph", Gtk::FILE_CHOOSER_ACTION_SAVE);
68 fcd_->add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
69 fcd_->add_button(Gtk::Stock::SAVE, Gtk::RESPONSE_OK);
71 Gtk::FileFilter *filter_pdf = Gtk::manage(
new Gtk::FileFilter());
72 filter_pdf->set_name(
"Portable Document Format (PDF)");
73 filter_pdf->add_pattern(
"*.pdf");
74 Gtk::FileFilter *filter_svg = Gtk::manage(
new Gtk::FileFilter());
76 filter_svg->set_name(
"Scalable Vector Graphic (SVG)");
77 filter_svg->add_pattern(
"*.svg");
78 Gtk::FileFilter *filter_png = Gtk::manage(
new Gtk::FileFilter());
80 filter_png->set_name(
"Portable Network Graphic (PNG)");
81 filter_png->add_pattern(
"*.png");
82 fcd_->add_filter(*filter_pdf);
83 fcd_->add_filter(*filter_svg);
84 fcd_->add_filter(*filter_png);
85 fcd_->set_filter(*filter_pdf);
87 gvplugin_skillgui_setup(gvc_,
this);
89 signal_size_allocate().connect_notify(
116 if (graph_fsm_ != fsm_name) {
117 translator_->set_translate(0, 0);
119 graph_fsm_ = fsm_name;
139 translator_->insert(d);
148 Papyrus::Gtk::Viewport::clear();
149 translator_->clear();
204 return update_graph_;
213 update_graph_ = update;
223 Gtk::Allocation alloc = get_allocation();
225 affine_->get_scale(sx, sy);
228 affine_->set_scale(sx, sy);
229 affine_->set_translate((alloc.get_width() - bbw_ * sx) / 2.0,
230 (alloc.get_height() - bbh_ * sy) / 2.0);
232 scale_override_ =
true;
242 affine_->get_scale(sx, sy);
243 if ((sx > 0.1) && (sy > 0.1)) {
244 Gtk::Allocation alloc = get_allocation();
247 affine_->set_scale(sx, sy);
248 affine_->set_translate((alloc.get_width() - bbw_ * sx) / 2.0,
249 (alloc.get_height() - bbh_ * sy) / 2.0);
251 scale_override_ =
true;
260 affine_->set_scale(scale_);
261 affine_->set_translate(pad_x_ + translation_x_, pad_y_ + translation_y_);
262 translator_->set_translate(0, 0);
263 scale_override_ =
false;
272 affine_->set_scale(1.0);
274 affine_->set_translate(pad_x_ + translation_x_, pad_y_ + translation_y_);
276 affine_->set_translate(pad_x_, pad_y_);
278 scale_override_ =
true;
287 return scale_override_;
293Papyrus::AffineController::pointer
303 Gtk::Window *w =
dynamic_cast<Gtk::Window *
>(get_toplevel());
305 int result = fcd_->run();
306 if (result == Gtk::RESPONSE_OK) {
307 double old_scale_x, old_scale_y, old_translate_x, old_translate_y;
308 affine_->get_scale(old_scale_x, old_scale_y);
309 affine_->get_translate(old_translate_x, old_translate_y);
310 affine_->set_scale(1);
311 affine_->set_translate(pad_x_, pad_y_);
313 Papyrus::Canvas::pointer c = canvas();
315 Cairo::RefPtr<Cairo::Surface> surface;
317 std::string filename = fcd_->get_filename();
318 if (!filename.empty()) {
319 bool write_to_png =
false;
320 Gtk::FileFilter *f = fcd_->get_filter();
321 if (f->get_name().find(
"PDF") != Glib::ustring::npos) {
322 surface = Cairo::PdfSurface::create(filename, bbw_, bbh_);
323 }
else if (f->get_name().find(
"SVG") != Glib::ustring::npos) {
324 surface = Cairo::SvgSurface::create(filename, bbw_, bbh_);
325 }
else if (f->get_name().find(
"PNG") != Glib::ustring::npos) {
326 surface = Cairo::ImageSurface::create(Cairo::FORMAT_ARGB32, bbw_, bbh_);
331 Cairo::RefPtr<Cairo::Context> context = Cairo::Context::create(surface);
334 surface->write_to_png(filename);
339 Gtk::MessageDialog md(*w,
345 md.set_title(
"Invalid File Name");
349 affine_->set_scale(old_scale_x, old_scale_y);
350 affine_->set_translate(old_translate_x, old_translate_y);
363 Papyrus::Canvas::pointer c = canvas();
364#ifdef HAVE_TIMS_PAPYRUS_PATCHES
365 c->set_redraw_enabled(
false);
367 Agraph_t *g = agmemread((
char *)graph_.c_str());
369 gvLayout(gvc_, g, (
char *)
"dot");
370 gvRender(gvc_, g, (
char *)
"skillgui", NULL);
371 gvFreeLayout(gvc_, g);
376#ifdef HAVE_TIMS_PAPYRUS_PATCHES
377 c->set_redraw_enabled(
true);
387 if (scale_override_) {
388 Gtk::Allocation alloc = get_allocation();
391 affine_->get_scale(sx, sy);
392 affine_->set_translate(((alloc.get_width() - bbw_ * sx) / 2.0) + pad_x_,
393 ((alloc.get_height() - bbh_ * sy) / 2.0) + pad_y_);
void set_graph(const std::string &graph)
Set graph.
~SkillGuiGraphViewport()
Destructor.
void set_gvjob(GVJ_t *job)
Set current Graphviz job.
bool scale_override()
Check if scale override is enabled.
void render()
Render current graph.
void set_update_graph(bool update)
Set if the graph should be updated on new data.
void zoom_fit()
Zoom to fit.
Papyrus::AffineController::pointer get_affine()
Get scaler.
void save()
Render current graph.
void set_graph_fsm(const std::string &fsm_name)
Set graph's FSM name.
void set_pad(double pad_x, double pad_y)
Set padding.
virtual void clear()
Clear all drawables.
void set_bb(double bbw, double bbh)
Set bounding box.
SkillGuiGraphViewport()
Constructor.
void on_expose(GdkEventExpose *event)
Called on explose.
bool get_update_graph()
Check if graph is being updated.
void zoom_reset()
Zoom reset.
void add_drawable(Papyrus::Drawable::pointer d)
Add a drawable.
void set_scale(double scale)
Set scale.
void set_translation(double tx, double ty)
Set translation.