Recent

Author Topic: Weird case of TButtonControl.ClicksDisabled  (Read 293 times)

Arioch

  • Sr. Member
  • ****
  • Posts: 415
Weird case of TButtonControl.ClicksDisabled
« on: September 08, 2022, 04:52:57 pm »
The documentation says:

Quote
TButtonControl.ClicksDisabled

Disables clicking on the button, without showing the button in a disabled state.

Source position: stdctrls.pp line 1192
 
Code: Pascal  [Select][+][-]
  1. protected property TButtonControl.ClicksDisabled : Boolean
  2.   read FClicksDisabled
  3.   write FClicksDisabled;

Frankly, this "Disables clicking" is as vague as can be, is it user action, programmed action (funciton calls), something yet else? And what specific consequences would it have?

The tone suggests this to be like a published property, to be set in Object Inspector, saved in LFM and be some globally supported flag neutralizing the button, for whatever needs.

Grepping LCL sources, however, brings one single implementer and one single consumer.

Code: Pascal  [Select][+][-]
  1. procedure TButtonActionLink.SetChecked(Value: Boolean);
  2. begin
  3.   if IsCheckedLinked then
  4.   begin
  5.     FClientButton.ClicksDisabled := True;
  6.     try
  7.       FClientButton.Checked := Value;
  8.     finally
  9.       FClientButton.ClicksDisabled := False;
  10.     end;
  11.   end;
  12. end;
  13.  

Notice, how the prior value is never checked nor restored, it is just carelessly overwritten.

Code: Pascal  [Select][+][-]
  1. procedure TCustomCheckBox.DoClickOnChange;
  2. begin
  3.   Changed;
  4.   // emulate delphi OnClick behaviour (click will call OnChange)
  5.   if VCL_OnClick_Emulation and not ClicksDisabled then
  6.     inherited Click
  7.   else
  8.     DoOnChange;
  9. end;
  10.  
  11. procedure TCustomCheckBox.SetState(Value: TCheckBoxState);
  12. var
  13.   OldCheckState: TCheckBoxState;
  14.   OldActionListState: TActionListState;
  15.   LAction: TBasicAction;
  16. begin
  17.   LAction := Action;            // property getter is function, call only once.
  18.   // TAction does not have the 3rd state, nothing meaningful can be done then
  19.   if Value <> cbGrayed then begin
  20.     // no infinite recursion when we would be called again later by TAction itself
  21.     if not ClicksDisabled then begin
  22.       if LAction is TCustomAction then begin
  23.         TCustomAction(LAction).Checked := Value = cbChecked;
  24.         Exit;
  25.       end;
  26.     end;
  27.   end;
  28.  
  29.   if FState <> Value then
  30.   begin
  31.     OldCheckState := FState;
  32.     FState := Value;
  33. ....
  34.  



...and that is all.

The property is misleadingly named, misleadingly documented, and does not even has to be a property.

So, questions to muse about.

1. Was this property ever used in applications or 3rd party libraries, for sure or at least probably?

2. Can we just remove it and re-implement actions differently? As of now it was broken anyway. The least resistance would be making it a renamed variable inside checklistbox and nowehere else.

3. Should we perhaps uplift it, make published, and make all buttons adhere to it? Or this would be insanity no one needs?

4. Can, maybe, TControlState be extended with a flag, denoting if the curent Click-handling methods were called due to user's action on this very control, or programatically (like TAction, or TDataSet.Next, or radio/speedbuttons cancelling each other)? If so, what should be boundaries? To some extend, csClicked can be used, but i am not sure the boundaries are consistent or documented.

Related: https://gitlab.com/freepascal.org/lazarus/lazarus/-/issues/39869
« Last Edit: September 08, 2022, 04:55:33 pm by Arioch »

jamie

  • Hero Member
  • *****
  • Posts: 4934
Re: Weird case of TButtonControl.ClicksDisabled
« Reply #1 on: September 09, 2022, 01:23:25 pm »
if it follows the Delphi's rules and bugs, then there is no changing it.

I haven't looked at Delphi's code and behavior for this, but I assume it most likely is very close if not the same, which means it most likely won't get changed.

 You could always make your own button with your personal choices and install it, that is what I do.

 The only problem with making your own controls is you need to ensure you keep a copy of the installable or source files with your project file tucked away in a sub folder. Looking at old projects and not having the resources to the controls you made is a bit of a problem.

  I once asked if it was possible for the IDE to (optionally) manage these controls to ensure their resources are stored with the Project automatically. But I didn't get much of a leading on this.

The only true wisdom is knowing you know nothing

Arioch

  • Sr. Member
  • ****
  • Posts: 415
Re: Weird case of TButtonControl.ClicksDisabled
« Reply #2 on: September 09, 2022, 06:20:57 pm »
This `ClicksDisabled`is LCL's own trick, and not a nice one. Delphi implemented TAction without such a hack.

But, even if this was Delphi-like, since this is protected property, not public - in other words, not intended for use in applications anyway - the compatibility would be almost unaffected anyway.

 

TinyPortal © 2005-2018