comparison libinterp/corefcn/graphics.cc @ 19155:a30e1d20fd3c

Freset: properly reset graphics objects (bug #35511) * graphics.in.h (base_graphics_object, graphics_object, root): add new method "get_factory_defaults_list" to retrieve factory defaults as property_list * graphics.in.h (base_graphics_object::reset_default_properties (void)): move definition to graphics.cc * graphics.cc (xreset_default_properties): new function to set a list of prop/val * graphics.cc (base_graphics_object::reset_default_properties): use xreset_default_properties, override with parents' defaults * graphics.cc (root_figure::reset_default_properties, figure::reset_default_properties, uitoolbar::reset_default_properties): same as above but first empty local defaults * graphics.cc (axes_figure::reset_default_properties): same as above but use "propeties.set_defaults" to reset properties to their factory value. * graphics.cc (axes_figure::properties::set_defaults): new "reset" mode, that does the same as "replace" but x/y/zlabels and title are reset instead of being deleting/recreating. * graphics.cc: add %!tests for Freset
author pantxo <pantxo.diribarne@gmail.com>
date Fri, 21 Mar 2014 11:05:28 +0100
parents d4b69559a0f7
children a0c514c243f6
comparison
equal deleted inserted replaced
19154:d4b69559a0f7 19155:a30e1d20fd3c
2753 graphics_object go = gh_manager::get_object (h); 2753 graphics_object go = gh_manager::get_object (h);
2754 2754
2755 finalize (go); 2755 finalize (go);
2756 } 2756 }
2757 2757
2758 static void
2759 xreset_default_properties (graphics_handle gh,
2760 property_list::pval_map_type factory_pval)
2761 {
2762 graphics_object obj = gh_manager::get_object (gh);
2763
2764 property_list::pval_map_type pval;
2765
2766 for (property_list::pval_map_const_iterator it = factory_pval.begin ();
2767 it != factory_pval.end (); it++)
2768 {
2769 std::string pname = it->first;
2770
2771 // Don't reset internal properties and handle_properties
2772 if (! obj.has_readonly_property (pname) &&
2773 pname.find ("__") != 0 && pname.find ("current") != 0 &&
2774 pname != "uicontextmenu" && pname != "parent")
2775 {
2776 // Store *mode prop/val in order to set them last
2777 if (pname.find ("mode") == (pname.length () - 4))
2778 pval.insert (std::pair<std::string, octave_value>
2779 (pname, it->second));
2780 else
2781 obj.set (pname, it->second);
2782 }
2783 }
2784
2785 // set *mode properties
2786 for (property_list::pval_map_const_iterator it = pval.begin ();
2787 it != pval.end (); it++)
2788 obj.set (it->first, it->second);
2789 }
2790
2758 // --------------------------------------------------------------------- 2791 // ---------------------------------------------------------------------
2759 2792
2760 void 2793 void
2761 base_properties::set_from_list (base_graphics_object& obj, 2794 base_properties::set_from_list (base_graphics_object& obj,
2762 property_list& defaults) 2795 property_list& defaults)
2772 for (property_list::pval_map_const_iterator q = pval_map.begin (); 2805 for (property_list::pval_map_const_iterator q = pval_map.begin ();
2773 q != pval_map.end (); 2806 q != pval_map.end ();
2774 q++) 2807 q++)
2775 { 2808 {
2776 std::string pname = q->first; 2809 std::string pname = q->first;
2777 2810
2778 obj.set (pname, q->second); 2811 obj.set (pname, q->second);
2779 2812
2780 if (error_state) 2813 if (error_state)
2781 { 2814 {
2782 error ("error setting default property %s", pname.c_str ()); 2815 error ("error setting default property %s", pname.c_str ());
3083 3116
3084 if (! error_state && p.ok ()) 3117 if (! error_state && p.ok ())
3085 p.delete_listener (); 3118 p.delete_listener ();
3086 } 3119 }
3087 } 3120 }
3121
3122 void
3123 base_graphics_object::reset_default_properties (void)
3124 {
3125 if (valid_object ())
3126 {
3127 property_list::pval_map_type factory_pval =
3128 gh_manager::get_object (0).get_factory_defaults_list ()
3129 .find (type ())->second;
3130
3131 xreset_default_properties (get_handle (), factory_pval);
3132
3133 override_defaults (*this);
3134 }
3135 }
3088 3136
3089 std::string 3137 std::string
3090 base_graphics_object::values_as_string (void) 3138 base_graphics_object::values_as_string (void)
3091 { 3139 {
3092 std::string retval; 3140 std::string retval;
3568 } 3616 }
3569 3617
3570 property_list 3618 property_list
3571 root_figure::factory_properties = root_figure::init_factory_properties (); 3619 root_figure::factory_properties = root_figure::init_factory_properties ();
3572 3620
3573 static void
3574 reset_default_properties (property_list& default_properties)
3575 {
3576 property_list new_defaults;
3577
3578 for (property_list::plist_map_const_iterator p = default_properties.begin ();
3579 p != default_properties.end (); p++)
3580 {
3581 const property_list::pval_map_type pval_map = p->second;
3582 std::string prefix = p->first;
3583
3584 for (property_list::pval_map_const_iterator q = pval_map.begin ();
3585 q != pval_map.end ();
3586 q++)
3587 {
3588 std::string s = q->first;
3589
3590 if (prefix == "axes" && (s == "position" || s == "units"))
3591 new_defaults.set (prefix + s, q->second);
3592 else if (prefix == "figure" && (s == "position" || s == "units"
3593 || s == "windowstyle"
3594 || s == "paperunits"))
3595 new_defaults.set (prefix + s, q->second);
3596 }
3597 }
3598
3599 default_properties = new_defaults;
3600 }
3601
3602 void 3621 void
3603 root_figure::reset_default_properties (void) 3622 root_figure::reset_default_properties (void)
3604 { 3623 {
3605 ::reset_default_properties (default_properties); 3624 // empty list of local defaults
3625 default_properties = property_list ();
3626
3627 xreset_default_properties (get_handle (),
3628 xproperties.factory_defaults ());
3606 } 3629 }
3607 3630
3608 // --------------------------------------------------------------------- 3631 // ---------------------------------------------------------------------
3609 3632
3610 void 3633 void
4460 } 4483 }
4461 4484
4462 void 4485 void
4463 figure::reset_default_properties (void) 4486 figure::reset_default_properties (void)
4464 { 4487 {
4465 ::reset_default_properties (default_properties); 4488 // empty list of local defaults
4489 default_properties = property_list ();
4490
4491 property_list::pval_map_type plist = xproperties.factory_defaults ();
4492 plist.erase ("units");
4493 plist.erase ("position");
4494 plist.erase ("paperunits");
4495 plist.erase ("paperposition");
4496 plist.erase ("windowstyle");
4497 xreset_default_properties (get_handle (), plist);
4498
4499 // FIXME: the following short sleep is needed in order
4500 // to avoid a crash when using qt toolkit
4501 Fsleep (octave_value (0.001));
4502
4503 // override with parents' defaults
4504 override_defaults (*this);
4466 } 4505 }
4467 4506
4468 // --------------------------------------------------------------------- 4507 // ---------------------------------------------------------------------
4469 4508
4470 void 4509 void
4881 sy = "linear"; 4920 sy = "linear";
4882 sz = "linear"; 4921 sz = "linear";
4883 4922
4884 visible = "on"; 4923 visible = "on";
4885 4924
4886 // Replace preserves Position and Units properties 4925 // Replace/Reset preserves Position and Units properties
4887 if (mode != "replace") 4926 if (mode != "replace" && mode != "reset")
4888 { 4927 {
4889 outerposition = default_axes_outerposition (); 4928 outerposition = default_axes_outerposition ();
4890 position = default_axes_position (); 4929 position = default_axes_position ();
4891 activepositionproperty = "outerposition"; 4930 activepositionproperty = "outerposition";
4892 } 4931 }
4893 4932
4894 delete_children (true); 4933 if (mode != "reset")
4895 4934 {
4896 xlabel = gh_manager::make_graphics_handle ("text", __myhandle__, 4935 delete_children (true);
4897 false, false); 4936
4898 4937 xlabel = gh_manager::make_graphics_handle ("text", __myhandle__,
4899 ylabel = gh_manager::make_graphics_handle ("text", __myhandle__, 4938 false, false);
4900 false, false); 4939 ylabel = gh_manager::make_graphics_handle ("text", __myhandle__,
4901 4940 false, false);
4902 zlabel = gh_manager::make_graphics_handle ("text", __myhandle__, 4941 zlabel = gh_manager::make_graphics_handle ("text", __myhandle__,
4903 false, false); 4942 false, false);
4904 4943 title = gh_manager::make_graphics_handle ("text", __myhandle__,
4905 title = gh_manager::make_graphics_handle ("text", __myhandle__, 4944 false, false);
4906 false, false); 4945 adopt (xlabel.handle_value ());
4946 adopt (ylabel.handle_value ());
4947 adopt (zlabel.handle_value ());
4948 adopt (title.handle_value ());
4949 }
4950 else
4951 {
4952 graphics_object go = gh_manager::get_object (xlabel.handle_value ());
4953 go.reset_default_properties ();
4954 go = gh_manager::get_object (ylabel.handle_value ());
4955 go.reset_default_properties ();
4956 go = gh_manager::get_object (zlabel.handle_value ());
4957 go.reset_default_properties ();
4958 go = gh_manager::get_object (title.handle_value ());
4959 go.reset_default_properties ();
4960 }
4907 4961
4908 xset (xlabel.handle_value (), "handlevisibility", "off"); 4962 xset (xlabel.handle_value (), "handlevisibility", "off");
4909 xset (ylabel.handle_value (), "handlevisibility", "off"); 4963 xset (ylabel.handle_value (), "handlevisibility", "off");
4910 xset (zlabel.handle_value (), "handlevisibility", "off"); 4964 xset (zlabel.handle_value (), "handlevisibility", "off");
4911 xset (title.handle_value (), "handlevisibility", "off"); 4965 xset (title.handle_value (), "handlevisibility", "off");
4938 4992
4939 xset (xlabel.handle_value (), "autopos_tag", "xlabel"); 4993 xset (xlabel.handle_value (), "autopos_tag", "xlabel");
4940 xset (ylabel.handle_value (), "autopos_tag", "ylabel"); 4994 xset (ylabel.handle_value (), "autopos_tag", "ylabel");
4941 xset (zlabel.handle_value (), "autopos_tag", "zlabel"); 4995 xset (zlabel.handle_value (), "autopos_tag", "zlabel");
4942 xset (title.handle_value (), "autopos_tag", "title"); 4996 xset (title.handle_value (), "autopos_tag", "title");
4943
4944 adopt (xlabel.handle_value ());
4945 adopt (ylabel.handle_value ());
4946 adopt (zlabel.handle_value ());
4947 adopt (title.handle_value ());
4948 4997
4949 update_transform (); 4998 update_transform ();
4950 sync_positions (); 4999 sync_positions ();
4951 override_defaults (obj); 5000 override_defaults (obj);
4952 } 5001 }
7647 } 7696 }
7648 7697
7649 void 7698 void
7650 axes::reset_default_properties (void) 7699 axes::reset_default_properties (void)
7651 { 7700 {
7652 ::reset_default_properties (default_properties); 7701 // empty list of local defaults
7702 default_properties = property_list ();
7703
7704 // reset factory defaults
7705 set_defaults ("reset");
7653 } 7706 }
7654 7707
7655 void 7708 void
7656 axes::initialize (const graphics_object& go) 7709 axes::initialize (const graphics_object& go)
7657 { 7710 {
8692 } 8745 }
8693 8746
8694 void 8747 void
8695 uitoolbar::reset_default_properties (void) 8748 uitoolbar::reset_default_properties (void)
8696 { 8749 {
8697 ::reset_default_properties (default_properties); 8750 // empty list of local defaults
8751 default_properties = property_list ();
8752
8753 xreset_default_properties (get_handle (),
8754 xproperties.factory_defaults ());
8755
8756 // override with parents' defaults
8757 override_defaults (*this);
8698 } 8758 }
8699 8759
8700 // --------------------------------------------------------------------- 8760 // ---------------------------------------------------------------------
8701 8761
8702 octave_value 8762 octave_value
9318 return retval; 9378 return retval;
9319 } 9379 }
9320 9380
9321 DEFUN (reset, args, , 9381 DEFUN (reset, args, ,
9322 "-*- texinfo -*-\n\ 9382 "-*- texinfo -*-\n\
9323 @deftypefn {Built-in Function} {} reset (@var{h}, @var{property})\n\ 9383 @deftypefn {Built-in Function} {} reset (@var{h})\n\
9324 Remove any defaults set for the handle @var{h}. The default figure\n\ 9384 Resets the properites of object(s) @var{h} to their default values.\n\
9325 properties of @qcode{\"position\"}, @qcode{\"units\"},\n\ 9385 For figures, the properties @qcode{\"position\"}, @qcode{\"units\"},\n\
9326 @qcode{\"windowstyle\"} and @qcode{\"paperunits\"} and the default axes\n\ 9386 @qcode{\"windowstyle\"}, and @qcode{\"paperunits\"} are not affected.\n\
9327 properties of @qcode{\"position\"} and @qcode{\"units\"} are not reset.\n\ 9387 For axes, the properties @qcode{\"position\"} and @qcode{\"units\"} are\n\
9328 @seealso{cla, clf}\n\ 9388 not affected.\n\
9389 @seealso{cla, clf, newplot}\n\
9329 @end deftypefn") 9390 @end deftypefn")
9330 { 9391 {
9331 int nargin = args.length (); 9392 int nargin = args.length ();
9332 9393
9333 if (nargin != 1) 9394 if (nargin != 1)
9340 if (! error_state) 9401 if (! error_state)
9341 { 9402 {
9342 // loop over graphics objects 9403 // loop over graphics objects
9343 for (octave_idx_type n = 0; n < hcv.length (); n++) 9404 for (octave_idx_type n = 0; n < hcv.length (); n++)
9344 gh_manager::get_object (hcv(n)).reset_default_properties (); 9405 gh_manager::get_object (hcv(n)).reset_default_properties ();
9406
9407 if (! error_state)
9408 Fdrawnow ();
9345 } 9409 }
9346 } 9410 }
9347 9411
9348 return octave_value (); 9412 return octave_value ();
9349 } 9413 }
9414
9415 /*
9416
9417 %!test
9418 %! hf = figure ("visible", "off");
9419 %! unwind_protect
9420 %! tol = 20 * eps;
9421 %! hax = axes ("defaultlinelinewidth", 3);
9422 %!
9423 %! hli = line (1:10, 1:10, 1:10, "marker", "o",
9424 %! "markerfacecolor", "b", "linestyle", ":");
9425 %!
9426 %! reset (hli);
9427 %! assert (get (hli, "marker"), get (0, "defaultlinemarker"))
9428 %! assert (get (hli, "markerfacecolor"), ...
9429 %! get (0, "defaultlinemarkerfacecolor"))
9430 %! assert (get (hli, "linestyle"), ...
9431 %! get (0, "defaultlinelinestyle"))
9432 %! assert (get (hli, "linewidth"), 3, tol) # parent axes defaults
9433 %!
9434 %! unwind_protect_cleanup
9435 %! close (hf)
9436 %! end_unwind_protect
9437
9438 %!test
9439 %! hf = figure ("visible", "off");
9440 %! unwind_protect
9441 %! tol = 20 * eps;
9442 %! t1 = (1/16:1/8:1)' * 2*pi;
9443 %! t2 = ((1/16:1/16:1)' + 1/32) * 2*pi;
9444 %! x1 = sin (t1) - 0.8;
9445 %! y1 = cos (t1);
9446 %! x2 = sin (t2) + 0.8;
9447 %! y2 = cos (t2);
9448 %! vert = [x1, y1; x2, y2];
9449 %! fac = [1:8,NaN(1,8);9:24];
9450 %! hpa = patch ('Faces',fac, 'Vertices',vert, 'FaceColor','r');
9451 %!
9452 %! reset (hpa);
9453 %! assert (get (hpa, "faces"), get (0, "defaultpatchfaces"), tol)
9454 %! assert (get (hpa, "vertices"), get (0, "defaultpatchvertices"), tol)
9455 %! assert (get (hpa, "facevertexcdata"), ...
9456 %! get (0, "defaultpatchfacevertexcdata"), tol)
9457 %! unwind_protect_cleanup
9458 %! close (hf)
9459 %! end_unwind_protect
9460
9461 %!test
9462 %! hf = figure ("visible", "off");
9463 %! unwind_protect
9464 %! tol = 20 * eps;
9465 %! hsu = surface (peaks, "edgecolor", "none");
9466 %!
9467 %! reset (hsu);
9468 %! assert (get (hsu, "xdata"), get (0, "defaultsurfacexdata"), tol)
9469 %! assert (get (hsu, "ydata"), get (0, "defaultsurfaceydata"), tol)
9470 %! assert (get (hsu, "zdata"), get (0, "defaultsurfacezdata"), tol)
9471 %! assert (get (hsu, "edgecolor"), ...
9472 %! get (0, "defaultsurfaceedgecolor"), tol)
9473 %! unwind_protect_cleanup
9474 %! close (hf)
9475 %! end_unwind_protect
9476
9477 %!test
9478 %! hf = figure ("visible", "off");
9479 %! unwind_protect
9480 %! tol = 20 * eps;
9481 %! him =image (rand (10,10), "cdatamapping", "scaled");
9482 %!
9483 %! reset (him);
9484 %! assert (get (him, "cdata"), get (0, "defaultimagecdata"), tol)
9485 %! assert (get (him, "cdatamapping"), ...
9486 %! get (0, "defaultimagecdatamapping"), tol)
9487 %! unwind_protect_cleanup
9488 %! close (hf)
9489 %! end_unwind_protect
9490
9491 %!test
9492 %! hf = figure ("visible", "off");
9493 %! unwind_protect
9494 %! tol = 20 * eps;
9495 %! hte = text (5, 5, "Hi!", "fontsize", 20 ,"color", "r");
9496 %!
9497 %! reset (hte);
9498 %! assert (get (hte, "position"), get (0, "defaulttextposition"), tol)
9499 %! assert (get (hte, "fontsize"), get (0, "defaulttextfontsize"), tol)
9500 %! assert (get (hte, "color"), get (0, "defaulttextcolor"), tol)
9501 %! unwind_protect_cleanup
9502 %! close (hf)
9503 %! end_unwind_protect
9504
9505 %!test
9506 %! hf = figure ("visible", "off");
9507 %! unwind_protect
9508 %! tol = 20 * eps;
9509 %! pos = get (0, "defaultaxesposition") * .5;
9510 %! hax = axes ("linewidth", 2, "position", pos);
9511 %! title ("Reset me, please!")
9512 %!
9513 %! reset (hax);
9514 %! assert (get (hax, "linewidth"), get (0, "defaultaxeslinewidth"), tol)
9515 %! assert (get (hax, "position"), pos, tol) # axes position is unchanged
9516 %! assert (get (hax, "default"), struct ()) # no more axes' defaults
9517 %! assert (get (get (hax, "title"), "string"), "")
9518 %! unwind_protect_cleanup
9519 %! close (hf)
9520 %! end_unwind_protect
9521
9522 %!test
9523 %! set (0, "defaultfigurevisible", "off")
9524 %! hf = figure ("visible", "off", "paperunits", "centimeters", ...
9525 %! "papertype", "a4");
9526 %! unwind_protect
9527 %! reset (hf)
9528 %! assert (get (hf, "papertype"), get (0, "defaultfigurepapertype"))
9529 %! assert (get (hf, "paperunits"), "centimeters") # paperunits is unchanged
9530 %! assert (get (hf, "visible"), get (0, "defaultfigurevisible"))
9531 %! unwind_protect_cleanup
9532 %! close (hf)
9533 %! set (0, "defaultfigurevisible", "remove")
9534 %! end_unwind_protect
9535 */
9350 9536
9351 DEFUN (set, args, nargout, 9537 DEFUN (set, args, nargout,
9352 "-*- texinfo -*-\n\ 9538 "-*- texinfo -*-\n\
9353 @deftypefn {Built-in Function} {} set (@var{h}, @var{property}, @var{value}, @dots{})\n\ 9539 @deftypefn {Built-in Function} {} set (@var{h}, @var{property}, @var{value}, @dots{})\n\
9354 @deftypefnx {Built-in Function} {} set (@var{h}, @var{properties}, @var{values})\n\ 9540 @deftypefnx {Built-in Function} {} set (@var{h}, @var{properties}, @var{values})\n\