# HG changeset patch
# User Pantxo Diribarne <pantxo.diribarne@gmail.com>
# Date 1575839518 -3600
#      Sun Dec 08 22:11:58 2019 +0100
# Node ID 460cabb23cfdddef85dbb003fb45a178442e98e1
# Parent  14cf63e561f8a511e70a3de5573f8c54bc566bf3
Better documentation for legend objects (bug #57254)

* genpropdoc.m: New optionnal argument "props" to indicate that only a subset
  of properties should be printed. Add "legend" to the list of supported objects
  (getstructure): Add support for legend objects and eventually limited set of
  properties.
  (getdoc): Document legend specific properties in the axes section.

* legend.m: Rework doc and include a subset of legend specific properties.

* plot.txi: include legend properties after primitive objects.

* module.mk: Generate plot-legendproperties.texi.

diff -r 14cf63e561f8 -r 460cabb23cfd doc/interpreter/genpropdoc.m
--- a/doc/interpreter/genpropdoc.m	Sun Dec 08 17:52:18 2019 +0100
+++ b/doc/interpreter/genpropdoc.m	Sun Dec 08 22:11:58 2019 +0100
@@ -30,27 +30,27 @@
 ## @seealso{}
 ## @end deftypefn
 
-function genpropdoc (objname, fname)
+function genpropdoc (objname, fname = "", props = {})
   objnames = {"root", "figure", "axes", ...
               "image", "light", "line", "patch", "surface", "text", ...
               "uibuttongroup", "uicontextmenu", "uicontrol", "uipanel", ...
-              "uimenu", "uipushtool", "uitable", "uitoggletool" "uitoolbar"
-             };
+              "uimenu", "uipushtool", "uitable", "uitoggletool" "uitoolbar", ...
+              "legend"};
 
   ## Base properties
   base = getstructure ("base");
 
   ## Object properties
   if (any (strcmp (objname, objnames)))
-    obj = getstructure (objname, base);
+    obj = getstructure (objname, base, props);
   else
     error ("genpropdoc: unknown object %s", objname);
   endif
 
   ## Docstring
-  str = printdoc (objname, obj);
+  str = printdoc (objname, obj, ! isempty (props));
 
-  if (nargin == 2)
+  if (! isempty (fname))
     fid = fopen (fname,  "w+");
     if (fid < 0)
       error ("genpropdoc: couldn't open %s.", fname);
@@ -639,7 +639,7 @@
     endswitch
 
   ## Axes properties
-  elseif (strcmp (objname, "axes"))
+  elseif (strcmp (objname, "axes") || strcmp (objname, "legend"))
     switch (field)
       ## Overridden shared properties
       case "clipping"
@@ -660,7 +660,7 @@
         s.doc = doc_unused;
 
       case "box"
-        s.doc = "Control whether the axes has a surrounding box.";
+        s.doc = "Control whether the __objname__ has a surrounding box.";
 
       case "boxstyle"
         s.doc = "For 3-D axes, control whether the @qcode{\"full\"} \
@@ -693,7 +693,8 @@
         s.doc = doc_unused;
 
       case "color"
-        s.doc = "Color of the axes background.  @xref{Colors, , colorspec}.";
+        s.doc = "Color of the __objname__ background.  \
+@xref{Colors, , colorspec}.";
         s.valid = valid_color;
 
       case "colororder"
@@ -816,7 +817,13 @@
 
       case "plotboxaspectratiomode"
       case "position"
-        s.doc = "Specify the position of the plot excluding titles, \
+        if (strcmp (objname, "legend"))
+          s.doc = "Specify the position of the legend excluding title. \
+The four elements of the vector are the coordinates of the lower left corner \
+and width and height of the legend.  Changing this property also \
+switches the @qcode{\"location\"} to @qcode{\"none\"}.";
+        else
+          s.doc = "Specify the position of the plot excluding titles, \
 axes, and legend.  The four elements of the vector are the \
 coordinates of the lower left corner and width and height of the \
 plot, in units normalized to the width and height of the plot \
@@ -824,6 +831,7 @@
 left corner of the axes at @math{(0.2, 0.3)} and the width and \
 height to be 0.4 and 0.5 respectively.  \
 @xref{XREFaxesouterposition, , @w{outerposition property}}.";
