www.pudn.com > TMSSkinFactoryv1.27.zip > VsRadioButton.pas
{***************************************************************************}
{ TMS Skin Factory }
{ for Delphi 4.0,5.0,6.0 & C++Builder 4.0,5.0 }
{ }
{ Copyright 1996 - 2002 by TMS Software }
{ Email : info@tmssoftware.com }
{ Web : http://www.tmssoftware.com }
{ }
{ The source code is given as is. The author is not responsible }
{ for any possible damage done due to the use of this code. }
{ The component can be freely used in any application. The complete }
{ source code remains property of the author and may not be distributed, }
{ published, given or sold in any form as such. No parts of the source }
{ code can be included in any other component or application without }
{ written authorization of the author. }
{***************************************************************************}
unit VsRadioButton;
{$I VSLIB.INC}
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
VsClasses, VsGraphics, VsSkin, VsSysUtils;
type
TVsRadioButton = class(TVsSkinGraphicControl)
private
FChecked: Boolean;
FGroupIndex: Integer;
FGraphic: TVsGraphic;
FGraphicName: TVsGraphicName;
FSpacing: Integer;
FBtnDown: Boolean;
FMask: TBitmap;
FMaskRect: TRect;
FMaskColor: TColor;
FClipRect: TVsClipRect;
FHasMouse: Boolean;
procedure SetChecked(Value: Boolean);
procedure SetGroupIndex(Value: Integer);
procedure SetGraphicName(Value: TVsGraphicName);
procedure SetSpacing(Value: Integer);
procedure SetMaskColor(Value: TColor);
procedure SetClipRect(Value: TVsClipRect);
procedure ClipRectChanged(Sender: TObject);
procedure CMFontChanged(var Message: TMessage); message CM_FONTCHANGED;
procedure CMEnabledChanged(var Message: TMessage); message CM_ENABLEDCHANGED;
procedure CMTextChanged(var Message: TMessage); message CM_TEXTCHANGED;
procedure CMMouseLeave(var Message: TMessage); message CM_MOUSELEAVE;
protected
procedure Paint; override;
procedure Loaded; override;
function GlyphIndex: Integer;
procedure UpdateGraphic(Clip: Boolean); override;
function CheckClick(X, Y: Integer): Boolean;
procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
procedure MouseMove(Shift: TShiftState; X, Y: Integer); override;
procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
procedure GetGraphicBitmap(Bitmap: TBitmap); override;
procedure SetBounds(ALeft, ATop, AWidth, AHeight: Integer); override;
procedure Click; override;
procedure ReadConfig(IniFile: TVsIni); override;
procedure WriteConfig(IniFile: TVsIni); override;
published
property GraphicName: TVsGraphicName read FGraphicName write SetGraphicName;
property ClipRect: TVsClipRect read FClipRect write SetClipRect;
property MaskColor: TColor read FMaskColor write SetMaskColor default clNone;
property Spacing: Integer read FSpacing write SetSpacing default 5;
property Checked: Boolean read FChecked write SetChecked;
property GroupIndex: Integer read FGroupIndex write SetGroupIndex default -1;
property CursorTracking default false;
property Anchors;
property Caption;
// property Constraints;
property DragCursor;
property DragKind;
property DragMode;
property Enabled;
property Font;
property Hint;
property ParentFont;
property ParentShowHint;
property PopupMenu;
property ShowHint;
property Visible;
property OnClick;
{$IFDEF VER130}
property OnContextPopup;
{$ENDIF}
property OnDragDrop;
property OnDragOver;
property OnEndDock;
property OnEndDrag;
property OnMouseDown;
property OnMouseMove;
property OnMouseUp;
property OnStartDock;
property OnStartDrag;
end;
implementation
const
Glyphs = 4;
EnabledUnchecked = 0;
EnabledChecked = 1;
DisabledUnchecked = 2;
DisabledChecked = 3;
{ TVsRadioButton }
constructor TVsRadioButton.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
ControlStyle := ControlStyle + [csSetCaption, csReplicatable];
SetBounds(0, 0, 100, 21);
CursorTracking := false;
FGroupIndex := -1;
FChecked := false;
FSpacing := 5;
FMask := TBitmap.Create;
FMask.PixelFormat := pf24Bit;
FMaskColor := clNone;
FClipRect := TVsClipRect.Create;
FClipRect.OnChange := ClipRectChanged;
end;
destructor TVsRadioButton.Destroy;
begin
FMask.Free;
FClipRect.Free;
inherited Destroy;
end;
procedure TVsRadioButton.GetGraphicBitmap(Bitmap: TBitmap);
begin
inherited;
if (FGraphic <> nil) then
Bitmap.Assign(FGraphic.Bitmap);
end;
procedure TVsRadioButton.SetBounds(ALeft, ATop, AWidth, AHeight: Integer);
var
P: TSize;
begin
if (FGraphic <> nil) then
begin
AHeight := FClipRect.Height;
AWidth := FClipRect.Width div Glyphs;
if Trim(Caption) <> '' then
begin
AWidth := AWidth + FSpacing;
BitmapCanvas.Font := Self.Font;
P := BitmapCanvas.TextExtent(Caption);
AWidth := AWidth + P.cX + 4;
AHeight := MaxInteger(AHeight, P.cY + 4);
end;
end;
if FMask <> nil then
begin
FMask.Width := FClipRect.Width div Glyphs;
FMask.Height := FClipRect.Height;
end;
inherited SetBounds(ALeft, ATop, AWidth, AHeight);
end;
procedure TVsRadioButton.Loaded;
begin
inherited Loaded;
end;
procedure TVsRadioButton.SetChecked(Value: Boolean);
procedure TurnSiblingsOff;
var
I: Integer;
Sibling: TControl;
begin
if Parent <> nil then
with Parent do
for I := 0 to ControlCount - 1 do
begin
Sibling := Controls[I];
if (Sibling <> Self) and (Sibling is TVsRadioButton) then
if TVsRadioButton(Sibling).GroupIndex = Self.GroupIndex then
TVsRadioButton(Sibling).SetChecked(False);
end;
end;
begin
if FChecked <> Value then
begin
FChecked := Value;
if Value then
begin
TurnSiblingsOff;
inherited Click;
end;
RepaintControl;
end;
end;
procedure TVsRadioButton.SetGroupIndex(Value: Integer);
begin
if FGroupIndex <> Value then
begin
FGroupIndex := Value;
RepaintControl;
end;
end;
procedure TVsRadioButton.SetClipRect(Value: TVsClipRect);
begin
FClipRect.Assign(Value);
end;
procedure TVsRadioButton.ClipRectChanged(Sender: TObject);
begin
UpdateBounds;
end;
procedure TVsRadioButton.UpdateGraphic(Clip: Boolean);
begin
FGraphic := Skin.GetGraphic(FGraphicName);
if (FGraphic <> nil) and Clip then
FClipRect.BoundsRect := Bounds(0, 0, Gw(FGraphic), Gh(FGraphic));
UpdateBounds;
end;
function TVsRadioButton.GlyphIndex: Integer;
var
I: Integer;
begin
if not Enabled then
I := 2 else I := 0;
case Checked of
False: Result := 0 + I;
True: Result := 1 + I;
else Result := 0;
end;
end;
procedure TVsRadioButton.Paint;
var
H, W: Integer;
S, D: TRect;
begin
PaintBackImage;
W := 0;
if FGraphic <> nil then
begin
W := FMask.Width;
H := FMask.Height;
S := Bounds(ClipRect.Left + (GlyphIndex * W), ClipRect.Top, W, H);
D := Bounds(0, 0, W, H);
FMask.Canvas.CopyRect(D, FGraphic.Bitmap.Canvas, S);
FMaskRect := Bounds(0, (Height - H) div 2, W, H);
SetBrushStyle(BitmapCanvas.Brush, MaskColor);
BitmapCanvas.BrushCopy(FMaskRect, FMask, D, MaskColor);
end;
BitmapCanvas.Font := Self.Font;
BitmapCanvas.Brush.Style := bsClear;
D := ClientRect;
Inc(D.Left, W + Spacing);
DrawText(BitmapCanvas.Handle, PChar(Caption), Length(Caption), D,
DT_LEFT or DT_VCENTER or DT_SINGLELINE);
inherited Paint;
end;
procedure TVsRadioButton.CMFontChanged(var Message: TMessage);
begin
UpdateBounds;
inherited;
end;
procedure TVsRadioButton.CMEnabledChanged(var Message: TMessage);
begin
RepaintControl;
inherited;
end;
procedure TVsRadioButton.CMTextChanged(var Message: TMessage);
begin
UpdateBounds;
inherited;
end;
procedure TVsRadioButton.SetGraphicName(Value: TVsGraphicName);
begin
if FGraphicName <> Value then
begin
FGraphicName := Value;
UpdateGraphic(True);
end;
end;
procedure TVsRadioButton.SetMaskColor(Value: TColor);
begin
if FMaskColor <> Value then
begin
FMaskColor := Value;
RepaintControl;
end;
end;
procedure TVsRadioButton.SetSpacing(Value: Integer);
begin
if FSpacing <> Value then
begin
FSpacing := Value;
UpdateBounds;
end;
end;
procedure TVsRadioButton.Click;
begin
//don't remove
end;
function TVsRadioButton.CheckClick(X, Y: Integer): Boolean;
var
P: TPoint;
begin
P.X := X - FMaskRect.Left;
P.Y := Y - FMaskRect.Top;
Result := PtInRect(FMaskRect, Point(X, Y));
if FMaskColor <> clNone then
Result := Result and (FMask.Canvas.Pixels[P.X, P.Y] <> FMaskColor);
end;
procedure TVsRadioButton.CMMouseLeave(var Message: TMessage);
begin
FHasMouse := false;
inherited;
end;
procedure TVsRadioButton.MouseDown(Button: TMouseButton; Shift: TShiftState;
X, Y: Integer);
begin
inherited MouseDown(Button, Shift, X, Y);
if (Button = mbLeft) and (Enabled) then
FBtnDown := CheckClick(X, Y);
end;
procedure TVsRadioButton.MouseMove(Shift: TShiftState; X, Y: Integer);
begin
inherited;
if not FBtnDown then
begin
if not CheckClick(X, Y) then
begin
if FHasMouse then
begin
FHasMouse := false;
UpdateCursor(crDefault);
end;
end else
begin
if not FHasMouse then
begin
FHasMouse := True;
UpdateCursor(RefCursor);
end;
end;
end;
end;
procedure TVsRadioButton.MouseUp(Button: TMouseButton; Shift: TShiftState;
X, Y: Integer);
begin
inherited MouseUp(Button, Shift, X, Y);
if FBtnDown then
begin
FBtnDown := false;
if CheckClick(X, Y) and (not Checked) then
Checked := not FChecked;
end;
end;
procedure TVsRadioButton.ReadConfig(IniFile: TVsIni);
begin
ClipRect.BoundsRect := IniFile.ReadRect(Self.Name, 'ClipRect', EmptyRect);
MaskColor := IniFile.ReadColor(Self.Name, 'MaskColor', clNone);
Spacing := IniFile.ReadInteger(Self.Name, 'Spacing', 0);
Font.Color := IniFile.ReadColor(Self.Name, 'FontColor', clBlack);
Font := IniFile.ReadFont(Self.Name, 'Font', Font);
inherited;
end;
procedure TVsRadioButton.WriteConfig(IniFile: TVsIni);
begin
inherited;
IniFile.WriteRect(Self.Name, 'ClipRect', ClipRect.BoundsRect);
IniFile.WriteColor(Self.Name, 'MaskColor', MaskColor);
IniFile.WriteInteger(Self.Name, 'Spacing', Spacing);
IniFile.WriteFont(Self.Name, 'Font', Font);
IniFile.WriteColor(Self.Name, 'FontColor', Font.Color);
end;
end.