# HG changeset patch # User John W. Eaton # Date 1219771455 14400 # Node ID 75c99d3f97d7faf23e37a300cecfb115346af9b9 # Parent ca39c21fa4b88701efcc11599d75212734b8c4c6 Octave to backend notification scheme diff -r ca39c21fa4b8 -r 75c99d3f97d7 src/ChangeLog --- a/src/ChangeLog Tue Aug 26 13:23:27 2008 -0400 +++ b/src/ChangeLog Tue Aug 26 13:24:15 2008 -0400 @@ -1,3 +1,57 @@ +2008-08-26 Michael Goffioul + + * DLD_FUNCTIONS/fltk_backend.cc (fltk_backend::close_figure): Remove. + (fltk_backend::object_destroyed, fltk_backend::property_changed): New + methods. + * genprops.awk (emit_declarations): Generate "enum" property fields. + (emit_sources): Emit set_id calls. + * graphics.h.in (base_property::id): New field. + (base_property::base_property): Initialize it. + (base_property::get_id, base_property::set_id): Add accessors. + (property::get_id, property::set_id): Likewise. + (base_graphics_backend::close_figure, graphics_backend::close_figure): + Remove methods. + (base_graphics_backend::redraw_figure, + base_graphics_backend::print_figure, graphics_backend::redraw_figure, + graphics_backend::print_figure): Change graphics_handle argument into + graphics_object. + (base_graphics_backend::property_changed, + base_graphics_backend::object_created, + base_graphics_backend::object_destroyed, + graphics_backend::property_changed, graphics_backend::object_created, + graphics_backend::object_destroyed): New signature with + graphics_object argument. + (base_properties::base_properties): Add set_id calls. + (class base_properties): Add "enum" property fields. + (root_figure::properties::remove_child): Add overloaded method. + (figure::properties::close): Remove. + (figure::properties::set_backend): Call object_destroyed instead of + close. + (figure::~figure): Remove close call. + (figure::properties::get_title): New method. + * graphics.cc (base_property::set): Call property_changed only for + valid id (>=0); Use graphics_object argument. + (gh_manager::do_free): Call object_destroyed with graphics_object + argument. + (base_graphics_backend::property_changed, + base_graphics_backend::object_created, + base_graphics_object::object_destroyed): Implement wrappers for + graphics_handle argument case. + (gnuplot_backend::close_figure): Remove. + (gnuplot_backend::object_destroyed, + gnuplot_backend::property_changed): New methods. + (gnuplot_backend::redraw_figure, gnuplot_backend::print_figure): + Change graphics_handle argument to graphics_object. + (root_figure::properties::remove_child): Add. + (figure::properties::close): Remove. + (figure::properties::set_position): Do not call set_figure_position. + (figure::properties::get_title): New method. + (gh_manager::do_make_graphics_handle): Call object_created with + a graphics_object argument. + (gh_manager::do_make_figure_handle): Likewise. + (Fdrawnow): Call redraw_figure and print_figure with a graphics_object + argument. + 2008-08-26 Maciek Gajewski * graphics.h.in (base_property::set): Remove inline implementation. diff -r ca39c21fa4b8 -r 75c99d3f97d7 src/DLD-FUNCTIONS/fltk_backend.cc --- a/src/DLD-FUNCTIONS/fltk_backend.cc Tue Aug 26 13:23:27 2008 -0400 +++ b/src/DLD-FUNCTIONS/fltk_backend.cc Tue Aug 26 13:24:15 2008 -0400 @@ -696,10 +696,31 @@ bool is_valid (void) const { return true; } - void close_figure (const octave_value& ov) const + void object_destroyed (const graphics_object& go) + { + if (go.isa ("figure")) + { + octave_value ov = go.get (caseless_str ("__plot_stream__")); + figure_manager::Instance ().delete_window (ov.string_value ()); + } + } + + void property_changed (const graphics_object& go, int id) { - if (ov.is_string ()) - figure_manager::Instance ().delete_window (ov.string_value ()); + if (go.isa ("figure")) + { + octave_value ov = go.get (caseless_str ("__plot_stream__")); + + if (! ov.is_empty ()) + { + switch (id) + { + case base_properties::VISIBLE: + // FIXME: something to do here + break; + } + } + } } void redraw_figure (const graphics_handle& fh) const diff -r ca39c21fa4b8 -r 75c99d3f97d7 src/genprops.awk --- a/src/genprops.awk Tue Aug 26 13:23:27 2008 -0400 +++ b/src/genprops.awk Tue Aug 26 13:24:15 2008 -0400 @@ -260,6 +260,18 @@ if (idx > 0) print "\npublic:\n"; + + if (idx > 0) + { + printf (" enum\n {"); + for (i = 1; i <= idx; i++) + { + printf ("%s\n %s = %d", (i == 1 ? "" : ","), toupper(name[i]), pcount); + pcount++; + } + printf ("\n };\n\n"); + pcount = (int(pcount/1000)+1)*1000; + } for (i = 1; i <= idx; i++) { @@ -325,7 +337,8 @@ printf (" set_%smode (\"manual\");\n", name[i]); if (has_builtin_listeners) printf (" %s.run_listeners (POSTSET);\n", name[i]); - printf (" mark_modified ();\n }\n }\n\n"); + printf (" mark_modified ();\n"); + printf (" }\n }\n\n"); } else printf (";\n\n"); @@ -380,6 +393,7 @@ for (i = 1; i <= idx; i++) { ## printf (" insert_static_property (\"%s\", %s);\n", name[i], name[i]) >> filename; + printf (" %s.set_id (%s);\n", name[i], toupper(name[i])) >> filename; if (hidden[i]) printf (" %s.set_hidden (true);\n", name[i]) >> filename; } @@ -492,6 +506,7 @@ filename = "graphics-props.cc"; printf ("// DO NOT EDIT! Generated automatically by genprops.awk.\n\n"); printf ("// DO NOT EDIT! Generated automatically by genprops.awk.\n\n") > filename; + pcount = 1000; } /BEGIN_PROPERTIES\(.*\)/ { diff -r ca39c21fa4b8 -r 75c99d3f97d7 src/graphics.cc --- a/src/graphics.cc Tue Aug 26 13:23:27 2008 -0400 +++ b/src/graphics.cc Tue Aug 26 13:24:15 2008 -0400 @@ -33,6 +33,7 @@ #include #include #include +#include #include "file-ops.h" #include "file-stat.h" @@ -464,12 +465,15 @@ do_set (v); // notify backend - graphics_object go = gh_manager::get_object (parent); - if (go) + if (id >= 0) { - graphics_backend backend = go.get_backend(); - if (backend) - backend.property_changed (parent, name); + graphics_object go = gh_manager::get_object (parent); + if (go) + { + graphics_backend backend = go.get_backend(); + if (backend) + backend.property_changed (go, id); + } } // run listeners @@ -1189,13 +1193,16 @@ if (p != handle_map.end ()) { + // FIXME: should we explicitely free all children first? + // => call delete_children () ? + p->second.get_properties ().set_beingdeleted (true); p->second.get_properties ().execute_deletefcn (); // notify backend graphics_backend backend = p->second.get_backend (); if (backend) - backend.object_destroyed (h); + backend.object_destroyed (p->second); // note - this will be valid only for first explicitly deleted object. // All his children will have unknown backend then. @@ -1342,6 +1349,31 @@ // --------------------------------------------------------------------- +void +base_graphics_backend::property_changed (const graphics_handle& h, int id) +{ + graphics_object go = gh_manager::get_object (h); + + property_changed (go, id); +} + +void +base_graphics_backend::object_created (const graphics_handle& h) +{ + graphics_object go = gh_manager::get_object (h); + + object_created (go); +} + +void +base_graphics_backend::object_destroyed (const graphics_handle& h) +{ + graphics_object go = gh_manager::get_object (h); + + object_destroyed (go); +} +// --------------------------------------------------------------------- + static int compare (const void *a_arg, const void *b_arg) { @@ -1763,8 +1795,76 @@ ~gnuplot_backend (void) { } bool is_valid (void) const { return true; } - - void close_figure (const octave_value& pstream) const + + void object_destroyed (const graphics_object& go) + { + if (go.isa ("figure")) + { + const figure::properties& props = + dynamic_cast (go.get_properties ()); + + send_quit (props.get___plot_stream__ ()); + } + } + + void property_changed (const graphics_object& go, int id) + { + if (go.isa ("figure")) + { + graphics_object obj (go); + + figure::properties& props = + dynamic_cast (obj.get_properties ()); + + switch (id) + { + case base_properties::VISIBLE: + if (! props.is_visible ()) + { + send_quit (props.get___plot_stream__ ()); + props.set___plot_stream__ (Matrix ()); + props.set___enhanced__ (false); + } + break; + } + } + } + + void redraw_figure (const graphics_object& go) const + { + octave_value_list args; + args(0) = go.get_handle ().as_octave_value (); + feval ("gnuplot_drawnow", args); + } + + void print_figure (const graphics_object& go, const std::string& term, + const std::string& file, bool mono, + const std::string& debug_file) const + { + octave_value_list args; + if (! debug_file.empty ()) + args(4) = debug_file; + args(3) = mono; + args(2) = file; + args(1) = term; + args(0) = go.get_handle ().as_octave_value (); + feval ("gnuplot_drawnow", args); + } + + Matrix get_canvas_size (const graphics_handle&) const + { + Matrix sz (1, 2, 0.0); + return sz; + } + + double get_screen_resolution (void) const + { return 72.0; } + + Matrix get_screen_size (void) const + { return Matrix (1, 2, 0.0); } + +private: + void send_quit (const octave_value& pstream) const { if (! pstream.is_empty()) { @@ -1787,39 +1887,6 @@ } } } - - void redraw_figure (const graphics_handle& fh) const - { - octave_value_list args; - args(0) = fh.as_octave_value (); - feval ("gnuplot_drawnow", args); - } - - void print_figure (const graphics_handle& fh, const std::string& term, - const std::string& file, bool mono, - const std::string& debug_file) const - { - octave_value_list args; - if (! debug_file.empty ()) - args(4) = debug_file; - args(3) = mono; - args(2) = file; - args(1) = term; - args(0) = fh.as_octave_value (); - feval ("gnuplot_drawnow", args); - } - - Matrix get_canvas_size (const graphics_handle&) const - { - Matrix sz (1, 2, 0.0); - return sz; - } - - double get_screen_resolution (void) const - { return 72.0; } - - Matrix get_screen_size (void) const - { return Matrix (1, 2, 0.0); } }; graphics_backend @@ -1903,6 +1970,18 @@ gripe_set_invalid ("callbackobject"); } +void +root_figure::properties::remove_child (const graphics_handle& gh) +{ + gh_manager::pop_figure (gh); + + graphics_handle cf = gh_manager::current_figure (); + + xset (0, "currentfigure", cf.value ()); + + base_properties::remove_child (gh); +} + property_list root_figure::factory_properties = root_figure::init_factory_properties (); @@ -1936,22 +2015,6 @@ } } -void -figure::properties::close (bool pop) -{ - if (backend) - backend.close_figure (get___plot_stream__ ()); - - if (pop) - { - gh_manager::pop_figure (__myhandle__); - - graphics_handle cf = gh_manager::current_figure (); - - xset (0, "currentfigure", cf.value ()); - } -} - Matrix figure::properties::get_boundingbox (bool) const { @@ -1999,9 +2062,6 @@ if (old_bb != new_bb) { - // FIXME: maybe this should be converted into a more generic - // call like "update_gui (this)" - get_backend ().set_figure_position (__myhandle__, new_bb); if (old_bb(2) != new_bb(2) || old_bb(3) != new_bb(3)) { execute_resizefcn (); @@ -2013,6 +2073,24 @@ } } +std::string +figure::properties::get_title (void) const +{ + if (is_numbertitle ()) + { + std::ostringstream os; + std::string name = get_name (); + + os << "Figure " << __myhandle__.value (); + if (! name.empty ()) + os << ": " << get_name (); + + return os.str (); + } + else + return get_name (); +} + octave_value figure::get_default (const caseless_str& name) const { @@ -3548,14 +3626,16 @@ if (go) { - handle_map[h] = graphics_object (go); + graphics_object obj (go); + + handle_map[h] = obj; if (do_createfcn) go->get_properties ().execute_createfcn (); // notify backend graphics_backend backend = go->get_backend (); if (backend) - backend.object_created (h); + backend.object_created (obj); } else error ("gh_manager::do_make_graphics_handle: invalid object type `%s'", @@ -3570,12 +3650,14 @@ graphics_handle h = val; base_graphics_object* go = new figure (h, 0); - handle_map[h] = graphics_object (go); + graphics_object obj (go); + + handle_map[h] = obj; // notify backend graphics_backend backend = go->get_backend (); if (backend) - backend.object_created (h); + backend.object_created (obj); return h; } @@ -4563,16 +4645,11 @@ { gh_manager::unlock (); - fprops.get_backend ().redraw_figure (h); + fprops.get_backend ().redraw_figure (go); gh_manager::lock (); } - else if (! fprops.get___plot_stream__ ().is_empty ()) - { - fprops.close (false); - fprops.set___plot_stream__ (Matrix ()); - fprops.set___enhanced__ (false); - } + fprops.set_modified (false); } } @@ -4641,7 +4718,7 @@ gh_manager::unlock (); go.get_backend () - .print_figure (h, term, file, mono, debug_file); + .print_figure (go, term, file, mono, debug_file); gh_manager::lock (); } diff -r ca39c21fa4b8 -r 75c99d3f97d7 src/graphics.h.in --- a/src/graphics.h.in Tue Aug 26 13:23:27 2008 -0400 +++ b/src/graphics.h.in Tue Aug 26 13:24:15 2008 -0400 @@ -348,13 +348,13 @@ friend class property; public: - base_property (void) : count (1) { } + base_property (void) : id (-1), count (1) { } base_property (const std::string& s, const graphics_handle& h) - : count (1), name (s), parent (h), hidden (false) { } + : id (-1), count (1), name (s), parent (h), hidden (false) { } base_property (const base_property& p) - : count (1), name (p.name), parent (p.parent), hidden (p.hidden) { } + : id (-1), count (1), name (p.name), parent (p.parent), hidden (p.hidden) { } virtual ~base_property (void) { } @@ -372,6 +372,10 @@ void set_hidden (bool flag) { hidden = flag; } + int get_id (void) const { return id; } + + void set_id (int d) { id = d; } + // Sets property value, notifies backend. // If do_run is true, runs associated listeners. void set (const octave_value& v, bool do_run = true); @@ -409,6 +413,7 @@ typedef std::map::const_iterator listener_map_const_iterator; private: + int id; int count; std::string name; graphics_handle parent; @@ -1190,6 +1195,12 @@ void set_hidden (bool flag) { rep->set_hidden (flag); } + int get_id (void) const + { return rep->get_id (); } + + void set_id (int d) + { rep->set_id (d); } + octave_value get (void) const { return rep->get (); } @@ -1299,6 +1310,7 @@ // --------------------------------------------------------------------- class graphics_backend; +class graphics_object; class base_graphics_backend { @@ -1315,13 +1327,10 @@ virtual bool is_valid (void) const { return false; } - virtual void close_figure (const octave_value& /*pstream*/) const - { gripe_invalid ("close_figure"); } - - virtual void redraw_figure (const graphics_handle&) const + virtual void redraw_figure (const graphics_object&) const { gripe_invalid ("redraw_figure"); } - virtual void print_figure (const graphics_handle&, const std::string&, + virtual void print_figure (const graphics_object&, const std::string&, const std::string&, bool, const std::string& = "") const { gripe_invalid ("print_figure"); } @@ -1344,21 +1353,24 @@ return Matrix (1, 2, 0.0); } - virtual void set_figure_position (const graphics_handle&, const Matrix&) const - { gripe_invalid ("set_figure_position"); } - // Called when graphics object using this backend changes it's property. - virtual void property_changed (const graphics_handle&, const std::string&) + virtual void property_changed (const graphics_object&, int) { gripe_invalid ("property_changed"); } + + void property_changed (const graphics_handle&, int); // Called when new object using this backend is created. - virtual void object_created (const graphics_handle&) + virtual void object_created (const graphics_object&) { gripe_invalid ("object_created"); } + void object_created (const graphics_handle&); + // Called when object using this backend is destroyed. - virtual void object_destroyed (const graphics_handle&) + virtual void object_destroyed (const graphics_object&) { gripe_invalid ("object_destroyed"); } + void object_destroyed (const graphics_handle&); + private: std::string name; int count; @@ -1416,16 +1428,13 @@ std::string get_name (void) const { return rep->get_name (); } - void close_figure (const octave_value& pstream) const - { rep->close_figure (pstream); } - - void redraw_figure (const graphics_handle& fh) const - { rep->redraw_figure (fh); } + void redraw_figure (const graphics_object& go) const + { rep->redraw_figure (go); } - void print_figure (const graphics_handle& fh, const std::string& term, + void print_figure (const graphics_object& go, const std::string& term, const std::string& file, bool mono, const std::string& debug_file = "") const - { rep->print_figure (fh, term, file, mono, debug_file); } + { rep->print_figure (go, term, file, mono, debug_file); } Matrix get_canvas_size (const graphics_handle& fh) const { return rep->get_canvas_size (fh); } @@ -1436,20 +1445,26 @@ Matrix get_screen_size (void) const { return rep->get_screen_size (); } - void set_figure_position (const graphics_handle& h, const Matrix& pos) const - { rep->set_figure_position (h, pos); } + // Notifies backend that object't property has changed. + void property_changed (const graphics_object& go, int id) + { rep->property_changed (go, id); } - // Notifies backend that object't property has changed. - void property_changed (const graphics_handle& h, const std::string& prop) - { rep->property_changed (h, prop); } + void property_changed (const graphics_handle& h, int id) + { rep->property_changed (h, id); } // Notifies backend that new object was created. + void object_created (const graphics_object& go) + { rep->object_created (go); } + void object_created (const graphics_handle& h) { rep->object_created (h); } // Notifies backend that object was destroyed. // This is called only for explicitly deleted object. Children are // deleted implicitly and backend isn't notified. + void object_destroyed (const graphics_object& go) + { rep->object_destroyed (go); } + void object_destroyed (const graphics_handle& h) { rep->object_destroyed (h); } @@ -1482,7 +1497,6 @@ return m; } - private: base_graphics_backend *rep; @@ -1523,7 +1537,23 @@ __modified__ ("__modified__", mh, true), __myhandle__ (mh), uicontextmenu ("uicontextmenu", mh, graphics_handle ()) - { } + { + beingdeleted.set_id (BEINGDELETED); + busyaction.set_id (BUSYACTION); + buttondownfcn.set_id (BUTTONDOWNFCN); + clipping.set_id (CLIPPING); + createfcn.set_id (CREATEFCN); + deletefcn.set_id (DELETEFCN); + handlevisibility.set_id (HANDLEVISIBILITY); + hittest.set_id (HITTEST); + interruptible.set_id (INTERRUPTIBLE); + parent.set_id (PARENT); + selected.set_id (SELECTED); + selectionhighlight.set_id (SELECTIONHIGHLIGHT); + tag.set_id (TAG); + userdata.set_id (USERDATA); + visible.set_id (VISIBLE); + } virtual ~base_properties (void) { } @@ -1787,7 +1817,27 @@ virtual bool is_zliminclude (void) const { return false; } virtual bool is_climinclude (void) const { return false; } virtual bool is_aliminclude (void) const { return false; } - + + enum + { + BEINGDELETED = 0, + BUSYACTION, + BUTTONDOWNFCN, + // CHILDREN, + CLIPPING, + CREATEFCN, + DELETEFCN, + HANDLEVISIBILITY, + HITTEST, + INTERRUPTIBLE, + PARENT, + SELECTED, + SELECTIONHIGHLIGHT, + TAG, + USERDATA, + VISIBLE + }; + protected: // properties common to all objects bool_property beingdeleted; @@ -2195,6 +2245,8 @@ class OCTINTERP_API properties : public base_properties { public: + void remove_child (const graphics_handle& h); + // See the genprops.awk script for an explanation of the // properties declarations. @@ -2311,8 +2363,6 @@ class OCTINTERP_API properties : public base_properties { public: - void close (bool pop = true); - void set_visible (const octave_value& val); graphics_backend get_backend (void) const @@ -2325,7 +2375,8 @@ void set_backend (const graphics_backend& b) { - close (false); + if (backend) + backend.object_destroyed (__myhandle__); backend = b; __backend__ = b.get_name (); __plot_stream__ = Matrix (); @@ -2359,6 +2410,8 @@ void set_boundingbox (const Matrix& bb); + std::string get_title (void) const; + // See the genprops.awk script for an explanation of the // properties declarations. @@ -2444,7 +2497,6 @@ ~figure (void) { xproperties.delete_children (); - xproperties.close (); } void override_defaults (base_graphics_object& obj)