unit RackCtls;
{ WK }
{ Änderungen, die bei LEDDisplay nachfolgende Nullen bei LeadingZeros=False doch zeichnet }
{ Ergänzt von Wolfgang Kleinrath }
{ wk }

{ RackControls:
  TLEDButton, TButtonPanel, TScrewPanel, TLEDDisplay, TLEDMeter

  Die Komponente TLEDDisplay ist eine Weiterentwicklung
  der Komponente TLCDDisplay von Luis Iglesias:
  luis.iglesias@vigo.org

  (C)opyright 1998 Version 1.01
  Autor : Simon Reinhardt
  eMail : S.Reinhardt@WTal.de
  Internet : http://sr-soft.wtal.de

  Diese Komponenten sind Public Domain, das Copyright liegt aber beim Autor.}

interface

uses
  {$IFDEF WIN32} Windows, {$ELSE} WinTypes, WinProcs, Menus, Forms, {$ENDIF} Classes, Graphics,
  Controls, SysUtils, ExtCtrls, Messages, Dialogs;

const
  DefaultWidth  = 45;
  DefaultHeight = 45;
  DefaultDepth  = 3;
  VNr           = 'v1.01';

type
  TBorderStyle     = (bsNone, bsSingle);
  TButtonDirection = (bdBottomUp, bdLeftUp, bdNone, bdRightUp, bdTopUp);
  TDecSeperator    = (dsPoint,dsComma,dsDoublePoint,dsMinus);
  TLEDColor        = (lcAqua, lcBlue, lcFuchsia, lcGray, lcLime, lcRed, lcWhite, lcYellow);
  TMeterDirection  = (mdDown, mdLeft, mdRight, mdUp);
  TNumGlyphs       = 1..4;
  TScrewSize       = 1..8;
  TSegmentStyle    = (ssRectangular, ssBeveled);
  TTextPosition    = (tpAbove, tpBelow, tpNone, tpOnButton);

  TLEDButton = class(TGraphicControl)
  private
    FBeveled:          boolean;
    FBorderStyle:      TBorderStyle;
    FButtonDirection:  TButtonDirection;
    FColor:            TColor;
    FColorHighlight:   TColor;
    FColorLED:         TLEDColor;
    FColorShadow:      TColor;
    FDepth:            integer;
    FDown:             boolean;
    FFont:             TFont;
    FGlyph:            TBitmap;
    FNumGlyphs:        TNumGlyphs;
    FShowLED:          boolean;
    FStateOn:          boolean;
    FSwitching:        boolean;
    FTextPosition:     TTextPosition;

    FMouseDown:        boolean;
    FOnClick:          TNotifyEvent;

  protected
    procedure Paint;  override;
    procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
       override;
    procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
       override;

    procedure SetBeveled(newValue: boolean);
    procedure SetBorderStyle(newBorderStyle: TBorderStyle);
    procedure SetButtonDirection(NewDirection: TButtonDirection);
    procedure SetColor(newColor: TColor);
    procedure SetColorLED(newColor: TLEDColor);
    procedure SetDepth(newValue: integer);
    procedure SetFont(newFont: TFont);
    procedure SetGlyph(newGlyph: TBitmap);
    procedure SetNumGlyphs(newNumGlyphs: TNumGlyphs);
    procedure SetShowLED(newValue: boolean);
    procedure SetStateOn(newValue: boolean);
    procedure SetTextPosition(newValue: TTextPosition);

    procedure DrawBorder(Dest:TRect);
    procedure DrawCaption(Dest:TRect);
    procedure DrawGlyph(Dest:TRect);
    procedure DrawLED(var Dest:TRect);

  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;

    procedure CMTextChanged(var msg: TMessage);message CM_TEXTCHANGED;
    procedure CMDialogChar(var Message: TCMDialogChar);message CM_DIALOGCHAR;

  published
    property Beveled: boolean read FBeveled write SetBeveled;
    property BorderStyle: TBorderStyle read FBorderStyle write SetBorderStyle;
    property ButtonDirection: TButtonDirection read FButtonDirection write SetButtonDirection;
    property Caption;
    property Color: TColor read FColor write SetColor;
    property ColorLED: TLEDColor read FColorLED write SetColorLED;
    property Depth: integer read FDepth write SetDepth;
    property Enabled;
    property Font: TFont read FFont write SetFont;
    property Glyph: TBitmap read FGlyph write SetGlyph;
    property NumGlyphs: TNumGlyphs read FNumGlyphs write SetNumGlyphs default 1;
    property ParentFont;
    property ParentShowHint;
    property ShowHint;
    property ShowLED: boolean read FShowLED write SetShowLED;
    property StateOn: boolean read FStateOn write SetStateOn;
    property Switching: boolean read FSwitching write FSwitching;
    property TextPosition: TTextPosition read FTextPosition write SetTextPosition;
    property Visible;
    property OnClick;
    property OnMouseDown;
    property OnMouseMove;
    property OnMouseUp;
  end;

  TButtonPanel = class(TCustomPanel)
  private
    FBeveled:          boolean;
    FBorderStyle:      TBorderStyle;
    FColor:            TColor;
    FColorHighlight:   TColor;
    FColorShadow:      TColor;
    FDepth:            integer;
    FPanelDirection:   TButtonDirection;
    FShowLED:          boolean;

  protected
    procedure Paint;  override;

    procedure SetBeveled(newValue: boolean);
    procedure SetBorderStyle(newBorderStyle: TBorderStyle);
    procedure SetColor(newColor: TColor);
    procedure SetDepth(newValue: integer);
    procedure SetPanelDirection(NewDirection: TButtonDirection);
    procedure SetShowLED(newValue: boolean);

    procedure DrawBorder(Dest:TRect);
    procedure DrawCaption(Dest:TRect);
    procedure DrawLED(var Dest:TRect);

  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;

  published
    property Align;
    property Alignment;
    property Beveled: boolean read FBeveled write SetBeveled;
    property BorderStyle: TBorderStyle read FBorderStyle write SetBorderStyle;
    property Caption;
    property Color: TColor read FColor write SetColor;
    property Ctl3D;
    property Depth: integer read FDepth write SetDepth;
    property DragCursor;
    property DragMode;
    property Enabled;
    {$IFDEF WIN32}
    property FullRepaint;
    {$ENDIF}
    property Font;
    property Locked;
    property PanelDirection: TButtonDirection read FPanelDirection write SetPanelDirection;
    property ParentColor;
    property ParentCtl3D;
    property ParentFont;
    property ParentShowHint;
    property PopupMenu;
    property ShowHint;
    property ShowLED: boolean read FShowLED write SetShowLED;
    property TabOrder;
    property TabStop;
    property Visible;

    property OnClick;
    property OnDblClick;
    property OnDragDrop;
    property OnDragOver;
    property OnEndDrag;
    property OnEnter;
    property OnExit;
    property OnMouseDown;
    property OnMouseMove;
    property OnMouseUp;
    property OnResize;
    {$IFDEF WIN32}
    property OnStartDrag;
    {$ENDIF}
  end;

  TScrewPanel = class(TCustomPanel)
  private
    FColor:            TColor;
    FColorHighlight:   TColor;
    FColorShadow:      TColor;
    FMargin:           integer;
    FScrewSize:        TScrewSize;
    FShowScrews:       boolean;

  protected
    procedure Paint;  override;

    procedure SetColor(newColor: TColor);
    procedure SetMargin(newValue: integer);
    procedure SetScrewSize(newValue: TScrewSize);
    procedure SetShowScrews(newValue: boolean);

    procedure DrawScrew(X,Y:integer);
    procedure DrawBevel(ARect:TRect;Raised:boolean);

  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;

  published
    property Align;
    property Alignment;
    property BevelInner;
    property BevelOuter;
    property BevelWidth;
    property BorderWidth;
    property BorderStyle;
    property Caption;
    property Color: TColor read FColor write SetColor;
    property Ctl3D;
    property DragCursor;
    property DragMode;
    property Enabled;
    {$IFDEF WIN32}
    property FullRepaint;
    {$ENDIF}
    property Font;
    property Locked;
    property Margin: integer read FMargin write SetMargin;
    property ParentColor;
    property ParentCtl3D;
    property ParentFont;
    property ParentShowHint;
    property PopupMenu;
    property ScrewSize: TScrewSize read FScrewSize write SetScrewSize;
    property ShowHint;
    property ShowScrews: boolean read FShowScrews write SetShowScrews;
    property TabOrder;
    property TabStop;
    property Visible;

    property OnClick;
    property OnDblClick;
    property OnDragDrop;
    property OnDragOver;
    property OnEndDrag;
    property OnEnter;
    property OnExit;
    property OnMouseDown;
    property OnMouseMove;
    property OnMouseUp;
    property OnResize;
    {$IFDEF WIN32}
    property OnStartDrag;
    {$ENDIF}
  end;

  TLEDDisplay = class(TGraphicControl)
  private
    FBevelStyle      : TPanelBevel;
    FBorderStyle     : TBorderStyle;
    FColorBackGround,
    FColorSegmentOff,
    FColorLED        : TColor;
    FDecSeperator    : TDecSeperator;
    FDigit           : array [0..9] of TBitmap;
    FDigitHeight,
    FDigitWidth,
    FFractionDigits,
    FLineWidth,
    FNumDigits       : integer;
    FLeadingZeros    : boolean;
    FSegCl           : array [0..9, 1..7] of TColor;
    FSegmentStyle    : TSegmentStyle;
    FValue           : extended;

    FOnChange            : TNotifyEvent;

    procedure setBevelStyle (newValue: TPanelBevel);
    procedure setBorderStyle (newValue: TBorderStyle);
    procedure setColorBackGround (newValue: TColor);
    procedure setColorLED (newValue: TColor);
    procedure setDecSeperator (newValue: TDecSeperator);
    procedure setDigitHeight (newValue: integer);
    procedure setDigitWidth (newValue: integer);
    procedure setFractionDigits (newValue: integer);
    procedure setLeadingZeros (newValue: boolean);
    procedure setLineWidth (newValue: integer);
    procedure setNumDigits (newValue: integer);
    procedure setSegmentStyle (newValue: TSegmentStyle);
    procedure setValue (newValue: extended);

    procedure GenerateBitMaps;
    procedure AssignColors (seg: integer; s1,s2,s3,s4,s5,s6,s7: Boolean);

  protected
    procedure paint; override;
    procedure Change; dynamic;


  public
    constructor Create (AOwner: TComponent); override;
    destructor Destroy; override;

  published
    property BevelStyle: TPanelBevel read FBevelStyle write SetBevelStyle;
    property BorderStyle: TBorderStyle read FBorderStyle write SetBorderStyle;
    property ColorBackGround: TColor read FColorBackGround write setColorBackGround default clOlive;
    property ColorLED: TColor read FColorLED write setColorLED default cllime;
    property DecSeperator: TDecSeperator read FDecSeperator write setDecSeperator;
    property DigitHeight: integer read FDigitHeight write setDigitHeight default 30;
    property DigitWidth: integer read FDigitWidth write setDigitWidth default 20;
    property DigitLineWidth: integer read FLineWidth write setLineWidth default 3;
    property FractionDigits: integer read FFractionDigits write setFractionDigits default 0;
    property Height default 36;
    property LeadingZeros: boolean read FLeadingZeros write setLeadingZeros default true;
    property NumDigits: integer read FNumDigits write setNumDigits default 6;
    property SegmentStyle: TSegmentStyle read FSegmentStyle write setSegmentStyle;
    property Value: extended read FValue write setValue;
    property Visible;
    property Width default 168;

    property OnChange: TNotifyEvent read FOnChange write FOnChange;
    property OnMouseDown;
    property OnMouseMove;
    property OnMouseUp;
  end;

  TLEDMeter = class(tgraphiccontrol)
  private
    FBevelStyle     : TPanelBevel;
    FColorLED1,
    FColorLED2,
    FColorLED3,
    FColorOff1,
    FColorOff2,
    FColorOff3,
    FColorSeperator : TColor;
    FDirection      : TMeterDirection;
    FMax, FMin,
    FNumDigits,
    FPosition	    : integer;
    {added 15.10.99, U. Conrad:}
    FSingleLED      : boolean;
    FStartColor2,
    FStartColor3    : integer;

    FOnChange       : TNotifyEvent;

    procedure setBevelStyle(newVal : TPanelBevel);
    procedure setColorLED1(newVal : tColor);
    procedure setColorLED2(newVal : tColor);
    procedure setColorLED3(newVal : tColor);
    procedure setColorSeperator(newVal : tColor);
    procedure setDirection(newVal : TMeterdirection);
    procedure setMax(newVal : integer);
    procedure setMin(newVal : integer);
    procedure setNumDigits(newVal : integer);
    procedure setPosition(newVal : integer);
    {added 15.10.99, U. Conrad:}
    procedure setSingleLED(newVal : boolean);
    procedure setStartColor2(newVal : integer);
    procedure setStartColor3(newVal : integer);

  protected
    procedure Paint;override;
    procedure Change; dynamic;

  public
    constructor Create(AOwner : TComponent);override;
    destructor Destroy ; override;

  published
    property BevelStyle: TPanelBevel read FBevelStyle write SetBevelStyle;
    property ColorLED1 : TColor read FColorLED1 write setColorLED1;
    property ColorLED2 : TColor read FColorLED2 write setColorLED2;
    property ColorLED3 : TColor read FColorLED3 write setColorLED3;
    property ColorSeperator: TColor read FColorSeperator write setColorSeperator;
    property Cursor;
    property Direction: TMeterDirection read FDirection write setDirection;
    property DragCursor;
    property DragMode;
    property Max: integer read FMax write setMax;
    property Min: integer read FMin write setMin;
    property NumDigits: integer read FNumDigits write setNumDigits;
    property Position: integer read FPosition write setPosition;
    {added 15.10.99, U. Conrad:}
    property SingleLED : boolean read FSingleLED write setSingleLED;
    property StartColor2: integer read FStartColor2 write setStartColor2;
    property StartColor3: integer read FStartColor3 write setStartColor3;
    property Visible;

    property OnChange: TNotifyEvent read FOnChange write FOnChange;
    property OnDragDrop;
    property OnDragOver;
    property OnEndDrag;
    property OnMouseDown;
    property OnMouseMove;
    property OnMouseUp;
end;

procedure Register;

implementation

function IsAccellerator(VK: Word; const Str: string): Boolean;
var
  P : Integer;
begin
  P := Pos('&', Str);
  Result := (P <> 0) and (P < Length(Str)) and
    (Upcase(Str[P + 1])=Upcase(Char(VK)));
end;

function ChangeBrightness(Color:TColor;Percentage:longint):TColor;
var RGBColor       : longint;
    Red,Green,Blue : byte;
    NewR,NewG,NewB : longint;
    Overflow       : longint;
begin
  RGBColor := ColorToRGB(Color);
  {Rot}
  Red:=GetRValue(RGBColor);
  NewR:=Red+(Percentage*Red div 100);
  if NewR > 255 then begin
    Overflow := NewR-255;
    NewG := Overflow;
    NewB := Overflow;
  end
  else begin
    NewG:=0;
    NewB:=0;
    {Overflow := 0;}
  end;
  {Grün}
  Green:=GetGValue(RGBColor);
  NewG:=NewG+Green+(Percentage*Green div 100);
  if NewG>255 then begin
    Overflow := NewG - 255;
    NewR := NewR + Overflow;
    NewB := Overflow;
  end;
  {Blau}
  Blue := GetBValue(RGBColor);
  NewB := NewB+Blue+(Percentage*Blue div 100);
  if NewB > 255 then begin
    Overflow := NewB - 255;
    if NewG <= 255 then
      NewR := NewR + Overflow;
  end;
  if NewR > 255 then
    NewR := 255;
  if NewG > 255 then
    NewG := 255;
  if NewB > 255 then
    NewB := 255;
  if NewR < 0 then
    NewR := 0;
  if NewG < 0 then
    NewG := 0;
  if NewB < 0 then
    NewB := 0;
  Result := NewR + (NewG shl 8)+(NewB shl 16);
end;


{Komponente LEDButton}
constructor TLEDButton.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);

  {Vorgabewerte setzen}
  FBeveled := true;
  FBorderStyle := bsSingle;
  FButtonDirection := bdBottomUp;
  FColor := clGray;
  FColorHighlight := ChangeBrightness(FColor,50);
  FColorShadow := ChangeBrightness(FColor,-50);
  FColorLED := lcBlue;
  FDepth := DefaultDepth;
  FDown := false;
  FFont := TFont.Create;
  FGlyph := TBitmap.Create;
  FNumGlyphs := 1;
  FShowLED := true;
  FStateOn := false;
  FSwitching := true;
  FTextPosition := tpNone;
  Height := DefaultHeight;
  Width := DefaultWidth;

  FMouseDown := False;
end;

destructor  TLEDButton.Destroy;
begin
  FFont.Free;
  FGlyph.Free;
  inherited Destroy;
end;

procedure TLEDButton.SetBeveled(NewValue: boolean);
begin
  FBeveled:=NewValue;
  Invalidate;
end;

procedure TLEDButton.SetBorderStyle(NewBorderStyle: TBorderStyle);
begin
  FBorderStyle:=NewBorderStyle;
  Invalidate;
end;

procedure TLEDButton.SetButtonDirection(NewDirection: TButtonDirection);
begin
  FButtonDirection:=NewDirection;
  Invalidate;
end;

