PngButtonFunctions.pas 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. unit PngButtonFunctions;
  2. interface
  3. uses
  4. Windows, Buttons, Graphics, pngimage;
  5. {$IF RTLVersion < 20.0 }
  6. type
  7. TPngImage = TPNGObject;
  8. {$IFEND}
  9. procedure CalcButtonLayout(Canvas: TCanvas; PngImage: TPngImage; const Client:
  10. TRect; Pressed, Down: Boolean; const Caption: string; Layout: TButtonLayout;
  11. Margin, Spacing: Integer; var GlyphPos, TextPos: TPoint; BiDiFlags: LongInt);
  12. implementation
  13. uses
  14. Classes;
  15. procedure CalcButtonLayout(Canvas: TCanvas; PngImage: TPngImage; const Client:
  16. TRect; Pressed, Down: Boolean; const Caption: string; Layout: TButtonLayout;
  17. Margin, Spacing: Integer; var GlyphPos, TextPos: TPoint; BiDiFlags: LongInt);
  18. var
  19. ClientSize, GlyphSize, TextSize, TotalSize: TPoint;
  20. TextBounds: TRect;
  21. begin
  22. if (BiDiFlags and DT_RIGHT) = DT_RIGHT then begin
  23. if Layout = blGlyphLeft then
  24. Layout := blGlyphRight
  25. else if Layout = blGlyphRight then
  26. Layout := blGlyphLeft;
  27. end;
  28. //Calculate the item sizes
  29. ClientSize := Point(Client.Right - Client.Left, Client.Bottom - Client.Top);
  30. if PngImage <> nil then
  31. GlyphSize := Point(PngImage.Width, PngImage.Height)
  32. else
  33. GlyphSize := Point(0, 0);
  34. if Length(Caption) > 0 then begin
  35. TextBounds := Rect(0, 0, Client.Right - Client.Left, 0);
  36. DrawText(Canvas.Handle, PChar(Caption), Length(Caption), TextBounds,
  37. DT_CALCRECT or BiDiFlags);
  38. TextSize := Point(TextBounds.Right - TextBounds.Left, TextBounds.Bottom -
  39. TextBounds.Top);
  40. end
  41. else begin
  42. TextBounds := Rect(0, 0, 0, 0);
  43. TextSize := Point(0, 0);
  44. end;
  45. //If the layout has the glyph on the right or the left, then both the
  46. //text and the glyph are centered vertically. If the glyph is on the top
  47. //or the bottom, then both the text and the glyph are centered horizontally.
  48. if Layout in [blGlyphLeft, blGlyphRight] then
  49. GlyphPos.Y := (ClientSize.Y - GlyphSize.Y + 1) div 2
  50. else
  51. GlyphPos.X := (ClientSize.X - GlyphSize.X + 1) div 2;
  52. //If there is no text or no bitmap, then Spacing is irrelevant
  53. if (TextSize.X = 0) or (GlyphSize.X = 0) then
  54. Spacing := 0;
  55. //Adjust Margin and Spacing
  56. if Margin = -1 then begin
  57. if Spacing = -1 then begin
  58. TotalSize := Point(GlyphSize.X + TextSize.X, GlyphSize.Y + TextSize.Y);
  59. if Layout in [blGlyphLeft, blGlyphRight] then
  60. Margin := (ClientSize.X - TotalSize.X) div 3
  61. else
  62. Margin := (ClientSize.Y - TotalSize.Y) div 3;
  63. end
  64. else begin
  65. TotalSize := Point(GlyphSize.X + Spacing + TextSize.X, GlyphSize.Y +
  66. Spacing + TextSize.Y);
  67. if Layout in [blGlyphLeft, blGlyphRight] then
  68. Margin := (ClientSize.X - TotalSize.X) div 2
  69. else
  70. Margin := (ClientSize.Y - TotalSize.Y) div 2;
  71. end
  72. end
  73. else if Spacing = -1 then begin
  74. TotalSize := Point(ClientSize.X - (Margin + GlyphSize.X), ClientSize.Y -
  75. (Margin + GlyphSize.Y));
  76. end;
  77. case Layout of
  78. blGlyphLeft: GlyphPos.X := Margin;
  79. blGlyphRight: GlyphPos.X := ClientSize.X - Margin - GlyphSize.X;
  80. blGlyphTop: GlyphPos.Y := Margin;
  81. blGlyphBottom: GlyphPos.Y := ClientSize.Y - Margin - GlyphSize.Y;
  82. end;
  83. if Layout in [blGlyphLeft, blGlyphRight] then
  84. TextPos.Y := (ClientSize.Y - TextSize.Y) div 2
  85. else
  86. TextPos.X := (ClientSize.X - TextSize.X) div 2;
  87. case Layout of
  88. blGlyphLeft: TextPos.X := GlyphPos.X + GlyphSize.X + Spacing;
  89. blGlyphRight: TextPos.X := GlyphPos.X - Spacing - TextSize.X;
  90. blGlyphTop: TextPos.Y := GlyphPos.Y + GlyphSize.Y + Spacing;
  91. blGlyphBottom: TextPos.Y := GlyphPos.Y - Spacing - TextSize.Y;
  92. end;
  93. //Fixup the result variables
  94. with GlyphPos do begin
  95. Inc(X, Client.Left + Integer(Pressed or Down));
  96. Inc(Y, Client.Top + Integer(Pressed or Down));
  97. end;
  98. with TextPos do begin
  99. Inc(X, Client.Left + Integer(Pressed or Down));
  100. Inc(Y, Client.Top + Integer(Pressed or Down));
  101. end;
  102. end;
  103. end.