AppsLayout.pas 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  1. unit AppsLayout;
  2. interface
  3. uses
  4. Windows, Classes, SysUtils, StrUtils, Controls, Math;
  5. type
  6. /// <remarks>
  7. /// 控制所以APP按钮的布局
  8. /// </remarks>
  9. TAppsLayout = class
  10. private
  11. FCol,
  12. FRow,
  13. FPageCount,
  14. FPageIndex: Integer;
  15. FClientRect: TRect;
  16. FApps: TStringList;
  17. FAppCountInPage: Integer;
  18. FFirstAppRect: TRect;
  19. FVisible: Boolean;
  20. procedure SetClientRect(const Value: TRect);
  21. procedure SetCol(const Value: Integer);
  22. procedure SetPageIndex(const Value: Integer);
  23. procedure SetRow(const Value: Integer);
  24. procedure SetVisible(const Value: Boolean);
  25. procedure SetAllControlCanntVisible;
  26. /// <summary>
  27. /// 根据FCol、FRow和FClientRect,得到PageCount、首个App显示区域和单页可以显示个数
  28. /// 如果PageCount < PageIndex, 需要重置PageIndex
  29. /// </summary>
  30. procedure Calculate;
  31. /// <summary>
  32. /// 更具FPageIndex显示页数
  33. /// </summary>
  34. procedure ShowPage;
  35. public
  36. constructor Create;
  37. destructor Destroy; override;
  38. procedure AddAppBtn(AAppBtn: TControl);
  39. procedure RemoveAppBtn(AAppBtn: TControl);
  40. /// <summary>
  41. /// 根据首个App显示区域、FCol和FRow,布局好引用
  42. /// </summary>
  43. procedure Layout;
  44. property Col: Integer read FCol write SetCol;
  45. property Row: Integer read FRow write SetRow;
  46. property PageIndex: Integer read FPageIndex write SetPageIndex;
  47. property ClientRect: TRect read FClientRect write SetClientRect;
  48. property Visible: Boolean read FVisible write SetVisible;
  49. property PageCount: Integer read FPageCount;
  50. property Apps: TStringList read FApps;
  51. end;
  52. implementation
  53. { TAppLayout }
  54. procedure TAppsLayout.AddAppBtn(AAppBtn: TControl);
  55. begin
  56. AAppBtn.Visible := False;
  57. FApps.AddObject(IntToStr(FApps.Count), AAppBtn);
  58. end;
  59. procedure TAppsLayout.Calculate;
  60. var
  61. w, h: Integer;
  62. begin
  63. //如果区域没显示就不进行计算,也不进行显示
  64. if (FClientRect.Left >= FClientRect.Right)
  65. or (FClientRect.Top >= FClientRect.Bottom)
  66. or (FCol <= 0)
  67. or (FRow <= 0) then
  68. begin
  69. FPageCount := 0;
  70. FPageIndex := -1;
  71. FAppCountInPage := 0;
  72. FFirstAppRect.Left := 0;
  73. FFirstAppRect.Right := 0;
  74. FFirstAppRect.Top := 0;
  75. FFirstAppRect.Bottom := 0;
  76. Exit;
  77. end;
  78. w := Round((FClientRect.Right - FClientRect.Left) div FCol);
  79. h := Round((FClientRect.Bottom - FClientRect.Top) div FRow);
  80. FFirstAppRect.Top := FClientRect.Top;
  81. FFirstAppRect.Left := FClientRect.Left;
  82. FFirstAppRect.Bottom := FFirstAppRect.Top + h;
  83. FFirstAppRect.Right := FFirstAppRect.Left + w;
  84. FAppCountInPage := FCol * FRow;
  85. Layout;
  86. end;
  87. constructor TAppsLayout.Create;
  88. begin
  89. FApps := TStringList.Create;
  90. inherited Create;
  91. end;
  92. destructor TAppsLayout.Destroy;
  93. begin
  94. FreeAndNil(FApps);
  95. inherited;
  96. end;
  97. procedure TAppsLayout.Layout;
  98. var
  99. iLoop,
  100. jLoop,
  101. zLoop, iIndex : Integer;
  102. w, h: Integer;
  103. begin
  104. if FApps.Count = 0 then
  105. Exit;
  106. FPageCount := Ceil(FApps.Count / FAppCountInPage);
  107. if (FPageIndex < 0) and (FPageCount > 0) then
  108. FPageIndex := 0
  109. else
  110. if FPageIndex >= FPageCount then
  111. FPageIndex := FPageCount - 1;
  112. w := FFirstAppRect.Right - FFirstAppRect.Left;
  113. h := FFirstAppRect.Bottom - FFirstAppRect.Top;
  114. iIndex := 0;
  115. for zLoop := 0 to FPageCount - 1 do
  116. for iLoop := 0 to FRow - 1 do
  117. for jLoop := 0 to FCol - 1 do
  118. begin
  119. with FApps.Objects[iIndex] as TControl do
  120. begin
  121. Top := FFirstAppRect.Top + iLoop * h + Round((h - Height) div 2);
  122. Left := FFirstAppRect.Left + jLoop * w + Round((w - Width) div 2);
  123. BringToFront;
  124. end;
  125. if iIndex >= (FApps.Count - 1) then
  126. begin
  127. ShowPage;
  128. Exit;
  129. end;
  130. Inc(iIndex);
  131. end;
  132. end;
  133. procedure TAppsLayout.RemoveAppBtn(AAppBtn: TControl);
  134. var
  135. i: Integer;
  136. begin
  137. i := FApps.IndexOfObject(AAppBtn);
  138. if i < 0 then
  139. Exit;
  140. FApps.Delete(i);
  141. Layout;
  142. end;
  143. procedure TAppsLayout.SetAllControlCanntVisible;
  144. var
  145. iLoop: Integer;
  146. begin
  147. for iLoop := 0 to FApps.Count - 1 do
  148. (FApps.Objects[iLoop] as TControl).Visible := False;
  149. end;
  150. procedure TAppsLayout.SetClientRect(const Value: TRect);
  151. begin
  152. if EqualRect(FClientRect, Value) then
  153. Exit;
  154. FClientRect := Value;
  155. Calculate;
  156. end;
  157. procedure TAppsLayout.SetCol(const Value: Integer);
  158. begin
  159. if FCol = Value then
  160. Exit;
  161. FCol := Value;
  162. Calculate;
  163. end;
  164. procedure TAppsLayout.SetPageIndex(const Value: Integer);
  165. begin
  166. if (Value < 0) or (Value > FPageCount - 1) then
  167. Exit;
  168. if Value = FPageIndex then
  169. Exit;
  170. FPageIndex := Value;
  171. ShowPage;
  172. end;
  173. procedure TAppsLayout.SetRow(const Value: Integer);
  174. begin
  175. if FRow = Value then
  176. Exit;
  177. FRow := Value;
  178. Calculate;
  179. end;
  180. procedure TAppsLayout.SetVisible(const Value: Boolean);
  181. var
  182. iLoop: Integer;
  183. begin
  184. if FVisible = Value then
  185. Exit;
  186. FVisible := Value;
  187. if FVisible then
  188. ShowPage
  189. else
  190. SetAllControlCanntVisible;
  191. end;
  192. procedure TAppsLayout.ShowPage;
  193. var
  194. iLoop: Integer;
  195. begin
  196. if (FClientRect.Left >= FClientRect.Right)
  197. or (FClientRect.Top >= FClientRect.Bottom)
  198. or (FCol <= 0)
  199. or (FRow <= 0)
  200. or (FPageIndex < 0)then
  201. Exit;
  202. SetAllControlCanntVisible;
  203. for iLoop := FPageIndex * FAppCountInPage to (FPageIndex + 1) * FAppCountInPage - 1 do
  204. begin
  205. if iLoop > FApps.Count - 1 then
  206. Exit;
  207. (FApps.Objects[iLoop] as TControl).Visible := True;
  208. (FApps.Objects[iLoop] as TControl).Invalidate;
  209. end;
  210. end;
  211. end.