changeset 13816:7ee18dc46bbb

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.
author John W. Eaton <jwe@octave.org>
date Fri, 04 Nov 2011 06:25:13 -0400
parents 0aba6f90f5f8
children b3e1f9ae64dc
files scripts/plot/waitbar.m src/DLD-FUNCTIONS/__init_fltk__.cc src/graphics.cc src/graphics.h.in
diffstat 4 files changed, 225 insertions(+), 12 deletions(-) [+]
line wrap: on
line diff
--- a/scripts/plot/waitbar.m	Fri Nov 04 05:51:53 2011 -0400
+++ b/scripts/plot/waitbar.m	Fri Nov 04 06:25:13 2011 -0400
@@ -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{:});
 
--- a/src/DLD-FUNCTIONS/__init_fltk__.cc	Fri Nov 04 05:51:53 2011 -0400
+++ b/src/DLD-FUNCTIONS/__init_fltk__.cc	Fri Nov 04 06:25:13 2011 -0400
@@ -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<figure::properties&> (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;
               }
           }
       }
--- a/src/graphics.cc	Fri Nov 04 05:51:53 2011 -0400
+++ b/src/graphics.cc	Fri Nov 04 06:25:13 2011 -0400
@@ -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);
 
--- a/src/graphics.h.in	Fri Nov 04 05:51:53 2011 -0400
+++ b/src/graphics.h.in	Fri Nov 04 06:25:13 2011 -0400
@@ -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<double>::iterator children_list_iterator;
   typedef std::list<double>::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));