# HG changeset patch # User John W. Eaton # Date 1292900218 18000 # Node ID 4996bcf3670691e425185fab07f375424486a62b # Parent f1a4db353da5aa9a9062dc0e27ff7961622ea190 avoid crash with invisible FLTK plots diff --git a/src/ChangeLog b/src/ChangeLog --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,15 @@ +2010-12-20 John W. Eaton + + * graphics.cc (graphics_handle::is_visible): New function. + * graphics.h.in: Provide decl. + * DLD-FUNCTIONS/fltk_backend.cc (figure_manager::do_update_canvas): + Don't show canvas if it is invisible. + (plot_window::uimenu_update): Don't call show_menubar if the + uimenu object is not visible. + (plot_window::plot_window): Don't show objects that are + not visible. Check handle for visibility, not just properties + of current object. + 2012-12-17 Konstantinos Poulios * graphics.h.in (class axes::properties): Tag xtickmode, ytickmode diff --git a/src/DLD-FUNCTIONS/fltk_backend.cc b/src/DLD-FUNCTIONS/fltk_backend.cc --- a/src/DLD-FUNCTIONS/fltk_backend.cc +++ b/src/DLD-FUNCTIONS/fltk_backend.cc @@ -621,6 +621,8 @@ { callback (window_close, static_cast (this)); + graphics_handle gh = fp.get___myhandle__ (); + begin (); { @@ -638,7 +640,7 @@ status_h); bottom->box(FL_FLAT_BOX); - ndim = calc_dimensions (gh_manager::get_object (fp.get___myhandle__ ())); + ndim = calc_dimensions (gh_manager::get_object (gh)); autoscale = new Fl_Button (0, @@ -702,7 +704,8 @@ // This allows us to have a valid OpenGL context right away. canvas->mode (FL_DEPTH | FL_DOUBLE ); - if (fp.is_visible ()) + + if (gh.is_visible ()) { show (); if (fp.get_currentaxes ().ok()) @@ -713,21 +716,28 @@ } end (); - status->show (); - autoscale->show (); - togglegrid->show (); - panzoom->show (); - rotate->show (); + if (gh.is_visible ()) + { + status->show (); + autoscale->show (); + togglegrid->show (); + panzoom->show (); + rotate->show (); + } set_name (); resizable (canvas); size_range (4*status_h, 2*status_h); gui_mode = (ndim == 3 ? rotate_zoom : pan_zoom); uimenu->add_to_menu (fp); - if (uimenu->items_to_show ()) - show_menubar (); - else - hide_menubar (); + + if (gh.is_visible ()) + { + if (uimenu->items_to_show ()) + show_menubar (); + else + hide_menubar (); + } } ~plot_window (void) @@ -827,12 +837,12 @@ break; } - if (uimenu->items_to_show ()) - show_menubar (); - else - hide_menubar (); + if (uimenu->items_to_show () && gh.is_visible ()) + show_menubar (); + else + hide_menubar (); - mark_modified(); + mark_modified(); } } @@ -1635,7 +1645,7 @@ wm_iterator win; if ((win = windows.find (idx)) != windows.end ()) { - if (ca.ok ()) + if (ca.is_visible ()) win->second->show_canvas (); else win->second->hide_canvas (); diff --git a/src/graphics.cc b/src/graphics.cc --- a/src/graphics.cc +++ b/src/graphics.cc @@ -759,6 +759,34 @@ // --------------------------------------------------------------------- +// An object is visible if its "visible" property is "on" and all its +// parents are also visible. + +bool +graphics_handle::is_visible (void) const +{ + if (ok ()) + { + graphics_object go = gh_manager::get_object (*this); + + if (go) + { + base_properties& go_props = go.get_properties (); + + if (go_props.is_visible ()) + { + graphics_handle gh = go.get_parent (); + + return gh.ok () ? gh.is_visible () : true; + } + else + return false; + } + } + + return false; +} + bool base_property::set (const octave_value& v, bool do_run ) { diff --git a/src/graphics.h.in b/src/graphics.h.in --- a/src/graphics.h.in +++ b/src/graphics.h.in @@ -110,6 +110,8 @@ bool ok (void) const { return ! xisnan (val); } + bool is_visible (void) const; + private: double val; };