changeset 20086:10600b2dd3c1

make units other than data work for axes labels and title (bug #35857) * graphics.in.h, graphics.cc (base_property::invalidate): New function. (axes::properties::set_defaults): If mode is not "reset", invalidate label and title handles before recreating them. Don't notify toolkit when recreating label and title handles. Update label and title positions after they are created. (convert_label_position): New static function. (axes::properties::update_xlabel_position, axes::properties::update_ylabel_position, axes::properties::update_zlabel_position, axes::properties::update_title_position): Return early if object is not valid. Call convert_label_position to handle units other than "data". (text::properties::update_units): Preserve "auto" positionmode. (gh_manager::do_make_graphics_handle): Call override_defaults here for newly created objects. If creating an axes object, also call override_defaults for the axes label and title objects. (graphics_object::override_defaults): New function. (figure::figure, axes::axes, line::line, text::text, image::image, patch::patch, surface::surface, hggroup::hggroup, uimenu::uimenu, uicontextmenu::uicontextmenu, uicontrol::uicontrol, uipanel::uipanel, uitoolbar::uitoolbar, uipushtool::uipushtool, uitoggletool::uitoggletool): Don't call override_defaults from constructor.
author John W. Eaton <jwe@octave.org>
date Wed, 08 Apr 2015 16:46:10 -0400
parents 48aa3d6d3427
children 8b501a0db1e9
files libinterp/corefcn/graphics.cc libinterp/corefcn/graphics.in.h
diffstat 2 files changed, 137 insertions(+), 51 deletions(-) [+]
line wrap: on
line diff
--- a/libinterp/corefcn/graphics.cc	Wed Apr 08 21:39:24 2015 +0200
+++ b/libinterp/corefcn/graphics.cc	Wed Apr 08 16:46:10 2015 -0400
@@ -5068,18 +5068,29 @@
     {
       delete_children (true);
 
+      xlabel.invalidate ();
+      ylabel.invalidate ();
+      zlabel.invalidate ();
+      title.invalidate ();
+
       xlabel = gh_manager::make_graphics_handle ("text", __myhandle__,
-                                                 false, false);
+                                                 false, false, false);
       ylabel = gh_manager::make_graphics_handle ("text", __myhandle__,
-                                                 false, false);
+                                                 false, false, false);
       zlabel = gh_manager::make_graphics_handle ("text", __myhandle__,
-                                                 false, false);
+                                                 false, false, false);
       title = gh_manager::make_graphics_handle ("text", __myhandle__,
-                                                false, false);
+                                                false, false, false);
+
       adopt (xlabel.handle_value ());
       adopt (ylabel.handle_value ());
       adopt (zlabel.handle_value ());
       adopt (title.handle_value ());
