comparison src/graphics.cc @ 8208:f6ca8ff51818

[mq]: graphics-backend
author John W. Eaton <jwe@octave.org>
date Fri, 10 Oct 2008 11:07:53 -0400
parents 32e9e8103390
children 2abbc8036f6a
comparison
equal deleted inserted replaced
8207:60b4c75287a1 8208:f6ca8ff51818
1289 { 1289 {
1290 iterator p = handle_map.find (h); 1290 iterator p = handle_map.find (h);
1291 1291
1292 if (p != handle_map.end ()) 1292 if (p != handle_map.end ())
1293 { 1293 {
1294 // FIXME: should we explicitely free all children first? 1294 base_properties& bp = p->second.get_properties ();
1295 // => call delete_children () ? 1295
1296 1296 bp.set_beingdeleted (true);
1297 p->second.get_properties ().set_beingdeleted (true); 1297
1298 p->second.get_properties ().execute_deletefcn (); 1298 bp.delete_children ();
1299
1300 octave_value val = bp.get_deletefcn ();
1301
1302 bp.execute_deletefcn ();
1299 1303
1300 // notify backend 1304 // notify backend
1301 graphics_backend backend = p->second.get_backend (); 1305 graphics_backend backend = p->second.get_backend ();
1302 if (backend) 1306 if (backend)
1303 backend.object_destroyed (p->second); 1307 backend.object_destroyed (p->second);
1304 // note - this will be valid only for first explicitly deleted object. 1308
1305 // All his children will have unknown backend then. 1309 // Note: this will be valid only for first explicitly
1306 1310 // deleted object. All its children will then have an
1311 // unknown backend.
1312
1307 handle_map.erase (p); 1313 handle_map.erase (p);
1308 1314
1309 if (h.value () < 0) 1315 if (h.value () < 0)
1310 handle_free_list.insert (h); 1316 handle_free_list.insert (h);
1311 } 1317 }
1735 void 1741 void
1736 base_properties::delete_children (void) 1742 base_properties::delete_children (void)
1737 { 1743 {
1738 octave_idx_type n = children.numel (); 1744 octave_idx_type n = children.numel ();
1739 1745
1746 // A callback function might have already deleted the child,
1747 // so check before deleting
1740 for (octave_idx_type i = 0; i < n; i++) 1748 for (octave_idx_type i = 0; i < n; i++)
1741 gh_manager::free (children(i)); 1749 {
1750 graphics_object go = gh_manager::get_object (children(i));
1751
1752 if (go.valid_object ())
1753 gh_manager::free (children(i));
1754 }
1742 } 1755 }
1743 1756
1744 graphics_backend 1757 graphics_backend
1745 base_properties::get_backend (void) const 1758 base_properties::get_backend (void) const
1746 { 1759 {
2102 // --------------------------------------------------------------------- 2115 // ---------------------------------------------------------------------
2103 2116
2104 void 2117 void
2105 axes::properties::sync_positions (void) 2118 axes::properties::sync_positions (void)
2106 { 2119 {
2120 #if 0
2107 // FIXME -- this should take font metrics into consideration, 2121 // FIXME -- this should take font metrics into consideration,
2108 // for now we'll just make it position 90% of outerposition 2122 // and also the fact that the colorbox leaves the outerposition
2123 // alone but alters the position. For now just don't adjust the
2124 // positions relative to each other.
2125
2109 if (activepositionproperty.is ("outerposition")) 2126 if (activepositionproperty.is ("outerposition"))
2110 { 2127 {
2111 Matrix outpos = outerposition.get ().matrix_value (); 2128 Matrix outpos = outerposition.get ().matrix_value ();
2112 Matrix defpos = default_axes_position (); 2129 Matrix defpos = default_axes_position ();
2113 Matrix pos(outpos); 2130 Matrix pos(outpos);
2124 pos(1) -= pos(3)*0.05; 2141 pos(1) -= pos(3)*0.05;
2125 pos(2) *= 1.1; 2142 pos(2) *= 1.1;
2126 pos(3) *= 1.1; 2143 pos(3) *= 1.1;
2127 outerposition = pos; 2144 outerposition = pos;
2128 } 2145 }
2146 #endif
2129 2147
2130 update_transform (); 2148 update_transform ();
2131 } 2149 }
2132 2150
2133 void 2151 void
2180 2198
2181 void 2199 void
2182 axes::properties::set_defaults (base_graphics_object& obj, 2200 axes::properties::set_defaults (base_graphics_object& obj,
2183 const std::string& mode) 2201 const std::string& mode)
2184 { 2202 {
2185 title = graphics_handle (); 2203 delete_text_child (title);
2204
2186 box = "on"; 2205 box = "on";
2187 key = "off"; 2206 key = "off";
2188 keybox = "off"; 2207 keybox = "off";
2189 keypos = 1.0; 2208 keypos = 1.0;
2190 colororder = default_colororder (); 2209 colororder = default_colororder ();
2204 2223
2205 xlimmode = "auto"; 2224 xlimmode = "auto";
2206 ylimmode = "auto"; 2225 ylimmode = "auto";
2207 zlimmode = "auto"; 2226 zlimmode = "auto";
2208 climmode = "auto"; 2227 climmode = "auto";
2209 xlabel = graphics_handle (); 2228
2210 ylabel = graphics_handle (); 2229 delete_text_child (xlabel);
2211 zlabel = graphics_handle (); 2230 delete_text_child (ylabel);
2231 delete_text_child (zlabel);
2232
2212 xgrid = "off"; 2233 xgrid = "off";
2213 ygrid = "off"; 2234 ygrid = "off";
2214 zgrid = "off"; 2235 zgrid = "off";
2215 xminorgrid = "off"; 2236 xminorgrid = "off";
2216 yminorgrid = "off"; 2237 yminorgrid = "off";
2287 2308
2288 position = default_axes_position (); 2309 position = default_axes_position ();
2289 } 2310 }
2290 2311
2291 activepositionproperty = "outerposition"; 2312 activepositionproperty = "outerposition";
2292 __colorbar__ = "none";
2293 2313
2294 delete_children (); 2314 delete_children ();
2295 2315
2296 children = Matrix (); 2316 children = Matrix ();
2297 2317
2298 update_transform (); 2318 update_transform ();
2299 2319
2300 override_defaults (obj); 2320 override_defaults (obj);
2301 } 2321 }
2302 2322
2303 graphics_handle 2323 void
2304 axes::properties::get_title (void) const 2324 axes::properties::delete_text_child (handle_property& hp)
2305 { 2325 {
2306 if (! title.handle_value ().ok ()) 2326 graphics_handle h = hp.handle_value ();
2307 title = gh_manager::make_graphics_handle ("text", __myhandle__); 2327
2308 2328 if (h.ok ())
2309 return title.handle_value (); 2329 {
2310 } 2330 graphics_object go = gh_manager::get_object (h);
2311 2331
2312 graphics_handle 2332 if (go.valid_object ())
2313 axes::properties::get_xlabel (void) const 2333 gh_manager::free (h);
2314 { 2334 }
2315 if (! xlabel.handle_value ().ok ()) 2335
2316 xlabel = gh_manager::make_graphics_handle ("text", __myhandle__); 2336 if (! is_beingdeleted ())
2317 2337 hp = gh_manager::make_graphics_handle ("text", __myhandle__);
2318 return xlabel.handle_value ();
2319 }
2320
2321 graphics_handle
2322 axes::properties::get_ylabel (void) const
2323 {
2324 if (! ylabel.handle_value ().ok ())
2325 ylabel = gh_manager::make_graphics_handle ("text", __myhandle__);
2326
2327 return ylabel.handle_value ();
2328 }
2329
2330 graphics_handle
2331 axes::properties::get_zlabel (void) const
2332 {
2333 if (! zlabel.handle_value ().ok ())
2334 zlabel = gh_manager::make_graphics_handle ("text", __myhandle__);
2335
2336 return zlabel.handle_value ();
2337 } 2338 }
2338 2339
2339 void 2340 void
2340 axes::properties::remove_child (const graphics_handle& h) 2341 axes::properties::remove_child (const graphics_handle& h)
2341 { 2342 {
2342 if (title.handle_value ().ok () && h == title.handle_value ()) 2343 if (title.handle_value ().ok () && h == title.handle_value ())
2343 title = gh_manager::make_graphics_handle ("text", __myhandle__); 2344 delete_text_child (title);
2344 else if (xlabel.handle_value ().ok () && h == xlabel.handle_value ()) 2345 else if (xlabel.handle_value ().ok () && h == xlabel.handle_value ())
2345 xlabel = gh_manager::make_graphics_handle ("text", __myhandle__); 2346 delete_text_child (xlabel);
2346 else if (ylabel.handle_value ().ok () && h == ylabel.handle_value ()) 2347 else if (ylabel.handle_value ().ok () && h == ylabel.handle_value ())
2347 ylabel = gh_manager::make_graphics_handle ("text", __myhandle__); 2348 delete_text_child (ylabel);
2348 else if (zlabel.handle_value ().ok () && h == zlabel.handle_value ()) 2349 else if (zlabel.handle_value ().ok () && h == zlabel.handle_value ())
2349 zlabel = gh_manager::make_graphics_handle ("text", __myhandle__); 2350 delete_text_child (zlabel);
2350 else 2351 else
2351 base_properties::remove_child (h); 2352 base_properties::remove_child (h);
2352 } 2353 }
2353 2354
2354 void 2355 void
2355 axes::properties::delete_children (void) 2356 axes::properties::delete_children (void)
2356 { 2357 {
2357 base_properties::delete_children (); 2358 base_properties::delete_children ();
2358 2359
2359 gh_manager::free (title.handle_value ()); 2360 delete_text_child (title);
2360 gh_manager::free (xlabel.handle_value ()); 2361
2361 gh_manager::free (ylabel.handle_value ()); 2362 delete_text_child (xlabel);
2362 gh_manager::free (zlabel.handle_value ()); 2363 delete_text_child (ylabel);
2364 delete_text_child (zlabel);
2363 } 2365 }
2364 2366
2365 inline Matrix 2367 inline Matrix
2366 xform_matrix (void) 2368 xform_matrix (void)
2367 { 2369 {
4429 4431
4430 if (h.ok ()) 4432 if (h.ok ())
4431 { 4433 {
4432 graphics_object obj = gh_manager::get_object (h); 4434 graphics_object obj = gh_manager::get_object (h);
4433 4435
4434 graphics_handle parent_h = obj.get_parent (); 4436 // Don't do recursive deleting, due to callbacks
4435 4437 if (! obj.get_properties ().is_beingdeleted ())
4436 graphics_object parent_obj = 4438 {
4437 gh_manager::get_object (parent_h); 4439 graphics_handle parent_h = obj.get_parent ();
4438 4440
4439 // NOTE: free the handle before removing it from its parent's 4441 graphics_object parent_obj =
4440 // children, such that the object's state is correct 4442 gh_manager::get_object (parent_h);
4441 // when the deletefcn callback is executed 4443
4442 4444 // NOTE: free the handle before removing it from its
4443 gh_manager::free (h); 4445 // parent's children, such that the object's
4444 4446 // state is correct when the deletefcn callback
4445 parent_obj.remove_child (h); 4447 // is executed
4446 4448
4447 Vdrawnow_requested = true; 4449 gh_manager::free (h);
4450
4451 // A callback function might have already deleted
4452 // the parent
4453 if (parent_obj.valid_object ())
4454 parent_obj.remove_child (h);
4455
4456 Vdrawnow_requested = true;
4457 }
4448 } 4458 }
4449 else 4459 else
4450 { 4460 {
4451 error ("delete: invalid graphics object (= %g)", 4461 error ("delete: invalid graphics object (= %g)",
4452 vals.elem (i)); 4462 vals.elem (i));
4498 if (h.ok ()) 4508 if (h.ok ())
4499 { 4509 {
4500 graphics_object obj = gh_manager::get_object (h); 4510 graphics_object obj = gh_manager::get_object (h);
4501 4511
4502 obj.set_defaults (mode); 4512 obj.set_defaults (mode);
4513
4514 h = gh_manager::lookup (val);
4515 if (! h.ok ())
4516 error ("__go_axes_init__: axis deleted during initialization (= %g)", val);
4503 } 4517 }
4504 else 4518 else
4505 error ("__go_axes_init__: invalid graphics object (= %g)", val); 4519 error ("__go_axes_init__: invalid graphics object (= %g)", val);
4506 } 4520 }
4507 else 4521 else