changeset 7367:600808df131c

[project @ 2008-01-14 08:58:02 by jwe]
author jwe
date Mon, 14 Jan 2008 08:58:02 +0000
parents 2a2115742cb5
children 68269e42f573
files liboctave/dMatrix.cc src/ChangeLog src/genprops.awk src/graphics.cc src/graphics.h.in
diffstat 5 files changed, 115 insertions(+), 17 deletions(-) [+]
line wrap: on
line diff
--- a/liboctave/dMatrix.cc	Sun Jan 13 06:46:39 2008 +0000
+++ b/liboctave/dMatrix.cc	Mon Jan 14 08:58:02 2008 +0000
@@ -2111,11 +2111,11 @@
       double dminmn = static_cast<double> (minmn);
       double dsmlsizp1 = static_cast<double> (smlsiz+1);
 #if defined (HAVE_LOG2)
-      double tmp = log2 (dminmn) / dsmlsizp1 + 1;
+      double tmp = log2 (dminmn / dsmlsizp1);
 #else
-      double tmp = log (dminmn) / dsmlsizp1 / log (2.0) + 1;
+      double tmp = log (dminmn / dsmlsizp1) / log (2.0);
 #endif
-      octave_idx_type nlvl = static_cast<int> (tmp);
+      octave_idx_type nlvl = static_cast<int> (tmp) + 1;
       if (nlvl < 0)
 	nlvl = 0;
 
--- a/src/ChangeLog	Sun Jan 13 06:46:39 2008 +0000
+++ b/src/ChangeLog	Mon Jan 14 08:58:02 2008 +0000
@@ -1,3 +1,17 @@
+2008-01-14  Michael Goffioul <michael.goffioul@gmail.com>
+
+	* genprops.awk (emit_get_callback): Pass user data to execute method.
+	* graphics.cc (execute_callback): New static function.
+	(callback_property::validate): Make it work.
+	(callback_property::execute): Make it work.
+	(gh_manager::do_free): Execute delete function here.
+	* graphics.h.in (callback_property::execute): Fix decl.
+	(base_properties::buttondownfcn, base_properties::createfcn,
+	base_properties::deletefcn, base_properties::userdata): Default
+	value is empty Matrix, not undefined octave_value object.
+	(base_properties::execute_createfcn): New function.
+	(base_properties::execute_deletefcn): New function.
+
 2007-12-13  Shai Ayal  <shaiay@users.sourceforge.net>
 
 	* graphics.h.in, graphics.cc (class base_properties): New
--- a/src/genprops.awk	Sun Jan 13 06:46:39 2008 +0000
+++ b/src/genprops.awk	Mon Jan 14 08:58:02 2008 +0000
@@ -176,10 +176,10 @@
 
 function emit_get_callback (i)
 {
-  printf ("  void execute_%s (void)", name[i]);
+  printf ("  void execute_%s (const octave_value& data = octave_value ()) const", name[i]);
   
   if (emit_get[i] == "definition")
-    printf (" { %s.execute (); }\n", name[i]);
+    printf (" { %s.execute (data); }\n", name[i]);
   else
     printf (";\n");
 
--- a/src/graphics.cc	Sun Jan 13 06:46:39 2008 +0000
+++ b/src/graphics.cc	Mon Jan 14 08:58:02 2008 +0000
@@ -137,6 +137,61 @@
   return retval;
 }
 
+// NOTE: "cb" is passed by value, because "function_value" method
+//       is non-const; passing "cb" by const-reference is not
+//       possible
+
+static void
+execute_callback (octave_value cb, const graphics_handle& h,
+                  const octave_value& data)
+{
+  octave_value_list args;
+  octave_function *fcn = 0;
+
+  args(0) = h.as_octave_value ();
+  args(1) = data;
+
+  BEGIN_INTERRUPT_WITH_EXCEPTIONS;
+
+  if (cb.is_function_handle ())
+    fcn = cb.function_value ();
+  else if (cb.is_string ())
+    {
+      std::string s = cb.string_value ();
+      octave_value f = symbol_table::find_function (s);
+      int status;
+
+      if (f.is_defined ())
+        fcn = f.function_value ();
+      else
+        {
+          eval_string (s, false, status);
+          return;
+        }
+    }
+  else if (cb.is_cell () && cb.length () > 0
+           && (cb.rows () == 1 || cb.columns () == 1)
+           && cb.cell_value ()(0).is_function_handle ())
+    {
+      Cell c = cb.cell_value ();
+
+      fcn = c(0).function_value ();
+      if (! error_state)
+        {
+          for (int i = 0; i < c.length () ; i++)
+            args(2+i) = c(i);
+        }
+    }
+  else
+    error ("trying to execute non-executable object (class = %s)",
+           cb.class_name ());
+
+  if (! error_state)
+    feval (fcn, args);
+  
+  END_INTERRUPT_WITH_EXCEPTIONS;
+}
+
 // ---------------------------------------------------------------------
 
 radio_values::radio_values (const std::string& opt_string)
