home *** CD-ROM | disk | FTP | other *** search
- {************************************************}
- { }
- { Turbo Pascal 6.0 }
- { Turbo Vision Demo }
- { Copyright (c) 1990 by Borland International }
- { }
- {************************************************}
-
- unit Calc;
-
- {$F+,O+,S-,D-}
-
- { Calculator object. See TVDEMO.PAS for an example
- program that uses this unit.
- }
-
- interface
-
- uses Drivers, Objects, Views, Dialogs;
-
- type
-
- TCalcState = (csFirst, csValid, csError);
-
- PCalcDisplay = ^TCalcDisplay;
- TCalcDisplay = object(TView)
- Status: TCalcState;
- Number: string[15];
- Sign: Char;
- Operator: Char;
- Operand: Real;
- constructor Init(var Bounds: TRect);
- constructor Load(var S: TStream);
- procedure CalcKey(Key: Char);
- procedure Clear;
- procedure Draw; virtual;
- function GetPalette: PPalette; virtual;
- procedure HandleEvent(var Event: TEvent); virtual;
- procedure Store(var S: TStream);
- end;
-
- PCalculator = ^TCalculator;
- TCalculator = object(TDialog)
- constructor Init;
- end;
-
- const
- RCalcDisplay: TStreamRec = (
- ObjType: 10040;
- VmtLink: Ofs(TypeOf(TCalcDisplay)^);
- Load: @TCalcDisplay.Load;
- Store: @TCalcDisplay.Store
- );
- RCalculator: TStreamRec = (
- ObjType: 10041;
- VmtLink: Ofs(TypeOf(TCalculator)^);
- Load: @TCalculator.Load;
- Store: @TCalculator.Store
- );
-
- procedure RegisterCalc;
-
- implementation
-
- const
- cmCalcButton = 100;
-
- constructor TCalcDisplay.Init(var Bounds: TRect);
- begin
- TView.Init(Bounds);
- Options := Options or ofSelectable;
- EventMask := evKeyDown + evBroadcast;
- Clear;
- end;
-
- constructor TCalcDisplay.Load(var S: TStream);
- begin
- TView.Load(S);
- S.Read(Status, SizeOf(Status) + SizeOf(Number) + SizeOf(Sign) +
- SizeOf(Operator) + SizeOf(Operand));
- end;
-
- procedure TCalcDisplay.CalcKey(Key: Char);
- var
- R: Real;
-
- procedure Error;
- begin
- Status := csError;
- Number := 'Error';
- Sign := ' ';
- end;
-
- procedure SetDisplay(R: Real);
- var
- S: string[63];
- begin
- Str(R: 0: 10, S);
- if S[1] <> '-' then Sign := ' ' else
- begin
- Delete(S, 1, 1);
- Sign := '-';
- end;
- if Length(S) > 15 + 1 + 10 then Error
- else
- begin
- while S[Length(S)] = '0' do Dec(S[0]);
- if S[Length(S)] = '.' then Dec(S[0]);
- Number := S;
- end;
- end;
-
- procedure GetDisplay(var R: Real);
- var
- E: Integer;
- begin
- Val(Sign + Number, R, E);
- end;
-
- procedure CheckFirst;
- begin
- if Status = csFirst then
- begin
- Status := csValid;
- Number := '0';
- Sign := ' ';
- end;
- end;
-
- begin
- Key := UpCase(Key);
- if (Status = csError) and (Key <> 'C') then Key := ' ';
- case Key of
- '0'..'9':
- begin
- CheckFirst;
- if Number = '0' then Number := '';
- Number := Number + Key;
- end;
- '.':
- begin
- CheckFirst;
- if Pos('.', Number) = 0 then Number := Number + '.';
- end;
- #8, #27:
- begin
- CheckFirst;
- if Length(Number) = 1 then Number := '0' else Dec(Number[0]);
- end;
- '_', #241:
- if Sign = ' ' then Sign := '-' else Sign := ' ';
- '+', '-', '*', '/', '=', '%', #13:
- begin
- if Status = csValid then
- begin
- Status := csFirst;
- GetDisplay(R);
- if Key = '%' then
- case Operator of
- '+', '-': R := Operand * R / 100;
- '*', '/': R := R / 100;
- end;
- case Operator of
- '+': SetDisplay(Operand + R);
- '-': SetDisplay(Operand - R);
- '*': SetDisplay(Operand * R);
- '/': if R = 0 then Error else SetDisplay(Operand / R);
- end;
- end;
- Operator := Key;
- GetDisplay(Operand);
- end;
- 'C':
- Clear;
- end;
- DrawView;
- end;
-
- procedure TCalcDisplay.Clear;
- begin
- Status := csFirst;
- Number := '0';
- Sign := ' ';
- Operator := '=';
- end;
-
- procedure TCalcDisplay.Draw;
- var
- Color: Byte;
- I: Integer;
- B: TDrawBuffer;
- begin
- Color := GetColor(1);
- I := Size.X - Length(Number) - 2;
- MoveChar(B, ' ', Color, Size.X);
- MoveChar(B[I], Sign, Color, 1);
- MoveStr(B[I + 1], Number, Color);
- WriteBuf(0, 0, Size.X, 1, B);
- end;
-
- function TCalcDisplay.GetPalette: PPalette;
- const
- P: string[1] = #19;
- begin
- GetPalette := @P;
- end;
-
- procedure TCalcDisplay.HandleEvent(var Event: TEvent);
- begin
- TView.HandleEvent(Event);
- case Event.What of
- evKeyDown:
- begin
- CalcKey(Event.CharCode);
- ClearEvent(Event);
- end;
- evBroadcast:
- if Event.Command = cmCalcButton then
- begin
- CalcKey(PButton(Event.InfoPtr)^.Title^[1]);
- ClearEvent(Event);
- end;
- end;
- end;
-
- procedure TCalcDisplay.Store(var S: TStream);
- begin
- TView.Store(S);
- S.Write(Status, SizeOf(Status) + SizeOf(Number) + SizeOf(Sign) +
- SizeOf(Operator) + SizeOf(Operand));
- end;
-
- { TCalculator }
-
- constructor TCalculator.Init;
- const
- KeyChar: array[0..19] of Char = 'C'#27'%'#241'789/456*123-0.=+';
- var
- I: Integer;
- P: PView;
- R: TRect;
- begin
- R.Assign(5, 3, 29, 18);
- TDialog.Init(R, 'Calculator');
- Options := Options or ofFirstClick;
- for I := 0 to 19 do
- begin
- R.A.X := (I mod 4) * 5 + 2;
- R.A.Y := (I div 4) * 2 + 4;
- R.B.X := R.A.X + 5;
- R.B.Y := R.A.Y + 2;
- P := New(PButton, Init(R, KeyChar[I], cmCalcButton,
- bfNormal + bfBroadcast));
- P^.Options := P^.Options and not ofSelectable;
- Insert(P);
- end;
- R.Assign(3, 2, 21, 3);
- Insert(New(PCalcDisplay, Init(R)));
- end;
-
- procedure RegisterCalc;
- begin
- RegisterType(RCalcDisplay);
- RegisterType(RCalculator);
- end;
-
- end.
-