Files
lazarus-ccr/components/jvcllaz/run/JvStdCtrls/jvcheckbox.pas

634 lines
17 KiB
ObjectPascal

{-----------------------------------------------------------------------------
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: JvCheckBox.PAS, released on 2001-02-28.
The Initial Developer of the Original Code is Sébastien Buysse [sbuysse att buypin dott com]
Portions created by Sébastien Buysse are Copyright (C) 2001 Sébastien Buysse.
All Rights Reserved.
Contributor(s):
Michael Beck [mbeck att bigfoot dott com].
Ain Valtin - ReadOnly, Alignment, Layout, RightButton
Robert Marquardt RightButton renamed to LeftText
Peter Thörnqvist- added LinkedControls property
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 JvCheckBox;
{$mode objfpc}{$H+}
interface
uses
LCLIntf, LCLType,
Classes, Graphics, Controls, StdCtrls,
JvLinkedControls;
const
DefaultValueChecked = '1';
DefaultValueUnchecked = '0';
type
TJvCheckBox = class;
(******************* NOT CONVERTED *****
TJvCheckBoxDataConnector = class(TJvFieldDataConnector)
private
FCheckBox: TJvCheckBox;
FValueChecked: string;
FValueUnchecked: string;
procedure SetValueChecked(const Value: string);
procedure SetValueUnchecked(const Value: string);
function IsValueCheckedStored: Boolean;
function IsValueUncheckedStored: Boolean;
protected
procedure UpdateData; override;
procedure RecordChanged; override;
public
constructor Create(ACheckBox: TJvCheckBox);
procedure Assign(Source: TPersistent); override;
published
property ValueChecked: string read FValueChecked write SetValueChecked stored IsValueCheckedStored;
property ValueUnchecked: string read FValueUnchecked write SetValueUnchecked stored IsValueUncheckedStored;
end;
***********************)
TJvCheckBox = class(TCheckbox) //TJvExCheckBox)
private
FLinkedControls: TJvLinkedControls;
FCheckingLinkedControls: Boolean;
(**************** NOT CONVERTED ***
FReadOnly:Boolean;
FHotTrack: Boolean;
FHotTrackFont: TFont;
FFontSave: TFont;
FHotTrackFontOptions: TJvTrackFontOptions;
FAutoSize: Boolean;
FCanvas: TControlCanvas;
FWordWrap: Boolean;
FAlignment: TAlignment;
FLayout: TTextLayout;
FLeftText: Boolean;
FDataConnector: TJvCheckBoxDataConnector;
function GetCanvas: TCanvas;
procedure SetHotTrackFont(const Value: TFont);
procedure SetHotTrackFontOptions(const Value: TJvTrackFontOptions);
procedure SetWordWrap(const Value: Boolean);
procedure SetAlignment(const Value: TAlignment);
procedure SetLayout(const Value: TTextLayout);
procedure SetLeftText(const Value: Boolean);
procedure SetDataConnector(const Value: TJvCheckBoxDataConnector);
function IsHotTrackFontStored: Boolean;
procedure SetClientSize(W, H: Integer);
*****************)
procedure SetLinkedControls(const Value: TJvLinkedControls);
procedure ReadAssociated(Reader: TReader);
protected
(**************** NOT CONVERTED ****
procedure SetAutoSize(Value: Boolean); override;
procedure CalcAutoSize; virtual;
function CreateDataConnector: TJvCheckBoxDataConnector; virtual;
procedure CreateParams(var Params: TCreateParams); override;
procedure DoExit; override;
procedure KeyPress(var Key: Char); override;
procedure BmSetCheck(var Msg: TLMessage); message BM_SETCHECK;
procedure TextChanged; override;
procedure UpdateProperties;
procedure FontChanged; override;
procedure MouseEnter; override;
procedure MouseLeave; override;
***************)
procedure CheckLinkedControls; virtual;
procedure DefineProperties(Filer: TFiler); override;
procedure DoClickOnChange; override;
procedure EnabledChanged;override;
procedure LinkedControlsChange(Sender: TObject);
procedure Loaded; override;
procedure Notification(AComponent: TComponent; Operation: TOperation);override;
procedure SetChecked(AValue: Boolean); override;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
procedure Toggle; override;
procedure SetFocus; override;
(*************** NOT CONVERTED ***
property Canvas: TCanvas read GetCanvas;
***)
published
property LinkedControls: TJvLinkedControls read FLinkedControls write SetLinkedControls;
(************** NOT CONVERTED ***
property Alignment: TAlignment read FAlignment write SetAlignment default taLeftJustify;
// link the enabled state of other controls to the checked and/or enabled state of this control
property AutoSize: Boolean read FAutoSize write SetAutoSize default True;
property HotTrack: Boolean read FHotTrack write FHotTrack default False;
property HotTrackFont: TFont read FHotTrackFont write SetHotTrackFont stored IsHotTrackFontStored;
property HotTrackFontOptions: TJvTrackFontOptions read FHotTrackFontOptions write SetHotTrackFontOptions
default DefaultTrackFontOptions;
property Layout: TTextLayout read FLayout write SetLayout default tlCenter;
// show text to the left of the checkbox
property LeftText: Boolean read FLeftText write SetLeftText default False;
property WordWrap: Boolean read FWordWrap write SetWordWrap default False;
property OnMouseEnter;
property OnMouseLeave;
property DataConnector: TJvCheckBoxDataConnector read FDataConnector write SetDataConnector;
property HintColor;
property ReadOnly: Boolean read FReadOnly write FReadOnly default False;
property OnParentColorChange;
***)
end;
implementation
uses
SysUtils;
// JvJCLUtils, JvJVCLUtils;
(******************** NOT CONVERTED ***
//=== { TJvCheckBoxDataConnector } ===========================================
constructor TJvCheckBoxDataConnector.Create(ACheckBox: TJvCheckBox);
begin
inherited Create;
FCheckBox := ACheckBox;
FValueChecked := DefaultValueChecked;
FValueUnchecked := DefaultValueUnchecked;
end;
function TJvCheckBoxDataConnector.IsValueCheckedStored: Boolean;
begin
Result := FValueChecked <> DefaultValueChecked;
end;
function TJvCheckBoxDataConnector.IsValueUncheckedStored: Boolean;
begin
Result := FValueUnchecked <> DefaultValueUnchecked;
end;
procedure TJvCheckBoxDataConnector.Assign(Source: TPersistent);
begin
inherited Assign(Source);
if Source is TJvCheckBoxDataConnector then
begin
FValueChecked := TJvCheckBoxDataConnector(Source).ValueChecked;
FValueUnchecked := TJvCheckBoxDataConnector(Source).ValueUnchecked;
Reset;
end;
end;
procedure TJvCheckBoxDataConnector.RecordChanged;
begin
if Field.IsValid and (ValueChecked <> '') and (ValueUnchecked <> '') then
begin
if not (csDesigning in FCheckBox.ComponentState) then
FCheckBox.ReadOnly := not Field.CanModify;
if not Field.IsNull then
FCheckBox.Checked := AnsiCompareText(Field.AsString, ValueUnchecked) <> 0
else
FCheckBox.State := cbGrayed;
end
else
begin
FCheckBox.State := cbGrayed;
if not (csDesigning in FCheckBox.ComponentState) then
FCheckBox.ReadOnly := True;
end;
end;
procedure TJvCheckBoxDataConnector.UpdateData;
begin
if Field.CanModify and Field.IsValid and (ValueChecked <> '') and (ValueUnchecked <> '') then
begin
if FCheckBox.Checked then
Field.AsString := ValueChecked
else
Field.AsString := ValueUnchecked;
end;
end;
procedure TJvCheckBoxDataConnector.SetValueChecked(const Value: string);
begin
if Value <> FValueChecked then
begin
FValueChecked := Value;
Reset;
end;
end;
procedure TJvCheckBoxDataConnector.SetValueUnchecked(const Value: string);
begin
if Value <> FValueUnchecked then
begin
FValueUnchecked := Value;
Reset;
end;
end;
***)
//=== { TJvCheckBox } ========================================================
constructor TJvCheckBox.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
(***************** NOT CONVERTED ***
FDataConnector := CreateDataConnector;
FCanvas := TControlCanvas.Create;
FCanvas.Control := Self;
FHotTrack := False;
FHotTrackFont := TFont.Create;
FFontSave := TFont.Create;
FHotTrackFontOptions := DefaultTrackFontOptions;
FAutoSize := True;
FWordWrap := False;
FAlignment := taLeftJustify;
FLeftText := False;
FLayout := tlCenter;
FReadOnly := False;
***)
FLinkedControls := TJvLinkedControls.Create(Self);
FLinkedControls.OnChange := @LinkedControlsChange;
end;
destructor TJvCheckBox.Destroy;
begin
(************* NOT CONVERTED ***
FHotTrackFont.Free;
FFontSave.Free;
FDataConnector.Free;
*)
FreeAndNil(FLinkedControls);
inherited Destroy;
(************* NOT CONVERTED ***
// (rom) destroy Canvas AFTER inherited Destroy
FCanvas.Free;
***)
end;
procedure TJvCheckBox.Loaded;
begin
inherited Loaded;
CheckLinkedControls;
(************* NOT CONVERTED ***
CalcAutoSize;
DataConnector.Reset;
*)
end;
(************* NOT CONVERTED ***
function TJvCheckBox.CreateDataConnector: TJvCheckBoxDataConnector;
begin
Result := TJvCheckBoxDataConnector.Create(Self);
end;
procedure TJvCheckBox.DoExit;
begin
try
DataConnector.UpdateRecord;
except
SetFocus;
raise;
end;
inherited DoExit;
end;
function TJvCheckBox.GetCanvas: TCanvas;
begin
Result := FCanvas;
end;
procedure TJvCheckBox.KeyPress(var Key: Char);
begin
inherited KeyPress(Key);
case Key of
#8, ' ':
DataConnector.Modify;
#27:
DataConnector.Reset;
end;
end;
procedure TJvCheckBox.SetDataConnector(const Value: TJvCheckBoxDataConnector);
begin
if Value <> FDataConnector then
FDataConnector.Assign(Value);
end;
*)
(******************** TO DO (Font HotTracking) ***
procedure TJvCheckBox.CreateParams(var Params: TCreateParams);
const
cAlign: array [TAlignment] of Word = (BS_LEFT, BS_RIGHT, BS_CENTER);
cLeftText: array [Boolean] of Word = (0, BS_RIGHTBUTTON);
cLayout: array [TTextLayout] of Word = (BS_TOP, BS_VCENTER, BS_BOTTOM);
cWordWrap: array [Boolean] of Word = (0, BS_MULTILINE);
begin
inherited CreateParams(Params);
with Params do
Style := Style or cAlign[Alignment] or cLayout[Layout] or
cLeftText[LeftText] or cWordWrap[WordWrap];
end;
procedure TJvCheckBox.MouseEnter;
begin
if csDesigning in ComponentState then
Exit;
if FHotTrack then
begin
FFontSave.Assign(Font);
Font.Assign(FHotTrackFont);
end;
inherited MouseEnter;
end;
procedure TJvCheckBox.MouseLeave;
begin
if FHotTrack then
Font.Assign(FFontSave);
inherited MouseLeave;
end;
procedure TJvCheckBox.FontChanged;
begin
inherited FontChanged;
CalcAutoSize;
UpdateTrackFont(HotTrackFont, Font, HotTrackFontOptions);
end;
procedure TJvCheckBox.UpdateProperties;
begin
RecreateWnd(self);
end;
procedure TJvCheckBox.TextChanged;
begin
inherited TextChanged;
CalcAutoSize;
end;
procedure TJvCheckBox.SetClientSize(W, H: Integer);
var
Client: TRect;
begin
Client := GetClientRect;
SetBounds(Left, Top, Width - Client.Right + W, Height - Client.Bottom + H);
end;
procedure TJvCheckBox.CalcAutoSize;
const
Flags: array [Boolean] of Cardinal = (DT_SINGLELINE, DT_WORDBREAK);
var
AWidth, AHeight: Integer;
ASize: TSize;
R: TRect;
begin
if (Parent = nil) or not AutoSize or (csDestroying in ComponentState) or
(csLoading in ComponentState) then
Exit;
ASize := GetDefaultCheckBoxSize;
// add some spacing
Inc(ASize.cy, 4);
FCanvas.Font := Font;
// This is slower than GetTextExtentPoint but it does consider hotkeys
if Caption <> '' then
begin
R := ClientRect;
DrawText(FCanvas, Caption, -1, R, Flags[WordWrap] or DT_LEFT or DT_NOCLIP or DT_CALCRECT);
AWidth := (R.Right - R.Left) + ASize.cx + 8;
AHeight := R.Bottom - R.Top;
end
else
begin
AWidth := ASize.cx;
AHeight := ASize.cy;
end;
if AWidth < ASize.cx then
AWidth := ASize.cx;
if AHeight < ASize.cy then
AHeight := ASize.cy;
SetClientSize(AWidth, AHeight);
end;
procedure TJvCheckBox.SetHotTrackFont(const Value: TFont);
begin
FHotTrackFont.Assign(Value);
end;
procedure TJvCheckBox.SetAutoSize(Value: Boolean);
begin
if FAutoSize <> Value then
begin
//inherited SetAutoSize(Value);
FAutoSize := Value;
if Value then
WordWrap := False;
CalcAutoSize;
end;
end;
function TJvCheckBox.IsHotTrackFontStored: Boolean;
begin
Result := IsHotTrackFontDfmStored(HotTrackFont, Font, HotTrackFontOptions);
end;
procedure TJvCheckBox.SetHotTrackFontOptions(const Value: TJvTrackFontOptions);
begin
if FHotTrackFontOptions <> Value then
begin
FHotTrackFontOptions := Value;
UpdateTrackFont(HotTrackFont, Font, FHotTrackFontOptions);
end;
end;
procedure TJvCheckBox.SetWordWrap(const Value: Boolean);
begin
if FWordWrap <> Value then
begin
FWordWrap := Value;
if Value then
AutoSize := False;
UpdateProperties;
end;
end;
procedure TJvCheckBox.SetAlignment(const Value: TAlignment);
begin
if FAlignment <> Value then
begin
FAlignment := Value;
UpdateProperties;
end;
end;
procedure TJvCheckBox.SetLayout(const Value: TTextLayout);
begin
if FLayout <> Value then
begin
FLayout := Value;
UpdateProperties;
end;
end;
procedure TJvCheckBox.SetLeftText(const Value: Boolean);
begin
if FLeftText <> Value then
begin
FLeftText := Value;
UpdateProperties;
end;
end;
*)
procedure TJvCheckBox.SetLinkedControls(const Value: TJvLinkedControls);
begin
FLinkedControls.Assign(Value);
end;
procedure TJvCheckBox.CheckLinkedControls;
var
I: Integer;
begin
if not FCheckingLinkedControls then // prevent an infinite recursion
begin
FCheckingLinkedControls := True;
try
if LinkedControls <> nil then
for I := 0 to LinkedControls.Count - 1 do
with LinkedControls[I] do
if Control <> nil then
Control.Enabled := CheckLinkControlEnabled(Self.Enabled, Self.Checked, Options);
finally
FCheckingLinkedControls := False;
end;
end;
end;
procedure TJvCheckBox.LinkedControlsChange(Sender: TObject);
begin
CheckLinkedControls;
end;
procedure TJvCheckBox.ReadAssociated(Reader: TReader);
var
C: TComponent;
begin
if Owner <> nil then
C := Owner.FindComponent(Reader.ReadIdent)
else
C := nil;
if (C is TControl) and (LinkedControls <> nil) then
LinkedControls.Add.Control := TControl(C);
end;
type
TWinControlAccess = class(TWinControl);
procedure TJvCheckBox.SetFocus;
var
I: Integer;
FocusLinkedControl: TJvLinkedControl;
FocusTargetControl: TControl;
begin
inherited SetFocus;
// We want to transfer our own focus either to our children or to
// the first focus accepting sibling, depending on the direction
// that the user asked for.
if GetKeyState(VK_SHIFT) >= 0 then
begin
for I := 0 to LinkedControls.Count - 1 do
begin
FocusLinkedControl := LinkedControls[I];
if loForceFocus in FocusLinkedControl.Options then
begin
FocusTargetControl := FocusLinkedControl.Control;
if (FocusTargetControl is TWinControl) and TWinControl(FocusTargetControl).CanFocus then
begin
TWinControl(FocusTargetControl).SetFocus;
Break; // found the new focus owner
end;
end;
end;
end
else
if LinkedControls.Count > 0 then
TWinControlAccess(Parent).SelectNext(Self, False, True);
end;
procedure TJvCheckBox.DefineProperties(Filer: TFiler);
begin
inherited DefineProperties(Filer);
Filer.DefineProperty('Associated', @ReadAssociated, nil, False);
end;
(******************** NOT CONVERTED ***
procedure TJvCheckBox.BmSetCheck(var Msg: TMessage);
begin
// if not ReadOnly then
// begin
inherited;
CheckLinkedControls;
// end;
end;
***)
procedure TJvCheckbox.DoClickOnChange;
begin
inherited;
CheckLinkedControls;
end;
procedure TJvCheckBox.EnabledChanged;
begin
inherited EnabledChanged;
CheckLinkedControls;
end;
procedure TJvCheckBox.Notification(AComponent: TComponent;
Operation: TOperation);
begin
inherited Notification(AComponent, Operation);
if Assigned(FLinkedControls) then
LinkedControls.Notification(AComponent, Operation);
end;
procedure TJvCheckBox.SetChecked(AValue: Boolean);
begin
inherited;
CheckLinkedControls;
end;
procedure TJvCheckBox.Toggle;
begin
(****************** NOT CONVERTED ***
if not ReadOnly then
begin
************************************)
inherited;
CheckLinkedControls;
(****************** NOT CONVERTED ***
if not (csLoading in ComponentState) then
DataConnector.Modify;
end;
***********************************)
end;
end.