📄 iknob.pas
字号:
MinorRadius2 : Double;
TextRadius : Double;
TextPoint : TPoint;
TickValue : Double;
TextString : String;
x, y : Integer;
CurrentMin : Double;
CurrentMax : Double;
CurrentPosition : Double;
MajorStepSize : Double;
MinorStepSize : Double;
begin
with Canvas do
begin
Brush.Style := bsClear;
MajorRadius1 := FKnobRadius + TickMargin - 1;
MajorRadius2 := FKnobRadius + TickMargin + TickMajorLength;
case TickMinorAlignment of
itmnaInside : begin
MinorRadius1 := MajorRadius1;
MinorRadius2 := MajorRadius1 + TickMinorLength;
end;
itmnaCenter : begin
MinorRadius1 := (MajorRadius1 + MajorRadius2)/2 - TickMinorLength/2;
MinorRadius2 := (MajorRadius1 + MajorRadius2)/2 + TickMinorLength/2;
end;
itmnaOutside : begin
MinorRadius1 := MajorRadius2;
MinorRadius2 := MajorRadius2 - TickMinorLength;
end;
else begin
MinorRadius1 := 0;
MinorRadius2 := 0;
end;
end;
if not ShowTicksMajor then MajorRadius1 := FKnobRadius;
if AutoScaleEnabled and (AutoScaleStyle = iassFixedMinMax) then
begin
CurrentMin := FAutoScaleMinTick;
CurrentMax := FAutoScaleMaxTick;
end
else
begin
CurrentMin := PositionMin;
CurrentMax := PositionMax;
end;
MajorStepSize := (CurrentMax-CurrentMin)/(TickMajorCount - 1);
MinorStepSize := MajorStepSize /(TickMinorCount + 1);
for x := 0 to TickMajorCount - 1 do
begin
CurrentPosition := CurrentMin + MajorStepSize * x;
//------------------------------------------------------------------------------------------------------------------------------------------
if ShowTicksMajor then
begin
Pen.Color := TickMajorColor;
OuterPoint := GetXYRadPoint(PositionToDegrees(CurrentPosition), MajorRadius1, CenterPoint);
InnerPoint := GetXYRadPoint(PositionToDegrees(CurrentPosition), MajorRadius2, CenterPoint);
Polyline([InnerPoint, OuterPoint]);
end;
//------------------------------------------------------------------------------------------------------------------------------------------
if ShowTickLabels then
begin
TickValue := (CurrentMax - CurrentMin) /(TickMajorCount-1) * x + CurrentMin;
TextString := Trim(SysUtils.Format('%.' + IntToStr(GetDecimalPoints) + 'f', [TickValue]));
if Assigned(OnCustomizeTickLabel) then TOnCustomizeTickLabel(OnCustomizeTickLabel)(Self, x, TextString);
Font.Assign(TickLabelFont);
TextRadius := MajorRadius2 + TickLabelMargin + 4;
TextPoint := GetXYRadPoint(PositionToDegrees(CurrentPosition), TextRadius, CenterPoint);
TextOut(TextPoint.x - TextWidth (TextString) div 2, TextPoint.y - TextHeight(TextString) div 2, TextString);
end;
//------------------------------------------------------------------------------------------------------------------------------------------
if ShowTicksMinor and (x < TickMajorCount - 1) then
begin
Pen.Color := TickMinorColor;
for y := 1 to TickMinorCount do
begin
CurrentPosition := CurrentMin + MajorStepSize*x + MinorStepSize*y;
OuterPoint := GetXYRadPoint(PositionToDegrees(CurrentPosition), MinorRadius1, CenterPoint);
InnerPoint := GetXYRadPoint(PositionToDegrees(CurrentPosition), MinorRadius2, CenterPoint);
Polyline([InnerPoint, OuterPoint]);
end;
end;
end;
//------------------------------------------------------------------------------------------------------------------------------------------
if (AutoScaleStyle = iassFixedMinMax) and ShowTicksMinor and (MinorStepSize <> 0) then
begin
CurrentPosition := FAutoScaleMaxTick + MinorStepSize;
while CurrentPosition <= PositionMax do
begin
OuterPoint := GetXYRadPoint(PositionToDegrees(CurrentPosition), MinorRadius1, CenterPoint);
InnerPoint := GetXYRadPoint(PositionToDegrees(CurrentPosition), MinorRadius2, CenterPoint);
Polyline([InnerPoint, OuterPoint]);
CurrentPosition := CurrentPosition + MinorStepSize;
end;
CurrentPosition := FAutoScaleMinTick - MinorStepSize;
while CurrentPosition >= PositionMin do
begin
OuterPoint := GetXYRadPoint(PositionToDegrees(CurrentPosition), MinorRadius1, CenterPoint);
InnerPoint := GetXYRadPoint(PositionToDegrees(CurrentPosition), MinorRadius2, CenterPoint);
Polyline([InnerPoint, OuterPoint]);
CurrentPosition := CurrentPosition - MinorStepSize;
end;
end;
end;
end;
//****************************************************************************************************************************************************
procedure TiKnob.DrawPosition(Canvas: TCanvas; const CenterPoint: TPoint);
var
TextString : String;
x, y : Integer;
begin
with Canvas do
begin
if FShowPostionDisplay then
begin
Brush.Style := bsClear;
Font.Assign(FPositionDisplayFont);
TextString := Trim(Format('%4.' + IntToStr(FPositionDisplayPrecision) + 'f',[Position])) + FPositionDisplayUnits;
y := CenterPoint.y - TextHeight(TextString) div 2;
x := CenterPoint.x - TextWidth(TextString) div 2;
TextOut(x, y, TextString);
end;
end;
end;
//****************************************************************************************************************************************************
function TiKnob.GetXYRadPoint2(AngleDegrees, Radius: Double; OffsetX, OffsetY : Double) : TPoint;
begin
Result := Point(Trunc(OffsetX + Cos(DegToRad(AngleDegrees))*Radius),Trunc(OffsetY - Sin(DegToRad(AngleDegrees))*Radius));
end;
//****************************************************************************************************************************************************
procedure TiKnob.iWantSpecialKey(var CharCode: Word; var Result: Longint);
begin
inherited iWantSpecialKey(CharCode, Result);
if FUseKeyboard then
begin
if CharCode in [VK_LEFT, VK_DOWN, VK_RIGHT, VK_UP] then Result := 1 else Result := 0;
end;
end;
//****************************************************************************************************************************************************
procedure TiKnob.iKeyUp(var CharCode: Word; Shift: TShiftState);
begin
inherited;
InvalidateChange;
if FKeyDown then
begin
FKeyDown := False;
if PositionedChanged then DoPositionChangeFinished;
end;
end;
//****************************************************************************************************************************************************
procedure TiKnob.iKeyDown(var CharCode: Word; Shift: TShiftState);
begin
if FUseKeyboard then
begin
FKeyDown := True;
UserGenerated := True;
try
//KYLIX TODO
{$ifndef iCLX}
if (CharCode = VK_LEFT) or (CharCode = VK_DOWN) then
begin
Position := Position - FKeyArrowStepSize;
CharCode := 0;
end
else if (CharCode = VK_RIGHT) or (CharCode = VK_UP) then
begin
Position := Position + FKeyArrowStepSize;
CharCode := 0;
end
else if (CharCode = VK_PRIOR) then //PageUp
begin
Position := Position + FKeyPageStepSize;
CharCode := 0;
end
else if (CharCode = VK_NEXT) then //PageDown
begin
Position := Position - FKeyPageStepSize;
CharCode := 0;
end
else if (CharCode = VK_HOME) then
begin
Position := PositionMin;
CharCode := 0;
end
else if (CharCode = VK_END) then
begin
Position := PositionMax;
CharCode := 0;
end;
{$endif}
finally
UserGenerated := False;
end;
end;
inherited;
end;
//****************************************************************************************************************************************************
procedure TiKnob.DefineProperties(Filer: TFiler);
begin
inherited DefineProperties(Filer);
Filer.DefineProperty('KeyArrowStepSize_2', ReadKeyArrowStepSize, WriteKeyArrowStepSize, True);
Filer.DefineProperty('KeyPageStepSize_2', ReadKeyPageStepSize, WriteKeyPageStepSize, True);
end;
//****************************************************************************************************************************************************
procedure TiKnob.ReadKeyArrowStepSize(Reader: TReader);
begin
FKeyArrowStepSize := Reader.ReadFloat;
end;
//****************************************************************************************************************************************************
procedure TiKnob.ReadKeyPageStepSize(Reader: TReader);
begin
FKeyPageStepSize := Reader.ReadFloat;
end;
//****************************************************************************************************************************************************
procedure TiKnob.WriteKeyArrowStepSize(Writer: TWriter);
begin
Writer.WriteFloat(FKeyArrowStepSize);
end;
//****************************************************************************************************************************************************
procedure TiKnob.WriteKeyPageStepSize(Writer: TWriter);
begin
Writer.WriteFloat(FKeyPageStepSize);
end;
//****************************************************************************************************************************************************
procedure TiKnob.DoOPCPositionChangeFinished;
begin
OPCOutputData('Position', Position);
end;
//****************************************************************************************************************************************************
{$ifdef iVCL}function TiKnob.DoMouseWheel(Shift: TShiftState; WheelDelta: Integer; MousePos: TPoint ): Boolean;{$endif}
{$ifdef iCLX}function TiKnob.DoMouseWheel(Shift: TShiftState; WheelDelta: Integer; const MousePos: TPoint): Boolean;{$endif}
begin
Result := inherited DoMouseWheel(Shift, WheelDelta, MousePos);
if (Now -FLastWheelTime)*24*60*60*1000 < 30 then Exit;
FLastWheelTime := Now;
UserGenerated := True;
try
Position := Position + WheelDelta/ABS(WheelDelta) * FMouseWheelStepSize;
DoPositionChangeFinished;
finally
UserGenerated := False;
end;
end;
//****************************************************************************************************************************************************
procedure TiKnob.iDoKillFocus;
begin
inherited;
FMouseDown := False;
FKeyDown := False;
end;
//****************************************************************************************************************************************************
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -