home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / sibdemo3.zip / SOURCE.DAT / SOURCE / ADDON / SEVEN.PAS < prev    next >
Pascal/Delphi Source File  |  1998-05-02  |  7KB  |  283 lines

  1. {************************************************}
  2. {                                                }
  3. { TSevenSegDisplay component                     }
  4. {                                                }
  5. { A seven-segment display panel for Sibyl        }
  6. {                                                }
  7. { Copyright (C) 1996-1997 Joerg Pleumann         }
  8. {                                                }
  9. { Mail bugs to: pleumann@uni-duisburg.de         }
  10. {                                                }
  11. {************************************************}
  12.  
  13. unit Seven;
  14.  
  15. interface
  16.  
  17. uses
  18.   Classes, Forms, Graphics;
  19.  
  20. type
  21.   TSevenSegDisplay = class(TControl)
  22.   private
  23.     FDigits:      string;
  24.     FSegments:    string;
  25.     FBorderStyle: TBorderStyle;
  26.     FMargin:      LongInt;
  27.  
  28.     procedure SetBorderStyle(Value: TBorderStyle);
  29.     procedure SetDigits(const Value: string);
  30.     procedure SetMargin(Value: LongInt);
  31.   public
  32.     constructor Create(Owner: TComponent); override;
  33.     procedure Redraw(const Rec: TRect); override;
  34.  
  35.     property XAlign;
  36.     property XStretch;
  37.     property YAlign;
  38.     property YStretch;
  39.   published
  40.     property Align;
  41.     property BorderStyle: TBorderStyle read FBorderStyle write SetBorderStyle;
  42.       { Holds the border style of the seven segment
  43.         display. The following values are supported:
  44.         bsNone   - No border
  45.         bsSingle - Border with 3D appearance }
  46.     property Digits: string read FDigits write SetDigits;
  47.       { The Digits property holds the current content
  48.         string of the seven segment display. The
  49.         following digits and characters are supported:
  50.  
  51.         The characters '0' to '9' and 'A' to 'F',
  52.         allowing the display of decimal and
  53.         hexadecimal numbers.
  54.  
  55.         The additional characters 'H', 'I', 'J', 'L',
  56.         'N', 'O', 'R', 'S', 'U', and 'Y', allowing the
  57.         display of the following strings:
  58.  
  59.         'ON'            'EIN'
  60.         'OFF'           'AUS'
  61.         'YES'           'JA'
  62.         'NO'            'NEIN'
  63.         'ERROR'         'FEHLER'
  64.  
  65.         I must, however, admit that some of the
  66.         strings look very strange... :-)
  67.  
  68.         The minus sign ('-') highlights the center
  69.         segment.
  70.  
  71.         The space (' ') results in a digit with no
  72.         segments highlighted. The underscore ('_')
  73.         results in a place with no segments at all.
  74.         This might be useful if you want to display
  75.         date and time in one panel, as an example.
  76.  
  77.         After each character, an additional modifier
  78.         may be used to control the separators between
  79.         two digits. The following modifiers are
  80.         supported:
  81.  
  82.         '~'      - No separator at all, not even
  83.                    the segments are displayed.
  84.         '.', ',' - Highlights the lower separator
  85.                    segment.
  86.         ':'      - Highlights both separator segments.
  87.  
  88.         The modifiers are optional. If none of them
  89.         is present, both separator segments are
  90.         visible, but not highlighted. }
  91.     property DragCursor;
  92.     property DragMode;
  93.     property Margin: LongInt read FMargin write SetMargin;
  94.       { Holds the distance between each of the four
  95.         borders and the digits. }
  96.     property ParentShowHint;
  97.     property PopupMenu;
  98.     property ShowHint;
  99.     property Visible;
  100.     property ZOrder;
  101.  
  102.     property OnCanDrag;
  103.     property OnDblClick;
  104.     property OnDragDrop;
  105.     property OnDragOver;
  106.     property OnEndDrag;
  107.     property OnMouseClick;
  108.     property OnMouseDblClick;
  109.     property OnMouseDown;
  110.     property OnMouseMove;
  111.     property OnMouseUp;
  112.     property OnResize;
  113.     property OnSetupShow;
  114.     property OnStartDrag;
  115.   end;
  116.  
  117. implementation
  118.  
  119. {$r Seven}
  120.  
  121. var
  122.   Digits: TBitmap;
  123.  
  124. procedure DrawDigit(Canvas: TCanvas; Dest: TRect; Digit, Separator: Byte);
  125. var
  126.   SourceRect, DestRect: TRect;
  127. begin
  128.   DestRect := Dest;
  129.   Dec(DestRect.Right, (Dest.Right - Dest.Left) div 5);
  130.  
  131.   with SourceRect do
  132.   begin
  133.     Left   := 20 * (Digit mod 10);
  134.     Bottom := 60 - 30 * Int((Digit / 10)); (* Igitt! *)
  135.     Right  := Left + 20;
  136.     Top    := Bottom + 30;
  137.   end;
  138.  
  139.   Digits.PartialDraw(Canvas, SourceRect, DestRect);
  140.  
  141.   DestRect.Left := DestRect.Right;
  142.   DestRect.Right := Dest.Right;
  143.  
  144.   with SourceRect do
  145.   begin
  146.     Left   := 180 + Separator * 5;
  147.     Right  := Left + 5;
  148.     Bottom := 0;
  149.     Top    := 30;
  150.   end;
  151.  
  152.   Digits.PartialDraw(Canvas, SourceRect, DestRect);
  153. end;
  154.  
  155. constructor TSevenSegDisplay.Create(Owner: TComponent);
  156. begin
  157.   inherited Create(Owner);
  158.   Name := 'SevenSegDisplay';
  159.   Width := 110;
  160.   Height := 40;
  161.   Color := clBlack;
  162.   PenColor := clBlack;
  163.   Margin := 5;
  164. end;
  165.  
  166. procedure TSevenSegDisplay.Redraw(const Rec: TRect);
  167. var
  168.   DestRect: TRect;
  169.   DigitWidth, DigitHeight: LongInt;
  170.   I, B: Byte;
  171. begin
  172.   inherited Redraw(Rec);
  173.  
  174.   DestRect := ClientRect;
  175.  
  176.   if BorderStyle = bsSingle then
  177.     DrawSystemBorder(self, DestRect, bsSingle);
  178.  
  179.   if FSegments = '' then Exit;
  180.  
  181.   DigitWidth := (Width - 2 * FMargin) div Length(FSegments);
  182.   DigitHeight := Height - 2 * FMargin;
  183.  
  184.   DestRect := Rect(FMargin, FMargin, FMargin + DigitWidth, FMargin + DigitHeight);
  185.  
  186.   for I := 1 to Length(FSegments) do
  187.   begin
  188.     B := Ord(FSegments[I]);
  189.  
  190.     if not IsRectEmpty(IntersectRect(Rec, DestRect)) then
  191.       DrawDigit(Canvas, DestRect, B and 31, B shr 5);
  192.  
  193.     Inc(DestRect.Left, DigitWidth);
  194.     Inc(DestRect.Right, DigitWidth);
  195.   end;
  196. end;
  197.  
  198. procedure TSevenSegDisplay.SetBorderStyle(Value: TBorderStyle);
  199. begin
  200.   FBorderStyle := Value;
  201.   Invalidate;
  202. end;
  203.  
  204. procedure TSevenSegDisplay.SetDigits(const Value: string);
  205. var
  206.   I: Integer;
  207.   C: Char;
  208.   D: Byte;
  209. begin
  210.   if Value <> FDigits then
  211.   begin
  212.     FSegments := '';
  213.     I := 1;
  214.     while I <= Length(Value) do
  215.     begin
  216.       C := UpCase(Value[I]);
  217.       case C of
  218.         '0' .. '9': D := Ord(C) - Ord('0');
  219.         'A' .. 'F': D := 10 + Ord(C) - Ord('A');
  220.         'H'       : D := 16;
  221.         'I'       : D := 17;
  222.         'J'       : D := 18;
  223.         'L'       : D := 19;
  224.         'N'       : D := 20;
  225.         'O'       : D := 21;
  226.         'R'       : D := 22;
  227.         'S'       : D :=  5;
  228.         'U'       : D := 23;
  229.         'Y'       : D := 24;
  230.         ' '       : D := 26;
  231.         '-'       : D := 27;
  232.         '_'       : D := 28;
  233.       else
  234.         D := 255;
  235.       end;
  236.       Inc(I);
  237.  
  238.       if I <= Length(Value) then
  239.       begin
  240.         C := UpCase(Value[I]);
  241.         case C of
  242.           '~':      Inc(I);
  243.           '.', ',': begin
  244.                       D := D or 64;
  245.                       Inc(I);
  246.                     end;
  247.           ':':      begin
  248.                       D := D or 96;
  249.                       Inc(I);
  250.                     end;
  251.         else
  252.           D := D or 32;
  253.         end;
  254.       end
  255.       else D := D or 32;
  256.  
  257.       if D <> 255 then FSegments := FSegments + Chr(D);
  258.     end;
  259.   end;
  260.  
  261.   FDigits := Value;
  262.  
  263.   InvalidateRect(Rect(FMargin, FMargin, Width - FMargin, Height - FMargin));
  264. end;
  265.  
  266. procedure TSevenSegDisplay.SetMargin(Value: LongInt);
  267. begin
  268.   FMargin := Value;
  269.   Invalidate;
  270. end;
  271.  
  272. initialization
  273.   RegisterClasses([TSevenSegDisplay]);
  274.  
  275.   Digits := TBitmap.Create;
  276.   Digits.LoadFromResourceName('SevenSegDigits');
  277.  
  278. finalization
  279.  
  280.   Digits.Free;
  281. end.
  282.  
  283.