procedure TLEDButton.SetColor(newColor: TColor);
begin
  FColor:=newColor;
  FColorHighlight:=ChangeBrightness(FColor,50);
  FColorShadow:=ChangeBrightness(FColor,-50);
  Invalidate;
end;

procedure TLEDButton.SetColorLED(newColor: TLEDColor);
begin
  FColorLED:=newColor;
  Invalidate;
end;

procedure TLEDButton.SetDepth(newValue: integer);
begin
  FDepth:=newValue;
  Invalidate;
end;

procedure TLEDButton.SetFont(newFont: TFont);
begin
  FFont.Assign(NewFont);
  Invalidate;
end;

procedure TLEDButton.SetGlyph(newGlyph: TBitmap);
begin
  if(Assigned(FGlyph)) then begin
    FGlyph.Assign(newGlyph);

    if (csDesigning in ComponentState) then begin
      { Glyph 1: Normal, 2: Disabled, 3: Down;
        Muß die Ausmaße (Height * NumGlyphs) = Width  haben}
      if (newGlyph.width mod newGlyph.height = 0) then
        FNumGlyphs:= newGlyph.width div newGlyph.height
      else
        FNumGlyphs:= 1;
    end;

    Invalidate;
  end;
end;

procedure TLEDButton.SetNumGlyphs(newNumGlyphs: TNumGlyphs);
begin
  FNumGlyphs:= newNumGlyphs;
  Invalidate;
end;

procedure TLEDButton.SetShowLED(newValue: boolean);
begin
  FShowLED := newValue;
  Invalidate;
end;

procedure TLEDButton.SetStateOn(newValue: boolean);
begin
  FStateOn := newValue;
  Invalidate;
end;

procedure TLEDButton.SetTextPosition(newValue: TTextPosition);
begin
  FTextPosition := newValue;
  Invalidate;
end;

procedure TLEDButton.DrawBorder(Dest:TRect);
var i : integer;
begin
  Dest:=GetClientRect;
  if FTextPosition=tpAbove then
    Dest.Top:=Dest.Top+Canvas.TextWidth('W')+2;
  if FTextPosition=tpBelow then
    Dest.Bottom:=Dest.Bottom-Canvas.TextWidth('W')-2;
  with Canvas do begin
    if FBorderStyle=bsSingle then begin
      Brush.Color:=clWindowFrame;
      FrameRect(Dest);
      InflateRect(Dest,-1,-1);
    end;
    Pen.Width:=1;
    if FButtonDirection=bdBottomUp then begin
      Pen.Color:=FColorHighlight;
      {oben}
      MoveTo(Dest.Right-1,Dest.Top);
      LineTo(Dest.Left,Dest.Top);
      {links}
      if not FBeveled then begin
        MoveTo(Dest.Left,Dest.Top);
        LineTo(Dest.Left,Dest.Bottom-1);
      end
      else
        for i:=0 to FDepth do begin
          MoveTo(Dest.Left,Dest.Top);
          if FDown then
            LineTo(Dest.Left+(i div 2),Dest.Bottom-1)
          else
            LineTo(Dest.Left+i,Dest.Bottom-i-1);
        end;
      Pen.Color:=FColorShadow;
      {rechts}
      if not FBeveled then begin
        MoveTo(Dest.Right-1,Dest.Top);
        LineTo(Dest.Right-1,Dest.Bottom);
      end
      else
        for i:=0 to FDepth do begin
          MoveTo(Dest.Right-1,Dest.Top);
          if FDown then
            LineTo(Dest.Right-(i div 2)-1,Dest.Bottom-1)
          else
            LineTo(Dest.Right-i-1,Dest.Bottom-i-1);
        end;
      {unten}
      if FDown then begin
        MoveTo(Dest.Left,Dest.Bottom-1);
        LineTo(Dest.Right-1,Dest.Bottom-1);
      end
      else
        for i:=0 to FDepth do begin
          if not FBeveled then begin
            MoveTo(Dest.Left,Dest.Bottom-i-1);
            LineTo(Dest.Right-1,Dest.Bottom-i-1);
          end
          else begin
            MoveTo(Dest.Left+i,Dest.Bottom-i-1);
            LineTo(Dest.Right-i-1,Dest.Bottom-i-1);
          end;
        end;
    end;
    if FButtonDirection=bdTopUp then begin
      Pen.Color:=FColorHighlight;
      {oben}
      if FDown then begin
        MoveTo(Dest.Left,Dest.Top);
        LineTo(Dest.Right-1,Dest.Top);
      end
      else
        for i:=0 to FDepth do begin
          if not FBeveled then begin
            MoveTo(Dest.Left,Dest.Top+i);
            LineTo(Dest.Right-1,Dest.Top+i);
          end
          else begin
            MoveTo(Dest.Left+i,Dest.Top+i);
            LineTo(Dest.Right-i-1,Dest.Top+i);
          end;
        end;
      {links}
      if not FBeveled then begin
        MoveTo(Dest.Left,Dest.Top);
        LineTo(Dest.Left,Dest.Bottom-1);
      end
      else
        for i:=0 to FDepth do begin
          MoveTo(Dest.Left,Dest.Bottom-1);
          if FDown then
            LineTo(Dest.Left+(i div 2),Dest.Top)
          else
            LineTo(Dest.Left+i,Dest.Top+i);
        end;
      Pen.Color:=FColorShadow;
      {rechts}
      if not FBeveled then begin
        MoveTo(Dest.Right-1,Dest.Top);
        LineTo(Dest.Right-1,Dest.Bottom);
      end
      else
        for i:=0 to FDepth do begin
          MoveTo(Dest.Right-1,Dest.Bottom-1);
          if FDown then
            LineTo(Dest.Right-(i div 2)-1,Dest.Top)
          else
            LineTo(Dest.Right-i-1,Dest.Top+i);
        end;
      {unten}
      MoveTo(Dest.Right-1,Dest.Bottom-1);
      LineTo(Dest.Left,Dest.Bottom-1);
    end;
    if FButtonDirection=bdLeftUp then begin
      Pen.Color:=FColorHighlight;
      {oben}
      if not FBeveled then begin
        MoveTo(Dest.Left,Dest.Top);
        LineTo(Dest.Right-1,Dest.Top);
      end
      else
        for i:=0 to FDepth do begin
          MoveTo(Dest.Right-1,Dest.Top);
          if FDown then
            LineTo(Dest.Left,Dest.Top+(i div 2))
          else
            LineTo(Dest.Left+i,Dest.Top+i);
        end;
      {links}
      if FDown then begin
        MoveTo(Dest.Left,Dest.Top);
        LineTo(Dest.Left,Dest.Bottom-1);
      end
      else
        for i:=0 to FDepth do begin
          if not FBeveled then begin
            MoveTo(Dest.Left+i,Dest.Top);
            LineTo(Dest.Left+i,Dest.Bottom-1);
          end
          else begin
            MoveTo(Dest.Left+i,Dest.Top+i);
            LineTo(Dest.Left+i,Dest.Bottom-i-1);
          end;
        end;
      Pen.Color:=FColorShadow;
      {rechts}
      MoveTo(Dest.Right-1,Dest.Top);
      LineTo(Dest.Right-1,Dest.Bottom-1);
      {unten}
      if not FBeveled then begin
        MoveTo(Dest.Right-1,Dest.Bottom-1);
        LineTo(Dest.Left,Dest.Bottom-1);
      end
      else
        for i:=0 to FDepth do begin
          MoveTo(Dest.Right-1,Dest.Bottom-1);
          if FDown then
            LineTo(Dest.Left,Dest.Bottom-(i div 2)-1)
          else
            LineTo(Dest.Left+i,Dest.Bottom-i-1);
        end;
    end;
    if FButtonDirection=bdRightUp then begin
      Pen.Color:=FColorHighlight;
      {oben}
      if not FBeveled then begin
        MoveTo(Dest.Left,Dest.Top);
        LineTo(Dest.Right-1,Dest.Top);
      end
      else
        for i:=0 to FDepth do begin
          MoveTo(Dest.Left,Dest.Top);
          if FDown then
            LineTo(Dest.Right-1,Dest.Top+(i div 2))
          else
            LineTo(Dest.Right-1-i,Dest.Top+i);
        end;
      {links}
      MoveTo(Dest.Left,Dest.Top);
      LineTo(Dest.Left,Dest.Bottom-1);
      Pen.Color:=FColorShadow;
      {rechts}
      if FDown then begin
        MoveTo(Dest.Right-1,Dest.Top);
        LineTo(Dest.Right-1,Dest.Bottom-1);
      end
      else
        for i:=0 to FDepth do begin
          if not FBeveled then begin
            MoveTo(Dest.Right-1-i,Dest.Top);
            LineTo(Dest.Right-1-i,Dest.Bottom-1);
          end
          else begin
            MoveTo(Dest.Right-1-i,Dest.Top+i);
            LineTo(Dest.Right-1-i,Dest.Bottom-i-1);
          end;
        end;
      {unten}
      if not FBeveled then begin
        MoveTo(Dest.Left,Dest.Bottom-1);
        LineTo(Dest.Right-1,Dest.Bottom-1);
      end
      else
        for i:=0 to FDepth do begin
          MoveTo(Dest.Left,Dest.Bottom-1);
          if FDown then
            LineTo(Dest.Right-1,Dest.Bottom-(i div 2)-1)
          else
            LineTo(Dest.Right-1-i,Dest.Bottom-i-1);
        end;
    end;
  end;
