
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@963 8e941d3f-bd1b-0410-a28a-d453659cc2b4
604 lines
15 KiB
ObjectPascal
604 lines
15 KiB
ObjectPascal
{*********************************************************}
|
|
{* OVCEDCLC.PAS 4.06 *}
|
|
{*********************************************************}
|
|
|
|
{* ***** BEGIN LICENSE BLOCK ***** *}
|
|
{* Version: MPL 1.1 *}
|
|
{* *}
|
|
{* The contents of this file are subject to the Mozilla Public License *}
|
|
{* Version 1.1 (the "License"); you may not use this file except in *}
|
|
{* compliance with the License. You may obtain a copy of the License at *}
|
|
{* http://www.mozilla.org/MPL/ *}
|
|
{* *}
|
|
{* 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 TurboPower Orpheus *}
|
|
{* *}
|
|
{* The Initial Developer of the Original Code is TurboPower Software *}
|
|
{* *}
|
|
{* Portions created by TurboPower Software Inc. are Copyright (C)1995-2002 *}
|
|
{* TurboPower Software Inc. All Rights Reserved. *}
|
|
{* *}
|
|
{* Contributor(s): *}
|
|
{* *}
|
|
{* ***** END LICENSE BLOCK ***** *}
|
|
|
|
{$I OVC.INC}
|
|
|
|
{$B-} {Complete Boolean Evaluation}
|
|
{$I+} {Input/Output-Checking}
|
|
{$P+} {Open Parameters}
|
|
{$T-} {Typed @ Operator}
|
|
{.W-} {Windows Stack Frame}
|
|
{$X+} {Extended Syntax}
|
|
|
|
unit ovcedclc;
|
|
{-numeric edit field with popup calculator}
|
|
|
|
interface
|
|
|
|
uses
|
|
{$IFNDEF LCL} Windows, Messages, {$ELSE} LclIntf, LMessages, LclType, MyMisc, {$ENDIF}
|
|
Buttons, Classes, Controls, Forms, Graphics, Menus,
|
|
StdCtrls, SysUtils, {$IFDEF VERSION4}{$IFNDEF LCL} MultiMon, {$ENDIF}{$ENDIF}
|
|
OvcBase, OvcCalc, OvcEdPop, OvcMisc;
|
|
|
|
type
|
|
TOvcCustomNumberEdit = class(TOvcEdPopup)
|
|
{.Z+}
|
|
protected {private}
|
|
FAllowIncDec : Boolean;
|
|
FCalculator : TOvcCalculator;
|
|
|
|
{internal variables}
|
|
PopupClosing : Boolean;
|
|
HoldCursor : TCursor;
|
|
WasAutoScroll : Boolean;
|
|
|
|
{property methods}
|
|
function GetAsFloat : Double;
|
|
function GetAsInteger : LongInt;
|
|
function GetAsString : string;
|
|
function GetPopupColors : TOvcCalcColors;
|
|
function GetPopupDecimals : Integer;
|
|
function GetPopupFont : TFont;
|
|
function GetPopupHeight : Integer;
|
|
function GetPopupWidth : Integer;
|
|
function GetReadOnly : Boolean;
|
|
procedure SetAsFloat(Value : Double);
|
|
procedure SetAsInteger(Value : LongInt);
|
|
procedure SetAsString(const Value : string);
|
|
procedure SetPopupColors(Value : TOvcCalcColors);
|
|
procedure SetPopupDecimals(Value : Integer);
|
|
procedure SetPopupFont(Value : TFont);
|
|
procedure SetPopupHeight(Value : Integer);
|
|
procedure SetPopupWidth(Value : Integer);
|
|
procedure SetReadOnly(Value : Boolean);
|
|
|
|
{internal methods}
|
|
procedure PopupButtonPressed(Sender : TObject; Button : TOvcCalculatorButton);
|
|
procedure PopupKeyDown(Sender : TObject; var Key : Word; Shift : TShiftState);
|
|
procedure PopupKeyPress(Sender : TObject; var Key : Char);
|
|
procedure PopupMouseDown(Sender : TObject; Button : TMouseButton; Shift : TShiftState; X, Y : Integer);
|
|
|
|
protected
|
|
procedure DoExit;
|
|
override;
|
|
procedure GlyphChanged;
|
|
override;
|
|
procedure KeyDown(var Key : Word; Shift : TShiftState);
|
|
override;
|
|
procedure KeyPress(var Key : Char);
|
|
override;
|
|
{.Z-}
|
|
|
|
property AllowIncDec : Boolean
|
|
read FAllowIncDec write FAllowIncDec;
|
|
property PopupColors : TOvcCalcColors
|
|
read GetPopupColors write SetPopupColors;
|
|
property PopupDecimals : Integer
|
|
read GetPopupDecimals write SetPopupDecimals;
|
|
property PopupFont : TFont
|
|
read GetPopupFont write SetPopupFont;
|
|
property PopupHeight : Integer
|
|
read GetPopupHeight write SetPopupHeight;
|
|
property PopupWidth : Integer
|
|
read GetPopupWidth write SetPopupWidth;
|
|
property ReadOnly : Boolean
|
|
read GetReadOnly write SetReadOnly;
|
|
|
|
public
|
|
{.Z+}
|
|
constructor Create(AOwner : TComponent);
|
|
override;
|
|
{.Z-}
|
|
|
|
procedure PopupClose(Sender : TObject);
|
|
override;
|
|
procedure PopupOpen;
|
|
override;
|
|
|
|
property AsInteger : LongInt
|
|
read GetAsInteger
|
|
write SetAsInteger;
|
|
|
|
{public properties}
|
|
property Calculator : TOvcCalculator
|
|
read FCalculator;
|
|
property AsFloat : Double
|
|
read GetAsFloat write SetAsFloat;
|
|
property AsString : string
|
|
read GetAsString write SetAsString;
|
|
end;
|
|
|
|
TOvcNumberEdit = class(TOvcCustomNumberEdit)
|
|
published
|
|
{properties}
|
|
{$IFDEF VERSION4}
|
|
property Anchors;
|
|
property Constraints;
|
|
property DragKind;
|
|
{$ENDIF}
|
|
property About;
|
|
property AllowIncDec;
|
|
{$IFNDEF LCL}
|
|
property AutoSelect;
|
|
{$ENDIF}
|
|
property AutoSize;
|
|
property BorderStyle;
|
|
property ButtonGlyph;
|
|
property Color;
|
|
property Ctl3D;
|
|
property Cursor;
|
|
property DragCursor;
|
|
property DragMode;
|
|
property Enabled;
|
|
property Font;
|
|
{$IFNDEF LCL}
|
|
property HideSelection;
|
|
{$ENDIF}
|
|
property LabelInfo;
|
|
property ParentColor;
|
|
{$IFNDEF LCL}
|
|
property ParentCtl3D;
|
|
{$ENDIF}
|
|
property ParentFont;
|
|
property ParentShowHint;
|
|
property PopupAnchor;
|
|
property PopupColors;
|
|
property PopupDecimals;
|
|
property PopupFont;
|
|
property PopupHeight;
|
|
property PopupWidth;
|
|
property PopupMenu;
|
|
property ReadOnly;
|
|
property ShowHint;
|
|
property ShowButton;
|
|
property TabOrder;
|
|
property TabStop;
|
|
property Visible;
|
|
|
|
{events}
|
|
property OnChange;
|
|
property OnClick;
|
|
property OnDblClick;
|
|
property OnDragDrop;
|
|
property OnDragOver;
|
|
property OnEndDrag;
|
|
property OnEnter;
|
|
property OnExit;
|
|
property OnKeyDown;
|
|
property OnKeyPress;
|
|
property OnKeyUp;
|
|
property OnMouseDown;
|
|
property OnMouseMove;
|
|
property OnMouseUp;
|
|
property OnPopupClose;
|
|
property OnPopupOpen;
|
|
property OnStartDrag;
|
|
end;
|
|
|
|
|
|
implementation
|
|
|
|
|
|
{*** TOvcCustomNumberEdit ***}
|
|
|
|
constructor TOvcCustomNumberEdit.Create(AOwner : TComponent);
|
|
begin
|
|
inherited Create(AOwner);
|
|
|
|
ControlStyle := ControlStyle - [csSetCaption];
|
|
|
|
FAllowIncDec := False;
|
|
|
|
{load button glyph}
|
|
{$IFNDEF LCL}
|
|
FButtonGlyph.Handle := LoadBaseBitmap('ORBTNCLC');
|
|
{$ELSE}
|
|
FButtonGlyph.LoadFromLazarusResource('ORBTNCLC');
|
|
{$ENDIF}
|
|
FButton.Glyph.Assign(FButtonGlyph);
|
|
|
|
FCalculator := TOvcCalculator.CreateEx(Self, True);
|
|
FCalculator.OnButtonPressed := PopupButtonPressed;
|
|
FCalculator.OnExit := PopupClose;
|
|
FCalculator.OnKeyDown := PopupKeyDown;
|
|
FCalculator.OnKeyPress := PopupKeyPress;
|
|
FCalculator.OnMouseDown := PopupMouseDown;
|
|
FCalculator.Visible := False; {to avoid flash at 0,0}
|
|
FCalculator.Options := [coShowItemCount];
|
|
FCalculator.BorderStyle := bsSingle;
|
|
FCalculator.ParentFont := False;
|
|
end;
|
|
|
|
procedure TOvcCustomNumberEdit.DoExit;
|
|
begin
|
|
if not PopupActive then
|
|
inherited DoExit;
|
|
end;
|
|
|
|
function TOvcCustomNumberEdit.GetAsFloat : Double;
|
|
var
|
|
I : Integer;
|
|
S : string;
|
|
begin
|
|
S := Text;
|
|
for I := Length(S) downto 1 do
|
|
if not (S[I] in ['0'..'9', '+', '-', DecimalSeparator]) then
|
|
Delete(S, I, 1);
|
|
Result := StrToFloat(S);
|
|
end;
|
|
|
|
function TOvcCustomNumberEdit.GetAsInteger : LongInt;
|
|
begin
|
|
Result := Round(GetAsFloat);
|
|
end;
|
|
|
|
function TOvcCustomNumberEdit.GetAsString : string;
|
|
begin
|
|
Result := Text;
|
|
end;
|
|
|
|
function TOvcCustomNumberEdit.GetPopupColors : TOvcCalcColors;
|
|
begin
|
|
Result := FCalculator.Colors;
|
|
end;
|
|
|
|
function TOvcCustomNumberEdit.GetPopupDecimals : Integer;
|
|
begin
|
|
Result := FCalculator.Decimals;
|
|
end;
|
|
|
|
function TOvcCustomNumberEdit.GetPopupFont : TFont;
|
|
begin
|
|
Result := FCalculator.Font;
|
|
end;
|
|
|
|
function TOvcCustomNumberEdit.GetPopupHeight : Integer;
|
|
begin
|
|
Result := FCalculator.Height;
|
|
end;
|
|
|
|
function TOvcCustomNumberEdit.GetPopupWidth : Integer;
|
|
begin
|
|
Result := FCalculator.Width;
|
|
end;
|
|
|
|
function TOvcCustomNumberEdit.GetReadOnly : Boolean;
|
|
begin
|
|
Result := inherited ReadOnly;
|
|
end;
|
|
|
|
procedure TOvcCustomNumberEdit.GlyphChanged;
|
|
begin
|
|
inherited GlyphChanged;
|
|
|
|
if FButtonGlyph.Empty then
|
|
{$IFNDEF LCL}
|
|
FButtonGlyph.Handle := LoadBaseBitmap('ORBTNCLC');
|
|
{$ELSE}
|
|
FButtonGlyph.LoadFromLazarusResource('ORBTNCLC');
|
|
{$ENDIF}
|
|
end;
|
|
|
|
procedure TOvcCustomNumberEdit.KeyDown(var Key : Word; Shift : TShiftState);
|
|
begin
|
|
inherited KeyDown(Key, Shift);
|
|
|
|
if (Key = VK_DOWN) and (ssAlt in Shift) then
|
|
PopupOpen;
|
|
end;
|
|
|
|
procedure TOvcCustomNumberEdit.KeyPress(var Key : Char);
|
|
var
|
|
D : Double;
|
|
X : Integer;
|
|
L : Integer;
|
|
begin
|
|
inherited KeyPress(Key);
|
|
|
|
if not ((Key = #22) or (Key = #3) or (Key = #24)) then begin
|
|
if not (Key in [#27, '0'..'9', '.', DecimalSeparator,
|
|
#8, '+', '-', '*', '/']) then begin
|
|
Key := #0;
|
|
{$IFNDEF LCL}
|
|
MessageBeep(0);
|
|
{$ENDIF}
|
|
Exit;
|
|
end;
|
|
|
|
{Disallow more than one DecimalSeparator in the number}
|
|
if (SelLength <> Length(Text))
|
|
and (Key = DecimalSeparator) and (Pos(DecimalSeparator, Text) > 0)
|
|
then begin
|
|
Key := #0;
|
|
{$IFNDEF LCL}
|
|
MessageBeep(0);
|
|
{$ENDIF}
|
|
Exit;
|
|
end;
|
|
|
|
if FAllowIncDec and (Key in ['+', '-']) then begin
|
|
if Text = '' then
|
|
Text := '0';
|
|
D := StrToFloat(Text);
|
|
X := SelStart;
|
|
L := SelLength;
|
|
|
|
if Key = '+' then
|
|
Text := FloatToStr(D+1)
|
|
else {'-'}
|
|
Text := FloatToStr(D-1);
|
|
|
|
SelStart := X;
|
|
SelLength := L;
|
|
|
|
Key := #0; {clear key}
|
|
end;
|
|
|
|
if (Key in ['+', '*', '/']) then begin
|
|
PopUpOpen;
|
|
FCalculator.KeyPress(Key);
|
|
Key := #0; {clear key}
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TOvcCustomNumberEdit.PopupButtonPressed(Sender : TObject;
|
|
Button : TOvcCalculatorButton);
|
|
begin
|
|
case Button of
|
|
cbEqual :
|
|
begin
|
|
{get the current value}
|
|
Text := FloatToStr(FCalculator.DisplayValue);
|
|
Modified := True;
|
|
|
|
{hide the calculator}
|
|
PopupClose(Sender);
|
|
SetFocus;
|
|
SelStart := Length(Text);
|
|
SelLength := 0;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TOvcCustomNumberEdit.PopupClose(Sender : TObject);
|
|
begin
|
|
if not FCalculator.Visible then
|
|
Exit; {already closed, exit}
|
|
|
|
if PopupClosing then
|
|
Exit;
|
|
|
|
PopupClosing := True; {avoid recursion}
|
|
try
|
|
inherited PopupClose(Sender);
|
|
|
|
if GetCapture = FCalculator.Handle then
|
|
ReleaseCapture;
|
|
|
|
SetFocus;
|
|
FCalculator.Hide; {hide the calculator}
|
|
TForm(FCalculator.Parent).AutoScroll := WasAutoScroll;
|
|
Cursor := HoldCursor;
|
|
|
|
{change parentage so that we control the window handle destruction}
|
|
FCalculator.Parent := Self;
|
|
finally
|
|
PopupClosing := False;
|
|
end;
|
|
end;
|
|
|
|
procedure TOvcCustomNumberEdit.PopupKeyDown(Sender : TObject; var Key : Word; Shift : TShiftState);
|
|
var
|
|
X : Integer;
|
|
begin
|
|
case Key of
|
|
|
|
VK_TAB :
|
|
begin
|
|
if Shift = [ssShift] then begin
|
|
PopupClose(Sender);
|
|
PostMessage(Handle, WM_KeyDown, VK_TAB, Integer(ssShift));
|
|
end else if Shift = [] then begin
|
|
PopupClose(Sender);
|
|
PostMessage(Handle, WM_KeyDown, VK_TAB, 0);
|
|
end;
|
|
end;
|
|
|
|
|
|
VK_UP : if Shift = [ssAlt] then begin
|
|
PopupClose(Sender);
|
|
X := SelStart;
|
|
SetFocus;
|
|
SelStart := X;
|
|
SelLength := 0;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TOvcCustomNumberEdit.PopupKeyPress(Sender : TObject; var Key : Char);
|
|
var
|
|
X : Integer;
|
|
begin
|
|
case Key of
|
|
#27 :
|
|
begin
|
|
PopupClose(Sender);
|
|
X := SelStart;
|
|
SetFocus;
|
|
SelStart := X;
|
|
SelLength := 0;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TOvcCustomNumberEdit.PopupMouseDown(Sender : TObject; Button : TMouseButton; Shift : TShiftState; X, Y : Integer);
|
|
var
|
|
P : TPoint;
|
|
I : Integer;
|
|
begin
|
|
P := Point(X,Y);
|
|
if not PtInRect(FCalculator.ClientRect, P) then
|
|
PopUpClose(Sender);
|
|
|
|
{convert to our coordinate system}
|
|
P := ScreenToClient(FCalculator.ClientToScreen(P));
|
|
|
|
if PtInRect(ClientRect, P) then begin
|
|
I := SelStart;
|
|
SetFocus;
|
|
SelStart := I;
|
|
SelLength := 0;
|
|
end;
|
|
end;
|
|
|
|
procedure TOvcCustomNumberEdit.PopupOpen;
|
|
var
|
|
P : TPoint;
|
|
R : TRect;
|
|
{$IFDEF VERSION4}
|
|
{$IFNDEF LCL}
|
|
F : TCustomForm;
|
|
MonInfo : TMonitorInfo;
|
|
{$ENDIF}
|
|
{$ENDIF}
|
|
begin
|
|
if FCalculator.Visible then
|
|
Exit; {already popped up, exit}
|
|
|
|
inherited PopupOpen;
|
|
|
|
FCalculator.Parent := GetImmediateParentForm(Self);
|
|
if FCalculator.Parent is TForm then begin
|
|
WasAutoScroll := TForm(FCalculator.Parent).AutoScroll;
|
|
TForm(FCalculator.Parent).AutoScroll := False;
|
|
end;
|
|
|
|
{set 3d to be the same as our own}
|
|
{$IFNDEF LCL}
|
|
FCalculator.ParentCtl3D := False;
|
|
{$ENDIF}
|
|
FCalculator.Ctl3D := False;
|
|
|
|
{determine the proper position}
|
|
SystemParametersInfo(SPI_GETWORKAREA, 0, @R, 0);
|
|
{$IFDEF VERSION4}
|
|
{$IFNDEF LCL}
|
|
F := GetParentForm(Self);
|
|
if Assigned(F) then begin
|
|
FillChar(MonInfo, SizeOf(MonInfo), #0);
|
|
MonInfo.cbSize := SizeOf(MonInfo);
|
|
GetMonitorInfo(F.Monitor.Handle, @MonInfo);
|
|
R := MonInfo.rcWork;
|
|
end;
|
|
{$ENDIF}
|
|
{$ENDIF}
|
|
if FPopupAnchor = paLeft then
|
|
P := ClientToScreen(Point(-3, Height-4))
|
|
else {paRight}
|
|
P := ClientToScreen(Point(Width-FCalculator.Width-1, Height-2));
|
|
if not Ctl3D then begin
|
|
Inc(P.X, 3);
|
|
Inc(P.Y, 3);
|
|
end;
|
|
if P.Y + FCalculator.Height >= R.Bottom then
|
|
P.Y := P.Y - FCalculator.Height - Height;
|
|
if P.X + FCalculator.Width >= R.Right then
|
|
P.X := R.Right - FCalculator.Width - 1;
|
|
if P.X <= R.Left then
|
|
P.X := R.Left + 1;
|
|
|
|
{$IFNDEF LCL}
|
|
MoveWindow(FCalculator.Handle, P.X, P.Y, FCalculator.Width, FCalculator.Height, False);
|
|
{$ENDIF}
|
|
|
|
HoldCursor := Cursor;
|
|
Cursor := crArrow;
|
|
FCalculator.PressButton(cbClear);
|
|
FCalculator.Show;
|
|
FCalculator.Visible := True;
|
|
if Text <> '' then
|
|
FCalculator.PushOperand(AsFloat)
|
|
else
|
|
FCalculator.PushOperand(0);
|
|
FCalculator.SetFocus;
|
|
|
|
SetCapture(FCalculator.Handle);
|
|
end;
|
|
|
|
procedure TOvcCustomNumberEdit.SetAsFloat(Value : Double);
|
|
begin
|
|
Text := FloatToStr(Value);
|
|
end;
|
|
|
|
procedure TOvcCustomNumberEdit.SetAsInteger(Value : LongInt);
|
|
begin
|
|
Text := IntToStr(Value);
|
|
end;
|
|
|
|
procedure TOvcCustomNumberEdit.SetAsString(const Value : string);
|
|
begin
|
|
Text := Value;
|
|
end;
|
|
|
|
procedure TOvcCustomNumberEdit.SetPopupColors(Value : TOvcCalcColors);
|
|
begin
|
|
FCalculator.Colors := Value;
|
|
end;
|
|
|
|
procedure TOvcCustomNumberEdit.SetPopupDecimals(Value : Integer);
|
|
begin
|
|
FCalculator.Decimals := Value;
|
|
end;
|
|
|
|
procedure TOvcCustomNumberEdit.SetPopupFont(Value : TFont);
|
|
begin
|
|
if Assigned(Value) then
|
|
FCalculator.Font.Assign(Value);
|
|
end;
|
|
|
|
procedure TOvcCustomNumberEdit.SetPopupHeight(Value : Integer);
|
|
begin
|
|
FCalculator.Height := Value;
|
|
end;
|
|
|
|
procedure TOvcCustomNumberEdit.SetPopupWidth(Value : Integer);
|
|
begin
|
|
FCalculator.Width := Value;
|
|
end;
|
|
|
|
procedure TOvcCustomNumberEdit.SetReadOnly(Value : Boolean);
|
|
begin
|
|
inherited ReadOnly := Value;
|
|
|
|
FButton.Enabled := not ReadOnly;
|
|
end;
|
|
|
|
end.
|