system.imagelist.pp 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272
  1. {
  2. This file is part of the Free Pascal Run Time Library (rtl)
  3. Copyright (c) 2023 by the Free Pascal development team
  4. This file provides the base of an image list.
  5. See the file COPYING.FPC, included in this distribution,
  6. for details about the copyright.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. **********************************************************************}
  11. {$mode objfpc}
  12. {$h+}
  13. unit System.ImageList;
  14. interface
  15. {$IFDEF FPC_DOTTEDUNITS}
  16. uses
  17. System.Classes, System.UITypes;
  18. {$ELSE}
  19. uses
  20. Classes, System.UITypes;
  21. {$ENDIF}
  22. type
  23. TImageLink = class;
  24. { TBaseImageList }
  25. TBaseImageList = class(TComponent)
  26. private
  27. FUpdateCount: Integer;
  28. FList: TFPList;
  29. FChanged: Boolean;
  30. function GetLinkCount: Integer;
  31. function GetLinks(const aIndex: Integer): TImageLink;
  32. Procedure ClearList;
  33. protected
  34. procedure AddLink(aLink: TImageLink);
  35. procedure DeleteLink(aLink: TImageLink);
  36. function LinkContains(const aLink: TImageLink; const aStartIndex: Integer = -1): Boolean;
  37. procedure DoChange; virtual; abstract;
  38. function GetCount: Integer; virtual; abstract;
  39. procedure Updated; override;
  40. procedure Loaded; override;
  41. property LinkCount: Integer read GetLinkCount;
  42. property Links[aIndex: Integer]: TImageLink read GetLinks;
  43. public
  44. constructor Create(aOwner : TComponent); override;
  45. destructor Destroy; override;
  46. procedure Change; virtual;
  47. procedure BeginUpdate;
  48. procedure EndUpdate;
  49. property Count: Integer read GetCount;
  50. end;
  51. { TImageLink }
  52. TImageLink = class
  53. private
  54. FImages: TBaseImageList;
  55. FImageIndex: TImageIndex;
  56. FIgnoreIndex: Boolean;
  57. FOnChange: TNotifyEvent;
  58. FIgnoreImages: Boolean;
  59. procedure SetImageList(aValue: TBaseImageList);
  60. procedure SetImageIndex(aValue: TImageIndex);
  61. public
  62. constructor Create; virtual;
  63. destructor Destroy; override;
  64. procedure Change; virtual;
  65. property Images: TBaseImageList read FImages write SetImageList;
  66. property ImageIndex: TImageIndex read FImageIndex write SetImageIndex;
  67. property IgnoreIndex: Boolean read FIgnoreIndex write FIgnoreIndex;
  68. property IgnoreImages: Boolean read FIgnoreImages write FIgnoreImages;
  69. property OnChange: TNotifyEvent read FOnChange write FOnChange;
  70. end;
  71. implementation
  72. uses
  73. {$IFDEF FPC_DOTTEDUNITS}
  74. System.SysUtils;
  75. {$ELSE}
  76. SysUtils;
  77. {$ENDIF}
  78. { TBaseImageList }
  79. function TBaseImageList.GetLinkCount: Integer;
  80. begin
  81. Result:=FList.Count;
  82. end;
  83. function TBaseImageList.GetLinks(const aIndex: Integer): TImageLink;
  84. begin
  85. Result:=TImageLink(FList[aIndex]);
  86. end;
  87. procedure TBaseImageList.AddLink(aLink: TImageLink);
  88. begin
  89. if Not assigned(aLink) then
  90. exit;
  91. FList.Add(aLink);
  92. end;
  93. procedure TBaseImageList.DeleteLink(aLink: TImageLink);
  94. begin
  95. if not Assigned(aLink) then
  96. exit;
  97. FList.Remove(aLink);
  98. aLink.FImages:=Nil;
  99. end;
  100. function TBaseImageList.LinkContains(const aLink: TImageLink; const aStartIndex: Integer): Boolean;
  101. begin
  102. Result:=False;
  103. if (aStartIndex<0) or (aStartIndex>=LinkCount) then
  104. exit;
  105. Result:=FList.IndexOf(aLink)>=aStartIndex;
  106. end;
  107. procedure TBaseImageList.Updated;
  108. begin
  109. inherited Updated;
  110. if FChanged then
  111. Change;
  112. end;
  113. procedure TBaseImageList.Loaded;
  114. begin
  115. inherited Loaded;
  116. if FChanged then
  117. Change;
  118. end;
  119. procedure TBaseImageList.ClearList;
  120. var
  121. aCount : integer;
  122. begin
  123. aCount:=FList.Count-1;
  124. While aCount>=0 do
  125. begin
  126. TImageLink(FList[aCount]).FImages:=Nil;
  127. FList.Delete(aCount);
  128. aCount:=FList.Count-1;
  129. end;
  130. end;
  131. constructor TBaseImageList.Create(aOwner: TComponent);
  132. begin
  133. inherited Create(aOwner);
  134. FList:=TFPList.Create;
  135. end;
  136. destructor TBaseImageList.Destroy;
  137. begin
  138. ClearList;
  139. FreeAndNil(FList);
  140. inherited Destroy;
  141. end;
  142. procedure TBaseImageList.Change;
  143. const
  144. NoChangeStates = [csLoading,csDestroying,csUpdating];
  145. begin
  146. FChanged:=True;
  147. if ((ComponentState*NoChangeStates)=[]) then
  148. begin
  149. DoChange;
  150. FChanged:=False;
  151. end;
  152. end;
  153. procedure TBaseImageList.BeginUpdate;
  154. begin
  155. if FUpdateCount = 0 then
  156. Updating;
  157. Inc(FUpdateCount);
  158. end;
  159. procedure TBaseImageList.EndUpdate;
  160. begin
  161. if FUpdateCount<=0 then
  162. exit;
  163. Dec(FUpdateCount);
  164. if FUpdateCount=0 then
  165. Updated;
  166. end;
  167. { TImageLink }
  168. procedure TImageLink.SetImageList(aValue: TBaseImageList);
  169. begin
  170. if aValue=FImages then
  171. exit;
  172. if Assigned(FImages) then
  173. FImages.DeleteLink(Self);
  174. FImages:=aValue;
  175. if Assigned(FImages) then
  176. FImages.AddLink(Self);
  177. if not FIgnoreImages then
  178. Change;
  179. end;
  180. procedure TImageLink.SetImageIndex(aValue: TImageIndex);
  181. begin
  182. if aValue=FImageIndex then
  183. exit;
  184. FImageIndex:=aValue;
  185. If not IgnoreIndex then
  186. Change;
  187. end;
  188. constructor TImageLink.Create;
  189. begin
  190. FImageIndex:=-1;
  191. end;
  192. destructor TImageLink.Destroy;
  193. begin
  194. Images:=Nil;
  195. inherited Destroy;
  196. end;
  197. procedure TImageLink.Change;
  198. begin
  199. if Assigned(FOnChange) then
  200. FOnChange(FImages);
  201. end;
  202. end.