end;

procedure TLEDButton.DrawCaption(Dest:TRect);
var OutText : array [0..79] of char;
begin
  with Canvas do begin
    Brush.Style:=bsClear;
    StrPCopy(OutText, Caption);
    if not Enabled then
      Font.Color:=clGrayText;
    if FTextPosition=tpAbove then
      DrawText(Handle, OutText, length(Caption), Dest, dt_center or dt_top or dt_singleline);
    if FTextPosition=tpBelow then
      DrawText(Handle, OutText, length(Caption), Dest, dt_center or dt_bottom or dt_singleline);
    if FTextPosition=tpOnButton then
      DrawText(Handle, OutText, length(Caption), Dest, dt_center or dt_vcenter or dt_singleline);
  end;
end;

procedure TLEDButton.DrawGlyph(Dest:TRect);
var
  Source    : TRect;
  outWidth  : integer;
  outHeight : integer;
begin
  with Canvas do begin
    { Größe des Destination-Rechtecks }
    outWidth:=  FGlyph.Width div FNumGlyphs;
    outHeight:= FGlyph.Height;
    with Source do begin
      Top:=0;
      Bottom:=FGlyph.Height;
      { Glyph 1: Normal, 2: Disabled, 3: Down;}
      if Enabled then begin
        if FStateOn and (FNumGlyphs>2) then
          Left:=(outWidth*2)+1
        else
          Left:=0;
      end
      else
        Left:=outWidth+1;
      Right:= Left+outWidth;
    end;
    Dest.Left:=  ((Dest.Right +Dest.Left - outWidth)  shr 1);
    Dest.Right:= Dest.Left+outWidth;
    Dest.Top:=   ((Dest.Bottom + Dest.Top - outHeight) shr 1);
    Dest.Bottom:=Dest.Top+outHeight;
    Pen.Color := Color;
    BrushCopy(Dest,FGlyph,Source,FGlyph.Canvas.Pixels[0,FGlyph.Height-1]);
  end;
end;

procedure TLEDButton.DrawLED(var Dest:TRect);
begin
  with Canvas do begin
    if FStateOn then
      case FColorLED of
        lcAqua : Brush.Color:=clAqua;
        lcBlue : Brush.Color:=clBlue;
        lcFuchsia : Brush.Color:=clFuchsia;
        lcGray : Brush.Color:=clGray;
        lcLime : Brush.Color:=clLime;
        lcRed : Brush.Color:=clRed;
        lcWhite : Brush.Color:=clWhite;
        lcYellow : Brush.Color:=clYellow;
      end
    else
      case FColorLED of
        lcAqua : Brush.Color:=clTeal;
        lcBlue : Brush.Color:=clNavy;
        lcFuchsia : Brush.Color:=clPurple;
        lcGray : Brush.Color:=clBlack;
        lcLime : Brush.Color:=clGreen;
        lcRed : Brush.Color:=clMaroon;
        lcWhite : Brush.Color:=clSilver;
        lcYellow : Brush.Color:=clOlive;
      end;
    if not Enabled then
      Brush.Color:=FColor;
    case ButtonDirection of
      bdLeftUp : begin
        if FDown then
          OffsetRect(Dest,-FDepth div 2,0);
        Rectangle(Dest.Left+FDepth+9,Dest.Top+FDepth+3,Dest.Left+FDepth+4,Dest.Bottom-FDepth-3);
        Dest.Left:=Dest.Left+FDepth+9;
      end;
      bdRightUp : begin
        if FDown then
          OffsetRect(Dest,FDepth div 2,0);
        Rectangle(Dest.Right-FDepth-9,Dest.Top+FDepth+3,Dest.Right-FDepth-4,Dest.Bottom-FDepth-3);
        Dest.Right:=Dest.Right-FDepth-9;
      end;
      bdTopUp : begin
        if FDown then
          OffsetRect(Dest,0,-FDepth div 2);
        Rectangle(Dest.Left+FDepth+3,Dest.Top+FDepth+4,Dest.Right-FDepth-3,Dest.Top+FDepth+9);
        Dest.Top:=Dest.Top+FDepth+7;
      end;
      else begin
        if FDown then
          OffsetRect(Dest,0,FDepth div 2);
        Rectangle(Dest.Left+FDepth+3,Dest.Bottom-FDepth-9,Dest.Right-FDepth-3,Dest.Bottom-FDepth-4);
        Dest.Bottom:=Dest.Bottom-FDepth-7;
      end;
    end;
  end;
end;

procedure TLEDButton.Paint;
var ARect : TRect;
begin
  Canvas.Font.Assign(Font);
  with Canvas do begin
    ARect:=GetClientRect;
    if (Caption<>'') and (FTextPosition<>tpOnButton) and (FTextPosition<>tpNone) then
      DrawCaption(ARect);
    if FTextPosition=tpAbove then
      ARect.Top:=ARect.Top+TextWidth('W')+2;
    if FTextPosition=tpBelow then
      ARect.Bottom:=ARect.Bottom-TextWidth('W')-2;
    Brush.Style:=bsSolid;
    Brush.Color:=FColor;
    FillRect(ARect);
    DrawBorder(ARect);
    Pen.Color:=clBlack;
    if FShowLED then
      DrawLED(ARect);
    if (Caption<>'') and (FTextPosition=tpOnButton) then
      DrawCaption(ARect);
    Brush.Color:=Self.Color;
    if Assigned(FGlyph) and (FNumGlyphs > 0) and (FTextPosition<>tpOnButton) then
      DrawGlyph(ARect);
  end;
end;

procedure TLEDButton.CMDialogChar(var Message: TCMDialogChar);
begin
  with Message do begin
    if IsAccellerator(CharCode, Caption) then begin
      if Enabled then begin
        Click;
        if FSwitching then
          FStateOn:=not FStateOn;
        Invalidate;
      end;
      Result := 1;
    end
    else
      inherited;
  end;
end;

procedure TLEDButton.MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
  if Enabled then begin
    FDown:=true;
    Invalidate;
  end;
  FMouseDown:= True;
end;

procedure TLEDButton.MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
  if Enabled then begin
    FDown:=false;
    if FSwitching then
      FStateOn:=not FStateOn;
    Paint;
    if Assigned(FOnClick) then
       FOnClick(Self);
  end;
  FMouseDown:= False;
end;

procedure TLEDButton.CMTextChanged(var msg: TMessage);
begin
  Invalidate;
end;


{Komponente ButtonPanel}
constructor TButtonPanel.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);

  {Vorgabewerte setzen}
  FBeveled:=true;
  FBorderStyle:=bsSingle;
  FPanelDirection:=bdBottomUp;
  FColor:=clGray;
  FColorHighlight:=ChangeBrightness(FColor,50);
  FColorShadow:=ChangeBrightness(FColor,-50);
  FDepth:=DefaultDepth;
  FShowLED:=true;
  Height:=DefaultHeight;
  Width:=DefaultWidth;
end;

destructor  TButtonPanel.Destroy;
begin
  inherited Destroy;
end;

procedure TButtonPanel.SetBeveled(NewValue: boolean);
begin
  FBeveled:=NewValue;
  Invalidate;
end;

procedure TButtonPanel.SetBorderStyle(NewBorderStyle: TBorderStyle);
begin
  FBorderStyle:=NewBorderStyle;
  Invalidate;
end;

procedure TButtonPanel.SetPanelDirection(NewDirection: TButtonDirection);
begin
  FPanelDirection:=NewDirection;
  Invalidate;
end;

procedure TButtonPanel.SetColor(newColor: TColor);
begin
  FColor:=newColor;
  FColorHighlight:=ChangeBrightness(FColor,50);
  FColorShadow:=ChangeBrightness(FColor,-50);
  Invalidate;
end;

procedure TButtonPanel.SetDepth(newValue: integer);
begin
  FDepth:=newValue;
  Invalidate;
end;

procedure TButtonPanel.SetShowLED(newValue: boolean);
begin
  FShowLED := newValue;
  Invalidate;
end;

