Mercurial > octave-nkf
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"); |