+        endif
         s.valid = valid_4elvec;
 
       case "projection"
@@ -866,8 +874,13 @@
         s.doc = "Control variant of base font used for the axes title.";
 
       case "units"
-        s.doc = "Units used to interpret the @qcode{\"position\"}, \
+        if (strcmp (objname, "legend"))
+          s.doc = "Units used to interpret the @qcode{\"position\"}, \
+ property.";
+        else
+          s.doc = "Units used to interpret the @qcode{\"position\"}, \
 @qcode{\"outerposition\"}, and @qcode{\"tightinset\"} properties.";
+        endif
 
       case "view"
         s.doc = "Two-element vector @code{[azimuth elevation]} specifying \
@@ -1003,6 +1016,45 @@
         s.doc = doc_unused;
 
       case "ztickmode"
+
+      ## Legend specific properties
+      case "autoupdate"
+        s.doc = "Control wether the legend item are updated when new objects \
+are added to the peer axes.";
+
+      case "edgecolor"
+        s.doc = "Control the color of the legend outline.";
+        s.valid = valid_color;
+
+      case "interpreter"
+        s.doc = "Control if and eventually how labels strings are interpreted \
+before rendering.";
+
+      case "location"
+        s.doc = "Control the location of the legend.";
+
+      case "numcolumns"
+        s.doc = "Control the the number of columns used to layout legend item. \
+ __modemsg__.";
+        s.valid = "scalar interger";
+
+      case "orientation"
+        s.doc = "Control wether the legend item are arranged vertically \
+(column-wise) or horizontally (row-wise).";
+
+      case "string"
+        s.doc = "List of labels for the legend item.";
+        s.valid = valid_cellstring;
+        s.printdefault = false;
+
+      case "textcolor"
+        s.doc = "Control the color of the text strings for legend item.";
+        s.valid = valid_color;
+
+      case "textcolor"
+        s.doc = "Control wether text strings are displayed on the left or \
+right of their corresponding icon.";
+
     endswitch
 
   ## Line properties
@@ -1838,7 +1890,7 @@
   strout = strrep (strout, "__fcnmsg__", fcnmsg);
 endfunction
 
-function s = getstructure (objname, base = [])
+function s = getstructure (objname, base = [], props = {})
   hf = [];
   if (! strcmp (objname, "root"))
     ## Use an improbable number to avoid ishghandle to return true for 1
@@ -1854,6 +1906,15 @@
     h = 0;
   elseif (strcmp (objname, "figure"))
     h = hf;
+  elseif (strcmp (objname, "legend"))
+    line ();
+    h = legend ();
+    if (isempty (props))
+        props = {"autoupdate", "box", "color", "edgecolor", "fontangle", ...
+                 "fontname", "fontsize", "fontunits", "fontweight", ...
+                 "location", "numcolumns", "orientation", "position", ...
+                 "string", "textcolor", "title", "units"};
+    endif
   else
     eval (["h = " objname " ();"]);
   endif
@@ -1861,6 +1922,15 @@
   gprop = get (h);
   sprop = set (h);
 
+  if (! isempty (props))
+    flds = fieldnames (gprop);
+    idx = cellfun (@(s) ! any (strcmp (props, s)), flds);
+    gprop = rmfield (gprop, flds(idx));
+    flds = fieldnames (sprop);
+    idx = cellfun (@(s) ! any (strcmp (props, s)), flds);
+    sprop = rmfield (sprop, flds(idx));
+  endif
+
   fields = fieldnames (gprop);
   nf = numel (fields);
   args = cell (2*nf, 1);
