You've already forked lazarus-ccr
jvcllaz: Add JvCheckbox (can disable linked controls).
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@6661 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
283
components/jvcllaz/run/JvStdCtrls/jvlinkedcontrols.pas
Normal file
283
components/jvcllaz/run/JvStdCtrls/jvlinkedcontrols.pas
Normal file
@ -0,0 +1,283 @@
|
||||
{-----------------------------------------------------------------------------
|
||||
The contents of this file are subject to the Mozilla Public License
|
||||
Version 1.1 (the "License"); you may not use this file except in compliance
|
||||
with the License. You may obtain a copy of the License at
|
||||
http://www.mozilla.org/MPL/MPL-1.1.html
|
||||
|
||||
Software distributed under the License is distributed on an "AS IS" basis,
|
||||
WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See the License for
|
||||
the specific language governing rights and limitations under the License.
|
||||
|
||||
The Original Code is: JvLinkedControls.PAS, released on 2004-01-26.
|
||||
|
||||
The Initial Developer of the Original Code is Peter Th�rnqvist
|
||||
Portions created by Peter Th�rnqvist are Copyright (C) 2004 Peter Th�rnqvist.
|
||||
All Rights Reserved.
|
||||
|
||||
Contributor(s):
|
||||
|
||||
You may retrieve the latest version of this file at the Project JEDI's JVCL home page,
|
||||
located at http://jvcl.delphi-jedi.org
|
||||
|
||||
Known Issues:
|
||||
-----------------------------------------------------------------------------}
|
||||
// $Id$
|
||||
|
||||
unit JvLinkedControls;
|
||||
|
||||
{$mode objfpc}{$H+}
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
SysUtils, Controls, Classes;
|
||||
|
||||
type
|
||||
TJvLinkedControlsOption = (loLinkChecked, loLinkEnabled, loInvertChecked, loInvertEnabled, loForceFocus);
|
||||
TJvLinkedControlsOptions = set of TJvLinkedControlsOption;
|
||||
|
||||
TJvLinkedControl = class(TCollectionItem)
|
||||
private
|
||||
FOwnerControl, FControl: TControl;
|
||||
FOptions: TJvLinkedControlsOptions;
|
||||
FOriginalEnabled: Boolean;
|
||||
procedure SetControl(const Value: TControl);
|
||||
procedure SetOptions(const Value: TJvLinkedControlsOptions);
|
||||
protected
|
||||
function GetDisplayName: string; override;
|
||||
public
|
||||
constructor Create(ACollection: TCollection); override;
|
||||
destructor Destroy; override;
|
||||
procedure Assign(Source: TPersistent); override;
|
||||
published
|
||||
property Control: TControl read FControl write SetControl;
|
||||
property Options: TJvLinkedControlsOptions read FOptions write SetOptions default [loLinkChecked, loLinkEnabled];
|
||||
end;
|
||||
|
||||
TJvLinkedControls = class(TOwnedCollection)
|
||||
private
|
||||
FControl: TControl;
|
||||
FOnChange: TNotifyEvent;
|
||||
FRestoreEnabled: Boolean;
|
||||
function GetItems(Index: Integer): TJvLinkedControl;
|
||||
procedure SetItems(Index: Integer; const Value: TJvLinkedControl);
|
||||
protected
|
||||
procedure Update(Item: TCollectionItem); override;
|
||||
public
|
||||
// You must call Notification in the Owning controls overridden Notification
|
||||
// or hell will break loose when linked controls are removed!!!
|
||||
procedure Notification(AComponent: TComponent; Operation: TOperation); virtual;
|
||||
constructor Create(AControl: TControl);
|
||||
function Add: TJvLinkedControl;
|
||||
procedure Assign(Source: TPersistent); override;
|
||||
// If RestoreEnabled is True, TJvLinkedControls will try to restore the Enabled state
|
||||
// of linked controls when an item is changed or removed
|
||||
property Items[Index: Integer]: TJvLinkedControl read GetItems write SetItems; default;
|
||||
property OnChange: TNotifyEvent read FOnChange write FOnChange;
|
||||
published
|
||||
property RestoreEnabled: Boolean read FRestoreEnabled write FRestoreEnabled default True;
|
||||
end;
|
||||
|
||||
function CheckLinkControlEnabled(Enabled, Checked: Boolean; Options: TJvLinkedControlsOptions): Boolean;
|
||||
|
||||
{$IFDEF UNITVERSIONING}
|
||||
const
|
||||
UnitVersioning: TUnitVersionInfo = (
|
||||
RCSfile: '$URL$';
|
||||
Revision: '$Revision$';
|
||||
Date: '$Date$';
|
||||
LogPath: 'JVCL\run'
|
||||
);
|
||||
{$ENDIF UNITVERSIONING}
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
JvResources;
|
||||
|
||||
function CheckLinkControlEnabled(Enabled, Checked: Boolean; Options: TJvLinkedControlsOptions): Boolean;
|
||||
var
|
||||
IsChecked, IsEnabled: Boolean;
|
||||
begin
|
||||
if loInvertChecked in Options then
|
||||
IsChecked := not Checked
|
||||
else
|
||||
IsChecked := Checked;
|
||||
|
||||
if loInvertEnabled in Options then
|
||||
IsEnabled := not Enabled
|
||||
else
|
||||
IsEnabled := Enabled;
|
||||
|
||||
if (loLinkChecked in Options) and (loLinkEnabled in Options) then
|
||||
Result := IsChecked and IsEnabled
|
||||
else
|
||||
Result := ((loLinkChecked in Options) and IsChecked) or ((loLinkEnabled in Options) and IsEnabled);
|
||||
|
||||
// Result := ((loLinkChecked in Options) and ((not Checked and (loInvertChecked in Options) or (Checked and not (loInvertChecked in Options))))) or
|
||||
// ((loLinkEnabled in Options) and (not Enabled and (loInvertEnabled in Options)) or (Enabled and not (loInvertEnabled in Options)));
|
||||
end;
|
||||
|
||||
//=== { TJvLinkedControl } ===================================================
|
||||
|
||||
constructor TJvLinkedControl.Create(ACollection: TCollection);
|
||||
begin
|
||||
inherited Create(ACollection);
|
||||
if (ACollection is TJvLinkedControls) then
|
||||
FOwnerControl := TJvLinkedControls(ACollection).FControl;
|
||||
FOptions := [loLinkChecked, loLinkEnabled];
|
||||
end;
|
||||
|
||||
destructor TJvLinkedControl.Destroy;
|
||||
begin
|
||||
if (FControl <> nil) and not (csDestroying in FControl.ComponentState) and
|
||||
(Collection is TJvLinkedControls) and TJvLinkedControls(Collection).RestoreEnabled then
|
||||
FControl.Enabled := FOriginalEnabled;
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
procedure TJvLinkedControl.Assign(Source: TPersistent);
|
||||
begin
|
||||
if Source is TJvLinkedControl then
|
||||
begin
|
||||
if Source <> Self then
|
||||
begin
|
||||
Control := TJvLinkedControl(Source).Control;
|
||||
Options := TJvLinkedControl(Source).Options;
|
||||
Changed(False);
|
||||
end;
|
||||
end
|
||||
else
|
||||
inherited Assign(Source);
|
||||
end;
|
||||
|
||||
function TJvLinkedControl.GetDisplayName: string;
|
||||
begin
|
||||
if Control <> nil then
|
||||
Result := Control.Name
|
||||
else
|
||||
Result := inherited GetDisplayName;
|
||||
end;
|
||||
|
||||
procedure TJvLinkedControl.SetControl(const Value: TControl);
|
||||
begin
|
||||
if FControl <> Value then
|
||||
begin
|
||||
if (FOwnerControl = nil) and (Collection is TJvLinkedControls) then
|
||||
FOwnerControl := TJvLinkedControls(Collection).FControl;
|
||||
if (Value = FOwnerControl) and (FOwnerControl <> nil) then
|
||||
raise Exception.CreateRes(@RsEOwnerLinkError);
|
||||
if Assigned(FControl) then
|
||||
begin
|
||||
if Assigned(FOwnerControl) then
|
||||
FControl.RemoveFreeNotification(FOwnerControl);
|
||||
if (Collection is TJvLinkedControls) and TJvLinkedControls(Collection).RestoreEnabled and
|
||||
not (csDestroying in FControl.ComponentState) then
|
||||
FControl.Enabled := FOriginalEnabled;
|
||||
end;
|
||||
if (FOwnerControl <> nil) and (csDestroying in FOwnerControl.ComponentState) then
|
||||
FControl := nil
|
||||
else
|
||||
FControl := Value;
|
||||
if Assigned(FControl) then
|
||||
begin
|
||||
FOriginalEnabled := FControl.Enabled;
|
||||
if Assigned(FOwnerControl) then
|
||||
FControl.FreeNotification(FOwnerControl);
|
||||
end;
|
||||
Changed(False);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TJvLinkedControl.SetOptions(const Value: TJvLinkedControlsOptions);
|
||||
begin
|
||||
if FOptions <> Value then
|
||||
begin
|
||||
FOptions := Value;
|
||||
Changed(False);
|
||||
end;
|
||||
end;
|
||||
|
||||
//=== { TJvLinkedControls } ==================================================
|
||||
|
||||
constructor TJvLinkedControls.Create(AControl: TControl);
|
||||
begin
|
||||
inherited Create(AControl, TJvLinkedControl);
|
||||
FControl := AControl;
|
||||
FRestoreEnabled := True;
|
||||
end;
|
||||
|
||||
function TJvLinkedControls.Add: TJvLinkedControl;
|
||||
begin
|
||||
Result := TJvLinkedControl(inherited Add);
|
||||
Result.FOwnerControl := FControl;
|
||||
end;
|
||||
|
||||
procedure TJvLinkedControls.Assign(Source: TPersistent);
|
||||
var
|
||||
I: Integer;
|
||||
begin
|
||||
if Source is TJvLinkedControls then
|
||||
begin
|
||||
if Source <> Self then
|
||||
begin
|
||||
BeginUpdate;
|
||||
try
|
||||
Clear;
|
||||
for I := 0 to TJvLinkedControls(Source).Count - 1 do
|
||||
Add.Assign(TJvLinkedControls(Source)[I]);
|
||||
RestoreEnabled := TJvLinkedControls(Source).RestoreEnabled;
|
||||
finally
|
||||
EndUpdate;
|
||||
end;
|
||||
end;
|
||||
end
|
||||
else
|
||||
inherited Assign(Source);
|
||||
end;
|
||||
|
||||
function TJvLinkedControls.GetItems(Index: Integer): TJvLinkedControl;
|
||||
begin
|
||||
Result := TJvLinkedControl(inherited Items[Index]);
|
||||
end;
|
||||
|
||||
procedure TJvLinkedControls.Notification(AComponent: TComponent; Operation: TOperation);
|
||||
var
|
||||
I: Integer;
|
||||
begin
|
||||
if (Operation = opRemove) and (AComponent is TControl) then
|
||||
begin
|
||||
BeginUpdate;
|
||||
try
|
||||
for I := 0 to Count - 1 do
|
||||
if Items[I].Control = AComponent then
|
||||
Items[I].Control := nil;
|
||||
finally
|
||||
EndUpdate;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TJvLinkedControls.SetItems(Index: Integer; const Value: TJvLinkedControl);
|
||||
begin
|
||||
inherited Items[Index] := Value;
|
||||
end;
|
||||
|
||||
procedure TJvLinkedControls.Update(Item: TCollectionItem);
|
||||
begin
|
||||
inherited Update(Item);
|
||||
if Item <> nil then
|
||||
TJvLinkedControl(Item).FOwnerControl := FControl;
|
||||
if Assigned(FOnChange) then
|
||||
FOnChange(Self);
|
||||
end;
|
||||
|
||||
{$IFDEF UNITVERSIONING}
|
||||
initialization
|
||||
RegisterUnitVersion(HInstance, UnitVersioning);
|
||||
|
||||
finalization
|
||||
UnregisterUnitVersion(HInstance);
|
||||
{$ENDIF UNITVERSIONING}
|
||||
|
||||
end.
|
Reference in New Issue
Block a user