📄 jvqxslider.pas
字号:
function TJvCustomSlider.GetSliderRect: TRect;
begin
Result := Bounds(0, 0, Width, Height);
if BevelStyle <> bvNone then
InflateRect(Result, -FBevelWidth, -FBevelWidth);
end;
procedure TJvCustomSlider.DrawThumb(Canvas: TCanvas; Origin: TPoint;
Highlight: Boolean);
var
R: TRect;
Image: TBitmap;
TransColor: TColor;
begin
if Orientation = soHorizontal then
Image := ImageHThumb
else
Image := ImageVThumb;
R := Rect(0, 0, Image.Width, Image.Height);
if NumThumbStates = 2 then
begin
if Highlight then
R.Left := (R.Right - R.Left) div 2
else
R.Right := (R.Right - R.Left) div 2;
end;
if soThumbOpaque in Options then
TransColor := clNone
else
TransColor := Image.TransparentColor;
DrawBitmapRectTransparent(Canvas, Origin.X, Origin.Y, R, Image, TransColor);
end;
procedure TJvCustomSlider.InternalDrawPoints(ACanvas: TCanvas; PointsStep,
PointsHeight, ExtremePointsHeight: Longint);
const
MinInterval = 3;
var
RulerLength: Integer;
Interval, Scale, PointsCnt, I, Val: Longint;
X, H, X1, X2, Y1, Y2: Integer;
Range: Double;
begin
RulerLength := GetRulerLength;
ACanvas.Pen.Color := clWindowText;
Scale := 0;
Range := MaxValue - MinValue;
repeat
Inc(Scale);
PointsCnt := Round(Range / (Scale * PointsStep)) + 1;
if PointsCnt > 1 then
Interval := RulerLength div (PointsCnt - 1)
else
Interval := RulerLength;
until (Interval >= MinInterval + 1) or (Interval >= RulerLength);
Val := MinValue;
for I := 1 to PointsCnt do
begin
H := PointsHeight;
if I = PointsCnt then
Val := MaxValue;
if (Val = MaxValue) or (Val = MinValue) then
H := ExtremePointsHeight;
X := GetOffsetByValue(Val);
if Orientation = soHorizontal then
begin
X1 := X + (FImages[siHThumb].Width div NumThumbStates) div 2;
Y1 := FPointsRect.Top;
X2 := X1;
Y2 := Y1 + H;
end
else
begin
X1 := FPointsRect.Left;
Y1 := X + FImages[siVThumb].Height div 2;
X2 := X1 + H;
Y2 := Y1;
end;
with ACanvas do
begin
MoveTo(X1, Y1);
LineTo(X2, Y2);
end;
Inc(Val, Scale * PointsStep);
end;
end;
procedure TJvCustomSlider.DefaultDrawPoints(PointsStep, PointsHeight,
ExtremePointsHeight: Longint);
begin
InternalDrawPoints(Canvas, PointsStep, PointsHeight, ExtremePointsHeight);
end;
procedure TJvCustomSlider.CreateElements;
var
I: TSliderImage;
begin
FRuler := TBitmap.Create;
for I := Low(FImages) to High(FImages) do
SetImage(Ord(I), nil);
AdjustElements;
end;
procedure TJvCustomSlider.BuildRuler(R: TRect);
var
DstR, BmpR: TRect;
I, L, B, N, C, Offs, Len, RulerWidth: Integer;
TmpBmp: TBitmap;
Index: TSliderImage;
begin
TmpBmp := TBitmap.Create;
try
if Orientation = soHorizontal then
Index := siHRuler
else
Index := siVRuler;
if Orientation = soHorizontal then
begin
L := R.Right - R.Left - 2 * Indent;
if L < 0 then
L := 0;
TmpBmp.Width := L;
TmpBmp.Height := FImages[Index].Height;
L := TmpBmp.Width - 2 * FEdgeSize;
B := FImages[Index].Width - 2 * FEdgeSize;
RulerWidth := FImages[Index].Width;
end
else
begin
TmpBmp.Width := FImages[Index].Width;
TmpBmp.Height := R.Bottom - R.Top - 2 * Indent;
L := TmpBmp.Height - 2 * FEdgeSize;
B := FImages[Index].Height - 2 * FEdgeSize;
RulerWidth := FImages[Index].Height;
end;
N := (L div B) + 1;
C := L mod B;
for I := 0 to N - 1 do
begin
if I = 0 then
begin
Offs := 0;
Len := RulerWidth - FEdgeSize;
end
else
begin
Offs := FEdgeSize + I * B;
if I = N - 1 then
Len := C + FEdgeSize
else
Len := B;
end;
if Orientation = soHorizontal then
DstR := Rect(Offs, 0, Offs + Len, TmpBmp.Height)
else
DstR := Rect(0, Offs, TmpBmp.Width, Offs + Len);
if I = 0 then
Offs := 0
else
if I = N - 1 then
Offs := FEdgeSize + B - C
else
Offs := FEdgeSize;
if Orientation = soHorizontal then
BmpR := Rect(Offs, 0, Offs + DstR.Right - DstR.Left, TmpBmp.Height)
else
BmpR := Rect(0, Offs, TmpBmp.Width, Offs + DstR.Bottom - DstR.Top);
TmpBmp.Canvas.CopyRect(DstR, FImages[Index].Canvas, BmpR);
end;
FRuler.Assign(TmpBmp);
finally
TmpBmp.Free;
end;
end;
procedure TJvCustomSlider.AdjustElements;
var
SaveValue: Longint;
R: TRect;
begin
SaveValue := Value;
R := SliderRect;
BuildRuler(R);
if Orientation = soHorizontal then
begin
if FImages[siHThumb].Height > FRuler.Height then
begin
FThumbRect := Bounds(R.Left + Indent, R.Top + Indent,
FImages[siHThumb].Width div NumThumbStates, FImages[siHThumb].Height);
FRulerOrg := Point(R.Left + Indent, R.Top + Indent +
(FImages[siHThumb].Height - FRuler.Height) div 2);
FPointsRect := Rect(FRulerOrg.X, R.Top + Indent +
FImages[siHThumb].Height + 1,
FRulerOrg.X + FRuler.Width, R.Bottom - R.Top - 1);
end
else
begin
FThumbRect := Bounds(R.Left + Indent, R.Top + Indent +
(FRuler.Height - FImages[siHThumb].Height) div 2,
FImages[siHThumb].Width div NumThumbStates, FImages[siHThumb].Height);
FRulerOrg := Point(R.Left + Indent, R.Top + Indent);
FPointsRect := Rect(FRulerOrg.X, R.Top + Indent + FRuler.Height + 1,
FRulerOrg.X + FRuler.Width, R.Bottom - R.Top - 1);
end;
end
else
begin { soVertical }
if FImages[siVThumb].Width div NumThumbStates > FRuler.Width then
begin
FThumbRect := Bounds(R.Left + Indent, R.Top + Indent,
FImages[siVThumb].Width div NumThumbStates, FImages[siVThumb].Height);
FRulerOrg := Point(R.Left + Indent + (FImages[siVThumb].Width div NumThumbStates -
FRuler.Width) div 2, R.Top + Indent);
FPointsRect := Rect(R.Left + Indent + FImages[siVThumb].Width div NumThumbStates + 1,
FRulerOrg.Y, R.Right - R.Left - 1, FRulerOrg.Y + FRuler.Height);
end
else
begin
FThumbRect := Bounds(R.Left + Indent + (FRuler.Width -
FImages[siVThumb].Width div NumThumbStates) div 2, R.Top + Indent,
FImages[siVThumb].Width div NumThumbStates, FImages[siVThumb].Height);
FRulerOrg := Point(R.Left + Indent, R.Top + Indent);
FPointsRect := Rect(R.Left + Indent + FRuler.Width + 1, FRulerOrg.Y,
R.Right - R.Left - 1, FRulerOrg.Y + FRuler.Height);
end;
end;
Value := SaveValue;
Invalidate;
end;
procedure TJvCustomSlider.Sized;
begin
AdjustElements;
end;
procedure TJvCustomSlider.Change;
begin
if Assigned(FOnChange) then
FOnChange(Self);
end;
procedure TJvCustomSlider.Changed;
begin
if Assigned(FOnChanged) then
FOnChanged(Self);
end;
procedure TJvCustomSlider.RangeChanged;
begin
end;
procedure TJvCustomSlider.DefineProperties(Filer: TFiler);
function DoWrite: Boolean;
begin
if Assigned(Filer.Ancestor) then
Result := FUserImages <> TJvCustomSlider(Filer.Ancestor).FUserImages
else
Result := FUserImages <> [];
end;
begin
if Filer is TReader then
inherited DefineProperties(Filer);
Filer.DefineBinaryProperty('UserImages', ReadUserImages, WriteUserImages,DoWrite);
end;
procedure TJvCustomSlider.ReadUserImages(Stream: TStream);
begin
Stream.ReadBuffer(FUserImages, SizeOf(FUserImages));
end;
procedure TJvCustomSlider.WriteUserImages(Stream: TStream);
begin
Stream.WriteBuffer(FUserImages, SizeOf(FUserImages));
end;
function TJvCustomSlider.StoreImage(Index: Integer): Boolean;
begin
Result := TSliderImage(Index) in FUserImages;
end;
function TJvCustomSlider.GetImage(Index: Integer): TBitmap;
begin
Result := FImages[TSliderImage(Index)];
end;
procedure TJvCustomSlider.SliderImageChanged(Sender: TObject);
begin
if not (csCreating in ControlState) then
Sized;
end;
procedure TJvCustomSlider.SetImage(Index: Integer; Value: TBitmap);
var
Idx: TSliderImage;
begin
Idx := TSliderImage(Index);
if FImages[Idx] = nil then
begin
FImages[Idx] := TBitmap.Create;
FImages[Idx].OnChange := SliderImageChanged;
end;
if Value = nil then
begin
FImages[Idx].Handle := LoadBitmap(HInstance, ImagesResNames[Idx]);
Exclude(FUserImages, Idx);
if not (csReading in ComponentState) then
begin
if Idx in [siHThumb, siVThumb] then
Exclude(FOptions, soThumbOpaque)
else
Exclude(FOptions, soRulerOpaque);
Invalidate;
end;
end
else
begin
FImages[Idx].Assign(Value);
Include(FUserImages, Idx);
end;
end;
procedure TJvCustomSlider.SetEdgeSize(Value: Integer);
var
MaxSize: Integer;
begin
if Orientation = soHorizontal then
MaxSize := FImages[siHRuler].Width
else
MaxSize := FImages[siVRuler].Height;
if Value * 2 < MaxSize then
if Value <> FEdgeSize then
begin
FEdgeSize := Value;
Sized;
end;
end;
function TJvCustomSlider.GetNumThumbStates: TNumThumbStates;
begin
Result := FNumThumbStates;
end;
procedure TJvCustomSlider.SetNumThumbStates(Value: TNumThumbStates);
begin
if FNumThumbStates <> Value then
begin
FNumThumbStates := Value;
AdjustElements;
end;
end;
procedure TJvCustomSlider.SetBevelStyle(Value: TPanelBevel);
begin
if Value <> FBevelStyle then
begin
FBevelStyle := Value;
Sized;
Update;
end;
end;
procedure TJvCustomSlider.SetOrientation(Value: TSliderOrientation);
begin
if Orientation <> Value then
begin
FOrientation := Value;
Sized;
if ComponentState * [csLoading, csUpdating] = [] then
SetBounds(Left, Top, Height, Width);
end;
end;
procedure TJvCustomSlider.SetOptions(Value: TSliderOptions);
begin
if Value <> FOptions then
begin
FOptions := Value;
Invalidate;
end;
end;
procedure TJvCustomSlider.SetRange(Min, Max: Longint);
begin
if (Min < Max) or (csReading in ComponentState) then
begin
FMinValue := Min;
FMaxValue := Max;
if not (csReading in ComponentState) then
if Min + Increment > Max then
FIncrement := Max - Min;
if (soShowPoints in Options) then
Invalidate;
Self.Value := FValue;
RangeChanged;
end;
end;
procedure TJvCustomSlider.SetMinValue(Value: Longint);
begin
if FMinValue <> Value then
SetRange(Value, MaxValue);
end;
procedure TJvCustomSlider.SetMaxValue(Value: Longint);
begin
if FMaxValue <> Value then
SetRange(MinValue, Value);
end;
procedure TJvCustomSlider.SetIncrement(Value: Longint);
begin
if not (csReading in ComponentState) and ((Value > MaxValue - MinValue) or
(Value < 1)) then
raise EJVCLException.CreateResFmt(@SOutOfRange, [1, MaxValue - MinValue]);
if (Value > 0) and (FIncrement <> Value) then
begin
FIncrement := Value;
Self.Value := FValue;
Invalidate;
end;
end;
function TJvCustomSlider.GetValueByOffset(Offset: Integer): Longint;
var
Range: Double;
R: TRect;
begin
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -