# HG changeset patch
# User Markus Mützel <markus.muetzel@gmx.de>
# Date 1544874798 -3600
#      Sat Dec 15 12:53:18 2018 +0100
# Node ID bc0a25be029f271dabf48e0f025db5ca1e61cd18
# Parent  7902a3a8f02cbd34704c6f3e76aa8b01b96917ab
Add (failing) BISTs for uibuttongroup (bug #55230).

* graphics.cc (uibuttongroup::properties::adopt,
  uibuttongroup::properties::remove_child): Add new functions.

* graphics.cc (uicontrol::properties::set_style,
  uibuttongroup::properties::adopt,
  uibuttongroup::properties::remove_child): Update "selectedobject" and "value".

* uibuttongroup.m: Make the demo resizable. Add BISTs for programmatic
  interaction.

diff -r 7902a3a8f02c -r bc0a25be029f libinterp/corefcn/graphics.cc
--- a/libinterp/corefcn/graphics.cc	Fri Dec 28 22:05:27 2018 -0800
+++ b/libinterp/corefcn/graphics.cc	Sat Dec 15 12:53:18 2018 +0100
@@ -10485,6 +10485,26 @@
 void
 uicontrol::properties::set_style (const octave_value& st)
 {
+  graphics_object go = gh_manager::get_object (get_parent ());
+  if (go.valid_object () && go.isa ("uibuttongroup"))
+    {
+      bool was_button = style_is ("radiobutton") || style_is ("togglebutton");
+      style = st;
+      bool now_button = style_is ("radiobutton") || style_is ("togglebutton");
+      uibuttongroup::properties& props =
+        dynamic_cast<uibuttongroup::properties&> (go.get_properties ());
+      // update selectedobject
+      if (! was_button && now_button && ! props.get_selectedobject ().ok ())
+        {
+          props.set_selectedobject (get___myhandle__ ().value ());
+          value.set (octave_value (1));
+        }
+      else if (was_button && ! now_button
+          && (props.get_selectedobject ().value ()
+              == get___myhandle__ ().value ()))
+        props.set_selectedobject (Matrix ());
+    }
+
   style = st;
 
   // if we know know what we are, can override value for listbox and popupmenu
@@ -10761,6 +10781,37 @@
   err_set_invalid ("selectedobject");
 }
 
+void
+uibuttongroup::properties::adopt (const graphics_handle& h)
+{
+  base_properties::adopt (h);
+
+  graphics_handle current_selected = get_selectedobject ();
+  bool has_selected = current_selected.ok ();
+  graphics_object go = gh_manager::get_object (h);
+
+  if (! has_selected && go.valid_object () && go.isa ("uicontrol"))
+    {
+      const uicontrol::properties& props =
+        dynamic_cast<const uicontrol::properties&> (go.get_properties ());
+      if (props.style_is ("radiobutton") || props.style_is ("togglebutton"))
+        {
+          set_selectedobject (h.value ());
+        }
+    }
+}
+
+void
+uibuttongroup::properties::remove_child (const graphics_handle& h)
+{
+  graphics_handle current_selected = get_selectedobject ();
+  if (h.value () == current_selected.value ())
+    set_selectedobject (Matrix ());
+
+  base_properties::remove_child (h);
+
+}
+
 // ---------------------------------------------------------------------
 
 Matrix
diff -r 7902a3a8f02c -r bc0a25be029f libinterp/corefcn/graphics.in.h
--- a/libinterp/corefcn/graphics.in.h	Fri Dec 28 22:05:27 2018 -0800
+++ b/libinterp/corefcn/graphics.in.h	Sat Dec 15 12:53:18 2018 +0100
@@ -5599,6 +5599,9 @@
     void update_units (const caseless_str& old_units);
     void update_fontunits (const caseless_str& old_units);
 
+    void adopt (const graphics_handle& h);
+    void remove_child (const graphics_handle& h);
+
   };
 
 private:
diff -r 7902a3a8f02c -r bc0a25be029f scripts/gui/uibuttongroup.m
--- a/scripts/gui/uibuttongroup.m	Fri Dec 28 22:05:27 2018 -0800
+++ b/scripts/gui/uibuttongroup.m	Sat Dec 15 12:53:18 2018 +0100
@@ -82,29 +82,122 @@
 
 
 %!demo
-%! f = figure;
-%! gp = uibuttongroup (f, "Position", [ 0 0.5 1 1], ...
+%! f = clf ();
+%! gp = uibuttongroup (f, "position", [0 0.5 1 0.5], ...
 %!                     "selectionchangedfcn", ...
-%!                     @(x, y) display (['Selection Changed: ' get(y.NewValue, 'String')]));
+%!                     @(h, e) fprintf ("Selection changed: %s\n", get (e.NewValue, "string")));
 %! b1 = uicontrol (gp, "style", "radiobutton", ...
 %!                 "string", "Choice 1", ...
-%!                 "Position", [ 10 150 100 50 ]);
+%!                 "units", "normalized", ...
+%!                 "position", [0.01 0.5 0.98 0.5]);
 %! b2 = uicontrol (gp, "style", "radiobutton", ...
 %!                 "string", "Choice 2", ...
-%!                 "Position", [ 10 50 100 30 ]);
+%!                 "units", "normalized", ...
+%!                 "position", [0.01 0 0.98 0.5]);
 %! b3 = uicontrol (f, "style", "radiobutton", ...
 %!                 "string", "Not in the group", ...
-%!                 "Position", [ 10 50 100 50 ]);
-%! disp (['Current selected: ' get(get(gp, 'selectedobject'), 'String')]);
+%!                 "units", "normalized", ...
+%!                 "position", [ 0.01 0 0.98 0.5 ]);
+%! fprintf ("Current selected: %s\n", get (get (gp, "selectedobject"), "string"));
 %! pause (0.5);