+
+      update_xlabel_position ();
+      update_ylabel_position ();
+      update_zlabel_position ();
+      update_title_position ();
     }
   else
     {
@@ -5766,6 +5777,35 @@
 %!  title title;
 */
 
+static ColumnVector
+convert_label_position (const ColumnVector& p,
+                        const text::properties& props,
+                        const graphics_xform& xform,
+                        const Matrix& bbox)
+{
+  ColumnVector retval;
+
+  caseless_str to_units = props.get_units ();
+
+  if (! to_units.compare ("data"))
+    {
+      ColumnVector v = xform.transform (p(0), p(1), p(2));
+
+      retval.resize (3);
+
+      retval(0) = v(0) - bbox(0) + 1;
+      retval(1) = bbox(1) + bbox(3) - v(1) + 1;
+      retval(2) = 0;
+
+      retval = convert_position (retval, "pixels", to_units,
+                                 bbox.extract_n (0, 2, 1, 2));
+    }
+  else
+    retval = p;
+
+  return retval;
+}
+
 static bool updating_xlabel_position = false;
 
 void
@@ -5774,9 +5814,13 @@
   if (updating_xlabel_position)
     return;
 
+  graphics_object obj = gh_manager::get_object (get_xlabel ());
+
+  if (! obj.valid_object ())
+    return;
+
   text::properties& xlabel_props
-    = reinterpret_cast<text::properties&>
-        (gh_manager::get_object (get_xlabel ()).get_properties ());
+    = reinterpret_cast<text::properties&> (obj.get_properties ());
 
   bool is_empty = xlabel_props.get_string ().is_empty ();
 
@@ -5848,6 +5892,10 @@
       if (xlabel_props.positionmode_is ("auto"))
         {
           p = xform.untransform (p(0), p(1), p(2), true);
+
+          p = convert_label_position (p, xlabel_props, xform,
+                                      get_extent (false));
+
           xlabel_props.set_position (p.extract_n (0, 3).transpose ());
           xlabel_props.set_positionmode ("auto");
         }
@@ -5868,9 +5916,13 @@
   if (updating_ylabel_position)
     return;
 
+  graphics_object obj = gh_manager::get_object (get_ylabel ());
+
+  if (! obj.valid_object ())
+    return;
+
   text::properties& ylabel_props
-    = reinterpret_cast<text::properties&>
-        (gh_manager::get_object (get_ylabel ()).get_properties ());
+    = reinterpret_cast<text::properties&> (obj.get_properties ());
 
   bool is_empty = ylabel_props.get_string ().is_empty ();
 
@@ -5951,6 +6003,10 @@
       if (ylabel_props.positionmode_is ("auto"))
         {
           p = xform.untransform (p(0), p(1), p(2), true);
+
+          p = convert_label_position (p, ylabel_props, xform,
+                                      get_extent (false));
+
           ylabel_props.set_position (p.extract_n (0, 3).transpose ());
           ylabel_props.set_positionmode ("auto");
         }
@@ -5971,9 +6027,13 @@
   if (updating_zlabel_position)
     return;
 
+  graphics_object obj = gh_manager::get_object (get_zlabel ());
+
+  if (! obj.valid_object ())
+    return;
+
   text::properties& zlabel_props
-    = reinterpret_cast<text::properties&>
-        (gh_manager::get_object (get_zlabel ()).get_properties ());
+    = reinterpret_cast<text::properties&> (obj.get_properties ());
 
   bool camAuto = cameraupvectormode_is ("auto");
   bool is_empty = zlabel_props.get_string ().is_empty ();
@@ -6067,6 +6127,10 @@
       if (zlabel_props.positionmode_is ("auto"))
         {
           p = xform.untransform (p(0), p(1), p(2), true);
+
+          p = convert_label_position (p, zlabel_props, xform,
+                                      get_extent (false));
+
           zlabel_props.set_position (p.extract_n (0, 3).transpose ());
           zlabel_props.set_positionmode ("auto");
         }
@@ -6087,9 +6151,13 @@
   if (updating_title_position)
     return;
 
+  graphics_object obj = gh_manager::get_object (get_title ());
+
+  if (! obj.valid_object ())
+    return;
+
   text::properties& title_props
-    = reinterpret_cast<text::properties&>
-        (gh_manager::get_object (get_title ()).get_properties ());
+    = reinterpret_cast<text::properties&> (obj.get_properties ());
 
   unwind_protect frame;
   frame.protect_var (updating_title_position);
@@ -6118,6 +6186,8 @@
 
       p = xform.untransform (p(0), p(1), p(2), true);
 
+      p = convert_label_position (p, title_props, xform, bbox);
+
       title_props.set_position (p.extract_n (0, 3).transpose ());
       title_props.set_positionmode ("auto");
     }
@@ -8145,11 +8215,18 @@
   Matrix pos = get_position ().matrix_value ();
 
   pos = convert_text_position (pos, *this, cached_units, get_units ());
+
   // FIXME: if the current axes view is 2D, then one should
   // probably drop the z-component of "pos" and leave "zliminclude"
   // to "off".
+
+  bool autopos = positionmode_is ("auto");
+
   set_position (pos);
 
+  if (autopos)
+    set_positionmode ("auto");
+
   if (units_is ("data"))
     {
       set_xliminclude ("on");
@@ -9097,6 +9174,35 @@
       graphics_object obj (go);
 
       handle_map[h] = obj;
+
+      // Overriding defaults will work now because the handle is valid
+      // and we can find parent objects (not just handles).
+      obj.override_defaults ();
+
+      if (go_name == "axes")
+        {
+          // Handle defaults for labels since overriding defaults for
+          // them can't work before the axes object is fully
+          // constructed.
+
+          axes::properties& props =
+            dynamic_cast<axes::properties&> (obj.get_properties ());
+
+          graphics_object tgo;
+
+          tgo = gh_manager::get_object (props.get_xlabel ());
+          tgo.override_defaults ();
+
+          tgo = gh_manager::get_object (props.get_ylabel ());
+          tgo.override_defaults ();
+
+          tgo = gh_manager::get_object (props.get_zlabel ());
+          tgo.override_defaults ();
+
+          tgo = gh_manager::get_object (props.get_title ());
+          tgo.override_defaults ();
+        }
+
       if (do_createfcn)
         go->get_properties ().execute_createfcn ();
 
--- a/libinterp/corefcn/graphics.in.h	Wed Apr 08 21:39:24 2015 +0200
+++ b/libinterp/corefcn/graphics.in.h	Wed Apr 08 16:46:10 2015 -0400
@@ -1577,6 +1577,8 @@
     return *this;
   }
 