@@ -335,16 +390,34 @@
 }
 
 bool
-callback_property::validate (const octave_value&) const
+callback_property::validate (const octave_value& v) const
 {
-  // FIXME: implement this
-  return true;
+  // case 1: function handle
+  // case 2: cell array with first element being a function handle
+  // case 3: string corresponding to known function name
+  // case 4: evaluatable string
+  // case 5: empty matrix
+
+  if (v.is_function_handle ())
+    return true;
+  else if (v.is_string ())
+    // complete validation will be done at execution-time
+    return true;
+  else if (v.is_cell () && v.length () > 0
+           && (v.rows() == 1 || v.columns () == 1)
+           && v.cell_value ()(0).is_function_handle ())
+    return true;
+  else if (v.is_empty ())
+    return true;
+
+  return false;
 }
 
 void
-callback_property::execute (void)
+callback_property::execute (const octave_value& data) const
 {
-  // FIXME: define correct signature and implement this
+  if (callback.is_defined () && ! callback.is_empty ())
+    execute_callback (callback, get_parent (), data);
 }
 
 // ---------------------------------------------------------------------
@@ -606,6 +679,8 @@
 
 	  if (p != handle_map.end ())
 	    {
+              p->second.get_properties ().execute_deletefcn ();
+
 	      handle_map.erase (p);
 
 	      if (h.value () < 0)
@@ -2065,9 +2140,13 @@
 
 	      graphics_object parent_obj = gh_manager::get_object (parent_h);
 
-	      parent_obj.remove_child (h);
+              // NOTE: free the handle before removing it from its parent's
+              //       children, such that the object's state is correct when
+              //       the deletefcn callback is executed
 
 	      gh_manager::free (h);
+
+	      parent_obj.remove_child (h);
 	    }
 	  else
 	    error ("delete: invalid graphics object (= %g)", val);
--- a/src/graphics.h.in	Sun Jan 13 06:46:39 2008 +0000
+++ b/src/graphics.h.in	Mon Jan 14 08:58:02 2008 +0000
@@ -796,7 +796,7 @@
                get_name ().c_str ());
     }
 
-  OCTINTERP_API void execute (void);
+  OCTINTERP_API void execute (const octave_value& data = octave_value ()) const;
 
   callback_property& operator = (const octave_value& val)
     {
@@ -967,17 +967,17 @@
       parent ("parent", mh, p), 
       children (),
       busyaction ("parent", mh, "{queue}|cancel"),
-      buttondownfcn ("buttondownfcn", mh, octave_value ()),
+      buttondownfcn ("buttondownfcn", mh, Matrix ()),
       clipping ("clipping", mh, true),
-      createfcn ("createfcn" , mh, octave_value ()),
-      deletefcn ("deletefcn", mh, octave_value ()),
+      createfcn ("createfcn" , mh, Matrix ()),
+      deletefcn ("deletefcn", mh, Matrix ()),
       handlevisibility ("handlevisibility", mh, "{on}|callback|off"),
       hittest ("hittest", mh, true),
       interruptible ("interruptible", mh, true),
       selected ("selected", mh, false),
       selectionhighlight ("selectionhighlight", mh, true),
       uicontextmenu ("uicontextmenu", mh, graphics_handle ()),
-      userdata ("userdata", mh, octave_value ()),
+      userdata ("userdata", mh, Matrix ()),
       visible ("visible", mh, true)
     { }
 
@@ -1025,8 +1025,14 @@
 
   std::string get_clipping (void) const { return clipping.current_value (); }
 
+  void execute_createfcn (const octave_value& data = octave_value ()) const
+    { createfcn.execute (data); }
+
   octave_value get_createfcn (void) const { return createfcn.get (); }
 
+  void execute_deletefcn (const octave_value& data = octave_value ()) const
+    { deletefcn.execute (data); }
+
   octave_value get_deletefcn (void) const { return deletefcn.get (); }
 
   std::string get_handlevisibility (void) const { return handlevisibility.current_value (); }
@@ -1719,7 +1725,6 @@
       {
         colormap.add_constraint (dim_vector (-1, 3));
       }
-
   };
 
 private: