{******************************************************************************}
{ }
{ Tulip - User Interface Library }
{ }
{ Copyright(c) 2012 Marcos Gomes. All rights Reserved. }
{ }
{ -------------------------------------------------------------------------- }
{ }
{ This product is based on Asphyre Sphinx (c) 2000 - 2012 Yuriy Kotsarenko. }
{ All rights reserved. Official web site: http://www.afterwarp.net }
{ }
{******************************************************************************}
{ }
{ Important Notice: }
{ }
{ If you modify/use this code or one of its parts either in original or }
{ modified form, you must comply with Mozilla Public License Version 2.0, }
{ including section 3, "Responsibilities". Failure to do so will result in }
{ the license breach, which will be resolved in the court. Remember that }
{ violating author's rights either accidentally or intentionally is }
{ considered a serious crime in many countries. Thank you! }
{ }
{ !! Please *read* Mozilla Public License 2.0 document located at: }
{ http://www.mozilla.org/MPL/ }
{ }
{ -------------------------------------------------------------------------- }
{ }
{ The contents of this file are subject to the Mozilla Public License }
{ Version 2.0 (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/ }
{ }
{ Software distributed under the License is distributed on an "AS IS" }
{ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the }
{ License for the specific language governing rights and limitations }
{ under the License. }
{ }
{ The Original Code is Tulip.UI.RadioButtons.pas. }
{ }
{ The Initial Developer of the Original Code is Marcos Gomes. }
{ Portions created by Marcos Gomes are Copyright (C) 2012, Marcos Gomes. }
{ All Rights Reserved. }
{ }
{******************************************************************************}
{ }
{ Tulip.UI.RadioButtons.pas Modified: 05-Out-2012 }
{ -------------------------------------------------------------------------- }
{ }
{ Base Implementations for RadioButton Controls }
{ }
{ Version 1.02 }
{ }
{******************************************************************************}
unit Tulip.UI.RadioButtons;
interface
uses
System.SysUtils, System.Classes,
// Asphyre Units
AbstractCanvas, AsphyreFonts, AsphyreImages, AsphyreTypes, Vectors2,
// Tulip UI Units
Tulip.UI.Types, Tulip.UI.Classes, Tulip.UI.Controls, Tulip.UI.Helpers,
Tulip.UI.Utils;
type
{$REGION 'TCustomARadioButton'}
TCustomARadioButton = class(TWControl)
private
FAntialiased: Boolean;
FBorder: TBorder;
FBox: TCkBox;
FCaption: String;
FChecked: Boolean;
FColor: TFillColor;
FFocusRect: TFocusRect;
FFont: TFormatedFont;
FImage: TImage;
FMargin: Word;
FReadOnly: Boolean;
FTransparent: Boolean;
procedure SetAntialiased(Value: Boolean);
procedure SetBorder(Value: TBorder);
procedure SetBox(Value: TCkBox);
procedure SetCaption(Value: String);
procedure SetChecked(Value: Boolean);
procedure SetColor(Value: TFillColor);
procedure SetFocusRect(Value: TFocusRect);
procedure SetFont(Value: TFormatedFont);
procedure SetImage(Value: TImage);
procedure SetMargin(Value: Word);
procedure SetReadOnly(Value: Boolean);
procedure SetTransparent(Value: Boolean);
protected
procedure AssignTo(Dest: TPersistent); override;
procedure Paint; override;
procedure SetHeight(Value: Integer); override;
procedure SetWidth(Value: Integer); override;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
procedure DblClick; override;
procedure KeyDown(var Key: Word; Shift: TShiftState); override;
procedure MouseDown(Button: TMouseButton; Shift: TShiftState;
X, Y: Integer); override;
procedure MouseUp(Button: TMouseButton; Shift: TShiftState;
X, Y: Integer); override;
property Antialiased: Boolean read FAntialiased write SetAntialiased;
property Border: TBorder read FBorder write SetBorder;
property Box: TCkBox read FBox write SetBox;
property Caption: String read FCaption write SetCaption;
property Checked: Boolean read FChecked write SetChecked;
property Color: TFillColor read FColor write SetColor;
property FocusRect: TFocusRect read FFocusRect write SetFocusRect;
property Font: TFormatedFont read FFont write SetFont;
property Image: TImage read FImage write SetImage;
property Margin: Word read FMargin write SetMargin;
property ReadOnly: Boolean read FReadOnly write SetReadOnly;
property Transparent: Boolean read FTransparent write SetTransparent;
end;
{$ENDREGION}
implementation
{$REGION 'TCustomARadioButton'}
{ TCustomARadioButton }
procedure TCustomARadioButton.AssignTo(Dest: TPersistent);
begin
ControlState := ControlState + [csReadingState];
inherited AssignTo(Dest);
if Dest is TCustomARadioButton then
with TCustomARadioButton(Dest) do
begin
Antialiased := Self.Antialiased;
Border := Self.Border;
Box := Self.Box;
Caption := Self.Caption;
Checked := Self.Checked;
Color := Self.Color;
FocusRect := Self.FocusRect;
Font := Self.Font;
Image := Self.Image;
Margin := Self.Margin;
ReadOnly := Self.ReadOnly;
Transparent := Self.Transparent;
end;
ControlState := ControlState - [csReadingState];
end;
constructor TCustomARadioButton.Create(AOwner: TComponent);
var
I, Num: Integer;
Control: TComponent;
begin
ControlState := ControlState + [csCreating];
inherited Create(AOwner);
if (AOwner <> nil) and (AOwner <> Self) and (AOwner is TWControl) then
begin
// Auto generate name
Num := 1;
begin
while AOwner.FindComponent('RadioButton' + IntToStr(Num)) <> nil do
Inc(Num);
Name := 'RadioButton' + IntToStr(Num);
end;
end;
// Fields
FAntialiased := True;
FBorder := TBorder.Create;
FBorder.Color := $B0FFFFFF;
FBorder.Size := 0;
FBox := TCkBox.Create;
FCaption := Name;
FChecked := True;
// check parent for other radiobuttons
if (AOwner <> nil) and (AOwner <> Self) and (AOwner is TWControl) then
begin
for I := 0 to AOwner.ComponentCount - 1 do
begin
Control := AOwner.Components[I];
if (Control <> Self) and (Control is TCustomARadioButton) then
begin
if ((Control as TCustomARadioButton).Checked = True) then
begin
FChecked := False;
Break;
end;
end;
end;
end;
FColor := TFillColor.Create($FF4090F0, $FF4090F0, $FF4090F0, $FF4090F0);
FFocusRect := fDark;
FFont := TFormatedFont.Create;
FFont.HorizontalAlign := aLeft;
FImage := TImage.Create;
FMargin := 2;
FReadOnly := False;
FTransparent := True;
// Properties
Self.Left := 0;
Self.Top := 0;
Self.Width := 120;
Self.Height := 24;
Self.TabStop := True;
Self.Visible := True;
ControlState := ControlState - [csCreating];
end;
procedure TCustomARadioButton.DblClick;
begin
if not(FReadOnly) then
begin
Self.Checked := True;
end;
inherited DblClick;
end;
destructor TCustomARadioButton.Destroy;
var
I: Integer;
C: TComponent;
begin
if (FChecked = True) and (Owner <> nil) and (Owner <> Self) then
begin
for I := Owner.ComponentCount - 1 downto 0 do
begin
C := Owner.Components[I];
if (C <> Self) and (C is TCustomARadioButton) then
begin
(C as TCustomARadioButton).Checked := True;
Break;
end;
end;
end;
FBorder.Free;
FBox.Free;
FColor.Free;
FFont.Free;
FImage.Free;
inherited;
end;
procedure TCustomARadioButton.KeyDown(var Key: Word; Shift: TShiftState);
begin
if not(FReadOnly) then
begin
if (Key = $20) then
begin
Self.Checked := True;
end;
end;
inherited KeyDown(Key, Shift);
end;
procedure TCustomARadioButton.MouseDown(Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
Self.SetFocus;
inherited MouseDown(Button, Shift, X, Y);
end;
procedure TCustomARadioButton.MouseUp(Button: TMouseButton; Shift: TShiftState;
X, Y: Integer);
var
L, T, H, W: Integer;
begin
T := Self.ClientTop + FBorder.Size + FMargin;
H := Self.Height - (FBorder.Size * 2) - (FMargin * 2);
T := T + (H div 2 - FBox.Size div 2);
L := Self.ClientLeft + FBorder.Size + FMargin;
W := Self.ClientLeft + FBorder.Size + FMargin + FBox.Size;
H := T + FBox.Size;
if not(FReadOnly) then
begin
if (X >= L) and (X < W) and (Y >= T) and (Y < H) then
begin
Self.Checked := True;
end;
end;
inherited MouseUp(Button, Shift, X, Y);
end;
procedure TCustomARadioButton.Paint;
var
X, Y: Integer;
AFont: TAsphyreFont;
AImage: TAsphyreImage;
bTop, bBottom: TConstraintSize;
L, T, H, W: Integer;
begin
// Set initial values
X := ClientLeft;
Y := ClientTop;
ControlManager.Canvas.Antialias := FAntialiased;
// Draw Background
if not FTransparent then
begin
AImage := ControlManager.Images.Image[FImage.Image];
if AImage <> nil then
begin
ControlManager.Canvas.UseImagePx(AImage, pRect4(FImage.Rect));
ControlManager.Canvas.TexMap(pRect4(Rect(X, Y, X + Width, Y + Height)),
cAlpha4(FColor), beNormal);
end
else
begin
ControlManager.Canvas.FillRect(Rect(X, Y, X + Width, Y + Height),
cColor4(FColor), beNormal);
end;
end;
// Draw Border
if Border.Size > 0 then
begin
bTop := 0;
bBottom := 0;
if eTop in Border.Edges then
begin
ControlManager.Canvas.FillRect(Rect(X, Y, X + Width, Y + Border.Size),
Border.Color, beNormal);
bTop := Border.Size;
end;
if eBottom in Border.Edges then
begin
ControlManager.Canvas.FillRect(Rect(X, Y + Height - Border.Size,
X + Width, Y + Height), Border.Color, beNormal);
bBottom := Border.Size;
end;
if eLeft in Border.Edges then
ControlManager.Canvas.FillRect(Rect(X, Y + bTop, X + Border.Size,
Y + Height - bBottom), Border.Color, beNormal);
if eRight in Border.Edges then
ControlManager.Canvas.FillRect(Rect(X + Width - Border.Size, Y + bTop,
X + Width, Y + Height - bBottom), Border.Color, beNormal);
end;
// Draw DisplayText
AFont := ControlManager.Fonts.Font[FFont.Name];
if (AFont <> nil) and (FCaption <> '') then
begin
AFont.TextRectEx(Point2(X + Border.Size + Box.Size + (Margin * 3),
Y + Border.Size + Margin + 1), Point2(Width - Box.Size - (Border.Size * 2)
- (Margin * 4), Height - (Border.Size * 2) - (Margin * 2)), FCaption,
cColor2(FFont.Color), 1.0, FFont.HorizontalAlign, FFont.VerticalAlign,
FFont.ParagraphLine);
end;
// Draw box
// Draw box Background
T := Y + Border.Size + Margin;
H := Height - (Border.Size * 2) - (Margin * 2);
T := T + (H div 2 - FBox.Size div 2);
L := X + Border.Size + Margin;
W := X + Border.Size + Margin + FBox.Size;
H := T + FBox.Size;
if FChecked then
AImage := ControlManager.Images.Image[FBox.CheckedImage.Image]
else
AImage := ControlManager.Images.Image[FBox.Image.Image];
if AImage <> nil then
begin
if FChecked then
ControlManager.Canvas.UseImagePx(AImage, pRect4(FBox.CheckedImage.Rect))
else
ControlManager.Canvas.UseImagePx(AImage, pRect4(FBox.Image.Rect));
ControlManager.Canvas.TexMap(pRect4(Rect(L, T, W, H)), cAlpha4(FColor),
beNormal);
end
else
begin
ControlManager.Canvas.FillRect(Rect(L, T, W, H), cColor4(FBox.Color),
beNormal);
// draw check
if FChecked then
begin
ControlManager.Canvas.FillRect(Rect(L + (FBox.Size div 4),
T + (FBox.Size div 4), W - (FBox.Size div 4), H - (FBox.Size div 4)),
cColor4(FBox.CheckedColor), beNormal);
end;
end;
// Draw box Border
if FBox.Border.Size > 0 then
begin
bTop := 0;
bBottom := 0;
if eTop in FBox.Border.Edges then
begin
ControlManager.Canvas.FillRect(Rect(L, T, W, T + FBox.Border.Size),
FBox.Border.Color, beNormal);
bTop := FBox.Border.Size;
end;
if eBottom in FBox.Border.Edges then
begin
ControlManager.Canvas.FillRect(Rect(L, H - FBox.Border.Size, W, H),
FBox.Border.Color, beNormal);
bBottom := FBox.Border.Size;
end;
if eLeft in FBox.Border.Edges then
ControlManager.Canvas.FillRect(Rect(L, T + bTop, L + FBox.Border.Size,
H - bBottom), FBox.Border.Color, beNormal);
if eRight in FBox.Border.Edges then
ControlManager.Canvas.FillRect(Rect(W - FBox.Border.Size, T + bTop, W,
H - bBottom), FBox.Border.Color, beNormal);
end;
// Draw box Focus rect
if (ControlManager.ActiveControl = Self) and (Self.FocusRect = fLight) then
begin
ControlManager.Canvas.FrameRect(Rect(L - 1, T - 1, W + 1, H + 1),
cColor4($40FFFFFF), beNormal);
end;
if (ControlManager.ActiveControl = Self) and (Self.FocusRect = fDark) then
begin
ControlManager.Canvas.FrameRect(Rect(L - 1, T - 1, W + 1, H + 1),
cColor4($30000000), beNormal);
end;
end;
procedure TCustomARadioButton.SetAntialiased(Value: Boolean);
begin
FAntialiased := Value;
end;
procedure TCustomARadioButton.SetBorder(Value: TBorder);
begin
if Value <> nil then
FBorder.Assign(Value);
end;
procedure TCustomARadioButton.SetBox(Value: TCkBox);
begin
if Value <> nil then
FBox.Assign(Value);
end;
procedure TCustomARadioButton.SetCaption(Value: String);
begin
FCaption := Value;
end;
procedure TCustomARadioButton.SetChecked(Value: Boolean);
var
I: Integer;
C: TComponent;
begin
if (Value = True) and (Owner <> nil) and (Owner <> Self) then
begin
for I := Owner.ComponentCount - 1 downto 0 do
begin
C := Owner.Components[I];
if (C <> Self) and (C is TCustomARadioButton) then
begin
if (C as TCustomARadioButton).Checked = True then
(C as TCustomARadioButton).Checked := False;
end;
end;
end;
FChecked := Value;
end;
procedure TCustomARadioButton.SetColor(Value: TFillColor);
begin
if Value <> nil then
FColor.Assign(Value);
end;
procedure TCustomARadioButton.SetFocusRect(Value: TFocusRect);
begin
FFocusRect := Value;
end;
procedure TCustomARadioButton.SetFont(Value: TFormatedFont);
begin
if Value <> nil then
FFont.Assign(Value);
end;
procedure TCustomARadioButton.SetHeight(Value: Integer);
var
MinH: Integer;
begin
MinH := FBorder.Size * 2 + FMargin * 2 + FBox.Size;
if Value < MinH then
Value := MinH;
inherited SetHeight(Value);
end;
procedure TCustomARadioButton.SetImage(Value: TImage);
begin
if Value <> nil then
FImage.Assign(Value);
end;
procedure TCustomARadioButton.SetMargin(Value: Word);
begin
FMargin := Value;
SetHeight(Self.Height);
SetWidth(Self.Width);
end;
procedure TCustomARadioButton.SetReadOnly(Value: Boolean);
begin
FReadOnly := Value;
end;
procedure TCustomARadioButton.SetTransparent(Value: Boolean);
begin
FTransparent := Value;
end;
procedure TCustomARadioButton.SetWidth(Value: Integer);
var
MinW: Integer;
begin
MinW := FBorder.Size * 2 + FMargin * 2 + FBox.Size;
if Value < MinW then
Value := MinW;
inherited SetWidth(Value);
end;
{$ENDREGION}
end.
