diff options
author | graemeg <graemeg@ae50a9b5-8222-0410-bf8d-8a13f76226bf> | 2008-10-03 14:45:14 +0000 |
---|---|---|
committer | graemeg <graemeg@ae50a9b5-8222-0410-bf8d-8a13f76226bf> | 2008-10-03 14:45:14 +0000 |
commit | ff87ebe7afdf27042b7963ca04246963adbdcaab (patch) | |
tree | 7291dd44940bfce41b08eeaccc397e9e15a061b3 | |
parent | 7a6030c56def0f368a5208763a78dce163cb0bc4 (diff) | |
download | fpGUI-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.lpk | 8 | ||||
-rw-r--r-- | src/corelib/gdi/fpgui_toolkit.pas | 2 | ||||
-rw-r--r-- | src/corelib/x11/fpgui_toolkit.lpk | 6 | ||||
-rw-r--r-- | src/corelib/x11/fpgui_toolkit.pas | 2 | ||||
-rw-r--r-- | src/gui/fpg_button.pas | 2 | ||||
-rw-r--r-- | src/gui/fpg_edit.pas | 56 | ||||
-rw-r--r-- | src/gui/fpg_popupcalendar.pas | 8 | ||||
-rw-r--r-- | src/gui/fpg_spinedit.pas | 881 |
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. + |