Mercurial > octave
changeset 27730:5b9067c17e4b
Keep track of children in uibuttongroup (bug #55230).
* graphics.in.h (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.
author | Markus Mützel <markus.muetzel@gmx.de> |
---|---|
date | Sat, 15 Dec 2018 12:53:18 +0100 |
parents | 718845eb3c7a |
children | f9c334a207bb |
files | libinterp/corefcn/graphics.cc libinterp/corefcn/graphics.in.h scripts/gui/uibuttongroup.m |
diffstat | 3 files changed, 180 insertions(+), 22 deletions(-) [+] |
line wrap: on
line diff
--- a/libinterp/corefcn/graphics.cc Wed Nov 20 19:34:15 2019 -0600 +++ b/libinterp/corefcn/graphics.cc Sat Dec 15 12:53:18 2018 +0100 @@ -10885,6 +10885,29 @@ void uicontrol::properties::set_style (const octave_value& st) { + gh_manager& gh_mgr + = octave::__get_gh_manager__ ("uicontrol::properties::set_style"); + + graphics_object go_parent = gh_mgr.get_object (get_parent ()); + if (go_parent.valid_object () && go_parent.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_parent.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 ()); + } + // Don't notify the style change until the "value" property is fixed bool modified = style.set (st, true, false); @@ -10900,9 +10923,6 @@ // Notify toolkit - gh_manager& gh_mgr - = octave::__get_gh_manager__ ("uicontrol::properties::set_style"); - graphics_object go = gh_mgr.get_object (get___myhandle__ ()); if (go) @@ -11190,6 +11210,39 @@ err_set_invalid ("selectedobject"); } +void +uibuttongroup::properties::remove_child (const graphics_handle& h, + bool from_root) +{ + graphics_handle current_selected = get_selectedobject (); + if (h.value () == current_selected.value ()) + set_selectedobject (Matrix ()); + + base_properties::remove_child (h, from_root); +} + +void +uibuttongroup::properties::adopt (const graphics_handle& h) +{ + base_properties::adopt (h); + + graphics_handle current_selected = get_selectedobject (); + bool has_selected = current_selected.ok (); + + gh_manager& gh_mgr + = octave::__get_gh_manager__ ("uibuttongroup::properties::adopt"); + + graphics_object go = gh_mgr.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 ()); + } +} + // --------------------------------------------------------------------- Matrix
--- a/libinterp/corefcn/graphics.in.h Wed Nov 20 19:34:15 2019 -0600 +++ b/libinterp/corefcn/graphics.in.h Sat Dec 15 12:53:18 2018 +0100 @@ -5602,6 +5602,10 @@ class OCTINTERP_API properties : public base_properties { public: + void remove_child (const graphics_handle& h, bool from_root = false); + + void adopt (const graphics_handle& h); + Matrix get_boundingbox (bool internal = false, const Matrix& parent_pix_size = Matrix ()) const;
--- a/scripts/gui/uibuttongroup.m Wed Nov 20 19:34:15 2019 -0600 +++ b/scripts/gui/uibuttongroup.m Sat Dec 15 12:53:18 2018 +0100 @@ -81,29 +81,130 @@ %!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 ]); +%! "string", "Choice 1", ... +%! "units", "normalized", ... +%! "position", [0.01 0.5 0.98 0.5]); %! b2 = uicontrol (gp, "style", "radiobutton", ... -%! "string", "Choice 2", ... -%! "Position", [ 10 50 100 30 ]); +%! "string", "Choice 2", ... +%! "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')]); +%! "string", "Not in the group", ... +%! "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 +## FIXME: commented out until a test can be found that doesn't rely on +## long values for pause() which still can occasionally fail. +%!#test <*55230> +%! hf = figure ("visible", "off"); +%! unwind_protect +%! bg = uibuttongroup (hf); +%! b1 = uicontrol (bg, "style", "radiobutton", "units", "normalized", ... +%! "position", [0, 0, 1, 0.5]); +%! b2 = uicontrol (bg, "style", "radiobutton", "units", "normalized", ... +%! "position", [0, 0.5, 1, 0.5]); +%! assert (get (bg, "selectedobject"), b1); +%! assert (get (b1, "value"), 1); +%! assert (get (b2, "value"), 0); +%! ## select radiobutton 2 +%! set (bg, "selectedobject", b2); +%! pause (0.5); +%! assert (get (b1, "value"), 0); +%! assert (get (b2, "value"), 1); +%! ## set radiobutton 1 +%! set (b1, "value", 1); +%! pause (0.5); +%! assert (get (bg, "selectedobject"), b1); +%! assert (get (b1, "value"), 1); +%! assert (get (b2, "value"), 0); +%! ## unset all radiobuttons +%! set (bg, "selectedobject", []); +%! pause (0.5); +%! assert (get (b1, "value"), 0); +%! assert (get (b2, "value"), 0); +%! ## change style of selected button +%! set (b1, "value", 1); +%! pause (0.5); +%! assert (get (bg, "selectedobject"), b1); +%! set (b1, "style", "pushbutton"); +%! pause (0.5); +%! assert (get (bg, "selectedobject"), []); +%! ## add new button +%! b3 = uicontrol (bg, "style", "togglebutton"); +%! pause (0.5); +%! assert (get (bg, "selectedobject"), b3); +%! assert (get (b2, "value"), 0); +%! assert (get (b3, "value"), 1); +%! ## remove selected button +%! delete (b3); +%! pause (0.5); +%! assert (get (bg, "selectedobject"), []); +%! unwind_protect_cleanup +%! close (hf); +%! end_unwind_protect + +## Test mutual selection logic for togglebuttons +## FIXME: commented out until a test can be found that doesn't rely on +## long values for pause() which still can occasionally fail. +%!#test <*55230> +%! hf = figure ("visible", "off"); +%! unwind_protect +%! bg = uibuttongroup (hf); +%! b1 = uicontrol (bg, "style", "togglebutton", "units", "normalized", ... +%! "position", [0, 0, 1, 0.5]); +%! b2 = uicontrol (bg, "style", "togglebutton", "units", "normalized", ... +%! "position", [0, 0.5, 1, 0.5]); +%! assert (get (bg, "selectedobject"), b1); +%! assert (get (b1, "value"), 1); +%! assert (get (b2, "value"), 0); +%! ## select togglebutton 2 +%! set (bg, "selectedobject", b2); +%! pause (0.5); +%! assert (get (b1, "value"), 0); +%! assert (get (b2, "value"), 1); +%! ## set togglebutton 1 +%! set (b1, "value", 1); +%! pause (0.5); +%! assert (get (bg, "selectedobject"), b1); +%! assert (get (b1, "value"), 1); +%! assert (get (b2, "value"), 0); +%! ## unset all togglebuttons +%! set (bg, "selectedobject", []); +%! pause (0.5); +%! assert (get (b1, "value"), 0); +%! assert (get (b2, "value"), 0); +%! ## change style of selected button +%! set (b1, "value", 1); +%! pause (0.5); +%! assert (get (bg, "selectedobject"), b1); +%! set (b1, "style", "pushbutton"); +%! assert (get (bg, "selectedobject"), []); +%! ## add new button +%! b3 = uicontrol (bg, "style", "togglebutton"); +%! pause (0.5); +%! assert (get (bg, "selectedobject"), b3); +%! assert (get (b2, "value"), 0); +%! assert (get (b3, "value"), 1); +%! ## remove selected button +%! delete (b3); +%! pause (0.5); +%! assert (get (bg, "selectedobject"), []); +%! unwind_protect_cleanup +%! close (hf); +%! end_unwind_protect