+  void invalidate (void) { current_val = octave_NaN; }
+
   base_property* clone (void) const { return new handle_property (*this); }
 
 protected:
@@ -3005,6 +3007,11 @@
     rep->override_defaults (obj);
   }
 
+  void override_defaults (void)
+  {
+    rep->override_defaults (*rep);
+  }
+
   void build_user_defaults_map (property_list::pval_map_type &def,
                                 const std::string go_name) const
   {
@@ -3535,9 +3542,7 @@
 public:
   figure (const graphics_handle& mh, const graphics_handle& p)
     : base_graphics_object (), xproperties (mh, p), default_properties ()
-  {
-    xproperties.override_defaults (*this);
-  }
+  { }
 
   ~figure (void) { }
 
@@ -4290,7 +4295,6 @@
     : base_graphics_object (), xproperties (mh, p), default_properties ()
   {
     xproperties.update_transform ();
-    xproperties.override_defaults (*this);
   }
 
   ~axes (void) { }
@@ -4440,9 +4444,7 @@
 public:
   line (const graphics_handle& mh, const graphics_handle& p)
     : base_graphics_object (), xproperties (mh, p)
-  {
-    xproperties.override_defaults (*this);
-  }
+  { }
 
   ~line (void) { }
 
@@ -4617,7 +4619,6 @@
     : base_graphics_object (), xproperties (mh, p)
   {
     xproperties.set_clipping ("off");
-    xproperties.override_defaults (*this);
   }
 
   ~text (void) { }
@@ -4825,7 +4826,6 @@
   image (const graphics_handle& mh, const graphics_handle& p)
     : base_graphics_object (), xproperties (mh, p)
   {
-    xproperties.override_defaults (*this);
     xproperties.initialize_data ();
   }
 
@@ -5015,9 +5015,7 @@
 public:
   patch (const graphics_handle& mh, const graphics_handle& p)
     : base_graphics_object (), xproperties (mh, p)
-  {
-    xproperties.override_defaults (*this);
-  }
+  { }
 
   ~patch (void) { }
 
@@ -5179,9 +5177,7 @@
 public:
   surface (const graphics_handle& mh, const graphics_handle& p)
     : base_graphics_object (), xproperties (mh, p)
-  {
-    xproperties.override_defaults (*this);
-  }
+  { }
 
   ~surface (void) { }
 
@@ -5259,9 +5255,7 @@
 public:
   hggroup (const graphics_handle& mh, const graphics_handle& p)
     : base_graphics_object (), xproperties (mh, p)
-  {
-    xproperties.override_defaults (*this);
-  }
+  { }
 
   ~hggroup (void) { }
 
@@ -5333,9 +5327,7 @@
 public:
   uimenu (const graphics_handle& mh, const graphics_handle& p)
     : base_graphics_object (), xproperties (mh, p)
-  {
-    xproperties.override_defaults (*this);
-  }
+  { }
 
   ~uimenu (void) { }
 
@@ -5388,9 +5380,7 @@
 public:
   uicontextmenu (const graphics_handle& mh, const graphics_handle& p)
     : base_graphics_object (), xproperties (mh, p)
-  {
-    xproperties.override_defaults (*this);
-  }
+  { }
 
   ~uicontextmenu (void) { }
 
@@ -5489,9 +5479,7 @@
 public:
   uicontrol (const graphics_handle& mh, const graphics_handle& p)
     : base_graphics_object (), xproperties (mh, p)
-  {
-    xproperties.override_defaults (*this);
-  }
+  { }
 
   ~uicontrol (void) { }
 
@@ -5564,9 +5552,7 @@
 public:
   uipanel (const graphics_handle& mh, const graphics_handle& p)
     : base_graphics_object (), xproperties (mh, p)
-  {
-    xproperties.override_defaults (*this);
-  }
+  { }
 
   ~uipanel (void) { }
 
@@ -5612,9 +5598,7 @@
 public:
   uitoolbar (const graphics_handle& mh, const graphics_handle& p)
     : base_graphics_object (), xproperties (mh, p), default_properties ()
-  {
-    xproperties.override_defaults (*this);
-  }
+  { }
 
   ~uitoolbar (void) { }
 
@@ -5723,9 +5707,7 @@
 public:
   uipushtool (const graphics_handle& mh, const graphics_handle& p)
     : base_graphics_object (), xproperties (mh, p)
-  {
-    xproperties.override_defaults (*this);
-  }
+  { }
 
   ~uipushtool (void) { }
 
@@ -5784,9 +5766,7 @@
 public:
   uitoggletool (const graphics_handle& mh, const graphics_handle& p)
     : base_graphics_object (), xproperties (mh, p)
-  {
-    xproperties.override_defaults (*this);
-  }
+  { }
 
   ~uitoggletool (void) { }