Files
Ansgar Becker be80dc2de2 - Create Delphi 11 package for PngComponents (D10 to come)
- Replace Thany.inc by using compilers.inc
- Set correct output and search directories
2008-03-01 00:24:10 +00:00

149 lines
3.9 KiB
ObjectPascal

unit PngSpeedButton;
{$I compilers.inc}
interface
uses
Windows, SysUtils, Classes, Controls, Buttons, Graphics, ActnList,
PngFunctions, PngButtonFunctions, pngimage;
type
TPngSpeedButton = class(TSpeedButton)
private
FPngImage: TPngObject;
FPngOptions: TPngOptions;
FImageFromAction: Boolean;
function PngImageStored: Boolean;
procedure SetPngImage(const Value: TPngObject);
procedure SetPngOptions(const Value: TPngOptions);
procedure CreatePngGlyph;
protected
procedure ActionChange(Sender: TObject; CheckDefaults: Boolean); override;
procedure Paint; override;
procedure Loaded; override;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
published
property PngImage: TPngObject read FPngImage write SetPngImage stored PngImageStored;
property PngOptions: TPngOptions read FPngOptions write SetPngOptions default [pngBlendOnDisabled];
property Glyph stored False;
property NumGlyphs stored False;
end;
implementation
{ TPngSpeedButton }
constructor TPngSpeedButton.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FPngImage := TPNGObject.Create;
FPngOptions := [pngBlendOnDisabled];
FImageFromAction := False;
end;
destructor TPngSpeedButton.Destroy;
begin
FPngImage.Free;
inherited Destroy;
end;
procedure TPngSpeedButton.ActionChange(Sender: TObject; CheckDefaults: Boolean);
begin
inherited ActionChange(Sender, CheckDefaults);
if Sender is TCustomAction
then with TCustomAction(Sender)
do begin
//Copy image from action's imagelist
if (PngImage.Empty or FImageFromAction) and (ActionList <> nil) and (ActionList.Images <> nil) and (ImageIndex >= 0) and (ImageIndex < ActionList.Images.Count)
then begin
CopyImageFromImageList(FPngImage, ActionList.Images, ImageIndex);
CreatePngGlyph;
FImageFromAction := True;
end;
end;
end;
procedure TPngSpeedButton.Paint;
var
PaintRect: TRect;
GlyphPos, TextPos: TPoint;
begin
inherited Paint;
if FPngImage <> nil
then begin
//Calculate the position of the PNG glyph
CalcButtonLayout(Canvas, FPngImage, ClientRect, FState = bsDown, Down, Caption, Layout, Margin, Spacing, GlyphPos, TextPos, DrawTextBiDiModeFlags(0));
PaintRect := Rect(GlyphPos.X, GlyphPos.Y, GlyphPos.X + FPngImage.Width, GlyphPos.Y + FPngImage.Height);
if Enabled
then DrawPNG(FPngImage, Canvas, PaintRect, [])
else DrawPNG(FPngImage, Canvas, PaintRect, FPngOptions);
end;
end;
procedure TPngSpeedButton.Loaded;
begin
inherited Loaded;
CreatePngGlyph;
end;
function TPngSpeedButton.PngImageStored: Boolean;
begin
Result := not FImageFromAction;
end;
procedure TPngSpeedButton.SetPngImage(const Value: TPngObject);
begin
//This is all neccesary, because you can't assign a nil to a TPNGObject
if Value = nil
then begin
FPngImage.Free;
FPngImage := TPNGObject.Create;
end
else FPngImage.Assign(Value);
//To work around the gamma-problem
with FPngImage
do if Header.ColorType in [COLOR_RGB, COLOR_RGBALPHA, COLOR_PALETTE]
then Chunks.RemoveChunk(Chunks.ItemFromClass(TChunkgAMA));
FImageFromAction := False;
CreatePngGlyph;
Repaint;
end;
procedure TPngSpeedButton.SetPngOptions(const Value: TPngOptions);
begin
if FPngOptions <> Value
then begin
FPngOptions := Value;
CreatePngGlyph;
Repaint;
end;
end;
procedure TPngSpeedButton.CreatePngGlyph;
var
Bmp: TBitmap;
begin
//Create an empty glyph, just to align the text correctly
Bmp := TBitmap.Create;
try
Bmp.Width := FPngImage.Width;
Bmp.Height := FPngImage.Height;
Bmp.Canvas.Brush.Color := clBtnFace;
Bmp.Canvas.FillRect(Rect(0, 0, Bmp.Width, Bmp.Height));
Glyph.Assign(Bmp);
NumGlyphs := 1;
finally
Bmp.Free;
end;
end;
end.