-%! disp (['Select None']);
-%! set (gp, 'selectedobject', []);
+%! disp ("Select b2");
+%! set (gp, "selectedobject", b2);
+%! fprintf ("Current selected: %s\n", get (get (gp, "selectedobject"), "string"));
+%! pause (0.5);
+%! disp ("Select None");
+%! set (gp, "selectedobject", []);
 %! pause (0.1);
-%! disp (['Current selected: ' get(get(gp, 'selectedobject'), 'String')]);
-%! pause (0.5);
-%! disp (['Select b1']);
-%! set (gp, 'selectedobject', b1);
-%! disp (['Current selected: ' get(get(gp, 'selectedobject'), 'String')]);
+%! fprintf ("Current selected: %s\n", get (get (gp, "selectedobject"), "string"));
 
-## Uncertain if tests can be performed
-%!assert (1)
+## Test mutual selection logic for radiobuttons
+%!test <55230*>
+%! hf = figure ("visible", "off");
+%! unwind_protect
+%!   bg = uibuttongroup (hf);
+%!   b1 = uicontrol (bg, "style", "radiobutton");
+%!   b2 = uicontrol (bg, "style", "radiobutton");
+%!   assert (get (bg, "selectedobject"), b1);
+%!   assert (get (b1, "value"), 1);
+%!   assert (get (b2, "value"), 0);
+%!   ## select radiobutton 2
+%!   set (bg, "selectedobject", b2);
+%!   pause (0.1);
+%!   assert (get (b1, "value"), 0);
+%!   assert (get (b2, "value"), 1);
+%!   ## set radiobutton 1
+%!   set (b1, "value", 1);
+%!   pause (0.1);
+%!   assert (get (bg, "selectedobject"), b1);
+%!   assert (get (b1, "value"), 1);
+%!   assert (get (b2, "value"), 0);
+%!   ## unset all radiobuttons
+%!   set (bg, "selectedobject", []);
+%!   pause (0.1);
+%!   assert (get (b1, "value"), 0);
+%!   assert (get (b2, "value"), 0);
+%!   ## change style of selected button
+%!   set (b1, "value", 1);
+%!   pause (0.1);
+%!   assert (get (bg, "selectedobject"), b1);
+%!   set (b1, "style", "pushbutton");
+%!   pause (0.1);
+%!   assert (get (bg, "selectedobject"), []);
+%!   ## add new button
+%!   b3 = uicontrol (bg, "style", "togglebutton");
+%!   pause (0.1);
+%!   assert (get (bg, "selectedobject"), b3);
+%!   assert (get (b2, "value"), 0);
+%!   assert (get (b3, "value"), 1);
+%!   ## remove selected button
+%!   delete (b3);
+%!   pause (0.1);
+%!   assert (get (bg, "selectedobject"), []);
+%! unwind_protect_cleanup
+%!   close (hf);
+%! end_unwind_protect
+
+## Test mutual selection logic for togglebuttons
+%!test <55230*>
+%! hf = figure ("visible", "off");
+%! unwind_protect
+%!   bg = uibuttongroup (hf);
+%!   b1 = uicontrol (bg, "style", "togglebutton");
+%!   b2 = uicontrol (bg, "style", "togglebutton");
+%!   assert (get (bg, "selectedobject"), b1);
+%!   assert (get (b1, "value"), 1);
+%!   assert (get (b2, "value"), 0);
+%!   ## select togglebutton 2
+%!   set (bg, "selectedobject", b2);
+%!   pause (0.1);
+%!   assert (get (b1, "value"), 0);
+%!   assert (get (b2, "value"), 1);
+%!   ## set togglebutton 1
+%!   set (b1, "value", 1);
+%!   pause (0.1);
+%!   assert (get (bg, "selectedobject"), b1);
+%!   assert (get (b1, "value"), 1);
+%!   assert (get (b2, "value"), 0);
+%!   ## unset all togglebuttons
+%!   set (bg, "selectedobject", []);
+%!   pause (0.1);
+%!   assert (get (b1, "value"), 0);
+%!   assert (get (b2, "value"), 0);
+%!   ## change style of selected button
+%!   set (b1, "value", 1);
+%!   pause (0.1);
+%!   assert (get (bg, "selectedobject"), b1);
+%!   set (b1, "style", "pushbutton");
+%!   assert (get (bg, "selectedobject"), []);
+%!   ## add new button
+%!   b3 = uicontrol (bg, "style", "togglebutton");
+%!   pause (0.1);
+%!   assert (get (bg, "selectedobject"), b3);
+%!   assert (get (b2, "value"), 0);
+%!   assert (get (b3, "value"), 1);
+%!   ## remove selected button
+%!   delete (b3);
+%!   pause (0.1);
+%!   assert (get (bg, "selectedobject"), []);
+%! unwind_protect_cleanup
+%!   close (hf);
+%! end_unwind_protect
