2
0

NewNotebook.pas 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322
  1. unit NewNotebook;
  2. {
  3. Inno Setup
  4. Copyright (C) 1997-2025 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: NativeInt): TNewNotebookPage;
  19. function GetPageCount: NativeInt;
  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: NativeInt read GetPageCount;
  33. property Pages[Index: NativeInt]: 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 ParentBackground;
  44. property ParentColor;
  45. property ParentFont;
  46. property ParentShowHint;
  47. property PopupMenu;
  48. property ShowHint;
  49. property TabOrder;
  50. property TabStop;
  51. property Visible;
  52. property OnDragDrop;
  53. property OnDragOver;
  54. property OnEndDrag;
  55. property OnEnter;
  56. property OnExit;
  57. property OnMouseDown;
  58. property OnMouseMove;
  59. property OnMouseUp;
  60. property OnStartDrag;
  61. end;
  62. TNewNotebookPage = class(TCustomControl)
  63. private
  64. FNotebook: TNewNotebook;
  65. function GetPageIndex: NativeInt;
  66. procedure SetNotebook(ANotebook: TNewNotebook);
  67. procedure SetPageIndex(Value: NativeInt);
  68. protected
  69. procedure Paint; override;
  70. procedure ReadState(Reader: TReader); override;
  71. public
  72. constructor Create(AOwner: TComponent); override;
  73. destructor Destroy; override;
  74. property Notebook: TNewNotebook read FNotebook write SetNotebook;
  75. published
  76. property Color nodefault; { nodefault needed for Color=clWindow to persist }
  77. property DragMode;
  78. property Enabled;
  79. property Font;
  80. property Height stored False;
  81. property Left stored False;
  82. property PageIndex: NativeInt read GetPageIndex write SetPageIndex stored False;
  83. property ParentBackground;
  84. property ParentColor;
  85. property ParentFont;
  86. property ParentShowHint;
  87. property PopupMenu;
  88. property ShowHint;
  89. property Top stored False;
  90. property Visible stored False;
  91. property Width stored False;
  92. property OnDragDrop;
  93. property OnDragOver;
  94. property OnEndDrag;
  95. property OnEnter;
  96. property OnExit;
  97. property OnMouseDown;
  98. property OnMouseMove;
  99. property OnMouseUp;
  100. property OnStartDrag;
  101. end;
  102. implementation
  103. uses
  104. Types;
  105. { TNewNotebookPage }
  106. constructor TNewNotebookPage.Create(AOwner: TComponent);
  107. begin
  108. inherited;
  109. Align := alClient;
  110. ControlStyle := ControlStyle + [csAcceptsControls, csNoDesignVisible];
  111. Visible := False;
  112. end;
  113. destructor TNewNotebookPage.Destroy;
  114. begin
  115. if Assigned(FNotebook) then
  116. FNotebook.RemovePage(Self);
  117. inherited;
  118. end;
  119. function TNewNotebookPage.GetPageIndex: NativeInt;
  120. begin
  121. if Assigned(FNotebook) then
  122. Result := FNotebook.FPages.IndexOf(Self)
  123. else
  124. Result := -1;
  125. end;
  126. procedure TNewNotebookPage.Paint;
  127. begin
  128. inherited;
  129. if csDesigning in ComponentState then begin
  130. Canvas.Pen.Style := psDash;
  131. Canvas.Brush.Style := bsClear;
  132. Canvas.Rectangle(0, 0, Width, Height);
  133. end;
  134. end;
  135. procedure TNewNotebookPage.ReadState(Reader: TReader);
  136. begin
  137. inherited;
  138. if Reader.Parent is TNewNotebook then
  139. Notebook := TNewNotebook(Reader.Parent);
  140. end;
  141. procedure TNewNotebookPage.SetNotebook(ANotebook: TNewNotebook);
  142. begin
  143. if FNotebook <> ANotebook then begin
  144. if Assigned(FNotebook) then
  145. FNotebook.RemovePage(Self);
  146. Parent := ANotebook;
  147. if Assigned(ANotebook) then
  148. ANotebook.InsertPage(Self);
  149. end;
  150. end;
  151. procedure TNewNotebookPage.SetPageIndex(Value: NativeInt);
  152. begin
  153. if Assigned(FNotebook) then begin
  154. if Value >= FNotebook.FPages.Count then
  155. Value := FNotebook.FPages.Count-1;
  156. if Value < 0 then
  157. Value := 0;
  158. FNotebook.FPages.Move(PageIndex, Value);
  159. end;
  160. end;
  161. { TNewNotebook }
  162. constructor TNewNotebook.Create(AOwner: TComponent);
  163. begin
  164. inherited;
  165. Width := 150;
  166. Height := 150;
  167. FPages := TList.Create;
  168. end;
  169. destructor TNewNotebook.Destroy;
  170. begin
  171. if Assigned(FPages) then begin
  172. for var 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. begin
  206. if FPages.Count > 0 then begin
  207. var StartIndex := FPages.IndexOf(CurPage);
  208. if StartIndex = -1 then begin
  209. if GoForward then
  210. StartIndex := FPages.Count-1
  211. else
  212. StartIndex := 0;
  213. end;
  214. var I := StartIndex;
  215. repeat
  216. if GoForward then begin
  217. Inc(I);
  218. if I = FPages.Count then
  219. I := 0;
  220. end
  221. else begin
  222. if I = 0 then
  223. I := FPages.Count;
  224. Dec(I);
  225. end;
  226. Result := FPages[I];
  227. Exit;
  228. until I = StartIndex;
  229. end;
  230. Result := nil;
  231. end;
  232. procedure TNewNotebook.GetChildren(Proc: TGetChildProc; Root: TComponent);
  233. begin
  234. for var I := 0 to FPages.Count-1 do
  235. Proc(TNewNotebookPage(FPages[I]));
  236. end;
  237. function TNewNotebook.GetPage(Index: NativeInt): TNewNotebookPage;
  238. begin
  239. Result := FPages[Index];
  240. end;
  241. function TNewNotebook.GetPageCount: NativeInt;
  242. begin
  243. Result := FPages.Count;
  244. end;
  245. procedure TNewNotebook.InsertPage(Page: TNewNotebookPage);
  246. begin
  247. FPages.Add(Page);
  248. Page.FNotebook := Self;
  249. end;
  250. procedure TNewNotebook.RemovePage(Page: TNewNotebookPage);
  251. begin
  252. Page.FNotebook := nil;
  253. FPages.Remove(Page);
  254. if FActivePage = Page then
  255. SetActivePage(nil);
  256. end;
  257. procedure TNewNotebook.ShowControl(AControl: TControl);
  258. begin
  259. if (AControl is TNewNotebookPage) and (TNewNotebookPage(AControl).FNotebook = Self) then
  260. SetActivePage(TNewNotebookPage(AControl));
  261. inherited;
  262. end;
  263. procedure TNewNotebook.SetActivePage(Page: TNewNotebookPage);
  264. begin
  265. if Assigned(Page) and (Page.FNotebook <> Self) then
  266. Exit;
  267. if FActivePage <> Page then begin
  268. const ParentForm = GetParentForm(Self);
  269. if Assigned(ParentForm) and Assigned(FActivePage) and
  270. FActivePage.ContainsControl(ParentForm.ActiveControl) then
  271. ParentForm.ActiveControl := FActivePage;
  272. if Assigned(Page) then begin
  273. Page.BringToFront;
  274. Page.Visible := True;
  275. if Assigned(ParentForm) and Assigned(FActivePage) and
  276. (ParentForm.ActiveControl = FActivePage) then begin
  277. if Page.CanFocus then
  278. ParentForm.ActiveControl := Page
  279. else
  280. ParentForm.ActiveControl := Self;
  281. end;
  282. end;
  283. if Assigned(FActivePage) then
  284. FActivePage.Visible := False;
  285. FActivePage := Page;
  286. if Assigned(ParentForm) and Assigned(FActivePage) and
  287. (ParentForm.ActiveControl = FActivePage) then
  288. FActivePage.SelectFirst;
  289. end;
  290. end;
  291. end.