Mercurial > octave-nkf
diff src/graphics.cc @ 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 | 74d64ead0cd7 |
line wrap: on
line diff
--- 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);