NewNotebook.pas 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329
  1. unit NewNotebook;
  2. {
  3. Inno Setup
  4. Copyright (C) 1997-2018 Jordan Russell
  5. Portions by Martijn Laan
  6. For conditions of distribution and use, see LICENSE.TXT.
  7. TNewNotebook component
  8. }
  9. interface
  10. uses
  11. Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms;
  12. type
  13. TNewNotebookPage = class;
  14. TNewNotebook = class(TWinControl)
  15. private
  16. FActivePage: TNewNotebookPage;
  17. FPages: TList;
  18. function GetPage(Index: Integer): TNewNotebookPage;
  19. function GetPageCount: Integer;
  20. procedure InsertPage(Page: TNewNotebookPage);
  21. procedure RemovePage(Page: TNewNotebookPage);
  22. procedure SetActivePage(Page: TNewNotebookPage);
  23. protected
  24. procedure AlignControls(AControl: TControl; var Rect: TRect); override;
  25. procedure CreateParams(var Params: TCreateParams); override;
  26. procedure ShowControl(AControl: TControl); override;
  27. public
  28. constructor Create(AOwner: TComponent); override;
  29. destructor Destroy; override;
  30. function FindNextPage(CurPage: TNewNotebookPage; GoForward: Boolean): TNewNotebookPage;
  31. procedure GetChildren(Proc: TGetChildProc; Root: TComponent); override;
  32. property PageCount: Integer read GetPageCount;
  33. property Pages[Index: Integer]: TNewNotebookPage read GetPage;
  34. published
  35. property ActivePage: TNewNotebookPage read FActivePage write SetActivePage;
  36. property Align;
  37. property Anchors;
  38. property Color;
  39. property DragCursor;
  40. property DragMode;
  41. property Enabled;
  42. property Font;
  43. property ParentColor;
  44. property ParentFont;
  45. property ParentShowHint;
  46. property PopupMenu;
  47. property ShowHint;
  48. property TabOrder;
  49. property TabStop;
  50. property Visible;
  51. property OnDragDrop;
  52. property OnDragOver;
  53. property OnEndDrag;
  54. property OnEnter;
  55. property OnExit;
  56. property OnMouseDown;
  57. property OnMouseMove;
  58. property OnMouseUp;
  59. property OnStartDrag;
  60. end;
  61. TNewNotebookPage = class(TCustomControl)
  62. private
  63. FNotebook: TNewNotebook;
  64. function GetPageIndex: Integer;
  65. procedure SetNotebook(ANotebook: TNewNotebook);
  66. procedure SetPageIndex(Value: Integer);
  67. protected
  68. procedure Paint; override;
  69. procedure ReadState(Reader: TReader); override;
  70. public
  71. constructor Create(AOwner: TComponent); override;
  72. destructor Destroy; override;
  73. property Notebook: TNewNotebook read FNotebook write SetNotebook;
  74. published
  75. property Color nodefault; { nodefault needed for Color=clWindow to persist }
  76. property DragMode;
  77. property Enabled;
  78. property Font;
  79. property Height stored False;
  80. property Left stored False;
  81. property PageIndex: Integer read GetPageIndex write SetPageIndex stored False;
  82. property ParentColor;
  83. property ParentFont;
  84. property ParentShowHint;
  85. property PopupMenu;
  86. property ShowHint;
  87. property Top stored False;
  88. property Visible stored False;
  89. property Width stored False;
  90. property OnDragDrop;
  91. property OnDragOver;
  92. property OnEndDrag;
  93. property OnEnter;
  94. property OnExit;
  95. property OnMouseDown;
  96. property OnMouseMove;
  97. property OnMouseUp;
  98. property OnStartDrag;
  99. end;
  100. implementation
  101. uses
  102. Types;
  103. { TNewNotebookPage }
  104. constructor TNewNotebookPage.Create(AOwner: TComponent);
  105. begin
  106. inherited;
  107. Align := alClient;
  108. ControlStyle := ControlStyle + [csAcceptsControls, csNoDesignVisible];
  109. Visible := False;
  110. end;
  111. destructor TNewNotebookPage.Destroy;
  112. begin
  113. if Assigned(FNotebook) then
  114. FNotebook.RemovePage(Self);
  115. inherited;
  116. end;
  117. function TNewNotebookPage.GetPageIndex: Integer;
  118. begin
  119. if Assigned(FNotebook) then
  120. Result := FNotebook.FPages.IndexOf(Self)
  121. else
  122. Result := -1;
  123. end;
  124. procedure TNewNotebookPage.Paint;
  125. begin
  126. inherited;
  127. if csDesigning in ComponentState then begin
  128. Canvas.Pen.Style := psDash;
  129. Canvas.Brush.Style := bsClear;
  130. Canvas.Rectangle(0, 0, Width, Height);
  131. end;
  132. end;
  133. procedure TNewNotebookPage.ReadState(Reader: TReader);
  134. begin
  135. inherited;
  136. if Reader.Parent is TNewNotebook then
  137. Notebook := TNewNotebook(Reader.Parent);
  138. end;
  139. procedure TNewNotebookPage.SetNotebook(ANotebook: TNewNotebook);
  140. begin
  141. if FNotebook <> ANotebook then begin
  142. if Assigned(FNotebook) then
  143. FNotebook.RemovePage(Self);
  144. Parent := ANotebook;
  145. if Assigned(ANotebook) then
  146. ANotebook.InsertPage(Self);
  147. end;
  148. end;
  149. procedure TNewNotebookPage.SetPageIndex(Value: Integer);
  150. begin
  151. if Assigned(FNotebook) then begin
  152. if Value >= FNotebook.FPages.Count then
  153. Value := FNotebook.FPages.Count-1;
  154. if Value < 0 then
  155. Value := 0;
  156. FNotebook.FPages.Move(PageIndex, Value);
  157. end;
  158. end;
  159. { TNewNotebook }
  160. constructor TNewNotebook.Create(AOwner: TComponent);
  161. begin
  162. inherited;
  163. Width := 150;
  164. Height := 150;
  165. FPages := TList.Create;
  166. end;
  167. destructor TNewNotebook.Destroy;
  168. var
  169. I: Integer;
  170. begin
  171. if Assigned(FPages) then begin
  172. for I := 0 to FPages.Count-1 do
  173. TNewNotebookPage(FPages[I]).FNotebook := nil;
  174. FPages.Free;
  175. end;
  176. inherited;
  177. end;
  178. procedure TNewNotebook.AlignControls(AControl: TControl; var Rect: TRect);
  179. var
  180. I: Integer;
  181. Ctl: TControl;
  182. begin
  183. inherited;
  184. { The default AlignControls implementation in Delphi 2 and 3 doesn't set
  185. the size of invisible controls. Pages that aren't currently visible must
  186. have valid sizes for BidiUtils' FlipControls to work properly.
  187. Note: We loop through Controls and not FPages here because
  188. TNewNotebookPage.SetNotebook sets Parent (causing AlignControls to be
  189. called) before it calls InsertPage. }
  190. if not IsRectEmpty(Rect) then begin
  191. for I := 0 to ControlCount-1 do begin
  192. Ctl := Controls[I];
  193. if (Ctl is TNewNotebookPage) and not Ctl.Visible then
  194. Ctl.BoundsRect := Rect;
  195. end;
  196. end;
  197. end;
  198. procedure TNewNotebook.CreateParams(var Params: TCreateParams);
  199. begin
  200. inherited;
  201. Params.Style := Params.Style or WS_CLIPCHILDREN;
  202. end;
  203. function TNewNotebook.FindNextPage(CurPage: TNewNotebookPage;
  204. GoForward: Boolean): TNewNotebookPage;
  205. var
  206. I, StartIndex: Integer;
  207. begin
  208. if FPages.Count > 0 then begin
  209. StartIndex := FPages.IndexOf(CurPage);
  210. if StartIndex = -1 then begin
  211. if GoForward then
  212. StartIndex := FPages.Count-1
  213. else
  214. StartIndex := 0;
  215. end;
  216. I := StartIndex;
  217. repeat
  218. if GoForward then begin
  219. Inc(I);
  220. if I = FPages.Count then
  221. I := 0;
  222. end
  223. else begin
  224. if I = 0 then
  225. I := FPages.Count;
  226. Dec(I);
  227. end;
  228. Result := FPages[I];
  229. Exit;
  230. until I = StartIndex;
  231. end;
  232. Result := nil;
  233. end;
  234. procedure TNewNotebook.GetChildren(Proc: TGetChildProc {$IFNDEF DELPHI2} ;
  235. Root: TComponent {$ENDIF});
  236. var
  237. I: Integer;
  238. begin
  239. for I := 0 to FPages.Count-1 do
  240. Proc(TNewNotebookPage(FPages[I]));
  241. end;
  242. function TNewNotebook.GetPage(Index: Integer): TNewNotebookPage;
  243. begin
  244. Result := FPages[Index];
  245. end;
  246. function TNewNotebook.GetPageCount: Integer;
  247. begin
  248. Result := FPages.Count;
  249. end;
  250. procedure TNewNotebook.InsertPage(Page: TNewNotebookPage);
  251. begin
  252. FPages.Add(Page);
  253. Page.FNotebook := Self;
  254. end;
  255. procedure TNewNotebook.RemovePage(Page: TNewNotebookPage);
  256. begin
  257. Page.FNotebook := nil;
  258. FPages.Remove(Page);
  259. if FActivePage = Page then
  260. SetActivePage(nil);
  261. end;
  262. procedure TNewNotebook.ShowControl(AControl: TControl);
  263. begin
  264. if (AControl is TNewNotebookPage) and (TNewNotebookPage(AControl).FNotebook = Self) then
  265. SetActivePage(TNewNotebookPage(AControl));
  266. inherited;
  267. end;
  268. procedure TNewNotebook.SetActivePage(Page: TNewNotebookPage);
  269. var
  270. ParentForm: {$IFDEF DELPHI2} TForm {$ELSE} TCustomForm {$ENDIF};
  271. begin
  272. if Assigned(Page) and (Page.FNotebook <> Self) then
  273. Exit;
  274. if FActivePage <> Page then begin
  275. ParentForm := GetParentForm(Self);
  276. if Assigned(ParentForm) and Assigned(FActivePage) and
  277. FActivePage.ContainsControl(ParentForm.ActiveControl) then
  278. ParentForm.ActiveControl := FActivePage;
  279. if Assigned(Page) then begin
  280. Page.BringToFront;
  281. Page.Visible := True;
  282. if Assigned(ParentForm) and Assigned(FActivePage) and
  283. (ParentForm.ActiveControl = FActivePage) then begin
  284. if Page.CanFocus then
  285. ParentForm.ActiveControl := Page
  286. else
  287. ParentForm.ActiveControl := Self;
  288. end;
  289. end;
  290. if Assigned(FActivePage) then
  291. FActivePage.Visible := False;
  292. FActivePage := Page;
  293. if Assigned(ParentForm) and Assigned(FActivePage) and
  294. (ParentForm.ActiveControl = FActivePage) then
  295. FActivePage.SelectFirst;
  296. end;
  297. end;
  298. end.