| [7] | 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 | 
 | 
|---|