📄 jvqsegmentedleddisplay.pas
字号:
Result := Display.DigitWidth + MaxSlantDif;
end;
procedure TJvCustomSegmentedLEDDigit.SetText(Value: string);
var
P: PChar;
begin
if Value <> Text then
begin
if Display.CharacterMapper <> nil then
begin
P := PChar(Value);
Display.CharacterMapper.MapText(P, Self);
end
else
UpdateText(Value);
Display.UpdateText;
end;
end;
procedure TJvCustomSegmentedLEDDigit.EnableAllSegs;
begin
end;
function TJvCustomSegmentedLEDDigit.GetSegmentRenderInfo(Index: Integer;
out RenderType: TSegmentRenderType; out Points: TPointArray): Boolean;
begin
Result := (Index >= 0) and (Index < SegmentCount);
if Result then
begin
RenderType := FSegmentRenderInfo[Index].RenderType;
Points := FSegmentRenderInfo[Index].Points;
end;
end;
procedure TJvCustomSegmentedLEDDigit.SetSegmentRenderInfo(Index: Integer;
RenderType: TSegmentRenderType; Points: array of TPoint);
begin
FSegmentRenderInfo[Index].RenderType := RenderType;
SetLength(FSegmentRenderInfo[Index].Points, Length(Points));
if Length(Points) > 0 then
Move(Points[0], FSegmentRenderInfo[Index].Points[0], Length(Points) * SizeOf(Points[0]));
end;
function TJvCustomSegmentedLEDDigit.GetSegmentState(Index: Integer): Boolean;
begin
Result := (FSegmentStates and (1 shl Index)) <> 0;
end;
procedure TJvCustomSegmentedLEDDigit.SetSegmentState(Index: Integer; Value: Boolean);
begin
if Value <> GetSegmentState(Index) then
begin
FSegmentStates := FSegmentStates xor (1 shl Index);
InvalidateStates;
end;
end;
procedure TJvCustomSegmentedLEDDigit.SetSegmentStates(Value: Int64);
begin
if Value <> FSegmentStates then
begin
FSegmentStates := Value;
InvalidateStates;
end;
end;
procedure TJvCustomSegmentedLEDDigit.UpdateText(Value: string);
begin
if Value <> Text then
begin
FText := Value;
Display.UpdateText;
end;
end;
function TJvCustomSegmentedLEDDigit.GetLitSegColor(Index: Integer): TColor;
begin
Result := Display.SegmentLitColor;
end;
function TJvCustomSegmentedLEDDigit.GetUnlitSegColor(Index: Integer): TColor;
begin
Result := Display.GetRealUnlitColor;
end;
function TJvCustomSegmentedLEDDigit.GetSegmentColor(Index: Integer): TColor;
begin
if GetSegmentState(Index) then
Result := GetLitSegColor(Index)
else
Result := GetUnlitSegColor(Index);
end;
function TJvCustomSegmentedLEDDigit.Display: TJvCustomSegmentedLEDDisplay;
begin
Assert(Collection <> nil);
Result := TJvSegmentedLEDDigits(Collection).Display;
Assert(Result <> nil);
end;
procedure TJvCustomSegmentedLEDDigit.Invalidate;
begin
Display.Invalidate;
end;
procedure TJvCustomSegmentedLEDDigit.InvalidateStates;
begin
Display.Invalidate;
end;
procedure TJvCustomSegmentedLEDDigit.InvalidateRefPoints;
begin
SlantAngle := Display.Slant;
Spacing := Display.SegmentSpacing;
SegmentWidth := Display.SegmentThickness;
DotSize := Display.DotSize;
MaxSlantDif := Trunc(Abs(ArcTan(SlantAngle * Pi / 180.0) * Display.DigitHeight));
FRecalcNeeded := True;
SetLength(FSegmentRenderInfo, 0);
SetLength(FSegmentRenderInfo, SegmentCount);
FillChar(FSegmentRenderInfo[0], SegmentCount * SizeOf(FSegmentRenderInfo[0]), 0);
Display.InvalidateView;
end;
function TJvCustomSegmentedLEDDigit.NeedsPainting: Boolean;
begin
Result := FRecalcNeeded;
end;
procedure TJvCustomSegmentedLEDDigit.Paint;
var
I: Integer;
begin
if RecalcNeeded then
begin
RecalcRefPoints;
RecalcSegments;
FRecalcNeeded := False;
end;
for I := 0 to SegmentCount - 1 do
PaintSegment(I);
end;
procedure TJvCustomSegmentedLEDDigit.PaintSegment(Index: Integer);
var
SegColor: TColor;
begin
SegColor := GetSegmentColor(Index);
Display.Canvas.Brush.Color := SegColor;
Display.Canvas.Pen.Color := SegColor;
case FSegmentRenderInfo[Index].RenderType of
srtPolygon:
Display.Canvas.Polygon(FSegmentRenderInfo[Index].Points);
srtCircle:
Display.Canvas.Ellipse(
FSegmentRenderInfo[Index].Points[0].X, FSegmentRenderInfo[Index].Points[0].Y,
FSegmentRenderInfo[Index].Points[1].X, FSegmentRenderInfo[Index].Points[1].Y);
srtRect:
Display.Canvas.Rectangle(
FSegmentRenderInfo[Index].Points[0].X, FSegmentRenderInfo[Index].Points[0].Y,
FSegmentRenderInfo[Index].Points[1].X, FSegmentRenderInfo[Index].Points[1].Y);
end;
end;
function TJvCustomSegmentedLEDDigit.GetHitInfo(X, Y: Integer): TSLDHitInfo;
var
DummyIndex: Integer;
begin
Result := GetHitInfo(X, Y, DummyIndex);
end;
function TJvCustomSegmentedLEDDigit.GetHitInfo(X, Y: Integer;
out SegmentIndex: Integer): TSLDHitInfo;
begin
Result := shiNowhere;
if PtInRect(Rect(Left, 0, Width, Height + BaseTop), Point(X, Y)) then
begin
SegmentIndex := SegmentCount - 1;
while (SegmentIndex >= 0) and not PtInSegment(SegmentIndex, Point(X, Y)) do
Dec(SegmentIndex);
if SegmentIndex > -1 then
Result := shiDigitSegment
else
Result := shiDigit;
end;
end;
function TJvCustomSegmentedLEDDigit.PtInSegment(SegmentIndex: Integer; Pt: TPoint): Boolean;
var
SegType: TSegmentRenderType;
SegPts: TPointArray;
Rgn: HRGN;
begin
if GetSegmentRenderInfo(SegmentIndex, SegType, SegPts) then
begin
case SegType of
srtNone:
Result := False;
srtPolygon:
begin
Rgn := CreatePolygonRgn(SegPts[0], Length(SegPts), WINDING);
try
if Rgn <> NullHandle then
Result := PtInRegion(Rgn, Pt.X, Pt.Y)
else
Result := False;
finally
DeleteObject(Rgn);
end;
end;
srtRect:
Result := PtInRect(Rect(SegPts[0].X, SegPts[0].Y, SegPts[1].X, SegPts[1].Y), Pt);
srtCircle:
begin
Rgn := CreateEllipticRgn(SegPts[0].X, SegPts[0].Y, SegPts[1].X, SegPts[1].Y);
try
if Rgn <> NullHandle then
Result := PtInRegion(Rgn, Pt.X, Pt.Y)
else
Result := False;
finally
DeleteObject(Rgn);
end;
end;
else
Result := False; // Call method to check additional render types?
end;
end
else
Result := False;
end;
function TJvCustomSegmentedLEDDigit.GetSegmentStates: Int64;
begin
Result := FSegmentStates;
end;
class function TJvCustomSegmentedLEDDigit.MapperFileID: string;
begin
// DO NOTHING.
// THIS CAN'T BE AN ABSTRACT CLASS METHOD AS THIS IS NOT
// SUPPORTED BY C++ BUILDER
end;
class function TJvCustomSegmentedLEDDigit.GetSegmentIndex(
Name: string): Integer;
begin
// DO NOTHING.
// THIS CAN'T BE AN ABSTRACT CLASS METHOD AS THIS IS NOT
// SUPPORTED BY C++ BUILDER
Result := 0;
end;
class function TJvCustomSegmentedLEDDigit.GetSegmentName(
Index: Integer): string;
begin
// DO NOTHING.
// THIS CAN'T BE AN ABSTRACT CLASS METHOD AS THIS IS NOT
// SUPPORTED BY C++ BUILDER
Result := '';
end;
class function TJvCustomSegmentedLEDDigit.SegmentCount: Integer;
begin
// DO NOTHING.
// THIS CAN'T BE AN ABSTRACT CLASS METHOD AS THIS IS NOT
// SUPPORTED BY C++ BUILDER
Result := 0;
end;
//=== { TJvBaseSegmentedLEDDigit } ===========================================
procedure TJvBaseSegmentedLEDDigit.EnableAllSegs;
begin
inherited EnableAllSegs;
UseDP := True;
end;
procedure TJvBaseSegmentedLEDDigit.SetUseDP(Value: Boolean);
begin
if Value <> UseDP then
begin
FUseDP := Value;
UpdateDPWidth;
InvalidateRefPoints;
end;
end;
function TJvBaseSegmentedLEDDigit.GetDPWidth: Integer;
begin
Result := FDPWidth;
end;
procedure TJvBaseSegmentedLEDDigit.SetDPWidth(Value: Integer);
begin
if Value <> DPWidth then
begin
FDPWidth := Value;
Display.UpdateDigitsPositions;
end;
end;
procedure TJvBaseSegmentedLEDDigit.UpdateDPWidth;
begin
if UseDP then
begin
// Determine if width will suffice for the DP, otherwise set FDPWidth to the required additional width
if MaxSlantDif < (Spacing + DotSize) then
DPWidth := Spacing + DotSize - MaxSlantDif
else
DPWidth := 0;
end
else
DPWidth := 0;
end;
procedure TJvBaseSegmentedLEDDigit.CalcASeg(Index: Integer);
begin
SetSegmentRenderInfo(Index, srtPolygon, [
AngleAdjustPoint(FRefLeft + Spacing div 2, FRefTop, SlantAngle),
AngleAdjustPoint(FRefRight - Spacing div 2, FRefTop, SlantAngle),
AngleAdjustPoint(FRefRight - Spacing div 2 - SegmentWidth, FRefTop + SegmentWidth, SlantAngle),
AngleAdjustPoint(FRefLeft + Spacing div 2 + SegmentWidth, FRefTop + SegmentWidth, SlantAngle)
]);
end;
procedure TJvBaseSegmentedLEDDigit.CalcBSeg(Index: Integer);
begin
SetSegmentRenderInfo(Index, srtPolygon, [
AngleAdjustPoint(FRefRight, FRefTop + Spacing div 2, SlantAngle),
AngleAdjustPoint(FRefRight, FRefCenterY - Spacing div 2, SlantAngle),
AngleAdjustPoint(FRefRight - SegmentWidth, FRefCenterY - Spacing div 2 - SegmentWidth, SlantAngle),
AngleAdjustPoint(FRefRight - SegmentWidth, FRefTop + Spacing div 2 + SegmentWidth, SlantAngle)
]);
end;
procedure TJvBaseSegmentedLEDDigit.CalcCSeg(Index: Integer);
begin
SetSegmentRenderInfo(Index, srtPolygon, [
AngleAdjustPoint(FRefRight, FRefCenterY + Spacing div 2, SlantAngle),
AngleAdjustPoint(FRefRight, FRefBottom - Spacing div 2, SlantAngle),
AngleAdjustPoint(FRefRight - SegmentWidth, FRefBottom - Spacing div 2 - SegmentWidth, SlantAngle),
AngleAdjustPoint(FRefRight - SegmentWidth, FRefCenterY + Spacing div 2 + SegmentWidth, SlantAngle)
]);
end;
procedure TJvBaseSegmentedLEDDigit.CalcDSeg(Index: Integer);
begin
SetSegmentRenderInfo(Index, srtPolygon, [
AngleAdjustPoint(FRefLeft + Spacing div 2, FRefBottom, SlantAngle),
AngleAdjustPoint(FRefRight - Spacing div 2, FRefBottom, SlantAngle),
AngleAdjustPoint(FRefRight - Spacing div 2 - SegmentWidth, FRefBottom - SegmentWidth, SlantAngle),
AngleAdjustPoint(FRefLeft + Spacing div 2 + SegmentWidth, FRefBottom - SegmentWidth, SlantAngle)
]);
end;
procedure TJvBaseSegmentedLEDDigit.CalcESeg(Index: Integer);
begin
SetSegmentRenderInfo(Index, srtPolygon, [
AngleAdjustPoint(FRefLeft, FRefCenterY + Spacing div 2, SlantAngle),
AngleAdjustPoint(FRefLeft, FRefBottom - Spacing div 2, SlantAngle),
AngleAdjustPoint(FRefLeft + SegmentWidth, FRefBottom - Spacing div 2 - SegmentWidth, SlantAngle),
AngleAdjustPoint(FRefLeft + SegmentWidth, FRefCenterY + Spacing div 2 + SegmentWidth, SlantAngle)
]);
end;
procedure TJvBaseSegmentedLEDDigit.CalcFSeg(Index: Integer);
begin
SetSegmentRenderInfo(Index, srtPolygon, [
AngleAdjustPoint(FRefLeft, FRefTop + Spacing div 2, SlantAngle),
AngleAdjustPoint(FRefLeft, FRefCenterY - Spacing div 2, SlantAngle),
AngleAdjustPoint(FRefLeft + SegmentWidth, FRefCenterY - Spacing div 2 - SegmentWidth, SlantAngle),
AngleAdjustPoint(FRefLeft + SegmentWidth, FRefTop + Spacing div 2 + SegmentWidth, SlantAngle)
]);
end;
procedure TJvBaseSegmentedLEDDigit.CalcGSeg(Index: Integer);
begin
SetSegmentRenderInfo(Index, srtPolygon, [
AngleAdjustPoint(FRefLeft + Spacing div 2, FRefCenterY, SlantAngle),
AngleAdjustPoint(FRefLeft + Spacing div 2 + SegmentWidth div 2, FRefCenterY - SegmentWidth div 2, SlantAngle),
AngleAdjustPoint(FRefRight - Spacing div 2 - SegmentWidth div 2, FRefCenterY - SegmentWidth div 2, SlantAngle),
AngleAdjustPoint(FRefRight - Spacing div 2, FRefCenterY, SlantAngle),
AngleAdjustPoint(FRefRight - Spacing div 2 - SegmentWidth div 2, FRefCenterY + SegmentWidth div 2, SlantAngle),
AngleAdjustPoint(FRefLeft + Spacing div 2 + SegmentWidth div 2, FRefCenterY + SegmentWidth div 2, SlantAngle)
]);
end;
procedure TJvBaseSegmentedLEDDigit.CalcDPSeg(Index: Integer);
var
UpperLeftPoint: TPoint;
begin
UpperLeftPoint := AngleAdjustPoint(FRefRight + Spacing, FRefBottom - DotSize, SlantAngle);
SetSegmentRenderInfo(Index, srtCircle, [
UpperLeftPoint,
Point(UpperLeftPoint.X + DotSize, UpperLeftPoint.Y + DotSize)
]);
end;
function TJvBaseSegmentedLEDDigit.GetWidth: Integer;
begin
Result := inherited GetWidth + DPWidth;
end;
procedure TJvBaseSegmentedLEDDigit.InvalidateRefPoints;
begin
inherited InvalidateRefPoints;
UpdateDPWidth;
end;
procedure TJvBaseSegmentedLEDDigit.RecalcRefPoints;
begin
FRefLeft := Left + MaxSlantDif;
FRefCenterX := FRefLeft + (Display.DigitWidth - 1) div 2;
FRefRight := FRefLeft + Display.DigitWidth - 1;
FRefTop := GetVertAdjust;
FRefCenterY := FRefTop + (Display.DigitHeight - 1) div 2;
FRefBottom := FRefTop + (Display.DigitHeight - 1);
end;
procedure TJvBaseSegmentedLEDDigit.RecalcSegments;
begin
CalcASeg(0);
CalcBSeg(1);
CalcCSeg(2);
CalcDSeg(3);
CalcESeg(4);
CalcFSeg(5);
CalcGSeg(6);
if UseDP then
CalcDPSeg(7);
end;
class function TJvBaseSegmentedLEDDigit.SegmentCount: Integer;
begin
Result := 8;
end;
class function TJvBaseSegmentedLEDDigit.GetSegmentName(Index: Integer): string;
begin
if Index < 7 then
Result := Chr(Ord('A') + Index)
else
if Index = 7 then
Result := 'DP'
else
Result := '';
end;
class function TJvBaseSegmentedLEDDigit.GetSegmentIndex(Name: string): Integer;
begin
Result := -1;
Name := UpperCase(Name);
if Length(Name) = 1 then
begin
Result := Ord(Name[1]) - Ord('A');
if Result > 6 then
Result := -1;
end
else
if Name = 'DP' then
Result := 7;
end;
function TJvBaseSegmentedLEDDigit.GetSegmentString: string;
var
I: Integer;
begin
Result := '';
for I := 0 to SegmentCount - 1 do
begin
if GetSegmentState(I) then
begin
if Length(Result) > 0 then
Result := Result + ',' + GetSegmentName(I)
else
Result := GetSegmentName(I);
end;
end;
end;
//=== { TJvSegmentedLEDCharacterMapper } =====================================
constructor TJvSegmentedLEDCharacterMapper.Create(ADisplay: TJvCustomSegmentedLEDDisplay);
begin
inherited Create;
FDisplay := ADisplay;
LoadDefaultMapping;
end;
function TJvSegmentedLEDCharacterMapper.GetCharMapping(Chr: Char): Int64;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -