mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-19 04:19:09 +02:00
LCL: Separate TCalculatorForm from ExtDlgs to its own unit. Issue #28516, modified patch from Alexey Torgashin.
git-svn-id: trunk@49687 -
This commit is contained in:
parent
e9b079631b
commit
80a540632b
@ -32,7 +32,7 @@ interface
|
||||
uses
|
||||
Classes, SysUtils, LCLProc, LResources, LCLStrConsts, Types, LCLType, LMessages,
|
||||
Graphics, Controls, Forms, LazFileUtils, Dialogs, StdCtrls, Buttons, Calendar,
|
||||
ExtDlgs, CalendarPopup, MaskEdit, Menus, StrUtils, DateUtils, TimePopup;
|
||||
ExtDlgs, CalendarPopup, MaskEdit, Menus, StrUtils, DateUtils, TimePopup, CalcForm;
|
||||
|
||||
const
|
||||
NullDate: TDateTime = 0;
|
||||
|
777
lcl/extdlgs.pas
777
lcl/extdlgs.pas
@ -23,7 +23,7 @@ interface
|
||||
uses
|
||||
Types, Classes, SysUtils, LCLProc, LResources, LCLType, LCLStrConsts,
|
||||
FileUtil, LazFileUtils, Controls, Dialogs, GraphType, Graphics, ExtCtrls,
|
||||
StdCtrls, Forms, Calendar, Buttons, Masks;
|
||||
StdCtrls, Forms, Calendar, Buttons, Masks, CalcForm;
|
||||
|
||||
type
|
||||
|
||||
@ -45,7 +45,6 @@ type
|
||||
write SetPreviewFileDialog;
|
||||
end;
|
||||
|
||||
|
||||
{ TPreviewFileDialog }
|
||||
|
||||
TPreviewFileDialog = class(TOpenDialog)
|
||||
@ -61,7 +60,6 @@ type
|
||||
property PreviewFileControl: TPreviewFileControl read FPreviewFileControl;
|
||||
end;
|
||||
|
||||
|
||||
{ TOpenPictureDialog }
|
||||
|
||||
TOpenPictureDialog = class(TPreviewFileDialog)
|
||||
@ -89,7 +87,6 @@ type
|
||||
property Filter stored IsFilterStored;
|
||||
end;
|
||||
|
||||
|
||||
{ TSavePictureDialog }
|
||||
|
||||
TSavePictureDialog = class(TOpenPictureDialog)
|
||||
@ -100,7 +97,6 @@ type
|
||||
constructor Create(TheOwner: TComponent); override;
|
||||
end;
|
||||
|
||||
|
||||
{ TExtCommonDialog }
|
||||
|
||||
// A common base class for custom drawn dialogs (Calculator and Calendar).
|
||||
@ -127,20 +123,7 @@ type
|
||||
property DialogPosition: TPosition read FDialogPosition write FDialogPosition default poMainFormCenter;
|
||||
end;
|
||||
|
||||
|
||||
{ ---------------------------------------------------------------------
|
||||
Calculator Dialog
|
||||
---------------------------------------------------------------------}
|
||||
|
||||
const
|
||||
DefCalcPrecision = 15;
|
||||
|
||||
type
|
||||
TCalcState = (csFirst, csValid, csError);
|
||||
TCalculatorLayout = (clNormal, clSimple);
|
||||
TCalculatorForm = class;
|
||||
|
||||
{ TCalculatorDialog }
|
||||
{ TCalculatorDialog }
|
||||
|
||||
TCalculatorDialog = class(TExtCommonDialog)
|
||||
private
|
||||
@ -178,7 +161,7 @@ type
|
||||
published
|
||||
property BeepOnError: Boolean read FBeepOnError write FBeepOnError default True;
|
||||
property CalculatorLayout: TCalculatorLayout read FLayout write FLayout default clNormal;
|
||||
property Precision: Byte read FPrecision write FPrecision default DefCalcPrecision;
|
||||
property Precision: Byte read FPrecision write FPrecision default CalcDefPrecision;
|
||||
property Title;
|
||||
property Value: Double read FValue write FValue;
|
||||
property OnCalcKey: TKeyPressEvent read FOnCalcKey write FOnCalcKey;
|
||||
@ -195,43 +178,6 @@ type
|
||||
property ColorDisplayBack: TColor read FColorDisplayBack write FColorDisplayBack;
|
||||
end;
|
||||
|
||||
{ TCalculatorForm }
|
||||
|
||||
TCalculatorForm = class(TForm)
|
||||
private
|
||||
FMainPanel: TPanel;
|
||||
FCalcPanel: TPanel;
|
||||
FDisplayPanel: TPanel;
|
||||
FDisplayLabel: TLabel;
|
||||
procedure FormKeyPress(Sender: TObject; var Key: char);
|
||||
procedure CopyItemClick(Sender: TObject);
|
||||
function GetValue: Double;
|
||||
procedure PasteItemClick(Sender: TObject);
|
||||
procedure SetValue(const AValue: Double);
|
||||
protected
|
||||
class procedure WSRegisterClass; override;
|
||||
procedure OkClick(Sender: TObject);
|
||||
procedure CancelClick(Sender: TObject);
|
||||
procedure CalcKey(Sender: TObject; var Key: char);
|
||||
procedure DisplayChange(Sender: TObject);
|
||||
procedure InitForm(ALayout : TCalculatorLayout); virtual;
|
||||
property MainPanel: TPanel read FMainPanel;
|
||||
property CalcPanel: TPanel read FCalcPanel;
|
||||
property DisplayPanel: TPanel read FDisplayPanel;
|
||||
property DisplayLabel: TLabel read FDisplayLabel;
|
||||
public
|
||||
constructor Create(AOwner: TComponent; ALayout: TCalculatorLayout); reintroduce;
|
||||
property Value: Double read GetValue write SetValue;
|
||||
end;
|
||||
|
||||
function CreateCalculatorForm(AOwner: TComponent; ALayout : TCalculatorLayout; AHelpContext: THelpContext): TCalculatorForm;
|
||||
|
||||
{ ---------------------------------------------------------------------
|
||||
Date Dialog
|
||||
---------------------------------------------------------------------}
|
||||
|
||||
|
||||
Type
|
||||
{ TCalendarDialog }
|
||||
|
||||
TCalendarDialog = class(TExtCommonDialog)
|
||||
@ -288,16 +234,6 @@ begin
|
||||
TCalendarDialog,TCalculatorDialog]);
|
||||
end;
|
||||
|
||||
var
|
||||
cColorBtnDigits: TColor = clblack;
|
||||
cColorBtnMemory: TColor = clnavy;
|
||||
cColorBtnClear: TColor = clred;
|
||||
cColorBtnOk: TColor = clgreen;
|
||||
cColorBtnCancel: TColor = clmaroon;
|
||||
cColorBtnOthers: TColor = clblack;
|
||||
cColorDisplayText: TColor = clblack;
|
||||
cColorDisplayBack: TColor = clwhite;
|
||||
|
||||
{ TPreviewFileControl }
|
||||
|
||||
class procedure TPreviewFileControl.WSRegisterClass;
|
||||
@ -501,58 +437,6 @@ begin
|
||||
fCompStyle:=csSaveFileDialog;
|
||||
end;
|
||||
|
||||
type
|
||||
TCalcBtnKind =
|
||||
(cbNone, cbNum0, cbNum1, cbNum2, cbNum3, cbNum4, cbNum5, cbNum6,
|
||||
cbNum7, cbNum8, cbNum9, cbSgn, cbDcm, cbDiv, cbMul, cbSub,
|
||||
cbAdd, cbSqrt, cbSquare, cbPcnt, cbRev, cbEql, cbBck, cbClr, cbMP,
|
||||
cbMS, cbMR, cbMC, cbOk, cbCancel);
|
||||
|
||||
const
|
||||
CalcFormWidth: array[TCalculatorLayout] of integer = (278, 170);
|
||||
CalcFormHeight: array[TCalculatorLayout] of integer = (160, 150);
|
||||
CalcBtnEqualWidthNormal = 74;
|
||||
CalcBtnClearWidthNormal = 50;
|
||||
CalcBtnEqualWidthSimple = 54;
|
||||
CalcResultKeys = [#13, '=', '%'];
|
||||
|
||||
const
|
||||
CalcBtnSizes: array[TCalculatorLayout,1..2] of Integer =
|
||||
((36,22), (25,21));
|
||||
CalcBtnCaptions: array[cbSgn..cbCancel] of String =
|
||||
('±', ',', '/', '*', '-', '+', '√', 'x²', '%', '1/x', '=', '«', 'C',
|
||||
'MP','MS','MR','MC', 'ok', 'x');
|
||||
CalcBtnPos: array[TCalculatorLayout, TCalcBtnKind] of TPoint =
|
||||
((
|
||||
//normal layout
|
||||
(X: -1; Y: -1), (X: 47; Y: 104), (X: 47; Y: 80), (X: 85; Y: 80),
|
||||
(X: 123; Y: 80), (X: 47; Y: 56), (X: 85; Y: 56), (X: 123; Y: 56),
|
||||
(X: 47; Y: 32), (X: 85; Y: 32), (X: 123; Y: 32), (X: 85; Y: 104),
|
||||
(X: 123; Y: 104), (X: 161; Y: 32), (X: 161; Y: 56), (X: 161; Y: 80),
|
||||
(X: 161; Y: 104),
|
||||
(X: 199; Y: 32), //sqrt
|
||||
(X: 199+38; Y: 32), //sqr
|
||||
(X: 199; Y: 56), //%
|
||||
(X: 199; Y: 80), //1/x
|
||||
(X: 199; Y: 104), //=
|
||||
(X: 170; Y: 6), //back
|
||||
(X: 223; Y: 6), //clear
|
||||
(X: 5; Y: 104), (X: 5; Y: 80), (X: 5; Y: 56), (X: 5; Y: 32), //mem
|
||||
(X: 47; Y: 6), //ok
|
||||
(X: 100; Y: 6) //cancel
|
||||
),
|
||||
(
|
||||
//simple layout
|
||||
(X: -1; Y: -1), (X: 6; Y: 75), (X: 6; Y: 52), (X: 34; Y: 52),
|
||||
(X: 62; Y: 52), (X: 6; Y: 29), (X: 34; Y: 29), (X: 62; Y: 29),
|
||||
(X: 6; Y: 6), (X: 34; Y: 6), (X: 62; Y: 6), (X: 62; Y: 75),
|
||||
(X: 34; Y: 75), (X: 90; Y: 6), (X: 90; Y: 29), (X: 90; Y: 52),
|
||||
(X: 90; Y: 75), (X: -1; Y: -1), (X: -1; Y: -1), (X: -1; Y: -1), (X: -1; Y: -1),
|
||||
(X: 62; Y: 98), (X: 34; Y: 98), (X: 6; Y: 98), (X: -1; Y: -1),
|
||||
(X: -1; Y: -1), (X: -1; Y: -1), (X: -1; Y: -1),
|
||||
(X: 140; Y: 6), (X: 140; Y: 29)
|
||||
));
|
||||
|
||||
{ ---------------------------------------------------------------------
|
||||
Auxiliary
|
||||
---------------------------------------------------------------------}
|
||||
@ -569,24 +453,6 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
function CreateCalculatorForm(AOwner: TComponent; ALayout: TCalculatorLayout; AHelpContext: THelpContext): TCalculatorForm;
|
||||
begin
|
||||
Result:=TCalculatorForm.Create(AOwner, ALayout);
|
||||
with Result do
|
||||
try
|
||||
HelpContext:=AHelpContext;
|
||||
if Screen.PixelsPerInch <> 96 then
|
||||
begin { scale to screen res }
|
||||
SetDefaultFont(Font, ALayout);
|
||||
Left:=(Screen.Width - Width) div 2;
|
||||
Top:=(Screen.Height - Height) div 2;
|
||||
end;
|
||||
except
|
||||
Free;
|
||||
raise;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
{ TExtCommonDialog }
|
||||
|
||||
@ -642,504 +508,12 @@ begin
|
||||
end;
|
||||
|
||||
|
||||
{ ---------------------------------------------------------------------
|
||||
Calculator Dialog
|
||||
---------------------------------------------------------------------}
|
||||
|
||||
{ TCalcButton }
|
||||
|
||||
type
|
||||
TCalcButton = class(TCustomSpeedButton)
|
||||
private
|
||||
FKind: TCalcBtnKind;
|
||||
public
|
||||
constructor CreateKind(AOwner: TComponent; AKind: TCalcBtnKind);
|
||||
property Kind: TCalcBtnKind read FKind;
|
||||
property ParentFont;
|
||||
end;
|
||||
|
||||
constructor TCalcButton.CreateKind(AOwner: TComponent; AKind: TCalcBtnKind);
|
||||
begin
|
||||
inherited Create(AOwner);
|
||||
FKind:=AKind;
|
||||
if FKind in [cbNum0..cbClr] then
|
||||
Tag:=Ord(Kind) - 1
|
||||
else
|
||||
Tag:=-1;
|
||||
end;
|
||||
|
||||
function CreateCalcBtn(AParent: TWinControl; AKind: TCalcBtnKind;
|
||||
AOnClick: TNotifyEvent; ALayout: TCalculatorLayout): TCalcButton;
|
||||
begin
|
||||
Result:=TCalcButton.CreateKind(AParent, AKind);
|
||||
with Result do
|
||||
try
|
||||
if Kind in [cbNum0..cbNum9] then
|
||||
Caption:=IntToStr(Tag)
|
||||
else if Kind = cbDcm then
|
||||
Caption:=DefaultFormatSettings.DecimalSeparator
|
||||
else if Kind in [cbSgn..cbCancel] then
|
||||
Caption:=CalcBtnCaptions[Kind];
|
||||
|
||||
Left:=CalcBtnPos[ALayout, Kind].X;
|
||||
Top:=CalcBtnPos[ALayout, Kind].Y;
|
||||
Width:=CalcBtnSizes[ALayout,1];
|
||||
Height:=CalcBtnSizes[ALayout,2];
|
||||
OnClick:=AOnClick;
|
||||
ParentFont:=True;
|
||||
Parent:=AParent;
|
||||
|
||||
case Result.Kind of
|
||||
cbMC, cbMR, cbMS, cbMP: Result.Font.Color:= cColorBtnMemory;
|
||||
cbOk: Result.Font.Color:= cColorBtnOk;
|
||||
cbCancel: Result.Font.Color:= cColorBtnCancel;
|
||||
cbClr: Result.Font.Color:= cColorBtnClear;
|
||||
cbNum0..cbNum9: Result.Font.Color:= cColorBtnDigits;
|
||||
else Result.Font.Color:= cColorBtnOthers;
|
||||
end;
|
||||
except
|
||||
Free;
|
||||
raise;
|
||||
end;
|
||||
end;
|
||||
|
||||
{ TCalculatorPanel }
|
||||
|
||||
type
|
||||
TCalculatorPanel = class(TPanel)
|
||||
private
|
||||
FText: string;
|
||||
FStatus: TCalcState;
|
||||
FOperator: Char;
|
||||
FOperand: Double;
|
||||
FMemory: Double;
|
||||
FPrecision: Byte;
|
||||
FBeepOnError: Boolean;
|
||||
FMemoryPanel: TPanel;
|
||||
FMemoryLabel: TLabel;
|
||||
FOnError: TNotifyEvent;
|
||||
FOnOk: TNotifyEvent;
|
||||
FOnCancel: TNotifyEvent;
|
||||
FOnResult: TNotifyEvent;
|
||||
FOnTextChange: TNotifyEvent;
|
||||
FOnCalcKey: TKeyPressEvent;
|
||||
FOnDisplayChange: TNotifyEvent;
|
||||
FControl: TControl;
|
||||
procedure SetCalcText(const Value: string);
|
||||
procedure CheckFirst;
|
||||
procedure CalcKey(Key: char);
|
||||
procedure Clear;
|
||||
procedure Error;
|
||||
procedure SetDisplay(R: Double);
|
||||
function GetDisplay: Double;
|
||||
procedure UpdateMemoryLabel;
|
||||
function FindButton(Key: Char): TCustomSpeedButton;
|
||||
procedure BtnClick(Sender: TObject);
|
||||
protected
|
||||
procedure ErrorBeep;
|
||||
procedure TextChange; virtual;
|
||||
class procedure WSRegisterClass; override;
|
||||
public
|
||||
constructor CreateLayout(AOwner: TComponent; ALayout: TCalculatorLayout);
|
||||
procedure CalcKeyPress(Sender: TObject; var Key: char);
|
||||
procedure Copy;
|
||||
procedure Paste;
|
||||
function WorkingPrecision : Integer;
|
||||
property DisplayValue: Double read GetDisplay write SetDisplay;
|
||||
property Text: string read FText;
|
||||
property OnOkClick: TNotifyEvent read FOnOk write FOnOk;
|
||||
property OnCancelClick: TNotifyEvent read FOnCancel write FOnCancel;
|
||||
property OnResultClick: TNotifyEvent read FOnResult write FOnResult;
|
||||
property OnError: TNotifyEvent read FOnError write FOnError;
|
||||
property OnTextChange: TNotifyEvent read FOnTextChange write FOnTextChange;
|
||||
property OnCalcKey: TKeyPressEvent read FOnCalcKey write FOnCalcKey;
|
||||
property OnDisplayChange: TNotifyEvent read FOnDisplayChange write FOnDisplayChange;
|
||||
property Color default clBtnFace;
|
||||
end;
|
||||
|
||||
constructor TCalculatorPanel.CreateLayout(AOwner: TComponent; ALayout: TCalculatorLayout);
|
||||
const
|
||||
PanelSizes: array[TCalculatorLayout,1..2] of Integer =
|
||||
((129,140),(124,98));
|
||||
var
|
||||
I: TCalcBtnKind;
|
||||
Bitmap: TCustomBitmap;
|
||||
begin
|
||||
inherited Create(AOwner);
|
||||
ParentColor:=False;
|
||||
Color:=clBtnFace;
|
||||
Height:=PanelSizes[ALayout,1];
|
||||
Width:=PanelSizes[ALayout,2];
|
||||
SetDefaultFont(Font, ALayout);
|
||||
ParentFont:=False;
|
||||
BevelOuter:=bvNone;
|
||||
BevelInner:=bvNone;
|
||||
ParentColor:=True;
|
||||
for I:=cbNum0 to cbCancel do
|
||||
begin
|
||||
if CalcBtnPos[ALayout, I].X > 0 then
|
||||
with CreateCalcBtn(Self, I, @BtnClick, ALayout) do
|
||||
begin
|
||||
if ALayout = clNormal then
|
||||
begin
|
||||
if (Kind in [cbBck, cbClr, cbOk, cbCancel]) then
|
||||
Width:=CalcBtnClearWidthNormal;
|
||||
if (Kind in [cbPcnt, cbRev, cbEql]) then
|
||||
Width:=CalcBtnEqualWidthNormal;
|
||||
end
|
||||
else
|
||||
begin
|
||||
if Kind in [cbEql] then Width:=CalcBtnEqualWidthSimple;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
if ALayout = clNormal then
|
||||
begin
|
||||
{ Memory panel }
|
||||
FMemoryPanel:=TPanel.Create(Self);
|
||||
with FMemoryPanel do
|
||||
begin
|
||||
SetBounds(6, 7, 34, 20);
|
||||
BevelInner:=bvLowered;
|
||||
BevelOuter:=bvNone;
|
||||
ParentColor:=True;
|
||||
Parent:=Self;
|
||||
end;
|
||||
FMemoryLabel:=TLabel.Create(Self);
|
||||
with FMemoryLabel do
|
||||
begin
|
||||
SetBounds(3, 3, 26, 14);
|
||||
Alignment:=taCenter;
|
||||
AutoSize:=False;
|
||||
Parent:=FMemoryPanel;
|
||||
Font.Style:=[];
|
||||
end;
|
||||
end;
|
||||
FText:='0';
|
||||
FMemory:=0.0;
|
||||
FPrecision:=DefCalcPrecision;
|
||||
FBeepOnError:=True;
|
||||
end;
|
||||
|
||||
procedure TCalculatorPanel.SetCalcText(const Value: string);
|
||||
begin
|
||||
if FText <> Value then
|
||||
begin
|
||||
FText:=Value;
|
||||
TextChange;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TCalculatorPanel.TextChange;
|
||||
begin
|
||||
if Assigned(FControl) then
|
||||
TLabel(FControl).Caption:=FText;
|
||||
if Assigned(FOnTextChange) then
|
||||
FOnTextChange(Self);
|
||||
end;
|
||||
|
||||
class procedure TCalculatorPanel.WSRegisterClass;
|
||||
begin
|
||||
inherited WSRegisterClass;
|
||||
RegisterCalculatorPanel;
|
||||
end;
|
||||
|
||||
procedure TCalculatorPanel.ErrorBeep;
|
||||
|
||||
begin
|
||||
if FBeepOnError then
|
||||
// MessageBeep(0);
|
||||
end;
|
||||
|
||||
procedure TCalculatorPanel.Error;
|
||||
begin
|
||||
FStatus:=csError;
|
||||
SetCalcText(rsError);
|
||||
ErrorBeep;
|
||||
if Assigned(FOnError) then
|
||||
FOnError(Self);
|
||||
end;
|
||||
|
||||
procedure TCalculatorPanel.SetDisplay(R: Double);
|
||||
var
|
||||
S: string;
|
||||
begin
|
||||
S:=FloatToStrF(R, ffGeneral, WorkingPrecision, 0);
|
||||
if FText <> S then
|
||||
begin
|
||||
SetCalcText(S);
|
||||
if Assigned(FOnDisplayChange) then
|
||||
FOnDisplayChange(Self);
|
||||
end;
|
||||
end;
|
||||
|
||||
function TCalculatorPanel.GetDisplay: Double;
|
||||
begin
|
||||
if (FStatus=csError) then
|
||||
Result:=0.0
|
||||
else
|
||||
Result:=StrToDouble(Trim(FText));
|
||||
end;
|
||||
|
||||
procedure TCalculatorPanel.CheckFirst;
|
||||
begin
|
||||
if (FStatus=csFirst) then
|
||||
begin
|
||||
FStatus:=csValid;
|
||||
SetCalcText('0');
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TCalculatorPanel.UpdateMemoryLabel;
|
||||
begin
|
||||
if (FMemoryLabel<>nil) then
|
||||
if (FMemory<>0.0) then
|
||||
FMemoryLabel.Caption:='M'
|
||||
else
|
||||
FMemoryLabel.Caption:='';
|
||||
end;
|
||||
|
||||
function TCalculatorPanel.WorkingPrecision : Integer;
|
||||
|
||||
begin
|
||||
Result:=2;
|
||||
If FPrecision>2 then
|
||||
Result:=FPrecision;
|
||||
end;
|
||||
|
||||
|
||||
procedure TCalculatorPanel.CalcKey(Key: char);
|
||||
var
|
||||
R: Double;
|
||||
begin
|
||||
{$IFDEF GTK1}
|
||||
Key:=UpCase(Key);
|
||||
{$ENDIF GTK1}
|
||||
if (FStatus = csError) and (Key <> 'C') then
|
||||
Key:=#0;
|
||||
if Assigned(FOnCalcKey) then
|
||||
FOnCalcKey(Self, Key);
|
||||
if Key in [DefaultFormatSettings.DecimalSeparator, '.', ','] then
|
||||
begin
|
||||
CheckFirst;
|
||||
if Pos(DefaultFormatSettings.DecimalSeparator, FText) = 0 then
|
||||
SetCalcText(FText + DefaultFormatSettings.DecimalSeparator);
|
||||
end
|
||||
else
|
||||
case Key of
|
||||
'R':
|
||||
if (FStatus in [csValid, csFirst]) then
|
||||
begin
|
||||
FStatus:=csFirst;
|
||||
if GetDisplay = 0 then
|
||||
Error
|
||||
else
|
||||
SetDisplay(1.0 / GetDisplay);
|
||||
end;
|
||||
'Q':
|
||||
if FStatus in [csValid, csFirst] then
|
||||
begin
|
||||
FStatus:=csFirst;
|
||||
if GetDisplay < 0 then
|
||||
Error
|
||||
else
|
||||
SetDisplay(Sqrt(GetDisplay));
|
||||
end;
|
||||
'S':
|
||||
if FStatus in [csValid, csFirst] then
|
||||
begin
|
||||
FStatus:=csFirst;
|
||||
SetDisplay(Sqr(GetDisplay));
|
||||
end;
|
||||
'0'..'9':
|
||||
begin
|
||||
CheckFirst;
|
||||
if (FText='0') then
|
||||
SetCalcText('');
|
||||
if (Pos('E', FText)=0) then
|
||||
begin
|
||||
if (Length(FText) < WorkingPrecision + Ord(Boolean(Pos('-', FText)))) then
|
||||
SetCalcText(FText + Key)
|
||||
else
|
||||
ErrorBeep;
|
||||
end;
|
||||
end;
|
||||
#8:
|
||||
begin
|
||||
CheckFirst;
|
||||
if ((Length(FText)=1) or ((Length(FText)=2) and (FText[1]='-'))) then
|
||||
SetCalcText('0')
|
||||
else
|
||||
SetCalcText(System.Copy(FText,1,Length(FText)-1));
|
||||
end;
|
||||
'_':
|
||||
SetDisplay(-GetDisplay);
|
||||
'+', '-', '*', '/', '=', '%', #13:
|
||||
begin
|
||||
if (FStatus=csValid) then
|
||||
begin
|
||||
FStatus:=csFirst;
|
||||
R:=GetDisplay;
|
||||
if (Key='%') then
|
||||
case FOperator of
|
||||
'+', '-': R:=(FOperand*R)/100.0;
|
||||
'*', '/': R:=R/100.0;
|
||||
end;
|
||||
case FOperator of
|
||||
'+': SetDisplay(FOperand+R);
|
||||
'-': SetDisplay(FOperand-R);
|
||||
'*': SetDisplay(FOperand*R);
|
||||
'/': if R = 0 then
|
||||
Error
|
||||
else
|
||||
SetDisplay(FOperand / R);
|
||||
end;
|
||||
end;
|
||||
FOperator:=Key;
|
||||
FOperand:=GetDisplay;
|
||||
if (Key in CalcResultKeys) and Assigned(FOnResult) then
|
||||
FOnResult(Self);
|
||||
end;
|
||||
#27, 'C':
|
||||
Clear;
|
||||
^C:
|
||||
Copy;
|
||||
^V:
|
||||
Paste;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TCalculatorPanel.Clear;
|
||||
begin
|
||||
FStatus:=csFirst;
|
||||
SetDisplay(0.0);
|
||||
FOperator:='=';
|
||||
end;
|
||||
|
||||
procedure TCalculatorPanel.CalcKeyPress(Sender: TObject; var Key: char);
|
||||
|
||||
var
|
||||
Btn: TCustomSpeedButton;
|
||||
|
||||
begin
|
||||
Btn:=FindButton(Key);
|
||||
if Assigned(Btn) then
|
||||
Btn.Click
|
||||
else
|
||||
CalcKey(Key);
|
||||
end;
|
||||
|
||||
function TCalculatorPanel.FindButton(Key: Char): TCustomSpeedButton;
|
||||
const
|
||||
ButtonChars = '0123456789_./*-+Q%R='#8'C';
|
||||
var
|
||||
I: Integer;
|
||||
BtnTag: Longint;
|
||||
begin
|
||||
if Key in [DefaultFormatSettings.DecimalSeparator, '.', ','] then
|
||||
Key:='.'
|
||||
else if Key = #13 then
|
||||
Key:='='
|
||||
else if Key = #27 then
|
||||
Key:='C';
|
||||
Result:=nil;
|
||||
BtnTag:=Pos(UpCase(Key), ButtonChars) - 1;
|
||||
if (BtnTag>=0) then
|
||||
begin
|
||||
I:=0;
|
||||
While (Result=Nil) and (I<ControlCount) do
|
||||
begin
|
||||
if Controls[I] is TCustomSpeedButton then
|
||||
If BtnTag=TCustomSpeedButton(Controls[I]).Tag then
|
||||
Result:=TCustomSpeedButton(Controls[I]);
|
||||
Inc(I);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TCalculatorPanel.BtnClick(Sender: TObject);
|
||||
begin
|
||||
case TCalcButton(Sender).Kind of
|
||||
cbNum0..cbNum9: CalcKey(Char(TComponent(Sender).Tag + Ord('0')));
|
||||
cbSgn: CalcKey('_');
|
||||
cbDcm: CalcKey(DefaultFormatSettings.DecimalSeparator);
|
||||
cbDiv: CalcKey('/');
|
||||
cbMul: CalcKey('*');
|
||||
cbSub: CalcKey('-');
|
||||
cbAdd: CalcKey('+');
|
||||
cbSqrt: CalcKey('Q');
|
||||
cbSquare: CalcKey('S');
|
||||
cbPcnt: CalcKey('%');
|
||||
cbRev: CalcKey('R');
|
||||
cbEql: CalcKey('=');
|
||||
cbBck: CalcKey(#8);
|
||||
cbClr: CalcKey('C');
|
||||
cbMP:
|
||||
if (FStatus in [csValid, csFirst]) then
|
||||
begin
|
||||
FStatus:=csFirst;
|
||||
FMemory:=FMemory + GetDisplay;
|
||||
UpdateMemoryLabel;
|
||||
end;
|
||||
cbMS:
|
||||
if FStatus in [csValid, csFirst] then
|
||||
begin
|
||||
FStatus:=csFirst;
|
||||
FMemory:=GetDisplay;
|
||||
UpdateMemoryLabel;
|
||||
end;
|
||||
cbMR:
|
||||
if (FStatus in [csValid, csFirst]) then
|
||||
begin
|
||||
FStatus:=csFirst;
|
||||
CheckFirst;
|
||||
SetDisplay(FMemory);
|
||||
end;
|
||||
cbMC:
|
||||
begin
|
||||
FMemory:=0.0;
|
||||
UpdateMemoryLabel;
|
||||
end;
|
||||
cbOk:
|
||||
begin
|
||||
if FStatus <> csError then
|
||||
begin
|
||||
DisplayValue:=DisplayValue; { to raise exception on error }
|
||||
if Assigned(FOnOk) then
|
||||
FOnOk(Self);
|
||||
end
|
||||
else
|
||||
ErrorBeep;
|
||||
end;
|
||||
cbCancel:
|
||||
if Assigned(FOnCancel) then
|
||||
FOnCancel(Self);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TCalculatorPanel.Copy;
|
||||
begin
|
||||
// Clipboard.AsText:=FText;
|
||||
end;
|
||||
|
||||
procedure TCalculatorPanel.Paste;
|
||||
begin
|
||||
{ if Clipboard.HasFormat(CF_TEXT) then
|
||||
try
|
||||
SetDisplay(StrToFloat(Trim(ReplaceStr(Clipboard.AsText,
|
||||
CurrencyString, ''))));
|
||||
except
|
||||
SetCalcText('0');
|
||||
end;
|
||||
}
|
||||
end;
|
||||
|
||||
{ TCalculatorDialog }
|
||||
|
||||
constructor TCalculatorDialog.Create(AOwner: TComponent);
|
||||
begin
|
||||
inherited Create(AOwner);
|
||||
FPrecision:=DefCalcPrecision;
|
||||
FPrecision:=CalcDefPrecision;
|
||||
FBeepOnError:=True;
|
||||
FDialogScale:=100;
|
||||
FLayout:=clNormal;
|
||||
@ -1170,7 +544,7 @@ end;
|
||||
function TCalculatorDialog.GetDisplay: Double;
|
||||
begin
|
||||
if Assigned(DlgForm) then
|
||||
Result:=TCalculatorPanel(TCalculatorForm(DlgForm).FCalcPanel).GetDisplay
|
||||
Result:=TCalculatorForm(DlgForm).CalcPanel.DisplayValue
|
||||
else Result:=FValue;
|
||||
end;
|
||||
|
||||
@ -1219,6 +593,9 @@ begin
|
||||
|
||||
DlgForm:=CreateCalculatorForm(Application, FLayout, HelpContext);
|
||||
try
|
||||
(DlgForm as TCalculatorForm).OnCalcKey:= @Self.CalcKey;
|
||||
(DlgForm as TCalculatorForm).OnDisplayChange:= @Self.DisplayChange;
|
||||
|
||||
if FDialogScale<>100 then
|
||||
DlgForm.ScaleBy(FDialogScale,100);
|
||||
if (csDesigning in ComponentState) then
|
||||
@ -1232,20 +609,20 @@ begin
|
||||
FLeft:=DlgForm.Left;
|
||||
FTop:=DlgForm.Top;
|
||||
end;
|
||||
CPanel:=TCalculatorPanel(TCalculatorForm(DlgForm).FCalcPanel);
|
||||
CPanel:=TCalculatorForm(DlgForm).CalcPanel;
|
||||
|
||||
DlgForm.Caption:=Title;
|
||||
CPanel.FMemory:=FMemory;
|
||||
CPanel.Memory:=FMemory;
|
||||
CPanel.UpdateMemoryLabel;
|
||||
If Precision>2 then
|
||||
CPanel.FPrecision:=Precision
|
||||
CPanel.Precision:=Precision
|
||||
else
|
||||
CPanel.FPrecision:=2;
|
||||
CPanel.FBeepOnError:=BeepOnError;
|
||||
CPanel.Precision:=2;
|
||||
CPanel.BeepOnError:=BeepOnError;
|
||||
if FValue <> 0 then begin
|
||||
CPanel.DisplayValue:=FValue;
|
||||
CPanel.FStatus:=csFirst;
|
||||
CPanel.FOperator:='=';
|
||||
CPanel.Status:=csFirst;
|
||||
CPanel.OperatorChar:='=';
|
||||
end;
|
||||
Result := (DlgForm.ShowModal = mrOk);
|
||||
FLeft := DlgForm.Left;
|
||||
@ -1254,7 +631,7 @@ begin
|
||||
SetHeight(DlgForm.Height);
|
||||
SetWidth(DlgForm.Width);
|
||||
if Result then begin
|
||||
FMemory:=CPanel.FMemory;
|
||||
FMemory:=CPanel.Memory;
|
||||
if CPanel.DisplayValue <> FValue then begin
|
||||
FValue:=CPanel.DisplayValue;
|
||||
Change;
|
||||
@ -1266,128 +643,6 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
{ TCalculatorForm }
|
||||
|
||||
constructor TCalculatorForm.Create(AOwner: TComponent; ALayout: TCalculatorLayout);
|
||||
begin
|
||||
BeginFormUpdate;
|
||||
inherited CreateNew(AOwner, 0);
|
||||
InitForm(ALayout);
|
||||
EndFormUpdate;
|
||||
end;
|
||||
|
||||
procedure TCalculatorForm.InitForm(ALayout: TCalculatorLayout);
|
||||
begin
|
||||
BorderStyle:=bsDialog;
|
||||
Caption:=rsCalculator;
|
||||
ClientHeight:=CalcFormHeight[ALayout];
|
||||
ClientWidth:=CalcFormWidth[ALayout];
|
||||
SetDefaultFont(Font, ALayout);
|
||||
KeyPreview:=True;
|
||||
PixelsPerInch:=96;
|
||||
Position:=poScreenCenter;
|
||||
OnKeyPress:=@FormKeyPress;
|
||||
{ MainPanel }
|
||||
FMainPanel:=TPanel.Create(Self);
|
||||
with FMainPanel do
|
||||
begin
|
||||
Align:=alClient;
|
||||
Parent:=Self;
|
||||
BevelOuter:=bvLowered;
|
||||
ParentColor:=True;
|
||||
end;
|
||||
{ DisplayPanel }
|
||||
FDisplayPanel:=TPanel.Create(Self);
|
||||
with FDisplayPanel do
|
||||
begin
|
||||
Height:=23;
|
||||
Align:=alTop;
|
||||
BorderSpacing.Around:=7;
|
||||
Parent:=FMainPanel;
|
||||
BevelOuter:=bvLowered;
|
||||
Color:=cColorDisplayBack;
|
||||
Font:=Self.Font;
|
||||
end;
|
||||
FDisplayLabel:=TLabel.Create(Self);
|
||||
with FDisplayLabel do
|
||||
begin
|
||||
AutoSize:=False;
|
||||
Alignment:=taRightJustify;
|
||||
Align:=alClient;
|
||||
BorderSpacing.Around:=2;
|
||||
Parent:=FDisplayPanel;
|
||||
Caption:='0';
|
||||
Font.Color:=cColorDisplayText;
|
||||
end;
|
||||
{ CalcPanel }
|
||||
FCalcPanel:=TCalculatorPanel.CreateLayout(Self, ALayout);
|
||||
with TCalculatorPanel(FCalcPanel) do
|
||||
begin
|
||||
Align:=alBottom;
|
||||
Top:=17;
|
||||
Anchors:=[akLeft,akRight,AkBottom];
|
||||
Parent:=FMainPanel;
|
||||
OnOkClick:=@Self.OkClick;
|
||||
OnCancelClick:=@Self.CancelClick;
|
||||
OnCalcKey:=@Self.CalcKey;
|
||||
OnDisplayChange:=@Self.DisplayChange;
|
||||
FControl:=FDisplayLabel;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
procedure TCalculatorForm.FormKeyPress(Sender: TObject; var Key: char);
|
||||
begin
|
||||
TCalculatorPanel(FCalcPanel).CalcKeyPress(Sender, Key);
|
||||
end;
|
||||
|
||||
procedure TCalculatorForm.CopyItemClick(Sender: TObject);
|
||||
begin
|
||||
TCalculatorPanel(FCalcPanel).Copy;
|
||||
end;
|
||||
|
||||
function TCalculatorForm.GetValue: Double;
|
||||
begin
|
||||
Result:=TCalculatorPanel(FCalcPanel).DisplayValue
|
||||
end;
|
||||
|
||||
procedure TCalculatorForm.PasteItemClick(Sender: TObject);
|
||||
begin
|
||||
TCalculatorPanel(FCalcPanel).Paste;
|
||||
end;
|
||||
|
||||
procedure TCalculatorForm.SetValue(const AValue: Double);
|
||||
begin
|
||||
TCalculatorPanel(FCalcPanel).DisplayValue:=AValue;
|
||||
end;
|
||||
|
||||
class procedure TCalculatorForm.WSRegisterClass;
|
||||
begin
|
||||
inherited WSRegisterClass;
|
||||
RegisterCalculatorForm;
|
||||
end;
|
||||
|
||||
procedure TCalculatorForm.OkClick(Sender: TObject);
|
||||
begin
|
||||
ModalResult:=mrOk;
|
||||
end;
|
||||
|
||||
procedure TCalculatorForm.CancelClick(Sender: TObject);
|
||||
begin
|
||||
ModalResult:=mrCancel;
|
||||
end;
|
||||
|
||||
procedure TCalculatorForm.CalcKey(Sender: TObject; var Key: char);
|
||||
begin
|
||||
if (Owner <> nil) and (Owner is TCalculatorDialog) then
|
||||
TCalculatorDialog(Owner).CalcKey(Key);
|
||||
end;
|
||||
|
||||
procedure TCalculatorForm.DisplayChange(Sender: TObject);
|
||||
begin
|
||||
if (Owner <> nil) and (Owner is TCalculatorDialog) then
|
||||
TCalculatorDialog(Owner).DisplayChange;
|
||||
end;
|
||||
|
||||
{ ---------------------------------------------------------------------
|
||||
TCalendarDialog
|
||||
|
Loading…
Reference in New Issue
Block a user