⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 jvqsegmentedleddisplay.pas

📁 East make Tray Icon in delphi
💻 PAS
📖 第 1 页 / 共 4 页
字号:
  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 + -