📄 qiknob.pas
字号:
FIndicatorSize := Value;
if FIndicatorSize < 1 then FIndicatorSize := 1;
InvalidateChange;
end;
end;
//****************************************************************************************************************************************************
procedure TiKnob.SetPositionDisplayUnits(const Value: String);
begin
if FPositionDisplayUnits <> Value then
begin
FPositionDisplayUnits := Value;
if Trim(FPositionDisplayUnits) = '' then FPositionDisplayUnits := '';
InvalidateChange;
end;
end;
//****************************************************************************************************************************************************
procedure TiKnob.iMouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
var
X1, Y1 : Integer;
begin
if (Button = mbLeft) and Enabled then
begin
PositionedChanged := False;
SetFocus;
X1 := x - FCenterPoint.x;
Y1 := y - FCenterPoint.y;
if Round(Sqrt(X1*X1 + Y1*Y1)) < FKnobRadius then
begin
FMouseDown := True;
FMouseDownDegrees := RadToDeg(ArcTan2(Y-FCenterPoint.Y,X-FCenterPoint.x));
InvalidateChange;
end;
end;
end;
//****************************************************************************************************************************************************
procedure TiKnob.iMouseMove(Shift: TShiftState; X, Y: Integer);
var
CurrentDegrees : Double;
DeltaAngle : Double;
begin
if FMouseDown then
begin
CurrentDegrees := RadToDeg(ArcTan2(Y-FCenterPoint.y,X-FCenterPoint.x));
DeltaAngle := FMouseDownDegrees - CurrentDegrees;
if DeltaAngle > 200 then DeltaAngle := DeltaAngle - 360;
if DeltaAngle < -200 then DeltaAngle := DeltaAngle + 360;
UserGenerated := True;
try
PositionDegrees := PositionDegrees - DeltaAngle;
finally
UserGenerated := False;
end;
FMouseDownDegrees := CurrentDegrees;
InvalidateChange;
end;
end;
//****************************************************************************************************************************************************
procedure TiKnob.iMouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
InvalidateChange;
if FMouseDown then
begin
FMouseDown := False;
DoPositionChangeFinished;
end;
end;
//****************************************************************************************************************************************************
function TiKnob.GetPositionDegrees : Double;
begin
if PositionMax = PositionMin then Result := FRotationStartDegrees
else Result := FRotationMaxDegrees * ValuePercent(Position);
end;
//****************************************************************************************************************************************************
function TiKnob.PositionToDegrees(Value: Double): Double;
begin
Result := FRotationStartDegrees - FRotationMaxDegrees * ValuePercent(Value);
end;
//****************************************************************************************************************************************************
procedure TiKnob.AdjustKnobRadius(Canvas: TCanvas; const CenterPoint: TPoint);
var
KnobDiameter : Integer;
x : Integer;
TickValue : Double;
TextPoint : TPoint;
TextString : String;
ATextWidth : Integer;
ATextHeight : Integer;
MaxWidth : Integer;
MaxHeight : Integer;
begin
with Canvas do
begin
Font.Assign(TickLabelFont);
if Width < Height then KnobDiameter := Width - 2*FOuterMargin
else KnobDiameter := Height - 2*FOuterMargin;
MaxWidth := 0;
MaxHeight := 0;
if ShowTickLabels then
begin
for x := 0 to TickMajorCount - 1 do
begin
TickValue := (PositionMax - PositionMin)/(TickMajorCount-1) * x + PositionMin;
TextPoint := GetXYRadPoint(PositionToDegrees(TickValue), 1, Point(0,0));
TextString := Trim(Format('%.' + IntToStr(GetDecimalPoints) + 'f', [TickValue]));
ATextWidth := ABS(TextWidth (TextString) * TextPoint.x);
ATextHeight := ABS(TextHeight(TextString) * TextPoint.y);
if ATextWidth > MaxWidth then MaxWidth := ATextWidth;
if ATextHeight > MaxHeight then MaxHeight := ATextHeight;
end;
if MaxWidth > MaxHeight then KnobDiameter := KnobDiameter - MaxWidth
else KnobDiameter := KnobDiameter - MaxHeight;
KnobDiameter := KnobDiameter - 2*(TickMargin + TickMajorLength + TickLabelMargin + 4);
end
else if ShowTicksMajor or ShowTicksMinor then
begin
KnobDiameter := KnobDiameter - 2*(TickMargin + TickMajorLength);
end;
FKnobRadius := KnobDiameter div 2;
end;
end;
//****************************************************************************************************************************************************
procedure TiKnob.iPaintTo(Canvas: TCanvas);
begin
FCenterPoint := GetCenterPoint(Canvas);
if CachedDrawing then
begin
if BackGroundChanged then
begin
CreateBackGroundBitmap;
if FAutoSize then AdjustKnobRadius(BackGroundBitmap.Canvas, FCenterPoint);
DrawBackGround(BackGroundBitmap.Canvas, BackGroundColor);
DrawKnob (BackGroundBitmap.Canvas, FCenterPoint);
DrawTicks (BackGroundBitmap.Canvas, FCenterPoint);
ResetBackGroundChange;
end;
TransferBackGround(Canvas);
end
else
begin
if FAutoSize then AdjustKnobRadius(Canvas, FCenterPoint);
DrawBackGround(Canvas, BackGroundColor);
DrawKnob (Canvas, FCenterPoint);
DrawTicks (Canvas, FCenterPoint);
end;
DrawPosition (Canvas, FCenterPoint);
DrawIndicator(Canvas, FCenterPoint);
if FShowFocusRect and HasFocus then iDrawFocusRect(Canvas, ClientRect, BackGroundColor);
end;
//****************************************************************************************************************************************************
procedure TiKnob.DrawKnob(Canvas: TCanvas; const CenterPoint: TPoint);
var
OuterRect : TRect;
InnerRect : TRect;
ReverseColors : Boolean;
begin
case FKnobStyle of
iksRaisedEdge : ReverseColors := False;
iksRaised : ReverseColors := False;
iksSunken : ReverseColors := True;
iksSunkenEdge : ReverseColors := True;
else ReverseColors := False;
end;
with Canvas do
begin
OuterRect := Rect(CenterPoint.x - (FKnobRadius),
CenterPoint.y - (FKnobRadius),
CenterPoint.x + (FKnobRadius),
CenterPoint.y + (FKnobRadius));
InnerRect := Rect(CenterPoint.x - (FKnobRadius - FKnobEdgeWidth),
CenterPoint.y - (FKnobRadius - FKnobEdgeWidth),
CenterPoint.x + (FKnobRadius - FKnobEdgeWidth),
CenterPoint.y + (FKnobRadius - FKnobEdgeWidth));
DrawGradientCircle(Canvas, CenterPoint, FKnobRadius, ReverseColors);
Pen.Color := BackGroundColor;
if (FKnobStyle = iksRaisedEdge) or (FKnobStyle = ikssunkenEdge) then
begin
Brush.Style := bsSolid;
Brush.Color := clBtnFace;
Pen.Color := clBtnFace;
with InnerRect do
Ellipse(Left, Top, Right, Bottom);
end;
end;
end;
//****************************************************************************************************************************************************
procedure TiKnob.DrawIndicator(Canvas: TCanvas; const CenterPoint: TPoint);
var
InnerPoint : TPoint;
OuterPoint : TPoint;
IndicatorCenterPoint : Tpoint;
IndicatorRect : TRect;
IndicatorDegrees : Double;
PointerEndPoint : TPoint;
PointerBasePoint : TPoint;
Point1 : TPoint;
Point2 : Tpoint;
begin
IndicatorDegrees := RotationStartDegrees - PositionDegrees;
with Canvas, IndicatorRect do
begin
Brush.Style := bsSolid;
IndicatorCenterPoint := GetXYRadPoint(IndicatorDegrees, FKnobRadius - FIndicatorMargin - FIndicatorSize, CenterPoint);
IndicatorRect := Rect(IndicatorCenterPoint.x - FIndicatorSize,
IndicatorCenterPoint.y - FIndicatorSize,
IndicatorCenterPoint.x + FIndicatorSize,
IndicatorCenterPoint.y + FIndicatorSize);
if FMouseDown or FKeyDown then begin Pen.Color := FIndicatorActiveColor; Brush.Color := FIndicatorActiveColor end
else begin Pen.Color := FIndicatorInactiveColor; Brush.Color := FIndicatorInactiveColor; end;
case FIndicatorStyle of
ikisDotLowered : begin
Ellipse(Left, Top, Right, Bottom);
Pen.Color := clGray; Arc(Left, Top, Right, Bottom, Right, Top , Left , Bottom);
Pen.Color := clWhite; Arc(Left, Top, Right, Bottom, Left , Bottom, Right, Top );
end;
ikisDotRaised : begin
Ellipse(Left, Top, Right, Bottom);
Pen.Color := clWhite; Arc(Left, Top, Right, Bottom, Right, Top , Left , Bottom);
Pen.Color := clGray; Arc(Left, Top, Right, Bottom, Left , Bottom, Right, Top );
end;
ikisDot : begin
Ellipse(Left, Top, Right, Bottom);
end;
ikisLineCenter : begin
OuterPoint:=GetXYRadPoint(IndicatorDegrees,FKnobRadius-FIndicatorMargin,CenterPoint);
PolyLine([OuterPoint, CenterPoint]);
end;
ikisLineCustom : begin
OuterPoint:=GetXYRadPoint(IndicatorDegrees,FKnobRadius-FIndicatorMargin, CenterPoint);
InnerPoint:=GetXYRadPoint(IndicatorDegrees,FKnobRadius-FIndicatorMargin-FIndicatorSize,CenterPoint);
PolyLine([OuterPoint, InnerPoint]);
end;
ikisTriangle : begin
PointerEndPoint :=GetXYRadPoint(IndicatorDegrees,FKnobRadius-FIndicatorMargin, CenterPoint);
PointerBasePoint:=GetXYRadPoint(IndicatorDegrees,FKnobRadius-FIndicatorMargin-FIndicatorSize,CenterPoint);
Point1 := GetXYRadPoint(IndicatorDegrees + 90, FIndicatorSize/2, PointerBasePoint);
Point2 := GetXYRadPoint(IndicatorDegrees - 90, FIndicatorSize/2, PointerBasePoint);
Polygon([Point1, Point2, PointerEndPoint]);
end;
end;
end;
end;
//****************************************************************************************************************************************************
procedure TiKnob.DrawTicks(Canvas: TCanvas; const CenterPoint: TPoint);
var
OuterPoint : TPoint;
InnerPoint : TPoint;
MajorRadius1 : Double;
MajorRadius2 : Double;
MinorRadius1 : Double;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -