scroll.pas 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  1. {
  2. This file is part of the Free Pascal run time library.
  3. Copyright (c) 2000 by B'rczi, Gÿbor
  4. member of the Free Pascal development team
  5. Support objects for the install program
  6. See the file COPYING.FPC, included in this distribution,
  7. for details about the copyright.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  11. **********************************************************************}
  12. unit Scroll;
  13. interface
  14. uses Objects,
  15. FVConsts,
  16. Drivers,Views,App;
  17. const
  18. CScrollBoxBackground = #6;
  19. type
  20. PScrollBoxBackground = ^TScrollBoxBackground;
  21. TScrollBoxBackground = object(TBackground)
  22. function GetPalette: PPalette; virtual;
  23. end;
  24. PScrollBox = ^TScrollBox;
  25. TScrollBox = object(TGroup)
  26. Delta,Limit: TPoint;
  27. HScrollBar,VScrollBar: PScrollBar;
  28. Background: PScrollBoxBackground;
  29. constructor Init(var Bounds: TRect; AHScrollBar, AVScrollBar: PScrollBar);
  30. procedure InitBackground; virtual;
  31. procedure HandleEvent(var Event: TEvent); virtual;
  32. procedure ChangeBounds(var Bounds: TRect); virtual;
  33. procedure ScrollDraw; virtual;
  34. procedure ScrollTo(X, Y: Sw_Integer);
  35. procedure SetLimit(X, Y: Sw_Integer);
  36. procedure SetState(AState: Word; Enable: Boolean); virtual;
  37. procedure TrackCursor;
  38. procedure Draw; virtual;
  39. function ClipChilds: boolean; virtual;
  40. procedure BeforeInsert(P: PView); virtual;
  41. procedure AfterInsert(P: PView); virtual;
  42. procedure AfterDelete(P: PView); virtual;
  43. private
  44. DrawLock: Byte;
  45. DrawFlag: Boolean;
  46. procedure CheckDraw;
  47. procedure UpdateLimits;
  48. procedure ShiftViews(DX,DY: sw_integer);
  49. end;
  50. implementation
  51. function TScrollBoxBackground.GetPalette: PPalette;
  52. const P: string[length(CScrollBoxBackground)] = CScrollBoxBackground;
  53. begin
  54. GetPalette:=@P;
  55. end;
  56. constructor TScrollBox.Init(var Bounds: TRect; AHScrollBar, AVScrollBar: PScrollBar);
  57. begin
  58. inherited Init(Bounds);
  59. EventMask:=EventMask or evBroadcast;
  60. HScrollBar:=AHScrollBar; VScrollBar:=AVScrollBar;
  61. InitBackground;
  62. if Assigned(Background) then Insert(Background);
  63. ReDraw;
  64. end;
  65. procedure TScrollBox.InitBackground;
  66. var R: TRect;
  67. begin
  68. GetExtent(R);
  69. New(Background, Init(R,' '));
  70. end;
  71. procedure TScrollBox.HandleEvent(var Event: TEvent);
  72. begin
  73. if (Event.What=evBroadcast) and (Event.Command=cmCursorChanged) then
  74. TrackCursor;
  75. inherited HandleEvent(Event);
  76. end;
  77. procedure TScrollBox.ChangeBounds(var Bounds: TRect);
  78. begin
  79. SetBounds(Bounds);
  80. Inc(DrawLock);
  81. SetLimit(Limit.X, Limit.Y);
  82. Dec(DrawLock);
  83. DrawFlag := False;
  84. DrawView;
  85. end;
  86. procedure TScrollBox.CheckDraw;
  87. begin
  88. if (DrawLock = 0) and DrawFlag then
  89. begin
  90. DrawFlag := False;
  91. ReDraw; DrawView;
  92. end;
  93. end;
  94. procedure TScrollBox.ScrollDraw;
  95. var
  96. D: TPoint;
  97. begin
  98. if HScrollBar <> nil then
  99. D.X := HScrollBar^.Value
  100. else
  101. D.X := 0;
  102. if VScrollBar <> nil then
  103. D.Y := VScrollBar^.Value
  104. else
  105. D.Y := 0;
  106. if (D.X <> Delta.X) or (D.Y <> Delta.Y) then
  107. begin
  108. SetCursor(Cursor.X + Delta.X - D.X, Cursor.Y + Delta.Y - D.Y);
  109. Delta := D;
  110. if DrawLock <> 0 then
  111. DrawFlag := True
  112. else
  113. DrawView;
  114. end;
  115. end;
  116. procedure TScrollBox.ScrollTo(X, Y: Sw_Integer);
  117. var DX,DY: sw_integer;
  118. begin
  119. Inc(DrawLock);
  120. DX:=Delta.X-X;
  121. DY:=Delta.Y-Y;
  122. if HScrollBar <> nil then
  123. HScrollBar^.SetValue(X);
  124. if VScrollBar <> nil then
  125. VScrollBar^.SetValue(Y);
  126. ShiftViews(DX,DY);
  127. Dec(DrawLock);
  128. CheckDraw;
  129. end;
  130. procedure TScrollBox.ShiftViews(DX,DY: sw_integer);
  131. procedure DoShift(P: PView);
  132. begin
  133. P^.MoveTo(P^.Origin.X+DX,P^.Origin.Y+DY);
  134. end;
  135. begin
  136. ForEach(@DoShift);
  137. end;
  138. procedure TScrollBox.SetLimit(X, Y: Sw_Integer);
  139. begin
  140. Limit.X := X;
  141. Limit.Y := Y;
  142. Inc(DrawLock);
  143. if HScrollBar <> nil then
  144. HScrollBar^.SetParams(HScrollBar^.Value, 0, X - Size.X, Size.X - 1, HScrollBar^.ArStep);
  145. if VScrollBar <> nil then
  146. VScrollBar^.SetParams(VScrollBar^.Value, 0, Y - Size.Y, Size.Y - 1, VScrollBar^.ArStep);
  147. Dec(DrawLock);
  148. CheckDraw;
  149. end;
  150. procedure TScrollBox.SetState(AState: Word; Enable: Boolean);
  151. procedure ShowSBar(SBar: PScrollBar);
  152. begin
  153. if (SBar <> nil) then
  154. if GetState(sfActive + sfSelected) then
  155. SBar^.Show
  156. else
  157. SBar^.Hide;
  158. end;
  159. var OState: word;
  160. begin
  161. OState:=State;
  162. inherited SetState(AState, Enable);
  163. if AState and (sfActive + sfSelected) <> 0 then
  164. begin
  165. ShowSBar(HScrollBar);
  166. ShowSBar(VScrollBar);
  167. end;
  168. if ((OState xor State) and (sfFocused))<>0 then
  169. TrackCursor;
  170. end;
  171. procedure TScrollBox.TrackCursor;
  172. var V: PView;
  173. P,ND: TPoint;
  174. begin
  175. V:=Current;
  176. if (not Assigned(V)) then Exit;
  177. P.X:=V^.Origin.X+V^.Cursor.X;
  178. P.Y:=V^.Origin.Y+V^.Cursor.Y;
  179. ND:=Delta;
  180. if (P.X<0) then
  181. Dec(ND.X,-P.X)
  182. else
  183. if (P.X>=Size.X) then
  184. Inc(ND.X,P.X-(Size.X-1));
  185. if (P.Y<0) then
  186. Dec(ND.Y,-P.Y)
  187. else
  188. if (P.Y>=Size.Y) then
  189. Inc(ND.Y,P.Y-(Size.Y-1));
  190. if (ND.X<>Delta.X) or (ND.Y<>Delta.Y) then
  191. ScrollTo(ND.X,ND.Y);
  192. end;
  193. function TScrollBox.ClipChilds: boolean;
  194. begin
  195. ClipChilds:=false;
  196. end;
  197. procedure TScrollBox.BeforeInsert(P: PView);
  198. begin
  199. if Assigned(P) then
  200. P^.MoveTo(P^.Origin.X-Delta.X,P^.Origin.Y-Delta.Y);
  201. end;
  202. procedure TScrollBox.AfterInsert(P: PView);
  203. begin
  204. UpdateLimits;
  205. end;
  206. procedure TScrollBox.AfterDelete(P: PView);
  207. begin
  208. { UpdateLimits;
  209. removed because it creates GPF PM }
  210. end;
  211. procedure TScrollBox.Draw;
  212. begin
  213. inherited Draw;
  214. end;
  215. procedure TScrollBox.UpdateLimits;
  216. var Max: TPoint;
  217. procedure Check(P: PView);
  218. var O: TPoint;
  219. begin
  220. O.X:=P^.Origin.X+P^.Size.X+Delta.X;
  221. O.Y:=P^.Origin.Y+P^.Size.Y+Delta.Y;
  222. if O.X>Max.X then
  223. Max.X:=O.X;
  224. if O.Y>Max.Y then
  225. Max.Y:=O.Y;
  226. end;
  227. begin
  228. Max.X:=0; Max.Y:=0;
  229. ForEach(@Check);
  230. if (Max.X<>Limit.X) or (Max.Y<>Limit.Y) then
  231. SetLimit(Max.X,Max.Y);
  232. end;
  233. END.