home *** CD-ROM | disk | FTP | other *** search
/ The Devil's Doorknob BBS Capture (1996-2003) / devilsdoorknobbbscapture1996-2003.iso / Dloads / OTHERUTI / TPASCAL3.ZIP / TVISION.ZIP / APP.PAS next >
Pascal/Delphi Source File  |  1991-06-11  |  13KB  |  609 lines

  1.  
  2. {*******************************************************}
  3. {                                                       }
  4. {       Turbo Pascal Version 6.0                        }
  5. {       Turbo Vision Unit                               }
  6. {                                                       }
  7. {       Copyright (c) 1990 Borland International        }
  8. {                                                       }
  9. {*******************************************************}
  10.  
  11. unit App;
  12.  
  13. {$F+,O+,S-,X+,D-}
  14.  
  15. interface
  16.  
  17. uses Objects, Drivers, Memory, HistList, Views, Menus;
  18.  
  19. const
  20.  
  21. { TApplication palette entries }
  22.  
  23.   apColor      = 0;
  24.   apBlackWhite = 1;
  25.   apMonochrome = 2;
  26.  
  27. { TApplication palettes }
  28.  
  29.   CColor =
  30.         #$71#$70#$78#$74#$20#$28#$24#$17#$1F#$1A#$31#$31#$1E#$71#$00 +
  31.     #$37#$3F#$3A#$13#$13#$3E#$21#$00#$70#$7F#$7A#$13#$13#$70#$7F#$00 +
  32.     #$70#$7F#$7A#$13#$13#$70#$70#$7F#$7E#$20#$2B#$2F#$78#$2E#$70#$30 +
  33.     #$3F#$3E#$1F#$2F#$1A#$20#$72#$31#$31#$30#$2F#$3E#$31#$13#$00#$00;
  34.  
  35.   CBlackWhite =
  36.         #$70#$70#$78#$7F#$07#$07#$0F#$07#$0F#$07#$70#$70#$07#$70#$00 +
  37.     #$07#$0F#$07#$70#$70#$07#$70#$00#$70#$7F#$7F#$70#$07#$70#$07#$00 +
  38.     #$70#$7F#$7F#$70#$07#$70#$70#$7F#$7F#$07#$0F#$0F#$78#$0F#$78#$07 +
  39.     #$0F#$0F#$0F#$70#$0F#$07#$70#$70#$70#$07#$70#$0F#$07#$07#$00#$00;
  40.  
  41.   CMonochrome =
  42.         #$70#$07#$07#$0F#$70#$70#$70#$07#$0F#$07#$70#$70#$07#$70#$00 +
  43.     #$07#$0F#$07#$70#$70#$07#$70#$00#$70#$70#$70#$07#$07#$70#$07#$00 +
  44.     #$70#$70#$70#$07#$07#$70#$70#$70#$0F#$07#$07#$0F#$70#$0F#$70#$07 +
  45.     #$0F#$0F#$07#$70#$07#$07#$70#$07#$07#$07#$70#$0F#$07#$07#$00#$00;
  46.  
  47.  
  48. { TBackground palette }
  49.  
  50.   CBackground = #1;
  51.  
  52. type
  53.  
  54. { TBackground object }
  55.  
  56.   PBackground = ^TBackground;
  57.   TBackground = object(TView)
  58.     Pattern: Char;
  59.     constructor Init(var Bounds: TRect; APattern: Char);
  60.     constructor Load(var S: TStream);
  61.     procedure Draw; virtual;
  62.     function GetPalette: PPalette; virtual;
  63.     procedure Store(var S: TStream);
  64.   end;
  65.  
  66. { TDeskTop object }
  67.  
  68.   PDeskTop = ^TDeskTop;
  69.   TDeskTop = object(TGroup)
  70.     Background: PBackground;
  71.     constructor Init(var Bounds: TRect);
  72.     procedure Cascade(var R: TRect);
  73.     procedure HandleEvent(var Event: TEvent); virtual;
  74.     procedure InitBackground; virtual;
  75.     procedure Tile(var R: TRect);
  76.     procedure TileError; virtual;
  77.   end;
  78.  
  79. { TProgram object }
  80.  
  81.   { Palette layout }
  82.   {     1 = TBackground }
  83.   {  2- 7 = TMenuView and TStatusLine }
  84.   {  8-15 = TWindow(Blue) }
  85.   { 16-23 = TWindow(Cyan) }
  86.   { 24-31 = TWindow(Gray) }
  87.   { 32-63 = TDialog }
  88.  
  89.   PProgram = ^TProgram;
  90.   TProgram = object(TGroup)
  91.     constructor Init;
  92.     destructor Done; virtual;
  93.     procedure GetEvent(var Event: TEvent); virtual;
  94.     function GetPalette: PPalette; virtual;
  95.     procedure HandleEvent(var Event: TEvent); virtual;
  96.     procedure Idle; virtual;
  97.     procedure InitDeskTop; virtual;
  98.     procedure InitMenuBar; virtual;
  99.     procedure InitScreen; virtual;
  100.     procedure InitStatusLine; virtual;
  101.     procedure OutOfMemory; virtual;
  102.     procedure PutEvent(var Event: TEvent); virtual;
  103.     procedure Run; virtual;
  104.     procedure SetScreenMode(Mode: Word);
  105.     function ValidView(P: PView): PView;
  106.   end;
  107.  
  108. { TApplication object }
  109.  
  110.   PApplication = ^TApplication;
  111.   TApplication = object(TProgram)
  112.     constructor Init;
  113.     destructor Done; virtual;
  114.   end;
  115.  
  116. { App registration procedure }
  117.  
  118. procedure RegisterApp;
  119.  
  120. const
  121.  
  122. { Public variables }
  123.  
  124.   Application: PProgram = nil;
  125.   DeskTop: PDeskTop = nil;
  126.   StatusLine: PStatusLine = nil;
  127.   MenuBar: PMenuView = nil;
  128.   AppPalette: Integer = apColor;
  129.  
  130. { Stream registration records }
  131.  
  132.   RBackground: TStreamRec = (
  133.     ObjType: 30;
  134.     VmtLink: Ofs(TypeOf(TBackground)^);
  135.     Load: @TBackground.Load;
  136.     Store: @TBackground.Store);
  137.  
  138.   RDeskTop: TStreamRec = (
  139.     ObjType: 31;
  140.     VmtLink: Ofs(TypeOf(TDeskTop)^);
  141.     Load: @TDeskTop.Load;
  142.     Store: @TDeskTop.Store);
  143.  
  144. implementation
  145.  
  146. const
  147.  
  148. { Private variables }
  149.  
  150.   Pending: TEvent = (What: evNothing);
  151.  
  152. { TBackground }
  153.  
  154. constructor TBackground.Init(var Bounds: TRect; APattern: Char);
  155. begin
  156.   TView.Init(Bounds);
  157.   GrowMode := gfGrowHiX + gfGrowHiY;
  158.   Pattern := APattern;
  159. end;
  160.  
  161. constructor TBackground.Load(var S: TStream);
  162. begin
  163.   TView.Load(S);
  164.   S.Read(Pattern, SizeOf(Pattern));
  165. end;
  166.  
  167. procedure TBackground.Draw;
  168. var
  169.   B: TDrawBuffer;
  170. begin
  171.   MoveChar(B, Pattern, GetColor($01), Size.X);
  172.   WriteLine(0, 0, Size.X, Size.Y, B);
  173. end;
  174.  
  175. function TBackground.GetPalette: PPalette;
  176. const
  177.   P: string[Length(CBackground)] = CBackground;
  178. begin
  179.   GetPalette := @P;
  180. end;
  181.  
  182. procedure TBackground.Store(var S: TStream);
  183. begin
  184.   TView.Store(S);
  185.   S.Write(Pattern, SizeOf(Pattern));
  186. end;
  187.  
  188. { TDeskTop object }
  189.  
  190. constructor TDeskTop.Init(var Bounds: TRect);
  191. begin
  192.   TGroup.Init(Bounds);
  193.   GrowMode := gfGrowHiX + gfGrowHiY;
  194.   InitBackground;
  195.   if Background <> nil then Insert(Background);
  196. end;
  197.  
  198. function Tileable(P: PView): Boolean;
  199. begin
  200.   Tileable := (P^.Options and ofTileable <> 0) and
  201.     (P^.State and sfVisible <> 0);
  202. end;
  203.  
  204. procedure TDeskTop.Cascade(var R: TRect);
  205. var
  206.   CascadeNum: Integer;
  207.   LastView: PView;
  208.   Min, Max: TPoint;
  209.  
  210.  
  211. procedure DoCount(P: PView); far;
  212. begin
  213.   if Tileable(P) then
  214.   begin
  215.     Inc(CascadeNum);
  216.     LastView := P;
  217.   end;
  218. end;
  219.  
  220. procedure DoCascade(P: PView); far;
  221. var
  222.   NR: TRect;
  223. begin
  224.   if Tileable(P) and (CascadeNum >= 0) then
  225.   begin
  226.     NR.Copy(R);
  227.     Inc(NR.A.X, CascadeNum); Inc(NR.A.Y, CascadeNum);
  228.     P^.Locate(NR);
  229.     Dec(CascadeNum);
  230.   end;
  231. end;
  232.  
  233. begin
  234.   CascadeNum := 0;
  235.   ForEach(@DoCount);
  236.   if CascadeNum > 0 then
  237.   begin
  238.     LastView^.SizeLimits(Min, Max);
  239.     if (Min.X > R.B.X - R.A.X - CascadeNum) or
  240.        (Min.Y > R.B.Y - R.A.Y - CascadeNum) then TileError
  241.     else
  242.     begin
  243.       Dec(CascadeNum);
  244.       Lock;
  245.       ForEach(@DoCascade);
  246.       Unlock;
  247.     end;
  248.   end;
  249. end;
  250.  
  251. procedure TDeskTop.HandleEvent(var Event: TEvent);
  252. begin
  253.   TGroup.HandleEvent(Event);
  254.   if Event.What = evCommand then
  255.   begin
  256.     case Event.Command of
  257.       cmNext: SelectNext(False);
  258.       cmPrev: Current^.PutInFrontOf(Background);
  259.     else
  260.       Exit;
  261.     end;
  262.     ClearEvent(Event);
  263.   end;
  264. end;
  265.  
  266. procedure TDeskTop.InitBackground;
  267. var
  268.   R: TRect;
  269. begin
  270.   GetExtent(R);
  271.   New(Background, Init(R, #176));
  272. end;
  273.  
  274. function ISqr(X: Integer): Integer; assembler;
  275. asm
  276.     MOV    CX,X
  277.         MOV    BX,0
  278. @@1:    INC     BX
  279.     MOV    AX,BX
  280.     IMUL    AX
  281.         CMP    AX,CX
  282.         JLE    @@1
  283.     MOV    AX,BX
  284.         DEC     AX
  285. end;
  286.  
  287. procedure MostEqualDivisors(N: Integer; var X, Y: Integer);
  288. var
  289.   I: Integer;
  290. begin
  291.   I := ISqr(N);
  292.   if ((N mod I) <> 0) then
  293.     if (N mod (I+1)) = 0 then Inc(I);
  294.   if I < (N div I) then I := N div I;
  295.   X := N div I;
  296.   Y := I;
  297. end;
  298.  
  299. procedure TDeskTop.Tile(var R: TRect);
  300. var
  301.   NumCols, NumRows, NumTileable, LeftOver, TileNum: Integer;
  302.  
  303. procedure DoCountTileable(P: PView); far;
  304. begin
  305.   if Tileable(P) then Inc(NumTileable);
  306. end;
  307.  
  308. function DividerLoc(Lo, Hi, Num, Pos: Integer): Integer;
  309. begin
  310.   DividerLoc := LongDiv(LongMul(Hi - Lo, Pos), Num) + Lo;
  311. end;
  312.  
  313. procedure CalcTileRect(Pos: Integer; var NR: TRect);
  314. var
  315.   X,Y,D: Integer;
  316. begin
  317.   D := (NumCols - LeftOver) * NumRows;
  318.   if Pos < D then
  319.   begin
  320.     X := Pos div NumRows;
  321.     Y := Pos mod NumRows;
  322.   end else
  323.   begin
  324.     X := (Pos - D) div (NumRows + 1) + (NumCols - LeftOver);
  325.     Y := (Pos - D) mod (NumRows + 1);
  326.   end;
  327.   NR.A.X := DividerLoc(R.A.X, R.B.X, NumCols, X);
  328.   NR.B.X := DividerLoc(R.A.X, R.B.X, NumCols, X+1);
  329.   if Pos >= D then
  330.   begin
  331.     NR.A.Y := DividerLoc(R.A.Y, R.B.Y, NumRows+1, Y);
  332.     NR.B.Y := DividerLoc(R.A.Y, R.B.Y, NumRows+1, Y+1);
  333.   end else
  334.   begin
  335.     NR.A.Y := DividerLoc(R.A.Y, R.B.Y, NumRows, Y);
  336.     NR.B.Y := DividerLoc(R.A.Y, R.B.Y, NumRows, Y+1);
  337.   end;
  338. end;
  339.  
  340. procedure DoTile(P: PView); far;
  341. var
  342.   R: TRect;
  343. begin
  344.   if Tileable(P) then
  345.   begin
  346.     CalcTileRect(TileNum, R);
  347.     P^.Locate(R);
  348.     Dec(TileNum);
  349.   end;
  350. end;
  351.  
  352. begin
  353.   NumTileable := 0;
  354.   ForEach(@DoCountTileable);
  355.   if NumTileable > 0 then
  356.   begin
  357.     MostEqualDivisors(NumTileable, NumCols, NumRows);
  358.     if ((R.B.X - R.A.X) div NumCols = 0) or
  359.        ((R.B.Y - R.A.Y) div NumRows = 0) then TileError
  360.     else
  361.     begin
  362.       LeftOver := NumTileable mod NumCols;
  363.       TileNum := NumTileable-1;
  364.       Lock;
  365.       ForEach(@DoTile);
  366.       Unlock;
  367.     end;
  368.   end;
  369. end;
  370.  
  371. procedure TDesktop.TileError;
  372. begin
  373. end;
  374.  
  375. { TProgram }
  376.  
  377. constructor TProgram.Init;
  378. var
  379.   R: TRect;
  380. begin
  381.   Application := @Self;
  382.   InitScreen;
  383.   R.Assign(0, 0, ScreenWidth, ScreenHeight);
  384.   TGroup.Init(R);
  385.   State := sfVisible + sfSelected + sfFocused + sfModal + sfExposed;
  386.   Options := 0;
  387.   Buffer := ScreenBuffer;
  388.   InitDeskTop;
  389.   InitStatusLine;
  390.   InitMenuBar;
  391.   if DeskTop <> nil then Insert(DeskTop);
  392.   if StatusLine <> nil then Insert(StatusLine);
  393.   if MenuBar <> nil then Insert(MenuBar);
  394. end;
  395.  
  396. destructor TProgram.Done;
  397. begin
  398.   if DeskTop <> nil then Dispose(DeskTop, Done);
  399.   if MenuBar <> nil then Dispose(MenuBar, Done);
  400.   if StatusLine <> nil then Dispose(StatusLine, Done);
  401.   Application := nil;
  402. end;
  403.  
  404. procedure TProgram.GetEvent(var Event: TEvent);
  405. var
  406.   R: TRect;
  407.  
  408. function ContainsMouse(P: PView): Boolean; far;
  409. begin
  410.   ContainsMouse := (P^.State and sfVisible <> 0) and
  411.     P^.MouseInView(Event.Where);
  412. end;
  413.  
  414. begin
  415.   if Pending.What <> evNothing then
  416.   begin
  417.     Event := Pending;
  418.     Pending.What := evNothing;
  419.   end else
  420.   begin
  421.     GetMouseEvent(Event);
  422.     if Event.What = evNothing then
  423.     begin
  424.       GetKeyEvent(Event);
  425.       if Event.What = evNothing then Idle;
  426.     end;
  427.   end;
  428.   if StatusLine <> nil then
  429.     if (Event.What and evKeyDown <> 0) or
  430.       (Event.What and evMouseDown <> 0) and
  431.       (FirstThat(@ContainsMouse) = PView(StatusLine)) then
  432.       StatusLine^.HandleEvent(Event);
  433. end;
  434.  
  435. function TProgram.GetPalette: PPalette;
  436. const
  437.   P: array[apColor..apMonochrome] of string[Length(CColor)] =
  438.     (CColor, CBlackWhite, CMonochrome);
  439. begin
  440.   GetPalette := @P[AppPalette];
  441. end;
  442.  
  443. procedure TProgram.HandleEvent(var Event: TEvent);
  444. var
  445.   I: Word;
  446.   C: Char;
  447. begin
  448.   if Event.What = evKeyDown then
  449.   begin
  450.     C := GetAltChar(Event.KeyCode);
  451.     if (C >= '1') and (C <= '9') then
  452.       if Message(DeskTop, evBroadCast, cmSelectWindowNum,
  453.         Pointer(Byte(C) - $30)) <> nil then ClearEvent(Event);
  454.   end;
  455.   TGroup.HandleEvent(Event);
  456.   if Event.What = evCommand then
  457.     if Event.Command = cmQuit then
  458.     begin
  459.       EndModal(cmQuit);
  460.       ClearEvent(Event);
  461.     end;
  462. end;
  463.  
  464. procedure TProgram.Idle;
  465. begin
  466.   if StatusLine <> nil then StatusLine^.Update;
  467.   if CommandSetChanged then
  468.   begin
  469.     Message(@Self, evBroadcast, cmCommandSetChanged, nil);
  470.     CommandSetChanged := False;
  471.   end;
  472. end;
  473.  
  474. procedure TProgram.InitDeskTop;
  475. var
  476.   R: TRect;
  477. begin
  478.   GetExtent(R);
  479.   Inc(R.A.Y);
  480.   Dec(R.B.Y);
  481.   New(DeskTop, Init(R));
  482. end;
  483.  
  484. procedure TProgram.InitMenuBar;
  485. var
  486.   R: TRect;
  487. begin
  488.   GetExtent(R);
  489.   R.B.Y := R.A.Y + 1;
  490.   MenuBar := New(PMenuBar, Init(R, nil));
  491. end;
  492.  
  493. procedure TProgram.InitScreen;
  494. begin
  495.   if Lo(ScreenMode) <> smMono then
  496.   begin
  497.     if ScreenMode and smFont8x8 <> 0 then
  498.       ShadowSize.X := 1 else
  499.       ShadowSize.X := 2;
  500.     ShadowSize.Y := 1;
  501.     ShowMarkers := False;
  502.     if Lo(ScreenMode) = smBW80 then
  503.       AppPalette := apBlackWhite else
  504.       AppPalette := apColor;
  505.   end else
  506.   begin
  507.     ShadowSize.X := 0;
  508.     ShadowSize.Y := 0;
  509.     ShowMarkers := True;
  510.     AppPalette := apMonochrome;
  511.   end;
  512. end;
  513.  
  514. procedure TProgram.InitStatusLine;
  515. var
  516.   R: TRect;
  517. begin
  518.   GetExtent(R);
  519.   R.A.Y := R.B.Y - 1;
  520.   New(StatusLine, Init(R,
  521.     NewStatusDef(0, $FFFF,
  522.       NewStatusKey('~Alt-X~ Exit', kbAltX, cmQuit,
  523.       NewStatusKey('', kbF10, cmMenu,
  524.       NewStatusKey('', kbAltF3, cmClose,
  525.       NewStatusKey('', kbF5, cmZoom,
  526.       NewStatusKey('', kbCtrlF5, cmResize,
  527.       NewStatusKey('', kbF6, cmNext, nil)))))), nil)));
  528. end;
  529.  
  530. procedure TProgram.OutOfMemory;
  531. begin
  532. end;
  533.  
  534. procedure TProgram.PutEvent(var Event: TEvent);
  535. begin
  536.   Pending := Event;
  537. end;
  538.  
  539. procedure TProgram.Run;
  540. begin
  541.   Execute;
  542. end;
  543.  
  544. procedure TProgram.SetScreenMode(Mode: Word);
  545. var
  546.   R: TRect;
  547. begin
  548.   HideMouse;
  549.   SetVideoMode(Mode);
  550.   DoneMemory;
  551.   InitScreen;
  552.   Buffer := ScreenBuffer;
  553.   R.Assign(0, 0, ScreenWidth, ScreenHeight);
  554.   ChangeBounds(R);
  555.   ShowMouse;
  556. end;
  557.  
  558. function TProgram.ValidView(P: PView): PView;
  559. begin
  560.   ValidView := nil;
  561.   if P <> nil then
  562.   begin
  563.     if LowMemory then
  564.     begin
  565.       Dispose(P, Done);
  566.       OutOfMemory;
  567.       Exit;
  568.     end;
  569.     if not P^.Valid(cmValid) then
  570.     begin
  571.       Dispose(P, Done);
  572.       Exit;
  573.     end;
  574.     ValidView := P;
  575.   end;
  576. end;
  577.  
  578. { TApplication }
  579.  
  580. constructor TApplication.Init;
  581. begin
  582.   InitMemory;
  583.   InitVideo;
  584.   InitEvents;
  585.   InitSysError;
  586.   InitHistory;
  587.   TProgram.Init;
  588. end;
  589.  
  590. destructor TApplication.Done;
  591. begin
  592.   TProgram.Done;
  593.   DoneHistory;
  594.   DoneSysError;
  595.   DoneEvents;
  596.   DoneVideo;
  597.   DoneMemory;
  598. end;
  599.  
  600. { App registration procedure }
  601.  
  602. procedure RegisterApp;
  603. begin
  604.   RegisterType(RBackground);
  605.   RegisterType(RDeskTop);
  606. end;
  607.  
  608. end.
  609.