procedure TButtonPanel.DrawBorder(Dest:TRect);
var i : integer;
begin
  Dest:=GetClientRect;
  with Canvas do begin
    if FBorderStyle=bsSingle then begin
      Brush.Color:=clWindowFrame;
      FrameRect(Dest);
      InflateRect(Dest,-1,-1);
    end;
    Pen.Width:=1;
    if FPanelDirection=bdBottomUp then begin
      Pen.Color:=FColorHighlight;
      {oben}
      MoveTo(Dest.Right-1,Dest.Top);
      LineTo(Dest.Left,Dest.Top);
      {links}
      if not FBeveled then begin
        MoveTo(Dest.Left,Dest.Top);
        LineTo(Dest.Left,Dest.Bottom-1);
      end
      else
        for i:=0 to FDepth do begin
          MoveTo(Dest.Left,Dest.Top);
          LineTo(Dest.Left+i,Dest.Bottom-i-1);
        end;
      Pen.Color:=FColorShadow;
      {rechts}
      if not FBeveled then begin
        MoveTo(Dest.Right-1,Dest.Top);
        LineTo(Dest.Right-1,Dest.Bottom);
      end
      else
        for i:=0 to FDepth do begin
          MoveTo(Dest.Right-1,Dest.Top);
          LineTo(Dest.Right-i-1,Dest.Bottom-i-1);
        end;
      {unten}
      for i:=0 to FDepth do begin
        if not FBeveled then begin
          MoveTo(Dest.Left,Dest.Bottom-i-1);
          LineTo(Dest.Right-1,Dest.Bottom-i-1);
        end
        else begin
          MoveTo(Dest.Left+i,Dest.Bottom-i-1);
          LineTo(Dest.Right-i-1,Dest.Bottom-i-1);
        end;
      end;
    end;
    if FPanelDirection=bdTopUp then begin
      Pen.Color:=FColorHighlight;
      {oben}
      for i:=0 to FDepth do begin
        if not FBeveled then begin
          MoveTo(Dest.Left,Dest.Top+i);
          LineTo(Dest.Right-1,Dest.Top+i);
        end
        else begin
          MoveTo(Dest.Left+i,Dest.Top+i);
          LineTo(Dest.Right-i-1,Dest.Top+i);
        end;
      end;
      {links}
      if not FBeveled then begin
        MoveTo(Dest.Left,Dest.Top);
        LineTo(Dest.Left,Dest.Bottom-1);
      end
      else
        for i:=0 to FDepth do begin
          MoveTo(Dest.Left,Dest.Bottom-1);
          LineTo(Dest.Left+i,Dest.Top+i);
        end;
      Pen.Color:=FColorShadow;
      {rechts}
      if not FBeveled then begin
        MoveTo(Dest.Right-1,Dest.Top);
        LineTo(Dest.Right-1,Dest.Bottom);
      end
      else
        for i:=0 to FDepth do begin
          MoveTo(Dest.Right-1,Dest.Bottom-1);
          LineTo(Dest.Right-i-1,Dest.Top+i);
        end;
      {unten}
      MoveTo(Dest.Right-1,Dest.Bottom-1);
      LineTo(Dest.Left,Dest.Bottom-1);
    end;
    if FPanelDirection=bdLeftUp then begin
      Pen.Color:=FColorHighlight;
      {oben}
      if not FBeveled then begin
        MoveTo(Dest.Left,Dest.Top);
        LineTo(Dest.Right-1,Dest.Top);
      end
      else
        for i:=0 to FDepth do begin
          MoveTo(Dest.Right-1,Dest.Top);
          LineTo(Dest.Left+i,Dest.Top+i);
        end;
      {links}
      for i:=0 to FDepth do begin
        if not FBeveled then begin
          MoveTo(Dest.Left+i,Dest.Top);
          LineTo(Dest.Left+i,Dest.Bottom-1);
        end
        else begin
          MoveTo(Dest.Left+i,Dest.Top+i);
          LineTo(Dest.Left+i,Dest.Bottom-i-1);
        end;
      end;
      Pen.Color:=FColorShadow;
      {rechts}
      MoveTo(Dest.Right-1,Dest.Top);
      LineTo(Dest.Right-1,Dest.Bottom-1);
      {unten}
      if not FBeveled then begin
        MoveTo(Dest.Right-1,Dest.Bottom-1);
        LineTo(Dest.Left,Dest.Bottom-1);
      end
      else
        for i:=0 to FDepth do begin
          MoveTo(Dest.Right-1,Dest.Bottom-1);
          LineTo(Dest.Left+i,Dest.Bottom-i-1);
        end;
    end;
    if FPanelDirection=bdRightUp then begin
      Pen.Color:=FColorHighlight;
      {oben}
      if not FBeveled then begin
        MoveTo(Dest.Left,Dest.Top);
        LineTo(Dest.Right-1,Dest.Top);
      end
      else
        for i:=0 to FDepth do begin
          MoveTo(Dest.Left,Dest.Top);
          LineTo(Dest.Right-1-i,Dest.Top+i);
        end;
      {links}
      MoveTo(Dest.Left,Dest.Top);
      LineTo(Dest.Left,Dest.Bottom-1);
      Pen.Color:=FColorShadow;
      {rechts}
      for i:=0 to FDepth do begin
        if not FBeveled then begin
          MoveTo(Dest.Right-1-i,Dest.Top);
          LineTo(Dest.Right-1-i,Dest.Bottom-1);
        end
        else begin
          MoveTo(Dest.Right-1-i,Dest.Top+i);
          LineTo(Dest.Right-1-i,Dest.Bottom-i-1);
        end;
      end;
      {unten}
      if not FBeveled then begin
        MoveTo(Dest.Left,Dest.Bottom-1);
        LineTo(Dest.Right-1,Dest.Bottom-1);
      end
      else
        for i:=0 to FDepth do begin
          MoveTo(Dest.Left,Dest.Bottom-1);
          LineTo(Dest.Right-1-i,Dest.Bottom-i-1);
        end;
    end;
  end;
end;

procedure TButtonPanel.DrawCaption(Dest:TRect);
var OutText : array [0..79] of char;
begin
  with Canvas do begin
    Brush.Style:=bsClear;
    StrPCopy(OutText, Caption);
    DrawText(Handle, OutText, length(Caption), Dest, dt_center or dt_vcenter or dt_singleline);
  end;
end;

procedure TButtonPanel.DrawLED(var Dest:TRect);
begin
  with Canvas do begin
    Brush.Color:=clWindowFrame;
    case PanelDirection of
      bdLeftUp : begin
        FrameRect(Rect(Dest.Left+FDepth+9,Dest.Top+FDepth+3,Dest.Left+FDepth+4,Dest.Bottom-FDepth-3));
        Dest.Left:=Dest.Left+FDepth+9;
      end;
      bdRightUp : begin
        FrameRect(Rect(Dest.Right-FDepth-9,Dest.Top+FDepth+3,Dest.Right-FDepth-4,Dest.Bottom-FDepth-3));
        Dest.Right:=Dest.Right-FDepth-9;
      end;
      bdTopUp : begin
        FrameRect(Rect(Dest.Left+FDepth+3,Dest.Top+FDepth+4,Dest.Right-FDepth-3,Dest.Top+FDepth+9));
        Dest.Top:=Dest.Top+FDepth+7;
      end;
      else begin
        FrameRect(Rect(Dest.Left+FDepth+3,Dest.Bottom-FDepth-9,Dest.Right-FDepth-3,Dest.Bottom-FDepth-4));
        Dest.Bottom:=Dest.Bottom-FDepth-7;
      end;
    end;
  end;
end;

procedure TButtonPanel.Paint;
var ARect : TRect;
begin
  Canvas.Font.Assign(Font);
  with Canvas do begin
    ARect:=GetClientRect;
    Brush.Style:=bsSolid;
    Brush.Color:=FColor;
    FillRect(ARect);
    DrawBorder(ARect);
    Pen.Color:=clBlack;
    if FShowLED then
      DrawLED(ARect);
    if Caption<>'' then
      DrawCaption(ARect);
  end;
end;


{Komponente ScrewPanel}
constructor TScrewPanel.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);

  {Vorgabewerte setzen}
  FColor:=clBtnFace;
  FColorHighlight:=ChangeBrightness(FColor,50);
  FColorShadow:=ChangeBrightness(FColor,-50);
  FMargin:=2;
  FScrewSize:=2;
  FShowScrews:=true;
  Height:=DefaultHeight;
  Width:=DefaultWidth;
end;

destructor  TScrewPanel.Destroy;
begin
  inherited Destroy;
end;

procedure TScrewPanel.SetColor(newColor: TColor);
begin
  FColor:=newColor;
  FColorHighlight:=ChangeBrightness(FColor,50);
  FColorShadow:=ChangeBrightness(FColor,-50);
  Invalidate;
end;

procedure TScrewPanel.SetMargin(newValue: integer);
begin
  if (NewValue<(Width-FScrewSize)) and (NewValue<(Height-FScrewSize)) then begin
    FMargin := newValue;
    Invalidate;
  end;
end;

