changeset 30622:18a9b3c7b63b

legend.m: Implement "itemhitfcn" property * gendpropdoc.m: Document new property * legend.m (execute_item_hit): New callback function. (create_item): Change "buttondownfcn" of legend item objects to run execute_item_hit.
author Pantxo Diribarne <pantxo.diribarne@gmail.com>
date Sun, 09 Jan 2022 16:57:26 +0100
parents 7fa86ceb8077
children 3b2140303d33
files doc/interpreter/genpropdoc.m scripts/plot/appearance/legend.m
diffstat 2 files changed, 66 insertions(+), 10 deletions(-) [+]
line wrap: on
line diff
--- a/doc/interpreter/genpropdoc.m	Sun Jan 09 16:32:38 2022 +0100
+++ b/doc/interpreter/genpropdoc.m	Sun Jan 09 16:57:26 2022 +0100
@@ -1064,6 +1064,29 @@
 before rendering.\n\
 @xref{XREFinterpreterusage, , @w{Use of the interpreter property}}.";
 
+      case "itemhitfcn"
+        s.doc = "Callback function which is executed when a legend item \
+is clicked.  @xref{Callbacks, , @w{Callbacks section}}.\n\
+\n\
+The callback function must have the following prototype \
+@code{fcn (hlegend, evnt)}, where @code{hlegend} is the legend object handle \
+and @code{evnt} is a structure with the following fields:\n\
+@table @code\n\
+@item Peer\n\
+Handle of the plot object to which the clicked item is associated.\n\
+@item Region\n\
+May be @qcode{\"icon\"} or @qcode{\"label\"} depending on which part of \
+the item is clicked.\n\
+@item SelectionType\n\
+One of @qcode{\"normal\"}, @qcode{\"extend\"}, @qcode{\"open\"}, or \
+@qcode{\"alt\"}. \
+@xref{XREFfigureselectiontype, , @w{Figure @qcode{\"selectiontype\"}}}.\n\
+@item Source\n\
+Handle of the legend object.\n\
+@item EventName\n\
+Name is @qcode{\"ItemHit\"}.\n\
+@end table";
+
       case "location"
         s.doc = "Control the location of the legend.";
 
@@ -2077,8 +2100,8 @@
     if (isempty (props))
         props = {"autoupdate", "box", "color", "edgecolor", "fontangle", ...
                  "fontname", "fontsize", "fontunits", "fontweight", ...
-                 "location", "numcolumns", "orientation", "position", ...
-                 "string", "textcolor", "title", "units"};
+                 "itemhitfcn", "location", "numcolumns", "orientation", ...
+                 "position", "string", "textcolor", "title", "units"};
     endif
   elseif (strcmp (objname, "scatter"))
     ## Make sure to get a scatter object independent of graphics toolkit
--- a/scripts/plot/appearance/legend.m	Sun Jan 09 16:32:38 2022 +0100
+++ b/scripts/plot/appearance/legend.m	Sun Jan 09 16:57:26 2022 +0100
@@ -308,7 +308,7 @@
                       "deletefcn", {@reset_cb, hl});
 
     ## Listeners to foreign objects properties are stored for later
-    ## deletion in "delfunction"
+    ## deletion in "reset_cb"
     hax = opts.axes_handles(1);
     hf = ancestor (hax, "figure");
 
@@ -350,7 +350,7 @@
 
     addlistener (hl, "textcolor", ...
                  @(h, ~) set (findobj (h, "type", "text"), ...
-                               "color", get (hl, "textcolor")));
+                              "color", get (hl, "textcolor")));
 
     addlistener (hl, "visible", @update_visible_cb);
 
@@ -1076,14 +1076,21 @@
 
       ## Main line
       vals = get (hplt(1), lprops);
-      hicon = __go_line__ (hl, [lprops; vals]{:});
+      hicon = __go_line__ (hl, [lprops; vals]{:}, ...
+                           "pickableparts", "all", ...
+                           "buttondownfcn", ...
+                           {@execute_itemhit, hl, hplt, "icon"});
+
       addproperty ("markerxdata", hicon, "double", 0);
       addproperty ("markerydata", hicon, "double", 0);
 
       ## Additional line for the marker
       vals = get (hplt(end), mprops);
       hmarker = __go_line__ (hl, "handlevisibility", "off", ...
-                             "xdata", 0, "ydata", 0, [mprops; vals]{:});
+                             "xdata", 0, "ydata", 0, [mprops; vals]{:}, ...
+                             "pickableparts", "all", ...
+                             "buttondownfcn", ...
+                             {@execute_itemhit, hl, hplt, "icon"});
       update_marker_cb (hmarker);
 
       ## Listeners
@@ -1127,7 +1134,10 @@
       vals {end-1} = mean (vals {end-1}, 1);
       vals {end} = mean (vals {end}, 1);
 
-      hicon = __go_scatter__ (hl, [all_sprops; vals]{:});
+      hicon = __go_scatter__ (hl, [all_sprops; vals]{:}, ...
+                              "pickableparts", "all", ...
+                              "buttondownfcn", ...
+                              {@execute_itemhit, hl, hplt, "icon"});
 
       ## Simple Listeners
       safe_property_link (hplt(1), hicon, sprops);
@@ -1151,7 +1161,10 @@
       ## Main patch
 
       vals = get (hplt(1), pprops);
-      hicon = __go_patch__ (hl, [pprops; vals]{:});
+      hicon = __go_patch__ (hl, [pprops; vals]{:}, ...
+                            "pickableparts", "all", ...
+                            "buttondownfcn", ...
+                            {@execute_itemhit, hl, hplt, "icon"});
 
       addproperty ("innerxdata", hicon, "any", 0);
       addproperty ("innerydata", hicon, "any", 0);
@@ -1159,7 +1172,10 @@
       ## Additional patch for the inner contour
       vals = get (hplt(end), pprops);
       htmp =  __go_patch__ (hl, "handlevisibility", "off", ...
-                            "xdata", 0, "ydata", 0, [pprops; vals]{:});
+                            "xdata", 0, "ydata", 0, [pprops; vals]{:}, ...
+                            "pickableparts", "all", ...
+                            "buttondownfcn", ...
+                            {@execute_itemhit, hl, hplt, "icon"});
 
       ## Listeners
       safe_property_link (hplt(1), hicon, pprops);
@@ -1177,13 +1193,30 @@
 
   endswitch
 
-  htxt = __go_text__ (hl, txtpval{:}, "string", str);
+  htxt = __go_text__ (hl, txtpval{:}, "string", str, ...
+                      "pickableparts", "all", ...
+                      "buttondownfcn", {@execute_itemhit, hl, hplt, "label"});
+
+  set (htxt, "buttondownfcn", {@execute_itemhit, hl, hplt, "label"});
 
   addproperty ("peer_object", htxt, "double", base_hplt);
   addproperty ("peer_object", hicon, "double", base_hplt);
 
 endfunction
 
+function execute_itemhit (h, ~, hl, hplt, region)
+
+  fcn = get (hl, "itemhitfcn");
+
+  if (! isempty (fcn))
+    evt = struct ("Peer", hplt, "Region", region, ...
+                  "SelectionType", get (gcbf (), "selectiontype"), ...
+                  "Source", hl, "EventName", "ItemHit");
+    fcn (hl, evt)
+  endif
+
+endfunction
+
 function safe_property_link (h1, h2, props)
 
   for ii = 1:numel (props)