bcbasectrls.pas 49 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837
  1. // SPDX-License-Identifier: LGPL-3.0-linking-exception
  2. { Base framework classes
  3. originally written in 2012 by Krzysztof Dibowski dibowski at interia.pl
  4. }
  5. {******************************* CONTRIBUTOR(S) ******************************
  6. - Edivando S. Santos Brasil | [email protected]
  7. (Compatibility with delphi VCL 11/2018)
  8. ***************************** END CONTRIBUTOR(S) *****************************}
  9. unit BCBaseCtrls;
  10. {$I bgracontrols.inc}
  11. interface
  12. uses
  13. Classes, SysUtils, Controls, ExtCtrls, Graphics,
  14. {$IFNDEF FPC}Windows, Messages, BGRAGraphics, GraphType, FPImage, {$ELSE} LCLType,{$ENDIF}
  15. BGRABitmap, BGRABitmapTypes;
  16. type
  17. {$IFNDEF FPC}
  18. TSpacingSize = Integer;
  19. TControlCellAlign = (
  20. ccaFill,
  21. ccaLeftTop,
  22. ccaRightBottom,
  23. ccaCenter
  24. );
  25. TControlCellAligns = set of TControlCellAlign;
  26. TControlBorderSpacingDefault = record
  27. Left: TSpacingSize;
  28. Top: TSpacingSize;
  29. Right: TSpacingSize;
  30. Bottom: TSpacingSize;
  31. Around: TSpacingSize;
  32. end;
  33. PControlBorderSpacingDefault = ^TControlBorderSpacingDefault;
  34. TBGRAGraphicCtrl = class;
  35. TBGRACustomCtrl = class;
  36. TControlBorderSpacing = class;
  37. ILCLControl = interface
  38. ['{97A3D274-C4BD-4095-9B23-8E50D6E0EA24}']
  39. procedure DoOnResize;
  40. procedure CalculatePreferredSize(var PreferredWidth, PreferredHeight: integer;{%H-}WithThemeSpace: boolean);
  41. procedure MouseEnter;
  42. procedure MouseLeave;
  43. procedure TextChanged;
  44. procedure FontChanged(Sender: TObject);
  45. procedure RealSetText(const Value: TCaption);
  46. procedure Resize;
  47. procedure SetColor(Value: TColor);
  48. function GetColor : TColor;
  49. function ColorIsStored: boolean;
  50. function RealGetText: TCaption;
  51. function CreateControlBorderSpacing: TControlBorderSpacing;
  52. procedure SetBorderSpacing(const AValue: TControlBorderSpacing);
  53. procedure SetInitialBounds(aLeft, aTop, aWidth, aHeight: integer);
  54. procedure InvalidatePreferredSize;
  55. procedure EnableAutoSizing;
  56. procedure DoBorderSpacingChange(Sender: TObject; InnerSpaceChanged: Boolean);
  57. function GetInstance : TObject;
  58. function IsInnerBorderStored: boolean;
  59. end;
  60. TControlBorderSpacing = class(TPersistent)
  61. private
  62. FAround: TSpacingSize;
  63. FBottom: TSpacingSize;
  64. FCellAlignHorizontal: TControlCellAlign;
  65. FCellAlignVertical: TControlCellAlign;
  66. FControl: ILCLControl;
  67. FInnerBorder: Integer;
  68. FLeft: TSpacingSize;
  69. FOnChange: TNotifyEvent;
  70. FRight: TSpacingSize;
  71. FTop: TSpacingSize;
  72. FDefault: PControlBorderSpacingDefault;
  73. function GetAroundBottom: Integer;
  74. function GetAroundLeft: Integer;
  75. function GetAroundRight: Integer;
  76. function GetAroundTop: Integer;
  77. function GetControlBottom: Integer;
  78. function GetControlHeight: Integer;
  79. function GetControlLeft: Integer;
  80. function GetControlRight: Integer;
  81. function GetControlTop: Integer;
  82. function GetControlWidth: Integer;
  83. function IsAroundStored: boolean;
  84. function IsBottomStored: boolean;
  85. function IsInnerBorderStored: boolean;
  86. function IsLeftStored: boolean;
  87. function IsRightStored: boolean;
  88. function IsTopStored: boolean;
  89. procedure SetAround(const AValue: TSpacingSize);
  90. procedure SetBottom(const AValue: TSpacingSize);
  91. procedure SetCellAlignHorizontal(const AValue: TControlCellAlign);
  92. procedure SetCellAlignVertical(const AValue: TControlCellAlign);
  93. procedure SetInnerBorder(const AValue: Integer);
  94. procedure SetLeft(const AValue: TSpacingSize);
  95. procedure SetRight(const AValue: TSpacingSize);
  96. procedure SetSpace(Kind: TAnchorKind; const AValue: integer);
  97. procedure SetTop(const AValue: TSpacingSize);
  98. protected
  99. procedure Change(InnerSpaceChanged: Boolean); virtual;
  100. public
  101. constructor Create(OwnerControl: ILCLControl; ADefault: PControlBorderSpacingDefault = nil);
  102. procedure Assign(Source: TPersistent); override;
  103. procedure AssignTo(Dest: TPersistent); override;
  104. function IsEqual(Spacing: TControlBorderSpacing): boolean;
  105. procedure GetSpaceAround(var SpaceAround: TRect); virtual;
  106. function GetSideSpace(Kind: TAnchorKind): Integer; // Around+GetSpace
  107. function GetSpace(Kind: TAnchorKind): Integer; virtual;
  108. procedure AutoAdjustLayout(const AXProportion, AYProportion: Double);
  109. public
  110. property Control: ILCLControl read FControl;
  111. property Space[Kind: TAnchorKind]: integer read GetSpace write SetSpace;
  112. property AroundLeft: Integer read GetAroundLeft;
  113. property AroundTop: Integer read GetAroundTop;
  114. property AroundRight: Integer read GetAroundRight;
  115. property AroundBottom: Integer read GetAroundBottom;
  116. property ControlLeft: Integer read GetControlLeft;
  117. property ControlTop: Integer read GetControlTop;
  118. property ControlWidth: Integer read GetControlWidth;
  119. property ControlHeight: Integer read GetControlHeight;
  120. property ControlRight: Integer read GetControlRight;
  121. property ControlBottom: Integer read GetControlBottom;
  122. published
  123. property OnChange: TNotifyEvent read FOnChange write FOnChange;
  124. property Left: TSpacingSize read FLeft write SetLeft stored IsLeftStored;
  125. property Top: TSpacingSize read FTop write SetTop stored IsTopStored;
  126. property Right: TSpacingSize read FRight write SetRight stored IsRightStored;
  127. property Bottom: TSpacingSize read FBottom write SetBottom stored IsBottomStored;
  128. property Around: TSpacingSize read FAround write SetAround stored IsAroundStored;
  129. property InnerBorder: Integer read FInnerBorder write SetInnerBorder stored IsInnerBorderStored default 0;
  130. property CellAlignHorizontal: TControlCellAlign read FCellAlignHorizontal write SetCellAlignHorizontal default ccaFill;
  131. property CellAlignVertical: TControlCellAlign read FCellAlignVertical write SetCellAlignVertical default ccaFill;
  132. end;
  133. TChildControlResizeStyle = (
  134. crsAnchorAligning, // (like Delphi)
  135. crsScaleChilds, // scale children equally, keep space between children fixed
  136. crsHomogenousChildResize, // enlarge children equally (i.e. by the same amount of pixel)
  137. crsHomogenousSpaceResize // enlarge space between children equally
  138. {$IFDEF EnablecrsSameSize}
  139. ,crsSameSize // each child gets the same size (maybe one pixel difference)
  140. {$ENDIF}
  141. );
  142. TControlChildrenLayout = (
  143. cclNone,
  144. cclLeftToRightThenTopToBottom, // if BiDiMode <> bdLeftToRight then it becomes RightToLeft
  145. cclTopToBottomThenLeftToRight
  146. );
  147. TControlChildSizing = class(TPersistent)
  148. private
  149. FControl: ILCLControl;
  150. FControlsPerLine: integer;
  151. FEnlargeHorizontal: TChildControlResizeStyle;
  152. FEnlargeVertical: TChildControlResizeStyle;
  153. FHorizontalSpacing: integer;
  154. FLayout: TControlChildrenLayout;
  155. FLeftRightSpacing: integer;
  156. FOnChange: TNotifyEvent;
  157. FShrinkHorizontal: TChildControlResizeStyle;
  158. FShrinkVertical: TChildControlResizeStyle;
  159. FTopBottomSpacing: integer;
  160. FVerticalSpacing: integer;
  161. procedure SetControlsPerLine(const AValue: integer);
  162. procedure SetEnlargeHorizontal(const AValue: TChildControlResizeStyle);
  163. procedure SetEnlargeVertical(const AValue: TChildControlResizeStyle);
  164. procedure SetHorizontalSpacing(const AValue: integer);
  165. procedure SetLayout(const AValue: TControlChildrenLayout);
  166. procedure SetLeftRightSpacing(const AValue: integer);
  167. procedure SetShrinkHorizontal(const AValue: TChildControlResizeStyle);
  168. procedure SetShrinkVertical(const AValue: TChildControlResizeStyle);
  169. procedure SetTopBottomSpacing(const AValue: integer);
  170. procedure SetVerticalSpacing(const AValue: integer);
  171. protected
  172. procedure Change; virtual;
  173. public
  174. constructor Create(OwnerControl: ILCLControl);
  175. procedure Assign(Source: TPersistent); override;
  176. procedure AssignTo(Dest: TPersistent); override;
  177. function IsEqual(Sizing: TControlChildSizing): boolean;
  178. procedure SetGridSpacing(Spacing: integer);
  179. public
  180. property Control: ILCLControl read FControl;
  181. property OnChange: TNotifyEvent read FOnChange write FOnChange;
  182. published
  183. property LeftRightSpacing: integer read FLeftRightSpacing write SetLeftRightSpacing default 0;
  184. property TopBottomSpacing: integer read FTopBottomSpacing write SetTopBottomSpacing default 0;
  185. property HorizontalSpacing: integer read FHorizontalSpacing write SetHorizontalSpacing default 0;
  186. property VerticalSpacing: integer read FVerticalSpacing write SetVerticalSpacing default 0;
  187. property EnlargeHorizontal: TChildControlResizeStyle read FEnlargeHorizontal
  188. write SetEnlargeHorizontal default crsAnchorAligning;
  189. property EnlargeVertical: TChildControlResizeStyle read FEnlargeVertical
  190. write SetEnlargeVertical default crsAnchorAligning;
  191. property ShrinkHorizontal: TChildControlResizeStyle read FShrinkHorizontal
  192. write SetShrinkHorizontal default crsAnchorAligning;
  193. property ShrinkVertical: TChildControlResizeStyle read FShrinkVertical
  194. write SetShrinkVertical default crsAnchorAligning;
  195. property Layout: TControlChildrenLayout read FLayout write SetLayout default cclNone;
  196. property ControlsPerLine: integer read FControlsPerLine write SetControlsPerLine default 0;
  197. end;
  198. {$ENDIF}
  199. {$IFDEF FPC}
  200. TBGRAGraphicCtrl = class(TGraphicControl)
  201. {$ELSE}
  202. TBGRAGraphicCtrl = class(TGraphicControl, ILCLControl)
  203. protected
  204. FBorderSpacing: TControlBorderSpacing;
  205. FOnChange: TNotifyEvent;
  206. FMouseInClient: boolean;
  207. procedure DoOnResize; virtual;
  208. procedure CalculatePreferredSize(var PreferredWidth, PreferredHeight: integer;{%H-}WithThemeSpace: boolean); virtual;
  209. procedure MouseEnter; virtual;
  210. procedure MouseLeave; virtual;
  211. procedure TextChanged; virtual;
  212. procedure FontChanged(Sender: TObject); virtual;
  213. procedure RealSetText(const Value: TCaption); virtual;
  214. procedure Resize; override;
  215. class function GetControlClassDefaultSize: TSize; virtual;
  216. procedure SetColor(Value: TColor); virtual;
  217. function GetColor : TColor;
  218. procedure CMMouseEnter(var Message :TMessage); message CM_MOUSEENTER;
  219. procedure CMMouseLeave(var Message :TMessage); message CM_MOUSELEAVE;
  220. procedure CMTextChanged(var Message: TMessage); message CM_TEXTCHANGED;
  221. function ColorIsStored: boolean; virtual;
  222. function RealGetText: TCaption; virtual;
  223. function CreateControlBorderSpacing: TControlBorderSpacing; virtual;
  224. procedure SetBorderSpacing(const AValue: TControlBorderSpacing);
  225. procedure DoBorderSpacingChange(Sender: TObject; InnerSpaceChanged: Boolean); virtual;
  226. function GetInstance : TObject;
  227. function IsInnerBorderStored: boolean;
  228. public
  229. constructor Create(TheOwner: TComponent);override;
  230. destructor Destroy;override;
  231. procedure SetInitialBounds(aLeft, aTop, aWidth, aHeight: integer); virtual;
  232. procedure InvalidatePreferredSize; virtual;
  233. procedure EnableAutoSizing;
  234. property Color: TColor read GetColor write SetColor stored ColorIsStored default clWindow;
  235. property BorderSpacing: TControlBorderSpacing read FBorderSpacing write SetBorderSpacing;
  236. property Caption;
  237. property Canvas;
  238. {$ENDIF}
  239. end;
  240. {$IFDEF FPC}
  241. TBGRACustomCtrl = class(TCustomControl)
  242. {$ELSE}
  243. TBGRACustomCtrl = class(TCustomControl, ILCLControl)
  244. protected
  245. FBorderSpacing: TControlBorderSpacing;
  246. FChildSizing: TControlChildSizing;
  247. FOnChange: TNotifyEvent;
  248. FMouseInClient: boolean;
  249. procedure CalculatePreferredSize(var PreferredWidth, PreferredHeight: integer;{%H-}WithThemeSpace: boolean); {$IFDEF FPC}override;{$ELSE}virtual;{$ENDIF}
  250. procedure DoOnResize; virtual;
  251. procedure MouseEnter; virtual;
  252. procedure MouseLeave; virtual;
  253. procedure TextChanged; virtual;
  254. procedure FontChanged(Sender: TObject); virtual;
  255. function GetDefaultDockCaption: String; virtual;
  256. procedure RealSetText(const Value: TCaption); virtual;
  257. procedure EnabledChanged; virtual;
  258. procedure Resize; override;
  259. class function GetControlClassDefaultSize: TSize; virtual;
  260. procedure SetColor(Value: TColor); virtual;
  261. function GetColor : TColor;
  262. procedure UTF8KeyPress(var UTF8Key: {$IFDEF FPC}TUTF8Char{$ELSE}String{$ENDIF}); virtual;
  263. procedure CMMouseEnter(var Message :TMessage); message CM_MOUSEENTER;
  264. procedure CMMouseLeave(var Message :TMessage); message CM_MOUSELEAVE;
  265. procedure CMTextChanged(var Message: TMessage); message CM_TEXTCHANGED;
  266. function ColorIsStored: boolean; virtual;
  267. function RealGetText: TCaption; virtual;
  268. function CreateControlBorderSpacing: TControlBorderSpacing; virtual;
  269. procedure SetBorderSpacing(const AValue: TControlBorderSpacing);
  270. procedure DoBorderSpacingChange(Sender: TObject; InnerSpaceChanged: Boolean); virtual;
  271. function GetInstance : TObject;
  272. function IsInnerBorderStored: boolean;
  273. procedure SetChildSizing(const AValue: TControlChildSizing);
  274. procedure DoChildSizingChange(Sender: TObject); virtual;
  275. public
  276. constructor Create(TheOwner: TComponent);override;
  277. destructor Destroy;override;
  278. procedure SetInitialBounds(aLeft, aTop, aWidth, aHeight: integer); virtual;
  279. procedure InvalidatePreferredSize; virtual;
  280. procedure EnableAutoSizing;
  281. property Color: TColor read GetColor write SetColor stored ColorIsStored default clWindow;
  282. property BorderSpacing: TControlBorderSpacing read FBorderSpacing write SetBorderSpacing;
  283. property ChildSizing: TControlChildSizing read FChildSizing write SetChildSizing;
  284. property Caption;
  285. property Canvas;
  286. {$ENDIF}
  287. end;
  288. {$IFDEF FPC}
  289. TBGRACustomPanel = class(TCustomPanel)
  290. {$ELSE}
  291. TBGRACustomPanel = class(TCustomPanel, ILCLControl)
  292. protected
  293. FBorderSpacing: TControlBorderSpacing;
  294. FChildSizing: TControlChildSizing;
  295. FOnChange: TNotifyEvent;
  296. FMouseInClient: boolean;
  297. procedure CalculatePreferredSize(var PreferredWidth, PreferredHeight: integer;{%H-}WithThemeSpace: boolean); {$IFDEF FPC}override;{$ELSE}virtual;{$ENDIF}
  298. procedure DoOnResize; virtual;
  299. procedure MouseEnter; virtual;
  300. procedure MouseLeave; virtual;
  301. procedure TextChanged; virtual;
  302. procedure FontChanged(Sender: TObject); virtual;
  303. function GetDefaultDockCaption: String; virtual;
  304. procedure RealSetText(const Value: TCaption); virtual;
  305. procedure EnabledChanged; virtual;
  306. procedure Resize; override;
  307. class function GetControlClassDefaultSize: TSize; virtual;
  308. procedure SetColor(Value: TColor); virtual;
  309. function GetColor : TColor;
  310. procedure UTF8KeyPress(var UTF8Key: {$IFDEF FPC}TUTF8Char{$ELSE}String{$ENDIF}); virtual;
  311. procedure CMMouseEnter(var Message :TMessage); message CM_MOUSEENTER;
  312. procedure CMMouseLeave(var Message :TMessage); message CM_MOUSELEAVE;
  313. procedure CMTextChanged(var Message: TMessage); message CM_TEXTCHANGED;
  314. function ColorIsStored: boolean; virtual;
  315. function RealGetText: TCaption; virtual;
  316. function CreateControlBorderSpacing: TControlBorderSpacing; virtual;
  317. procedure SetBorderSpacing(const AValue: TControlBorderSpacing);
  318. procedure DoBorderSpacingChange(Sender: TObject; InnerSpaceChanged: Boolean); virtual;
  319. function GetInstance : TObject;
  320. function IsInnerBorderStored: boolean;
  321. procedure SetChildSizing(const AValue: TControlChildSizing);
  322. procedure DoChildSizingChange(Sender: TObject); virtual;
  323. public
  324. constructor Create(TheOwner: TComponent);override;
  325. destructor Destroy;override;
  326. procedure SetInitialBounds(aLeft, aTop, aWidth, aHeight: integer); virtual;
  327. procedure InvalidatePreferredSize; virtual;
  328. procedure EnableAutoSizing;
  329. property Color: TColor read GetColor write SetColor stored ColorIsStored default clWindow;
  330. property BorderSpacing: TControlBorderSpacing read FBorderSpacing write SetBorderSpacing;
  331. property ChildSizing: TControlChildSizing read FChildSizing write SetChildSizing;
  332. property Canvas;
  333. {$ENDIF}
  334. end;
  335. TOnBCPropertyChange = procedure(ASender: TObject; AData: PtrInt) of object;
  336. { TBCProperty
  337. Base BC Property with OnChange event support
  338. }
  339. TBCProperty = class(TPersistent)
  340. private
  341. FOnChange: TOnBCPropertyChange;
  342. protected
  343. FControl: TControl;
  344. procedure Change(AData: PtrInt = 0); virtual;
  345. public
  346. constructor Create(AControl: TControl); virtual;
  347. public
  348. property Control: TControl read FControl;
  349. property OnChange: TOnBCPropertyChange read FOnChange write FOnChange;
  350. end;
  351. { TBGRABitmapEx
  352. Some BGRABitmap descendant which can store custom data and has NeedRender flag
  353. }
  354. TBGRABitmapEx = class(TBGRABitmap)
  355. private
  356. FCustomData: PtrInt;
  357. FNeedRender: Boolean;
  358. protected
  359. procedure Init; override;
  360. public
  361. property NeedRender: Boolean read FNeedRender write FNeedRender;
  362. property CustomData: PtrInt read FCustomData write FCustomData;
  363. procedure Discard;
  364. end;
  365. { TBCGraphicControl
  366. BC graphic control with some basic functionality like begin/end update and
  367. debug functions
  368. }
  369. TBCGraphicControl = class(TBGRAGraphicCtrl)
  370. private
  371. {$IFDEF INDEBUG}
  372. FPaintCount: Integer;
  373. {$ENDIF}
  374. FUpdateCount: Integer;
  375. protected
  376. procedure DoOnResize; override;
  377. protected
  378. {$IFDEF INDEBUG}
  379. function GetDebugText: String; virtual;
  380. {$ENDIF}
  381. procedure Paint; override; // do not override in descendants!
  382. // All descendants should use DrawControl method instead of Paint.
  383. // DrawControl is not called between BeginUpdate and EndUpdate
  384. procedure DrawControl; virtual;
  385. // This method is called when control should be rendered (when some
  386. // general action occur which change "body" e.g. resize)
  387. procedure RenderControl; virtual;
  388. public
  389. {$IFDEF FPC}
  390. { Save all published settings to file }
  391. procedure SaveToFile(AFileName: string); virtual; abstract;
  392. { Load and assign all published settings from file }
  393. procedure LoadFromFile(AFileName: string); virtual; abstract;
  394. { Assign the properties from AFileName to this instance }
  395. procedure AssignFromFile(AFileName: string); virtual; abstract;
  396. { Used by SaveToFile/LoadFromFile }
  397. {$ENDIF}
  398. constructor Create(AOwner: TComponent); override;
  399. // This disable DrawControl method
  400. procedure BeginUpdate; virtual;
  401. // This enable DrawControl method
  402. procedure EndUpdate; virtual;
  403. // Called on EndUpdate if FUpdateCount is 0
  404. procedure UpdateControl; virtual;
  405. // Check if BeginUpdate was called
  406. function IsUpdating: Boolean;
  407. end;
  408. { TBCStyleDummyProperty
  409. This is only dummy property type for access to style editor from
  410. object inspector
  411. }
  412. TBCStyleDummyProperty = class(TBCProperty)
  413. end;
  414. { TBCStyleGraphicControl
  415. All descendants of this class have support for saving and loading styles and
  416. access to style editor from object inspector or component context menu
  417. }
  418. TBCStyleGraphicControl = class(TBCGraphicControl)
  419. private
  420. FAssignStyle: TBCStyleDummyProperty;
  421. protected
  422. function GetStyleExtension: String; virtual; abstract;
  423. // Dummy property for access to style editor dialog
  424. property AssignStyle: TBCStyleDummyProperty read FAssignStyle;
  425. public
  426. constructor Create(AOwner: TComponent); override;
  427. destructor Destroy; override;
  428. property StyleExtension: String read GetStyleExtension;
  429. end;
  430. { TBCCustomControl
  431. BC custom control with some basic functionality like begin/end update and
  432. debug functions
  433. }
  434. TBCCustomControl = class(TBGRACustomCtrl)
  435. private
  436. {$IFDEF INDEBUG}
  437. FPaintCount: Integer;
  438. {$ENDIF}
  439. FUpdateCount: Integer;
  440. protected
  441. procedure DoOnResize; override;
  442. protected
  443. {$IFDEF INDEBUG}
  444. function GetDebugText: String; virtual;
  445. {$ENDIF}
  446. procedure Paint; override; // do not override in descendants!
  447. // All descendants should use DrawControl method instead of Paint.
  448. // DrawControl is not called between BeginUpdate and EndUpdate
  449. procedure DrawControl; virtual;
  450. // This method is called when control should be rendered (when some
  451. // general action occur which change "body" e.g. resize)
  452. procedure RenderControl; virtual;
  453. public
  454. constructor Create(AOwner: TComponent); override;
  455. // This disable DrawControl method
  456. procedure BeginUpdate; virtual;
  457. // This enable DrawControl method
  458. procedure EndUpdate; virtual;
  459. // Called on EndUpdate if FUpdateCount is 0
  460. procedure UpdateControl; virtual;
  461. // Check if BeginUpdate was called
  462. function IsUpdating: Boolean;
  463. end;
  464. { TBCStyleCustomControl
  465. All descendants of this class have support for saving and loading styles and
  466. access to style editor from object inspector or component context menu
  467. }
  468. TBCStyleCustomControl = class(TBCCustomControl)
  469. private
  470. FAssignStyle: TBCStyleDummyProperty;
  471. protected
  472. function GetStyleExtension: String; virtual; abstract;
  473. // Dummy property for access to style editor dialog
  474. property AssignStyle: TBCStyleDummyProperty read FAssignStyle;
  475. public
  476. constructor Create(AOwner: TComponent); override;
  477. destructor Destroy; override;
  478. property StyleExtension: String read GetStyleExtension;
  479. end;
  480. {$IFDEF FPC}procedure Register;{$ENDIF}
  481. implementation
  482. //{$IFDEF INDEBUG} uses Graphics; {$ENDIF}
  483. {$IFDEF FPC}
  484. procedure Register;
  485. begin
  486. RegisterNoIcon([TBCCustomControl]);
  487. end;
  488. {$ENDIF}
  489. { TBCStyleCustomControl }
  490. constructor TBCStyleCustomControl.Create(AOwner: TComponent);
  491. begin
  492. inherited Create(AOwner);
  493. FAssignStyle := TBCStyleDummyProperty.Create(Self);
  494. end;
  495. destructor TBCStyleCustomControl.Destroy;
  496. begin
  497. FAssignStyle.Free;
  498. inherited Destroy;
  499. end;
  500. { TBCStyleGraphicControl }
  501. constructor TBCStyleGraphicControl.Create(AOwner: TComponent);
  502. begin
  503. inherited Create(AOwner);
  504. FAssignStyle := TBCStyleDummyProperty.Create(Self);
  505. end;
  506. destructor TBCStyleGraphicControl.Destroy;
  507. begin
  508. FAssignStyle.Free;
  509. inherited Destroy;
  510. end;
  511. { TBCCustomControl }
  512. procedure TBCCustomControl.DoOnResize;
  513. begin
  514. inherited DoOnResize;
  515. RenderControl;
  516. end;
  517. {$IFDEF INDEBUG}
  518. function TBCCustomControl.GetDebugText: String;
  519. begin
  520. Result := EmptyStr;
  521. end;
  522. {$ENDIF}
  523. procedure TBCCustomControl.Paint;
  524. begin
  525. if (csCreating in ControlState) or IsUpdating then
  526. Exit;
  527. DrawControl;
  528. {$IFDEF INDEBUG}
  529. FPaintCount := FPaintCount +1;
  530. Canvas.Brush.Style := bsSolid;
  531. Canvas.Brush.Color := clBlack;
  532. Canvas.Font.Color := clWhite;
  533. Canvas.TextOut(1,1,'P: '+IntToStr(FPaintCount)+' '+GetDebugText);
  534. {$ENDIF}
  535. inherited Paint;
  536. end;
  537. procedure TBCCustomControl.DrawControl;
  538. begin
  539. end;
  540. procedure TBCCustomControl.RenderControl;
  541. begin
  542. end;
  543. constructor TBCCustomControl.Create(AOwner: TComponent);
  544. begin
  545. inherited Create(AOwner);
  546. {$IFDEF INDEBUG}
  547. FPaintCount := 0;
  548. {$ENDIF}
  549. end;
  550. procedure TBCCustomControl.BeginUpdate;
  551. begin
  552. FUpdateCount := FUpdateCount +1;
  553. end;
  554. procedure TBCCustomControl.EndUpdate;
  555. begin
  556. if FUpdateCount > 0 then
  557. begin
  558. FUpdateCount := FUpdateCount -1;
  559. if FUpdateCount=0 then
  560. UpdateControl;
  561. end;
  562. end;
  563. procedure TBCCustomControl.UpdateControl;
  564. begin
  565. Self.Invalidate;
  566. end;
  567. function TBCCustomControl.IsUpdating: Boolean;
  568. begin
  569. Result := FUpdateCount>0;
  570. end;
  571. { TBCProperty }
  572. procedure TBCProperty.Change(AData: PtrInt);
  573. begin
  574. if Assigned(FOnChange) then
  575. FOnChange(Self,AData);
  576. end;
  577. constructor TBCProperty.Create(AControl: TControl);
  578. begin
  579. FControl := AControl;
  580. inherited Create;
  581. end;
  582. { TBCGraphicControl }
  583. procedure TBCGraphicControl.DoOnResize;
  584. begin
  585. inherited DoOnResize;
  586. RenderControl;
  587. end;
  588. {$IFDEF INDEBUG}
  589. function TBCGraphicControl.GetDebugText: String;
  590. begin
  591. Result := EmptyStr;
  592. end;
  593. {$ENDIF}
  594. procedure TBCGraphicControl.Paint;
  595. begin
  596. //inherited Paint;
  597. if (csCreating in ControlState) or IsUpdating then
  598. Exit;
  599. DrawControl;
  600. {$IFDEF INDEBUG}
  601. FPaintCount := FPaintCount +1;
  602. Canvas.Brush.Style := bsSolid;
  603. Canvas.Brush.Color := clBlack;
  604. Canvas.Font.Color := clWhite;
  605. Canvas.TextOut(1,1,'P: '+IntToStr(FPaintCount)+' '+GetDebugText);
  606. {$ENDIF}
  607. end;
  608. procedure TBCGraphicControl.DrawControl;
  609. begin
  610. end;
  611. procedure TBCGraphicControl.RenderControl;
  612. begin
  613. end;
  614. constructor TBCGraphicControl.Create(AOwner: TComponent);
  615. begin
  616. inherited Create(AOwner);
  617. {$IFDEF INDEBUG}
  618. FPaintCount := 0;
  619. {$ENDIF}
  620. end;
  621. procedure TBCGraphicControl.BeginUpdate;
  622. begin
  623. FUpdateCount := FUpdateCount +1;
  624. end;
  625. procedure TBCGraphicControl.EndUpdate;
  626. begin
  627. if FUpdateCount > 0 then
  628. begin
  629. FUpdateCount := FUpdateCount -1;
  630. if FUpdateCount=0 then
  631. UpdateControl;
  632. end;
  633. end;
  634. procedure TBCGraphicControl.UpdateControl;
  635. begin
  636. Invalidate;
  637. end;
  638. function TBCGraphicControl.IsUpdating: Boolean;
  639. begin
  640. Result := FUpdateCount>0;
  641. end;
  642. { TBGRABitmapEx }
  643. procedure TBGRABitmapEx.Init;
  644. begin
  645. inherited Init;
  646. FNeedRender := True;
  647. FCustomData := 0;
  648. end;
  649. procedure TBGRABitmapEx.Discard;
  650. begin
  651. FNeedRender := true;
  652. SetSize(0,0);
  653. end;
  654. {$IFNDEF FPC}
  655. constructor TBGRAGraphicCtrl.Create(TheOwner: TComponent);
  656. begin
  657. inherited Create(TheOwner);
  658. FBorderSpacing := CreateControlBorderSpacing;
  659. FOnChange := Font.OnChange;
  660. Font.OnChange := FontChanged;
  661. end;
  662. function TBGRAGraphicCtrl.CreateControlBorderSpacing: TControlBorderSpacing;
  663. begin
  664. Result := TControlBorderSpacing.Create(Self);
  665. end;
  666. destructor TBGRAGraphicCtrl.Destroy;
  667. begin
  668. FreeAndNil(FBorderSpacing);
  669. inherited;
  670. end;
  671. procedure TBGRAGraphicCtrl.DoBorderSpacingChange(Sender: TObject; InnerSpaceChanged: Boolean);
  672. var
  673. IParent : ILCLControl;
  674. begin
  675. if Parent <> nil then
  676. if Supports(Parent, ILCLControl, IParent) then
  677. IParent.InvalidatePreferredSize;
  678. AdjustSize;
  679. end;
  680. procedure TBGRAGraphicCtrl.DoOnResize;
  681. begin
  682. if Assigned(OnResize) then
  683. OnResize(Self);
  684. end;
  685. procedure TBGRAGraphicCtrl.SetBorderSpacing(const AValue: TControlBorderSpacing);
  686. begin
  687. if FBorderSpacing=AValue then exit;
  688. FBorderSpacing.Assign(AValue);
  689. end;
  690. procedure TBGRAGraphicCtrl.SetColor(Value: TColor);
  691. begin
  692. if inherited Color <> Value then
  693. begin
  694. inherited Color := Value;
  695. ParentColor := False;
  696. Perform(CM_COLORCHANGED, 0, 0);
  697. Invalidate;
  698. end;
  699. end;
  700. function TBGRAGraphicCtrl.GetColor: TColor;
  701. begin
  702. Result := inherited Color;
  703. end;
  704. procedure TBGRAGraphicCtrl.EnableAutoSizing;
  705. begin
  706. end;
  707. class function TBGRAGraphicCtrl.GetControlClassDefaultSize: TSize;
  708. begin
  709. Result.CX := 75;
  710. Result.CY := 50;
  711. end;
  712. function TBGRAGraphicCtrl.GetInstance: TObject;
  713. begin
  714. result := Self;
  715. end;
  716. procedure TBGRAGraphicCtrl.CalculatePreferredSize(var PreferredWidth, PreferredHeight: integer;{%H-}WithThemeSpace: boolean);
  717. begin
  718. PreferredWidth:=0;
  719. PreferredHeight:=0;
  720. end;
  721. procedure TBGRAGraphicCtrl.MouseEnter;
  722. begin
  723. if Assigned(OnMouseEnter) then
  724. OnMouseEnter(Self);
  725. end;
  726. procedure TBGRAGraphicCtrl.MouseLeave;
  727. begin
  728. if Assigned(OnMouseLeave) then
  729. OnMouseLeave(Self);
  730. end;
  731. procedure TBGRAGraphicCtrl.TextChanged;
  732. begin
  733. // overrided;
  734. end;
  735. procedure TBGRAGraphicCtrl.FontChanged(Sender: TObject);
  736. begin
  737. ParentFont := False;
  738. DesktopFont := False;
  739. Invalidate;
  740. Perform(CM_FONTCHANGED, 0, 0);
  741. if AutoSize then
  742. begin
  743. InvalidatePreferredSize;
  744. AdjustSize;
  745. end;
  746. if Assigned(FOnChange) then
  747. FOnChange(Self);
  748. end;
  749. function TBGRAGraphicCtrl.RealGetText: TCaption;
  750. begin
  751. Result := Caption;
  752. end;
  753. procedure TBGRAGraphicCtrl.RealSetText(const Value: TCaption);
  754. begin
  755. if RealGetText = Value then Exit;
  756. Caption := Value;
  757. Perform(CM_TEXTCHANGED, 0, 0);
  758. end;
  759. procedure TBGRAGraphicCtrl.InvalidatePreferredSize;
  760. begin
  761. // Invalidate;
  762. end;
  763. function TBGRAGraphicCtrl.IsInnerBorderStored: boolean;
  764. begin
  765. Result:=BorderSpacing.InnerBorder<>0;
  766. end;
  767. procedure TBGRAGraphicCtrl.Resize;
  768. begin
  769. inherited;
  770. Invalidate;
  771. DoOnResize;
  772. end;
  773. function TBGRAGraphicCtrl.ColorIsStored: boolean;
  774. begin
  775. Result := not ParentColor;
  776. end;
  777. procedure TBGRAGraphicCtrl.SetInitialBounds(aLeft, aTop, aWidth, aHeight: integer);
  778. begin
  779. {if (csLoading in ComponentState)
  780. or ((Owner<>nil) and (csLoading in Owner.ComponentState)) then
  781. exit;}
  782. SetBounds(aLeft,aTop,aWidth,aHeight);
  783. // DoOnResize;
  784. end;
  785. procedure TBGRAGraphicCtrl.CMTextChanged(var Message: TMessage);
  786. begin
  787. inherited;
  788. TextChanged;
  789. end;
  790. procedure TBGRAGraphicCtrl.CMMouseEnter(var Message: TMessage);
  791. begin
  792. if FMouseInClient then
  793. Exit;
  794. FMouseInClient := True;
  795. // broadcast to parents first
  796. if Assigned(Parent) then
  797. Parent.Perform(CM_MOUSEENTER, 0, LParam(Self));
  798. // if it is not a child message then perform an event
  799. if (Message.LParam = 0) then
  800. MouseEnter;
  801. end;
  802. procedure TBGRAGraphicCtrl.CMMouseLeave(var Message: TMessage);
  803. begin
  804. if not FMouseInClient then
  805. Exit;
  806. FMouseInClient := False;
  807. // broadcast to parents first
  808. if Assigned(Parent) then
  809. Parent.Perform(CM_MOUSELEAVE, 0, LParam(Self));
  810. // if it is not a child message then perform an event
  811. if (Message.LParam = 0) then
  812. MouseLeave;
  813. end;
  814. {TBGRACustomCtrl}
  815. constructor TBGRACustomCtrl.Create(TheOwner: TComponent);
  816. begin
  817. inherited Create(TheOwner);
  818. FBorderSpacing := CreateControlBorderSpacing;
  819. FChildSizing:=TControlChildSizing.Create(Self);
  820. FChildSizing.OnChange := DoChildSizingChange;
  821. FOnChange := Font.OnChange;
  822. Font.OnChange := FontChanged;
  823. end;
  824. function TBGRACustomCtrl.CreateControlBorderSpacing: TControlBorderSpacing;
  825. begin
  826. Result := TControlBorderSpacing.Create(Self);
  827. end;
  828. destructor TBGRACustomCtrl.Destroy;
  829. begin
  830. FreeAndNil(FBorderSpacing);
  831. FreeAndNil(FChildSizing);
  832. inherited;
  833. end;
  834. procedure TBGRACustomCtrl.DoBorderSpacingChange(Sender: TObject; InnerSpaceChanged: Boolean);
  835. var
  836. IParent : ILCLControl;
  837. begin
  838. if Parent <> nil then
  839. if Supports(Parent, ILCLControl, IParent) then
  840. IParent.InvalidatePreferredSize;
  841. AdjustSize;
  842. end;
  843. procedure TBGRACustomCtrl.DoChildSizingChange(Sender: TObject);
  844. begin
  845. //debugln('TWinControl.DoChildSizingChange ',DbgSName(Self));
  846. if ControlCount=0 then exit;
  847. InvalidatePreferredSize;
  848. ReAlign;
  849. end;
  850. procedure TBGRACustomCtrl.DoOnResize;
  851. begin
  852. if Assigned(OnResize) then
  853. OnResize(Self);
  854. end;
  855. procedure TBGRACustomCtrl.CalculatePreferredSize(var PreferredWidth, PreferredHeight: integer;{%H-}WithThemeSpace: boolean);
  856. begin
  857. PreferredWidth:=0;
  858. PreferredHeight:=0;
  859. end;
  860. procedure TBGRACustomCtrl.MouseEnter;
  861. begin
  862. if Assigned(OnMouseEnter) then
  863. OnMouseEnter(Self);
  864. end;
  865. procedure TBGRACustomCtrl.MouseLeave;
  866. begin
  867. if Assigned(OnMouseLeave) then
  868. OnMouseLeave(Self);
  869. end;
  870. procedure TBGRACustomCtrl.TextChanged;
  871. begin
  872. // overrided;
  873. end;
  874. procedure TBGRACustomCtrl.FontChanged(Sender: TObject);
  875. begin
  876. ParentFont := False;
  877. DesktopFont := False;
  878. Invalidate;
  879. Perform(CM_FONTCHANGED, 0, 0);
  880. if AutoSize then
  881. begin
  882. InvalidatePreferredSize;
  883. AdjustSize;
  884. end;
  885. if Assigned(FOnChange) then
  886. FOnChange(Self);
  887. end;
  888. function TBGRACustomCtrl.GetDefaultDockCaption: String;
  889. begin
  890. end;
  891. function TBGRACustomCtrl.GetInstance: TObject;
  892. begin
  893. result := Self;
  894. end;
  895. function TBGRACustomCtrl.RealGetText: TCaption;
  896. begin
  897. Result := Caption;
  898. end;
  899. procedure TBGRACustomCtrl.RealSetText(const Value: TCaption);
  900. begin
  901. if RealGetText = Value then Exit;
  902. Caption := Value;
  903. Perform(CM_TEXTCHANGED, 0, 0);
  904. end;
  905. procedure TBGRACustomCtrl.EnabledChanged;
  906. begin
  907. end;
  908. procedure TBGRACustomCtrl.InvalidatePreferredSize;
  909. begin
  910. // Invalidate;
  911. end;
  912. function TBGRACustomCtrl.IsInnerBorderStored: boolean;
  913. begin
  914. Result:=BorderSpacing.InnerBorder<>0;
  915. end;
  916. procedure TBGRACustomCtrl.Resize;
  917. begin
  918. inherited;
  919. Invalidate;
  920. DoOnResize;
  921. end;
  922. procedure TBGRACustomCtrl.SetBorderSpacing(const AValue: TControlBorderSpacing);
  923. begin
  924. if FBorderSpacing=AValue then exit;
  925. FBorderSpacing.Assign(AValue);
  926. end;
  927. procedure TBGRACustomCtrl.SetChildSizing(const AValue: TControlChildSizing);
  928. begin
  929. if (FChildSizing=AValue) then exit;
  930. FChildSizing.Assign(AValue);
  931. end;
  932. procedure TBGRACustomCtrl.SetColor(Value: TColor);
  933. begin
  934. if inherited Color <> Value then
  935. begin
  936. inherited Color := Value;
  937. ParentColor := False;
  938. Perform(CM_COLORCHANGED, 0, 0);
  939. Invalidate;
  940. end;
  941. end;
  942. function TBGRACustomCtrl.GetColor : TColor;
  943. begin
  944. Result := inherited Color;
  945. end;
  946. procedure TBGRACustomCtrl.UTF8KeyPress(var UTF8Key: {$IFDEF FPC}TUTF8Char{$ELSE}String{$ENDIF});
  947. begin
  948. end;
  949. procedure TBGRACustomCtrl.EnableAutoSizing;
  950. begin
  951. end;
  952. function TBGRACustomCtrl.ColorIsStored: boolean;
  953. begin
  954. Result := not ParentColor;
  955. end;
  956. procedure TBGRACustomCtrl.SetInitialBounds(aLeft, aTop, aWidth, aHeight: integer);
  957. begin
  958. {if (csLoading in ComponentState)
  959. or ((Owner<>nil) and (csLoading in Owner.ComponentState)) then
  960. exit;}
  961. SetBounds(aLeft,aTop,aWidth,aHeight);
  962. // DoOnResize;
  963. end;
  964. class function TBGRACustomCtrl.GetControlClassDefaultSize: TSize;
  965. begin
  966. Result.CX := 75;
  967. Result.CY := 50;
  968. end;
  969. procedure TBGRACustomCtrl.CMTextChanged(var Message: TMessage);
  970. begin
  971. TextChanged;
  972. end;
  973. procedure TBGRACustomCtrl.CMMouseEnter(var Message: TMessage);
  974. begin
  975. if FMouseInClient then
  976. Exit;
  977. FMouseInClient := True;
  978. // broadcast to parents first
  979. if Assigned(Parent) then
  980. Parent.Perform(CM_MOUSEENTER, 0, LParam(Self));
  981. // if it is not a child message then perform an event
  982. if (Message.LParam = 0) then
  983. MouseEnter;
  984. end;
  985. procedure TBGRACustomCtrl.CMMouseLeave(var Message: TMessage);
  986. begin
  987. if not FMouseInClient then
  988. Exit;
  989. FMouseInClient := False;
  990. // broadcast to parents first
  991. if Assigned(Parent) then
  992. Parent.Perform(CM_MOUSELEAVE, 0, LParam(Self));
  993. // if it is not a child message then perform an event
  994. if (Message.LParam = 0) then
  995. MouseLeave;
  996. end;
  997. {TBGRACustomPanel}
  998. constructor TBGRACustomPanel.Create(TheOwner: TComponent);
  999. begin
  1000. inherited Create(TheOwner);
  1001. FBorderSpacing := CreateControlBorderSpacing;
  1002. FChildSizing:=TControlChildSizing.Create(Self);
  1003. FChildSizing.OnChange := DoChildSizingChange;
  1004. FOnChange := Font.OnChange;
  1005. Font.OnChange := FontChanged;
  1006. end;
  1007. function TBGRACustomPanel.CreateControlBorderSpacing: TControlBorderSpacing;
  1008. begin
  1009. Result := TControlBorderSpacing.Create(Self);
  1010. end;
  1011. destructor TBGRACustomPanel.Destroy;
  1012. begin
  1013. FreeAndNil(FBorderSpacing);
  1014. FreeAndNil(FChildSizing);
  1015. inherited;
  1016. end;
  1017. procedure TBGRACustomPanel.DoBorderSpacingChange(Sender: TObject; InnerSpaceChanged: Boolean);
  1018. var
  1019. IParent : ILCLControl;
  1020. begin
  1021. if Parent <> nil then
  1022. if Supports(Parent, ILCLControl, IParent) then
  1023. IParent.InvalidatePreferredSize;
  1024. AdjustSize;
  1025. end;
  1026. procedure TBGRACustomPanel.DoChildSizingChange(Sender: TObject);
  1027. begin
  1028. //debugln('TWinControl.DoChildSizingChange ',DbgSName(Self));
  1029. if ControlCount=0 then exit;
  1030. InvalidatePreferredSize;
  1031. ReAlign;
  1032. end;
  1033. procedure TBGRACustomPanel.DoOnResize;
  1034. begin
  1035. if Assigned(OnResize) then
  1036. OnResize(Self);
  1037. end;
  1038. procedure TBGRACustomPanel.CalculatePreferredSize(var PreferredWidth, PreferredHeight: integer;{%H-}WithThemeSpace: boolean);
  1039. begin
  1040. PreferredWidth:=0;
  1041. PreferredHeight:=0;
  1042. end;
  1043. procedure TBGRACustomPanel.MouseEnter;
  1044. begin
  1045. if Assigned(OnMouseEnter) then
  1046. OnMouseEnter(Self);
  1047. end;
  1048. procedure TBGRACustomPanel.MouseLeave;
  1049. begin
  1050. if Assigned(OnMouseLeave) then
  1051. OnMouseLeave(Self);
  1052. end;
  1053. procedure TBGRACustomPanel.TextChanged;
  1054. begin
  1055. // overrided;
  1056. end;
  1057. procedure TBGRACustomPanel.FontChanged(Sender: TObject);
  1058. begin
  1059. ParentFont := False;
  1060. DesktopFont := False;
  1061. Invalidate;
  1062. Perform(CM_FONTCHANGED, 0, 0);
  1063. if AutoSize then
  1064. begin
  1065. InvalidatePreferredSize;
  1066. AdjustSize;
  1067. end;
  1068. if Assigned(FOnChange) then
  1069. FOnChange(Self);
  1070. end;
  1071. function TBGRACustomPanel.GetDefaultDockCaption: String;
  1072. begin
  1073. end;
  1074. function TBGRACustomPanel.GetInstance: TObject;
  1075. begin
  1076. result := Self;
  1077. end;
  1078. function TBGRACustomPanel.RealGetText: TCaption;
  1079. begin
  1080. Result := Caption;
  1081. end;
  1082. procedure TBGRACustomPanel.RealSetText(const Value: TCaption);
  1083. begin
  1084. if RealGetText = Value then Exit;
  1085. Caption := Value;
  1086. Perform(CM_TEXTCHANGED, 0, 0);
  1087. end;
  1088. procedure TBGRACustomPanel.EnabledChanged;
  1089. begin
  1090. end;
  1091. procedure TBGRACustomPanel.InvalidatePreferredSize;
  1092. begin
  1093. // Invalidate;
  1094. end;
  1095. function TBGRACustomPanel.IsInnerBorderStored: boolean;
  1096. begin
  1097. Result:=BorderSpacing.InnerBorder<>0;
  1098. end;
  1099. procedure TBGRACustomPanel.Resize;
  1100. begin
  1101. inherited;
  1102. Invalidate;
  1103. DoOnResize;
  1104. end;
  1105. procedure TBGRACustomPanel.SetBorderSpacing(const AValue: TControlBorderSpacing);
  1106. begin
  1107. if FBorderSpacing=AValue then exit;
  1108. FBorderSpacing.Assign(AValue);
  1109. end;
  1110. procedure TBGRACustomPanel.SetChildSizing(const AValue: TControlChildSizing);
  1111. begin
  1112. if (FChildSizing=AValue) then exit;
  1113. FChildSizing.Assign(AValue);
  1114. end;
  1115. procedure TBGRACustomPanel.SetColor(Value: TColor);
  1116. begin
  1117. if inherited Color <> Value then
  1118. begin
  1119. inherited Color := Value;
  1120. ParentColor := False;
  1121. Perform(CM_COLORCHANGED, 0, 0);
  1122. Invalidate;
  1123. end;
  1124. end;
  1125. function TBGRACustomPanel.GetColor : TColor;
  1126. begin
  1127. Result := inherited Color;
  1128. end;
  1129. procedure TBGRACustomPanel.UTF8KeyPress(var UTF8Key: {$IFDEF FPC}TUTF8Char{$ELSE}String{$ENDIF});
  1130. begin
  1131. end;
  1132. procedure TBGRACustomPanel.EnableAutoSizing;
  1133. begin
  1134. end;
  1135. function TBGRACustomPanel.ColorIsStored: boolean;
  1136. begin
  1137. Result := not ParentColor;
  1138. end;
  1139. procedure TBGRACustomPanel.SetInitialBounds(aLeft, aTop, aWidth, aHeight: integer);
  1140. begin
  1141. {if (csLoading in ComponentState)
  1142. or ((Owner<>nil) and (csLoading in Owner.ComponentState)) then
  1143. exit;}
  1144. SetBounds(aLeft,aTop,aWidth,aHeight);
  1145. // DoOnResize;
  1146. end;
  1147. class function TBGRACustomPanel.GetControlClassDefaultSize: TSize;
  1148. begin
  1149. Result.CX := 75;
  1150. Result.CY := 50;
  1151. end;
  1152. procedure TBGRACustomPanel.CMTextChanged(var Message: TMessage);
  1153. begin
  1154. TextChanged;
  1155. end;
  1156. procedure TBGRACustomPanel.CMMouseEnter(var Message: TMessage);
  1157. begin
  1158. if FMouseInClient then
  1159. Exit;
  1160. FMouseInClient := True;
  1161. // broadcast to parents first
  1162. if Assigned(Parent) then
  1163. Parent.Perform(CM_MOUSEENTER, 0, LParam(Self));
  1164. // if it is not a child message then perform an event
  1165. if (Message.LParam = 0) then
  1166. MouseEnter;
  1167. end;
  1168. procedure TBGRACustomPanel.CMMouseLeave(var Message: TMessage);
  1169. begin
  1170. if not FMouseInClient then
  1171. Exit;
  1172. FMouseInClient := False;
  1173. // broadcast to parents first
  1174. if Assigned(Parent) then
  1175. Parent.Perform(CM_MOUSELEAVE, 0, LParam(Self));
  1176. // if it is not a child message then perform an event
  1177. if (Message.LParam = 0) then
  1178. MouseLeave;
  1179. end;
  1180. {$ENDIF}
  1181. {$IFNDEF FPC}
  1182. { TControlBorderSpacing }
  1183. procedure TControlBorderSpacing.SetAround(const AValue: TSpacingSize);
  1184. begin
  1185. if FAround=AValue then exit;
  1186. FAround:=AValue;
  1187. Change(false);
  1188. end;
  1189. function TControlBorderSpacing.IsAroundStored: boolean;
  1190. begin
  1191. if FDefault = nil
  1192. then Result := FAround <> 0
  1193. else Result := FAround <> FDefault^.Around;
  1194. end;
  1195. function TControlBorderSpacing.IsBottomStored: boolean;
  1196. begin
  1197. if FDefault = nil
  1198. then Result := FBottom <> 0
  1199. else Result := FBottom <> FDefault^.Bottom;
  1200. end;
  1201. function TControlBorderSpacing.IsInnerBorderStored: boolean;
  1202. begin
  1203. if Control <> nil then
  1204. Result:=Control.IsInnerBorderStored
  1205. else
  1206. Result:=True;
  1207. end;
  1208. function TControlBorderSpacing.IsLeftStored: boolean;
  1209. begin
  1210. if FDefault = nil
  1211. then Result := FLeft <> 0
  1212. else Result := FLeft <> FDefault^.Left;
  1213. end;
  1214. function TControlBorderSpacing.IsRightStored: boolean;
  1215. begin
  1216. if FDefault = nil
  1217. then Result := FRight <> 0
  1218. else Result := FRight <> FDefault^.Right;
  1219. end;
  1220. function TControlBorderSpacing.IsTopStored: boolean;
  1221. begin
  1222. if FDefault = nil
  1223. then Result := FTop <> 0
  1224. else Result := FTop <> FDefault^.Top;
  1225. end;
  1226. procedure TControlBorderSpacing.SetBottom(const AValue: TSpacingSize);
  1227. begin
  1228. if FBottom=AValue then exit;
  1229. FBottom:=AValue;
  1230. Change(false);
  1231. end;
  1232. procedure TControlBorderSpacing.SetCellAlignHorizontal(
  1233. const AValue: TControlCellAlign);
  1234. begin
  1235. if FCellAlignHorizontal=AValue then exit;
  1236. FCellAlignHorizontal:=AValue;
  1237. Change(false);
  1238. end;
  1239. procedure TControlBorderSpacing.SetCellAlignVertical(
  1240. const AValue: TControlCellAlign);
  1241. begin
  1242. if FCellAlignVertical=AValue then exit;
  1243. FCellAlignVertical:=AValue;
  1244. Change(false);
  1245. end;
  1246. procedure TControlBorderSpacing.SetInnerBorder(const AValue: Integer);
  1247. begin
  1248. if FInnerBorder=AValue then exit;
  1249. FInnerBorder:=AValue;
  1250. if Control<>nil then Control.InvalidatePreferredSize;
  1251. Change(true);
  1252. end;
  1253. procedure TControlBorderSpacing.SetLeft(const AValue: TSpacingSize);
  1254. begin
  1255. if FLeft=AValue then exit;
  1256. FLeft:=AValue;
  1257. Change(false);
  1258. end;
  1259. procedure TControlBorderSpacing.SetRight(const AValue: TSpacingSize);
  1260. begin
  1261. if FRight=AValue then exit;
  1262. FRight:=AValue;
  1263. Change(false);
  1264. end;
  1265. procedure TControlBorderSpacing.SetSpace(Kind: TAnchorKind;
  1266. const AValue: integer);
  1267. begin
  1268. case Kind of
  1269. akLeft: Left:=AValue;
  1270. akTop: Top:=AValue;
  1271. akBottom: Bottom:=AValue;
  1272. akRight: Right:=AValue;
  1273. end;
  1274. end;
  1275. procedure TControlBorderSpacing.SetTop(const AValue: TSpacingSize);
  1276. begin
  1277. if FTop=AValue then exit;
  1278. FTop:=AValue;
  1279. Change(false);
  1280. end;
  1281. constructor TControlBorderSpacing.Create(OwnerControl: ILCLControl; ADefault: PControlBorderSpacingDefault);
  1282. begin
  1283. FControl := OwnerControl;
  1284. FDefault := ADefault;
  1285. if ADefault <> nil then
  1286. begin
  1287. FLeft := ADefault^.Left;
  1288. FRight := ADefault^.Right;
  1289. FTop := ADefault^.Top;
  1290. FBottom := ADefault^.Bottom;
  1291. FAround := ADefault^.Around;
  1292. end;
  1293. FCellAlignHorizontal := ccaFill;
  1294. FCellAlignVertical := ccaFill;
  1295. inherited Create;
  1296. end;
  1297. procedure TControlBorderSpacing.Assign(Source: TPersistent);
  1298. var
  1299. SrcSpacing: TControlBorderSpacing;
  1300. begin
  1301. if Source is TControlBorderSpacing then begin
  1302. SrcSpacing:=TControlBorderSpacing(Source);
  1303. if IsEqual(SrcSpacing) then exit;
  1304. FAround:=SrcSpacing.Around;
  1305. FBottom:=SrcSpacing.Bottom;
  1306. FLeft:=SrcSpacing.Left;
  1307. FRight:=SrcSpacing.Right;
  1308. FTop:=SrcSpacing.Top;
  1309. FInnerBorder:=SrcSpacing.InnerBorder;
  1310. FCellAlignHorizontal:=SrcSpacing.CellAlignHorizontal;
  1311. FCellAlignVertical:=SrcSpacing.CellAlignVertical;
  1312. Change(false);
  1313. end else
  1314. inherited Assign(Source);
  1315. end;
  1316. procedure TControlBorderSpacing.AssignTo(Dest: TPersistent);
  1317. begin
  1318. Dest.Assign(Self);
  1319. end;
  1320. procedure TControlBorderSpacing.AutoAdjustLayout(const AXProportion,
  1321. AYProportion: Double);
  1322. procedure Scale(var Value: Integer; const Proportion: Double; var Changed: Boolean);
  1323. begin
  1324. if Value<>0 then
  1325. begin
  1326. Value := Round(Value * Proportion);
  1327. Changed := True;
  1328. end;
  1329. end;
  1330. var
  1331. InnerChanged, OuterChanged: Boolean;
  1332. begin
  1333. InnerChanged := False;
  1334. OuterChanged := False;
  1335. Scale(FAround, AXProportion, OuterChanged);
  1336. Scale(FInnerBorder, AXProportion, InnerChanged);
  1337. Scale(FLeft, AXProportion, OuterChanged);
  1338. Scale(FTop, AYProportion, OuterChanged);
  1339. Scale(FRight, AXProportion, OuterChanged);
  1340. Scale(FBottom, AYProportion, OuterChanged);
  1341. if OuterChanged or InnerChanged then
  1342. begin
  1343. if Control<>nil then Control.InvalidatePreferredSize;
  1344. Change(InnerChanged);
  1345. end;
  1346. end;
  1347. function TControlBorderSpacing.IsEqual(Spacing: TControlBorderSpacing
  1348. ): boolean;
  1349. begin
  1350. Result:=(FAround=Spacing.Around)
  1351. and (FBottom=Spacing.Bottom)
  1352. and (FLeft=Spacing.Left)
  1353. and (FRight=Spacing.Right)
  1354. and (FTop=Spacing.Top);
  1355. end;
  1356. procedure TControlBorderSpacing.GetSpaceAround(var SpaceAround: TRect);
  1357. begin
  1358. SpaceAround.Left:=Left+Around;
  1359. SpaceAround.Top:=Top+Around;
  1360. SpaceAround.Right:=Right+Around;
  1361. SpaceAround.Bottom:=Bottom+Around;
  1362. end;
  1363. function TControlBorderSpacing.GetSideSpace(Kind: TAnchorKind): Integer;
  1364. begin
  1365. Result:=Around+GetSpace(Kind);
  1366. end;
  1367. function TControlBorderSpacing.GetSpace(Kind: TAnchorKind): Integer;
  1368. begin
  1369. case Kind of
  1370. akLeft: Result:=Left;
  1371. akTop: Result:=Top;
  1372. akRight: Result:=Right;
  1373. akBottom: Result:=Bottom;
  1374. end;
  1375. end;
  1376. procedure TControlBorderSpacing.Change(InnerSpaceChanged: Boolean);
  1377. begin
  1378. if FControl <> nil then
  1379. FControl.DoBorderSpacingChange(Self,InnerSpaceChanged);
  1380. if Assigned(OnChange) then OnChange(Self);
  1381. end;
  1382. function TControlBorderSpacing.GetAroundBottom: Integer;
  1383. begin
  1384. Result := Around+Bottom;
  1385. end;
  1386. function TControlBorderSpacing.GetAroundLeft: Integer;
  1387. begin
  1388. Result := Around+Left;
  1389. end;
  1390. function TControlBorderSpacing.GetAroundRight: Integer;
  1391. begin
  1392. Result := Around+Right;
  1393. end;
  1394. function TControlBorderSpacing.GetAroundTop: Integer;
  1395. begin
  1396. Result := Around+Top;
  1397. end;
  1398. function TControlBorderSpacing.GetControlBottom: Integer;
  1399. begin
  1400. if (FControl<>nil) and (FControl.GetInstance<>nil) and FControl.GetInstance.InheritsFrom(TControl) then
  1401. Result := TControl(FControl.GetInstance).Top +TControl(FControl.GetInstance).Height +Around+Bottom
  1402. else
  1403. Result := 0;
  1404. end;
  1405. function TControlBorderSpacing.GetControlHeight: Integer;
  1406. begin
  1407. if (FControl<>nil) and (FControl.GetInstance<>nil) and FControl.GetInstance.InheritsFrom(TControl) then
  1408. Result := TControl(FControl.GetInstance).Height+Around*2+Top+Bottom
  1409. else
  1410. Result := 0;
  1411. end;
  1412. function TControlBorderSpacing.GetControlLeft: Integer;
  1413. begin
  1414. if (FControl<>nil) and (FControl.GetInstance<>nil) and FControl.GetInstance.InheritsFrom(TControl) then
  1415. Result := TControl(FControl.GetInstance).Left-Around-Left
  1416. else
  1417. Result := 0;
  1418. end;
  1419. function TControlBorderSpacing.GetControlRight: Integer;
  1420. begin
  1421. if (FControl<>nil) and (FControl.GetInstance<>nil) and FControl.GetInstance.InheritsFrom(TControl) then
  1422. Result := TControl(FControl.GetInstance).Left+TControl(FControl.GetInstance).Width+Around+Right
  1423. else
  1424. Result := 0;
  1425. end;
  1426. function TControlBorderSpacing.GetControlTop: Integer;
  1427. begin
  1428. if (FControl<>nil) and (FControl.GetInstance<>nil) and FControl.GetInstance.InheritsFrom(TControl) then
  1429. Result := TControl(FControl.GetInstance).Top-Around-Top
  1430. else
  1431. Result := 0;
  1432. end;
  1433. function TControlBorderSpacing.GetControlWidth: Integer;
  1434. begin
  1435. if (FControl<>nil) and (FControl.GetInstance<>nil) and FControl.GetInstance.InheritsFrom(TControl) then
  1436. Result := TControl(FControl.GetInstance).Width+Around*2+Left+Right
  1437. else
  1438. Result := 0;
  1439. end;
  1440. { TControlChildSizing }
  1441. procedure TControlChildSizing.SetEnlargeHorizontal(
  1442. const AValue: TChildControlResizeStyle);
  1443. begin
  1444. if FEnlargeHorizontal=AValue then exit;
  1445. FEnlargeHorizontal:=AValue;
  1446. Change;
  1447. end;
  1448. procedure TControlChildSizing.SetControlsPerLine(const AValue: integer);
  1449. begin
  1450. if FControlsPerLine=AValue then exit;
  1451. FControlsPerLine:=AValue;
  1452. Change;
  1453. end;
  1454. procedure TControlChildSizing.SetEnlargeVertical(
  1455. const AValue: TChildControlResizeStyle);
  1456. begin
  1457. if FEnlargeVertical=AValue then exit;
  1458. FEnlargeVertical:=AValue;
  1459. Change;
  1460. end;
  1461. procedure TControlChildSizing.SetHorizontalSpacing(const AValue: integer);
  1462. begin
  1463. if FHorizontalSpacing=AValue then exit;
  1464. FHorizontalSpacing:=AValue;
  1465. Change;
  1466. end;
  1467. procedure TControlChildSizing.SetLayout(const AValue: TControlChildrenLayout);
  1468. begin
  1469. if FLayout=AValue then exit;
  1470. FLayout:=AValue;
  1471. //debugln('TControlChildSizing.SetLayout ',DbgSName(Control));
  1472. Change;
  1473. end;
  1474. procedure TControlChildSizing.SetLeftRightSpacing(const AValue: integer);
  1475. begin
  1476. if FLeftRightSpacing=AValue then exit;
  1477. FLeftRightSpacing:=AValue;
  1478. Change;
  1479. end;
  1480. procedure TControlChildSizing.SetShrinkHorizontal(
  1481. const AValue: TChildControlResizeStyle);
  1482. begin
  1483. if FShrinkHorizontal=AValue then exit;
  1484. FShrinkHorizontal:=AValue;
  1485. Change;
  1486. end;
  1487. procedure TControlChildSizing.SetShrinkVertical(
  1488. const AValue: TChildControlResizeStyle);
  1489. begin
  1490. if FShrinkVertical=AValue then exit;
  1491. FShrinkVertical:=AValue;
  1492. Change;
  1493. end;
  1494. procedure TControlChildSizing.SetTopBottomSpacing(const AValue: integer);
  1495. begin
  1496. if FTopBottomSpacing=AValue then exit;
  1497. FTopBottomSpacing:=AValue;
  1498. Change;
  1499. end;
  1500. procedure TControlChildSizing.SetVerticalSpacing(const AValue: integer);
  1501. begin
  1502. if FVerticalSpacing=AValue then exit;
  1503. FVerticalSpacing:=AValue;
  1504. Change;
  1505. end;
  1506. constructor TControlChildSizing.Create(OwnerControl: ILCLControl);
  1507. begin
  1508. inherited Create;
  1509. FControl := OwnerControl;
  1510. FLayout := cclNone;
  1511. FEnlargeHorizontal :=crsAnchorAligning;
  1512. FEnlargeVertical := crsAnchorAligning;
  1513. FShrinkHorizontal := crsAnchorAligning;
  1514. FShrinkVertical := crsAnchorAligning;
  1515. end;
  1516. procedure TControlChildSizing.Assign(Source: TPersistent);
  1517. var
  1518. SrcSizing: TControlChildSizing;
  1519. begin
  1520. if Source is TControlChildSizing then begin
  1521. SrcSizing:=TControlChildSizing(Source);
  1522. if IsEqual(SrcSizing) then exit;
  1523. FEnlargeHorizontal:=SrcSizing.EnlargeHorizontal;
  1524. FEnlargeVertical:=SrcSizing.EnlargeVertical;
  1525. FShrinkHorizontal:=SrcSizing.ShrinkHorizontal;
  1526. FShrinkVertical:=SrcSizing.ShrinkVertical;
  1527. FEnlargeHorizontal:=SrcSizing.EnlargeHorizontal;
  1528. FEnlargeVertical:=SrcSizing.EnlargeVertical;
  1529. FShrinkHorizontal:=SrcSizing.ShrinkHorizontal;
  1530. FShrinkVertical:=SrcSizing.ShrinkVertical;
  1531. FControlsPerLine:=SrcSizing.ControlsPerLine;
  1532. FLayout:=SrcSizing.Layout;
  1533. FLeftRightSpacing:=SrcSizing.LeftRightSpacing;
  1534. FTopBottomSpacing:=SrcSizing.TopBottomSpacing;
  1535. FHorizontalSpacing:=SrcSizing.HorizontalSpacing;
  1536. FVerticalSpacing:=SrcSizing.VerticalSpacing;
  1537. Change;
  1538. end else
  1539. inherited Assign(Source);
  1540. end;
  1541. procedure TControlChildSizing.AssignTo(Dest: TPersistent);
  1542. begin
  1543. Dest.Assign(Self);
  1544. end;
  1545. function TControlChildSizing.IsEqual(Sizing: TControlChildSizing): boolean;
  1546. begin
  1547. Result:=(FEnlargeHorizontal=Sizing.EnlargeHorizontal)
  1548. and (FEnlargeVertical=Sizing.EnlargeVertical)
  1549. and (FShrinkHorizontal=Sizing.ShrinkHorizontal)
  1550. and (FShrinkVertical=Sizing.ShrinkVertical)
  1551. and (FEnlargeHorizontal=Sizing.EnlargeHorizontal)
  1552. and (FEnlargeVertical=Sizing.EnlargeVertical)
  1553. and (FShrinkHorizontal=Sizing.ShrinkHorizontal)
  1554. and (FShrinkVertical=Sizing.ShrinkVertical)
  1555. and (FControlsPerLine=Sizing.ControlsPerLine)
  1556. and (FLayout=Sizing.Layout)
  1557. and (FLeftRightSpacing=Sizing.LeftRightSpacing)
  1558. and (FTopBottomSpacing=Sizing.TopBottomSpacing)
  1559. and (FHorizontalSpacing=Sizing.HorizontalSpacing)
  1560. and (FVerticalSpacing=Sizing.VerticalSpacing);
  1561. end;
  1562. procedure TControlChildSizing.SetGridSpacing(Spacing: integer);
  1563. begin
  1564. if (LeftRightSpacing=Spacing)
  1565. and (TopBottomSpacing=Spacing)
  1566. and (HorizontalSpacing=Spacing)
  1567. and (VerticalSpacing=Spacing) then exit;
  1568. fLeftRightSpacing:=Spacing;
  1569. fTopBottomSpacing:=Spacing;
  1570. fHorizontalSpacing:=Spacing;
  1571. fVerticalSpacing:=Spacing;
  1572. Change;
  1573. end;
  1574. procedure TControlChildSizing.Change;
  1575. begin
  1576. if (FControl<>nil) and (FControl.GetInstance<>nil) and FControl.GetInstance.InheritsFrom(TBGRACustomCtrl) then
  1577. TBGRACustomCtrl(FControl.GetInstance).DoChildSizingChange(Self);
  1578. if Assigned(FOnChange) then
  1579. FOnChange(Self);
  1580. end;
  1581. {$ENDIF}
  1582. end.