procedure TScrewPanel.SetScrewSize(newValue: TScrewSize);
begin
  if (NewValue<Width) and (NewValue<Height) then begin
    FScrewSize := newValue;
    Invalidate;
  end;
end;

procedure TScrewPanel.SetShowScrews(newValue: boolean);
begin
  FShowScrews := newValue;
  Invalidate;
end;

procedure TScrewPanel.DrawScrew(X,Y:integer);
var Size : integer;
begin
  Size:=FScrewSize*4;
  with Canvas do begin
    Pen.Color:=FColorShadow;
    Brush.Color:=clSilver;
    Ellipse(X,Y,X+Size,Y+Size);
    Arc(X,Y,X+Size,Y+Size,
        X+((Size div 4)*3),Y+(Size div 4),
        X+(Size div 4),Y+((Size div 4)*3));
    Pen.Color:=clGray;
    MoveTo(X+(Size div 4)-1,Y+((Size div 4)*3)-1);
    LineTo(X+((Size div 4)*3),Y+(Size div 4)-2);
    Pen.Color:=FColorHighlight;
    Arc(X,Y,X+Size,Y+Size,
        X+(Size div 4),Y+((Size div 4)*3),
        X+((Size div 4)*3),Y+(Size div 4));
    Pen.Color:=clWhite;
    MoveTo(X+(Size div 4),Y+((Size div 4)*3));
    LineTo(X+((Size div 4)*3)+1,Y+(Size div 4)-1);
  end;
end;

procedure TScrewPanel.DrawBevel(ARect:TRect;Raised:boolean);
begin
  with Canvas do begin
    Pen.Width:=BevelWidth;
    if Raised then
      Pen.Color:=FColorHighlight
    else
      Pen.Color:=FColorShadow;
    MoveTo(ARect.Right-1,ARect.Top);
    LineTo(ARect.Left,ARect.Top);
    LineTo(ARect.Left,ARect.Bottom-1);
    if Raised then
      Pen.Color:=FColorShadow
    else
      Pen.Color:=FColorHighlight;
    MoveTo(ARect.Right-1,ARect.Top);
    LineTo(ARect.Right-1,ARect.Bottom-1);
    LineTo(ARect.Left,ARect.Bottom-1);
  end;
end;

procedure TScrewPanel.Paint;
var ARect   : TRect;
    Border  : integer;
    outText : array [0..79] of char;
begin
  with Canvas do begin
    Brush.Style:=bsSolid;
    Brush.Color:=Self.Color;
    ARect:=GetClientRect;
    FillRect(ARect);
    if BevelOuter<>bvNone then begin
      DrawBevel(ARect,BevelOuter=bvRaised);
      Border:=BevelWidth+BorderWidth;
    end
    else
      Border:=BorderWidth;
    InflateRect(ARect,-Border,-Border);
    if BevelInner<>bvNone then begin
      DrawBevel(ARect,BevelInner=bvRaised);
      InflateRect(ARect,-BevelWidth,-BevelWidth);
    end;
    if FShowScrews then begin
      DrawScrew(ARect.Left+FMargin,ARect.Top+FMargin);
      DrawScrew(ARect.Right-FMargin-(FScrewSize*4),ARect.Top+FMargin);
      DrawScrew(ARect.Left+FMargin,ARect.Bottom-FMargin-(FScrewSize*4));
      DrawScrew(ARect.Right-FMargin-(FScrewSize*4),ARect.Bottom-FMargin-(FScrewSize*4));
    end;
    Font:=Self.Font;
    Brush.Style:=bsClear;
    StrPCopy(outText,Caption);
    if Alignment=taCenter then
      DrawText(Handle,outText,length(Caption),Arect,DT_SINGLELINE or DT_VCENTER or DT_CENTER);
    if Alignment=taLeftJustify then
      DrawText(Handle,outText,length(Caption),Arect,DT_SINGLELINE or DT_VCENTER or DT_LEFT);
    if Alignment=taRightJustify then
      DrawText(Handle,outText,length(Caption),Arect,DT_SINGLELINE or DT_VCENTER or DT_RIGHT);
  end;
end;


{Komponente TLEDDisplay}
procedure TLEDDisplay.AssignColors (seg: integer; s1,s2,s3,s4,s5,s6,s7: Boolean);
begin
  if s1 then
    FSegCl[seg, 1] := FColorLED
  else
    FSegCl[seg, 1] := FColorSegmentOff;
  if s2 then
    FSegCl[seg, 2] := FColorLED
  else
    FSegCl[seg, 2] := FColorSegmentOff;
  if s3 then
    FSegCl[seg, 3] := FColorLED
  else
    FSegCl[seg, 3] := FColorSegmentOff;
  if s4 then
    FSegCl[seg, 4] := FColorLED
  else
    FSegCl[seg, 4] := FColorSegmentOff;
  if s5 then
    FSegCl[seg, 5] := FColorLED
  else
    FSegCl[seg, 5] := FColorSegmentOff;
  if s6 then
    FSegCl[seg, 6] := FColorLED
  else
    FSegCl[seg, 6] := FColorSegmentOff;
  if s7 then
    FSegCl[seg, 7] := FColorLED
  else
    FSegCl[seg, 7] := FColorSegmentOff;
end;

procedure TLEDDisplay.GenerateBitMaps;
var
  TL, TR, TBL, TBR,
  ML, MTL, MTR, MR,
  MBL, MBR, BL, BTL,
  BTR, BR            : TPoint;
  c, wAlt, LineW     : integer;
begin
  LineW:=FLineWidth+2;
  wAlt := FDigitHeight;
  {Polygonpunkte zuweisen}
  TL.x := 0;
  TL.y := 0;
  TR.x := FDigitWidth-1;
  TR.y := 0;
  TBL.x := LineW - 1;
  TBL.y := LineW -1;
  TBR.x := FDigitWidth - LineW;
  TBR.y := TBL.y;
  ML.x := 0;
  ML.y := wAlt div 2;
  MTL.x := TBL.x;
  MTL.y := ML.y - (LineW div 2);
  MTR.x := TBR.x;
  MTR.y := MTL.y;
  MR.x := TR.x;
  MR.y := ML.y;
  MBL.x := TBL.x;
  MBL.y := ML.y + (LineW div 2);
  MBR.x := MTR.x; MBR.y := MBL.y;
  BL.x := 0;
  BL.y := wAlt - 1;
  BR.x := TR.x;
  BR.y := BL.y;
  BTL.x := TBL.x;
  BTL.y := wAlt - LineW;
  BTR.x := TBR.x;
  BTR.y := BTL.y;

  {Segmentfarben zuweisen}
  AssignColors (0,true,true,true,false,true,true,true);
  AssignColors (1,false,false,true,false,false,true,false);
  AssignColors (2,true,false,true,true,true,false,true);
  AssignColors (3,true,false,true,true,false,true,true);
  AssignColors (4,false,true,true,true,false,true,false);
  AssignColors (5,true,true,false,true,false,true,true);
  AssignColors (6,false,true,false,true,true,true,true);
  AssignColors (7,true,false,true,false,false,true,false);
  AssignColors (8,true,true,true,true,true,true,true);
  AssignColors (9,true,true,true,true,false,true,true);

  {Bitmap erstellen}
  for c := 0 to 9 do begin
    FDigit[c].free;
    FDigit[c] := TBitmap.create;
    FDigit[c].width := FDigitWidth;
    FDigit[c].height := wAlt;
    with FDigit[c].canvas do begin
      Pen.Color := FColorBackGround;
      Brush.Color := FColorBackGround;
      Brush.style := bsSolid;
      Pen.Width := 1;
      Rectangle (TL.x, TL.y, BR.x+1, BR.y+1);
      if FSegmentStyle=ssRectangular then
        Pen.Width:=FLineWidth;
      {Segment 1}
      Brush.Color := FSegCl[c, 1];
      if FSegmentStyle=ssRectangular then begin
        Pen.Color := FSegCl[c, 1];
        MoveTo(FLineWidth, FLineWidth div 2);
        LineTo(FDigit[c].Width-FLineWidth-1, FLineWidth div 2);
      end
      else
        Polygon ([TL, TR, TBR, TBL]);
      {Segment 2}
      Brush.Color := FSegCl[c, 2];
      if FSegmentStyle=ssRectangular then begin
        Pen.Color := FSegCl[c, 2];
        MoveTo(FLineWidth div 2, FLineWidth*3 div 2);
        LineTo(FLineWidth div 2, (FDigit[c].Height div 2)-FLineWidth);
      end
      else
        Polygon ([TL, TBL, MTL, ML]);
      {Segment 3}
      Brush.Color := FSegCl[c, 3];
      if FSegmentStyle=ssRectangular then begin
        Pen.Color := FSegCl[c, 3];
        MoveTo(FDigit[c].Width-(FLineWidth div 2)-1, FLineWidth*3 div 2);
        LineTo(FDigit[c].Width-(FLineWidth div 2)-1, (FDigit[c].Height div 2)-FLineWidth);
      end
      else
        Polygon ([TR, MR, MTR, TBR]);
      {Segment 4}
      Brush.Color := FSegCl[c, 4];
      if FSegmentStyle=ssRectangular then begin
        Pen.Color := FSegCl[c, 4];
        MoveTo(FLineWidth, FDigit[c].Height div 2);
        LineTo(FDigit[c].Width-FLineWidth, FDigit[c].Height div 2);
      end
      else
        Polygon ([ML, MTL, MTR, MR, MBR, MBL]);
      {Segment 5}
      Brush.Color := FSegCl[c, 5];
      if FSegmentStyle=ssRectangular then begin
        Pen.Color := FSegCl[c, 5];
        MoveTo(FLineWidth div 2, (FDigit[c].Height div 2)+FLineWidth);
        LineTo(FLineWidth div 2, FDigit[c].Height-(FLineWidth*3 div 2));
      end
      else
        Polygon ([ML, MBL, BTL, BL]);
      {Segment 6}
      Brush.Color := FSegCl[c, 6];
      if FSegmentStyle=ssRectangular then begin
        Pen.Color := FSegCl[c, 6];
        MoveTo(FDigit[c].Width-(FLineWidth div 2)-1, (FDigit[c].Height div 2)+FLineWidth);
        LineTo((FDigit[c].Width-FLineWidth div 2)-1, FDigit[c].Height-(FLineWidth*3 div 2));
      end
      else
        Polygon ([MR, BR, BTR, MBR]);
      {Segment 7}
      Brush.Color := FSegCl[c, 7];
      if FSegmentStyle=ssRectangular then begin
        Pen.Color := FSegCl[c, 7];
        MoveTo(FLineWidth, FDigit[c].Height-(FLineWidth div 2)-1);
        LineTo(FDigit[c].Width-FLineWidth, FDigit[c].Height-(FLineWidth div 2)-1);
      end
      else
        Polygon ([BL, BTL, BTR, BR]);
    end;
  end;
