comparison src/graphics.cc @ 8059:75c99d3f97d7

Octave to backend notification scheme
author John W. Eaton <jwe@octave.org>
date Tue, 26 Aug 2008 13:24:15 -0400
parents ca39c21fa4b8
children f819e8992367
comparison
equal deleted inserted replaced
8058:ca39c21fa4b8 8059:75c99d3f97d7
31 #include <algorithm> 31 #include <algorithm>
32 #include <list> 32 #include <list>
33 #include <map> 33 #include <map>
34 #include <set> 34 #include <set>
35 #include <string> 35 #include <string>
36 #include <sstream>
36 37
37 #include "file-ops.h" 38 #include "file-ops.h"
38 #include "file-stat.h" 39 #include "file-stat.h"
39 40
40 #include "cmd-edit.h" 41 #include "cmd-edit.h"
462 base_property::set (const octave_value& v, bool do_run ) 463 base_property::set (const octave_value& v, bool do_run )
463 { 464 {
464 do_set (v); 465 do_set (v);
465 466
466 // notify backend 467 // notify backend
467 graphics_object go = gh_manager::get_object (parent); 468 if (id >= 0)
468 if (go) 469 {
469 { 470 graphics_object go = gh_manager::get_object (parent);
470 graphics_backend backend = go.get_backend(); 471 if (go)
471 if (backend) 472 {
472 backend.property_changed (parent, name); 473 graphics_backend backend = go.get_backend();
474 if (backend)
475 backend.property_changed (go, id);
476 }
473 } 477 }
474 478
475 // run listeners 479 // run listeners
476 if (do_run && ! error_state) 480 if (do_run && ! error_state)
477 run_listeners (POSTSET); 481 run_listeners (POSTSET);
1187 { 1191 {
1188 iterator p = handle_map.find (h); 1192 iterator p = handle_map.find (h);
1189 1193
1190 if (p != handle_map.end ()) 1194 if (p != handle_map.end ())
1191 { 1195 {
1196 // FIXME: should we explicitely free all children first?
1197 // => call delete_children () ?
1198
1192 p->second.get_properties ().set_beingdeleted (true); 1199 p->second.get_properties ().set_beingdeleted (true);
1193 p->second.get_properties ().execute_deletefcn (); 1200 p->second.get_properties ().execute_deletefcn ();
1194 1201
1195 // notify backend 1202 // notify backend
1196 graphics_backend backend = p->second.get_backend (); 1203 graphics_backend backend = p->second.get_backend ();
1197 if (backend) 1204 if (backend)
1198 backend.object_destroyed (h); 1205 backend.object_destroyed (p->second);
1199 // note - this will be valid only for first explicitly deleted object. 1206 // note - this will be valid only for first explicitly deleted object.
1200 // All his children will have unknown backend then. 1207 // All his children will have unknown backend then.
1201 1208
1202 handle_map.erase (p); 1209 handle_map.erase (p);
1203 1210
1338 { 1345 {
1339 graphics_object obj = gh_manager::get_object (h); 1346 graphics_object obj = gh_manager::get_object (h);
1340 obj.get_properties ().execute_createfcn (); 1347 obj.get_properties ().execute_createfcn ();
1341 } 1348 }
1342 1349
1350 // ---------------------------------------------------------------------
1351
1352 void
1353 base_graphics_backend::property_changed (const graphics_handle& h, int id)
1354 {
1355 graphics_object go = gh_manager::get_object (h);
1356
1357 property_changed (go, id);
1358 }
1359
1360 void
1361 base_graphics_backend::object_created (const graphics_handle& h)
1362 {
1363 graphics_object go = gh_manager::get_object (h);
1364
1365 object_created (go);
1366 }
1367
1368 void
1369 base_graphics_backend::object_destroyed (const graphics_handle& h)
1370 {
1371 graphics_object go = gh_manager::get_object (h);
1372
1373 object_destroyed (go);
1374 }
1343 // --------------------------------------------------------------------- 1375 // ---------------------------------------------------------------------
1344 1376
1345 static int 1377 static int
1346 compare (const void *a_arg, const void *b_arg) 1378 compare (const void *a_arg, const void *b_arg)
1347 { 1379 {
1761 : base_graphics_backend ("gnuplot") { } 1793 : base_graphics_backend ("gnuplot") { }
1762 1794
1763 ~gnuplot_backend (void) { } 1795 ~gnuplot_backend (void) { }
1764 1796
1765 bool is_valid (void) const { return true; } 1797 bool is_valid (void) const { return true; }
1766 1798
1767 void close_figure (const octave_value& pstream) const 1799 void object_destroyed (const graphics_object& go)
1800 {
1801 if (go.isa ("figure"))
1802 {
1803 const figure::properties& props =
1804 dynamic_cast<const figure::properties&> (go.get_properties ());
1805
1806 send_quit (props.get___plot_stream__ ());
1807 }
1808 }
1809
1810 void property_changed (const graphics_object& go, int id)
1811 {
1812 if (go.isa ("figure"))
1813 {
1814 graphics_object obj (go);
1815
1816 figure::properties& props =
1817 dynamic_cast<figure::properties&> (obj.get_properties ());
1818
1819 switch (id)
1820 {
1821 case base_properties::VISIBLE:
1822 if (! props.is_visible ())
1823 {
1824 send_quit (props.get___plot_stream__ ());
1825 props.set___plot_stream__ (Matrix ());
1826 props.set___enhanced__ (false);
1827 }
1828 break;
1829 }
1830 }
1831 }
1832
1833 void redraw_figure (const graphics_object& go) const
1834 {
1835 octave_value_list args;
1836 args(0) = go.get_handle ().as_octave_value ();
1837 feval ("gnuplot_drawnow", args);
1838 }
1839
1840 void print_figure (const graphics_object& go, const std::string& term,
1841 const std::string& file, bool mono,
1842 const std::string& debug_file) const
1843 {
1844 octave_value_list args;
1845 if (! debug_file.empty ())
1846 args(4) = debug_file;
1847 args(3) = mono;
1848 args(2) = file;
1849 args(1) = term;
1850 args(0) = go.get_handle ().as_octave_value ();
1851 feval ("gnuplot_drawnow", args);
1852 }
1853
1854 Matrix get_canvas_size (const graphics_handle&) const
1855 {
1856 Matrix sz (1, 2, 0.0);
1857 return sz;
1858 }
1859
1860 double get_screen_resolution (void) const
1861 { return 72.0; }
1862
1863 Matrix get_screen_size (void) const
1864 { return Matrix (1, 2, 0.0); }
1865
1866 private:
1867 void send_quit (const octave_value& pstream) const
1768 { 1868 {
1769 if (! pstream.is_empty()) 1869 if (! pstream.is_empty())
1770 { 1870 {
1771 octave_value_list args; 1871 octave_value_list args;
1772 Matrix fids = pstream.matrix_value (); 1872 Matrix fids = pstream.matrix_value ();
1785 feval ("pclose", args); 1885 feval ("pclose", args);
1786 } 1886 }
1787 } 1887 }
1788 } 1888 }
1789 } 1889 }
1790
1791 void redraw_figure (const graphics_handle& fh) const
1792 {
1793 octave_value_list args;
1794 args(0) = fh.as_octave_value ();
1795 feval ("gnuplot_drawnow", args);
1796 }
1797
1798 void print_figure (const graphics_handle& fh, const std::string& term,
1799 const std::string& file, bool mono,
1800 const std::string& debug_file) const
1801 {
1802 octave_value_list args;
1803 if (! debug_file.empty ())
1804 args(4) = debug_file;
1805 args(3) = mono;
1806 args(2) = file;
1807 args(1) = term;
1808 args(0) = fh.as_octave_value ();
1809 feval ("gnuplot_drawnow", args);
1810 }
1811
1812 Matrix get_canvas_size (const graphics_handle&) const
1813 {
1814 Matrix sz (1, 2, 0.0);
1815 return sz;
1816 }
1817
1818 double get_screen_resolution (void) const
1819 { return 72.0; }
1820
1821 Matrix get_screen_size (void) const
1822 { return Matrix (1, 2, 0.0); }
1823 }; 1890 };
1824 1891
1825 graphics_backend 1892 graphics_backend
1826 graphics_backend::default_backend (void) 1893 graphics_backend::default_backend (void)
1827 { 1894 {
1899 1966
1900 callbackobject = val; 1967 callbackobject = val;
1901 } 1968 }
1902 else 1969 else
1903 gripe_set_invalid ("callbackobject"); 1970 gripe_set_invalid ("callbackobject");
1971 }
1972
1973 void
1974 root_figure::properties::remove_child (const graphics_handle& gh)
1975 {
1976 gh_manager::pop_figure (gh);
1977
1978 graphics_handle cf = gh_manager::current_figure ();
1979
1980 xset (0, "currentfigure", cf.value ());
1981
1982 base_properties::remove_child (gh);
1904 } 1983 }
1905 1984
1906 property_list 1985 property_list
1907 root_figure::factory_properties = root_figure::init_factory_properties (); 1986 root_figure::factory_properties = root_figure::init_factory_properties ();
1908 1987
1934 2013
1935 visible = val; 2014 visible = val;
1936 } 2015 }
1937 } 2016 }
1938 2017
1939 void
1940 figure::properties::close (bool pop)
1941 {
1942 if (backend)
1943 backend.close_figure (get___plot_stream__ ());
1944
1945 if (pop)
1946 {
1947 gh_manager::pop_figure (__myhandle__);
1948
1949 graphics_handle cf = gh_manager::current_figure ();
1950
1951 xset (0, "currentfigure", cf.value ());
1952 }
1953 }
1954
1955 Matrix 2018 Matrix
1956 figure::properties::get_boundingbox (bool) const 2019 figure::properties::get_boundingbox (bool) const
1957 { 2020 {
1958 graphics_backend b = get_backend (); 2021 graphics_backend b = get_backend ();
1959 // FIXME: screen size should be obtained from root object 2022 // FIXME: screen size should be obtained from root object
1997 position = v; 2060 position = v;
1998 new_bb = get_boundingbox (); 2061 new_bb = get_boundingbox ();
1999 2062
2000 if (old_bb != new_bb) 2063 if (old_bb != new_bb)
2001 { 2064 {
2002 // FIXME: maybe this should be converted into a more generic
2003 // call like "update_gui (this)"
2004 get_backend ().set_figure_position (__myhandle__, new_bb);
2005 if (old_bb(2) != new_bb(2) || old_bb(3) != new_bb(3)) 2065 if (old_bb(2) != new_bb(2) || old_bb(3) != new_bb(3))
2006 { 2066 {
2007 execute_resizefcn (); 2067 execute_resizefcn ();
2008 update_boundingbox (); 2068 update_boundingbox ();
2009 } 2069 }
2010 } 2070 }
2011 2071
2012 mark_modified (); 2072 mark_modified ();
2013 } 2073 }
2074 }
2075
2076 std::string
2077 figure::properties::get_title (void) const
2078 {
2079 if (is_numbertitle ())
2080 {
2081 std::ostringstream os;
2082 std::string name = get_name ();
2083
2084 os << "Figure " << __myhandle__.value ();
2085 if (! name.empty ())
2086 os << ": " << get_name ();
2087
2088 return os.str ();
2089 }
2090 else
2091 return get_name ();
2014 } 2092 }
2015 2093
2016 octave_value 2094 octave_value
2017 figure::get_default (const caseless_str& name) const 2095 figure::get_default (const caseless_str& name) const
2018 { 2096 {
3546 3624
3547 go = make_graphics_object_from_type (go_name, h, p); 3625 go = make_graphics_object_from_type (go_name, h, p);
3548 3626
3549 if (go) 3627 if (go)
3550 { 3628 {
3551 handle_map[h] = graphics_object (go); 3629 graphics_object obj (go);
3630
3631 handle_map[h] = obj;
3552 if (do_createfcn) 3632 if (do_createfcn)
3553 go->get_properties ().execute_createfcn (); 3633 go->get_properties ().execute_createfcn ();
3554 3634
3555 // notify backend 3635 // notify backend
3556 graphics_backend backend = go->get_backend (); 3636 graphics_backend backend = go->get_backend ();
3557 if (backend) 3637 if (backend)
3558 backend.object_created (h); 3638 backend.object_created (obj);
3559 } 3639 }
3560 else 3640 else
3561 error ("gh_manager::do_make_graphics_handle: invalid object type `%s'", 3641 error ("gh_manager::do_make_graphics_handle: invalid object type `%s'",
3562 go_name.c_str ()); 3642 go_name.c_str ());
3563 3643
3568 gh_manager::do_make_figure_handle (double val) 3648 gh_manager::do_make_figure_handle (double val)
3569 { 3649 {
3570 graphics_handle h = val; 3650 graphics_handle h = val;
3571 3651
3572 base_graphics_object* go = new figure (h, 0); 3652 base_graphics_object* go = new figure (h, 0);
3573 handle_map[h] = graphics_object (go); 3653 graphics_object obj (go);
3654
3655 handle_map[h] = obj;
3574 3656
3575 // notify backend 3657 // notify backend
3576 graphics_backend backend = go->get_backend (); 3658 graphics_backend backend = go->get_backend ();
3577 if (backend) 3659 if (backend)
3578 backend.object_created (h); 3660 backend.object_created (obj);
3579 3661
3580 return h; 3662 return h;
3581 } 3663 }
3582 3664
3583 void 3665 void
4561 { 4643 {
4562 if (fprops.is_visible ()) 4644 if (fprops.is_visible ())
4563 { 4645 {
4564 gh_manager::unlock (); 4646 gh_manager::unlock ();
4565 4647
4566 fprops.get_backend ().redraw_figure (h); 4648 fprops.get_backend ().redraw_figure (go);
4567 4649
4568 gh_manager::lock (); 4650 gh_manager::lock ();
4569 } 4651 }
4570 else if (! fprops.get___plot_stream__ ().is_empty ()) 4652
4571 {
4572 fprops.close (false);
4573 fprops.set___plot_stream__ (Matrix ());
4574 fprops.set___enhanced__ (false);
4575 }
4576 fprops.set_modified (false); 4653 fprops.set_modified (false);
4577 } 4654 }
4578 } 4655 }
4579 } 4656 }
4580 4657
4639 graphics_object go = gh_manager::get_object (h); 4716 graphics_object go = gh_manager::get_object (h);
4640 4717
4641 gh_manager::unlock (); 4718 gh_manager::unlock ();
4642 4719
4643 go.get_backend () 4720 go.get_backend ()
4644 .print_figure (h, term, file, mono, debug_file); 4721 .print_figure (go, term, file, mono, debug_file);
4645 4722
4646 gh_manager::lock (); 4723 gh_manager::lock ();
4647 } 4724 }
4648 else 4725 else
4649 error ("drawnow: nothing to draw"); 4726 error ("drawnow: nothing to draw");