815 lines
23 KiB
ObjectPascal
815 lines
23 KiB
ObjectPascal
// SPDX-License-Identifier: LGPL-3.0-linking-exception
|
|
{
|
|
Created by BGRA Controls Team
|
|
Dibo, Circular, lainz (007) and contributors.
|
|
For detailed information see readme.txt
|
|
|
|
Site: https://sourceforge.net/p/bgra-controls/
|
|
Wiki: http://wiki.lazarus.freepascal.org/BGRAControls
|
|
Forum: http://forum.lazarus.freepascal.org/index.php/board,46.0.html
|
|
}
|
|
{******************************* CONTRIBUTOR(S) ******************************
|
|
- Edivando S. Santos Brasil | mailedivando@gmail.com
|
|
(Compatibility with delphi VCL 11/2018)
|
|
|
|
***************************** END CONTRIBUTOR(S) *****************************}
|
|
unit BCTrackbarUpdown;
|
|
|
|
{$I bgracontrols.inc}
|
|
|
|
interface
|
|
|
|
uses
|
|
{$IFDEF FPC}LCLType, LResources,{$ENDIF}
|
|
Classes, SysUtils, Types, Forms, Controls, Graphics, Dialogs,
|
|
{$IFNDEF FPC}BGRAGraphics, GraphType, FPImage, {$ENDIF}
|
|
ExtCtrls, BGRABitmap, BCBaseCtrls, BCTypes;
|
|
|
|
type
|
|
TTrackBarUpDownChangeEvent = procedure(Sender: TObject; AByUser: boolean) of object;
|
|
|
|
{ TCustomBCTrackbarUpdown }
|
|
|
|
TCustomBCTrackbarUpdown = class(TBCCustomControl)
|
|
protected
|
|
FHandlingUserInput: boolean;
|
|
FLongTimeInterval,FShortTimeInterval: integer;
|
|
FMinValue,FMaxValue,FIncrement,FValue: integer;
|
|
FAllowNegativeValues: boolean;
|
|
FStartNegativeValue: boolean;
|
|
FBarExponent: single;
|
|
FSelStart,FSelLength: integer;
|
|
FEmptyText: boolean;
|
|
FBarClick,FUpClick,FDownClick: boolean;
|
|
|
|
FTimer: TTimer;
|
|
FOnChange: TTrackBarUpDownChangeEvent;
|
|
FBCBorder: TBCBorder;
|
|
FBCRounding: TBCRounding;
|
|
FBCBackground: TBCBackground;
|
|
FBCButtonBackground,FBCButtonDownBackground: TBCBackground;
|
|
FArrowColor: TColor;
|
|
FHasTrackBar: boolean;
|
|
|
|
FCanvasScaling: double;
|
|
FTextLeft: Integer;
|
|
FBarLeft,FBarTop,FBarWidth,FBarHeight: Integer;
|
|
FUpDownWidth: Integer;
|
|
FUpDownLeft: Integer;
|
|
FDownButtonTop: integer;
|
|
function GetValue: integer;
|
|
procedure SetAllowNegativeValues(AValue: boolean);
|
|
procedure SetArrowColor(AValue: TColor);
|
|
procedure SetHasTrackBar(AValue: boolean);
|
|
procedure SetBarExponent(AValue: single);
|
|
procedure SetBCBackground(AValue: TBCBackground);
|
|
procedure SetBCBorder(AValue: TBCBorder);
|
|
procedure SetBCButtonBackground(AValue: TBCBackground);
|
|
procedure SetBCButtonDownBackground(AValue: TBCBackground);
|
|
procedure SetBCRounding(AValue: TBCRounding);
|
|
procedure OnChangeProperty({%H-}Sender: TObject; {%H-}AData: PtrInt);
|
|
procedure Timer({%H-}Sender: TObject);
|
|
procedure RenderOnBitmap(ABitmap: TBGRABitmap);
|
|
procedure DrawControl; override;
|
|
procedure DoSelectAll;
|
|
function GetText: string; virtual;
|
|
procedure SetText(AValue: string); virtual;
|
|
procedure EnabledChanged; override;
|
|
procedure NotifyChange; virtual;
|
|
procedure SetIncrement(AValue: integer);
|
|
procedure SetMaxValue(AValue: integer);
|
|
procedure SetMinValue(AValue: integer);
|
|
procedure SetValue(AValue: integer);
|
|
function ValueToBarPos(AValue: integer): integer;
|
|
function BarPosToValue(ABarPos: integer): integer;
|
|
procedure MouseDown(Button: TMouseButton; {%H-}Shift: TShiftState; X, Y: Integer); override;
|
|
procedure MouseMove(Shift: TShiftState; X, Y: Integer); override;
|
|
procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
|
|
function DoMouseWheel(Shift: TShiftState; WheelDelta: Integer; MousePos: TPoint): Boolean; override;
|
|
procedure UTF8KeyPress(var UTF8Key: {$IFDEF FPC}TUTF8Char{$ELSE}String{$ENDIF}); override;
|
|
procedure DoEnter; override;
|
|
procedure DoExit; override;
|
|
public
|
|
constructor Create(AOwner: TComponent); override;
|
|
procedure SelectAll;
|
|
function RemoveSelection: boolean; //returns True if there was a selection to be removed
|
|
procedure DelayTimer; //use after the program has been busy updating something according to the value of this component
|
|
procedure SetFocus; override;
|
|
destructor Destroy; override;
|
|
property Border: TBCBorder read FBCBorder write SetBCBorder;
|
|
property Background: TBCBackground read FBCBackground write SetBCBackground;
|
|
property ButtonBackground: TBCBackground read FBCButtonBackground write SetBCButtonBackground;
|
|
property ButtonDownBackground: TBCBackground read FBCButtonDownBackground write SetBCButtonDownBackground;
|
|
property Rounding: TBCRounding read FBCRounding write SetBCRounding;
|
|
property ArrowColor: TColor read FArrowColor write SetArrowColor;
|
|
property HasTrackBar: boolean read FHasTrackBar write SetHasTrackBar;
|
|
|
|
property AllowNegativeValues: boolean read FAllowNegativeValues write SetAllowNegativeValues;
|
|
property BarExponent: single read FBarExponent write SetBarExponent;
|
|
property Increment: integer read FIncrement write SetIncrement;
|
|
property LongTimeInterval: integer read FLongTimeInterval write FLongTimeInterval;
|
|
property MinValue: integer read FMinValue write SetMinValue;
|
|
property MaxValue: integer read FMaxValue write SetMaxValue;
|
|
property OnChange: TTrackBarUpDownChangeEvent read FOnChange write FOnChange;
|
|
property Text: string read GetText write SetText;
|
|
property Value: integer read GetValue write SetValue;
|
|
property SelStart: integer read FSelStart;
|
|
property SelLength: integer read FSelLength;
|
|
property ShortTimeInterval: integer read FShortTimeInterval write FShortTimeInterval;
|
|
end;
|
|
|
|
TBCTrackbarUpdown = class(TCustomBCTrackbarUpdown)
|
|
published
|
|
property AllowNegativeValues;
|
|
property BarExponent;
|
|
property Increment;
|
|
property LongTimeInterval;
|
|
property MinValue;
|
|
property MaxValue;
|
|
property OnChange;
|
|
property Value;
|
|
property SelStart;
|
|
property SelLength;
|
|
property ShortTimeInterval;
|
|
property Background;
|
|
property ButtonBackground;
|
|
property ButtonDownBackground;
|
|
property Border;
|
|
property Rounding;
|
|
property Font;
|
|
property HasTrackBar;
|
|
property ArrowColor;
|
|
|
|
//inherited
|
|
property Align;
|
|
property Anchors;
|
|
property BorderSpacing;
|
|
property ChildSizing;
|
|
{$IFDEF FPC} //#
|
|
property OnGetDockCaption;
|
|
{$ENDIF}
|
|
property ClientHeight;
|
|
property ClientWidth;
|
|
property Constraints;
|
|
property DockSite;
|
|
property DragCursor;
|
|
property DragKind;
|
|
property DragMode;
|
|
property Enabled;
|
|
property ParentShowHint;
|
|
property PopupMenu;
|
|
property ShowHint;
|
|
property TabOrder;
|
|
property TabStop;
|
|
property UseDockManager default True;
|
|
property Visible;
|
|
property OnClick;
|
|
property OnContextPopup;
|
|
property OnDockDrop;
|
|
property OnDockOver;
|
|
property OnDblClick;
|
|
property OnDragDrop;
|
|
property OnDragOver;
|
|
property OnEndDock;
|
|
property OnEndDrag;
|
|
property OnEnter;
|
|
property OnExit;
|
|
property OnGetSiteInfo;
|
|
property OnMouseDown;
|
|
property OnMouseEnter;
|
|
property OnMouseLeave;
|
|
property OnMouseMove;
|
|
property OnMouseUp;
|
|
property OnResize;
|
|
property OnStartDock;
|
|
property OnStartDrag;
|
|
property OnUnDock;
|
|
end;
|
|
|
|
{$IFDEF FPC}procedure Register;{$ENDIF}
|
|
|
|
implementation
|
|
|
|
uses BGRABitmapTypes, Math, BCTools;
|
|
|
|
{$IFDEF FPC}
|
|
procedure Register;
|
|
begin
|
|
RegisterComponents('BGRA Controls', [TBCTrackbarUpdown]);
|
|
end;
|
|
{$ENDIF}
|
|
|
|
{ TCustomBCTrackbarUpdown }
|
|
|
|
function TCustomBCTrackbarUpdown.GetText: string;
|
|
begin
|
|
if FEmptyText then
|
|
begin
|
|
if FStartNegativeValue then
|
|
result := '-'
|
|
else
|
|
result := '';
|
|
end else
|
|
result := IntToStr(FValue);
|
|
end;
|
|
|
|
procedure TCustomBCTrackbarUpdown.SetText(AValue: string);
|
|
var errPos,tempValue: integer;
|
|
txt: string;
|
|
prevActualValue: integer;
|
|
begin
|
|
if trim(AValue) = '' then
|
|
begin
|
|
if not FEmptyText or FStartNegativeValue then
|
|
begin
|
|
FEmptyText:= true;
|
|
FStartNegativeValue:= false;
|
|
Invalidate;
|
|
end;
|
|
exit;
|
|
end;
|
|
prevActualValue:= Value;
|
|
val(AValue,tempValue,errPos);
|
|
if errPos = 0 then
|
|
begin
|
|
if tempValue > FMaxValue then tempValue := FMaxValue;
|
|
if (tempValue < 0) and (tempValue < FMinValue) then tempValue:= FMinValue;
|
|
if (FValue = tempValue) and not FEmptyText then exit;
|
|
FValue := tempValue;
|
|
FEmptyText:= false;
|
|
end else
|
|
if (AValue = '-') and AllowNegativeValues then
|
|
begin
|
|
FEmptyText:= true;
|
|
FStartNegativeValue:= true;
|
|
end;
|
|
txt := Text;
|
|
if FSelStart > length(txt) then FSelStart := length(txt);
|
|
if FSelStart+FSelLength > length(txt) then FSelLength:= length(txt)-FSelStart;
|
|
Repaint;
|
|
if Value <> prevActualValue then NotifyChange;
|
|
end;
|
|
|
|
procedure TCustomBCTrackbarUpdown.EnabledChanged;
|
|
begin
|
|
inherited EnabledChanged;
|
|
Invalidate;
|
|
end;
|
|
|
|
procedure TCustomBCTrackbarUpdown.NotifyChange;
|
|
begin
|
|
if Assigned(FOnChange) then FOnChange(self, FHandlingUserInput);
|
|
end;
|
|
|
|
procedure TCustomBCTrackbarUpdown.SetIncrement(AValue: integer);
|
|
begin
|
|
if FIncrement=AValue then Exit;
|
|
FIncrement:=AValue;
|
|
end;
|
|
|
|
procedure TCustomBCTrackbarUpdown.SetMaxValue(AValue: integer);
|
|
begin
|
|
if not AllowNegativeValues and (AValue < 0) then AValue := 0;
|
|
if FMaxValue=AValue then Exit;
|
|
FMaxValue:=AValue;
|
|
if FMaxValue < FMinValue then FMinValue := FMaxValue;
|
|
if AValue > FMaxValue then FMaxValue:= AValue;
|
|
Invalidate;
|
|
end;
|
|
|
|
procedure TCustomBCTrackbarUpdown.SetMinValue(AValue: integer);
|
|
begin
|
|
if not AllowNegativeValues and (AValue < 0) then AValue := 0;
|
|
if FMinValue=AValue then Exit;
|
|
FMinValue:=AValue;
|
|
if FMinValue > FMaxValue then FMaxValue := FMinValue;
|
|
if AValue < FMinValue then FMinValue:= AValue;
|
|
Invalidate;
|
|
end;
|
|
|
|
procedure TCustomBCTrackbarUpdown.SetValue(AValue: integer);
|
|
begin
|
|
if AValue < FMinValue then AValue := FMinValue;
|
|
if AValue > FMaxValue then AValue := FMaxValue;
|
|
if FValue=AValue then Exit;
|
|
FValue:=AValue;
|
|
FEmptyText:= false;
|
|
DoSelectAll;
|
|
Invalidate;
|
|
NotifyChange;
|
|
end;
|
|
|
|
procedure TCustomBCTrackbarUpdown.SetArrowColor(AValue: TColor);
|
|
begin
|
|
if FArrowColor=AValue then Exit;
|
|
FArrowColor:=AValue;
|
|
Invalidate;
|
|
end;
|
|
|
|
procedure TCustomBCTrackbarUpdown.SetHasTrackBar(AValue: boolean);
|
|
begin
|
|
if FHasTrackBar=AValue then Exit;
|
|
FHasTrackBar:=AValue;
|
|
Invalidate;
|
|
end;
|
|
|
|
procedure TCustomBCTrackbarUpdown.SetAllowNegativeValues(AValue: boolean);
|
|
var
|
|
changeVal: Boolean;
|
|
begin
|
|
if FAllowNegativeValues=AValue then Exit;
|
|
FAllowNegativeValues:=AValue;
|
|
if not FAllowNegativeValues then
|
|
begin
|
|
if (FMinValue < 0) or (FValue < 0) or (FMaxValue < 0) then
|
|
begin
|
|
if FMinValue < 0 then FMinValue := 0;
|
|
if FValue < 0 then
|
|
begin
|
|
FValue := 0;
|
|
changeVal := true;
|
|
end else changeVal := false;
|
|
if FMaxValue < 0 then FMaxValue:= 0;
|
|
Invalidate;
|
|
if changeVal then NotifyChange;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function TCustomBCTrackbarUpdown.GetValue: integer;
|
|
begin
|
|
if FValue < FMinValue then result := FMinValue else
|
|
result := FValue;
|
|
end;
|
|
|
|
procedure TCustomBCTrackbarUpdown.SetBarExponent(AValue: single);
|
|
begin
|
|
if AValue <= 0 then exit;
|
|
if FBarExponent=AValue then Exit;
|
|
FBarExponent:=AValue;
|
|
Invalidate;
|
|
end;
|
|
|
|
procedure TCustomBCTrackbarUpdown.SetBCBackground(AValue: TBCBackground);
|
|
begin
|
|
if FBCBackground=AValue then Exit;
|
|
FBCBackground.Assign(AValue);
|
|
end;
|
|
|
|
procedure TCustomBCTrackbarUpdown.SetBCBorder(AValue: TBCBorder);
|
|
begin
|
|
if FBCBorder=AValue then Exit;
|
|
FBCBorder.Assign(AValue);
|
|
end;
|
|
|
|
procedure TCustomBCTrackbarUpdown.SetBCButtonBackground(AValue: TBCBackground);
|
|
begin
|
|
if FBCButtonBackground=AValue then Exit;
|
|
FBCButtonBackground.Assign(AValue);
|
|
end;
|
|
|
|
procedure TCustomBCTrackbarUpdown.SetBCButtonDownBackground(
|
|
AValue: TBCBackground);
|
|
begin
|
|
if FBCButtonDownBackground=AValue then Exit;
|
|
FBCButtonDownBackground.Assign(AValue);
|
|
end;
|
|
|
|
procedure TCustomBCTrackbarUpdown.SetBCRounding(AValue: TBCRounding);
|
|
begin
|
|
if FBCRounding=AValue then Exit;
|
|
FBCRounding.Assign(AValue);
|
|
end;
|
|
|
|
procedure TCustomBCTrackbarUpdown.OnChangeProperty(Sender: TObject;
|
|
AData: PtrInt);
|
|
begin
|
|
RenderControl;
|
|
Invalidate;
|
|
end;
|
|
|
|
procedure TCustomBCTrackbarUpdown.Timer(Sender: TObject);
|
|
begin
|
|
FHandlingUserInput:= true;
|
|
if FUpClick then
|
|
begin
|
|
Value := Value + Increment;
|
|
end else
|
|
if FDownClick then
|
|
Value := Value - Increment;
|
|
FHandlingUserInput:= false;
|
|
FTimer.Interval := ShortTimeInterval;
|
|
end;
|
|
|
|
procedure TCustomBCTrackbarUpdown.RenderOnBitmap(ABitmap: TBGRABitmap);
|
|
var bordercolor,fgcolor,btntext: TBGRAPixel;
|
|
x,y,ty,barx: integer;
|
|
s: TSize;
|
|
midy: integer;
|
|
midx: single;
|
|
beforeSel,inSel,afterSel: string;
|
|
bounds,fullBounds: TRect;
|
|
begin
|
|
fullbounds := rect(0,0,ABitmap.Width,ABitmap.Height);
|
|
bounds := fullBounds;
|
|
CalculateInnerRect(Border, bounds);
|
|
ty := bounds.bottom-bounds.top-2;
|
|
FTextLeft := bounds.left+1+((ty+5) div 10);
|
|
FUpDownWidth := (ty*3+3) div 5;
|
|
FUpDownLeft := bounds.right-FUpDownWidth;
|
|
|
|
FBarLeft := bounds.left+1;
|
|
if FHasTrackBar then
|
|
begin
|
|
FBarHeight := (bounds.bottom-bounds.top+3) div 5+1;
|
|
FBarWidth := bounds.right-FUpDownWidth-FBarHeight+1-FBarLeft;
|
|
if (Rounding.RoundX > 1) and (Rounding.RoundY > 1) then
|
|
FBarLeft := FBarLeft +FBarHeight+1;
|
|
end else
|
|
begin
|
|
FBarWidth := 0;
|
|
FBarHeight := 2;
|
|
end;
|
|
FBarTop := bounds.bottom-FBarHeight;
|
|
|
|
midy := ABitmap.Height div 2;
|
|
FDownButtonTop := midy;
|
|
|
|
ABitmap.ClipRect := rect(fullbounds.left,fullbounds.top,FUpDownLeft+1,fullbounds.bottom);
|
|
RenderBackgroundAndBorder(fullbounds, Background, ABitmap, Rounding, Border);
|
|
|
|
bordercolor := ColorToBGRA(ColorToRGB(Border.Color),Border.ColorOpacity);
|
|
ABitmap.VertLine(FUpDownLeft,bounds.top,bounds.bottom-1,bordercolor,dmDrawWithTransparency);
|
|
|
|
if FUpClick then
|
|
begin
|
|
ABitmap.ClipRect := rect(FUpDownLeft+1,fullbounds.top,fullbounds.Right,midy);
|
|
RenderBackgroundAndBorder(fullbounds, ButtonDownBackground, ABitmap, Rounding, Border);
|
|
ABitmap.ClipRect := rect(FUpDownLeft+1,midy,fullbounds.Right,fullbounds.bottom);
|
|
RenderBackgroundAndBorder(fullbounds, ButtonBackground, ABitmap, Rounding, Border);
|
|
end else
|
|
if FDownClick then
|
|
begin
|
|
ABitmap.ClipRect := rect(FUpDownLeft+1,fullbounds.top,fullbounds.Right,midy+1);
|
|
RenderBackgroundAndBorder(fullbounds, ButtonBackground, ABitmap, Rounding, Border);
|
|
ABitmap.ClipRect := rect(FUpDownLeft+1,midy+1,fullbounds.Right,fullbounds.bottom);
|
|
RenderBackgroundAndBorder(fullbounds, ButtonDownBackground, ABitmap, Rounding, Border);
|
|
end else
|
|
begin
|
|
ABitmap.ClipRect := rect(FUpDownLeft+1,fullbounds.top,fullbounds.Right,fullbounds.bottom);
|
|
RenderBackgroundAndBorder(fullbounds, ButtonBackground, ABitmap, Rounding, Border);
|
|
end;
|
|
ABitmap.NoClip;
|
|
ABitmap.HorizLine(FUpDownLeft+1,midy,bounds.right-1,bordercolor,dmDrawWithTransparency);
|
|
|
|
ABitmap.FontQuality := fqFineAntialiasing;
|
|
ABitmap.FontName := Font.Name;
|
|
ABitmap.FontStyle := Font.Style;
|
|
ABitmap.FontHeight := ((ty-FBarHeight+1)*8+4) div 9;
|
|
fgcolor := Font.Color;
|
|
|
|
x := FTextLeft;
|
|
y := bounds.top+1;
|
|
if Focused then
|
|
begin
|
|
if SelStart = 0 then
|
|
begin
|
|
beforeSel := '';
|
|
inSel := Text;
|
|
end else
|
|
begin
|
|
beforeSel := copy(Text,1,SelStart);
|
|
inSel := copy(Text,SelStart+1,length(Text)-SelStart);
|
|
end;
|
|
if length(inSel)>SelLength then
|
|
begin
|
|
afterSel:= copy(inSel,SelLength+1,length(inSel)-SelLength);
|
|
inSel := copy(inSel,1,SelLength);
|
|
end else
|
|
afterSel := '';
|
|
ABitmap.TextOut(x,y,beforeSel,fgcolor);
|
|
inc(x, ABitmap.TextSize(beforeSel).cx);
|
|
if inSel = '' then ABitmap.SetVertLine(x,y,y+ABitmap.FontFullHeight-1,fgcolor)
|
|
else
|
|
begin
|
|
s := ABitmap.TextSize(inSel);
|
|
ABitmap.FillRect(x,y+1,x+s.cx,y+s.cy,ColorToRGB(clHighlight),dmSet);
|
|
ABitmap.TextOut(x,y,inSel,ColorToRGB(clHighlightText));
|
|
inc(x,s.cx);
|
|
end;
|
|
ABitmap.TextOut(x,y,afterSel,fgcolor);
|
|
end else
|
|
begin
|
|
if Enabled then
|
|
ABitmap.TextOut(x,y,Text,fgcolor)
|
|
else
|
|
ABitmap.TextOut(x,y,Text,BGRA(fgcolor.red,fgcolor.green,fgcolor.blue,fgcolor.alpha div 2));
|
|
end;
|
|
|
|
barx := ValueToBarPos(Value);
|
|
if FHasTrackBar then
|
|
ABitmap.FillPolyAntialias([PointF(barx,FBarTop),PointF(barx+FBarHeight,FBarTop+FBarHeight),
|
|
PointF(barx-FBarHeight,FBarTop+FBarHeight)],fgcolor);
|
|
midx := FUpDownLeft+(FUpDownWidth-1)/2;
|
|
btntext := FArrowColor;
|
|
ABitmap.FillPolyAntialias([PointF(FUpDownLeft+2,midy*4/5),PointF(midx,midy/5),PointF(FUpDownLeft+FUpDownWidth-3,midy*4/5)],btntext);
|
|
ABitmap.FillPolyAntialias([PointF(FUpDownLeft+2,midy*6/5),PointF(midx,ABitmap.Height-midy/5),PointF(FUpDownLeft+FUpDownWidth-3,midy*6/5)],btntext);
|
|
end;
|
|
|
|
function TCustomBCTrackbarUpdown.ValueToBarPos(AValue: integer): integer;
|
|
var t: single;
|
|
begin
|
|
if FMaxValue>FMinValue then
|
|
begin
|
|
t := (AValue-FMinValue)/(FMaxValue-FMinValue);
|
|
if t < 0 then t := 0;
|
|
if t > 1 then t := 1;
|
|
result := FBarLeft+round(power(t,1/FBarExponent)*(FBarWidth-1))
|
|
end
|
|
else
|
|
result := FBarLeft;
|
|
end;
|
|
|
|
function TCustomBCTrackbarUpdown.BarPosToValue(ABarPos: integer): integer;
|
|
var t: single;
|
|
begin
|
|
if FBarWidth > FBarLeft then
|
|
begin
|
|
t := (ABarPos-FBarLeft)/(FBarWidth-1);
|
|
if t < 0 then t := 0;
|
|
if t > 1 then t := 1;
|
|
result := round(power(t,FBarExponent)*(FMaxValue-FMinValue))+FMinValue
|
|
end
|
|
else
|
|
result := FMinValue;
|
|
end;
|
|
|
|
procedure TCustomBCTrackbarUpdown.MouseDown(Button: TMouseButton;
|
|
Shift: TShiftState; X, Y: Integer);
|
|
begin
|
|
X := round(X*FCanvasScaling);
|
|
Y := round(Y*FCanvasScaling);
|
|
if Button = mbLeft then
|
|
begin
|
|
FHandlingUserInput:= true;
|
|
if X >= FUpDownLeft then
|
|
begin
|
|
if Y > FDownButtonTop then
|
|
begin
|
|
FDownClick:= true;
|
|
Value := Value-Increment;
|
|
Invalidate;
|
|
FTimer.Interval := LongTimeInterval;
|
|
FTimer.Enabled:= true;
|
|
end else
|
|
if Y < FDownButtonTop then
|
|
begin
|
|
FUpClick:= true;
|
|
Value := Value+Increment;
|
|
Invalidate;
|
|
FTimer.Interval := LongTimeInterval;
|
|
FTimer.Enabled:= true;
|
|
end;
|
|
end else
|
|
if (Y >= Height-FBarHeight-1) and (FBarWidth>1) then
|
|
begin
|
|
FBarClick:= true;
|
|
Value := BarPosToValue(X);
|
|
Repaint;
|
|
end;
|
|
FHandlingUserInput:= false;
|
|
end;
|
|
if not Focused then
|
|
begin
|
|
SetFocus;
|
|
SelectAll;
|
|
end;
|
|
inherited MouseDown(Button, Shift, X, Y);
|
|
end;
|
|
|
|
procedure TCustomBCTrackbarUpdown.MouseMove(Shift: TShiftState; X, Y: Integer);
|
|
begin
|
|
inherited MouseMove(Shift, X, Y);
|
|
X := round(X*FCanvasScaling);
|
|
Y := round(Y*FCanvasScaling);
|
|
if FBarClick and (FBarWidth>1) then
|
|
begin
|
|
FHandlingUserInput:= true;
|
|
Value := BarPosToValue(X);
|
|
FHandlingUserInput:= false;
|
|
end;
|
|
end;
|
|
|
|
procedure TCustomBCTrackbarUpdown.MouseUp(Button: TMouseButton;
|
|
Shift: TShiftState; X, Y: Integer);
|
|
begin
|
|
inherited MouseUp(Button, Shift, X, Y);
|
|
X := round(X*FCanvasScaling);
|
|
Y := round(Y*FCanvasScaling);
|
|
if Button = mbLeft then
|
|
begin
|
|
if FBarClick then FBarClick:= false else
|
|
if FUpClick then
|
|
begin
|
|
FUpClick:= false;
|
|
Invalidate;
|
|
FTimer.Enabled:= false;
|
|
end else
|
|
if FDownClick then
|
|
begin
|
|
FDownClick:= false;
|
|
Invalidate;
|
|
FTimer.Enabled:= false;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function TCustomBCTrackbarUpdown.DoMouseWheel(Shift: TShiftState;
|
|
WheelDelta: Integer; MousePos: TPoint): Boolean;
|
|
begin
|
|
if Assigned(OnMouseWheel) or Assigned(OnMouseWheelDown) or Assigned(OnMouseWheelUp) then
|
|
begin
|
|
result := inherited DoMouseWheel(Shift, WheelDelta, MousePos);
|
|
exit;
|
|
end;
|
|
FHandlingUserInput:= true;
|
|
Value := Value + Increment*WheelDelta div 120;
|
|
FHandlingUserInput := false;
|
|
Invalidate;
|
|
result := true;
|
|
end;
|
|
|
|
procedure TCustomBCTrackbarUpdown.UTF8KeyPress(var UTF8Key: {$IFDEF FPC}TUTF8Char{$ELSE}String{$ENDIF});
|
|
var tempText: string;
|
|
begin
|
|
FHandlingUserInput:= true;
|
|
if UTF8Key = #8 then
|
|
begin
|
|
if not RemoveSelection and (SelStart > 0) then
|
|
begin
|
|
tempText := Text;
|
|
Dec(FSelStart);
|
|
Delete(tempText,SelStart+1,1);
|
|
Text := tempText;
|
|
Invalidate;
|
|
end;
|
|
UTF8Key:= #0;
|
|
end else
|
|
if (length(UTF8Key)=1) and ((UTF8Key[1] in['0'..'9']) or ((UTF8Key[1]='-') and (SelStart = 0))) then
|
|
begin
|
|
RemoveSelection;
|
|
tempText := Text;
|
|
Insert(UTF8Key,tempText,SelStart+1);
|
|
Text := tempText;
|
|
if FSelStart < length(Text) then inc(FSelStart);
|
|
Invalidate;
|
|
UTF8Key:= #0;
|
|
end;
|
|
FHandlingUserInput:= false;
|
|
end;
|
|
|
|
procedure TCustomBCTrackbarUpdown.DoEnter;
|
|
begin
|
|
inherited DoEnter;
|
|
Invalidate;
|
|
end;
|
|
|
|
procedure TCustomBCTrackbarUpdown.DoExit;
|
|
begin
|
|
inherited DoExit;
|
|
if FValue > FMaxValue then FValue := FMaxValue;
|
|
if FValue < FMinValue then FValue := FMinValue;
|
|
if FEmptyText then
|
|
begin
|
|
FEmptyText:= false;
|
|
SelectAll;
|
|
end;
|
|
Invalidate;
|
|
end;
|
|
|
|
procedure TCustomBCTrackbarUpdown.DrawControl;
|
|
var bmp: TBGRABitmap;
|
|
begin
|
|
FCanvasScaling:= GetCanvasScaleFactor;
|
|
bmp := TBGRABitmap.Create(round(Width*FCanvasScaling),round(Height*FCanvasScaling));
|
|
RenderOnBitmap(bmp);
|
|
bmp.Draw(Canvas,rect(0,0,Width,Height),False);
|
|
bmp.Free;
|
|
end;
|
|
|
|
constructor TCustomBCTrackbarUpdown.Create(AOwner: TComponent);
|
|
begin
|
|
inherited Create(AOwner);
|
|
with GetControlClassDefaultSize do
|
|
SetInitialBounds(0, 0, CX, CY);
|
|
FMinValue:= 0;
|
|
FMaxValue := 100;
|
|
FValue := 50;
|
|
FIncrement := 1;
|
|
FBarExponent:= 1;
|
|
FCanvasScaling:= 1;
|
|
FTimer := TTimer.Create(self);
|
|
FTimer.Enabled := false;
|
|
FTimer.OnTimer:=Timer;
|
|
FLongTimeInterval:= 400;
|
|
FShortTimeInterval:= 100;
|
|
FHasTrackBar:= true;
|
|
FBCBorder := TBCBorder.Create(self);
|
|
FBCBorder.Color := clWindowText;
|
|
FBCBorder.Width := 1;
|
|
FBCBorder.Style := bboSolid;
|
|
FBCBorder.OnChange := OnChangeProperty;
|
|
FBCRounding := TBCRounding.Create(self);
|
|
FBCRounding.RoundX := 1;
|
|
FBCRounding.RoundY := 1;
|
|
FBCRounding.OnChange := OnChangeProperty;
|
|
FBCBackground := TBCBackground.Create(self);
|
|
FBCBackground.Style := bbsColor;
|
|
FBCBackground.Color := clWindow;
|
|
FBCBackground.OnChange := OnChangeProperty;
|
|
FBCButtonBackground := TBCBackground.Create(self);
|
|
FBCButtonBackground.Style := bbsGradient;
|
|
FBCButtonBackground.Gradient1EndPercent := 50;
|
|
FBCButtonBackground.Gradient1.Point1YPercent := -50;
|
|
FBCButtonBackground.Gradient1.Point2YPercent := 50;
|
|
FBCButtonBackground.Gradient1.StartColor := clBtnShadow;
|
|
FBCButtonBackground.Gradient1.EndColor := clBtnFace;
|
|
FBCButtonBackground.Gradient2.Point1YPercent := 50;
|
|
FBCButtonBackground.Gradient2.Point2YPercent := 150;
|
|
FBCButtonBackground.Gradient2.StartColor := clBtnFace;
|
|
FBCButtonBackground.Gradient2.EndColor := clBtnShadow;
|
|
FBCButtonBackground.OnChange := OnChangeProperty;
|
|
FBCButtonDownBackground := TBCBackground.Create(self);
|
|
FBCButtonDownBackground.Style := bbsColor;
|
|
FBCButtonDownBackground.Color := clBtnShadow;
|
|
FBCButtonDownBackground.OnChange := OnChangeProperty;
|
|
FArrowColor:= clBtnText;
|
|
Font.Color := clWindowText;
|
|
Font.Name := 'Arial';
|
|
|
|
DoSelectAll;
|
|
TabStop := true;
|
|
end;
|
|
|
|
procedure TCustomBCTrackbarUpdown.DoSelectAll;
|
|
begin
|
|
FSelStart := 0;
|
|
FSelLength := length(Text);
|
|
end;
|
|
|
|
procedure TCustomBCTrackbarUpdown.SelectAll;
|
|
begin
|
|
DoSelectAll;
|
|
Invalidate;
|
|
end;
|
|
|
|
function TCustomBCTrackbarUpdown.RemoveSelection: boolean;
|
|
var
|
|
tempText: string;
|
|
len:integer;
|
|
begin
|
|
if SelLength > 0 then
|
|
begin
|
|
tempText := Text;
|
|
len := FSelLength;
|
|
FSelLength := 0;
|
|
Delete(tempText,SelStart+1,len);
|
|
Text := tempText;
|
|
Invalidate;
|
|
result := true
|
|
end else
|
|
result := false;
|
|
end;
|
|
|
|
procedure TCustomBCTrackbarUpdown.DelayTimer;
|
|
begin
|
|
if FTimer.Enabled then
|
|
begin
|
|
FTimer.Enabled:= false;
|
|
FTimer.Enabled:= true;
|
|
end;
|
|
end;
|
|
|
|
procedure TCustomBCTrackbarUpdown.SetFocus;
|
|
begin
|
|
try
|
|
inherited SetFocus;
|
|
except
|
|
//in some cases, it is impossible to set the focus
|
|
//but that's not a reason to crash the program
|
|
end;
|
|
end;
|
|
|
|
destructor TCustomBCTrackbarUpdown.Destroy;
|
|
begin
|
|
FreeAndNil(FTimer);
|
|
FreeAndNil(FBCBackground);
|
|
FreeAndNil(FBCButtonBackground);
|
|
FreeAndNil(FBCButtonDownBackground);
|
|
FreeAndNil(FBCBorder);
|
|
FreeAndNil(FBCRounding);
|
|
inherited Destroy;
|
|
end;
|
|
|
|
end.
|