From ee0aa8a24562fc8a031e6b4c28548e8ebea25d04 Mon Sep 17 00:00:00 2001 From: Leandro Diaz Date: Sat, 4 May 2024 22:25:28 -0300 Subject: [PATCH 1/3] added bcfluentslider --- bcfluentslider.pas | 602 +++++++++++++++++++++++++++ bgracontrols.lpk | 253 +++++------ bgracontrols.pas | 32 +- test/test_bcfuentslider/project1.lpi | 89 ++++ test/test_bcfuentslider/project1.lpr | 25 ++ test/test_bcfuentslider/unit1.lfm | 40 ++ test/test_bcfuentslider/unit1.pas | 70 ++++ 7 files changed, 972 insertions(+), 139 deletions(-) create mode 100644 bcfluentslider.pas create mode 100644 test/test_bcfuentslider/project1.lpi create mode 100644 test/test_bcfuentslider/project1.lpr create mode 100644 test/test_bcfuentslider/unit1.lfm create mode 100644 test/test_bcfuentslider/unit1.pas diff --git a/bcfluentslider.pas b/bcfluentslider.pas new file mode 100644 index 0000000..5bb42e4 --- /dev/null +++ b/bcfluentslider.pas @@ -0,0 +1,602 @@ +{ + 2024 by hedgehog +} + +unit BCFluentSlider; + +{$mode ObjFPC}{$H+} + +interface + +uses + Classes, SysUtils, Controls, Graphics, ExtCtrls, + ComCtrls, + BGRAGraphicControl, BGRABitmapTypes, BCTypes; + +type + + TTickPlacement = (tpBottomRight, tpTopLeft); + TSliderOrientation = (pbHorizontal, pbVertical, pbRightToLeft, pbTopDown); + + { TBCFluentSlider } + + TBCFluentSlider = class(TCustomBGRAGraphicControl) + private + FOnChangeValue: TNotifyEvent; + FShowTicks: boolean; + FThumbState: TBCMouseState; + FDeltaThumbPos: TPointF; + FFullRect, FDrawRect: TRectF; + FThumbRadius: single; + FBorderWidth: single; + FThumbRect: TRectF; + FCenterDrawRect: TPointF; + FRealLineWidth: single; + FRealLineColor: TBGRAPixel; + FOrientation: TSliderOrientation; + FStartTickCount: QWord; + FAnimationPercent: integer; + FStartPercent: integer; + FTickFrequency: integer; + FTickPlacement: TTickPlacement; + FTimer: TTimer; + FMaxValue: integer; + FMinValue: integer; + FValue: integer; + FLineColor: TColor; + FLineBkgColor: TColor; + FLineWidth: integer; + procedure CalculateThumbRect; + function GetValueFromMouse(X, Y: single): integer; + function GetXYFromValue(v: integer): TPointF; + procedure SetLineBkgColor(AValue: TColor); + procedure SetLineColor(AValue: TColor); + procedure SetMaxValue(AValue: integer); + procedure SetMinValue(AValue: integer); + procedure SetOrientation(AValue: TSliderOrientation); + procedure SetShowTicks(AValue: boolean); + procedure SetTickFrequency(AValue: integer); + procedure SetTickPlacement(AValue: TTickPlacement); + procedure SetValue(AValue: integer); + procedure SetLineWidth(AValue: integer); + procedure DrawBackLine; + procedure DrawTicks; + procedure DrawThumb; + procedure SetStateAnimation(NewState: TBCMouseState); + protected + procedure MouseMove(Shift: TShiftState; X, Y: Integer); override; + procedure MouseDown(Button: TMouseButton; Shift: TShiftState; + X, Y: Integer); override; + procedure MouseUp(Button: TMouseButton; Shift: TShiftState; + X, Y: Integer); override; + procedure MouseLeave; override; + procedure RedrawBitmapContent; override; + procedure TimerEvent({%H-}Sender: TObject); + procedure TimerStart({%H-}Sender: TObject); + procedure DrawBackground; virtual; + public + constructor Create(AOwner: TComponent); override; + published + property MinValue: integer read FMinValue write SetMinValue default 0; + property MaxValue: integer read FMaxValue write SetMaxValue default 100; + property Value: integer read FValue write SetValue default 0; + property LineColor: TColor read FLineColor write SetLineColor default + TColor($009E5A00); + property LineBkgColor: TColor read FLineBkgColor write SetLineBkgColor default + TColor($00808080); + property LineWidth: integer read FLineWidth write SetLineWidth default 0; + property Orientation: TSliderOrientation read FOrientation write SetOrientation default pbHorizontal; + property ShowTicks: boolean read FShowTicks write SetShowTicks default false; + property OnChangeValue: TNotifyEvent read FOnChangeValue write FOnChangeValue; + property TickPlacement: TTickPlacement read FTickPlacement write SetTickPlacement default tpBottomRight; + property TickFrequency: integer read FTickFrequency write SetTickFrequency default 10; + property OnRedraw; + property Align; + property Anchors; + property BorderSpacing; + property Enabled; + property Hint; + property PopupMenu; + property Visible; + property OnClick; + property OnChangeBounds; + property OnDragDrop; + property OnDragOver; + property OnEndDock; + property OnEndDrag; + property OnMouseDown; + property OnMouseEnter; + property OnMouseLeave; + property OnMouseMove; + property OnMouseUp; + property OnMouseWheel; + property OnMouseWheelDown; + property OnMouseWheelUp; + property OnResize; + property OnStartDock; + property OnStartDrag; + end; + +procedure Register; + +implementation + +procedure Register; +begin + RegisterComponents('BGRA Controls', [TBCFluentSlider]); +end; + + +const + ThumbPercentArray: array [TBCMouseState] of integer = (50, 62, 41); + +function InflateRectF(const R: TRectF; dxy: single): TRectF; +begin + Result:= RectF(R.Left-dxy, R.Top-dxy, R.Right+dxy, R.Bottom+ dxy); +end; + +function InflateRectF(const R: TRectF; dx, dy: single): TRectF; +begin + Result:= RectF(R.Left-dx, R.Top-dy, R.Right+dx, R.Bottom+ dy); +end; + +function CenterOfRectF(const R: TRectF): TPointF; +begin + Result.x:= (R.Left + R.Right)/2; + Result.y:= (R.Top + R.Bottom)/2; +end; + +function ContainsInRectF(const R: TRectF; X, Y: integer): boolean; +begin + Result:= (X>= R.Left) and (X<= R.Right) and (Y>= R.Top) and (Y<= R.Bottom); +end; + +// TPointF.Offset() not worked for me( +function MovePointF(const P: TPointF; dx, dy: integer): TPointF; +begin + Result.x:= P.x + dx; + Result.y:= P.Y + dy; + +end; + +{ TBCFluentSlider } + +procedure TBCFluentSlider.SetMaxValue(AValue: integer); +begin + if FMaxValue = AValue then + exit; + FMaxValue := AValue; + if FValue > FMaxValue then + FValue := FMaxValue; + if FMinValue > FMaxValue then + FMinValue := FMaxValue; + DiscardBitmap; +end; + +procedure TBCFluentSlider.SetLineBkgColor(AValue: TColor); +begin + if FLineBkgColor = AValue then + Exit; + FLineBkgColor := AValue; + DiscardBitmap; +end; + +procedure TBCFluentSlider.SetLineColor(AValue: TColor); +begin + if FLineColor = AValue then + Exit; + FLineColor := AValue; + DiscardBitmap; +end; + +procedure TBCFluentSlider.SetMinValue(AValue: integer); +begin + if FMinValue = AValue then + exit; + FMinValue := AValue; + if FValue < FMinValue then + FValue := FMinValue; + if FMaxValue < FMinValue then + FMaxValue := FMinValue; + DiscardBitmap; +end; + +procedure TBCFluentSlider.SetOrientation(AValue: TSliderOrientation); +var + k: integer; +begin + if FOrientation=AValue then Exit; + k:= ord(FOrientation) + ord(AValue)+1; + FOrientation:=AValue; + if odd(k) or (Width=Height) then + DiscardBitmap + else + SetBounds(Left, Top, Height, Width); +end; + +procedure TBCFluentSlider.SetShowTicks(AValue: boolean); +begin + if FShowTicks=AValue then Exit; + FShowTicks:=AValue; + DiscardBitmap; +end; + +procedure TBCFluentSlider.SetTickFrequency(AValue: integer); +begin + if FTickFrequency=AValue then Exit; + FTickFrequency:=AValue; + if FShowTicks then + DiscardBitmap; +end; + +procedure TBCFluentSlider.SetTickPlacement(AValue: TTickPlacement); +begin + if FTickPlacement=AValue then Exit; + FTickPlacement:=AValue; + if FShowTicks then + DiscardBitmap; +end; + +procedure TBCFluentSlider.SetValue(AValue: integer); +begin + if FValue = AValue then + exit; + FValue := AValue; + if FValue < FMinValue then + FValue := FMinValue; + if FValue > FMaxValue then + FValue := FMaxValue; + DiscardBitmap; + if Assigned(FOnChangeValue) then FOnChangeValue(self); +end; + +procedure TBCFluentSlider.SetLineWidth(AValue: integer); +begin + if FLineWidth = AValue then exit; + FLineWidth := AValue; + DiscardBitmap; +end; + +procedure TBCFluentSlider.DrawBackground; +begin + //todo: +end; + +procedure TBCFluentSlider.DrawBackLine; +var + p, p1, p2: TPointF; +begin + p:= CenterOfRectF(FThumbRect); + p1:= p; + p2:= p; + Bitmap.LineCap := pecRound; + case FOrientation of + pbHorizontal: + begin + p1.x:= FDrawRect.Right-1; + p2.x:= FDrawRect.Left; + end; + pbVertical: + begin + p1.y:= FDrawRect.Top; + p2.y:= FDrawRect.Bottom-1; + end; + pbRightToLeft: + begin + p1.x:= FDrawRect.Left; + p2.x:= FDrawRect.Right-1; + end; + pbTopDown: + begin + p1.y:= FDrawRect.Bottom-1; + p2.y:= FDrawRect.Top; + end; + end; + if FValue < FMaxValue then + Bitmap.DrawLineAntialias(p.x, p.y, p1.x, p1.y, FLineBkgColor, FRealLineWidth); + if FValue > FMinValue then + begin + Bitmap.DrawLineAntialias(p2.x, p2.y, p.x, p.y, FRealLineColor, FRealLineWidth); + end; +end; + +procedure TBCFluentSlider.DrawTicks; +var + v: integer; + p: TPointF; + x, y, tickSize, xy1, xy2: single; + c: TBGRAPixel; +begin + if (not FShowTicks) or (FTickFrequency<1) then exit; + c:= FLineBkgColor; + tickSize:= Scale96ToScreen(40)/10; + if FTickPlacement = tpBottomRight then + begin + xy2:= FThumbRadius; + xy1:= xy2 - tickSize; + end + else + begin + xy2:= -FThumbRadius; + xy1:= xy2 + tickSize; + end; + v:= (FMinValue div FTickFrequency)*FTickFrequency; + if v < FMinValue then + v+= FTickFrequency; + + while v<= FMaxValue do + begin + p:= GetXYFromValue(v); + if (FOrientation = pbHorizontal) or (FOrientation = pbRightToLeft) then + begin + if FBorderWidth<2 then x:= round(p.x) else x:= p.x; + Bitmap.DrawLineAntialias(x, p.y + xy1, x, p.y+ xy2, c, FBorderWidth); + end + else + begin + if FBorderWidth<2 then y:= round(p.y) else y:= p.y; + Bitmap.DrawLineAntialias(x + xy1, y, x+ xy2, y, c, FBorderWidth); + end; + v+= FTickFrequency; + end; +end; + +procedure TBCFluentSlider.DrawThumb; +var + r: single; + c: TBGRAPixel; + p: TPointF; +begin + c:= BGRABlack; + c.alpha:= 50; + p:= CenterOfRectF(FThumbRect); + r:= FThumbRadius-FBorderWidth/2; + Bitmap.EllipseAntialias(p.X, p.Y, r, r, c, FBorderWidth); + c:= BGRAWhite; + c.alpha:= 220; + r:= FThumbRadius-FBorderWidth; + Bitmap.FillEllipseAntialias(p.X, p.Y, r, r, c); + c:= FRealLineColor; + if FTimer.Enabled then + r:= FThumbRadius*FAnimationPercent/100 + else + begin + r:= FThumbRadius*ThumbPercentArray[FThumbState]/100; + if FThumbState = msClicked then + c.alpha:= 220; + end; + Bitmap.FillEllipseAntialias(p.X, p.Y, r, r, c); +end; + +procedure TBCFluentSlider.MouseMove(Shift: TShiftState; X, Y: Integer); +begin + if (FThumbState = msClicked) then + begin + SetValue(GetValueFromMouse(X+FDeltaThumbPos.x, Y+FDeltaThumbPos.y)); + end + else if (FThumbState = msHover) then + begin + if not ContainsInRectF(FThumbRect, X, Y) then + SetStateAnimation(msNone); + end + else if (FThumbState = msNone) then + begin + if ContainsInRectF(FThumbRect, X, Y) then + SetStateAnimation(msHover); + end; + inherited MouseMove(Shift, X, Y); +end; + +procedure TBCFluentSlider.SetStateAnimation(NewState: TBCMouseState); +begin + if FTimer.Enabled then + begin + FStartPercent:= FAnimationPercent; + FTimer.Enabled:= false; + end + else + begin + FStartPercent:= ThumbPercentArray[FThumbState]; + end; + FThumbState:= NewState; + FTimer.Enabled:= true; +end; + +procedure TBCFluentSlider.MouseDown(Button: TMouseButton; Shift: TShiftState; + X, Y: Integer); +begin + if Button = mbLeft then + begin + if FThumbState = msHover then + begin + FDeltaThumbPos:= MovePointF(CenterOfRectF(FThumbRect), -X, -Y); + SetStateAnimation(msClicked); + end + else + begin + FThumbState:= msClicked; + FDeltaThumbPos:= PointF(0, 0); + SetValue(GetValueFromMouse(X, Y)); + end; + end; + inherited; +end; + +function TBCFluentSlider.GetValueFromMouse(X, Y: single): integer; + + function GetValPos(k: double): integer; inline; + begin + Result:= round(FMinValue +(FMaxValue - FMinValue)*k); + end; + +var + R: TRectF; +begin + R:= InflateRectF(FFullRect, - FThumbRadius); + case FOrientation of + pbHorizontal: + begin + if X< R.Left then Result:= FMinValue + else if X> R.Right then Result:= FMaxValue + else Result:= GetValPos((X - R.Left)/(R.Width-1)); + end; + pbVertical: + begin + if Y> R.Bottom then Result:= FMinValue + else if Y< R.Top then Result:= FMaxValue + else Result:= GetValPos((R.Bottom - Y)/(R.Height-1)); + end; + pbRightToLeft: + begin + if X< R.Left then Result:= FMaxValue + else if X> R.Right then Result:= FMinValue + else Result:= GetValPos((R.Right - X)/(R.Width-1)); + end; + pbTopDown: + begin + if Y> R.Bottom then Result:= FMaxValue + else if Y< R.Top then Result:= FMinValue + else Result:= GetValPos((Y - R.Top)/(R.Height-1)); + end; + end; +end; + +procedure TBCFluentSlider.MouseUp(Button: TMouseButton; Shift: TShiftState; X, + Y: Integer); +begin + if (Button = mbLeft) and (FThumbState = msClicked) then + begin + if ContainsInRectF(FThumbRect, X, Y) then + SetStateAnimation(msHover) + else + SetStateAnimation(msNone); + end; + inherited MouseUp(Button, Shift, X, Y); +end; + +procedure TBCFluentSlider.MouseLeave; +begin + if FThumbState = msHover then + SetStateAnimation(msNone); + inherited MouseLeave; +end; + +function TBCFluentSlider.GetXYFromValue(v: integer): TPointF; +var + k: double; + R: TRectF; + p: TPointF; +begin + R:= InflateRectF(FFullRect, -FThumbRadius); + k:= (v- FMinValue)/(FMaxValue - FMinValue); + p:= FCenterDrawRect; + case FOrientation of + pbHorizontal: p.x:= + R.Left + (R.Width-1)*k; + pbVertical: p.y:= + R.Bottom -1 - (R.Height-1)*k; + pbRightToLeft: p.x:= + R.Right -1 - (R.Width-1)*k; + pbTopDown: p.y:= + R.Top + (R.Height-1)*k; + end; + Result:= p; +end; + +procedure TBCFluentSlider.CalculateThumbRect; +var + k: double; + R: TRectF; + p: TPointF; +begin + FThumbRadius:= Scale96ToScreen(11); + if FLineWidth<1 then + FRealLineWidth:= Scale96ToScreen(40)/10 + else + FRealLineWidth:= Scale96ToScreen(FLineWidth*10)/10; + FBorderWidth:= Scale96ToScreen(10)/10; + FFullRect:= RectF(ClientRect); + FDrawRect:= InflateRectF(FFullRect, -FRealLineWidth/2); + R:= InflateRectF(FFullRect, -FThumbRadius); + FCenterDrawRect := CenterOfRectF(FDrawRect); + k:= (FValue- FMinValue)/(FMaxValue - FMinValue); + p:= FCenterDrawRect; + case FOrientation of + pbHorizontal: p.x:= + R.Left + (R.Width-1)*k; + pbVertical: p.y:= + R.Bottom -1 - (R.Height-1)*k; + pbRightToLeft: p.x:= + R.Right -1 - (R.Width-1)*k; + pbTopDown: p.y:= + R.Top + (R.Height-1)*k; + end; + FThumbRect:= RectF( + p.x - FThumbRadius, + p.y - FThumbRadius, + p.x + FThumbRadius, + p.y + FThumbRadius); +end; + +procedure TBCFluentSlider.RedrawBitmapContent; +begin + CalculateThumbRect; + DrawBackground; + FRealLineColor:= FLineColor; + if not Enabled then + FRealLineColor:= FRealLineColor.ToGrayscale; + DrawBackLine; + DrawTicks; + DrawThumb; + if Assigned(OnRedraw) then + OnRedraw(self, FBGRA); +end; + +procedure TBCFluentSlider.TimerEvent(Sender: TObject); +var + TickCount: QWord; + FAnimationTime: Int64; +const + Duration = 130; // ms +begin + TickCount:= GetTickCount64; + FAnimationTime:= TickCount - FStartTickCount; + if FAnimationTime >= Duration then + FTimer.Enabled:= false + else + FAnimationPercent:= FStartPercent+ + round(FAnimationTime*(ThumbPercentArray[FThumbState] - FStartPercent)/Duration); + DiscardBitmap; +end; + +procedure TBCFluentSlider.TimerStart(Sender: TObject); +begin + FStartTickCount:= GetTickCount64; +end; + +constructor TBCFluentSlider.Create(AOwner: TComponent); +begin + inherited Create(AOwner); + FThumbState:= msNone; + FOrientation:= pbHorizontal; + FTickFrequency:= 10; + FTimer:= TTimer.Create(self); + FTimer.Interval := 15; + FTimer.Enabled := false; + FTimer.OnTimer := @TimerEvent; + FTimer.OnStartTimer:= @TimerStart; + + with GetControlClassDefaultSize do + SetInitialBounds(0, 0, 150, 32); + FMaxValue := 100; + FMinValue := 0; + FValue := 0; + FLineWidth:=0; + FLineColor := TColor($009E5A00); + FLineBkgColor := TColor($00808080); +end; + + +end. + + diff --git a/bgracontrols.lpk b/bgracontrols.lpk index 152f281..f1decb6 100644 --- a/bgracontrols.lpk +++ b/bgracontrols.lpk @@ -15,8 +15,8 @@ - + @@ -34,7 +34,7 @@ - + @@ -80,297 +80,302 @@ - - + + + + + + + - - + + + + + + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - - - - - + diff --git a/bgracontrols.pas b/bgracontrols.pas index e9f8cdc..42c039b 100644 --- a/bgracontrols.pas +++ b/bgracontrols.pas @@ -9,20 +9,21 @@ interface uses atshapelinebgra, BCButton, BCButtonFocus, BCCheckComboBox, BCComboBox, - BCEffect, bcfilters, BCFluentProgressRing, BCGameGrid, BCGradientButton, - BCImageButton, BCLabel, BCListBox, BCListBoxEx, BCMaterialDesignButton, - BCMaterialEdit, BCMaterialFloatSpinEdit, BCMaterialProgressBarMarquee, - BCMaterialSpinEdit, BCMDButton, BCMDButtonFocus, BCPanel, - BCRadialProgressBar, BCRoundedImage, BCRTTI, BCSamples, BCStylesForm, - BCSVGButton, BCSVGViewer, BCToolBar, BCTrackbarUpdown, BGRAColorTheme, - bgracontrolsinfo, BGRACustomDrawn, BGRADrawerFlashProgressBar, - BGRAFlashProgressBar, BGRAGraphicControl, BGRAImageList, - BGRAImageManipulation, BGRAImageTheme, BGRAKnob, BGRAResizeSpeedButton, - BGRAShape, BGRASpeedButton, BGRASpriteAnimation, BGRASVGImageList, - BGRASVGTheme, BGRATheme, BGRAThemeButton, BGRAThemeCheckBox, - BGRAThemeRadioButton, BGRAVirtualScreen, ColorSpeedButton, DTAnalogClock, - DTAnalogCommon, DTAnalogGauge, dtthemedclock, dtthemedgauge, MaterialColors, - bgrasvgimagelistform, BCExpandPanels, LazarusPackageIntf; + BCEffect, BCExpandPanels, bcfilters, BCFluentProgressRing, BCFluentSlider, + BCGameGrid, BCGradientButton, BCImageButton, BCLabel, BCListBox, + BCListBoxEx, BCMaterialDesignButton, BCMaterialEdit, + BCMaterialFloatSpinEdit, BCMaterialProgressBarMarquee, BCMaterialSpinEdit, + BCMDButton, BCMDButtonFocus, BCPanel, BCRadialProgressBar, BCRoundedImage, + BCRTTI, BCSamples, BCStylesForm, BCSVGButton, BCSVGViewer, BCToolBar, + BCTrackbarUpdown, BGRAColorTheme, bgracontrolsinfo, BGRACustomDrawn, + BGRADrawerFlashProgressBar, BGRAFlashProgressBar, BGRAGraphicControl, + BGRAImageList, BGRAImageManipulation, BGRAImageTheme, BGRAKnob, + BGRAResizeSpeedButton, BGRAShape, BGRASpeedButton, BGRASpriteAnimation, + BGRASVGImageList, BGRASVGTheme, BGRATheme, BGRAThemeButton, + BGRAThemeCheckBox, BGRAThemeRadioButton, BGRAVirtualScreen, + ColorSpeedButton, DTAnalogClock, DTAnalogCommon, DTAnalogGauge, + dtthemedclock, dtthemedgauge, MaterialColors, bgrasvgimagelistform, + LazarusPackageIntf; implementation @@ -33,7 +34,9 @@ procedure Register; RegisterUnit('BCButtonFocus', @BCButtonFocus.Register); RegisterUnit('BCCheckComboBox', @BCCheckComboBox.Register); RegisterUnit('BCComboBox', @BCComboBox.Register); + RegisterUnit('BCExpandPanels', @BCExpandPanels.Register); RegisterUnit('BCFluentProgressRing', @BCFluentProgressRing.Register); + RegisterUnit('BCFluentSlider', @BCFluentSlider.Register); RegisterUnit('BCGameGrid', @BCGameGrid.Register); RegisterUnit('BCGradientButton', @BCGradientButton.Register); RegisterUnit('BCImageButton', @BCImageButton.Register); @@ -78,7 +81,6 @@ procedure Register; RegisterUnit('DTAnalogGauge', @DTAnalogGauge.Register); RegisterUnit('dtthemedclock', @dtthemedclock.Register); RegisterUnit('dtthemedgauge', @dtthemedgauge.Register); - RegisterUnit('BCExpandPanels', @BCExpandPanels.Register); end; initialization diff --git a/test/test_bcfuentslider/project1.lpi b/test/test_bcfuentslider/project1.lpi new file mode 100644 index 0000000..82ed1b2 --- /dev/null +++ b/test/test_bcfuentslider/project1.lpi @@ -0,0 +1,89 @@ + + + + + + + + + <Scaled Value="True"/> + <ResourceType Value="res"/> + <UseXPManifest Value="True"/> + <XPManifest> + <DpiAware Value="True"/> + </XPManifest> + <Icon Value="0"/> + </General> + <BuildModes> + <Item Name="Default" Default="True"/> + </BuildModes> + <PublishOptions> + <Version Value="2"/> + <UseFileFilters Value="True"/> + </PublishOptions> + <RunParams> + <FormatVersion Value="2"/> + </RunParams> + <RequiredPackages> + <Item> + <PackageName Value="bgracontrols"/> + </Item> + <Item> + <PackageName Value="LCL"/> + </Item> + </RequiredPackages> + <Units> + <Unit> + <Filename Value="project1.lpr"/> + <IsPartOfProject Value="True"/> + </Unit> + <Unit> + <Filename Value="unit1.pas"/> + <IsPartOfProject Value="True"/> + <ComponentName Value="Form1"/> + <HasResources Value="True"/> + <ResourceBaseClass Value="Form"/> + <UnitName Value="Unit1"/> + </Unit> + <Unit> + <Filename Value="bcfluentslider.pas"/> + <IsPartOfProject Value="True"/> + <UnitName Value="BCFluentSlider"/> + </Unit> + </Units> + </ProjectOptions> + <CompilerOptions> + <Version Value="11"/> + <PathDelim Value="\"/> + <Target> + <Filename Value="project1"/> + </Target> + <SearchPaths> + <IncludeFiles Value="$(ProjOutDir)"/> + <UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/> + </SearchPaths> + <Linking> + <Debugging> + <DebugInfoType Value="dsDwarf2Set"/> + </Debugging> + <Options> + <Win32> + <GraphicApplication Value="True"/> + </Win32> + </Options> + </Linking> + </CompilerOptions> + <Debugging> + <Exceptions> + <Item> + <Name Value="EAbort"/> + </Item> + <Item> + <Name Value="ECodetoolError"/> + </Item> + <Item> + <Name Value="EFOpenError"/> + </Item> + </Exceptions> + </Debugging> +</CONFIG> diff --git a/test/test_bcfuentslider/project1.lpr b/test/test_bcfuentslider/project1.lpr new file mode 100644 index 0000000..5966e09 --- /dev/null +++ b/test/test_bcfuentslider/project1.lpr @@ -0,0 +1,25 @@ +program project1; + +{$mode objfpc}{$H+} + +uses + {$IFDEF UNIX} + cthreads, + {$ENDIF} + {$IFDEF HASAMIGA} + athreads, + {$ENDIF} + Interfaces, // this includes the LCL widgetset + Forms, Unit1, BCFluentSlider + { you can add units after this }; + +{$R *.res} + +begin + RequireDerivedFormResource:=True; + Application.Scaled:=True; + Application.Initialize; + Application.CreateForm(TForm1, Form1); + Application.Run; +end. + diff --git a/test/test_bcfuentslider/unit1.lfm b/test/test_bcfuentslider/unit1.lfm new file mode 100644 index 0000000..86aaaf3 --- /dev/null +++ b/test/test_bcfuentslider/unit1.lfm @@ -0,0 +1,40 @@ +object Form1: TForm1 + Left = 579 + Height = 286 + Top = 224 + Width = 425 + Caption = 'Form1' + ClientHeight = 286 + ClientWidth = 425 + DesignTimePPI = 120 + OnCreate = FormCreate + LCLVersion = '2.2.6.0' + object Label1: TLabel + Left = 120 + Height = 37 + Top = 96 + Width = 93 + Caption = 'Value: 0' + Font.Height = -27 + ParentColor = False + ParentFont = False + end + object CheckBox1: TCheckBox + Left = 344 + Height = 24 + Top = 16 + Width = 56 + Caption = 'Ticks' + OnChange = CheckBox1Change + TabOrder = 0 + end + object CheckBox2: TCheckBox + Left = 344 + Height = 24 + Top = 48 + Width = 74 + Caption = 'Vertical' + OnChange = CheckBox2Change + TabOrder = 1 + end +end diff --git a/test/test_bcfuentslider/unit1.pas b/test/test_bcfuentslider/unit1.pas new file mode 100644 index 0000000..6b56c9b --- /dev/null +++ b/test/test_bcfuentslider/unit1.pas @@ -0,0 +1,70 @@ +unit Unit1; + +{$mode objfpc}{$H+} + +interface + +uses + Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls, + BCFluentSlider; + +type + + { TForm1 } + + TForm1 = class(TForm) + CheckBox1: TCheckBox; + CheckBox2: TCheckBox; + Label1: TLabel; + procedure CheckBox1Change(Sender: TObject); + procedure CheckBox2Change(Sender: TObject); + procedure FormCreate(Sender: TObject); + private + procedure SliderChangeValue(Sender: TObject); + + public + Slider: TBCFluentSlider; + end; + +var + Form1: TForm1; + +implementation + +{$R *.lfm} + +{ TForm1 } + +procedure TForm1.FormCreate(Sender: TObject); +begin + Slider:= TBCFluentSlider.Create(self); + with Slider do + begin + Top:= 10; + Left:= 10; + Width:= 240; + OnChangeValue:= @SliderChangeValue; + Parent:= self; + end; +end; + +procedure TForm1.CheckBox1Change(Sender: TObject); +begin + Slider.ShowTicks:= CheckBox1.Checked; +end; + +procedure TForm1.CheckBox2Change(Sender: TObject); +begin + if CheckBox2.Checked then + Slider.Orientation:= pbVertical + else + Slider.Orientation:= pbHorizontal; +end; + +procedure TForm1.SliderChangeValue(Sender: TObject); +begin + Label1.Caption:= 'Value: '+IntToStr(Slider.Value); +end; + +end. + From d99050c76dd0db56d4a74835ed4596e897b5e471 Mon Sep 17 00:00:00 2001 From: Leandro Diaz <lainz@users.noreply.github.com> Date: Sun, 5 May 2024 10:50:16 -0300 Subject: [PATCH 2/3] v9.0.1 --- bcfluentslider.pas | 19 ++++++++++ bcreg.pas | 6 ++-- bgracontrols.lpk | 2 +- images/TBCFluentProgressRing.png | Bin 0 -> 663 bytes images/TBCFluentProgressRing_150.png | Bin 0 -> 917 bytes images/TBCFluentProgressRing_200.png | Bin 0 -> 1164 bytes images/TBCFluentSlider.png | Bin 0 -> 770 bytes images/TBCFluentSlider_150.png | Bin 0 -> 815 bytes images/TBCFluentSlider_200.png | Bin 0 -> 813 bytes images/bgracontrols_images.res | Bin 222794 -> 210873 bytes images/bgracontrols_images_list.txt | 8 ++++- test/test_bcfuentslider/unit1.pas | 51 ++++++++++++++++++++++++++- 12 files changed, 81 insertions(+), 5 deletions(-) create mode 100644 images/TBCFluentProgressRing.png create mode 100644 images/TBCFluentProgressRing_150.png create mode 100644 images/TBCFluentProgressRing_200.png create mode 100644 images/TBCFluentSlider.png create mode 100644 images/TBCFluentSlider_150.png create mode 100644 images/TBCFluentSlider_200.png diff --git a/bcfluentslider.pas b/bcfluentslider.pas index 5bb42e4..660f0cd 100644 --- a/bcfluentslider.pas +++ b/bcfluentslider.pas @@ -47,6 +47,8 @@ TBCFluentSlider = class(TCustomBGRAGraphicControl) FLineBkgColor: TColor; FLineWidth: integer; procedure CalculateThumbRect; + function GetThumbPosition: TPoint; + function GetThumbRadius: integer; function GetValueFromMouse(X, Y: single): integer; function GetXYFromValue(v: integer): TPointF; procedure SetLineBkgColor(AValue: TColor); @@ -76,6 +78,8 @@ TBCFluentSlider = class(TCustomBGRAGraphicControl) procedure DrawBackground; virtual; public constructor Create(AOwner: TComponent); override; + property ThumbPosition: TPoint read GetThumbPosition; + property ThumbRadius: integer read GetThumbRadius; published property MinValue: integer read FMinValue write SetMinValue default 0; property MaxValue: integer read FMaxValue write SetMaxValue default 100; @@ -99,6 +103,7 @@ TBCFluentSlider = class(TCustomBGRAGraphicControl) property PopupMenu; property Visible; property OnClick; + property OnDblClick; property OnChangeBounds; property OnDragDrop; property OnDragOver; @@ -538,6 +543,20 @@ procedure TBCFluentSlider.CalculateThumbRect; p.y + FThumbRadius); end; +function TBCFluentSlider.GetThumbPosition: TPoint; +var + p: TPointF; +begin + p:= CenterOfRectF(FThumbRect); + Result.X:= round(p.x); + Result.Y:= round(p.y); +end; + +function TBCFluentSlider.GetThumbRadius: integer; +begin + Result:= round(FThumbRadius); +end; + procedure TBCFluentSlider.RedrawBitmapContent; begin CalculateThumbRect; diff --git a/bcreg.pas b/bcreg.pas index de77554..a401b51 100644 --- a/bcreg.pas +++ b/bcreg.pas @@ -19,7 +19,8 @@ interface BGRAImageList, BGRAImageManipulation, BGRAKnob, BGRAResizeSpeedButton, BGRAShape, BGRASpeedButton, BGRASpriteAnimation, BGRAVirtualScreen, ColorSpeedButton, DTAnalogClock, DTAnalogGauge, dtthemedclock, - dtthemedgauge, MaterialColors, bcmdbutton, bcmdbuttonfocus; + dtthemedgauge, MaterialColors, bcmdbutton, bcmdbuttonfocus, BCFluentProgressRing, + BCFluentSlider; procedure Register; @@ -39,7 +40,8 @@ procedure Register; TBGRAVirtualScreen, TBGRASpriteAnimation, TBGRASpeedButton, TBGRAResizeSpeedButton, TBGRAKnob, TBGRAImageManipulation, TBGRAImageList, TBGRAGraphicControl, TBGRAFlashProgressBar, TBCTrackbarUpdown, TBCToolBar, TBCSVGViewer, TBCSVGButton, TBCRadialProgressBar, - TBCPanel,TBCMDButtonFocus, TBCMDButton, TBCMaterialDesignButton + TBCPanel,TBCMDButtonFocus, TBCMDButton, TBCMaterialDesignButton, + TBCFluentProgressRing, TBCFluentSlider {TBCDefaultThemeManager, TBCKeyboard, TBCNumericKeyboard, TBCRealNumericKeyboard}]); diff --git a/bgracontrols.lpk b/bgracontrols.lpk index f1decb6..f3121ce 100644 --- a/bgracontrols.lpk +++ b/bgracontrols.lpk @@ -33,7 +33,7 @@ </CompilerOptions> <Description Value="BGRA Controls is a set of graphical UI elements that you can use with Lazarus LCL applications."/> <License Value="Modified LGPL"/> - <Version Major="9"/> + <Version Major="9" Release="1"/> <Files Count="70"> <Item1> <Filename Value="atshapelinebgra.pas"/> diff --git a/images/TBCFluentProgressRing.png b/images/TBCFluentProgressRing.png new file mode 100644 index 0000000000000000000000000000000000000000..6292fea0ba955bb02021bbba97a358ee95eab8a3 GIT binary patch literal 663 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM3?#3wJbMaAF%}28J29*~C-V}>VM%xNb!1@J z*w6hZkrl{)7~m7)I%(engXW{+rTg3_o-SQ`W9i9fcV2xnY&ph|zN2aDUH#^xTQ9$! zefaU?ci*>Mdeyq^u1d|JllMQAue+(+bToSIMV`Dp+KorHUwK`!=4Rf?>w9m!RjoZF zS9##t^DoA&$Fi1PJ9z7z$D}h$PClEo?_tcmOB41!kSN_RR<cj1Xm8!7+r7K*OP1~L z*>!);ktb6RJnYzUPrdH2K*64c$Dhhq9X$Qu!@W1(ZoK%i`QodJ^|w}^eX;7ybJnb# z%$YkkUwU=??t7)`gWS2hcVByxv;11)mOC3SzSOKgY}$U@y6dFd#4{^SKL`3U@$0^4 zK+3x$$S?Rm)d0h3$q#FQ#&Q;TL>4nJ@ErzW#^d=bQh<UlJY5_^G=g&{+zete6mUJ9 z)qG-|h7!}J#S0cR?PyR^`uku0$lE0|7p=I{uJV13=c+0mcEg1QDpK9=XTLkac~d3E zT0l`<qf+bb2hF`sQzkuIa5~az@>aES6_rXs*8T@GW-M~QVg20hptynR{2eVjK6M%$ z+3IiLa#TG}VO87btI@2#uPD4)*7()0Q;qqGiSC+Q)meN2rwhcR{U`d$Cp0j=-*~y% zDMh1JWwQM#%^k}3FHip4nQVDU<=3B2R&!7OcFBMD{@nds?oS^%GuZz`X>5wD<Gy^d t{*Lg8l&2kB&+b36`nmn*{awfQF#Cy=8GfA1RSxtsgQu&X%Q~loCIEgjZvFrO literal 0 HcmV?d00001 diff --git a/images/TBCFluentProgressRing_150.png b/images/TBCFluentProgressRing_150.png new file mode 100644 index 0000000000000000000000000000000000000000..a31971a397c8e9379504c792b8d7b9e245538a7b GIT binary patch literal 917 zcmeAS@N?(olHy`uVBq!ia0vp^Dj>|k3?#4J%UA`Z7>k44ofy`glX(f`u%tWsIx;Y9 z?C1WI$O@FR3-AeXz5e`5)7CrF4?bFV{>8Do?<ehhz>vO!CvSJ~jPtV&KQ?SRCR=f! zf6oK0h9ie>znif4LH*|2=}WE#Og}GHvafCX-J^HkCoH%;dEdiJPd+>Jp4xx&UGbV5 zrftVEmtAe%ddIQvlw{fd(+@r_JN3+M;^_mo-iep)yYlR_=j1aBk3Y>@ac#=}hlQ)I zPu%;!wEg((!;jaWf9W~-?DEskwq1TLP`IaR!!4PL16Q7YPFZy2(Cv5oZoFm9+8HqI zT<rWysf(}pPCdK$#M846Kc2k*VfpFja+L?{dQJ)z?af(!Epyqm?p^otS6<Iuam~2( z*u^KG&OG?&GU0UWyh{s?KRIyoZStbaojdP|mh8(|dewW%+4k*sryY1?)Ot+4?r_)6 z`xEy)oPFep|Fm=b1$#Mjc7@J7zv#r%qj%n~I`e$Sp~r38?@ikGaKi;qkQ(kk5)7oW zN`m}?|I-UF?0ItMG0;}d0*}aI1_r*vAk26?e?<x~QnNf=978PpdnZ1RIusz_BKUPt zQwQr&rbRb)cd$x}g}mAO{oTI*+!g7Y9fWv3{z)wRRx?3I?iai2q~(XABULT?V^@V8 z2oKgaPM-cM;?fW1OBph%OJ6l#vivjWf<o%c=60#svs{C8FG<Rq9a@{T_2ZB2E+U!c zYxsElgaXyQV>`|Xx!&x08RE7m&!bTGl&9^V(7jJpAC>#;@Ti?oqbKzBuvEcBHbvf@ z9)~Bm#ViT*NY=Y#v4mmCi6cu&RDB$0T?;C5TRCM)S(@V6%uKmN$0+U0HDZO!RhOi$ zT)QS=E0<>Tl50!MH=mo$yYGiuQkYnpP(;ql1xqD1-7*tXE8B7YWsCJk(<^%UU2h6^ z_j72TSbR!ufdF5Bk5MP1(9<3#+4%{V=FIba{B)wK)pWnuANs);SMTuAIubqcMO2iw z`7tB?z#m~^uJ0~w()MuqUbCL*Bl}BJ*UlFoUq<#!zi$3gV)K&9|3Cix`nU0)yUYHi WZ~M=_6<!HS2MnIBelF{r5}E)cvI@We literal 0 HcmV?d00001 diff --git a/images/TBCFluentProgressRing_200.png b/images/TBCFluentProgressRing_200.png new file mode 100644 index 0000000000000000000000000000000000000000..039f0c9aba3676882c7df15bc2dafc3cb7883676 GIT binary patch literal 1164 zcmeAS@N?(olHy`uVBq!ia0vp^1|ZDA3?vioaBc-sjKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WChCg2l#}z?z#TfsPz~_`VNWG{RS<^+$WxnUvO#e(I=1JeZTkm8&~cw)Ar-l z8*WWI@Th3@^_q>hJSUymbN!82$-WI2UY>vasdd}kqSZHa8jozc`10zrFG&k8vu5o) zaO>Tbr=LS-T@WhTd-mbS_U(5a`%Z1S^s0Z)gJq|lv1RYN^XhB#+>40|FMCZs%apP6 z^3%_Kd+w(#xuV~E^w{0^H(q?P>N-)p`bNo`8%s|<yZ-!(T;&1j^8KR4`=rYE&p!Nk z_L0XA-+p(Sc>2<l&$>-V^_q@WZMapu=7#r_vkQ(rJ$~=Kdfnl?mDf$%j`i%mfAhr` z_Uv6gQ_kkBxHe($gOz8VuQ>g@XV?8T=U!~Q__BBReUC|Jx_900*m2LS{Wx3JPT#3# z58r-&{?W&XITxkM_TPH>b?4RB%$YmSJotF=$)`iN-)+16%AomZ!K&*UFTPrT{$<(P zo0|29SDk&qleb%@;=rzJukXJ8=F)$fBWG8`<~z4vePzwsRk-R#<CZ&Z+wb0b`DO8m zXUU7M*!P^&Z92l4vrDjWZ|1VA(+)m*^zJ(_j>NWhm;<TSk|4j}|APQ9<YvS<0Ug9y z;1OBOz`%DHgc*<LuSfwVps$`Tjv*f2Yp14%2RjP19d7C{VQu0N>RRX;V5o7H$x-J^ zU(-~jCf1D&u`bWrH(P&JGB138_L<B)f8+OOiv9BP%7hp3SgI*bS-Pp%@5#I~&hHOu z%{djmV1d9z`!!C2*JdWQDC}KuCG&{StbUa_A8oq-F7)2Cfy?W(!3SZUho3f!-nc%; zSxP}dYxRcp=fah_#5$Br4YFRVc&H0pJ-kC9x2kcGfz*y-ffa!*%hE3I;JBjXcIJv7 zQ*6q@t5fovq`6;B(!0yD>&zk1SWB+AIxAM6V>%j{Q6g>?vE!LuOuFO#-0+2yTlLBt zBVL>fIdLxJMWOhU*zZm|3O|c2XFQ?*&5XPDub1kC-$n-x$%+;ESavkZ7xmsrZS=m{ z*EzR((~|RB#oiU4U4D2v`yS&Z+PXZ&i``OERCTnUg=9Cn?c}cNGQ1bC%;eCHEk)Wl zW=v?+3YKPM5AdCJ;Lwzw&pQp7e7zT?S$L(2UABA|v7j=Af2a2|!8GnmT^DwCeEBH+ zuD{|J&*bO&DguqurcGRZqf6z?sykw{u1)VyxFE$gEBv*z;M_HP>OPBgKAXEnmQ&>J zkrT&$>*iFl{8IS7u(#jte_{K5cdq$%$>%CqZ^hj|IH_G<qDjT^^VQGpD?00c_Z?JR x$rO06fBycu^7sEdd*1%N>;CLvy`sP(X0G=Bn0HU)Zv#^WgQu&X%Q~loCIGE5nlAtV literal 0 HcmV?d00001 diff --git a/images/TBCFluentSlider.png b/images/TBCFluentSlider.png new file mode 100644 index 0000000000000000000000000000000000000000..2d8455d3a503a24c468a434ddfd9d48bfaacf8c8 GIT binary patch literal 770 zcmV+d1O5DoP)<h;3K|Lk000e1NJLTq000;O000;W1^@s6;CDUv00001b5ch_0Itp) z=>Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!T<mc!T}X1N`L?W0+&fdK~zXf?Ug%- z6Hyd~&rBw-g-kXZO*9V@Hiea<qF5|gX>Z}O)%r+ht+tAWCF&MpN(&_hM6tAx2oY9T z8&L!WEyT@RLXydA;!Kixc<yAf?n+29h1l%ZT<)E7@45H<=bV8({yUUDPNY()FoVIs z(d+e0ilTtYWCE+zI$#)v_j<juZZ?*g9PFf2D*4dK3Lbu%rfH|X46-c$#PzonMJ4@y zzo;)8Bb&`S^ZEQMj^nzbD9ZRMRgxr?jDjExs?{owHqUf(V-$-;7asn!)9I)qBw11W zlB|s*n$4z~%jF)RJxlh@9HK&@kYri*g2UkeS;aXgz{h+WYJ498E;}3xI^Y0nMN1Xh z?Y7ACd^{Ko-k#Y(xm<2|Jf3-qqTy4q1NUBULFQ{6L`easoq=;ly>RtR2*PeVV920e zuYdOWd`GCno2>e1v!rdBME2$hIdsr%YKs!Ar?=pKCI{XAp9ET%V_^OKAy_@-0~1~w zUo50jsVM#UU3u!^1VN!`GS)hMc%N(SI-J1$l3??D6MFa}%p?*f8!lg@QJ0~`zhOTe zUGk$qn&1<$(^z51K8FQPhFF-hXb;-Pg&|ss%!8Gofm|9Bg4DvA5s{lHvU4Qz-SiL0 zeB-o`ur?yH2d<qBYa(N9K&@8$f+8O_lBQ4aR;xSH^g~Wh(*+wG$0+=jrgtz+Zw+_P z02YoLoy=NjiBX|#6N|;Bs;#$*^r%&kHZi7EJlD-Nb}Kc7a5&t;PI|f9?cQiK8ZWV! zHsbMk5*=>f`~`N~>t?h0l5VbH$N>R6W!Yk}B(Qr%G0w}lw1N(ov6EiG!yn>zVQ4wT zumb}A0|tRWfQv*TRh-%u7Z<BIZ%z9*>@fy_-$x*wNub7t_5c6?07*qoM6N<$g5<DU Apa1{> literal 0 HcmV?d00001 diff --git a/images/TBCFluentSlider_150.png b/images/TBCFluentSlider_150.png new file mode 100644 index 0000000000000000000000000000000000000000..c3df25013f1440b57af4ee4b4ba17bcac0aad293 GIT binary patch literal 815 zcmV+~1JL}5P)<h;3K|Lk000e1NJLTq001Na001Ni1^@s6;Q*MJ00001b5ch_0Itp) z=>Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!T<mc!T}X1N`L?W0>nu~K~z{r?Uv1N zQb7>F2MV;QDX~(%>;WpYO~9y)HXckg@uEGn@uo%(-t^)h(4;m&#CWGQQ4gLp(UWpO zIoWvdQfuO+7lJ?uP`<QKBRt^ooLL?fEHpsj_I}A`-_FeL&U-Vn`#?fMLPDYunb>zt zB9Ry?7K>VJP^nZvE|-H!rJ|PB>-8zotZfeMP%EO*=rTHZ2_3skPSzl&(fKu$eHtGh ze<+IkODGh2ACJd{d_FIf%Vhzb*lRQ<IqA{PBTnfLxPdAd47xL!jL;5bhxRKtZ%|yK zx5Q#GcRHOGc%B!xtg@B)BYX|*2x08&Av?0CdEyei%^`eK!DuwHq$ZNPMR0uxfaiM( zxH1oeiUF8ErG=$A3+U8U8!CqF?QJlbOw5-<IfQv|2D^E&4J(yOyGElS75pxg;qI$V zc)cEH<9cq+8sXV38;lGo*cd|xrBZ1VU&bz5db6?o;&TWRIgTki!8$f*n9>eSA6F}< z2IMl8<NA4>{@4i9eF^NqoO=Uu=-B_LhX%lV|14avjIwbyn+2cGm$X`~tFqY#Ug6tT z7Wj(5lpRsQ&G=HaA-`VUful#N`T6AI4_JKXXV1-ed~FgIubyDfg+c)w4hKw3On|%# zH~I#hSBfhq^^VBTd{-f}XovL}vMHllIgKGxa$Hdd;upF&Im$wlEAVVw56MYigX1`u znVCsp4n6H#Qtx8!+-s54H_jR0`E7giq-K&H5e|n1gTc^H_K&<&_DL-J3YNVb7EbFL z${rn|7uzfQo`MJ5O0$EJ4#f3?55`q-iTya8&aU&Eu7EDCj@1LNj>9-q12^z=d%6Dm zFX$m=vv~nGcVIZyC}F9&T&}mZXOfei?8GUp>GTWX51KX-iP!>xfX(msv!2Ez7fl$r t?*963hhBuN8SSpymyk(FNJz8|z+dhGE$<rO=?VY<002ovPDHLkV1m!*Zu$TK literal 0 HcmV?d00001 diff --git a/images/TBCFluentSlider_200.png b/images/TBCFluentSlider_200.png new file mode 100644 index 0000000000000000000000000000000000000000..e60ad7e2a9c2579b7ea4f1107e1f86c949d56146 GIT binary patch literal 813 zcmV+|1JeA7P)<h;3K|Lk000e1NJLTq001xm001xu1^@s6R|5Hm00001b5ch_0Itp) z=>Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!T<mc!T}X1N`L?W0>Vi|K~!i%?U=uh z5>XJxhXq0bxEKlu0ul(tRR(`V?rg0suk&xPve1?Ui%TT_4O&@hM{K=|@wB)?3qr#2 zD?mcR&qRK%`&}M}eIVe;F1h4=k_~TX=e^9lotZZa2?PRxKp+qZt}hn$YdZCMT^S4p zG#-y>GMQ*HtJO+2n~fX}2l;%yt!y*hfm*Gmbh}-0xm@IQIyGZqG=MX3s^9NZuh%2D z+f9DIf31zCI#4JS6uaF{Uawa(d>wG4*=*8iG@?i(vbRY2Lq4BZRD+a%1#>W$Ewdl6 z^H(u`4(4JFwww;bUkzd&Ng4<Qm_*O_Vu#Kz+uHd4ZJF+dZ)jtlYPG5*IiC}TJCMue zlu#(N6!Yho9eVcuC!OY7Ofusr=Ak#o2dXoAN01YxQi<a6xOonsR8FT;>>88IfbkDr zow2*se0_1a<b?V*Ns=U8iIv!|Az;@~DtWN;n^>iTwXo(QmXnVc%G=W-U6eaav_pP% z=*R10Itbomf?3SpORwMkIp1C$>T;sdXiz4T(Hsc|gOp4rNqToyGRAnIOzD<a{|4p> zyA8aqEX#zD1m$v>ve_(2YL(Ii*AWy3>FH6J?u29}+A$W1D$PE-nSoNdExc~K-PV#A zAcPW$gt1kqSS%_Yk4Nii7I}2?WvP7fpqzew{*c|xKo8YwwJ018n^T4GiqV+ypw4e% zl@8Y8&l5u(K)ps+$(KIVchq_8G7n^{&H$`|wfHvM&=3Mfw-TmcWHa|yQmK@Ji{1V= zMzzz1=D;GcSj>Vdf>7XdVinMVF6Lk^6E9(!0{~xEh+}k>Xv|>Ta5&UXS6moFhG)=$ z?xwFXQyl<ELbSv<kWkYrl?tWP=}+qQ0b|JU3_9B+tmzKSK{>>M6pcn<<YV=Ef-z*< r{v!eQ=D@BH4hRGSfj}U*GDN=taLg<lh!Fe^00000NkvXXu0mjfvM*?c literal 0 HcmV?d00001 diff --git a/images/bgracontrols_images.res b/images/bgracontrols_images.res index 1acb388bf4e68cdc944b9d9ab91d6cb34d971762..4fe43106ece5b6ae051e40b3ee9b77531d90ca28 100644 GIT binary patch delta 5434 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 delta 16853 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 VKA^&BYJ+<Z_tK>KtbaE6{{s(xF`xhd diff --git a/images/bgracontrols_images_list.txt b/images/bgracontrols_images_list.txt index af38e65..08878be 100644 --- a/images/bgracontrols_images_list.txt +++ b/images/bgracontrols_images_list.txt @@ -102,4 +102,10 @@ tbccombobox_150.png tbccombobox_200.png tbgrathemecheckbox.png tbgrathemecheckbox_150.png -tbgrathemecheckbox_200.png \ No newline at end of file +tbgrathemecheckbox_200.png +tbcfluentprogressring.png +tbcfluentprogressring_150.png +tbcfluentprogressring_200.png +tbcfluentslider.png +tbcfluentslider_150.png +tbcfluentslider_200.png \ No newline at end of file diff --git a/test/test_bcfuentslider/unit1.pas b/test/test_bcfuentslider/unit1.pas index 6b56c9b..b730a9d 100644 --- a/test/test_bcfuentslider/unit1.pas +++ b/test/test_bcfuentslider/unit1.pas @@ -6,7 +6,7 @@ interface uses Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls, - BCFluentSlider; + BCFluentSlider, BCFluentProgressRing; type @@ -20,7 +20,10 @@ TForm1 = class(TForm) procedure CheckBox2Change(Sender: TObject); procedure FormCreate(Sender: TObject); private + procedure DestroyInternalEdit(Data: PtrInt); + procedure InternalEditEditingDone(Sender: TObject); procedure SliderChangeValue(Sender: TObject); + procedure SliderDblClick(Sender: TObject); public Slider: TBCFluentSlider; @@ -44,6 +47,7 @@ procedure TForm1.FormCreate(Sender: TObject); Left:= 10; Width:= 240; OnChangeValue:= @SliderChangeValue; + OnDblClick:= @SliderDblClick; Parent:= self; end; end; @@ -66,5 +70,50 @@ procedure TForm1.SliderChangeValue(Sender: TObject); Label1.Caption:= 'Value: '+IntToStr(Slider.Value); end; +procedure TForm1.SliderDblClick(Sender: TObject); +var + ed: TEdit; +begin + ed:= TEdit.Create(self); + ed.AutoSelect:= false; + if (Slider.Orientation = pbHorizontal) or (Slider.Orientation =pbRightToLeft) then + begin + ed.Top:= Slider.BoundsRect.Bottom; + ed.Left:= Slider.Left + Slider.ThumbPosition.X - Slider.ThumbRadius; + end + else + begin + ed.Top:= Slider.Top + Slider.ThumbPosition.Y - Slider.ThumbRadius; + ed.Left:= Slider.BoundsRect.Right; + end; + ed.Parent:= self; + ed.OnEditingDone:= @InternalEditEditingDone; + ed.OnMouseLeave:= @InternalEditEditingDone; + ed.SetFocus; +end; + +procedure TForm1.DestroyInternalEdit(Data: PtrInt); +var + ed: TEdit; +begin + ed:= TEdit(Data); + ed.Free; +end; + +procedure TForm1.InternalEditEditingDone(Sender: TObject); +var + ed: TEdit; +begin + if Sender is TEdit then + begin + ed:= TEdit(Sender); + Label1.Caption:= ed.Text; + ed.OnEditingDone:= nil; + ed.OnMouseLeave:= nil; + ed.Visible:= false; + Application.QueueAsyncCall(@DestroyInternalEdit, PtrInt(ed)); + end; +end; + end. From dab1c8b7af47969879670824d2bc7c0c72daff5a Mon Sep 17 00:00:00 2001 From: Leandro Diaz <lainz@users.noreply.github.com> Date: Sun, 5 May 2024 10:51:44 -0300 Subject: [PATCH 3/3] v9.0.1 --- bgracontrolsinfo.pas | 2 +- bgrapascalscriptcomponent.lpk | 2 +- update_bgracontrols_force.json | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/bgracontrolsinfo.pas b/bgracontrolsinfo.pas index 8d82fe5..ee39233 100644 --- a/bgracontrolsinfo.pas +++ b/bgracontrolsinfo.pas @@ -9,7 +9,7 @@ interface Classes, SysUtils; const - BGRAControlsVersion = 9000000; + BGRAControlsVersion = 9000100; function BGRAControlsVersionStr: string; diff --git a/bgrapascalscriptcomponent.lpk b/bgrapascalscriptcomponent.lpk index 4ef6e2b..8d35586 100644 --- a/bgrapascalscriptcomponent.lpk +++ b/bgrapascalscriptcomponent.lpk @@ -11,7 +11,7 @@ <UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/> </SearchPaths> </CompilerOptions> - <Version Major="9"/> + <Version Major="9" Release="1"/> <Files Count="3"> <Item1> <Filename Value="bgrapascalscript.pas"/> diff --git a/update_bgracontrols_force.json b/update_bgracontrols_force.json index 7a5b170..3b65fa3 100644 --- a/update_bgracontrols_force.json +++ b/update_bgracontrols_force.json @@ -8,13 +8,13 @@ "ForceNotify" : true, "InternalVersion" : 25, "Name" : "bgracontrols.lpk", - "Version" : "9.0.0.0" + "Version" : "9.0.1.0" }, { "ForceNotify" : false, "InternalVersion" : 1, "Name" : "bgrapascalscriptcomponent.lpk", - "Version" : "9.0.0.0" + "Version" : "9.0.1.0" } ] } \ No newline at end of file