@@ -1948,7 +2018,7 @@
 
 endfunction
 
-function str = printdoc (objname, obj)
+function str = printdoc (objname, obj, is_prop_subset)
   ## Sort fields so that they appear in alphabetic order in the manual
   fields = sort (fieldnames (obj));
   nf = numel (fields);
@@ -1957,6 +2027,8 @@
   str = warn_autogen ();
   if (strcmp (objname, "root"))
     str = sprintf ("%s\n\nProperties of the root graphics object:", str);
+  elseif (is_prop_subset)
+    ## Do nothing
   else
     str = sprintf ("%s\n\nProperties of @code{%s} objects (@pxref{XREF%s,,%s}):",
                    str, objname, objname, objname);
@@ -1967,10 +2039,12 @@
     field = fields{ii};
     str = sprintf ("%s\n\n", str);
 
-    ## @anchor: cross reference using XREFobjnamefield label
-    ## Concept index: call info from octave with 'doc ("objname field")'
-    str = sprintf ("%s@anchor{XREF%s%s}\n@prindex %s %s\n",
-                   str, objname, field, objname, field);
+    if (! is_prop_subset)
+      ## @anchor: cross reference using XREFobjnamefield label
+      ## Concept index: call info from octave with 'doc ("objname field")'
+      str = sprintf ("%s@anchor{XREF%s%s}\n@prindex %s %s\n",
+                     str, objname, field, objname, field);
+    endif
 
     ## Item
     str = sprintf ("%s@item @code{%s}", str, field);
diff -r 14cf63e561f8 -r 460cabb23cfd doc/interpreter/module.mk
--- a/doc/interpreter/module.mk	Sun Dec 08 17:52:18 2019 +0100
+++ b/doc/interpreter/module.mk	Sun Dec 08 22:11:58 2019 +0100
@@ -4,6 +4,7 @@
   %reldir%/plot-axesproperties.texi \
   %reldir%/plot-figureproperties.texi \
   %reldir%/plot-imageproperties.texi \
+  %reldir%/plot-legendproperties.texi \
   %reldir%/plot-lightproperties.texi \
   %reldir%/plot-lineproperties.texi \
   %reldir%/plot-patchproperties.texi \
@@ -39,6 +40,9 @@
 %reldir%/plot-imageproperties.texi: %reldir%/genpropdoc.m $(GRAPHICS_PROPS_SRC)
 	$(AM_V_GEN)$(call gen-propdoc-texi,image)
 
+%reldir%/plot-legendproperties.texi: %reldir%/genpropdoc.m $(GRAPHICS_PROPS_SRC)
+	$(AM_V_GEN)$(call gen-propdoc-texi,legend)
+
 %reldir%/plot-lightproperties.texi: %reldir%/genpropdoc.m $(GRAPHICS_PROPS_SRC)
 	$(AM_V_GEN)$(call gen-propdoc-texi,light)
 
diff -r 14cf63e561f8 -r 460cabb23cfd doc/interpreter/plot.txi
--- a/doc/interpreter/plot.txi	Sun Dec 08 17:52:18 2019 +0100
+++ b/doc/interpreter/plot.txi	Sun Dec 08 22:11:58 2019 +0100
@@ -1499,6 +1499,7 @@
 * Uitoolbar Properties::
 * Uipushtool Properties::
 * Uitoggletool Properties::
+* Legend Properties::
 @end menu
 
 In this section the graphics object properties are discussed in detail,
@@ -1629,6 +1630,12 @@
 
 @include plot-uitoggletoolproperties.texi
 
+@node Legend Properties
+@subsubsection Legend Properties
+@prindex @sortas{@ Legend Properties} Legend Properties
+
+@include plot-legendproperties.texi
+
 @node Searching Properties
 @subsection Searching Properties
 
