# HG changeset patch # User John W. Eaton # Date 1320402313 14400 # Node ID 7ee18dc46bbb0719dc8964b918d6f4c2fdd7e48e # Parent 0aba6f90f5f8130d2644d18580905efed9716aca new and improved non-integer figure handles * waitbar.m: Pass NaN and "integerhandle" property to __go_figure__. * __init_fltk__.cc (OpenGL_fltk::renumber, plot_window::renumber, figure_manager::renumber_figure, figure_manager::do_renumber_figure): New functions. (figure_manager::hnd2idx): Don't declare double arg as const. Include figure number in error message. (fltk_graphics_toolkit::update): Handle ID_INTEGERHANDLE. * graphics.h.in, graphics.cc (gh_manager::do_get_handle): Rename from gh_manager::get_handle. (gh_manager::get_handle): New static function. (gh_manager::renumber_figure): New static function. (gh_manager::do_renumber_figure): New function. (figure::properties::set_integerhandle): New function. (figure::properties::integerhandle): Tag property declaration with S. (F__go_figure__): Intercept and handle integerhandle property here. * graphics.h.in (children_property::renumber): New function. (base_properties::init_integerhandle): New virtual function. (figure::properties::init_integerhandle): New function. (base_properties::renumber_child, base_properties::renumber_parent): New functions. diff --git a/scripts/plot/waitbar.m b/scripts/plot/waitbar.m --- a/scripts/plot/waitbar.m +++ b/scripts/plot/waitbar.m @@ -89,9 +89,10 @@ endif endif else - h = __go_figure__ (Inf, "position", [250, 500, 400, 100], + h = __go_figure__ (NaN, "position", [250, 500, 400, 100], "numbertitle", "off", "toolbar", "none", "menubar", "none", + "integerhandle", "off", "handlevisibility", "callback", varargin{:}); diff --git a/src/DLD-FUNCTIONS/__init_fltk__.cc b/src/DLD-FUNCTIONS/__init_fltk__.cc --- a/src/DLD-FUNCTIONS/__init_fltk__.cc +++ b/src/DLD-FUNCTIONS/__init_fltk__.cc @@ -134,6 +134,19 @@ redraw (); } + bool renumber (double new_number) + { + bool retval = false; + + if (number != new_number) + { + number = new_number; + retval = true; + } + + return retval; + } + private: double number; opengl_renderer renderer; @@ -741,9 +754,19 @@ delete uimenu; } - // FIXME -- this could change. double number (void) { return fp.get___myhandle__ ().value (); } + void renumber (double new_number) + { + if (canvas) + { + if (canvas->renumber (new_number)) + mark_modified (); + } + else + error ("unable to renumber figure"); + } + void print (const std::string& cmd, const std::string& term) { canvas->print (cmd, term); @@ -1449,6 +1472,12 @@ delete_window (str2idx (idx_str)); } + static void renumber_figure (const std::string& idx_str, double new_number) + { + if (instance_ok ()) + instance->do_renumber_figure (str2idx (idx_str), new_number); + } + static void toggle_window_visibility (int idx, bool is_visible) { if (instance_ok ()) @@ -1583,6 +1612,14 @@ } } + void do_renumber_figure (int idx, double new_number) + { + wm_iterator win = windows.find (idx); + + if (win != windows.end ()) + win->second->renumber (new_number); + } + void do_toggle_window_visibility (int idx, bool is_visible) { wm_iterator win = windows.find (idx); @@ -1707,7 +1744,7 @@ return -1; } - static int hnd2idx (const double h) + static int hnd2idx (double h) { graphics_object fobj = gh_manager::get_object (h); if (fobj && fobj.isa ("figure")) @@ -1716,7 +1753,7 @@ dynamic_cast (fobj.get_properties ()); return figprops2idx (fp); } - error ("figure_manager: H is not a figure"); + error ("figure_manager: H (= %g) is not a figure", h); return -1; } @@ -1844,6 +1881,15 @@ case figure::properties::ID_NUMBERTITLE: figure_manager::set_name (ov.string_value ()); break; + + case figure::properties::ID_INTEGERHANDLE: + { + std::string tmp = ov.string_value (); + graphics_handle gh = fp.get___myhandle__ (); + figure_manager::renumber_figure (tmp, gh.value ()); + figure_manager::set_name (tmp); + } + break; } } } diff --git a/src/graphics.cc b/src/graphics.cc --- a/src/graphics.cc +++ b/src/graphics.cc @@ -2108,7 +2108,7 @@ } graphics_handle -gh_manager::get_handle (bool integer_figure_handle) +gh_manager::do_get_handle (bool integer_figure_handle) { graphics_handle retval; @@ -2195,6 +2195,38 @@ } } +void +gh_manager::do_renumber_figure (const graphics_handle& old_gh, + const graphics_handle& new_gh) +{ + iterator p = handle_map.find (old_gh); + + if (p != handle_map.end ()) + { + graphics_object go = p->second; + + handle_map.erase (p); + + handle_map[new_gh] = go; + + if (old_gh.value () < 0) + handle_free_list.insert (std::ceil (old_gh.value ()) + - make_handle_fraction ()); + } + else + error ("graphics_handle::free: invalid object %g", old_gh.value ()); + + for (figure_list_iterator q = figure_list.begin (); + q != figure_list.end (); q++) + { + if (*q == old_gh) + { + *q = new_gh; + break; + } + } +} + gh_manager *gh_manager::instance = 0; static void @@ -2923,6 +2955,50 @@ gripe_set_invalid ("callbackobject"); } +void +figure::properties::set_integerhandle (const octave_value& val) +{ + if (! error_state) + { + if (integerhandle.set (val, true)) + { + bool int_fig_handle = integerhandle.is_on (); + + graphics_object this_go = gh_manager::get_object (__myhandle__); + + graphics_handle old_myhandle = __myhandle__; + + __myhandle__ = gh_manager::get_handle (int_fig_handle); + + gh_manager::renumber_figure (old_myhandle, __myhandle__); + + graphics_object parent_go = gh_manager::get_object (get_parent ()); + + base_properties& props = parent_go.get_properties (); + + props.renumber_child (old_myhandle, __myhandle__); + + Matrix kids = get_children (); + + for (octave_idx_type i = 0; i < kids.numel (); i++) + { + graphics_object kid = gh_manager::get_object (kids(i)); + + kid.get_properties ().renumber_parent (__myhandle__); + } + + graphics_handle cf = gh_manager::current_figure (); + + if (__myhandle__ == cf) + xset (0, "currentfigure", __myhandle__.value ()); + + this_go.update (integerhandle.get_id ()); + + mark_modified (); + } + } +} + // FIXME This should update monitorpositions and pointerlocation, but // as these properties are yet used, and so it doesn't matter that they // aren't set yet. @@ -8313,12 +8389,51 @@ } else { + bool int_fig_handle = true; + + octave_value_list xargs = args.splice (0, 1); + graphics_handle h = octave_NaN; - if (xisnan (val) || xisinf (val)) - h = gh_manager::make_graphics_handle ("figure", 0, - xisnan (val), - false, false); + if (xisnan (val)) + { + caseless_str p ("integerhandle"); + + for (int i = 0; i < xargs.length (); i++) + { + if (xargs(i).is_string () + && p.compare (xargs(i).string_value ())) + { + if (i < (xargs.length () - 1)) + { + std::string pval = xargs(i+1).string_value (); + + if (! error_state) + { + caseless_str on ("on"); + int_fig_handle = on.compare (pval); + xargs = xargs.splice (i, 2); + break; + } + } + } + } + + h = gh_manager::make_graphics_handle ("figure", 0, + int_fig_handle, + false, false); + + if (! int_fig_handle) + { + // We need to intiailize the integerhandle + // property without calling the set_integerhandle + // method, because doing that will generate a new + // handle value... + + graphics_object go = gh_manager::get_object (h); + go.get_properties ().init_integerhandle ("off"); + } + } else if (val > 0 && D_NINT (val) == val) h = gh_manager::make_figure_handle (val, false); @@ -8328,7 +8443,7 @@ gh_manager::push_figure (h); - xset (h, args.splice (0, 1)); + xset (h, xargs); xcreatefcn (h); xinitialize (h); diff --git a/src/graphics.h.in b/src/graphics.h.in --- a/src/graphics.h.in +++ b/src/graphics.h.in @@ -1711,6 +1711,21 @@ do_delete_children (clear); } + void renumber (graphics_handle old_gh, graphics_handle new_gh) + { + for (children_list_iterator p = children_list.begin (); + p != children_list.end (); p++) + { + if (*p == old_gh) + { + *p = new_gh.value (); + return; + } + } + + error ("children_list::renumber: child not found!"); + } + private: typedef std::list::iterator children_list_iterator; typedef std::list::const_iterator const_children_list_iterator; @@ -2273,6 +2288,11 @@ void override_defaults (base_graphics_object& obj); + virtual void init_integerhandle (const octave_value&) + { + panic_impossible (); + } + // Look through DEFAULTS for properties with given CLASS_NAME, and // apply them to the current object with set (virtual method). @@ -2377,6 +2397,16 @@ children.delete_children (clear); } + void renumber_child (graphics_handle old_gh, graphics_handle new_gh) + { + children.renumber (old_gh, new_gh); + } + + void renumber_parent (graphics_handle new_gh) + { + parent = new_gh; + } + static property_list::pval_map_type factory_defaults (void); // FIXME -- these functions should be generated automatically by the @@ -3075,6 +3105,11 @@ class OCTINTERP_API properties : public base_properties { public: + void init_integerhandle (const octave_value& val) + { + integerhandle = val; + } + void remove_child (const graphics_handle& h); void set_visible (const octave_value& val); @@ -3153,7 +3188,7 @@ bool_property dockcontrols , "off" bool_property doublebuffer , "on" string_property filename , "" - bool_property integerhandle , "on" + bool_property integerhandle S , "on" bool_property inverthardcopy , "off" callback_property keypressfcn , Matrix () callback_property keyreleasefcn , Matrix () @@ -5147,12 +5182,25 @@ return retval; } + static graphics_handle get_handle (bool integer_figure_handle) + { + return instance_ok () + ? instance->do_get_handle (integer_figure_handle) : graphics_handle (); + } + static void free (const graphics_handle& h) { if (instance_ok ()) instance->do_free (h); } + static void renumber_figure (const graphics_handle& old_gh, + const graphics_handle& new_gh) + { + if (instance_ok ()) + instance->do_renumber_figure (old_gh, new_gh); + } + static graphics_handle lookup (double val) { return instance_ok () ? instance->do_lookup (val) : graphics_handle (); @@ -5386,10 +5434,13 @@ // A flag telling whether event processing must be constantly on. int event_processing; - graphics_handle get_handle (bool integer_figure_handle); + graphics_handle do_get_handle (bool integer_figure_handle); void do_free (const graphics_handle& h); + void do_renumber_figure (const graphics_handle& old_gh, + const graphics_handle& new_gh); + graphics_handle do_lookup (double val) { iterator p = (xisnan (val) ? handle_map.end () : handle_map.find (val));