Mercurial > hg > octave-nkf
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\ |