diff -r 14cf63e561f8 -r 460cabb23cfd scripts/plot/appearance/legend.m
--- a/scripts/plot/appearance/legend.m	Sun Dec 08 17:52:18 2019 +0100
+++ b/scripts/plot/appearance/legend.m	Sun Dec 08 22:11:58 2019 +0100
@@ -45,24 +45,6 @@
 ## labeling all objects, provide their graphic handles in the input
 ## @var{hobjs}.
 ##
-## The optional parameter @var{loc} specifies the location of the legend as
-## follows:
-##
-## @multitable @columnfractions 0.06 0.14 0.80
-## @headitem @tab loc @tab location of the legend
-## @item @tab north @tab center top
-## @item @tab south @tab center bottom
-## @item @tab east @tab right center
-## @item @tab west @tab left center
-## @item @tab northeast @tab right top (default)
-## @item @tab northwest @tab left top
-## @item @tab southeast @tab right bottom
-## @item @tab southwest @tab left bottom
-## @sp 1
-## @item @tab outside @tab can be appended to any location string @*
-## @item @tab         @tab which will place the legend outside the axes
-## @end multitable
-##
 ## The following customizations are available using @var{command}:
 ##
 ## @table @asis
@@ -97,6 +79,39 @@
 ## including @var{property}/@var{value} pairs.  If using this calling form, the
 ## labels must be specified as a cell array of strings.
 ##
+## Following is a subset of supported legend properties:
+## @table @asis
+##
+## @item @code{autoupdate}: @qcode{"off"} | @{@qcode{"on"}@}
+## Control wether the legend item are updated when new objects are added to the peer axes.
+##
+## @item @code{box}: @qcode{"off"} | @{@qcode{"on"}@}
+## Control whether the legend has a surrounding box.
+##
+## @item @code{location}: @qcode{"best"} | @qcode{"bestoutside"} | @qcode{"east"} | @qcode{"eastoutside"} | @qcode{"none"} | @qcode{"north"} | @{@qcode{"northeast"}@} | @qcode{"northeastoutside"} | @qcode{"northoutside"} | @qcode{"northwest"} | @qcode{"northwestoutside"} | @qcode{"south"} | @qcode{"southeast"} | @qcode{"southeastoutside"} | @qcode{"southoutside"} | @qcode{"southwest"} | @qcode{"southwestoutside"} | @qcode{"west"} | @qcode{"westoutside"}
+## Control the location of the legend.
+##
+##
+## @item @code{numcolumns}: scalar interger, def. @code{1}
+## Control the the number of columns used to layout legend item.  Setting @code{numcolumns} also forces the @code{numcolumnsmode} property to be set to @qcode{"manual"}.
+##
+## @item @code{orientation}: @qcode{"horizontal"} | @{@qcode{"vertical"}@}
+## Control wether the legend item are arranged vertically (column-wise) or horizontally (row-wise).
+##
+## @item @code{string}: string | cell array of strings
+## List of labels for the legend item.
+##
+## @item @code{textcolor}: colorspec, def. @code{[0   0   0]}
+## Control the color of the text strings for legend item.
+##
+## @end table
+## The full list of supported legend specific properties can be found at
+## @ref{Legend Properties, , Legend Properties}.
+##
+## A legend is implemented as an additional axes object with the @code{tag}
+## property set to @qcode{"legend"}.  Properties of the legend object may be
+## manipulated directly by using @code{set}.
+##
 ## The optional output value @var{hleg} is a handle to the legend object.
 ##
 ## Implementation Note: The legend label text is either provided in the call to
@@ -110,10 +125,6 @@
 ## The legend @code{FontSize} property is initially set to 90% of the axes
 ## @code{FontSize} to which it is attached.  Use @code{set} to override this
 ## if necessary.
-##
-## A legend is implemented as an additional axes object with the @code{tag}
-## property set to @qcode{"legend"}.  Properties of the legend object may be
-## manipulated directly by using @code{set}.
 ## @end deftypefn
 
 function [hleg, hleg_obj, hplot, labels] = legend (varargin)
