summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorgraemeg <graemeg@ae50a9b5-8222-0410-bf8d-8a13f76226bf>2008-10-03 14:45:14 +0000
committergraemeg <graemeg@ae50a9b5-8222-0410-bf8d-8a13f76226bf>2008-10-03 14:45:14 +0000
commitff87ebe7afdf27042b7963ca04246963adbdcaab (patch)
tree7291dd44940bfce41b08eeaccc397e9e15a061b3
parent7a6030c56def0f368a5208763a78dce163cb0bc4 (diff)
downloadfpGUI-ff87ebe7afdf27042b7963ca04246963adbdcaab.tar.xz
* Added Jean-Marc initial implementation of SpinEdit component.
* I made some changes and minor bug fixes to the SpinEdit and highlighted some todo items in the header of the unit.
-rw-r--r--src/corelib/gdi/fpgui_toolkit.lpk8
-rw-r--r--src/corelib/gdi/fpgui_toolkit.pas2
-rw-r--r--src/corelib/x11/fpgui_toolkit.lpk6
-rw-r--r--src/corelib/x11/fpgui_toolkit.pas2
-rw-r--r--src/gui/fpg_button.pas2
-rw-r--r--src/gui/fpg_edit.pas56
-rw-r--r--src/gui/fpg_popupcalendar.pas8
-rw-r--r--src/gui/fpg_spinedit.pas881
8 files changed, 931 insertions, 34 deletions
diff --git a/src/corelib/gdi/fpgui_toolkit.lpk b/src/corelib/gdi/fpgui_toolkit.lpk
index e0d3533c..0c62a067 100644
--- a/src/corelib/gdi/fpgui_toolkit.lpk
+++ b/src/corelib/gdi/fpgui_toolkit.lpk
@@ -26,8 +26,8 @@
"/>
<License Value="Modified LGPL
"/>
- <Version Minor="6" Release="2"/>
- <Files Count="69">
+ <Version Minor="6" Release="3"/>
+ <Files Count="70">
<Item1>
<Filename Value="..\stdimages.inc"/>
<Type Value="Include"/>
@@ -304,6 +304,10 @@
<Filename Value="..\..\gui\fpg_hint.pas"/>
<UnitName Value="fpg_hint"/>
</Item69>
+ <Item70>
+ <Filename Value="..\..\gui\fpg_spinedit.pas"/>
+ <UnitName Value="fpg_spinedit"/>
+ </Item70>
</Files>
<LazDoc Paths="..\..\..\docs\xml\corelib\;..\..\..\docs\xml\corelib\x11\;..\..\..\docs\xml\corelib\gdi\;..\..\..\docs\xml\gui\"/>
<RequiredPkgs Count="1">
diff --git a/src/corelib/gdi/fpgui_toolkit.pas b/src/corelib/gdi/fpgui_toolkit.pas
index d4a92342..bbfa850e 100644
--- a/src/corelib/gdi/fpgui_toolkit.pas
+++ b/src/corelib/gdi/fpgui_toolkit.pas
@@ -16,7 +16,7 @@ uses
fpg_hyperlink, fpg_iniutils, fpg_label, fpg_listbox, fpg_listview, fpg_memo,
fpg_menu, fpg_mru, fpg_panel, fpg_popupcalendar, fpg_progressbar,
fpg_radiobutton, fpg_scrollbar, fpg_style, fpg_tab, fpg_trackbar, fpg_tree,
- fpgui_db, fpg_gdi, fpg_impl, fpg_splitter, fpg_hint;
+ fpgui_db, fpg_gdi, fpg_impl, fpg_splitter, fpg_hint, fpg_spinedit;
implementation
diff --git a/src/corelib/x11/fpgui_toolkit.lpk b/src/corelib/x11/fpgui_toolkit.lpk
index 0eb0ea09..7329a3bb 100644
--- a/src/corelib/x11/fpgui_toolkit.lpk
+++ b/src/corelib/x11/fpgui_toolkit.lpk
@@ -29,7 +29,7 @@
<License Value="Modified LGPL
"/>
<Version Minor="6" Release="3"/>
- <Files Count="71">
+ <Files Count="72">
<Item1>
<Filename Value="../stdimages.inc"/>
<Type Value="Include"/>
@@ -314,6 +314,10 @@
<Filename Value="../../gui/fpg_hint.pas"/>
<UnitName Value="fpg_hint"/>
</Item71>
+ <Item72>
+ <Filename Value="../../gui/fpg_spinedit.pas"/>
+ <UnitName Value="fpg_spinedit"/>
+ </Item72>
</Files>
<LazDoc Paths="../../../docs/xml/corelib/;../../../docs/xml/corelib/x11/;../../../docs/xml/corelib/gdi/;../../../docs/xml/gui/"/>
<RequiredPkgs Count="1">
diff --git a/src/corelib/x11/fpgui_toolkit.pas b/src/corelib/x11/fpgui_toolkit.pas
index 4d37c9c8..953d2aa1 100644
--- a/src/corelib/x11/fpgui_toolkit.pas
+++ b/src/corelib/x11/fpgui_toolkit.pas
@@ -17,7 +17,7 @@ uses
fpg_iniutils, fpg_label, fpg_listbox, fpg_listview, fpg_memo, fpg_menu,
fpg_mru, fpg_panel, fpg_popupcalendar, fpg_progressbar, fpg_radiobutton,
fpg_scrollbar, fpg_style, fpg_tab, fpg_trackbar, fpg_tree, fpgui_db,
- fpg_splitter, fpg_hint;
+ fpg_splitter, fpg_hint, fpg_spinedit;
implementation
diff --git a/src/gui/fpg_button.pas b/src/gui/fpg_button.pas
index fdb2f634..e3e2a62e 100644
--- a/src/gui/fpg_button.pas
+++ b/src/gui/fpg_button.pas
@@ -149,8 +149,10 @@ type
property Text;
property TextColor;
property TabOrder;
+ property OnMouseDown;
property OnMouseExit;
property OnMouseEnter;
+ property OnMouseUp;
property OnClick;
end;
diff --git a/src/gui/fpg_edit.pas b/src/gui/fpg_edit.pas
index 342718c2..dbf79361 100644
--- a/src/gui/fpg_edit.pas
+++ b/src/gui/fpg_edit.pas
@@ -40,7 +40,6 @@ type
FPopupMenu: TfpgPopupMenu;
FDefaultPopupMenu: TfpgPopupMenu;
FText: string;
- FFont: TfpgFont;
FPasswordMode: Boolean;
FBorderStyle: TfpgEditBorderStyle;
FOnChange: TNotifyEvent;
@@ -66,6 +65,7 @@ type
procedure DefaultPopupClearAll(Sender: TObject);
procedure SetDefaultPopupMenuItemsState;
protected
+ FFont: TfpgFont;
FSideMargin: integer;
FMouseDragPos: integer;
FSelStart: integer;
@@ -94,7 +94,6 @@ type
function GetDrawText: String;
property AutoSelect: Boolean read FAutoSelect write SetAutoSelect default True;
property BorderStyle: TfpgEditBorderStyle read FBorderStyle write SetBorderStyle default ebsDefault;
- property Font: TfpgFont read FFont;
property FontDesc: String read GetFontDesc write SetFontDesc;
property HideSelection: Boolean read FHideSelection write SetHideSelection default True;
property MaxLength: Integer read FMaxLength write FMaxLength;
@@ -112,12 +111,12 @@ type
procedure CopyToClipboard;
procedure CutToClipboard;
procedure PasteFromClipboard;
+ property Font: TfpgFont read FFont;
end;
TfpgEdit = class(TfpgBaseEdit)
public
- property Font;
property PopupMenu; // UI Designer doesn't fully support it yet
published
property AutoSelect;
@@ -182,7 +181,6 @@ type
property OnMouseEnter;
property OnMouseExit;
property OnPaint;
- property Text; { this should become Value }
public
constructor Create(AOwner: TComponent); override;
published
@@ -199,7 +197,8 @@ type
procedure HandleKeyChar(var AText: TfpgChar; var shiftstate: TShiftState; var consumed: Boolean); override;
public
constructor Create(AOwner: TComponent); override;
- property Text;
+ property OldColor;
+ property Text;
published
property Alignment;
property NegativeColor;
@@ -219,33 +218,37 @@ type
TfpgEditFloat = class(TfpgBaseNumericEdit)
private
- fDecimals: integer;
+ FDecimals: integer;
+ FFixedDecimals: boolean;
protected
function GetValue: extended; virtual;
procedure SetValue(const AValue: extended); virtual;
procedure SetShowThousand;
- procedure SetDecimals(AValue: integer);
+ procedure SetDecimals(const AValue: integer);
+ procedure SetFixedDecimals(const AValue: boolean);
procedure Format; override;
procedure HandleKeyChar(var AText: TfpgChar; var shiftstate: TShiftState; var consumed: Boolean); override;
public
constructor Create(AOwner: TComponent); override;
- property Text;
+ property OldColor;
+ property Text;
published
property Alignment;
property Decimals: integer read fDecimals write SetDecimals;
- property NegativeColor;
property DecimalSeparator;
- property Value: extended read GetValue write SetValue;
- property ShowThousand;
- property TabOrder;
- property TextColor;
- property ThousandSeparator;
+ property FixedDecimals: boolean read FFixedDecimals write SetFixedDecimals;
+ property NegativeColor;
property OnChange;
property OnEnter;
property OnExit;
property OnKeyPress;
property OnMouseEnter;
property OnMouseExit;
+ property ShowThousand;
+ property TabOrder;
+ property TextColor;
+ property ThousandSeparator;
+ property Value: extended read GetValue write SetValue;
end;
@@ -262,12 +265,12 @@ type
procedure HandleKeyPress(var keycode: word; var shiftstate: TShiftState; var consumed: Boolean); override;
public
constructor Create(AOwner: TComponent); override;
+ property OldColor;
property Text;
published
property Alignment;
property Decimals: integer read fDecimals write SetDecimals;
property NegativeColor;
- property OldColor;
property DecimalSeparator;
property ThousandSeparator;
property ShowThousand;
@@ -1356,6 +1359,7 @@ procedure TfpgEditInteger.SetValue(const AValue: integer);
begin
try
Text := IntToStr(AValue);
+ Format;
except
on E: EConvertError do
Text := '';
@@ -1575,12 +1579,18 @@ begin
end;
end;
-procedure TfpgEditFloat.SetDecimals(AValue: integer);
+procedure TfpgEditFloat.SetDecimals(const AValue: integer);
begin
if AValue < -1 then
Exit; // =>
- if fDecimals <> AValue then
- fDecimals := AValue
+ if FDecimals <> AValue then
+ FDecimals := AValue
+end;
+
+procedure TfpgEditFloat.SetFixedDecimals(const AValue: boolean);
+begin
+ if FFixedDecimals <> AValue then
+ FFixedDecimals := AValue;
end;
procedure TfpgEditFloat.Format;
@@ -1606,8 +1616,9 @@ end;
constructor TfpgEditFloat.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
- fDecimals := -1;
- fShowThousand := True;
+ FDecimals := -1;
+ FFixedDecimals := False;
+ FShowThousand := True;
end;
{ TfpgEditCurrency }
@@ -1729,14 +1740,11 @@ begin
Inc(FCursorPos);
end;
end;
- if AValue < 0 then
- TextColor := NegativeColor
- else
- TextColor := OldColor;
except
on E: EConvertError do
Text := '';
end;
+ Format;
end;
procedure TfpgEditCurrency.SetShowThousand;
diff --git a/src/gui/fpg_popupcalendar.pas b/src/gui/fpg_popupcalendar.pas
index 5884a722..d083fcac 100644
--- a/src/gui/fpg_popupcalendar.pas
+++ b/src/gui/fpg_popupcalendar.pas
@@ -23,11 +23,9 @@ unit fpg_popupcalendar;
{.$Define DEBUG} // while developing the component
{
- ***********************************************************
- ********** This is still under development! ***********
- ***********************************************************
-
- It needs lots of testing and debugging.
+ *****************************************************************
+ ********** This is still under heavy development! ***********
+ *****************************************************************
}
diff --git a/src/gui/fpg_spinedit.pas b/src/gui/fpg_spinedit.pas
new file mode 100644
index 00000000..19b36a84
--- /dev/null
+++ b/src/gui/fpg_spinedit.pas
@@ -0,0 +1,881 @@
+{
+ fpGUI - Free Pascal GUI Toolkit
+
+ Copyright (C) 2006 - 2008 See the file AUTHORS.txt, included in this
+ distribution, for details of the copyright.
+
+ See the file COPYING.modifiedLGPL, included in this distribution,
+ for details about redistributing fpGUI.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+ Description:
+ Defines a spinedit control.
+}
+
+unit fpg_spinedit;
+
+{$mode objfpc}{$H+}
+
+{
+ *****************************************************************
+ ********** This is still under heavy development! ***********
+ *****************************************************************
+}
+
+{ TODO : Base classes need to be abstracted from final classes. }
+{ TODO : Up/Down keyboard input needs to be corrected. }
+{ TODO : Step size needs to be implemented (small and large) }
+{ TODO : PgUp/PgDn keyboard needs to be supported. }
+{ TODO : Improve Timer and Step support. If the mouse is kept down on
+ a button, it should increment by small steps. After as certain
+ period, it should start inrementing by large steps. }
+{ TODO : Text cursor positioning should be fixed. }
+
+interface
+
+uses
+ Classes,
+ SysUtils,
+ fpg_base,
+ fpg_main,
+ fpg_widget,
+ fpg_panel,
+ fpg_edit,
+ fpg_button;
+
+type
+
+ { TfpgSpinEdit }
+
+ TfpgAbstractSpinEdit = class(TfpgBevel)
+ private
+ FButtonUp: TfpgButton;
+ FButtonDown: TfpgButton;
+ FArrowUpColor: Tfpgcolor;
+ FArrowDownColor: Tfpgcolor;
+ FTimer: TfpgTimer;
+ FUp: Boolean;
+ FDown: Boolean;
+ protected
+ FButtonWidth: integer;
+ function GetButtonsBackgroundColor: TfpgColor;
+ procedure SetButtonsBackgroundColor(const AValue: Tfpgcolor);
+ procedure SetArrowUpColor(const AValue: Tfpgcolor);
+ procedure SetArrowDownColor(const AValue: Tfpgcolor);
+ procedure ButtonUpPaint(Sender: TObject);
+ procedure ButtonDownPaint(Sender: TObject);
+ property ButtonsBackgroundColor: Tfpgcolor read GetButtonsBackgroundColor write SetButtonsBackgroundColor default clButtonFace;
+ property ArrowUpColor: TfpgColor read FArrowUpColor write SetArrowUpColor;
+ property ArrowDownColor: TfpgColor read FArrowDownColor write SetArrowDownColor;
+ public
+ constructor Create(AOwner: TComponent); override;
+ end;
+
+
+ TfpgSpinEditFloat = class(TfpgAbstractSpinEdit)
+ private
+ FEdit: TfpgEditFloat;
+ FMaxValue: extended;
+ FMinValue: extended;
+ FIncrement: extended;
+ FValue: extended;
+ procedure EnableButtons;
+ protected
+ function GetEditBackgroundColor: TfpgColor;
+ function GetTextColor: TfpgColor;
+ function GetNegativeColor: TfpgColor;
+ function GetFontDesc: string;
+ function GetDecimals: integer;
+ function GetFixedDecimals: Boolean;
+ procedure SetEditBackgroundColor(const AValue: Tfpgcolor);
+ procedure SetTextColor(const AValue: Tfpgcolor);
+ procedure SetNegativeColor(const AValue: Tfpgcolor);
+ procedure SetFontDesc(const AValue: string);
+ procedure SetMaxValue(const AValue: extended);
+ procedure SetMinValue(const AValue: extended);
+ procedure SetIncrement(const AValue: extended);
+ procedure SetValue(const AValue: extended);
+ procedure SetDecimals(const AValue: integer);
+ procedure SetFixedDecimals(const AValue: Boolean);
+ procedure ButtonUpClick(Sender: TObject);
+ procedure ButtonDownClick(Sender: TObject);
+ procedure ButtonUpMouseDown(Sender: TObject; AButton: TMouseButton; AShift: TShiftState; const AMousePos: TPoint);
+ procedure ButtonUpMouseUp(Sender: TObject; AButton: TMouseButton; AShift: TShiftState; const AMousePos: TPoint);
+ procedure ButtonDownMouseDown(Sender: TObject; AButton: TMouseButton; AShift: TShiftState; const AMousePos: TPoint);
+ procedure ButtonDownMouseUp(Sender: TObject; AButton: TMouseButton; AShift: TShiftState; const AMousePos: TPoint);
+ procedure EditKeyPress(Sender: TObject; var keycode: word; var shiftstate: TShiftState; var consumed: Boolean);
+ procedure EditExit(Sender: TObject);
+ procedure TimerStep(Sender: TObject);
+ public
+ constructor Create(AOwner: TComponent); override;
+ published
+ property EditBackgroundColor: Tfpgcolor read GetEditBackgroundColor write SetEditBackgroundColor default clBoxColor;
+ property ButtonsBackgroundColor;
+ property TextColor: Tfpgcolor read GetTextColor write SetTextColor;
+ property NegativeColor: TfpgColor read GetNegativeColor write SetNegativeColor;
+ property ArrowUpColor;
+ property ArrowDownColor;
+ property FontDesc: string read GetFontDesc write SetFontDesc;
+ property MaxValue: extended read FMaxValue write SetMaxValue;
+ property MinValue: extended read FMinValue write SetMinValue;
+ property Increment: extended read FIncrement write SetIncrement;
+ property Value: extended read FValue write SetValue;
+ property Decimals: integer read GetDecimals write SetDecimals;
+ property FixedDecimals: Boolean read GetFixedDecimals write SetFixedDecimals;
+ end;
+
+
+ TfpgSpinEdit = class(TfpgAbstractSpinEdit)
+ private
+ FEdit: TfpgEditInteger;
+ FMaxValue: integer;
+ FMinValue: integer;
+ FIncrement: integer;
+ FValue: integer;
+ procedure EnableButtons;
+ protected
+ function GetEditBackgroundColor: TfpgColor;
+ function GetTextColor: TfpgColor;
+ function GetNegativeColor: TfpgColor;
+ function GetFontDesc: string;
+ procedure SetEditBackgroundColor(const AValue: Tfpgcolor);
+ procedure SetTextColor(const AValue: Tfpgcolor);
+ procedure SetNegativeColor(const AValue: Tfpgcolor);
+ procedure SetFontDesc(const AValue: string);
+ procedure SetMaxValue(const AValue: integer);
+ procedure SetMinValue(const AValue: integer);
+ procedure SetIncrement(const AValue: integer);
+ procedure SetValue(const AValue: integer);
+ procedure ButtonUpClick(Sender: TObject);
+ procedure ButtonDownClick(Sender: TObject);
+ procedure ButtonUpMouseDown(Sender: TObject; AButton: TMouseButton; AShift: TShiftState; const AMousePos: TPoint);
+ procedure ButtonUpMouseUp(Sender: TObject; AButton: TMouseButton; AShift: TShiftState; const AMousePos: TPoint);
+ procedure ButtonDownMouseDown(Sender: TObject; AButton: TMouseButton; AShift: TShiftState; const AMousePos: TPoint);
+ procedure ButtonDownMouseUp(Sender: TObject; AButton: TMouseButton; AShift: TShiftState; const AMousePos: TPoint);
+ procedure EditKeyPress(Sender: TObject; var keycode: word; var shiftstate: TShiftState; var consumed: Boolean);
+ procedure EditExit(Sender: TObject);
+ procedure TimerStep(Sender: TObject);
+ public
+ constructor Create(AOwner: TComponent); override;
+ published
+ property EditBackgroundColor: Tfpgcolor read GetEditBackgroundColor write SetEditBackgroundColor default clBoxColor;
+ property ButtonsBackgroundColor;
+ property TextColor: Tfpgcolor read GetTextColor write SetTextColor;
+ property NegativeColor: TfpgColor read GetNegativeColor write SetNegativeColor;
+ property ArrowUpColor;
+ property ArrowDownColor;
+ property FontDesc: string read GetFontDesc write SetFontDesc;
+ property MaxValue: integer read FMaxValue write SetMaxValue;
+ property MinValue: integer read FMinValue write SetMinValue;
+ property Increment: integer read FIncrement write SetIncrement;
+ property Value: integer read FValue write SetValue;
+ end;
+
+
+function CreateSpinEditFloat(AOwner: TComponent; x, y, w, h: TfpgCoord; AMinValue: extended = 0; AMaxValue: extended = 100; AIncrement: extended = 1; ADecimals: integer = 1; AValue: extended = 0): TfpgSpinEditFloat;
+function CreateSpinEdit(AOwner: TComponent; x, y, w, h: TfpgCoord; AMinValue: integer = 0; AMaxValue: integer = 100; AIncrement: integer = 1; AValue: integer = 0): TfpgSpinEdit;
+
+
+implementation
+
+
+function CreateSpinEditFloat(AOwner: TComponent; x, y, w, h: TfpgCoord; AMinValue: extended = 0; AMaxValue: extended = 100; AIncrement: extended = 1; ADecimals: integer = 1; AValue: extended = 0): TfpgSpinEditFloat;
+begin
+ Result := TfpgSpinEditFloat.Create(AOwner);
+ Result.Left := x;
+ Result.Top := y;
+ Result.Width := w;
+ if h < Result.FEdit.Font.Height + 6 then
+ Result.Height := Result.FEdit.Font.Height + 6
+ else
+ Result.Height := h;
+ Result.FEdit.Height := Result.Height;
+ Result.FEdit.Width := Result.Width - Result.FButtonWidth;
+ Result.FButtonUp.Left := Result.Width - Result.FButtonWidth;
+ Result.FButtonDown.Left := Result.Width - Result.FButtonWidth;
+ if AMaxValue > AMinValue then
+ begin
+ Result.MinValue := AMinValue;
+ Result.MaxValue := AMaxValue;
+ end;
+ Result.Increment := AIncrement;
+ Result.FEdit.Decimals := ADecimals;
+ if (AValue <= Result.MaxValue) and (AValue >= Result.MinValue) then
+ Result.Value := AValue;
+end;
+
+function CreateSpinEdit(AOwner: TComponent; x, y, w, h: TfpgCoord; AMinValue: integer = 0; AMaxValue: integer = 100; AIncrement: integer = 1; AValue: integer = 0): TfpgSpinEdit;
+begin
+ Result := TfpgSpinEdit.Create(AOwner);
+ Result.Left := x;
+ Result.Top := y;
+ Result.Width := w;
+ if h < Result.FEdit.Font.Height + 6 then
+ Result.Height := Result.FEdit.Font.Height + 6
+ else
+ Result.Height := h;
+ Result.FEdit.Height := Result.Height;
+ Result.FEdit.Width := Result.Width - Result.FButtonWidth;
+ Result.FButtonUp.Left := Result.Width - Result.FButtonWidth;
+ Result.FButtonDown.Left := Result.Width - Result.FButtonWidth;
+ if AMaxValue > AMinValue then
+ begin
+ Result.MinValue := AMinValue;
+ Result.MaxValue := AMaxValue;
+ end;
+ Result.Increment := AIncrement;
+ if (AValue <= Result.MaxValue) and (AValue >= Result.MinValue) then
+ Result.Value := AValue;
+end;
+
+
+{ TfpgAbstractSpinEdit }
+
+function TfpgAbstractSpinEdit.GetButtonsBackgroundColor: TfpgColor;
+begin
+ Result := FButtonUp.BackgroundColor;
+end;
+
+procedure TfpgAbstractSpinEdit.SetButtonsBackgroundColor(const AValue: Tfpgcolor);
+begin
+ if FButtonUp.BackgroundColor <> AValue then
+ begin
+ FButtonUp.BackgroundColor := AValue;
+ FButtonDown.BackgroundColor := AValue;
+ end;
+end;
+
+procedure TfpgAbstractSpinEdit.SetArrowUpColor(const AValue: Tfpgcolor);
+begin
+ if FArrowUpColor <> AValue then
+ FArrowUpColor := AValue;
+end;
+
+procedure TfpgAbstractSpinEdit.SetArrowDownColor(const AValue: Tfpgcolor);
+begin
+ if FArrowDownColor <> AValue then
+ FArrowDownColor := AValue;
+end;
+
+procedure TfpgAbstractSpinEdit.ButtonUpPaint(Sender: TObject);
+begin
+ if TfpgButton(Sender).Enabled then
+ TfpgButton(Sender).Canvas.SetColor(FArrowUpColor)
+ else
+ TfpgButton(Sender).Canvas.SetColor(clShadow1);
+
+ fpgStyle.DrawDirectionArrow(TfpgButton(Sender).Canvas, 0, 0, TfpgButton(Sender).Width - 3, TfpgButton(Sender).Height, adUp);
+end;
+
+procedure TfpgAbstractSpinEdit.ButtonDownPaint(Sender: TObject);
+begin
+ if TfpgButton(Sender).Enabled then
+ TfpgButton(Sender).Canvas.SetColor(FArrowDownColor)
+ else
+ TfpgButton(Sender).Canvas.SetColor(clShadow1);
+
+ fpgStyle.DrawDirectionArrow(TfpgButton(Sender).Canvas, 0, 0, TfpgButton(Sender).Width - 3, TfpgButton(Sender).Height, adDown);
+end;
+
+constructor TfpgAbstractSpinEdit.Create(AOwner: TComponent);
+begin
+ inherited Create(AOwner);
+ FButtonWidth := 13; // width of spin buttons
+ Shape := bsSpacer;
+
+ FButtonUp := TfpgButton.Create(Self);
+ with FButtonUp do
+ begin
+ SetPosition(Width - FButtonWidth, 0, FButtonWidth, Height div 2);
+ Text := '';
+ BackgroundColor := clButtonFace;
+ Focusable := False;
+ OnPaint := @ButtonUpPaint;
+ end;
+ FArrowUpColor := clText1;
+ FButtonDown := TfpgButton.Create(Self);
+ with FButtonDown do
+ begin
+ SetPosition(Width - FButtonWidth, (Height div 2) + 1, FButtonWidth, (Height div 2) - 1);
+ Text := '';
+ BackgroundColor := clButtonFace;
+ Focusable := False;
+ OnPaint := @ButtonDownPaint;
+ end;
+ FArrowDownColor := clText1;
+ FTimer := TfpgTimer.Create(200);
+ FTimer.Enabled := False;
+end;
+
+
+{ TfpgSpinEditFloat }
+
+procedure TfpgSpinEditFloat.EnableButtons;
+begin
+ if FValue + FIncrement < FMaxValue then
+ FButtonUp.Enabled := True
+ else
+ begin
+ FUp := False;
+ if Assigned(FTimer) then
+ FTimer.Enabled := False;
+ end;
+ if FValue - FIncrement > FMinValue then
+ FButtonDown.Enabled := True
+ else
+ begin
+ FDown := False;
+ if Assigned(FTimer) then
+ FTimer.Enabled := False;
+ end;
+end;
+
+function TfpgSpinEditFloat.GetEditBackgroundColor: TfpgColor;
+begin
+ Result := FEdit.BackgroundColor;
+end;
+
+function TfpgSpinEditFloat.GetTextColor: TfpgColor;
+begin
+ Result := FEdit.TextColor;
+end;
+
+function TfpgSpinEditFloat.GetNegativeColor: TfpgColor;
+begin
+ Result := FEdit.NegativeColor;
+end;
+
+function TfpgSpinEditFloat.GetFontDesc: string;
+begin
+ Result := FEdit.FontDesc;
+end;
+
+function TfpgSpinEditFloat.GetDecimals: integer;
+begin
+ Result := FEdit.Decimals;
+end;
+
+function TfpgSpinEditFloat.GetFixedDecimals: Boolean;
+begin
+ Result := FEdit.FixedDecimals;
+end;
+
+procedure TfpgSpinEditFloat.SetEditBackgroundColor(const AValue: Tfpgcolor);
+begin
+ if FEdit.BackgroundColor <> AValue then
+ FEdit.BackgroundColor := AValue;
+end;
+
+procedure TfpgSpinEditFloat.SetTextColor(const AValue: Tfpgcolor);
+begin
+ if FEdit.OldColor <> AValue then
+ FEdit.OldColor := AValue;
+end;
+
+procedure TfpgSpinEditFloat.SetNegativeColor(const AValue: Tfpgcolor);
+begin
+ if FEdit.NegativeColor <> AValue then
+ FEdit.NegativeColor := AValue;
+end;
+
+procedure TfpgSpinEditFloat.SetFontDesc(const AValue: string);
+begin
+ if FEdit.FontDesc <> AValue then
+ begin
+ FEdit.FontDesc := AValue;
+ if Height < FEdit.Height then
+ begin
+ Height := FEdit.Height;
+ FButtonUp.Height := Height div 2;
+ FButtonDown.Height := Height div 2;
+ FButtonDown.Top := FButtonUp.Height + 1;
+ end;
+ end;
+end;
+
+procedure TfpgSpinEditFloat.SetMaxValue(const AValue: extended);
+begin
+ if (FMaxValue <> AValue) and (AValue > FMinValue) then
+ begin
+ FMaxValue := AValue;
+ if FValue > FMaxValue then
+ begin
+ FValue := FMaxValue;
+ FEdit.Value := FValue;
+ end;
+ EnableButtons;
+ end;
+end;
+
+procedure TfpgSpinEditFloat.SetMinValue(const AValue: extended);
+begin
+ if (FMinValue <> AValue) and (AValue < FMinValue) then
+ begin
+ FMinValue := AValue;
+ if FValue < FMinValue then
+ begin
+ FValue := FMinValue;
+ FEdit.Value := FValue;
+ end;
+ EnableButtons;
+ end;
+end;
+
+procedure TfpgSpinEditFloat.SetIncrement(const AValue: extended);
+begin
+ if FIncrement <> AValue then
+ FIncrement := AValue;
+end;
+
+procedure TfpgSpinEditFloat.SetValue(const AValue: extended);
+begin
+ if (FValue <> AValue) and (AValue <= FMaxValue) and (AValue >= FMinValue) then
+ begin
+ FValue := AValue;
+ FEdit.Value := FValue;
+ EnableButtons;
+ end;
+end;
+
+procedure TfpgSpinEditFloat.SetDecimals(const AValue: integer);
+begin
+ if AValue < 0 then
+ Exit; // =>
+ if FEdit.Decimals <> AValue then
+ FEdit.Decimals := AValue;
+end;
+
+procedure TfpgSpinEditFloat.SetFixedDecimals(const AValue: Boolean);
+begin
+ if FEdit.FixedDecimals <> AValue then
+ FEdit.FixedDecimals := AValue;
+end;
+
+procedure TfpgSpinEditFloat.ButtonUpClick(Sender: TObject);
+begin
+ if FValue + FIncrement <= FMaxValue then
+ begin
+ FValue := FValue + FIncrement;
+ FEdit.Value := FValue;
+ end;
+ EnableButtons;
+end;
+
+procedure TfpgSpinEditFloat.ButtonDownClick(Sender: TObject);
+begin
+ if FValue - FIncrement >= FMinValue then
+ begin
+ FValue := FValue - FIncrement;
+ FEdit.Value := FValue;
+ end;
+ EnableButtons;
+end;
+
+procedure TfpgSpinEditFloat.ButtonUpMouseDown(Sender: TObject; AButton: TMouseButton; AShift: TShiftState; const AMousePos: TPoint);
+begin
+ FUp := True;
+ FTimer.Enabled := True;
+end;
+
+procedure TfpgSpinEditFloat.ButtonUpMouseUp(Sender: TObject; AButton: TMouseButton; AShift: TShiftState; const AMousePos: TPoint);
+begin
+ FUp := False;
+ if Assigned(FTimer) then
+ FTimer.Enabled := False;
+ if (FEdit.Value + FIncrement) > FMaxValue then
+ FButtonUp.Enabled := False;
+end;
+
+procedure TfpgSpinEditFloat.ButtonDownMouseDown(Sender: TObject; AButton: TMouseButton; AShift: TShiftState; const AMousePos: TPoint);
+begin
+ FDown := True;
+ FTimer.Enabled := True;
+end;
+
+procedure TfpgSpinEditFloat.ButtonDownMouseUp(Sender: TObject; AButton: TMouseButton; AShift: TShiftState; const AMousePos: TPoint);
+begin
+ FDown := False;
+ if Assigned(FTimer) then
+ FTimer.Enabled := False;
+ if (FEdit.Value - FIncrement) < FMinValue then
+ FButtonDown.Enabled := False;
+end;
+
+procedure TfpgSpinEditFloat.EditKeyPress(Sender: TObject; var keycode: word; var shiftstate: TShiftState; var consumed: Boolean);
+begin
+ if (KeyCode = KeyReturn) or (KeyCode = KeyPEnter) then
+ if FEdit.Text = '' then
+ begin
+ FValue := 0.0;
+ FEdit.Value := FValue;
+ end
+ else if (StrToFloat(FEdit.Text) <= FMaxValue) and (StrToFloat(FEdit.Text) >= FMinValue) then
+ FValue := StrToFloat(FEdit.Text)
+ else
+ FEdit.Value := FValue;
+
+ if KeyCode = KeyUp then
+ if FEdit.Value + Increment <= FMaxValue then
+ begin
+ FValue := FValue + FIncrement;
+ FEdit.Value := FValue;
+ end;
+
+ if KeyCode = KeyDown then
+ if FEdit.Value - Increment >= FMinValue then
+ begin
+ FValue := FValue - FIncrement;
+ FEdit.Value := FValue;
+ end;
+
+ if KeyCode = KeyPageUp then
+ begin
+ FValue := FMaxValue;
+ FEdit.Value := FValue;
+ end;
+
+ if KeyCode = KeyPageDown then
+ begin
+ FValue := FMinValue;
+ FEdit.Value := FValue;
+ end;
+
+ EnableButtons;
+end;
+
+procedure TfpgSpinEditFloat.EditExit(Sender: TObject);
+begin
+ if FEdit.Text = '' then
+ begin
+ FValue := 0.0;
+ FEdit.Value := FValue;
+ end
+ else if (StrToFloat(FEdit.Text) <= FMaxValue) and (StrToFloat(FEdit.Text) >= FMinValue) then
+ FValue := StrToFloat(FEdit.Text)
+ else
+ FEdit.Value := FValue;
+ EnableButtons;
+end;
+
+procedure TfpgSpinEditFloat.TimerStep(Sender: TObject);
+begin
+ if FUp then
+ if FValue + FIncrement <= FMaxValue then
+ begin
+ Value := FValue + FIncrement;
+ FEdit.Value := FValue;
+ end;
+ if FDown then
+ if FValue - FIncrement >= FMinValue then
+ begin
+ FValue := FValue - FIncrement;
+ FEdit.Value := FValue;
+ end;
+ EnableButtons;
+end;
+
+constructor TfpgSpinEditFloat.Create(AOwner: TComponent);
+begin
+ inherited Create(AOwner);
+
+ FEdit := CreateEditFloat(Self, 0, 0, Width - FButtonWidth, Height, False, 2);
+
+ FMaxValue := 100.0;
+ FMinValue := 0.0;
+ FIncrement := 1.0;
+ FValue := FMinValue;
+ FUp := False;
+ FDown := False;
+
+ FEdit.Decimals := 1;
+ FEdit.Value := FValue;
+
+ FButtonUp.OnClick := @ButtonUpClick;
+ FButtonDown.OnClick := @ButtonDownClick;
+ FButtonUp.OnMouseDown := @ButtonUpMouseDown;
+ FButtonUp.OnMouseUp := @ButtonUpMouseUp;
+ FButtonDown.OnMouseDown := @ButtonDownMouseDown;
+ FButtonDown.OnMouseUp := @ButtonDownMouseUp;
+ FEdit.OnKeyPress := @EditKeyPress;
+ FEdit.OnExit := @EditExit;
+ FTimer.OnTimer := @TimerStep;
+ EnableButtons;
+end;
+
+
+{ TfpgSpinEdit }
+
+procedure TfpgSpinEdit.EnableButtons;
+begin
+ if FValue + FIncrement < FMaxValue then
+ FButtonUp.Enabled := True
+ else
+ begin
+ FUp := False;
+ if Assigned(FTimer) then
+ FTimer.Enabled := False;
+ end;
+ if FValue - FIncrement > FMinValue then
+ FButtonDown.Enabled := True
+ else
+ begin
+ FDown := False;
+ if Assigned(FTimer) then
+ FTimer.Enabled := False;
+ end;
+end;
+
+function TfpgSpinEdit.GetEditBackgroundColor: TfpgColor;
+begin
+ Result := FEdit.BackgroundColor;
+end;
+
+function TfpgSpinEdit.GetTextColor: TfpgColor;
+begin
+ Result := FEdit.TextColor;
+end;
+
+function TfpgSpinEdit.GetNegativeColor: TfpgColor;
+begin
+ Result := FEdit.NegativeColor;
+end;
+
+function TfpgSpinEdit.GetFontDesc: string;
+begin
+ Result := FEdit.FontDesc;
+end;
+
+procedure TfpgSpinEdit.SetEditBackgroundColor(const AValue: Tfpgcolor);
+begin
+ if FEdit.BackgroundColor <> AValue then
+ FEdit.BackgroundColor := AValue;
+end;
+
+procedure TfpgSpinEdit.SetTextColor(const AValue: Tfpgcolor);
+begin
+ if FEdit.OldColor <> AValue then
+ FEdit.OldColor := AValue;
+end;
+
+procedure TfpgSpinEdit.SetNegativeColor(const AValue: Tfpgcolor);
+begin
+ if FEdit.NegativeColor <> AValue then
+ FEdit.NegativeColor := AValue;
+end;
+
+procedure TfpgSpinEdit.SetFontDesc(const AValue: string);
+begin
+ if FEdit.FontDesc <> AValue then
+ begin
+ FEdit.FontDesc := AValue;
+ if Height < FEdit.Height then
+ begin
+ Height := FEdit.Height;
+ FButtonUp.Height := Height div 2;
+ FButtonDown.Height := Height div 2;
+ FButtonDown.Top := FButtonUp.Height + 1;
+ end;
+ end;
+end;
+
+procedure TfpgSpinEdit.SetMaxValue(const AValue: integer);
+begin
+ if (FMaxValue <> AValue) and (AValue > FMinValue) then
+ begin
+ FMaxValue := AValue;
+ if FValue > FMaxValue then
+ begin
+ FValue := FMaxValue;
+ FEdit.Value := FValue;
+ ;
+ end;
+ EnableButtons;
+ end;
+end;
+
+procedure TfpgSpinEdit.SetMinValue(const AValue: integer);
+begin
+ if (FMinValue <> AValue) and (AValue < FMaxValue) then
+ begin
+ FMinValue := AValue;
+ if FValue < FMinValue then
+ begin
+ FValue := FMinValue;
+ FEdit.Value := FValue;
+ ;
+ end;
+ EnableButtons;
+ end;
+end;
+
+procedure TfpgSpinEdit.SetIncrement(const AValue: integer);
+begin
+ if FIncrement <> AValue then
+ FIncrement := AValue;
+end;
+
+procedure TfpgSpinEdit.SetValue(const AValue: integer);
+begin
+ if (FValue <> AValue) and (AValue <= FMaxValue) and (AValue >= FMinValue) then
+ begin
+ FValue := AValue;
+ FEdit.Value := FValue;
+ EnableButtons;
+ end;
+end;
+
+procedure TfpgSpinEdit.ButtonUpClick(Sender: TObject);
+begin
+ if FValue + FIncrement <= FMaxValue then
+ begin
+ Inc(FValue, FIncrement);
+ FEdit.Value := FValue;
+ end;
+ EnableButtons;
+end;
+
+procedure TfpgSpinEdit.ButtonDownClick(Sender: TObject);
+begin
+ if FValue - FIncrement >= FMinValue then
+ begin
+ Dec(FValue, FIncrement);
+ FEdit.Value := FValue;
+ end;
+ EnableButtons;
+end;
+
+procedure TfpgSpinEdit.ButtonUpMouseDown(Sender: TObject; AButton: TMouseButton; AShift: TShiftState; const AMousePos: TPoint);
+begin
+ FUp := True;
+ FTimer.Enabled := True;
+end;
+
+procedure TfpgSpinEdit.ButtonUpMouseUp(Sender: TObject; AButton: TMouseButton; AShift: TShiftState; const AMousePos: TPoint);
+begin
+ FUp := False;
+ if Assigned(FTimer) then
+ FTimer.Enabled := False;
+ if (FEdit.Value + FIncrement) > FMaxValue then
+ FButtonUp.Enabled := False;
+end;
+
+procedure TfpgSpinEdit.ButtonDownMouseDown(Sender: TObject; AButton: TMouseButton; AShift: TShiftState; const AMousePos: TPoint);
+begin
+ FDown := True;
+ FTimer.Enabled := True;
+end;
+
+procedure TfpgSpinEdit.ButtonDownMouseUp(Sender: TObject; AButton: TMouseButton; AShift: TShiftState; const AMousePos: TPoint);
+begin
+ FDown := False;
+ if Assigned(FTimer) then
+ FTimer.Enabled := False;
+ if (FEdit.Value - FIncrement) < FMinValue then
+ FButtonDown.Enabled := False;
+end;
+
+procedure TfpgSpinEdit.EditKeyPress(Sender: TObject; var keycode: word; var shiftstate: TShiftState; var consumed: Boolean);
+begin
+ if (KeyCode = KeyReturn) or (KeyCode = KeyPEnter) then
+ if FEdit.Text = '' then
+ begin
+ FValue := 0;
+ FEdit.Value := FValue;
+ end
+ else if (StrToInt(FEdit.Text) <= FMaxValue) and (StrToInt(FEdit.Text) >= FMinValue) then
+ FValue := FEdit.Value
+ else
+ FEdit.Value := FValue;
+
+ if KeyCode = KeyUp then
+ if FEdit.Value + Increment <= FMaxValue then
+ begin
+ Inc(FValue, FIncrement);
+ FEdit.Value := FValue;
+ end;
+
+ if KeyCode = KeyDown then
+ if FEdit.Value - Increment >= FMinValue then
+ begin
+ Dec(FValue, FIncrement);
+ FEdit.Value := FValue;
+ end;
+
+ if KeyCode = KeyPageUp then
+ begin
+ FValue := FMaxValue;
+ FEdit.Value := FValue;
+ end;
+
+ if KeyCode = KeyPageDown then
+ begin
+ FValue := FMinValue;
+ FEdit.Value := FValue;
+ end;
+
+ EnableButtons;
+end;
+
+procedure TfpgSpinEdit.EditExit(Sender: TObject);
+begin
+ if FEdit.Text = '' then
+ begin
+ FValue := 0;
+ FEdit.Value := FValue;
+ end
+ else if (StrToInt(FEdit.Text) <= FMaxValue) and (StrToInt(FEdit.Text) >= FMinValue) then
+ FValue := FEdit.Value
+ else
+ FEdit.Value := FValue;
+ EnableButtons;
+end;
+
+procedure TfpgSpinEdit.TimerStep(Sender: TObject);
+begin
+ if FUp then
+ if FValue + FIncrement <= FMaxValue then
+ begin
+ Inc(FValue, FIncrement);
+ FEdit.Value := FValue;
+ end;
+ if FDown then
+ if FValue - FIncrement >= FMinValue then
+ begin
+ Dec(FValue, FIncrement);
+ FEdit.Value := FValue;
+ end;
+ EnableButtons;
+end;
+
+constructor TfpgSpinEdit.Create(AOwner: TComponent);
+begin
+ inherited Create(AOwner);
+
+ FEdit := CreateEditInteger(Self, 0, 0, Width - FButtonWidth, Height);
+
+ FMaxValue := 100;
+ FMinValue := 0;
+ FIncrement := 1;
+ FValue := FMinValue;
+ FUp := False;
+ FDown := False;
+
+ FEdit.Value := FValue;
+
+ FButtonUp.OnClick := @ButtonUpClick;
+ FButtonDown.OnClick := @ButtonDownClick;
+ FButtonUp.OnMouseDown := @ButtonUpMouseDown;
+ FButtonUp.OnMouseUp := @ButtonUpMouseUp;
+ FButtonDown.OnMouseDown := @ButtonDownMouseDown;
+ FButtonDown.OnMouseUp := @ButtonDownMouseUp;
+ FEdit.OnKeyPress := @EditKeyPress;
+ FEdit.OnExit := @EditExit;
+ FTimer.OnTimer := @TimerStep;
+ EnableButtons;
+end;
+
+end.
+