end;

constructor TLEDDisplay.Create (AOwner: TComponent);
begin
  inherited Create (AOwner);

  BevelStyle:= bvLowered;
  BorderStyle:= bsSingle;
  ColorBackGround:= clGray;
  ColorLED:= clLime;
  FColorSegmentOff:=ChangeBrightness(FColorLED,-50);
  DecSeperator:= dsComma;
  DigitHeight:= 30;
  DigitWidth:= 20;
  DigitLineWidth:= 3;
  Height:= 36;
  LeadingZeros:= true;
  NumDigits:= 6;
  SegmentStyle:= ssBeveled;
  Value:= 0;
  Width:= 168;

  GenerateBitMaps;
end;

destructor TLEDDisplay.Destroy;
begin
  inherited destroy;
end;

procedure TLEDDisplay.setBevelStyle (newValue: TPanelBevel);
begin
  FBevelStyle := newValue;
  Invalidate;
end;

procedure TLEDDisplay.setBorderStyle (newValue: TBorderStyle);
begin
  FBorderStyle := newValue;
  Invalidate;
end;

procedure TLEDDisplay.setColorBackGround (newValue: TColor);
begin
  FColorBackGround := NewValue;
  GenerateBitMaps;
  Invalidate;
end;

procedure TLEDDisplay.setColorLED (newValue: TColor);
begin
  FColorLED := newValue;
  FColorSegmentOff:=ChangeBrightness(FColorLED,-50);
  GenerateBitMaps;
  Invalidate;
end;

procedure TLEDDisplay.setDecSeperator (newValue: TDecSeperator);
begin
  FDecSeperator := newValue;
  Invalidate;
end;

procedure TLEDDisplay.setDigitHeight (newValue: integer);
begin
  FDigitHeight := newValue;
  GenerateBitMaps;
  Invalidate;
end;

procedure TLEDDisplay.setDigitWidth (newValue: integer);
begin
  FDigitWidth := newValue;
  GenerateBitMaps;
  Invalidate;
end;

procedure TLEDDisplay.setFractionDigits (newValue: integer);
begin
  FFractionDigits := newValue;
  if FFractionDigits>(FNumDigits-1) then
    FFractionDigits:=FNumDigits-1;
  Invalidate;
end;

procedure TLEDDisplay.setLeadingZeros (newValue: boolean);
begin
  FLeadingZeros := newValue;
  Invalidate;
end;

procedure TLEDDisplay.setLineWidth (newValue: integer);
begin
  FLineWidth := newValue;
  GenerateBitMaps;
  Invalidate;
end;

procedure TLEDDisplay.setNumDigits (newValue: integer);
begin
  FNumDigits := newValue;
  Invalidate;
end;

procedure TLEDDisplay.setSegmentStyle (newValue: TSegmentStyle);
begin
  FSegmentStyle:= newValue;
  GenerateBitMaps;
  Invalidate;
end;

procedure TLEDDisplay.setValue (newValue: extended);
begin
  FValue := NewValue;
  GenerateBitMaps;
  Invalidate;
  Change;
end;

procedure TLEDDisplay.Change;
begin
  if Assigned(FOnChange) then
    FOnChange(Self);
end;

procedure TLEDDisplay.paint;
var
  Area        : TRect;
  outText     : string;
  anchoPosi,
  posiLeft,
  PosiTop, c,
  SepPosition : integer;
  { WK }
  AlreadyNonZeroDigit: Boolean;
  { wk }
begin
  Area := getClientRect;
  try
    outText:=FloatToStrF(FValue,ffFixed,18,FFractionDigits);
  except
    outText:='';
  end;
  SepPosition:=Pos(DecimalSeparator,outText);
  if SepPosition>0 then
    delete(outText,SepPosition,1);
  while length(outText)<FNumDigits do begin
    outText:='0'+outText;
    if SepPosition>0 then
      inc(SepPosition);
  end;
  { WK }
  AlreadyNonZeroDigit := False; { bis jetzt noch keine Ziffer von 1..9 }
  { wk }
  with canvas do begin
    Brush.Color := FColorBackGround;
    FillRect (Area);
    anchoPosi := self.width div FNumDigits;
    PosiTop := (self.height - FDigitHeight) div 2;
    posiLeft := (anchoPosi - FDigitwidth) div 2;
    Brush.Color := FColorLED;
    Pen.Color := FColorLED;
    {Bitmaps und DecSeperator zeichnen}
    for c := 1 to FNumDigits do begin
      { nachfolgende Nullen müssen gezeichnet werden! }
      if FLeadingZeros or (strToInt(outText[c])<>0) { WK } or AlreadyNonZeroDigit { wk } then { WK } begin { wk }
        Draw (posiLeft, posiTop, FDigit[strToInt(outText[c])]);
        { WK }
        AlreadyNonZeroDigit := True; { spätestens jetzt isse da... }
      end; { wk }
      inc (posiLeft, anchoPosi);
      if c=(SepPosition-1) then begin
        Pen.Width:=1;
        if FDecSeperator=dsPoint then
          Ellipse(posiLeft-6, posiTop+FDigitHeight-5, posiLeft-2, posiTop+FDigitHeight-1);
        if FDecSeperator=dsComma then begin
          Ellipse(posiLeft-6, posiTop+FDigitHeight-8, posiLeft-2, posiTop+FDigitHeight-4);
          MoveTo(posiLeft-3, posiTop+FDigitHeight-5);
          LineTo(posiLeft-6, posiTop+FDigitHeight-1);
          LineTo(posiLeft-2, posiTop+FDigitHeight-6);
        end;
        if FDecSeperator=dsDoublePoint then begin
          Ellipse(posiLeft-6, posiTop+(FDigitHeight div 3)-2, posiLeft-2, posiTop+(FDigitHeight div 3)+2);
          Ellipse(posiLeft-6, posiTop+(FDigitHeight*2 div 3)-2, posiLeft-2, posiTop+(FDigitHeight*2 div 3)+2);
        end;
        if FDecSeperator=dsMinus then begin
          Pen.Width:=FLineWidth;
          MoveTo(posiLeft-6, posiTop+((FDigitHeight) div 2));
          LineTo(posiLeft-FLineWidth, posiTop+((FDigitHeight) div 2));
        end;
      end;
    end;
    {Bevel zeichnen}
    if BevelStyle<>bvNone then begin
      if BevelStyle=bvRaised then
        Pen.Color:=clBtnHighlight
      else
        Pen.Color:=clBtnShadow;
      MoveTo(Area.Right-1,Area.Top);
      LineTo(Area.Left,Area.Top);
      LineTo(Area.Left,Area.Bottom-1);
      if BevelStyle=bvRaised then
        Pen.Color:=clBtnShadow
      else
        Pen.Color:=clBtnHighlight;
      MoveTo(Area.Left,Area.Bottom-1);
      LineTo(Area.Right-1,Area.Bottom-1);
      LineTo(Area.Right-1,Area.Top);
      InflateRect(Area,-1,-1);
    end;
    {Border zeichnen}
    if BorderStyle<>bsNone then begin
      Brush.Color:=clWindowFrame;
      FrameRect(Area);
    end;
  end;
