home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / PASCAL / OPBONUS.ZIP / FBROWSE.LZH / FBROWSE.IN1 < prev    next >
Encoding:
Text File  |  1990-09-20  |  14.3 KB  |  474 lines

  1. {*********************************************************}
  2. {*                   FBROWSE.IN1 5.06                    *}
  3. {*       Copyright (c) TurboPower Software 1990.         *}
  4. {*                 All rights reserved.                  *}
  5. {*********************************************************}
  6.  
  7. {$IFDEF UseMouse}
  8.   procedure FBrowser.fbGotoRelPos(P : LongInt);
  9.     {-Move cursor to relative position P}
  10.   var
  11.     KeyStr : IsamKeyStr;
  12.     Ref    : LongInt;
  13.   begin
  14.     {find corresponding key and record number--use single-user routine: page
  15.     stack should be valid and we need the speed}
  16.     GetApprKeyAndRef(fbIFB, fbKeyNum, P, ScaleHigh, KeyStr, Ref);
  17.     if not IsamOK then
  18.       Exit;
  19.  
  20.     {move to the specified record}
  21.     SetCurrentRecord(KeyStr, Ref);
  22.   end;
  23.  
  24.   function FBrowser.fbProcessMouseCommand : Boolean;
  25.     {-Process ccMouseSel command. Returns True to return control to user.}
  26.   var
  27.     L : LongInt;
  28.     I : Word;
  29.     FramePos : FramePosType;
  30.     Row, Item, HotCode : Byte;
  31.   begin
  32.     fbProcessMouseCommand := False;
  33.  
  34.     {determine position of mouse}
  35.     EvaluateMousePos;
  36.     L := PosResults(FramePos, HotCode);
  37.  
  38.     case HotCode of
  39.       hsNone :           {not a hot spot}
  40.         case FramePos of
  41.           frInsideActive :       {inside window}
  42.             begin
  43.               {calculate item that cursor is on}
  44.               Row := MouseKeyWordY+MouseYLo-Pred(wYL);
  45.               Item := Succ(Pred(Row) div fbRowsPerItem);
  46.  
  47.               {is highlight already on current item?}
  48.               if Item = fbCurItem then begin
  49.                 {select the current item}
  50.                 if cwCmd = ccMouseSel then begin   {!!.06}
  51.                   cwCmd := ccSelect;
  52.                   fbProcessMouseCommand := True;
  53.                 end;                               {!!.06}
  54.               end
  55.               else
  56.                 {move cursor to the new item}
  57.                 fbGotoItem(Item);
  58.             end;
  59.           frTL..frRR,            {on the frame}
  60.           frInsideFrame,         {inside window frame but not in window boundaries}
  61.           frOutsideFrame :       {outside window frame}
  62.             fbProcessMouseCommand := LongFlagIsSet(wFlags, wAllMouseEvents);
  63.         end;
  64.       {$IFDEF UseScrollBars}
  65.       hsDecV :           {the decrement fixture of a vertical scroll bar}
  66.         if FlagIsSet(fbOptions, fbMousePage) then
  67.           fbPageUp
  68.         else
  69.           fbLineUp;
  70.       hsDecH :           {the decrement fixture of a horizontal scroll bar}
  71.         fbScrollHoriz(-fbBDelta);
  72.       hsIncV :           {the increment fixture of a vertical scroll bar}
  73.         if FlagIsSet(fbOptions, fbMousePage) then
  74.           fbPageDown
  75.         else
  76.           fbLineDown;
  77.       hsIncH :           {the increment fixture of a horizontal scroll bar}
  78.         fbScrollHoriz(fbBDelta);
  79.       hsBar :            {the slider portion of a scroll bar}
  80.         case FramePos of
  81.           frLL, frRR :   {vertical scroll bar}
  82.             begin
  83.               L := TweakSlider(FramePos, MouseKeyWordY+MouseYLo, L, 1);
  84.               if L <= 1 then
  85.                 {goto top of file}
  86.                 fbFirstRec
  87.               else if L >= ScaleHigh then
  88.                 {go to end of file}
  89.                 fbLastRec
  90.               else
  91.                 {go to specified position}
  92.                 fbGotoRelPos(L+fbScaleLow);
  93.             end;
  94.           else begin     {horizontal scroll bar}
  95.             I := TweakSlider(FramePos, MouseKeyWordX+MouseXLo, L, 1);
  96.             if I <> fbColOfs then begin
  97.               fbColOfs := I;
  98.               UpdateContents;
  99.             end;
  100.           end;
  101.         end;
  102.       {$ENDIF}
  103.       hsSpot,            {a single character hot spot}
  104.       hsRegion0..255 :   {a user-defined region relative to a frame}
  105.         fbProcessMouseCommand := True;
  106.     end;
  107.  
  108.   end;
  109. {$ENDIF}
  110.  
  111. {$IFDEF UseScrollBars}
  112.   function IsAll255(S : string) : Boolean;
  113.     {-Return True if S is all 255's}
  114.   inline(
  115.     $5F/                   {pop di         ;es:di => S}
  116.     $07/                   {pop es}
  117.     $31/$C9/               {xor cx,cx      ;cx = 0}
  118.     $31/$C0/               {xor ax,ax      ;ah = 1, al = 255}
  119.     $FE/$C4/               {inc ah}
  120.     $FE/$C8/               {dec al}
  121.     $26/$8A/$0D/           {mov cl,es:[di] ;cx = length(s)}
  122.     $47/                   {inc di         ;es:di => S[1]}
  123.     $FC/                   {cld            ;go forward}
  124.     $F3/$AE/               {repe scasb     ;scan while 0}
  125.     $74/$02/               {je done        ;True if still 0}
  126.     $FE/$CC/               {dec ah         ;False if not}
  127.                            {done:}
  128.     $88/$E0);              {mov al,ah      ;result into AL}
  129.  
  130.   procedure FBrowser.fbSetupForScrollBars;
  131.     {-Set boundaries for all scroll bars}
  132.   var
  133.     HorizH : Integer;
  134.     High : Word;
  135.     VertH, Ref : LongInt;
  136.     Key : IsamKeyStr;
  137.   begin
  138.     if not HasScrollBars then
  139.       Exit;
  140.  
  141.     if (fbScaleLow = $FFFF) then begin
  142.       {is there a subrange of keys?}
  143.       if (not LongFlagIsSet(fbOptions, fbAutoScale)) or
  144.          ((fbLowKey = '') and IsAll255(fbHighKey)) then begin
  145.         {if not, use 1..ScaleHigh}
  146.         fbScaleLow := 0;
  147.         High := ScaleHigh;
  148.       end
  149.       else begin
  150.         {get scaled value for low key}
  151.         Ref := 1;
  152.         Key := fbLowKey;
  153.         fbFindKey(Ref, Key, +1);
  154.         {use single-user routine: page stack should be valid and we need the
  155.          speed}
  156.         GetApprRelPos(fbIFB, fbKeyNum, fbScaleLow, ScaleHigh, Key, Ref);
  157.  
  158.         {get scaled value for high key}
  159.         Ref := MaxLongInt;
  160.         Key := fbHighKey;
  161.         fbFindKey(Ref, Key, -1);
  162.         {use single-user routine: page stack should be valid and we need the
  163.          speed}
  164.         GetApprRelPos(fbIFB, fbKeyNum, High, ScaleHigh, Key, Ref);
  165.       end;
  166.     end;
  167.  
  168.     {calculate high values}
  169.     HorizH := fbMaxCols-Width;
  170.     if HorizH < 0 then
  171.       HorizH := 0;
  172.     VertH := High-fbScaleLow;
  173.     if VertH < 0 then
  174.       VertH := 0;
  175.  
  176.     {reset scroll bar range}
  177.     ChangeAllScrollBars(0, HorizH, 0, VertH);
  178.   end;
  179.  
  180.   procedure FBrowser.fbUpdateScrollBars(DoVert : Boolean);
  181.     {-Update horizontal and vertical scroll bars}
  182.   var
  183.     RelPos : Word;
  184.   begin
  185.     if not HasScrollBars then
  186.       Exit;
  187.  
  188.     if fbScaleLow = $FFFF then
  189.       fbSetupForScrollBars;
  190.  
  191.     if DoVert then
  192.       {calculate relative position of current record--use single-user
  193.        routine: page stack should be valid and we need the speed}
  194.       GetApprRelPos(fbIFB, fbKeyNum, RelPos, ScaleHigh, fbCurKey, fbCurRef);
  195.  
  196.     if IsamOK then
  197.       DrawAllSliders(fbColOfs, RelPos-fbScaleLow);
  198.   end;
  199. {$ENDIF}
  200.  
  201. {$IFDEF UseAdjustableWindows}
  202.   procedure FBrowser.fbAdjustDisplay(NewH, OldH : Byte);
  203.     {-Adjust window display}
  204.   label
  205.     ExitPoint;
  206.   var
  207.     I, J, Delta : Integer;
  208.     Ref : LongInt;
  209.     Key : IsamKeyStr;
  210.   begin
  211.     {did window get bigger?}
  212.     if (NewH > OldH) then begin
  213.       {find the first row with no record}
  214.       J := 1;
  215.       while (J <= NewH) and (fbItemRecs^[J].irRef <> 0) do
  216.         Inc(J);
  217.  
  218.       {anything to do?}
  219.       if J > NewH then
  220.         Exit;
  221.  
  222.       {read-lock the file if desired}
  223.       fbReadLock(True);
  224.  
  225.       {locate last record we already have}
  226.       with fbItemRecs^[J-1] do begin
  227.         Ref := irRef;
  228.         Key := irKey;
  229.       end;
  230.       fbFindKey(Ref, Key, 0);
  231.       case IsamErrorClass of
  232.         0..1 : {ok};
  233.         2 : begin
  234.               GotError(epWarning+ecFileBlockLocked, emFileBlockLocked);
  235.               ClearErrors;
  236.               goto ExitPoint;
  237.             end;
  238.         else
  239.           GotError(epFatal+ecIsamError, emIsamError);
  240.           goto ExitPoint;
  241.       end;
  242.  
  243.       {find the next one}
  244.       fbNextKey(Ref, Key);
  245.       if IsamErrorClass > 0 then
  246.         goto ExitPoint;
  247.  
  248.       while (J <= NewH) and fbKeyInBounds(Key) and (IsamErrorClass = 0) do begin
  249.         with fbItemRecs^[J] do begin
  250.           irKey := Key;
  251.           irRef := Ref;
  252.           BuildOneItem(J, False);
  253.         end;
  254.         Inc(J);
  255.         if (J <= NewH) and (IsamErrorClass = 0) then begin
  256.           fbNextKey(Ref, Key);
  257.           if IsamErrorClass > 1 then begin
  258.             GotError(epFatal+ecIsamError, emIsamError);
  259.             goto ExitPoint;
  260.           end;
  261.         end;
  262.       end;
  263.  
  264. ExitPoint:
  265.       {release read-lock}
  266.       fbReadLock(False);
  267.     end
  268.     {it's smaller--is current row still visible?}
  269.     else if (fbCurItem > NewH) then begin
  270.       {scroll current row back into view}
  271.       Delta := NewH-fbCurItem;
  272.       fbScrollItemRecs(Delta, OldH);
  273.  
  274.       {reset current row}
  275.       fbCurItem := NewH;
  276.  
  277.       {empty all the rows that are wiped out}
  278.       for I := NewH+1 to fbMaxItems do
  279.         fbEmptyItemRec(I);
  280.     end;
  281.   end;
  282. {$ENDIF}
  283.  
  284.  
  285.  
  286. {$IFDEF UseStreams}
  287.   {-------- streams ----------}
  288.  
  289.   constructor FBrowser.Load(var S : IdStream);
  290.     {-Load a file browser from a stream}
  291.   var
  292.     I, J, M, N : Word;
  293.   begin
  294.     {initialize this in case Done is called}
  295.     fbItemRecs := nil;
  296.  
  297.     {Load the underlying command window}
  298.     if not CommandWindow.Load(S) then
  299.       Fail;
  300.  
  301.     {set the command processor if necessary}
  302.     if cwCmdPtr = nil then
  303.       SetCommandProcessor(FBrowserCommands);
  304.  
  305.     {read data specific to the browser}
  306.     @fbPreMove := S.ReadPointer;
  307.     @fbTask := S.ReadPointer;
  308.     @fbBuildItem := S.ReadPointer;
  309.     @fbUpdate := S.ReadPointer;
  310.     @fbFilter := S.ReadPointer;
  311.     @fbRefresh := S.ReadPointer;
  312.     fbIFB := S.ReadPointer;
  313.     fbDatPtr := S.ReadPointer;
  314.     S.ReadRange(fbKeyNum, fbItemRecs);
  315.     S.ReadRange(fbMaxItems, fbDummy);
  316.  
  317.     {check the error status}
  318.     if S.PeekStatus <> 0 then begin
  319.       Done;
  320.       Fail;
  321.     end;
  322.  
  323.     {allocate the row records array}
  324.     M := Word(fbMaxItems)*SizeOf(ItemRec);
  325.     if not GetMemCheck(fbItemRecs, M) then begin
  326.       InitStatus := epFatal+ecOutOfMemory;
  327.       Done;
  328.       Fail;
  329.     end;
  330.  
  331.     {initialize the array}
  332.     FillChar(fbItemRecs^, M, 0);
  333.  
  334.     {allocate the string pointers}
  335.     M := Word(fbMaxCols)+1;
  336.     N := fbRowsPerItem*SizeOf(Pointer);
  337.     for I := 1 to fbMaxItems do
  338.       with fbItemRecs^[I] do begin
  339.         if not GetMemCheck(irRows, N) then begin
  340.           InitStatus := epFatal+ecOutOfMemory;
  341.           Done;
  342.           Fail;
  343.         end
  344.         else begin
  345.           FillChar(irRows^, N, 0);
  346.           for J := 1 to fbRowsPerItem do
  347.             if GetMemCheck(irRows^[J], M) then
  348.               {initialize the string}
  349.               FillChar(irRows^[J]^, M, 0)
  350.             else begin
  351.               InitStatus := epFatal+ecOutOfMemory;
  352.               Done;
  353.               Fail;
  354.             end;
  355.         end;
  356.       end;
  357.  
  358.     {force a complete screen update}
  359.     SetLongFlag(fbOptions, fbForceUpdate);
  360.  
  361.     {make sure fbIsNet flag is set properly}
  362.     if IsNetFileBlock(fbIFB) then
  363.       SetLongFlag(fbOptions, fbIsNet)
  364.     else
  365.       ClearLongFlag(fbOptions, fbIsNet);
  366.   end;
  367.  
  368.   procedure FBrowser.Store(var S : IdStream);
  369.     {-Store a file browser in a stream}
  370.   begin
  371.     {Store the underlying command window}
  372.     CommandWindow.Store(S);
  373.     if S.PeekStatus <> 0 then
  374.       Exit;
  375.  
  376.     {store FBrowser data fields}
  377.     S.WriteUserPointer(@fbPreMove,   ptNil);
  378.     S.WriteUserPointer(@fbTask,      ptNil);
  379.     S.WriteUserPointer(@fbBuildItem, ptNil);
  380.     S.WriteUserPointer(@fbUpdate,    ptNil);
  381.     S.WriteUserPointer(@fbFilter,    ptNullFilterFunc);
  382.     S.WriteUserPointer(@fbRefresh,   ptNullRefreshFunc);
  383.     S.WritePointer(fbIFB);
  384.     S.WritePointer(fbDatPtr);
  385.     S.WriteRange(fbKeyNum, fbItemRecs);
  386.     S.WriteRange(fbMaxItems, fbDummy);
  387.   end;
  388.  
  389.   procedure FBrowserStream(SPtr : IdStreamPtr);
  390.     {-Register all types needed for streams containing file browsers}
  391.   begin
  392.     {register the command window}
  393.     CommandWindowStream(SPtr);
  394.  
  395.     {register the browser}
  396.     with SPtr^ do begin
  397.       RegisterType(otFBrowser, veFBrowser, TypeOf(FBrowser),
  398.                    @FBrowser.Store, @FBrowser.Load);
  399.       RegisterPointer(ptFBrowserCommands, @FBrowserCommands);
  400.  
  401.       {register default procedure pointers}
  402.       RegisterPointer(ptNullFilterFunc, @NullFilterFunc);
  403.       RegisterPointer(ptNullRefreshFunc, @NullRefreshFunc);
  404.     end;
  405.   end;
  406.  
  407.   procedure VBrowserStream(SPtr : IdStreamPtr);
  408.     {-Register all types needed for streams containing file browsers}
  409.   begin
  410.     {register the parent}
  411.     FBrowserStream(SPtr);
  412.  
  413.     {register the browser}
  414.     with SPtr^ do
  415.       RegisterType(otVBrowser, veVBrowser, TypeOf(VBrowser),
  416.                    @VBrowser.Store, @VBrowser.Load);
  417.   end;
  418.  
  419. {$ENDIF}
  420.  
  421.   function NullFilterFunc(RecNum : LongInt; Key : IsamKeyStr;
  422.                           FBP : FBrowserPtr) : Boolean;
  423.     {-Do-nothing record filtering function}
  424.   begin
  425.     NullFilterFunc := True;
  426.   end;
  427.  
  428.   function NullRefreshFunc(FBP : FBrowserPtr) : Boolean;
  429.     {-Do-nothing refresh function}
  430.   begin
  431.     NullRefreshFunc := False;
  432.   end;
  433.  
  434.   function RefreshAtEachCommand(FBP : FBrowserPtr) : Boolean;
  435.     {-Check for need to refresh before each command if no keystrokes pending}
  436.   begin
  437.     with FBP^, cwCmdPtr^ do
  438.       if LongFlagIsSet(fbOptions, fbIsNet) or cpKeyPressed then
  439.         RefreshAtEachCommand := False
  440.       else
  441.         RefreshAtEachCommand := PageStackValid(fbIFB, fbKeyNum) = StateInvalid;
  442.   end;
  443.  
  444.   function RefreshPeriodically(FBP : FBrowserPtr) : Boolean;
  445.     {-Check for need to refresh every RefreshPeriod clock ticks}
  446.   var
  447.     Ticks : LongInt absolute $40:$6C;
  448.     T : LongInt;
  449.   begin
  450.     {assume false}
  451.     RefreshPeriodically := False;
  452.  
  453.     with FBP^ do
  454.       {do nothing if this is a single-user fileblock}
  455.       if LongFlagIsSet(fbOptions, fbIsNet) then begin
  456.         {save tick count}
  457.         T := Ticks;
  458.  
  459.         {loop while key not pressed}
  460.         while not cwCmdPtr^.cpKeyPressed do
  461.           {is it time to check again?}
  462.           if (Ticks-T) >= RefreshPeriod then
  463.             {check to see if page stack has been invalidated}
  464.             if PageStackValid(fbIFB, fbKeyNum) = StateInvalid then begin
  465.               {we need to refresh the display}
  466.               RefreshPeriodically := True;
  467.               Exit;
  468.             end
  469.             else
  470.               {save the current tick count}
  471.               T := Ticks;
  472.       end;
  473.   end;
  474.