mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-05-25 22:02:37 +02:00
1565 lines
38 KiB
ObjectPascal
1565 lines
38 KiB
ObjectPascal
{
|
|
Copyright (C) 2011 Felipe Monteiro de Carvalho
|
|
|
|
License: The same modifying LGPL with static linking exception as the LCL
|
|
|
|
This unit should be a repository for various custom drawn components,
|
|
such as a custom drawn version of TButton, of TEdit, of TPageControl, etc,
|
|
eventually forming a full set of custom drawn components.
|
|
}
|
|
unit customdrawncontrols;
|
|
|
|
{$mode objfpc}{$H+}
|
|
|
|
interface
|
|
|
|
uses
|
|
// FPC
|
|
Classes, SysUtils, contnrs, Math, types,
|
|
// fpimage
|
|
fpcanvas, fpimgcanv, fpimage,
|
|
// LCL -> Use only TForm, TWinControl, TCanvas, TLazIntfImage
|
|
Graphics, Controls, LCLType, LCLIntf, IntfGraphics,
|
|
LMessages, Messages, LCLProc, Forms,
|
|
// Other LCL units are only for types
|
|
StdCtrls, ExtCtrls, ComCtrls,
|
|
//
|
|
customdrawndrawers;
|
|
|
|
type
|
|
{ TCDControl }
|
|
|
|
TCDControl = class(TCustomControl)
|
|
protected
|
|
FDrawStyle: TCDDrawStyle;
|
|
FDrawer: TCDDrawer;
|
|
FState: TCDControlState;
|
|
FStateEx: TCDControlStateEx;
|
|
procedure PrepareCurrentDrawer(); virtual;
|
|
procedure SetDrawStyle(const AValue: TCDDrawStyle); virtual;
|
|
function GetClientRect: TRect; override;
|
|
function GetControlId: TCDControlID; virtual;
|
|
procedure CreateControlStateEx; virtual;
|
|
procedure PrepareControlState; virtual;
|
|
procedure PrepareControlStateEx; virtual;
|
|
// mouse
|
|
procedure MouseEnter; override;
|
|
procedure MouseLeave; override;
|
|
//
|
|
property DrawStyle: TCDDrawStyle read FDrawStyle write SetDrawStyle;
|
|
public
|
|
//
|
|
constructor Create(AOwner: TComponent); override;
|
|
destructor Destroy; override;
|
|
procedure EraseBackground(DC: HDC); override;
|
|
procedure Paint; override;
|
|
end;
|
|
TCDControlClass = class of TCDControl;
|
|
|
|
// ===================================
|
|
// Standard Tab
|
|
// ===================================
|
|
|
|
TCDButtonControl = class(TCDControl)
|
|
private
|
|
protected
|
|
// keyboard
|
|
procedure DoEnter; override;
|
|
procedure DoExit; override;
|
|
procedure KeyDown(var Key: word; Shift: TShiftState); override;
|
|
procedure KeyUp(var Key: word; Shift: TShiftState); override;
|
|
// mouse
|
|
procedure MouseDown(Button: TMouseButton; Shift: TShiftState;
|
|
X, Y: integer); override;
|
|
procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: integer); override;
|
|
procedure MouseEnter; override;
|
|
procedure MouseLeave; override;
|
|
// button state change
|
|
procedure DoButtonDown(); virtual;
|
|
procedure DoButtonUp(); virtual;
|
|
procedure RealSetText(const Value: TCaption); override;
|
|
public
|
|
//property Down: Boolean read GetDown write SetDown;
|
|
end;
|
|
|
|
{ TCDButton }
|
|
|
|
TCDButton = class(TCDButtonControl)
|
|
private
|
|
protected
|
|
function GetControlId: TCDControlID; override;
|
|
public
|
|
constructor Create(AOwner: TComponent); override;
|
|
destructor Destroy; override;
|
|
published
|
|
property Action;
|
|
property Anchors;
|
|
property Caption;
|
|
property Color;
|
|
property Constraints;
|
|
property DrawStyle;
|
|
property Enabled;
|
|
property Font;
|
|
property OnChangeBounds;
|
|
property OnClick;
|
|
property OnContextPopup;
|
|
property OnDragDrop;
|
|
property OnDragOver;
|
|
property OnEndDrag;
|
|
property OnEnter;
|
|
property OnExit;
|
|
property OnKeyDown;
|
|
property OnKeyPress;
|
|
property OnKeyUp;
|
|
property OnMouseDown;
|
|
property OnMouseEnter;
|
|
property OnMouseLeave;
|
|
property OnMouseMove;
|
|
property OnMouseUp;
|
|
property OnResize;
|
|
property OnStartDrag;
|
|
property OnUTF8KeyPress;
|
|
property ParentFont;
|
|
property ParentShowHint;
|
|
property PopupMenu;
|
|
property ShowHint;
|
|
property TabOrder;
|
|
property TabStop;
|
|
property Visible;
|
|
end;
|
|
|
|
{ TCDEdit }
|
|
|
|
TCDEdit = class(TCDControl)
|
|
private
|
|
DragDropStarted: boolean;
|
|
FCaretTimer: TTimer;
|
|
FEditState: TCDEditStateEx; // Points to the same object as FStateEx, so don't Free!
|
|
function GetControlId: TCDControlID; override;
|
|
procedure CreateControlStateEx; override;
|
|
procedure HandleCaretTimer(Sender: TObject);
|
|
procedure DoDeleteSelection;
|
|
procedure DoManageVisibleTextStart;
|
|
function GetText: string;
|
|
procedure SetText(AValue: string);
|
|
protected
|
|
// keyboard
|
|
procedure DoEnter; override;
|
|
procedure DoExit; override;
|
|
procedure KeyDown(var Key: word; Shift: TShiftState); override;
|
|
procedure KeyUp(var Key: word; Shift: TShiftState); override;
|
|
procedure UTF8KeyPress(var UTF8Key: TUTF8Char); override;
|
|
// mouse
|
|
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;
|
|
procedure MouseEnter; override;
|
|
procedure MouseLeave; override;
|
|
public
|
|
constructor Create(AOwner: TComponent); override;
|
|
destructor Destroy; override;
|
|
published
|
|
property Color;
|
|
property TabStop default True;
|
|
property Text: string read GetText write SetText;
|
|
end;
|
|
|
|
{@@
|
|
TCDGroupBox is a custom-drawn group box control
|
|
}
|
|
|
|
{ TCDGroupBox }
|
|
|
|
TCDGroupBox = class(TCDControl)
|
|
private
|
|
function GetControlId: TCDControlID; override;
|
|
protected
|
|
procedure RealSetText(const Value: TCaption); override; // to update on caption changes
|
|
public
|
|
constructor Create(AOwner: TComponent); override;
|
|
destructor Destroy; override;
|
|
published
|
|
property DrawStyle;
|
|
property Caption;
|
|
property TabStop default False;
|
|
end;
|
|
|
|
{ TCDCheckBox }
|
|
|
|
TCDCheckBox = class(TCDButtonControl)
|
|
private
|
|
FAllowGrayed: Boolean;
|
|
FCheckedState: TCheckBoxState;
|
|
protected
|
|
procedure DoButtonUp(); override;
|
|
procedure CalculatePreferredSize(var PreferredWidth,
|
|
PreferredHeight: integer; WithThemeSpace: Boolean); override;
|
|
function GetControlId: TCDControlID; override;
|
|
public
|
|
constructor Create(AOwner: TComponent); override;
|
|
destructor Destroy; override;
|
|
published
|
|
property AllowGrayed: Boolean read FAllowGrayed write FAllowGrayed default False;
|
|
property DrawStyle;
|
|
property Caption;
|
|
property TabStop default True;
|
|
property State: TCheckBoxState read FCheckedState write FCheckedState default cbUnchecked;
|
|
end;
|
|
|
|
{ TCDCheckBoxDrawer }
|
|
|
|
TCDCheckBoxDrawer = class(TCDDrawer)
|
|
public
|
|
procedure CalculatePreferredSize(CDCheckBox: TCDCheckBox; var PreferredWidth,
|
|
PreferredHeight: integer; WithThemeSpace: Boolean); virtual; abstract;
|
|
procedure DrawToIntfImage(ADest: TFPImageCanvas; CDCheckBox: TCDCheckBox); virtual; abstract;
|
|
procedure DrawToCanvas(ADest: TCanvas; CDCheckBox: TCDCheckBox); virtual; abstract;
|
|
end;
|
|
|
|
// ===================================
|
|
// Common Controls Tab
|
|
// ===================================
|
|
|
|
{@@
|
|
TCDTrackBar is a custom-drawn trackbar control
|
|
}
|
|
|
|
{ TCDTrackBar }
|
|
|
|
TCDTrackBar = class(TCDControl)
|
|
private
|
|
DragDropStarted: boolean;
|
|
// fields
|
|
FMin: integer;
|
|
FMax: integer;
|
|
FPosition: integer;
|
|
FOnChange: TNotifyEvent;
|
|
procedure SetMax(Value: integer);
|
|
procedure SetMin(Value: integer);
|
|
procedure SetPosition(Value: integer);
|
|
//
|
|
function GetPositionFromMousePos(X, Y: Integer): integer;
|
|
protected
|
|
FTBState: TCDTrackBarStateEx;
|
|
function GetControlId: TCDControlID; override;
|
|
procedure CreateControlStateEx; override;
|
|
procedure PrepareControlStateEx; override;
|
|
procedure Changed; virtual;
|
|
// keyboard
|
|
procedure DoEnter; override;
|
|
procedure DoExit; override;
|
|
procedure KeyDown(var Key: word; Shift: TShiftState); override;
|
|
procedure KeyUp(var Key: word; Shift: TShiftState); override;
|
|
// mouse
|
|
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;
|
|
procedure MouseEnter; override;
|
|
procedure MouseLeave; override;
|
|
public
|
|
constructor Create(AOwner: TComponent); override;
|
|
destructor Destroy; override;
|
|
//procedure Paint; override;
|
|
published
|
|
property Color;
|
|
property Max: integer read FMax write SetMax default 10;
|
|
property Min: integer read FMin write SetMin default 0;
|
|
property OnChange: TNotifyEvent read FOnChange write FOnChange;
|
|
property Position: integer read FPosition write SetPosition;
|
|
property TabStop default True;
|
|
end;
|
|
|
|
{ TCDTrackBarDrawer }
|
|
|
|
TCDTrackBarDrawer = class(TCDDrawer)
|
|
public
|
|
procedure DrawToIntfImage(ADest: TFPImageCanvas; FPImg: TLazIntfImage;
|
|
CDTrackBar: TCDTrackBar); virtual; abstract;
|
|
procedure GetGeometry(var ALeftBorder, ARightBorder: Integer); virtual; abstract;
|
|
end;
|
|
|
|
{ TCDListView }
|
|
|
|
(* TCDListView = class(TCDControl)
|
|
private
|
|
DragDropStarted: boolean;
|
|
// fields
|
|
protected
|
|
// keyboard
|
|
procedure DoEnter; override;
|
|
procedure DoExit; override;
|
|
procedure KeyDown(var Key: word; Shift: TShiftState); override;
|
|
procedure KeyUp(var Key: word; Shift: TShiftState); override;
|
|
// mouse
|
|
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;
|
|
procedure MouseEnter; override;
|
|
procedure MouseLeave; override;
|
|
public
|
|
constructor Create(AOwner: TComponent); override;
|
|
destructor Destroy; override;
|
|
procedure EraseBackground(DC: HDC); override;
|
|
procedure Paint; override;
|
|
published
|
|
property Color;
|
|
property TabStop default True;
|
|
end;*)
|
|
|
|
{TCDTabControl}
|
|
|
|
{ TCDCustomTabControl }
|
|
|
|
TCDCustomTabControl = class;
|
|
|
|
{ TCDCustomTabSheet }
|
|
|
|
TCDCustomTabSheet = class(TCustomControl)
|
|
private
|
|
CDTabControl: TCDCustomTabControl;
|
|
FTabVisible: Boolean;
|
|
protected
|
|
procedure RealSetText(const Value: TCaption); override; // to update on caption changes
|
|
public
|
|
destructor Destroy; override;
|
|
property TabVisible: Boolean read FTabVisible write FTabVisible;
|
|
end;
|
|
|
|
TCDCustomTabControl = class(TCDControl)
|
|
private
|
|
FTabIndex: Integer;
|
|
FTabs: TStringList;
|
|
FOnChanging: TNotifyEvent;
|
|
FOnChange: TNotifyEvent;
|
|
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;
|
|
//procedure MouseEnter; override;
|
|
//procedure MouseLeave; override;
|
|
procedure SetTabIndex(AValue: Integer); virtual;
|
|
procedure SetTabs(AValue: TStringList);
|
|
protected
|
|
FTabCState: TCDCTabControlStateEx;
|
|
function GetControlId: TCDControlID; override;
|
|
procedure CreateControlStateEx; override;
|
|
procedure PrepareControlStateEx; override;
|
|
procedure CorrectTabIndex();
|
|
public
|
|
constructor Create(AOwner: TComponent); override;
|
|
destructor Destroy; override;
|
|
function GetTabCount: Integer;
|
|
property Tabs: TStringList read FTabs write SetTabs;
|
|
property OnChanging: TNotifyEvent read FOnChanging write FOnChanging;
|
|
property OnChange: TNotifyEvent read FOnChange write FOnChange;
|
|
property TabIndex: integer read FTabIndex write SetTabIndex;
|
|
end;
|
|
|
|
// TTabSelectedEvent = procedure(Sender: TObject; ATab: TTabItem;
|
|
// ASelected: boolean) of object;
|
|
|
|
TCDTabControl = class(TCDCustomTabControl)
|
|
published
|
|
property Color;
|
|
property Font;
|
|
property Tabs;
|
|
property TabIndex;
|
|
property OnChanging;
|
|
property OnChange;
|
|
end;
|
|
|
|
{ TCDTabSheet }
|
|
|
|
TCDPageControl = class;
|
|
|
|
TCDTabSheet = class(TCDCustomTabSheet)
|
|
public
|
|
constructor Create(AOwner: TComponent); override;
|
|
destructor Destroy; override;
|
|
procedure EraseBackground(DC: HDC); override;
|
|
procedure Paint; override;
|
|
published
|
|
property Caption;
|
|
property Color;
|
|
property Font;
|
|
property TabVisible: Boolean;
|
|
end;
|
|
|
|
{ TCDPageControl }
|
|
|
|
TCDPageControl = class(TCDCustomTabControl)
|
|
private
|
|
FOptions: TNoteBookOptions;
|
|
function GetActivePage: TCDTabSheet;
|
|
function GetPageCount: integer;
|
|
function GetPageIndex: integer;
|
|
procedure SetActivePage(Value: TCDTabSheet);
|
|
procedure SetOptions(AValue: TNoteBookOptions);
|
|
procedure SetPageIndex(Value: integer);
|
|
procedure UpdateAllDesignerFlags;
|
|
procedure UpdateDesignerFlags(APageIndex: integer);
|
|
procedure PositionTabSheet(ATabSheet: TCDTabSheet);
|
|
public
|
|
constructor Create(AOwner: TComponent); override;
|
|
destructor Destroy; override;
|
|
function InsertPage(aIndex: integer; S: string): TCDTabSheet;
|
|
procedure RemovePage(aIndex: integer);
|
|
function AddPage(S: string): TCDTabSheet;
|
|
function GetPage(aIndex: integer): TCDTabSheet;
|
|
property PageCount: integer read GetPageCount;
|
|
// Used by the property editor in customdrawnextras
|
|
function FindNextPage(CurPage: TCDTabSheet;
|
|
GoForward, CheckTabVisible: boolean): TCDTabSheet;
|
|
procedure SelectNextPage(GoForward: boolean; CheckTabVisible: boolean = True);
|
|
published
|
|
property ActivePage: TCDTabSheet read GetActivePage write SetActivePage;
|
|
property DrawStyle;
|
|
property Caption;
|
|
property Color;
|
|
property Font;
|
|
property PageIndex: integer read GetPageIndex write SetPageIndex;
|
|
property Options: TNoteBookOptions read FOptions write SetOptions;
|
|
property ParentColor;
|
|
property ParentFont;
|
|
property TabStop default True;
|
|
property TabIndex;
|
|
property OnChanging;
|
|
property OnChange;
|
|
end;
|
|
|
|
implementation
|
|
|
|
resourcestring
|
|
sTABSHEET_DEFAULT_NAME = 'CTabSheet';
|
|
|
|
{ TCDEdit }
|
|
|
|
function TCDEdit.GetText: string;
|
|
begin
|
|
Result := Caption;
|
|
end;
|
|
|
|
function TCDEdit.GetControlId: TCDControlID;
|
|
begin
|
|
Result := cidEdit;
|
|
end;
|
|
|
|
procedure TCDEdit.CreateControlStateEx;
|
|
begin
|
|
FEditState := TCDEditStateEx.Create;
|
|
FStateEx := FEditState;
|
|
end;
|
|
|
|
procedure TCDEdit.HandleCaretTimer(Sender: TObject);
|
|
begin
|
|
FEditState.CaretIsVisible := not FEditState.CaretIsVisible;
|
|
Invalidate;
|
|
end;
|
|
|
|
procedure TCDEdit.DoDeleteSelection;
|
|
begin
|
|
FEditState.SelStart := 1;
|
|
FEditState.SelLength := 0;
|
|
end;
|
|
|
|
procedure TCDEdit.DoManageVisibleTextStart;
|
|
var
|
|
lText: String;
|
|
lVisibleTextCharCount: Integer;
|
|
lAvailableWidth: Integer;
|
|
begin
|
|
// Moved to the left and we need to adjust the text start
|
|
FEditState.VisibleTextStart := Min(FEditState.CaretPos+1, FEditState.VisibleTextStart);
|
|
|
|
// Moved to the right and we need to adjust the text start
|
|
lText := Copy(Text, FEditState.VisibleTextStart, Length(Text));
|
|
lAvailableWidth := Width
|
|
- FDrawer.GetMeasures(TCDEDIT_LEFT_TEXT_SPACING)
|
|
- FDrawer.GetMeasures(TCDEDIT_RIGHT_TEXT_SPACING);
|
|
lVisibleTextCharCount := Canvas.TextFitInfo(lText, lAvailableWidth);
|
|
FEditState.VisibleTextStart := Max(FEditState.CaretPos-lVisibleTextCharCount, FEditState.VisibleTextStart);
|
|
end;
|
|
|
|
procedure TCDEdit.SetText(AValue: string);
|
|
begin
|
|
Caption := AValue;
|
|
end;
|
|
|
|
procedure TCDEdit.DoEnter;
|
|
begin
|
|
inherited DoEnter;
|
|
|
|
FCaretTimer.Enabled := True;
|
|
FEditState.CaretIsVisible := True;
|
|
Invalidate;
|
|
end;
|
|
|
|
procedure TCDEdit.DoExit;
|
|
begin
|
|
inherited DoExit;
|
|
|
|
FCaretTimer.Enabled := False;
|
|
FEditState.CaretIsVisible := False;
|
|
Invalidate;
|
|
end;
|
|
|
|
procedure TCDEdit.KeyDown(var Key: word; Shift: TShiftState);
|
|
var
|
|
lLeftText, lRightText, lOldText: String;
|
|
begin
|
|
inherited KeyDown(Key, Shift);
|
|
|
|
lOldText := Text;
|
|
|
|
case Key of
|
|
// Backspace
|
|
VK_BACK:
|
|
begin
|
|
// Selection backspace
|
|
if FEditState.SelLength > 0 then
|
|
DoDeleteSelection()
|
|
// Normal backspace
|
|
else if FEditState.CaretPos > 0 then
|
|
begin
|
|
lLeftText := Copy(lOldText, 1, FEditState.CaretPos-1);
|
|
lRightText := Copy(lOldText, FEditState.CaretPos+1, Length(lOldText));
|
|
Text := lLeftText + lRightText;
|
|
Dec(FEditState.CaretPos);
|
|
DoManageVisibleTextStart();
|
|
Invalidate;
|
|
end;
|
|
end;
|
|
// DEL
|
|
VK_DELETE:
|
|
begin
|
|
// Selection delete
|
|
if FEditState.SelLength > 0 then
|
|
DoDeleteSelection()
|
|
// Normal delete
|
|
else if FEditState.CaretPos < Length(lOldText) then
|
|
begin
|
|
lLeftText := Copy(lOldText, 1, FEditState.CaretPos);
|
|
lRightText := Copy(lOldText, FEditState.CaretPos+2, Length(lOldText));
|
|
Text := lLeftText + lRightText;
|
|
Invalidate;
|
|
end;
|
|
end;
|
|
VK_LEFT:
|
|
begin
|
|
if (FEditState.CaretPos > 0) then
|
|
begin
|
|
// Selecting to the left
|
|
if ssShift in Shift then
|
|
begin
|
|
Dec(FEditState.SelLength);
|
|
if FEditState.SelStart < 0 then FEditState.SelStart := FEditState.CaretPos;
|
|
end
|
|
// Normal move to the left
|
|
else FEditState.SelLength := 0;
|
|
|
|
Dec(FEditState.CaretPos);
|
|
DoManageVisibleTextStart();
|
|
FEditState.CaretIsVisible := True;
|
|
Invalidate;
|
|
end;
|
|
end;
|
|
VK_RIGHT:
|
|
begin
|
|
if FEditState.CaretPos < Length(lOldText) then
|
|
begin
|
|
// Selecting to the right
|
|
if ssShift in Shift then
|
|
begin
|
|
Inc(FEditState.SelLength);
|
|
if FEditState.SelStart < 0 then FEditState.SelStart := FEditState.CaretPos;
|
|
end
|
|
// Normal move to the right
|
|
else FEditState.SelLength := 0;
|
|
|
|
Inc(FEditState.CaretPos);
|
|
DoManageVisibleTextStart();
|
|
FEditState.CaretIsVisible := True;
|
|
Invalidate;
|
|
end;
|
|
end;
|
|
|
|
end; // case
|
|
end;
|
|
|
|
procedure TCDEdit.KeyUp(var Key: word; Shift: TShiftState);
|
|
begin
|
|
inherited KeyUp(Key, Shift);
|
|
end;
|
|
|
|
procedure TCDEdit.UTF8KeyPress(var UTF8Key: TUTF8Char);
|
|
var
|
|
lLeftText, lRightText, lOldText: String;
|
|
begin
|
|
inherited UTF8KeyPress(UTF8Key);
|
|
|
|
// LCL Carbon sends Backspace as a UTF-8 Char
|
|
// Don't handle it here because it is already handled in KeyDown
|
|
if UTF8Key = #8 then Exit;
|
|
|
|
DoDeleteSelection;
|
|
|
|
// Normal characters
|
|
lOldText := Text;
|
|
lLeftText := Copy(lOldText, 1, FEditState.CaretPos);
|
|
lRightText := Copy(lOldText, FEditState.CaretPos+1, Length(lOldText));
|
|
Text := lLeftText + UTF8Key + lRightText;
|
|
Inc(FEditState.CaretPos);
|
|
FEditState.CaretIsVisible := True;
|
|
Invalidate;
|
|
end;
|
|
|
|
procedure TCDEdit.MouseDown(Button: TMouseButton; Shift: TShiftState; X,
|
|
Y: integer);
|
|
begin
|
|
inherited MouseDown(Button, Shift, X, Y);
|
|
end;
|
|
|
|
procedure TCDEdit.MouseMove(Shift: TShiftState; X, Y: integer);
|
|
begin
|
|
inherited MouseMove(Shift, X, Y);
|
|
end;
|
|
|
|
procedure TCDEdit.MouseUp(Button: TMouseButton; Shift: TShiftState; X,
|
|
Y: integer);
|
|
begin
|
|
inherited MouseUp(Button, Shift, X, Y);
|
|
end;
|
|
|
|
procedure TCDEdit.MouseEnter;
|
|
begin
|
|
inherited MouseEnter;
|
|
end;
|
|
|
|
procedure TCDEdit.MouseLeave;
|
|
begin
|
|
inherited MouseLeave;
|
|
end;
|
|
|
|
constructor TCDEdit.Create(AOwner: TComponent);
|
|
begin
|
|
inherited Create(AOwner);
|
|
Width := 100;
|
|
Height := 30;
|
|
TabStop := True;
|
|
ControlStyle := [csCaptureMouse, csClickEvents,
|
|
csDoubleClicks, csReplicatable];
|
|
|
|
// State information
|
|
FEditState.VisibleTextStart := 1;
|
|
FEditState.SelStart := -1;
|
|
|
|
// Caret code
|
|
FCaretTimer := TTimer.Create(Self);
|
|
FCaretTimer.OnTimer := @HandleCaretTimer;
|
|
FCaretTimer.Interval := 500;
|
|
FCaretTimer.Enabled := False;
|
|
|
|
PrepareCurrentDrawer();
|
|
end;
|
|
|
|
destructor TCDEdit.Destroy;
|
|
begin
|
|
inherited Destroy;
|
|
end;
|
|
|
|
{ TCDCheckBox }
|
|
|
|
procedure TCDCheckBox.DoButtonUp;
|
|
begin
|
|
inherited DoButtonUp;
|
|
|
|
if AllowGrayed then
|
|
begin
|
|
case FCheckedState of
|
|
cbUnchecked: FCheckedState := cbGrayed;
|
|
cbGrayed: FCheckedState := cbChecked;
|
|
else
|
|
FCheckedState := cbUnchecked;
|
|
end;
|
|
end
|
|
else
|
|
begin
|
|
if FCheckedState in [cbUnchecked, cbGrayed] then FCheckedState := cbChecked
|
|
else FCheckedState := cbUnchecked;
|
|
end;
|
|
|
|
Invalidate;
|
|
end;
|
|
|
|
procedure TCDCheckBox.CalculatePreferredSize(var PreferredWidth,
|
|
PreferredHeight: integer; WithThemeSpace: Boolean);
|
|
begin
|
|
TCDCheckBoxDrawer(FDrawer).CalculatePreferredSize(
|
|
Self, PreferredWidth, PreferredHeight, WithThemeSpace)
|
|
end;
|
|
|
|
function TCDCheckBox.GetControlId: TCDControlID;
|
|
begin
|
|
Result := cidCheckBox;
|
|
end;
|
|
|
|
constructor TCDCheckBox.Create(AOwner: TComponent);
|
|
begin
|
|
inherited Create(AOwner);
|
|
Width := 75;
|
|
Height := 17;
|
|
TabStop := True;
|
|
ControlStyle := [csCaptureMouse, csClickEvents,
|
|
csDoubleClicks, csReplicatable];
|
|
AutoSize := True;
|
|
|
|
DrawStyle := dsWinXP;
|
|
PrepareCurrentDrawer();
|
|
end;
|
|
|
|
destructor TCDCheckBox.Destroy;
|
|
begin
|
|
inherited Destroy;
|
|
end;
|
|
|
|
{ TCDCustomTabSheet }
|
|
|
|
procedure TCDCustomTabSheet.RealSetText(const Value: TCaption);
|
|
var
|
|
lIndex: Integer;
|
|
begin
|
|
inherited RealSetText(Value);
|
|
lIndex := CDTabControl.Tabs.IndexOfObject(Self);
|
|
if lIndex >= 0 then
|
|
CDTabControl.Tabs.Strings[lIndex] := Value;
|
|
CDTabControl.Invalidate;
|
|
end;
|
|
|
|
destructor TCDCustomTabSheet.Destroy;
|
|
var
|
|
lIndex: Integer;
|
|
begin
|
|
// We should support deleting the tabsheet directly too,
|
|
// and then it should update the tabcontrol
|
|
// This is important mostly for the designer
|
|
if CDTabControl <> nil then
|
|
begin
|
|
lIndex := CDTabControl.FTabs.IndexOfObject(Self);
|
|
if lIndex >= 0 then
|
|
begin
|
|
CDTabControl.FTabs.Delete(lIndex);
|
|
CDTabControl.CorrectTabIndex();
|
|
end;
|
|
end;
|
|
|
|
inherited Destroy;
|
|
end;
|
|
|
|
{ TCDCustomTabControl }
|
|
|
|
procedure TCDCustomTabControl.MouseDown(Button: TMouseButton;
|
|
Shift: TShiftState; X, Y: integer);
|
|
var
|
|
i: Integer;
|
|
CurPage: TCDTabSheet;
|
|
CurStartLeftPos: Integer = 0;
|
|
VisiblePagesStarted: Boolean = False;
|
|
lTabWidth: Integer;
|
|
begin
|
|
inherited MouseDown(Button, Shift, X, Y);
|
|
|
|
for i := 0 to Tabs.Count - 1 do
|
|
begin
|
|
if i = FTabCState.LeftmostTabVisibleIndex then
|
|
VisiblePagesStarted := True;
|
|
|
|
if VisiblePagesStarted then
|
|
begin
|
|
FTabCState.TabIndex := i;
|
|
lTabWidth := FDrawer.GetMeasuresEx(Canvas, TCDCTABCONTROL_TAB_WIDTH, FState, FTabCState);
|
|
if (X > CurStartLeftPos) and
|
|
(X < CurStartLeftPos + lTabWidth) and
|
|
(Y < FDrawer.GetMeasuresEx(Canvas, TCDCTABCONTROL_TAB_HEIGHT, FState, FTabCState)) then
|
|
begin
|
|
if Self is TCDPageControl then
|
|
(Self as TCDPageControl).PageIndex := i
|
|
else
|
|
TabIndex := i;
|
|
|
|
Exit;
|
|
end;
|
|
CurStartLeftPos := CurStartLeftPos + lTabWidth;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TCDCustomTabControl.MouseUp(Button: TMouseButton; Shift: TShiftState;
|
|
X, Y: integer);
|
|
begin
|
|
|
|
inherited MouseUp(Button, Shift, X, Y);
|
|
end;
|
|
|
|
procedure TCDCustomTabControl.SetTabIndex(AValue: Integer);
|
|
begin
|
|
if FTabIndex = AValue then Exit;
|
|
if Assigned(OnChanging) then OnChanging(Self);
|
|
FTabIndex := AValue;
|
|
if Assigned(OnChange) then OnChange(Self);
|
|
Invalidate;
|
|
end;
|
|
|
|
procedure TCDCustomTabControl.SetTabs(AValue: TStringList);
|
|
begin
|
|
if FTabs=AValue then Exit;
|
|
FTabs.Assign(AValue);
|
|
CorrectTabIndex();
|
|
Invalidate;
|
|
end;
|
|
|
|
function TCDCustomTabControl.GetControlId: TCDControlID;
|
|
begin
|
|
Result := cidCustomTabControl;
|
|
end;
|
|
|
|
procedure TCDCustomTabControl.CreateControlStateEx;
|
|
begin
|
|
FTabCState := TCDCTabControlStateEx.Create;
|
|
FStateEx := FTabCState;
|
|
end;
|
|
|
|
procedure TCDCustomTabControl.PrepareControlStateEx;
|
|
begin
|
|
inherited PrepareControlStateEx;
|
|
|
|
FTabCState.Tabs := Tabs;
|
|
FTabCState.TabIndex := TabIndex;
|
|
FTabCState.TabCount := GetTabCount();
|
|
end;
|
|
|
|
constructor TCDCustomTabControl.Create(AOwner: TComponent);
|
|
begin
|
|
inherited Create(AOwner);
|
|
|
|
Width := 232;
|
|
Height := 184;
|
|
TabStop := True;
|
|
|
|
PrepareCurrentDrawer();
|
|
|
|
ParentColor := True;
|
|
ParentFont := True;
|
|
ControlStyle := ControlStyle + [csAcceptsControls, csDesignInteractive];
|
|
|
|
// FTabs should hold only visible tabs
|
|
FTabs := TStringList.Create;
|
|
end;
|
|
|
|
destructor TCDCustomTabControl.Destroy;
|
|
begin
|
|
FTabs.Free;
|
|
|
|
inherited Destroy;
|
|
end;
|
|
|
|
function TCDCustomTabControl.GetTabCount: Integer;
|
|
begin
|
|
Result := 0;
|
|
if FTabs <> nil then Result := FTabs.Count;
|
|
end;
|
|
|
|
procedure TCDCustomTabControl.CorrectTabIndex;
|
|
begin
|
|
if FTabIndex >= FTabs.Count then SetTabIndex(FTabs.Count - 1);
|
|
end;
|
|
|
|
{ TCDControl }
|
|
|
|
procedure TCDControl.PrepareCurrentDrawer;
|
|
begin
|
|
FDrawer := GetDrawer(FDrawStyle);
|
|
if FDrawer = nil then FDrawer := GetDrawer(dsCommon); // avoid exceptions in the object inspector if an invalid drawer is selected
|
|
if FDrawer = nil then raise Exception.Create('No registered drawers were found');
|
|
end;
|
|
|
|
procedure TCDControl.SetDrawStyle(const AValue: TCDDrawStyle);
|
|
begin
|
|
if FDrawStyle = AValue then exit;
|
|
FDrawStyle := AValue;
|
|
Invalidate;
|
|
PrepareCurrentDrawer();
|
|
|
|
//FCurrentDrawer.SetClientRectPos(Self);
|
|
end;
|
|
|
|
function TCDControl.GetClientRect: TRect;
|
|
begin
|
|
// Disable this, since although it works in Win32, it doesn't seam to work in LCL-Carbon
|
|
//if (FCurrentDrawer = nil) then
|
|
Result := inherited GetClientRect()
|
|
//else
|
|
//Result := FCurrentDrawer.GetClientRect(Self);
|
|
end;
|
|
|
|
function TCDControl.GetControlId: TCDControlID;
|
|
begin
|
|
Result := cidControl;
|
|
end;
|
|
|
|
procedure TCDControl.CreateControlStateEx;
|
|
begin
|
|
FStateEx := TCDControlStateEx.Create;
|
|
end;
|
|
|
|
procedure TCDControl.PrepareControlState;
|
|
begin
|
|
if Focused then FState := FState + [csfHasFocus]
|
|
else FState := FState - [csfHasFocus];
|
|
|
|
if Enabled then FState := FState + [csfEnabled]
|
|
else FState := FState - [csfEnabled];
|
|
end;
|
|
|
|
procedure TCDControl.PrepareControlStateEx;
|
|
begin
|
|
if Parent <> nil then FStateEx.ParentRGBColor := Parent.GetRGBBackgroundColor;
|
|
if Color = clDefault then FStateEx.RGBColor := FDrawer.GetControlColor(GetControlId())
|
|
else FStateEx.RGBColor := GetRGBBackgroundColor;
|
|
FStateEx.Caption := Caption;
|
|
FStateEx.Font := Font;
|
|
FStateEx.AutoSize := AutoSize;
|
|
end;
|
|
|
|
procedure TCDControl.EraseBackground(DC: HDC);
|
|
begin
|
|
|
|
end;
|
|
|
|
procedure TCDControl.Paint;
|
|
var
|
|
ABmp: TBitmap;
|
|
lSize: TSize;
|
|
lControlId: TCDControlID;
|
|
begin
|
|
inherited Paint;
|
|
|
|
PrepareCurrentDrawer();
|
|
|
|
ABmp := TBitmap.Create;
|
|
try
|
|
ABmp.Width := Width;
|
|
ABmp.Height := Height;
|
|
lSize := Size(Width, Height);
|
|
lControlId := GetControlId();
|
|
PrepareControlState;
|
|
PrepareControlStateEx;
|
|
FDrawer.DrawControl(ABmp.Canvas, Point(0, 0),
|
|
lSize, lControlId, FState, FStateEx);
|
|
Canvas.Draw(0, 0, ABmp);
|
|
finally
|
|
ABmp.Free;
|
|
end;
|
|
end;
|
|
|
|
procedure TCDControl.MouseEnter;
|
|
begin
|
|
FState := FState + [csfMouseOver];
|
|
inherited MouseEnter;
|
|
end;
|
|
|
|
procedure TCDControl.MouseLeave;
|
|
begin
|
|
FState := FState - [csfMouseOver];
|
|
inherited MouseLeave;
|
|
end;
|
|
|
|
constructor TCDControl.Create(AOwner: TComponent);
|
|
begin
|
|
inherited Create(AOwner);
|
|
CreateControlStateEx;
|
|
end;
|
|
|
|
destructor TCDControl.Destroy;
|
|
begin
|
|
FStateEx.Free;
|
|
inherited Destroy;
|
|
end;
|
|
|
|
{ TCDButtonDrawer }
|
|
|
|
procedure TCDButtonControl.DoEnter;
|
|
begin
|
|
Invalidate;
|
|
|
|
inherited DoEnter;
|
|
end;
|
|
|
|
procedure TCDButtonControl.DoExit;
|
|
begin
|
|
Invalidate;
|
|
|
|
inherited DoExit;
|
|
end;
|
|
|
|
procedure TCDButtonControl.KeyDown(var Key: word; Shift: TShiftState);
|
|
begin
|
|
inherited KeyDown(Key, Shift);
|
|
|
|
if (Key = VK_SPACE) or (Key = VK_RETURN) then
|
|
DoButtonDown();
|
|
end;
|
|
|
|
procedure TCDButtonControl.KeyUp(var Key: word; Shift: TShiftState);
|
|
begin
|
|
if (Key = VK_SPACE) or (Key = VK_RETURN) then
|
|
DoButtonUp();
|
|
|
|
inherited KeyUp(Key, Shift);
|
|
end;
|
|
|
|
procedure TCDButtonControl.MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: integer);
|
|
begin
|
|
if not Focused then
|
|
SetFocus;
|
|
DoButtonDown();
|
|
|
|
inherited MouseDown(Button, Shift, X, Y);
|
|
end;
|
|
|
|
procedure TCDButtonControl.MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: integer);
|
|
begin
|
|
DoButtonUp();
|
|
|
|
inherited MouseUp(Button, Shift, X, Y);
|
|
end;
|
|
|
|
procedure TCDButtonControl.MouseEnter;
|
|
begin
|
|
Invalidate;
|
|
inherited MouseEnter;
|
|
end;
|
|
|
|
procedure TCDButtonControl.MouseLeave;
|
|
begin
|
|
Invalidate;
|
|
inherited MouseLeave;
|
|
end;
|
|
|
|
procedure TCDButtonControl.DoButtonDown();
|
|
begin
|
|
if not (csfSunken in FState) then
|
|
begin
|
|
FState := FState + [csfSunken];
|
|
Invalidate;
|
|
end;
|
|
end;
|
|
|
|
procedure TCDButtonControl.DoButtonUp();
|
|
begin
|
|
if csfSunken in FState then
|
|
begin
|
|
FState := FState - [csfSunken];
|
|
Invalidate;
|
|
end;
|
|
end;
|
|
|
|
procedure TCDButtonControl.RealSetText(const Value: TCaption);
|
|
begin
|
|
inherited RealSetText(Value);
|
|
Invalidate;
|
|
end;
|
|
|
|
function TCDButton.GetControlId: TCDControlID;
|
|
begin
|
|
Result := cidButton;
|
|
end;
|
|
|
|
constructor TCDButton.Create(AOwner: TComponent);
|
|
begin
|
|
inherited Create(AOwner);
|
|
TabStop := True;
|
|
Width := 75;
|
|
Height := 25;
|
|
//Color := clTeal;
|
|
ParentFont := True;
|
|
Color := $00F1F5F5;
|
|
PrepareCurrentDrawer();
|
|
end;
|
|
|
|
destructor TCDButton.Destroy;
|
|
begin
|
|
inherited Destroy;
|
|
end;
|
|
|
|
{ TCDGroupBox }
|
|
|
|
function TCDGroupBox.GetControlId: TCDControlID;
|
|
begin
|
|
Result := cidGroupBox;
|
|
end;
|
|
|
|
procedure TCDGroupBox.RealSetText(const Value: TCaption);
|
|
begin
|
|
inherited RealSetText(Value);
|
|
Invalidate;
|
|
end;
|
|
|
|
constructor TCDGroupBox.Create(AOwner: TComponent);
|
|
begin
|
|
inherited Create(AOwner);
|
|
Width := 100;
|
|
Height := 100;
|
|
TabStop := False;
|
|
ControlStyle := [csAcceptsControls, csCaptureMouse, csClickEvents,
|
|
csDoubleClicks, csReplicatable];
|
|
end;
|
|
|
|
destructor TCDGroupBox.Destroy;
|
|
begin
|
|
inherited Destroy;
|
|
end;
|
|
|
|
{ TCDTrackBar }
|
|
|
|
procedure TCDTrackBar.SetMax(Value: integer);
|
|
begin
|
|
if Value = FMax then
|
|
Exit;
|
|
FMax := Value;
|
|
Invalidate;
|
|
end;
|
|
|
|
procedure TCDTrackBar.SetMin(Value: integer);
|
|
begin
|
|
if Value = FMin then
|
|
Exit;
|
|
FMin := Value;
|
|
Invalidate;
|
|
end;
|
|
|
|
procedure TCDTrackBar.SetPosition(Value: integer);
|
|
begin
|
|
if Value = FPosition then Exit;
|
|
FPosition := Value;
|
|
Invalidate;
|
|
end;
|
|
|
|
function TCDTrackBar.GetPositionFromMousePos(X, Y: integer): integer;
|
|
var
|
|
lLeftBorder, lRightBorder: Integer;
|
|
begin
|
|
TCDTrackBarDrawer(FDrawer).GetGeometry(lLeftBorder, lRightBorder);
|
|
if X > Width - lRightBorder then Result := FMax
|
|
else if X < lLeftBorder then Result := FMin
|
|
else Result := FMin + (X - lLeftBorder) * (FMax - FMin + 1) div (Width - lRightBorder - lLeftBorder);
|
|
|
|
// sanity check
|
|
if Result > FMax then Result := FMax;
|
|
if Result < FMin then Result := FMin;
|
|
end;
|
|
|
|
function TCDTrackBar.GetControlId: TCDControlID;
|
|
begin
|
|
Result := cidTrackBar;
|
|
end;
|
|
|
|
procedure TCDTrackBar.CreateControlStateEx;
|
|
begin
|
|
FTBState := TCDTrackBarStateEx.Create;
|
|
FStateEx := FTBState;
|
|
end;
|
|
|
|
procedure TCDTrackBar.PrepareControlStateEx;
|
|
begin
|
|
inherited PrepareControlStateEx;
|
|
FTBState.Min := FMin;
|
|
FTBState.Max := FMax;
|
|
FTBState.Position := FPosition;
|
|
end;
|
|
|
|
procedure TCDTrackBar.Changed;
|
|
begin
|
|
|
|
end;
|
|
|
|
procedure TCDTrackBar.DoEnter;
|
|
begin
|
|
inherited DoEnter;
|
|
end;
|
|
|
|
procedure TCDTrackBar.DoExit;
|
|
begin
|
|
inherited DoExit;
|
|
end;
|
|
|
|
procedure TCDTrackBar.KeyDown(var Key: word; Shift: TShiftState);
|
|
var
|
|
NewPosition: Integer;
|
|
begin
|
|
inherited KeyDown(Key, Shift);
|
|
if (Key = 37) or (Key = 40) then
|
|
NewPosition := FPosition - (FMax - FMin) div 10;
|
|
if (Key = 38) or (Key = 39) then
|
|
NewPosition := FPosition + (FMax - FMin) div 10;
|
|
|
|
// sanity check
|
|
if NewPosition > FMax then NewPosition := FMax;
|
|
if NewPosition < FMin then NewPosition := FMin;
|
|
|
|
Position := NewPosition;
|
|
end;
|
|
|
|
procedure TCDTrackBar.KeyUp(var Key: word; Shift: TShiftState);
|
|
begin
|
|
inherited KeyUp(Key, Shift);
|
|
end;
|
|
|
|
procedure TCDTrackBar.MouseDown(Button: TMouseButton; Shift: TShiftState;
|
|
X, Y: integer);
|
|
var
|
|
NewPosition: Integer;
|
|
begin
|
|
SetFocus;
|
|
|
|
NewPosition := GetPositionFromMousePos(X, Y);
|
|
|
|
DragDropStarted := True;
|
|
|
|
Position := NewPosition;
|
|
|
|
inherited MouseDown(Button, Shift, X, Y);
|
|
end;
|
|
|
|
procedure TCDTrackBar.MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: integer);
|
|
begin
|
|
DragDropStarted := False;
|
|
inherited MouseUp(Button, Shift, X, Y);
|
|
end;
|
|
|
|
procedure TCDTrackBar.MouseMove(Shift: TShiftState; X, Y: integer);
|
|
var
|
|
NewPosition: Integer;
|
|
begin
|
|
if DragDropStarted then
|
|
begin
|
|
NewPosition := GetPositionFromMousePos(X, Y);
|
|
Position := NewPosition;
|
|
end;
|
|
inherited MouseMove(Shift, X, Y);
|
|
end;
|
|
|
|
procedure TCDTrackBar.MouseEnter;
|
|
begin
|
|
inherited MouseEnter;
|
|
end;
|
|
|
|
procedure TCDTrackBar.MouseLeave;
|
|
begin
|
|
inherited MouseLeave;
|
|
end;
|
|
|
|
constructor TCDTrackBar.Create(AOwner: TComponent);
|
|
begin
|
|
inherited Create(AOwner);
|
|
Height := 25;
|
|
Width := 100;
|
|
|
|
DrawStyle := dsExtra1;
|
|
PrepareCurrentDrawer();
|
|
|
|
Color := clBtnFace;
|
|
FMax := 10;
|
|
FMin := 0;
|
|
TabStop := True;
|
|
end;
|
|
|
|
destructor TCDTrackBar.Destroy;
|
|
begin
|
|
inherited Destroy;
|
|
end;
|
|
|
|
{procedure TCDTrackBar.Paint;
|
|
var
|
|
AImage: TLazIntfImage = nil;
|
|
ABmp: TBitmap = nil;
|
|
lCanvas: TFPImageCanvas = nil;
|
|
begin
|
|
ABmp := TBitmap.Create;
|
|
try
|
|
ABmp.Width := Width;
|
|
ABmp.Height := Height;
|
|
AImage := ABmp.CreateIntfImage;
|
|
lCanvas := TFPImageCanvas.Create(AImage);
|
|
// First step of the drawing: FCL TFPCustomCanvas for fast pixel access
|
|
FCurrentDrawer.DrawToIntfImage(lCanvas, AImage, Self);
|
|
ABmp.LoadFromIntfImage(AImage);
|
|
Canvas.Draw(0, 0, ABmp);
|
|
finally
|
|
if lCanvas <> nil then
|
|
lCanvas.Free;
|
|
if AImage <> nil then
|
|
AImage.Free;
|
|
ABmp.Free;
|
|
end;
|
|
end;}
|
|
|
|
{ TCDTabSheet }
|
|
|
|
constructor TCDTabSheet.Create(AOwner: TComponent);
|
|
begin
|
|
inherited Create(AOwner);
|
|
|
|
TabStop := False;
|
|
ParentColor := True;
|
|
parentFont := True;
|
|
ControlStyle := [csAcceptsControls, csCaptureMouse, csClickEvents,
|
|
csDesignFixedBounds, csDoubleClicks, csDesignInteractive];
|
|
//ControlStyle := ControlStyle + [csAcceptsControls, csDesignFixedBounds,
|
|
// csNoDesignVisible, csNoFocus];
|
|
end;
|
|
|
|
destructor TCDTabSheet.Destroy;
|
|
begin
|
|
inherited Destroy;
|
|
end;
|
|
|
|
procedure TCDTabSheet.EraseBackground(DC: HDC);
|
|
begin
|
|
|
|
end;
|
|
|
|
procedure TCDTabSheet.Paint;
|
|
var
|
|
lSize: TSize;
|
|
begin
|
|
if CDTabControl <> nil then
|
|
begin
|
|
lSize := Size(Width, Height);
|
|
CDTabControl.FDrawer.DrawTabSheet(Canvas, Point(0, 0), lSize, CDTabControl.FState,
|
|
CDTabControl.FTabCState);
|
|
end;
|
|
end;
|
|
|
|
{ TCDPageControl }
|
|
|
|
function TCDPageControl.AddPage(S: string): TCDTabSheet;
|
|
// InsertPage(FPages.Count, S);
|
|
var
|
|
NewPage: TCDTabSheet;
|
|
begin
|
|
NewPage := TCDTabSheet.Create(Owner);
|
|
NewPage.Parent := Self;
|
|
NewPage.CDTabControl := Self;
|
|
//Name := Designer.CreateUniqueComponentName(ClassName);
|
|
{ NewPage.Name := GetUniqueName(sTABSHEET_DEFAULT_NAME, Self.Owner);
|
|
if S = '' then
|
|
NewPage.Caption := NewPage.Name
|
|
else}
|
|
NewPage.Caption := S;
|
|
|
|
PositionTabSheet(NewPage);
|
|
|
|
FTabs.AddObject(S, NewPage);
|
|
|
|
SetActivePage(NewPage);
|
|
|
|
Result := NewPage;
|
|
end;
|
|
|
|
function TCDPageControl.GetPage(AIndex: integer): TCDTabSheet;
|
|
begin
|
|
if (AIndex >= 0) and (AIndex < FTabs.Count) then
|
|
Result := TCDTabSheet(FTabs.Objects[AIndex])
|
|
else
|
|
Result := nil;
|
|
end;
|
|
|
|
function TCDPageControl.InsertPage(aIndex: integer; S: string): TCDTabSheet;
|
|
var
|
|
NewPage: TCDTabSheet;
|
|
begin
|
|
NewPage := TCDTabSheet.Create(Owner);
|
|
NewPage.Parent := Self;
|
|
//Name := Designer.CreateUniqueComponentName(ClassName);
|
|
{ NewPage.Name := GetUniqueName(sTABSHEET_DEFAULT_NAME, Self.Owner);
|
|
if S = '' then
|
|
NewPage.Caption := NewPage.Name
|
|
else}
|
|
NewPage.Caption := S;
|
|
|
|
PositionTabSheet(NewPage);
|
|
|
|
FTabs.InsertObject(AIndex, S, NewPage);
|
|
|
|
SetActivePage(NewPage);
|
|
Result := NewPage;
|
|
end;
|
|
|
|
procedure TCDPageControl.RemovePage(aIndex: integer);
|
|
begin
|
|
if (AIndex < 0) or (AIndex >= FTabs.Count) then Exit;
|
|
|
|
Application.ReleaseComponent(TComponent(FTabs.Objects[AIndex]));
|
|
|
|
FTabs.Delete(aIndex);
|
|
if FTabIndex >= FTabs.Count then SetTabIndex(FTabIndex-1);
|
|
|
|
Invalidate;
|
|
end;
|
|
|
|
function TCDPageControl.FindNextPage(CurPage: TCDTabSheet;
|
|
GoForward, CheckTabVisible: boolean): TCDTabSheet;
|
|
var
|
|
I, TempStartIndex: integer;
|
|
begin
|
|
if FTabs.Count <> 0 then
|
|
begin
|
|
//StartIndex := FPages.IndexOfObject(CurPage);
|
|
TempStartIndex := FTabs.IndexOfObject(CurPage);
|
|
if TempStartIndex = -1 then
|
|
if GoForward then
|
|
TempStartIndex := FTabs.Count - 1
|
|
else
|
|
TempStartIndex := 0;
|
|
I := TempStartIndex;
|
|
repeat
|
|
if GoForward then
|
|
begin
|
|
Inc(I);
|
|
if I = FTabs.Count then
|
|
I := 0;
|
|
end
|
|
else
|
|
begin
|
|
if I = 0 then
|
|
I := FTabs.Count;
|
|
Dec(I);
|
|
end;
|
|
Result := TCDTabSheet(FTabs.Objects[I]);
|
|
if not CheckTabVisible or Result.Visible then
|
|
Exit;
|
|
until I = TempStartIndex;
|
|
end;
|
|
Result := nil;
|
|
end;
|
|
|
|
procedure TCDPageControl.SelectNextPage(GoForward: boolean;
|
|
CheckTabVisible: boolean = True);
|
|
var
|
|
Page: TCDTabSheet;
|
|
begin
|
|
Page := FindNextPage(ActivePage, GoForward, CheckTabVisible);
|
|
if (Page <> nil) and (Page <> ActivePage) then
|
|
SetActivePage(Page);
|
|
end;
|
|
|
|
constructor TCDPageControl.Create(AOwner: TComponent);
|
|
begin
|
|
inherited Create(AOwner);
|
|
|
|
ControlStyle := ControlStyle - [csAcceptsControls];
|
|
end;
|
|
|
|
destructor TCDPageControl.Destroy;
|
|
begin
|
|
inherited Destroy;
|
|
end;
|
|
|
|
procedure TCDPageControl.SetActivePage(Value: TCDTabSheet);
|
|
var
|
|
i: integer;
|
|
CurPage: TCDTabSheet;
|
|
begin
|
|
for i := 0 to FTabs.Count - 1 do
|
|
begin
|
|
CurPage := TCDTabSheet(FTabs.Objects[i]);
|
|
if CurPage = Value then
|
|
begin
|
|
PositionTabSheet(CurPage);
|
|
CurPage.BringToFront;
|
|
CurPage.Visible := True;
|
|
|
|
// Check first, Tab is Visible?
|
|
SetTabIndex(i);
|
|
end
|
|
else if CurPage <> nil then
|
|
begin
|
|
//CurPage.Align := alNone;
|
|
//CurPage.Height := 0;
|
|
CurPage.Visible := False;
|
|
end;
|
|
end;
|
|
|
|
Invalidate;
|
|
end;
|
|
|
|
procedure TCDPageControl.SetOptions(AValue: TNoteBookOptions);
|
|
begin
|
|
if FOptions=AValue then Exit;
|
|
FOptions:=AValue;
|
|
end;
|
|
|
|
procedure TCDPageControl.SetPageIndex(Value: integer);
|
|
begin
|
|
if (Value > -1) and (Value < FTabs.Count) then
|
|
begin
|
|
SetTabIndex(Value);
|
|
ActivePage := GetPage(Value);
|
|
end;
|
|
end;
|
|
|
|
procedure TCDPageControl.UpdateAllDesignerFlags;
|
|
var
|
|
i: integer;
|
|
begin
|
|
for i := 0 to FTabs.Count - 1 do
|
|
UpdateDesignerFlags(i);
|
|
end;
|
|
|
|
procedure TCDPageControl.UpdateDesignerFlags(APageIndex: integer);
|
|
var
|
|
CurPage: TCDTabSheet;
|
|
begin
|
|
CurPage := GetPage(APageIndex);
|
|
if APageIndex <> fTabIndex then
|
|
CurPage.ControlStyle := CurPage.ControlStyle + [csNoDesignVisible]
|
|
else
|
|
CurPage.ControlStyle := CurPage.ControlStyle - [csNoDesignVisible];
|
|
end;
|
|
|
|
procedure TCDPageControl.PositionTabSheet(ATabSheet: TCDTabSheet);
|
|
var
|
|
lTabHeight, lIndex: Integer;
|
|
begin
|
|
// ATabSheet.SetBounds(1, 32 + 1, Width - 3, Height - 32 - 4);
|
|
lIndex := FTabs.IndexOfObject(ATabSheet);
|
|
FTabCState.TabIndex := lIndex;
|
|
lTabHeight := FDrawer.GetMeasuresEx(Canvas, TCDCTABCONTROL_TAB_HEIGHT, FState, FStateEx);
|
|
ATabSheet.BorderSpacing.Top := lTabHeight;
|
|
ATabSheet.BorderSpacing.Left := 2;
|
|
ATabSheet.BorderSpacing.Right := 3;
|
|
ATabSheet.BorderSpacing.Bottom := 3;
|
|
ATabSheet.Align := alClient;
|
|
end;
|
|
|
|
function TCDPageControl.GetActivePage: TCDTabSheet;
|
|
begin
|
|
Result := GetPage(FTabIndex);
|
|
end;
|
|
|
|
function TCDPageControl.GetPageCount: integer;
|
|
begin
|
|
Result := FTabs.Count;
|
|
end;
|
|
|
|
function TCDPageControl.GetPageIndex: integer;
|
|
begin
|
|
Result := FTabIndex;
|
|
end;
|
|
|
|
end.
|
|
|