end;


{Komponente TLEDMeter}
constructor TLEDMeter.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  FBevelStyle        := bvlowered;
  FColorLED1         := clLime;
  FColorLED2         := clYellow;
  FColorLED3         := clRed;
  FColorOff1         := ChangeBrightness(FColorLED1,-50);
  FColorOff2         := ChangeBrightness(FColorLED2,-50);
  FColorOff3         := ChangeBrightness(FColorLED3,-50);
  FColorSeperator    := clBlack;
  FDirection         := mdRight;
  FMax               := 100;
  FMin               := 0;
  FNumDigits         := 20;
  FPosition          := 0;
  FStartColor2       := 75;
  FStartColor3       := 90;
  Height             := 16;
  Width              := 143;
end;

destructor TLEDMeter.Destroy;
begin
  inherited Destroy;
end;

procedure TLEDMeter.SetBevelStyle(newVal : TPanelBevel);
begin
  if newVal <> FBevelStyle then begin
    FBevelStyle := newVal;
    Paint;
  end;
end;

procedure TLEDMeter.setColorLED1(newVal : tcolor);
begin
  if newVal <> FColorLED1 then begin
    FColorLED1 := newVal;
    FColorOff1 := ChangeBrightness(FColorLED1,-50);
    Paint;
  end;
end;

procedure TLEDMeter.setColorLED2(newVal : tcolor);
begin
  if newVal <> FColorLED2 then begin
    FColorLED2 := newVal;
    FColorOff2 := ChangeBrightness(FColorLED2,-50);
    Paint;
  end;
end;

procedure TLEDMeter.setColorLED3(newVal : tcolor);
begin
  if newVal <> FColorLED3 then begin
    FColorLED3 := newVal;
    FColorOff3 := ChangeBrightness(FColorLED3,-50);
    Paint;
  end;
end;

procedure TLEDMeter.setColorSeperator(newVal : tcolor);
begin
  if newVal <> FColorSeperator then begin
    FColorSeperator := newVal;
    Paint;
  end;
end;

procedure TLEDMeter.setDirection(newVal : TMeterDirection);
begin
  if newVal <> FDirection then begin
    FDirection := newVal;
    Paint;
  end;
end;

procedure TLEDMeter.setMax(newVal : integer);
begin
  if newVal <> FMax then begin
    FMax := newVal;
    if newVal<FStartColor2 then
      FStartColor2:=newVal;
    if newVal<FStartColor3 then
      FStartColor3:=newVal;
    Paint;
  end;
end;

procedure TLEDMeter.setMin(newVal : integer);
begin
  if newVal <> FMin then begin
    FMin := newVal;
    if newVal>FStartColor2 then
      FStartColor2:=newVal;
    if newVal>FStartColor3 then
      FStartColor3:=newVal;
    Paint;
  end;
end;

procedure TLEDMeter.setNumDigits(newVal : integer);
begin
  if newVal <> FNumDigits then begin
    FNumDigits := newVal;
    Paint;
  end;
end;

procedure TLEDMeter.setPosition(newVal : integer);
begin
  if newVal <> FPosition then begin
    if newVal>FMax then
      newVal:=FMax;
    if newVal<FMin then
      newVal:=FMin;
    FPosition := newVal;
    Paint;
    Change;
  end;
end;

procedure TLEDMeter.setStartColor2(newVal : integer);
begin
  if newVal <> FStartColor2 then begin
    if newVal>Max then
      newVal:=Max;
    if newVal<Min then
      newVal:=Min;
    if newVal>FStartColor3 then
      newVal:=FStartColor3;
    FStartColor2 := newVal;
    Paint;
  end;
end;

{added 15.10.99, U. Conrad:}
procedure TLEDMeter.setSingleLED(newVal : boolean);
begin
  if newVal<>FSingleLED then begin
    FSingleLED:=newVal;
    Paint;
  end;
end;

procedure TLEDMeter.setStartColor3(newVal : integer);
begin
  if newVal <> FStartColor3 then begin
    if newVal>Max then
      newVal:=Max;
    if newVal<Min then
      newVal:=Min;
    if newVal<FStartColor2 then
      newVal:=FStartColor2;
    FStartColor3 := newVal;
    Paint;
  end;
end;

procedure TLEDMeter.Change;
begin
  if Assigned(FOnChange) then
    FOnChange(Self);
end;

procedure TLEDMeter.Paint;
var ARect       : TRect;
    NumPos,DPos,
    FirstYel,
    FirstRed,
    DigitLeft,
    DigitTop,i,
    DigitWidth,
    DigitHeight,
    BevelWidth  : integer;
begin
  with Canvas do begin
    NumPos:=FMax-FMin;
    if BevelStyle<>bvNone then
      BevelWidth:=1
    else
      BevelWidth:=0;
    {v0.24}
    DigitLeft := 0;
    DigitTop := 0;
    {/v0.24}
    if (FDirection = mdRight) or (FDirection = mdLeft) then begin
      DigitWidth:=(Width-(2*BevelWidth)) div FNumDigits;
      DigitHeight:=Height-(2*BevelWidth);
      DigitTop:=BevelWidth;
    end
    else begin
      DigitWidth := Width-(2*BevelWidth)-1;
      DigitHeight := (Height-(2*BevelWidth)) div FNumDigits;
      DigitLeft := BevelWidth;
    end;
    if (NumPos>0) and (FPosition>0) then
      DPos:=round(FNumDigits/(NumPos/FPosition))
    else
      DPos:=0;
    if (NumPos>0) and (FStartColor2>0) then
      FirstYel:=round(FNumDigits/(NumPos/FStartColor2))
    else
      FirstYel:=0;
    if (NumPos>0) and (FStartColor3>0) then
      FirstRed:=round(FNumDigits/(NumPos/FStartColor3))
    else
      FirstRed:=0;

    {changed 15.10.99, U. Conrad:}
    for i:=0 to FNumDigits-1 do begin
      if i>=DPos then begin
        if i<FirstYel then
          Brush.Color:=FColorOff1
        else
          if i<FirstRed then
            Brush.Color:=FColorOff2
          else
            Brush.Color:=FColorOff3;
      end
      else begin
        {added 15.10.99, U. Conrad:}
        if FSingleLED then begin
          if (i=DPos-1) then begin
            if i<FirstYel then
              Brush.Color:=FColorLED1
            else
              if i<FirstRed then
                Brush.Color:=FColorLED2
              else
                Brush.Color:=FColorLED3;
          end
          else begin
            if i<FirstYel then
              Brush.Color:=FColorOff1
            else
              if i<FirstRed then
                Brush.Color:=FColorOff2
              else
                Brush.Color:=FColorOff3;
          end;
        end
        else begin
          if i<FirstYel then
            Brush.Color:=FColorLED1
          else
            if i<FirstRed then
              Brush.Color:=FColorLED2
            else
              Brush.Color:=FColorLED3;
        end;
      end;
      if FDirection = mdRight then
        DigitLeft := BevelWidth+(i*DigitWidth);
      if FDirection = mdLeft then
        DigitLeft := Width-BevelWidth-((i+1)*DigitWidth)-1;
      if FDirection = mdUp then
        DigitTop := Height-BevelWidth-((i+1)*DigitHeight);
      if FDirection = mdDown then
        DigitTop := BevelWidth+(i*DigitHeight);
      Pen.Color:=FColorSeperator;
      Rectangle(DigitLeft, DigitTop, DigitLeft + DigitWidth + 1, DigitTop + DigitHeight);
    end;
    if BevelStyle<>bvNone then begin
      if BevelStyle=bvRaised then
        Pen.Color:=clBtnHighlight
      else
        Pen.Color:=clBtnShadow;
      ARect:=GetClientRect;
      MoveTo(ARect.Right-1,ARect.Top);
      LineTo(ARect.Left,ARect.Top);
      LineTo(ARect.Left,ARect.Bottom-1);
      if BevelStyle=bvRaised then
        Pen.Color:=clBtnShadow
      else
        Pen.Color:=clBtnHighlight;
      MoveTo(ARect.Left,ARect.Bottom-1);
      LineTo(ARect.Right-1,ARect.Bottom-1);
      LineTo(ARect.Right-1,ARect.Top);
    end;
  end;
end;


procedure Register;
begin
  RegisterComponents('Devices',[TLEDButton]);
  RegisterComponents('Devices',[TButtonPanel]);
  RegisterComponents('Devices',[TScrewPanel]);
  RegisterComponents('Devices', [TLEDDisplay]);
  RegisterComponents('Devices', [TLEDMeter]);
end;

end.
