TGCheckButton and SetEnabled

I have a frame with several different widgets, which in some cases must be set to a fixed value. I use the SetEnabled () method to fix or to release a widget. For other widgets this seems to work well, but it seems that for TGCheckButton this does not work. Even when SetEnabled (false) is used, the user can still check/uncheck the checkbox.
Is this a knwon problem, or should I recheck my code once again?

It works with ROOT svn trunk… (see attachment)
– Bertrand.

It does not work always.
The attached demo code show that sometimes the DemoButton widget is disabled and its IsEnabled () method returns false, but still the user can check/uncheck the checkbox.
In addition, setting the DemoButton to ButtonUp or ButtonDown fails as well sometimes if the DemoButton is not enabled.
TestGraphics.cpp (3.01 KB)

In your code, you are using SetState, which sets the button state (it seems obvious)…
Now, looking at the possible button states:

enum EButtonState { kButtonUp, kButtonDown, kButtonEngaged, kButtonDisabled };
You can see that if you set the button state to kButtonDown or kButtonUp (like in your example) it will not be disabled (kButtonDisabled) anymore. Then, the proper way to do what you want is the following:

if (CheckedButton->IsDown ()) { ResultString += " Checked"; if (DemoButton->IsEnabled()) DemoButton->SetState (kButtonDown); } else { ResultString += " UnChecked"; if (DemoButton->IsEnabled()) DemoButton->SetState (kButtonUp); } Hope this helps.
Cheers, Bertrand.

[quote=“bellenot”]In your code, you are using SetState, which sets the button state (it seems obvious)…
Now, looking at the possible button states:

enum EButtonState { kButtonUp, kButtonDown, kButtonEngaged, kButtonDisabled };
You can see that if you set the button state to kButtonDown or kButtonUp (like in your example) it will not be disabled (kButtonDisabled) anymore. Then, the proper way to do what you want is the following:

if (CheckedButton->IsDown ()) { ResultString += " Checked"; if (DemoButton->IsEnabled()) DemoButton->SetState (kButtonDown); } else { ResultString += " UnChecked"; if (DemoButton->IsEnabled()) DemoButton->SetState (kButtonUp); }
[/quote]

This still does not do what I want.
If the DemoButton is disabled, it does no longer properly display the checked or unchecked state. It shows the ButtonDown stated (greyed out), even when I want to show it the ButtonUp state (greyed out) or the other way around, depending on how the disabled state was entered.
In addition, the result of IsDown () does not always correspond with the displayed ButtonUp/ButtonDown state (it alsways returns 0 when not enabled).

I get the impression that for the TGCheckButton, in contrast to other widgets, the SetEnabled () interferes with the “value” of the widget. When SetEnabled is set false, the display still shows the last “value” (ButtonUp/ButtonDown), ibut t looses its “value” (ButtonUp/ButtonDown) as returned by the IsDown () method.

Also, in contrast with other widgets, setting the “value” (ButtonUp/ButtonDown) interferes with the Enabled state.

Is this designed behaviour?

Hi,

OK, I see what you want to do. You’re absolutely right, the code is different for TGButton (and inherited classes). This is apparently due to historical reasons… This would not be too difficult to change, but for backward compatibility reasons, it is unfortunately not possible. Sorry about this.
The problem of IsEnabled() not returning the correct value has been fixed in svn trunk, thanks for pointing this out.
About your problem, please take a look at this solution:

[code] if (CheckedButton->IsDown ()) {
ResultString += " Checked";
if (!DemoButton->IsEnabled ())
DemoButton->SetDisabledAndSelected (kTRUE);
else
DemoButton->SetState (kButtonDown);
} else {
ResultString += " UnChecked";
if (!DemoButton->IsEnabled ())
DemoButton->SetDisabledAndSelected (kFALSE);
else
DemoButton->SetState (kButtonUp);
}

  DemoButton->SetText (ResultString.c_str ());
  if ((DemoButton->IsDisabledAndSelected() != CheckedButton->IsDown ()) ||
      (DemoButton->IsEnabled () && (DemoButton->IsDown () != CheckedButton->IsDown ())) || 
      (DemoButton->IsEnabled () != EnabledButton->IsDown ())) {
     DemoButton->SetBackgroundColor (0xFF0000);
  } else {
     DemoButton->SetBackgroundColor (TGFrame::GetDefaultFrameBackground());
  }

[/code]
I know it becomes a bit hairy and a bit more complex, but as said before, we all have to live with it… :cry:
:exclamation: NB :exclamation: This will work only with svn trunk version of ROOT.

Cheers,
Bertrand.

I understand the importance of backward compatibility.

Thanks for the work-around. I do not have the opportunity to check it soon, but I assume that you verified that the red label could no longer be produced with this work-around. And that the picture of the demo button corresponds to the settings of both the control buttons.

Sure! I verified all possible combinations :slight_smile:
And BTW, if you don’t want to try with svn trunk, you can try to use this:

[code] if (CheckedButton->IsDown ()) {
ResultString += " Checked";
if (DemoButton->GetState () == kButtonDisabled)
DemoButton->SetDisabledAndSelected (kTRUE);
else
DemoButton->SetState (kButtonDown);
} else {
ResultString += " UnChecked";
if (DemoButton->GetState () == kButtonDisabled)
DemoButton->SetDisabledAndSelected (kFALSE);
else
DemoButton->SetState (kButtonUp);
}

  DemoButton->SetText (ResultString.c_str ()); 
  if ((DemoButton->IsDisabledAndSelected() != CheckedButton->IsDown ()) || 
      ((DemoButton->GetState () != kButtonDisabled) && 
       (DemoButton->IsDown () != CheckedButton->IsDown ())) || 
      ((DemoButton->GetState () != kButtonDisabled) != 
       EnabledButton->IsDown ())) { 
     DemoButton->SetBackgroundColor (0xFF0000); 
  } else { 
     DemoButton->SetBackgroundColor (TGFrame::GetDefaultFrameBackground()); 
  } 

[/code]
It should work with previous version (as it doesn’t use DemoButton->IsEnabled())

Cheers,
Bertrand.