allow radio-box% to have no selected buttons

svn: r17865
This commit is contained in:
Matthew Flatt 2010-01-28 17:51:30 +00:00
parent e1f931038d
commit a09e671f34
15 changed files with 64 additions and 37 deletions

View File

@ -264,40 +264,47 @@
(check-container-parent cwho parent) (check-container-parent cwho parent)
(check-callback cwho callback) (check-callback cwho callback)
(check-orientation cwho style) (check-orientation cwho style)
(check-non-negative-integer cwho selection))) (check-non-negative-integer/false cwho selection)))
(private-field (private-field
[wx #f]) [wx #f])
(private (private
[check-button [check-button
(lambda (method n) (lambda (method n false-ok?)
(check-non-negative-integer `(method radio-box% ,method) n) ((if false-ok?
check-non-negative-integer/false
check-non-negative-integer)
`(method radio-box% ,method) n)
(when n
(unless (< n (length chcs)) (unless (< n (length chcs))
(raise-mismatch-error (who->name `(method radio-box% ,method)) "no such button: " n)))]) (raise-mismatch-error (who->name `(method radio-box% ,method)) "no such button: " n))))])
(override (override
[enable (entry-point [enable (entry-point
(case-lambda (case-lambda
[(on?) (send wx enable on?)] [(on?) (send wx enable on?)]
[(which on?) (check-button 'enable which) [(which on?) (check-button 'enable which #f)
(send wx enable which on?)]))] (send wx enable which on?)]))]
[is-enabled? (entry-point [is-enabled? (entry-point
(case-lambda (case-lambda
[() (send wx is-enabled?)] [() (send wx is-enabled?)]
[(which) (check-button 'is-enabled? which) [(which) (check-button 'is-enabled? which #f)
(send wx is-enabled? which)]))]) (send wx is-enabled? which)]))])
(public (public
[get-number (lambda () (length chcs))] [get-number (lambda () (length chcs))]
[get-item-label (lambda (n) [get-item-label (lambda (n)
(check-button 'get-item-label n) (check-button 'get-item-label n #f)
(list-ref chcs n))] (list-ref chcs n))]
[get-item-plain-label (lambda (n) [get-item-plain-label (lambda (n)
(check-button 'get-item-plain-label n) (check-button 'get-item-plain-label n #f)
(wx:label->plain-label (list-ref chcs n)))] (wx:label->plain-label (list-ref chcs n)))]
[get-selection (entry-point (lambda () (send wx get-selection)))] [get-selection (entry-point (lambda () (let ([v (send wx get-selection)])
(if (equal? v -1)
#f
v))))]
[set-selection (entry-point [set-selection (entry-point
(lambda (v) (lambda (v)
(check-button 'set-selection v) (check-button 'set-selection v #t)
(send wx set-selection v)))]) (send wx set-selection (or v -1))))])
(sequence (sequence
(as-entry (as-entry
(lambda () (lambda ()
@ -317,7 +324,7 @@
(length choices)) (length choices))
selection)))) selection))))
label parent callback #f))) label parent callback #f)))
(when (positive? selection) (when (or (not selection) (positive? selection))
(set-selection selection))))) (set-selection selection)))))
(define slider% (define slider%

View File

@ -28,7 +28,7 @@ Whenever the user changes the selected radio button, the radio box's
'vertical-label 'horizontal-label 'vertical-label 'horizontal-label
'deleted)) 'deleted))
'(vertical)] '(vertical)]
[selection exact-nonnegative-integer? 0] [selection (or/c exact-nonnegative-integer? #f) 0]
[font (is-a?/c font%) normal-control-font] [font (is-a?/c font%) normal-control-font]
[enabled any/c #t] [enabled any/c #t]
[vert-margin (integer-in 0 1000) 2] [vert-margin (integer-in 0 1000) 2]
@ -64,8 +64,9 @@ The @scheme[style] argument must include either @scheme['vertical] for a
@HVLabelNote[@scheme[style]]{radio box} @DeletedStyleNote[@scheme[style] @scheme[parent]]{radio box} @HVLabelNote[@scheme[style]]{radio box} @DeletedStyleNote[@scheme[style] @scheme[parent]]{radio box}
By default, the first radio button is initially selected. If By default, the first radio button is initially selected. If
@scheme[selection] is positive, it is passed to @method[radio-box% @scheme[selection] is positive or @scheme[#f], it is passed to
set-selection] to set the initial radio button selection. @method[radio-box% set-selection] to set the initial radio button
selection.
@FontKWs[@scheme[font]] @WindowKWs[@scheme[enabled]] @SubareaKWs[] @AreaKWs[] @FontKWs[@scheme[font]] @WindowKWs[@scheme[enabled]] @SubareaKWs[] @AreaKWs[]
@ -115,10 +116,10 @@ Returns the number of radio buttons in the radio box.
} }
@defmethod[(get-selection) @defmethod[(get-selection)
exact-nonnegative-integer?]{ (or/c exact-nonnegative-integer? #f)]{
Gets the position of the selected radio button. Radio buttons are Gets the position of the selected radio button, returning @scheme[#f]
numbered from @scheme[0]. if no button is selected. Radio buttons are numbered from @scheme[0].
} }
@ -139,10 +140,11 @@ box, @|MismatchExn|.
} }
@defmethod[(set-selection [n exact-nonnegative-integer?]) @defmethod[(set-selection [n (or/c exact-nonnegative-integer? #f)])
void?]{ void?]{
Sets the selected radio button by position. (The control's callback Sets the selected radio button by position, or deselects all radio
buttons if @scheme[n] is @scheme[#f]. (The control's callback
procedure is @italic{not} invoked.) Radio buttons are numbered from procedure is @italic{not} invoked.) Radio buttons are numbered from
@scheme[0]. If @scheme[n] is equal to or larger than the number of @scheme[0]. If @scheme[n] is equal to or larger than the number of
radio buttons in the radio box, @|MismatchExn|. radio buttons in the radio box, @|MismatchExn|.

View File

@ -1299,6 +1299,7 @@
(define mismatch-err (mk-err exn:fail:contract?)) (define mismatch-err (mk-err exn:fail:contract?))
(define do-sel (lambda (sel n) (for-each (lambda (rb) (sel rb (n rb))) rbs))) (define do-sel (lambda (sel n) (for-each (lambda (rb) (sel rb (n rb))) rbs)))
(define sel-false (lambda (sel) (do-sel sel (lambda (rb) #f))))
(define sel-minus (lambda (sel) (do-sel (type-err sel) (lambda (rb) -1)))) (define sel-minus (lambda (sel) (do-sel (type-err sel) (lambda (rb) -1))))
(define sel-first (lambda (sel) (do-sel sel (lambda (rb) 0)))) (define sel-first (lambda (sel) (do-sel sel (lambda (rb) 0))))
(define sel-middle (lambda (sel) (do-sel sel (lambda (rb) (floor (/ (send rb get-number) 2)))))) (define sel-middle (lambda (sel) (do-sel sel (lambda (rb) (floor (/ (send rb get-number) 2))))))
@ -1311,7 +1312,9 @@
(make-object button% (format "Select First~a" title) hp2 (lambda (b e) (sel-first sel))) (make-object button% (format "Select First~a" title) hp2 (lambda (b e) (sel-first sel)))
(make-object button% (format "Select Middle ~a" title) hp2 (lambda (b e) (sel-middle sel))) (make-object button% (format "Select Middle ~a" title) hp2 (lambda (b e) (sel-middle sel)))
(make-object button% (format "Select Last~a" title) hp2 (lambda (b e) (sel-last sel))) (make-object button% (format "Select Last~a" title) hp2 (lambda (b e) (sel-last sel)))
(make-object button% (format "Select N~a" title) hp2 (lambda (b e) (sel-N sel)))) (make-object button% (format "Select N~a" title) hp2 (lambda (b e) (sel-N sel)))
(when (equal? title "")
(make-object button% (format "Select #f~a" title) hp2 (lambda (b e) (sel-false sel)))))
(make-selectors "" normal-sel) (make-selectors "" normal-sel)
(make-selectors " by Simulate" simulate-sel) (make-selectors " by Simulate" simulate-sel)
(make-object button% "Check" p (make-object button% "Check" p

View File

@ -1,3 +1,10 @@
Version 4.2.4.1
Changed radio-box% to allow #f as a selection so that no buttons are
selected
----------------------------------------------------------------------
Version 4.2.4, January 2010 Version 4.2.4, January 2010
Minor bug fixes Minor bug fixes

View File

@ -3,3 +3,6 @@
@MACRO RANGERET[p.rv] = if ((x<p> < 0) || (x<p> >= THISOBJECT->Number())) { READY_TO_RETURN; return <rv>; } @MACRO RANGERET[p.rv] = if ((x<p> < 0) || (x<p> >= THISOBJECT->Number())) { READY_TO_RETURN; return <rv>; }
@MACRO RANGE[p] = $$RANGERET[<p>.scheme_void] @MACRO RANGE[p] = $$RANGERET[<p>.scheme_void]
@MACRO RANGEXRET[p.rv] = if ((x<p> < -1) || (x<p> >= THISOBJECT->Number())) { READY_TO_RETURN; return <rv>; }
@MACRO RANGEX[p] = $$RANGEXRET[<p>.scheme_void]

View File

@ -251,6 +251,7 @@ static l_TYPE l_POINT *l_MAKE_ARRAY(Scheme_Object *l, l_INTTYPE *c, char *who)
class os_wxChoice : public wxChoice { class os_wxChoice : public wxChoice {
public: public:
Scheme_Object *callback_closure; Scheme_Object *callback_closure;

View File

@ -289,6 +289,7 @@ static l_TYPE l_POINT *l_MAKE_ARRAY(Scheme_Object *l, l_INTTYPE *c, char *who)
class os_wxListBox : public wxListBox { class os_wxListBox : public wxListBox {
public: public:
Scheme_Object *callback_closure; Scheme_Object *callback_closure;

View File

@ -345,6 +345,7 @@ static l_TYPE l_POINT *l_MAKE_ARRAY(Scheme_Object *l, l_INTTYPE *c, char *who)
class os_wxRadioBox : public wxRadioBox { class os_wxRadioBox : public wxRadioBox {
public: public:
Scheme_Object *callback_closure; Scheme_Object *callback_closure;
@ -706,7 +707,7 @@ static Scheme_Object *os_wxRadioBoxSetSelection(int n, Scheme_Object *p[])
x0 = WITH_VAR_STACK(objscheme_unbundle_integer(p[POFFSET+0], "set-selection in radio-box%")); x0 = WITH_VAR_STACK(objscheme_unbundle_integer(p[POFFSET+0], "set-selection in radio-box%"));
if ((x0 < 0) || (x0 >= THISOBJECT->Number())) { READY_TO_RETURN; return scheme_void; } if ((x0 < -1) || (x0 >= THISOBJECT->Number())) { READY_TO_RETURN; return scheme_void; }
WITH_VAR_STACK(((wxRadioBox *)((Scheme_Class_Object *)p[0])->primdata)->SetSelection(x0)); WITH_VAR_STACK(((wxRadioBox *)((Scheme_Class_Object *)p[0])->primdata)->SetSelection(x0));

View File

@ -48,7 +48,7 @@
@ "get-selection" : int GetSelection(); @ "get-selection" : int GetSelection();
@ "number" : int Number() @ "number" : int Number()
@ "set-selection" : void SetSelection(int); : : /RANGE[0] @ "set-selection" : void SetSelection(int); : : /RANGEX[0]
@ "enable" : void Enable(int,bool); : : /RANGE[0] <> single-button @ "enable" : void Enable(int,bool); : : /RANGE[0] <> single-button
@ "enable" : void Enable(bool); <> all-buttons @ "enable" : void Enable(bool); <> all-buttons

View File

@ -274,6 +274,7 @@ static int unbundle_symset_tabStyle(Scheme_Object *v, const char *where) {
class os_wxTabChoice : public wxTabChoice { class os_wxTabChoice : public wxTabChoice {
public: public:
Scheme_Object *callback_closure; Scheme_Object *callback_closure;

View File

@ -282,7 +282,7 @@ void wxRadioBox::SetSelection(int N)
numberItems = cRadioButtons->Number(); numberItems = cRadioButtons->Number();
if (0 <= N && N < numberItems) { if (-1 <= N && N < numberItems) {
if (selected != N) { if (selected != N) {
if (0 <= selected && selected < numberItems) { if (0 <= selected && selected < numberItems) {
selectedNode = cRadioButtons->Nth(selected); selectedNode = cRadioButtons->Nth(selected);
@ -290,9 +290,11 @@ void wxRadioBox::SetSelection(int N)
selectedRadioButton->SetValue(FALSE); selectedRadioButton->SetValue(FALSE);
} }
if (N != -1) {
node = cRadioButtons->Nth(N); node = cRadioButtons->Nth(N);
radioButton = (wxRadioButton*)node->Data(); radioButton = (wxRadioButton*)node->Data();
radioButton->SetValue(TRUE); radioButton->SetValue(TRUE);
}
selected = N; selected = N;
} }

View File

@ -424,7 +424,7 @@ void wxRadioBox::SetButton(int which, int value)
void wxRadioBox::SetSelection(int N) void wxRadioBox::SetSelection(int N)
{ {
if ((N < 0) || (N >= no_items)) if ((N < -1) || (N >= no_items))
return; return;
if (N == selected) if (N == selected)
@ -433,6 +433,7 @@ void wxRadioBox::SetSelection(int N)
if (selected >= 0 && selected < no_items) if (selected >= 0 && selected < no_items)
SetButton(selected, 0); SetButton(selected, 0);
if (N != -1)
SetButton(N, 1); SetButton(N, 1);
selected = N; selected = N;

View File

@ -134,8 +134,7 @@ Bool wxRadioBox::Create(wxPanel *panel, wxFunction func, char *label,
X->frame = wgt; X->frame = wgt;
// create group widget, which holds the toggles // create group widget, which holds the toggles
wgt = XtVaCreateManagedWidget("radiobox", xfwfGroupWidgetClass, X->frame, wgt = XtVaCreateManagedWidget("radiobox", xfwfGroupWidgetClass, X->frame,
XtNselectionStyle, (style & wxAT_MOST_ONE) ? XtNselectionStyle, XfwfSingleSelection,
XfwfSingleSelection : XfwfOneSelection,
XtNstoreByRow, FALSE, XtNstoreByRow, FALSE,
XtNlabel, NULL, XtNlabel, NULL,
XtNframeWidth, 0, XtNframeWidth, 0,
@ -265,8 +264,7 @@ Bool wxRadioBox::Create(wxPanel *panel, wxFunction func, char *label,
// create group widget, which holds the toggles // create group widget, which holds the toggles
wgt = XtVaCreateManagedWidget("radiobox", xfwfGroupWidgetClass, X->frame, wgt = XtVaCreateManagedWidget("radiobox", xfwfGroupWidgetClass, X->frame,
XtNselectionStyle, (style & wxAT_MOST_ONE) ? XtNselectionStyle, XfwfSingleSelection,
XfwfSingleSelection : XfwfOneSelection,
XtNstoreByRow, FALSE, XtNstoreByRow, FALSE,
XtNlabel, NULL, XtNlabel, NULL,
XtNframeWidth, 0, XtNframeWidth, 0,
@ -518,7 +516,7 @@ void wxRadioBox::SetLabel(int item, wxBitmap *bitmap)
void wxRadioBox::SetSelection(int item) void wxRadioBox::SetSelection(int item)
{ {
if (0 <= item && item < num_toggles) if (-1 <= item && item < num_toggles)
XtVaSetValues(X->handle, XtNselection, (long)item, NULL); XtVaSetValues(X->handle, XtNselection, (long)item, NULL);
} }