Forum > LCL

Weird case of TButtonControl.ClicksDisabled

(1/1)

Arioch:
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  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---protected property TButtonControl.ClicksDisabled : Boolean  read FClicksDisabled  write FClicksDisabled;
--- End quote ---

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  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---procedure TButtonActionLink.SetChecked(Value: Boolean);begin  if IsCheckedLinked then  begin    FClientButton.ClicksDisabled := True;    try      FClientButton.Checked := Value;    finally      FClientButton.ClicksDisabled := False;    end;  end;end; 
Notice, how the prior value is never checked nor restored, it is just carelessly overwritten.


--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---procedure TCustomCheckBox.DoClickOnChange;begin  Changed;  // emulate delphi OnClick behaviour (click will call OnChange)  if VCL_OnClick_Emulation and not ClicksDisabled then    inherited Click  else    DoOnChange;end; procedure TCustomCheckBox.SetState(Value: TCheckBoxState);var  OldCheckState: TCheckBoxState;  OldActionListState: TActionListState;  LAction: TBasicAction;begin  LAction := Action;            // property getter is function, call only once.  // TAction does not have the 3rd state, nothing meaningful can be done then  if Value <> cbGrayed then begin    // no infinite recursion when we would be called again later by TAction itself    if not ClicksDisabled then begin      if LAction is TCustomAction then begin        TCustomAction(LAction).Checked := Value = cbChecked;        Exit;      end;    end;  end;   if FState <> Value then  begin    OldCheckState := FState;    FState := Value;.... 


...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

jamie:
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.

Arioch:
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.

Navigation

[0] Message Index

Go to full version