Skip to content

Commit

Permalink
Fix RadioButtons: Always select exactly one
Browse files Browse the repository at this point in the history
This was fixed in 0.10.4, then it regressed in 0.10.7.
Now we fix it again.
  • Loading branch information
SimonN committed May 1, 2023
1 parent d66cec5 commit f38fc01
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 22 deletions.
36 changes: 23 additions & 13 deletions src/gui/button/bitmap.d
Original file line number Diff line number Diff line change
Expand Up @@ -43,29 +43,39 @@ protected:
_cbe.draw();
}
}
// end class BitmapButton



class Checkbox : BitmapButton {
class CheckableButton : BitmapButton {
private:
immutable int _xfWhenChecked = 2; // 2 is the checkmark, or caller sets it.
immutable int _xfWhenChecked;

public:
this(Geom g, in int xfWhenChecked = 2)
{
this(Geom g, in int xfWhenChecked)
in { assert (xfWhenChecked != 0, "0 means empty button"); }
do {
g.xl = 20;
g.yl = 20;
super(g, InternalImage.menuCheckmark.toCutbit);
_xfWhenChecked = xfWhenChecked;
this.onExecute = (){ this.toggle; };
}

pure nothrow @safe @nogc:
bool isChecked() const { return xf == _xfWhenChecked; }
void check() { xf = _xfWhenChecked; }
void uncheck() { xf = 0; }
void checked(in bool b) { b ? check() : uncheck(); }
void toggle() { isChecked ? uncheck() : check(); }
final pure nothrow @safe @nogc {
bool isChecked() const { return xf == _xfWhenChecked; }
void check() { xf = _xfWhenChecked; }
void uncheck() { xf = 0; }
void checked(in bool b) { b ? check() : uncheck(); }
void toggle() { isChecked ? uncheck() : check(); }
}
}



class Checkbox : CheckableButton {
public:
this(Geom g)
{
super(g, 2); // X-frame 2 is the checkmark.
this.onExecute = () { toggle(); };
}
}
// end class Checkbox
21 changes: 12 additions & 9 deletions src/gui/radio.d
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,15 @@ public:
// Returns -1 when the mouse is over neither choice.
int theHovered() const
{
return _choices.countUntil!(ch => ch.isMouseHere) & 0xFFFF;
immutable ret = _choices.countUntil!(ch => ch.isMouseHere);
return ret == -1 ? -1 : ret & 0xFFFF;
}

// Returns -1 when nothing has been chosen yet
int theChosen() const
{
return _choices.countUntil!(ch => ch.isChosen) & 0xFFFF;
immutable ret = _choices.countUntil!(ch => ch.isChosen);
return ret == -1 ? -1 : ret & 0xFFFF;
}

void choose(int nr)
Expand All @@ -58,6 +60,9 @@ public:
ch.unchoose();
}
_choices[nr].choose();
assert (_choices.count!(ch => ch.isChosen) == 1,
"This is the first goal of foreach() unchoose(); [nr].choose()");
assert (theChosen == nr, "This is the second goal of [nr].choose()");
if (_onExecute)
_onExecute(nr);
}
Expand All @@ -74,24 +79,22 @@ protected:
}
}

private alias ChoiceButton = Checkbox;

private class Choice : Element {
ChoiceButton _button;
private final class Choice : Element {
CheckableButton _button;
Label _label;
bool _labelWasExecuted;

this(Geom g, string s) {
super(g);
// 6 is the x-frame for the active radio button.
_button = new ChoiceButton(new Geom(0, 0, 20, 20), 6);
// X-frame 6 is the x-frame for the active radio button.
_button = new CheckableButton(new Geom(0, 0, 20, 20), 6);
_label = new Label(new Geom(30, 0, xlg - 30, 20), s);
addChildren(_button, _label);
}

pure nothrow @safe @nogc {
bool execute() const { return _button.execute || _labelWasExecuted; }
bool isChosen() const { return _button.isChecked;}
bool isChosen() const { return _button.isChecked; }
void choose() { _button.checked = true; }
void unchoose() { _button.checked = false; }
}
Expand Down

0 comments on commit f38fc01

Please sign in to comment.