bcimagebutton.pas 40 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454
  1. // SPDX-License-Identifier: LGPL-3.0-linking-exception
  2. {
  3. Created by BGRA Controls Team
  4. Dibo, Circular, lainz (007) and contributors.
  5. For detailed information see readme.txt
  6. Site: https://sourceforge.net/p/bgra-controls/
  7. Wiki: http://wiki.lazarus.freepascal.org/BGRAControls
  8. Forum: http://forum.lazarus.freepascal.org/index.php/board,46.0.html
  9. }
  10. {******************************* CONTRIBUTOR(S) ******************************
  11. - Edivando S. Santos Brasil | [email protected]
  12. (Compatibility with delphi VCL 11/2018)
  13. ***************************** END CONTRIBUTOR(S) *****************************}
  14. unit BCImageButton;
  15. {$I bgracontrols.inc}
  16. interface
  17. uses
  18. Classes, SysUtils, Forms, Controls, Graphics,
  19. {$IFDEF FPC}{$ifdef Windows}Windows,{$endif}LCLType, LResources, LMessages,{$ENDIF} ExtCtrls,
  20. Types,
  21. {$IFNDEF FPC}Windows, Messages, BGRAGraphics, GraphType, FPImage, {$ENDIF}
  22. { BGRAControls }
  23. BCBaseCtrls, BCEffect,
  24. { BGRABitmap }
  25. BGRABitmap, BGRABitmapTypes, BGRASliceScaling;
  26. {off $DEFINE DEBUG}
  27. function CalculateAspectRatioH(W1, H1, W2: integer): integer; //result H2
  28. function CalculateAspectRatioW(W1, H1, H2: integer): integer; //result W2
  29. function CalculateDestRect(ImageW, ImageH, DestW, DestH: integer;
  30. Stretch, Proportional, Center: boolean): TRect;
  31. procedure AssignFontToBGRA(Source: TFont; Dest: TBGRABitmap);
  32. type
  33. TBCGraphicButtonState = (gbsNormal, gbsHover, gbsActive, gbsDisabled);
  34. TOnRenderControl = procedure(Sender: TObject; Bitmap: TBGRABitmap;
  35. State: TBCGraphicButtonState) of object;
  36. type
  37. { TBCGraphicButton }
  38. TBCGraphicButton = class(TBCGraphicControl)
  39. protected
  40. FState: TBCGraphicButtonState;
  41. FModalResult: TModalResult;
  42. protected
  43. procedure DoClick; virtual;
  44. procedure DoMouseDown; virtual;
  45. procedure DoMouseUp; virtual;
  46. procedure DoMouseEnter; virtual;
  47. procedure DoMouseLeave; virtual;
  48. procedure DoMouseMove({%H-}x, {%H-}y: integer); virtual;
  49. protected
  50. procedure Click; override;
  51. procedure MouseDown(Button: TMouseButton; Shift: TShiftState;
  52. X, Y: integer); override;
  53. procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: integer); override;
  54. procedure MouseEnter; override;
  55. procedure MouseLeave; override;
  56. procedure MouseMove(Shift: TShiftState; X,Y: Integer); override;
  57. public
  58. property ModalResult: TModalResult
  59. read FModalResult write FModalResult default mrNone;
  60. end;
  61. { TBCXButton }
  62. TBCXButton = class(TBCGraphicButton)
  63. protected
  64. FOnRenderControl: TOnRenderControl;
  65. FBGRANormal, FBGRAHover, FBGRAActive, FBGRADisabled: TBGRABitmap;
  66. protected
  67. class function GetControlClassDefaultSize: TSize; override;
  68. procedure DrawControl; override;
  69. procedure RenderControl; override;
  70. public
  71. constructor Create(AOwner: TComponent); override;
  72. destructor Destroy; override;
  73. published
  74. property OnRenderControl: TOnRenderControl
  75. read FOnRenderControl write FOnRenderControl;
  76. published
  77. property Action;
  78. property Align;
  79. property Anchors;
  80. property AutoSize;
  81. property BidiMode;
  82. property BorderSpacing;
  83. property Caption;
  84. property Color;
  85. property Constraints;
  86. property DragCursor;
  87. property DragKind;
  88. property DragMode;
  89. property Enabled;
  90. property Font;
  91. property ParentBidiMode;
  92. property ModalResult;
  93. {$IFDEF FPC}
  94. property OnChangeBounds;
  95. {$ENDIF}
  96. property OnClick;
  97. property OnContextPopup;
  98. property OnDragDrop;
  99. property OnDragOver;
  100. property OnEndDrag;
  101. property OnMouseDown;
  102. property OnMouseEnter;
  103. property OnMouseLeave;
  104. property OnMouseMove;
  105. property OnMouseUp;
  106. property OnMouseWheel;
  107. property OnMouseWheelDown;
  108. property OnMouseWheelUp;
  109. property OnResize;
  110. property OnStartDrag;
  111. property ParentFont;
  112. property ParentShowHint;
  113. property PopupMenu;
  114. property ShowHint;
  115. property Visible;
  116. end;
  117. { TBCSliceScalingOptions }
  118. TBCCustomSliceScalingOptions = class(TPersistent)
  119. protected
  120. FOwner: TControl;
  121. FBitmap: TBGRABitmap;
  122. FAutoDetectRepeat, FRepeatTop, FRepeatLeft, FRepeatMiddleHorizontal,
  123. FRepeatMiddleVertical, FRepeatRight, FRepeatBottom: boolean;
  124. FMarginTop, FMarginRight, FMarginBottom, FMarginLeft, FNumberOfItems: integer;
  125. FDirection: TSliceScalingDirection;
  126. FDrawMode: TDrawMode;
  127. FResampleMode: TResampleMode;
  128. FResampleFilter: TResampleFilter;
  129. private
  130. procedure SetFBitmap(AValue: TBGRABitmap);
  131. procedure SetFMarginBottom(AValue: integer);
  132. procedure SetFMarginLeft(AValue: integer);
  133. procedure SetFMarginRight(AValue: integer);
  134. procedure SetFMarginTop(AValue: integer);
  135. procedure SetFAutoDetectRepeat(AValue: boolean);
  136. procedure SetFDirection(AValue: TSliceScalingDirection);
  137. procedure SetFDrawMode(AValue: TDrawMode);
  138. procedure SetFNumberOfItems(AValue: integer);
  139. procedure SetFRepeatBottom(AValue: boolean);
  140. procedure SetFRepeatLeft(AValue: boolean);
  141. procedure SetFRepeatMiddleHorizontal(AValue: boolean);
  142. procedure SetFRepeatMiddleVertical(AValue: boolean);
  143. procedure SetFRepeatRight(AValue: boolean);
  144. procedure SetFRepeatTop(AValue: boolean);
  145. procedure SetFResampleFilter(AValue: TResampleFilter);
  146. procedure SetFResampleMode(AValue: TResampleMode);
  147. public
  148. constructor Create(AOwner: TControl);
  149. destructor Destroy; override;
  150. published
  151. property Bitmap: TBGRABitmap read FBitmap write SetFBitmap;
  152. property AutoDetectRepeat: boolean read FAutoDetectRepeat
  153. write SetFAutoDetectRepeat default False;
  154. property RepeatTop: boolean read FRepeatTop write SetFRepeatTop default False;
  155. property RepeatLeft: boolean read FRepeatLeft write SetFRepeatLeft default False;
  156. property RepeatMiddleHorizontal: boolean
  157. read FRepeatMiddleHorizontal write SetFRepeatMiddleHorizontal default False;
  158. property RepeatMiddleVertical: boolean read FRepeatMiddleVertical
  159. write SetFRepeatMiddleVertical default False;
  160. property RepeatRight: boolean read FRepeatRight write SetFRepeatRight default False;
  161. property RepeatBottom: boolean
  162. read FRepeatBottom write SetFRepeatBottom default False;
  163. property MarginTop: integer read FMarginTop write SetFMarginTop default 0;
  164. property MarginRight: integer read FMarginRight write SetFMarginRight default 0;
  165. property MarginBottom: integer read FMarginBottom write SetFMarginBottom default 0;
  166. property MarginLeft: integer read FMarginLeft write SetFMarginLeft default 0;
  167. property NumberOfItems: integer
  168. read FNumberOfItems write SetFNumberOfItems default 1;
  169. property Direction: TSliceScalingDirection read FDirection write SetFDirection;
  170. property DrawMode: TDrawMode read FDrawMode write SetFDrawMode default
  171. dmDrawWithTransparency;
  172. property ResampleMode: TResampleMode read FResampleMode
  173. write SetFResampleMode default rmFineResample;
  174. property ResampleFilter: TResampleFilter read FResampleFilter
  175. write SetFResampleFilter default rfBestQuality;
  176. end;
  177. { TBCImageButtonSliceScalingOptions }
  178. TBCImageButtonSliceScalingOptions = class(TBCCustomSliceScalingOptions)
  179. private
  180. procedure SetFCenter(AValue: boolean);
  181. procedure SetFProportional(AValue: boolean);
  182. procedure SetFStretch(AValue: boolean);
  183. protected
  184. FCenter, FStretch, FProportional: boolean;
  185. published
  186. property NumberOfItems: integer read FNumberOfItems default 4;
  187. property Center: boolean read FCenter write SetFCenter default True;
  188. property Stretch: boolean read FStretch write SetFStretch default True;
  189. property Proportional: boolean
  190. read FProportional write SetFProportional default False;
  191. public
  192. constructor Create(AOwner: TControl);
  193. procedure Assign(Source: TPersistent); override;
  194. end;
  195. { TBCCustomImageButton }
  196. TBCCustomImageButton = class(TBCGraphicButton)
  197. private
  198. { Private declarations }
  199. FAlphaTest: boolean;
  200. FAlphaTestValue: byte;
  201. {$IFDEF INDEBUG}
  202. FDrawCount: integer;
  203. FRenderCount: integer;
  204. {$ENDIF}
  205. FBitmapOptions: TBCImageButtonSliceScalingOptions;
  206. FBGRAMultiSliceScaling: TBGRAMultiSliceScaling;
  207. FBGRANormal, FBGRAHover, FBGRAActive, FBGRADisabled: TBGRABitmap;
  208. FDestRect: TRect;
  209. FPressed: boolean;
  210. FTimer: TTimer;
  211. FFade: TFading;
  212. FAnimation: boolean;
  213. FBitmapFile: string;
  214. FTextVisible: boolean;
  215. FToggle: boolean;
  216. FMouse: TPoint;
  217. procedure SetFAlphaTest(AValue: boolean);
  218. procedure SetFAlphaTestValue(AValue: byte);
  219. procedure SetFAnimation(AValue: boolean);
  220. procedure SetFBitmapFile(AValue: string);
  221. procedure SetFBitmapOptions(AValue: TBCImageButtonSliceScalingOptions);
  222. procedure Fade({%H-}Sender: TObject);
  223. procedure SetFPressed(AValue: boolean);
  224. procedure SetFTextVisible(AValue: boolean);
  225. procedure SetFToggle(AValue: boolean);
  226. protected
  227. { Protected declarations }
  228. procedure DrawControl; override;
  229. procedure RenderControl; override;
  230. procedure TextChanged; override;
  231. procedure FontChanged(Sender: TObject); override;
  232. procedure CMChanged(var {%H-}Message: {$IFDEF FPC}TLMessage{$ELSE}TMessage{$ENDIF}); message CM_CHANGED; {$IFDEF FPC}virtual;{$ENDIF}
  233. {$IFDEF INDEBUG}
  234. {$IFDEF FPC}
  235. function GetDebugText: string;
  236. {$ENDIF}
  237. {$ENDIF}
  238. procedure DoMouseDown; override;
  239. procedure DoMouseUp; override;
  240. procedure DoMouseEnter; override;
  241. procedure DoMouseLeave; override;
  242. procedure DoMouseMove(x, y: integer); override;
  243. procedure Click; override;
  244. public
  245. { Public declarations }
  246. property AlphaTest: boolean read FAlphaTest write SetFAlphaTest default True;
  247. property AlphaTestValue: byte
  248. read FAlphaTestValue write SetFAlphaTestValue default 255;
  249. property Toggle: boolean read FToggle write SetFToggle default False;
  250. property Pressed: boolean read FPressed write SetFPressed default False;
  251. //property State: TBCGraphicButtonState read FState;
  252. property BitmapOptions: TBCImageButtonSliceScalingOptions
  253. read FBitmapOptions write SetFBitmapOptions;
  254. property Animation: boolean read FAnimation write SetFAnimation default True;
  255. property BitmapFile: string read FBitmapFile write SetFBitmapFile;
  256. property TextVisible: boolean read FTextVisible write SetFTextVisible default True;
  257. constructor Create(AOwner: TComponent); override;
  258. destructor Destroy; override;
  259. { It loads the 'BitmapFile' }
  260. procedure LoadFromBitmapResource(const Resource: string; ResourceType: PChar); overload;
  261. procedure LoadFromBitmapResource(const Resource: string); overload;
  262. procedure LoadFromBitmapFile;
  263. procedure Assign(Source: TPersistent); override;
  264. { Streaming }
  265. {$IFDEF FPC}
  266. procedure SaveToFile(AFileName: string); override;
  267. procedure LoadFromFile(AFileName: string); override;
  268. procedure AssignFromFile(AFileName: string); override;
  269. {$ENDIF}
  270. procedure OnFindClass({%H-}Reader: TReader; const AClassName: string;
  271. var ComponentClass: TComponentClass);
  272. published
  273. { Published declarations }
  274. end;
  275. TBCImageButton = class(TBCCustomImageButton)
  276. published
  277. property AlphaTest;
  278. property AlphaTestValue;
  279. property Action;
  280. property Align;
  281. property Anchors;
  282. property Animation;
  283. property AutoSize;
  284. //property AutoSizeExtraHorizontal;
  285. //property AutoSizeExtraVertical;
  286. property BidiMode;
  287. //property Bitmap;
  288. property BitmapFile;
  289. property BitmapOptions;
  290. property BorderSpacing;
  291. property Caption;
  292. //property Checked;
  293. property Color;
  294. property Constraints;
  295. property DragCursor;
  296. property DragKind;
  297. property DragMode;
  298. property Enabled;
  299. property Font;
  300. property ModalResult;
  301. {$IFDEF FPC}
  302. property OnChangeBounds;
  303. {$ENDIF}
  304. property OnClick;
  305. property OnContextPopup;
  306. property OnDragDrop;
  307. property OnDragOver;
  308. property OnEndDrag;
  309. property OnMouseDown;
  310. property OnMouseMove;
  311. property OnMouseUp;
  312. property OnMouseEnter;
  313. property OnMouseLeave;
  314. property OnMouseWheel;
  315. property OnMouseWheelDown;
  316. property OnMouseWheelUp;
  317. //property OnPlaySound;
  318. //property OnRedraw;
  319. property OnResize;
  320. property OnStartDrag;
  321. property ParentBidiMode;
  322. property ParentFont;
  323. property ParentShowHint;
  324. property PopupMenu;
  325. //property Shadow;
  326. property ShowHint;
  327. //property Sound;
  328. //property SoundClick;
  329. //property SoundEnter;
  330. property TextVisible;
  331. property Toggle;
  332. property Pressed;
  333. property Visible;
  334. end;
  335. {$IFDEF FPC}procedure Register;{$ENDIF}
  336. implementation
  337. {$IFDEF FPC}procedure Register;
  338. begin
  339. RegisterComponents('BGRA Button Controls', [TBCImageButton]);
  340. RegisterComponents('BGRA Button Controls', [TBCXButton]);
  341. end;
  342. {$ENDIF}
  343. function CalculateAspectRatioH(W1, H1, W2: integer): integer;
  344. begin
  345. Result := Round(H1 / W1 * W2);
  346. end;
  347. function CalculateAspectRatioW(W1, H1, H2: integer): integer;
  348. begin
  349. Result := Round(W1 / H1 * H2);
  350. end;
  351. function CalculateDestRect(ImageW, ImageH, DestW, DestH: integer;
  352. Stretch, Proportional, Center: boolean): TRect;
  353. var
  354. w: integer;
  355. h: integer;
  356. begin
  357. // Stretch or Proportional when Image (Width or Height) is bigger than Destination
  358. if Stretch or (Proportional and ((ImageW > DestW) or (ImageH > DestH))) then
  359. begin
  360. // Proportional when Image (Width or Height) is bigger than 0
  361. if Proportional and (ImageW > 0) and (ImageH > 0) then
  362. begin
  363. w := DestW;
  364. h := CalculateAspectRatioH(ImageW, ImageH, DestW);
  365. if h > DestH then
  366. begin
  367. h := DestH;
  368. w := CalculateAspectRatioW(ImageW, ImageH, DestH);
  369. end;
  370. ImageW := w;
  371. ImageH := h;
  372. end
  373. // Stretch not Proportional or when Image (Width or Height) is 0
  374. else
  375. begin
  376. ImageW := DestW;
  377. ImageH := DestH;
  378. end;
  379. end;
  380. Result := Rect(0, 0, ImageW, ImageH);
  381. // Center: Destination (Width or Height) - Image divided by 2
  382. if Center then
  383. begin
  384. Result.Left := Round((DestW - ImageW) div 2);
  385. Result.Top := Round((DestH - ImageH) div 2);
  386. end;
  387. end;
  388. procedure AssignFontToBGRA(Source: TFont; Dest: TBGRABitmap);
  389. begin
  390. Dest.FontAntialias := True;
  391. Dest.FontName := Source.Name;
  392. Dest.FontStyle := Source.Style;
  393. Dest.FontOrientation := Source.Orientation;
  394. case Source.Quality of
  395. fqNonAntialiased: Dest.FontQuality := fqSystem;
  396. fqAntialiased: Dest.FontQuality := fqFineAntialiasing;
  397. fqProof: Dest.FontQuality := fqFineClearTypeRGB;
  398. fqDefault, fqDraft, fqCleartype, fqCleartypeNatural: Dest.FontQuality :=
  399. fqSystemClearType;
  400. end;
  401. Dest.FontHeight := -Source.Height;
  402. end;
  403. { TBCXButton }
  404. class function TBCXButton.GetControlClassDefaultSize: TSize;
  405. begin
  406. Result := inherited GetControlClassDefaultSize;
  407. end;
  408. procedure TBCXButton.DrawControl;
  409. begin
  410. if Enabled then
  411. case FState of
  412. gbsNormal: FBGRANormal.Draw(Canvas, 0, 0, False);
  413. gbsHover: FBGRAHover.Draw(Canvas, 0, 0, False);
  414. gbsActive: FBGRAActive.Draw(Canvas, 0, 0, False);
  415. end
  416. else
  417. FBGRADisabled.Draw(Canvas, 0, 0, False);
  418. end;
  419. procedure TBCXButton.RenderControl;
  420. begin
  421. { Free cache bitmaps }
  422. if FBGRANormal <> nil then
  423. FreeAndNil(FBGRANormal);
  424. if FBGRAHover <> nil then
  425. FreeAndNil(FBGRAHover);
  426. if FBGRAActive <> nil then
  427. FreeAndNil(FBGRAActive);
  428. if FBGRADisabled <> nil then
  429. FreeAndNil(FBGRADisabled);
  430. { Create cache bitmaps }
  431. FBGRANormal := TBGRABitmap.Create(Width, Height);
  432. FBGRAHover := TBGRABitmap.Create(Width, Height);
  433. FBGRAActive := TBGRABitmap.Create(Width, Height);
  434. FBGRADisabled := TBGRABitmap.Create(Width, Height);
  435. if Assigned(FOnRenderControl) then
  436. begin
  437. FOnRenderControl(Self, FBGRANormal, gbsNormal);
  438. FOnRenderControl(Self, FBGRAHover, gbsHover);
  439. FOnRenderControl(Self, FBGRAActive, gbsActive);
  440. FOnRenderControl(Self, FBGRADisabled, gbsDisabled);
  441. end;
  442. end;
  443. constructor TBCXButton.Create(AOwner: TComponent);
  444. begin
  445. inherited Create(AOwner);
  446. with GetControlClassDefaultSize do
  447. SetInitialBounds(0, 0, CX, CY);
  448. end;
  449. destructor TBCXButton.Destroy;
  450. begin
  451. if FBGRANormal <> nil then
  452. FreeAndNil(FBGRANormal);
  453. if FBGRAHover <> nil then
  454. FreeAndNil(FBGRAHover);
  455. if FBGRAActive <> nil then
  456. FreeAndNil(FBGRAActive);
  457. if FBGRADisabled <> nil then
  458. FreeAndNil(FBGRADisabled);
  459. inherited Destroy;
  460. end;
  461. { TBCImageButtonSliceScalingOptions }
  462. procedure TBCImageButtonSliceScalingOptions.SetFCenter(AValue: boolean);
  463. begin
  464. if FCenter = AValue then
  465. Exit;
  466. FCenter := AValue;
  467. FOwner.Perform(CM_CHANGED, 0, 0);
  468. FOwner.Invalidate;
  469. end;
  470. procedure TBCImageButtonSliceScalingOptions.SetFProportional(AValue: boolean);
  471. begin
  472. if FProportional = AValue then
  473. Exit;
  474. FProportional := AValue;
  475. FOwner.Perform(CM_CHANGED, 0, 0);
  476. FOwner.Invalidate;
  477. end;
  478. procedure TBCImageButtonSliceScalingOptions.SetFStretch(AValue: boolean);
  479. begin
  480. if FStretch = AValue then
  481. Exit;
  482. FStretch := AValue;
  483. FOwner.Perform(CM_CHANGED, 0, 0);
  484. FOwner.Invalidate;
  485. end;
  486. constructor TBCImageButtonSliceScalingOptions.Create(AOwner: TControl);
  487. begin
  488. inherited Create(AOwner);
  489. FNumberOfItems := 4;
  490. FCenter := True;
  491. FProportional := False;
  492. FStretch := True;
  493. end;
  494. procedure TBCImageButtonSliceScalingOptions.Assign(Source: TPersistent);
  495. begin
  496. if Source is TBCImageButtonSliceScalingOptions then
  497. begin
  498. FAutoDetectRepeat := TBCImageButtonSliceScalingOptions(Source).AutoDetectRepeat;
  499. FCenter := TBCImageButtonSliceScalingOptions(Source).Center;
  500. FRepeatTop := TBCImageButtonSliceScalingOptions(Source).RepeatTop;
  501. FRepeatLeft := TBCImageButtonSliceScalingOptions(Source).RepeatLeft;
  502. FRepeatMiddleHorizontal :=
  503. TBCImageButtonSliceScalingOptions(Source).RepeatMiddleHorizontal;
  504. FRepeatMiddleVertical := TBCImageButtonSliceScalingOptions(
  505. Source).RepeatMiddleVertical;
  506. FRepeatRight := TBCImageButtonSliceScalingOptions(Source).RepeatRight;
  507. FRepeatBottom := TBCImageButtonSliceScalingOptions(Source).RepeatBottom;
  508. FMarginTop := TBCImageButtonSliceScalingOptions(Source).MarginTop;
  509. FMarginRight := TBCImageButtonSliceScalingOptions(Source).MarginRight;
  510. FMarginBottom := TBCImageButtonSliceScalingOptions(Source).MarginBottom;
  511. FMarginLeft := TBCImageButtonSliceScalingOptions(Source).MarginLeft;
  512. FDirection := TBCImageButtonSliceScalingOptions(Source).Direction;
  513. FDrawMode := TBCImageButtonSliceScalingOptions(Source).DrawMode;
  514. FResampleMode := TBCImageButtonSliceScalingOptions(Source).ResampleMode;
  515. FResampleFilter := TBCImageButtonSliceScalingOptions(Source).ResampleFilter;
  516. FStretch := TBCImageButtonSliceScalingOptions(Source).Stretch;
  517. FProportional := TBCImageButtonSliceScalingOptions(Source).Proportional;
  518. end
  519. else
  520. inherited Assign(Source);
  521. end;
  522. { TBCCustomSliceScalingOptions }
  523. procedure TBCCustomSliceScalingOptions.SetFBitmap(AValue: TBGRABitmap);
  524. begin
  525. if FBitmap = AValue then
  526. Exit;
  527. FBitmap := AValue;
  528. FOwner.Perform(CM_CHANGED, 0, 0);
  529. FOwner.Invalidate;
  530. end;
  531. procedure TBCCustomSliceScalingOptions.SetFMarginBottom(AValue: integer);
  532. begin
  533. if FMarginBottom = AValue then
  534. Exit;
  535. FMarginBottom := AValue;
  536. FOwner.Perform(CM_CHANGED, 0, 0);
  537. FOwner.Invalidate;
  538. end;
  539. procedure TBCCustomSliceScalingOptions.SetFMarginLeft(AValue: integer);
  540. begin
  541. if FMarginLeft = AValue then
  542. Exit;
  543. FMarginLeft := AValue;
  544. FOwner.Perform(CM_CHANGED, 0, 0);
  545. FOwner.Invalidate;
  546. end;
  547. procedure TBCCustomSliceScalingOptions.SetFMarginRight(AValue: integer);
  548. begin
  549. if FMarginRight = AValue then
  550. Exit;
  551. FMarginRight := AValue;
  552. FOwner.Perform(CM_CHANGED, 0, 0);
  553. FOwner.Invalidate;
  554. end;
  555. procedure TBCCustomSliceScalingOptions.SetFMarginTop(AValue: integer);
  556. begin
  557. if FMarginTop = AValue then
  558. Exit;
  559. FMarginTop := AValue;
  560. FOwner.Perform(CM_CHANGED, 0, 0);
  561. FOwner.Invalidate;
  562. end;
  563. procedure TBCCustomSliceScalingOptions.SetFAutoDetectRepeat(AValue: boolean);
  564. begin
  565. if FAutoDetectRepeat = AValue then
  566. Exit;
  567. FAutoDetectRepeat := AValue;
  568. FOwner.Perform(CM_CHANGED, 0, 0);
  569. FOwner.Invalidate;
  570. end;
  571. procedure TBCCustomSliceScalingOptions.SetFDirection(AValue: TSliceScalingDirection);
  572. begin
  573. if FDirection = AValue then
  574. Exit;
  575. FDirection := AValue;
  576. FOwner.Perform(CM_CHANGED, 0, 0);
  577. FOwner.Invalidate;
  578. end;
  579. procedure TBCCustomSliceScalingOptions.SetFDrawMode(AValue: TDrawMode);
  580. begin
  581. if FDrawMode = AValue then
  582. Exit;
  583. FDrawMode := AValue;
  584. FOwner.Perform(CM_CHANGED, 0, 0);
  585. FOwner.Invalidate;
  586. end;
  587. procedure TBCCustomSliceScalingOptions.SetFNumberOfItems(AValue: integer);
  588. begin
  589. if FNumberOfItems = AValue then
  590. Exit;
  591. FNumberOfItems := AValue;
  592. end;
  593. procedure TBCCustomSliceScalingOptions.SetFRepeatBottom(AValue: boolean);
  594. begin
  595. if FRepeatBottom = AValue then
  596. Exit;
  597. FRepeatBottom := AValue;
  598. FOwner.Perform(CM_CHANGED, 0, 0);
  599. FOwner.Invalidate;
  600. end;
  601. procedure TBCCustomSliceScalingOptions.SetFRepeatLeft(AValue: boolean);
  602. begin
  603. if FRepeatLeft = AValue then
  604. Exit;
  605. FRepeatLeft := AValue;
  606. FOwner.Perform(CM_CHANGED, 0, 0);
  607. FOwner.Invalidate;
  608. end;
  609. procedure TBCCustomSliceScalingOptions.SetFRepeatMiddleHorizontal(AValue: boolean);
  610. begin
  611. if FRepeatMiddleHorizontal = AValue then
  612. Exit;
  613. FRepeatMiddleHorizontal := AValue;
  614. FOwner.Perform(CM_CHANGED, 0, 0);
  615. FOwner.Invalidate;
  616. end;
  617. procedure TBCCustomSliceScalingOptions.SetFRepeatMiddleVertical(AValue: boolean);
  618. begin
  619. if FRepeatMiddleVertical = AValue then
  620. Exit;
  621. FRepeatMiddleVertical := AValue;
  622. FOwner.Perform(CM_CHANGED, 0, 0);
  623. FOwner.Invalidate;
  624. end;
  625. procedure TBCCustomSliceScalingOptions.SetFRepeatRight(AValue: boolean);
  626. begin
  627. if FRepeatRight = AValue then
  628. Exit;
  629. FRepeatRight := AValue;
  630. FOwner.Perform(CM_CHANGED, 0, 0);
  631. FOwner.Invalidate;
  632. end;
  633. procedure TBCCustomSliceScalingOptions.SetFRepeatTop(AValue: boolean);
  634. begin
  635. if FRepeatTop = AValue then
  636. Exit;
  637. FRepeatTop := AValue;
  638. FOwner.Perform(CM_CHANGED, 0, 0);
  639. FOwner.Invalidate;
  640. end;
  641. procedure TBCCustomSliceScalingOptions.SetFResampleFilter(AValue: TResampleFilter);
  642. begin
  643. if FResampleFilter = AValue then
  644. Exit;
  645. FResampleFilter := AValue;
  646. FOwner.Perform(CM_CHANGED, 0, 0);
  647. FOwner.Invalidate;
  648. end;
  649. procedure TBCCustomSliceScalingOptions.SetFResampleMode(AValue: TResampleMode);
  650. begin
  651. if FResampleMode = AValue then
  652. Exit;
  653. FResampleMode := AValue;
  654. FOwner.Perform(CM_CHANGED, 0, 0);
  655. FOwner.Invalidate;
  656. end;
  657. constructor TBCCustomSliceScalingOptions.Create(AOwner: TControl);
  658. begin
  659. FOwner := AOwner;
  660. FBitmap := nil;
  661. FAutoDetectRepeat := False;
  662. FRepeatTop := False;
  663. FRepeatLeft := False;
  664. FRepeatMiddleHorizontal := False;
  665. FRepeatMiddleVertical := False;
  666. FRepeatRight := False;
  667. FRepeatBottom := False;
  668. FMarginTop := 0;
  669. FMarginRight := 0;
  670. FMarginBottom := 0;
  671. FMarginLeft := 0;
  672. FNumberOfItems := 1;
  673. FDirection := sdVertical;
  674. FDrawMode := dmDrawWithTransparency;
  675. FResampleMode := rmFineResample;
  676. FResampleFilter := rfBestQuality;
  677. inherited Create;
  678. end;
  679. destructor TBCCustomSliceScalingOptions.Destroy;
  680. begin
  681. if FBitmap <> nil then
  682. FreeAndNil(FBitmap);
  683. inherited Destroy;
  684. end;
  685. { TBCGraphicButton }
  686. procedure TBCGraphicButton.DoClick;
  687. var
  688. Form: TCustomForm;
  689. begin
  690. if ModalResult <> mrNone then
  691. begin
  692. Form := GetParentForm(Self);
  693. if Form <> nil then
  694. Form.ModalResult := ModalResult;
  695. end;
  696. end;
  697. procedure TBCGraphicButton.DoMouseDown;
  698. var
  699. NewState: TBCGraphicButtonState;
  700. begin
  701. NewState := gbsActive;
  702. if NewState <> FState then
  703. begin
  704. FState := NewState;
  705. Invalidate;
  706. end;
  707. end;
  708. procedure TBCGraphicButton.DoMouseUp;
  709. var
  710. NewState: TBCGraphicButtonState;
  711. p: TPoint;
  712. begin
  713. p := ScreenToClient(Mouse.CursorPos);
  714. if (p.x >= 0) and (p.x <= Width) and (p.y >= 0) and (p.y <= Height) then
  715. NewState := gbsHover
  716. else
  717. NewState := gbsNormal;
  718. if NewState <> FState then
  719. begin
  720. FState := NewState;
  721. Invalidate;
  722. end;
  723. end;
  724. procedure TBCGraphicButton.DoMouseEnter;
  725. var
  726. NewState: TBCGraphicButtonState;
  727. begin
  728. if Enabled then
  729. NewState := gbsHover
  730. else
  731. begin
  732. FState := gbsNormal;
  733. NewState := FState;
  734. end;
  735. if NewState <> FState then
  736. begin
  737. FState := NewState;
  738. Invalidate;
  739. end;
  740. end;
  741. procedure TBCGraphicButton.DoMouseLeave;
  742. var
  743. NewState: TBCGraphicButtonState;
  744. begin
  745. if Enabled then
  746. NewState := gbsNormal
  747. else
  748. begin
  749. FState := gbsNormal;
  750. NewState := FState;
  751. end;
  752. if NewState <> FState then
  753. begin
  754. FState := NewState;
  755. Invalidate;
  756. end;
  757. end;
  758. procedure TBCGraphicButton.DoMouseMove(x, y: integer);
  759. begin
  760. inherited;
  761. end;
  762. procedure TBCGraphicButton.Click;
  763. begin
  764. DoClick;
  765. inherited Click;
  766. end;
  767. procedure TBCGraphicButton.MouseDown(Button: TMouseButton; Shift: TShiftState;
  768. X, Y: integer);
  769. begin
  770. inherited MouseDown(Button, Shift, X, Y);
  771. if Button = mbLeft then
  772. DoMouseDown;
  773. end;
  774. procedure TBCGraphicButton.MouseUp(Button: TMouseButton; Shift: TShiftState;
  775. X, Y: integer);
  776. begin
  777. inherited MouseUp(Button, Shift, X, Y);
  778. DoMouseUp;
  779. end;
  780. procedure TBCGraphicButton.MouseEnter;
  781. begin
  782. inherited MouseEnter;
  783. DoMouseEnter;
  784. end;
  785. procedure TBCGraphicButton.MouseLeave;
  786. begin
  787. inherited MouseLeave;
  788. DoMouseLeave;
  789. end;
  790. procedure TBCGraphicButton.MouseMove(Shift: TShiftState; X, Y: Integer);
  791. begin
  792. inherited MouseMove(Shift, X, Y);
  793. DoMouseMove(X, Y);
  794. end;
  795. { TBCCustomImageButton }
  796. procedure TBCCustomImageButton.Fade(Sender: TObject);
  797. begin
  798. if FFade.Mode <> fmSuspended then
  799. Invalidate;
  800. if csDesigning in ComponentState then
  801. Exit;
  802. FTimer.Enabled := FAnimation;
  803. end;
  804. procedure TBCCustomImageButton.SetFPressed(AValue: boolean);
  805. begin
  806. if FPressed = AValue then
  807. Exit;
  808. FPressed := AValue;
  809. RenderControl;
  810. end;
  811. procedure TBCCustomImageButton.SetFTextVisible(AValue: boolean);
  812. begin
  813. if FTextVisible = AValue then
  814. Exit;
  815. FTextVisible := AValue;
  816. RenderControl;
  817. end;
  818. procedure TBCCustomImageButton.SetFToggle(AValue: boolean);
  819. begin
  820. if FToggle = AValue then
  821. Exit;
  822. FToggle := AValue;
  823. end;
  824. procedure TBCCustomImageButton.SetFBitmapOptions(AValue:
  825. TBCImageButtonSliceScalingOptions);
  826. begin
  827. if FBitmapOptions = AValue then
  828. Exit;
  829. FBitmapOptions := AValue;
  830. end;
  831. procedure TBCCustomImageButton.SetFAlphaTest(AValue: boolean);
  832. begin
  833. if FAlphaTest = AValue then
  834. Exit;
  835. FAlphaTest := AValue;
  836. end;
  837. procedure TBCCustomImageButton.SetFAlphaTestValue(AValue: byte);
  838. begin
  839. if FAlphaTestValue = AValue then
  840. Exit;
  841. FAlphaTestValue := AValue;
  842. end;
  843. procedure TBCCustomImageButton.SetFAnimation(AValue: boolean);
  844. begin
  845. if FAnimation = AValue then
  846. Exit;
  847. FAnimation := AValue;
  848. if csDesigning in ComponentState then Exit;
  849. FTimer.Enabled := FAnimation;
  850. end;
  851. procedure TBCCustomImageButton.SetFBitmapFile(AValue: string);
  852. begin
  853. if FBitmapFile = AValue then
  854. Exit;
  855. FBitmapFile := AValue;
  856. end;
  857. procedure TBCCustomImageButton.DrawControl;
  858. var
  859. temp: TBGRABitmap;
  860. begin
  861. {$IFNDEF FPC}//# //@ IN DELPHI RenderControl NEDD. IF NO RenderControl BE BLACK AFTER INVALIDATE.
  862. RenderControl;
  863. {$ENDIF}
  864. if Color <> clDefault then
  865. begin
  866. Canvas.Brush.Color := Color;
  867. Canvas.FillRect(Rect(0, 0, Width, Height));
  868. end;
  869. if Enabled then
  870. begin
  871. if (Toggle) then
  872. begin
  873. if (Pressed) then
  874. FBGRAActive.Draw(Canvas, FDestRect.Left, FDestRect.Top, False)
  875. else
  876. case FState of
  877. gbsHover: FBGRAHover.Draw(Canvas, FDestRect.Left,
  878. FDestRect.Top, False);
  879. else
  880. FBGRANormal.Draw(Canvas, FDestRect.Left,
  881. FDestRect.Top, False);
  882. end;
  883. end
  884. else
  885. begin
  886. case FState of
  887. gbsNormal, gbsHover: FBGRANormal.Draw(Canvas, FDestRect.Left,
  888. FDestRect.Top, False);
  889. gbsActive: FBGRAActive.Draw(Canvas, FDestRect.Left, FDestRect.Top, False);
  890. end;
  891. temp := TBGRABitmap.Create(Width, Height);
  892. FFade.Execute;
  893. FFade.PutImage(temp, 0, 0, FBGRAHover);
  894. temp.Draw(Canvas, FDestRect.Left, FDestRect.Top, False);
  895. temp.Free;
  896. end;
  897. end
  898. else
  899. FBGRADisabled.Draw(Canvas, FDestRect.Left, FDestRect.Top, False);
  900. {$IFDEF INDEBUG}
  901. FDrawCount := FDrawCount +1;
  902. {$ENDIF}
  903. {$IFDEF INDEBUG}
  904. Canvas.Brush.Color := clWhite;
  905. Canvas.TextOut(0, 0, GetDebugText);
  906. {$ENDIF}
  907. end;
  908. procedure TBCCustomImageButton.RenderControl;
  909. procedure DrawText(ABitmap: TBGRABitmap);
  910. begin
  911. AssignFontToBGRA(Font, ABitmap);
  912. ABitmap.TextRect(Rect(0, 0, Width, Height), Caption, taCenter, tlCenter,
  913. Font.Color);
  914. end;
  915. {$IFDEF INDEBUG}
  916. const
  917. Debug = True;
  918. {$ELSE}
  919. const
  920. Debug = False;
  921. {$ENDIF}
  922. var
  923. i: integer;
  924. begin
  925. { Free cache bitmaps }
  926. if FBGRANormal <> nil then
  927. FreeAndNil(FBGRANormal);
  928. if FBGRAHover <> nil then
  929. FreeAndNil(FBGRAHover);
  930. if FBGRAActive <> nil then
  931. FreeAndNil(FBGRAActive);
  932. if FBGRADisabled <> nil then
  933. FreeAndNil(FBGRADisabled);
  934. { Create cache bitmaps }
  935. FBGRANormal := TBGRABitmap.Create(Width, Height);
  936. FBGRAHover := TBGRABitmap.Create(Width, Height);
  937. FBGRAActive := TBGRABitmap.Create(Width, Height);
  938. FBGRADisabled := TBGRABitmap.Create(Width, Height);
  939. { Free FBGRAMultiSliceScaling }
  940. if FBGRAMultiSliceScaling <> nil then
  941. FreeAndNil(FBGRAMultiSliceScaling);
  942. if (FBitmapOptions.Bitmap <> nil) then
  943. begin
  944. { Create FBGRAMultiSliceScaling }
  945. FBGRAMultiSliceScaling := TBGRAMultiSliceScaling.Create(FBitmapOptions.Bitmap,
  946. FBitmapOptions.MarginTop, FBitmapOptions.MarginRight,
  947. FBitmapOptions.MarginBottom, FBitmapOptions.MarginLeft,
  948. FBitmapOptions.NumberOfItems, FBitmapOptions.Direction);
  949. { Set FBGRAMultiSliceScaling properties }
  950. for i := 0 to High(FBGRAMultiSliceScaling.SliceScalingArray) do
  951. begin
  952. FBGRAMultiSliceScaling.SliceScalingArray[i].ResampleFilter :=
  953. FBitmapOptions.ResampleFilter;
  954. FBGRAMultiSliceScaling.SliceScalingArray[i].ResampleMode :=
  955. FBitmapOptions.ResampleMode;
  956. FBGRAMultiSliceScaling.SliceScalingArray[i].DrawMode := FBitmapOptions.DrawMode;
  957. FBGRAMultiSliceScaling.SliceScalingArray[i].SliceRepeat[srpTop] :=
  958. FBitmapOptions.RepeatTop;
  959. FBGRAMultiSliceScaling.SliceScalingArray[i].SliceRepeat[srpBottom] :=
  960. FBitmapOptions.RepeatBottom;
  961. FBGRAMultiSliceScaling.SliceScalingArray[i].SliceRepeat[srpLeft] :=
  962. FBitmapOptions.RepeatLeft;
  963. FBGRAMultiSliceScaling.SliceScalingArray[i].SliceRepeat[srpRight] :=
  964. FBitmapOptions.RepeatRight;
  965. FBGRAMultiSliceScaling.SliceScalingArray[i].SliceRepeat[srpMiddleHorizontal] :=
  966. FBitmapOptions.RepeatMiddleHorizontal;
  967. FBGRAMultiSliceScaling.SliceScalingArray[i].SliceRepeat[srpMiddleVertical] :=
  968. FBitmapOptions.RepeatMiddleVertical;
  969. if FBitmapOptions.AutoDetectRepeat then
  970. FBGRAMultiSliceScaling.SliceScalingArray[i].AutodetectRepeat;
  971. end;
  972. { Calculate FDestRect }
  973. FDestRect := CalculateDestRect(
  974. FBGRAMultiSliceScaling.SliceScalingArray[0].BitmapWidth,
  975. FBGRAMultiSliceScaling.SliceScalingArray[0].BitmapHeight, Width,
  976. Height, FBitmapOptions.Stretch, FBitmapOptions.Proportional,
  977. FBitmapOptions.Center);
  978. { Draw in cache bitmaps }
  979. FBGRAMultiSliceScaling.Draw(0, FBGRANormal, 0, 0, FDestRect.Right,
  980. FDestRect.Bottom, Debug);
  981. FBGRAMultiSliceScaling.Draw(1, FBGRAHover, 0, 0, FDestRect.Right,
  982. FDestRect.Bottom, Debug);
  983. FBGRAMultiSliceScaling.Draw(2, FBGRAActive, 0, 0, FDestRect.Right,
  984. FDestRect.Bottom, Debug);
  985. FBGRAMultiSliceScaling.Draw(3, FBGRADisabled, 0, 0, FDestRect.Right,
  986. FDestRect.Bottom, Debug);
  987. if TextVisible then
  988. begin
  989. { Draw Text }
  990. DrawText(FBGRANormal);
  991. DrawText(FBGRAHover);
  992. DrawText(FBGRAActive);
  993. DrawText(FBGRADisabled);
  994. end;
  995. end
  996. else
  997. begin
  998. { Calculate FDestRect }
  999. FDestRect := Rect(0, 0, Width, Height);
  1000. { Draw default style in cache bitmaps }
  1001. FBGRANormal.Rectangle(0, 0, Width, Height, BGRA(173, 173, 173), BGRA(225, 225, 225),
  1002. dmSet);
  1003. FBGRAHover.Rectangle(0, 0, Width, Height, BGRA(0, 120, 215), BGRA(229, 241, 251),
  1004. dmSet);
  1005. FBGRAActive.Rectangle(0, 0, Width, Height, BGRA(0, 84, 153), BGRA(204, 228, 247),
  1006. dmSet);
  1007. FBGRADisabled.Rectangle(0, 0, Width, Height, BGRA(191, 191, 191), BGRA(204, 204, 204),
  1008. dmSet);
  1009. if TextVisible then
  1010. begin
  1011. { Draw Text }
  1012. DrawText(FBGRANormal);
  1013. DrawText(FBGRAHover);
  1014. DrawText(FBGRAActive);
  1015. DrawText(FBGRADisabled);
  1016. end;
  1017. end;
  1018. {$IFDEF INDEBUG}
  1019. FRenderCount := FRenderCount +1;
  1020. {$ENDIF}
  1021. end;
  1022. procedure TBCCustomImageButton.TextChanged;
  1023. begin
  1024. InvalidatePreferredSize;
  1025. {$IFDEF FPC}//#
  1026. if Assigned(Parent) and Parent.AutoSize then
  1027. Parent.AdjustSize;
  1028. {$ENDIF}
  1029. AdjustSize;
  1030. RenderControl;
  1031. Invalidate;
  1032. end;
  1033. procedure TBCCustomImageButton.FontChanged(Sender: TObject);
  1034. begin
  1035. inherited;
  1036. RenderControl;
  1037. Invalidate;
  1038. end;
  1039. procedure TBCCustomImageButton.CMChanged(var Message: {$IFDEF FPC}TLMessage{$ELSE}TMessage{$ENDIF});
  1040. begin
  1041. if csReadingState in ControlState then
  1042. Exit;
  1043. RenderControl;
  1044. end;
  1045. {$IFDEF INDEBUG}
  1046. {$IFDEF FPC}
  1047. function TBCCustomImageButton.GetDebugText: string;
  1048. begin
  1049. Result := 'Render: ' + IntToStr(FRenderCount) + ' Draw: ' + IntToStr(FDrawCount);
  1050. end;
  1051. {$ENDIF}
  1052. {$ENDIF}
  1053. procedure TBCCustomImageButton.DoMouseDown;
  1054. begin
  1055. if FAlphaTest and (FBGRANormal.GetPixel(FMouse.X, FMouse.Y).alpha < FAlphaTestValue) then
  1056. Exit;
  1057. FFade.Mode := fmFadeOut;
  1058. if Animation then
  1059. FFade.Step := 60
  1060. else
  1061. FFade.Step := 255;
  1062. inherited DoMouseDown;
  1063. end;
  1064. procedure TBCCustomImageButton.DoMouseUp;
  1065. var
  1066. Ctrl: TControl;
  1067. begin
  1068. if FAlphaTest and (FBGRANormal.GetPixel(FMouse.X, FMouse.Y).alpha < FAlphaTestValue) then
  1069. Exit;
  1070. FFade.Mode := fmFadeIn;
  1071. if Animation then
  1072. FFade.Step := 20
  1073. else
  1074. FFade.Step := 255;
  1075. {$IFDEF FPC} //#
  1076. Ctrl := Application.GetControlAtMouse;
  1077. {$ENDIF}
  1078. if Ctrl = Self then
  1079. DoMouseEnter
  1080. else
  1081. DoMouseLeave;
  1082. inherited DoMouseUp;
  1083. end;
  1084. procedure TBCCustomImageButton.DoMouseEnter;
  1085. begin
  1086. FFade.Mode := fmFadeIn;
  1087. if Animation then
  1088. FFade.Step := 15
  1089. else
  1090. FFade.Step := 255;
  1091. inherited DoMouseEnter;
  1092. end;
  1093. procedure TBCCustomImageButton.DoMouseLeave;
  1094. begin
  1095. FFade.Mode := fmFadeOut;
  1096. if Animation then
  1097. FFade.Step := 8
  1098. else
  1099. FFade.Step := 255;
  1100. inherited DoMouseLeave;
  1101. end;
  1102. procedure TBCCustomImageButton.DoMouseMove(x, y: integer);
  1103. begin
  1104. FMouse := Point(X, Y);
  1105. if FAlphaTest then
  1106. if FBGRANormal.GetPixel(X, Y).alpha >= FAlphaTestValue then
  1107. DoMouseEnter
  1108. else
  1109. DoMouseLeave;
  1110. end;
  1111. procedure TBCCustomImageButton.Click;
  1112. begin
  1113. if FAlphaTest and (FBGRANormal.GetPixel(FMouse.X, FMouse.Y).alpha < FAlphaTestValue) then
  1114. Exit;
  1115. inherited Click;
  1116. if (Toggle) then
  1117. begin
  1118. Pressed := not Pressed;
  1119. end;
  1120. end;
  1121. constructor TBCCustomImageButton.Create(AOwner: TComponent);
  1122. begin
  1123. inherited Create(AOwner);
  1124. {$IFDEF INDEBUG}
  1125. FDrawCount := 0;
  1126. FRenderCount := 0;
  1127. {$ENDIF}
  1128. {$IFDEF FPC}
  1129. DisableAutoSizing;
  1130. Include(FControlState, csCreating);
  1131. {$ELSE} //#
  1132. {$ENDIF}
  1133. BeginUpdate;
  1134. try
  1135. FBitmapOptions := TBCImageButtonSliceScalingOptions.Create(Self);
  1136. with GetControlClassDefaultSize do
  1137. SetInitialBounds(0, 0, CX, CY);
  1138. ControlStyle := ControlStyle + [csAcceptsControls];
  1139. // FBitmapOptions := TBCImageButtonSliceScalingOptions.Create(Self);
  1140. {FBitmapOptions.Bitmap := TBGRABitmap.Create(1,4,BGRAWhite);
  1141. FBitmapOptions.Bitmap.SetPixel(0,0,BGRA(255,0,0,255));
  1142. FBitmapOptions.Bitmap.SetPixel(0,1,BGRA(0,255,0,255));
  1143. FBitmapOptions.Bitmap.SetPixel(0,2,BGRA(0,0,255,255));
  1144. FBitmapOptions.Bitmap.SetPixel(0,3,BGRA(100,100,100,255));}
  1145. FAlphaTest := True;
  1146. FAlphaTestValue := 255;
  1147. FFade.Step := 15;
  1148. FFade.Mode := fmFadeOut;
  1149. FTimer := TTimer.Create(Self);
  1150. FTimer.Interval := 15;
  1151. FTimer.OnTimer := Fade;
  1152. if csDesigning in ComponentState then
  1153. FTimer.Enabled := False;
  1154. FAnimation := True;
  1155. FTextVisible := True;
  1156. finally
  1157. {$IFDEF FPC}
  1158. Exclude(FControlState, csCreating);
  1159. EnableAutoSizing;
  1160. {$ELSE} //#
  1161. {$ENDIF}
  1162. EndUpdate;
  1163. end;
  1164. end;
  1165. destructor TBCCustomImageButton.Destroy;
  1166. begin
  1167. FTimer.Enabled := False;
  1168. FTimer.OnTimer := nil;
  1169. FTimer.Free;
  1170. if FBGRAMultiSliceScaling <> nil then
  1171. FreeAndNil(FBGRAMultiSliceScaling);
  1172. if FBGRANormal <> nil then
  1173. FreeAndNil(FBGRANormal);
  1174. if FBGRAHover <> nil then
  1175. FreeAndNil(FBGRAHover);
  1176. if FBGRAActive <> nil then
  1177. FreeAndNil(FBGRAActive);
  1178. if FBGRADisabled <> nil then
  1179. FreeAndNil(FBGRADisabled);
  1180. FreeAndNil(FBitmapOptions);
  1181. inherited Destroy;
  1182. end;
  1183. procedure TBCCustomImageButton.LoadFromBitmapResource(const Resource: string;
  1184. ResourceType: PChar);
  1185. var
  1186. res: TResourceStream;
  1187. begin
  1188. res := TResourceStream.Create(HInstance, Resource, ResourceType);
  1189. if BitmapOptions.Bitmap <> nil then
  1190. BitmapOptions.Bitmap.Free;
  1191. BitmapOptions.Bitmap := TBGRABitmap.Create(res);
  1192. res.Free;
  1193. end;
  1194. procedure TBCCustomImageButton.LoadFromBitmapResource(const Resource: string);
  1195. begin
  1196. LoadFromBitmapResource(Resource, {$ifdef Windows}Windows.{$endif}RT_RCDATA);
  1197. end;
  1198. procedure TBCCustomImageButton.LoadFromBitmapFile;
  1199. begin
  1200. if BitmapFile <> '' then
  1201. if BitmapOptions.Bitmap <> nil then
  1202. BitmapOptions.Bitmap.LoadFromFile(BitmapFile)
  1203. else
  1204. BitmapOptions.Bitmap := TBGRABitmap.Create(BitmapFile);
  1205. end;
  1206. procedure TBCCustomImageButton.Assign(Source: TPersistent);
  1207. begin
  1208. if Source is TBCCustomImageButton then
  1209. begin
  1210. FBitmapOptions.Assign(TBCCustomImageButton(Source).BitmapOptions);
  1211. FAnimation := TBCCustomImageButton(Source).Animation;
  1212. FBitmapFile := TBCCustomImageButton(Source).BitmapFile;
  1213. FTextVisible := TBCCustomImageButton(Source).TextVisible;
  1214. if TBCCustomImageButton(Source).BitmapOptions.Bitmap <> nil then
  1215. begin
  1216. if FBitmapOptions.Bitmap <> nil then
  1217. FBitmapOptions.Bitmap.Free;
  1218. FBitmapOptions.Bitmap :=
  1219. TBGRABitmap.Create(TBCCustomImageButton(Source).BitmapOptions.Bitmap.Bitmap);
  1220. end
  1221. else
  1222. LoadFromBitmapFile;
  1223. RenderControl;
  1224. Invalidate;
  1225. end
  1226. else
  1227. inherited Assign(Source);
  1228. end;
  1229. {$IFDEF FPC}
  1230. procedure TBCCustomImageButton.SaveToFile(AFileName: string);
  1231. var
  1232. AStream: TMemoryStream;
  1233. begin
  1234. AStream := TMemoryStream.Create;
  1235. try
  1236. WriteComponentAsTextToStream(AStream, Self);
  1237. AStream.SaveToFile(AFileName);
  1238. finally
  1239. AStream.Free;
  1240. end;
  1241. end;
  1242. procedure TBCCustomImageButton.LoadFromFile(AFileName: string);
  1243. var
  1244. AStream: TMemoryStream;
  1245. begin
  1246. AStream := TMemoryStream.Create;
  1247. try
  1248. AStream.LoadFromFile(AFileName);
  1249. ReadComponentFromTextStream(AStream, TComponent(Self), OnFindClass);
  1250. finally
  1251. AStream.Free;
  1252. end;
  1253. end;
  1254. procedure TBCCustomImageButton.AssignFromFile(AFileName: string);
  1255. var
  1256. AStream: TMemoryStream;
  1257. AButton: TBCImageButton;
  1258. begin
  1259. AButton := TBCImageButton.Create(nil);
  1260. AStream := TMemoryStream.Create;
  1261. try
  1262. AStream.LoadFromFile(AFileName);
  1263. ReadComponentFromTextStream(AStream, TComponent(AButton), OnFindClass);
  1264. Assign(AButton);
  1265. finally
  1266. AStream.Free;
  1267. AButton.Free;
  1268. end;
  1269. end;
  1270. {$ENDIF}
  1271. procedure TBCCustomImageButton.OnFindClass(Reader: TReader;
  1272. const AClassName: string; var ComponentClass: TComponentClass);
  1273. begin
  1274. if CompareText(AClassName, 'TBCImageButton') = 0 then
  1275. ComponentClass := TBCImageButton;
  1276. end;
  1277. end.