pngextra.pas
上传用户:ctlcnc
上传日期:2021-12-10
资源大小:4933k
文件大小:9k
源码类别:

2D图形编程

开发平台:

Delphi

  1. unit pngextra;
  2. interface
  3. uses
  4.   Windows, Graphics, Messages, SysUtils, Classes, Controls, pngimage, Buttons,
  5.   ExtCtrls;
  6. type
  7.   TPNGButtonStyle = (pbsDefault, pbsFlat);
  8.   TPNGButtonLayout = (pbsImageAbove, pbsImageBellow);
  9.   TPNGButtonState = (pbsNormal, pbsDown, pbsDisabled);
  10.   TPNGButton = class(TGraphicControl)
  11.   private
  12.     {Holds the property values}
  13.     fButtonStyle: TPNGButtonStyle;
  14.     fMouseOverControl: Boolean;
  15.     FCaption: String;
  16.     FButtonLayout: TPNGButtonLayout;
  17.     FButtonState: TPNGButtonState;
  18.     FImageDown: TPNGObject;
  19.     fImageNormal: TPNGObject;
  20.     fImageDisabled: TPNGObject;
  21.     fImageOver: TPNGObject;
  22.     {Procedures for setting the property values}
  23.     procedure SetButtonStyle(const Value: TPNGButtonStyle);
  24.     procedure SetCaption(const Value: String);
  25.     procedure SetButtonLayout(const Value: TPNGButtonLayout);
  26.     procedure SetButtonState(const Value: TPNGButtonState);
  27.     procedure SetImageNormal(const Value: TPNGObject);
  28.     procedure SetImageDown(const Value: TPNGObject);
  29.     procedure SetImageOver(const Value: TPNGObject);
  30.   published
  31.     {Published properties}
  32.     property Font;
  33.     property Visible;
  34.     property ButtonLayout: TPNGButtonLayout read FButtonLayout write SetButtonLayout;
  35.     property Caption: String read FCaption write SetCaption;
  36.     property ImageNormal: TPNGObject read fImageNormal write SetImageNormal;
  37.     property ImageDown: TPNGObject read FImageDown write SetImageDown;
  38.     property ImageOver: TPNGObject read FImageOver write SetImageOver;
  39.     property ButtonStyle: TPNGButtonStyle read fButtonStyle
  40.       write SetButtonStyle;
  41.     property Enabled;
  42.     {Default events}
  43.     property OnMouseDown;
  44.     property OnClick;
  45.     property OnMouseUp;
  46.     property OnMouseMove;
  47.     property OnDblClick;
  48.   public
  49.     {Public properties}
  50.     property ButtonState: TPNGButtonState read FButtonState write SetButtonState;
  51.   protected
  52.     {Being painted}
  53.     procedure Paint; override;
  54.     {Clicked}
  55.     procedure Click; override;
  56.     {Mouse pressed}
  57.     procedure MouseDown(Button: TMouseButton; Shift: TShiftState;
  58.       X, Y: Integer); override;
  59.     procedure MouseUp(Button: TMouseButton; Shift: TShiftState;
  60.       X, Y: Integer); override;
  61.     procedure MouseMove(Shift: TShiftState; X, Y: Integer); override;
  62.     {Mouse entering or leaving}
  63.     procedure CMMouseEnter(var Message: TMessage); message CM_MOUSEENTER;
  64.     procedure CMMouseLeave(var Message: TMessage); message CM_MOUSELEAVE;
  65.     {Being enabled or disabled}
  66.     procedure CMEnabledChanged(var Message: TMessage);
  67.       message CM_ENABLEDCHANGED;
  68.   public
  69.     {Returns if the mouse is over the control}
  70.     property IsMouseOver: Boolean read fMouseOverControl;
  71.     {Constructor and destructor}
  72.     constructor Create(AOwner: TComponent); override;
  73.     destructor Destroy; override;
  74.   end;
  75. procedure Register;
  76. procedure MakeImageHalfTransparent(Source, Dest: TPNGObject);
  77. implementation
  78. procedure Register;
  79. begin
  80.   RegisterComponents('Samples', [TPNGButton]);
  81. end;
  82. procedure MakeImageHalfTransparent(Source, Dest: TPNGObject);
  83. var
  84.   i, j: Integer;
  85. begin
  86.   Dest.Assign(Source);
  87.   Dest.CreateAlpha;
  88.   if (Dest.Header.ColorType <> COLOR_PALETTE) then
  89.     for j := 0 to Source.Height - 1 do
  90.       for i := 0 to Source.Width - 1 do
  91.         Dest.AlphaScanline[j]^[i] := Dest.AlphaScanline[j]^[i] div 3;
  92. end;
  93. {TPNGButton implementation}
  94. {Being created}
  95. constructor TPNGButton.Create(AOwner: TComponent);
  96. begin
  97.   {Calls ancestor}
  98.   inherited Create(AOwner);
  99.   {Creates the TPNGObjects}
  100.   fImageNormal := TPNGObject.Create;
  101.   fImageDown := TPNGObject.Create;
  102.   fImageDisabled := TPNGObject.Create;
  103.   fImageOver := TPNGObject.Create;
  104.   {Initial properties}
  105.   ControlStyle := ControlStyle + [csCaptureMouse];
  106.   SetBounds(Left, Top, 23, 23);
  107.   fMouseOverControl := False;
  108.   fButtonLayout := pbsImageAbove;
  109.   fButtonState := pbsNormal
  110. end;
  111. destructor TPNGButton.Destroy;
  112. begin
  113.   {Frees the TPNGObject}
  114.   fImageNormal.Free;
  115.   fImageDown.Free;
  116.   fImageDisabled.Free;
  117.   fImageOver.Free;
  118.   {Calls ancestor}
  119.   inherited Destroy;
  120. end;
  121. {Being enabled or disabled}
  122. procedure TPNGButton.CMEnabledChanged(var Message: TMessage);
  123. begin
  124.   if not Enabled then MakeImageHalfTransparent(fImageNormal, fImageDisabled);
  125.   if Enabled then ButtonState := pbsNormal else ButtonState := pbsDisabled
  126. end;
  127. {Button being painted}
  128. procedure TPNGButton.Paint;
  129. const
  130.   Slide: Array[false..true] of Integer = (0, 2);
  131. var
  132.   Area: TRect;
  133.   TextSize, ImageSize: TSize;
  134.   TextPos, ImagePos: TPoint;
  135.   Image: TPNGObject;
  136.   Pushed: Boolean;
  137. begin
  138.   {Prepares the canvas}
  139.   Canvas.Font.Assign(Font);
  140.   {Determines if the button is pushed}
  141.   Pushed := (ButtonState = pbsDown) and IsMouseOver;
  142.   {Determines the image to use}
  143.   if (Pushed) and not fImageDown.Empty then
  144.     Image := fImageDown
  145.   else if IsMouseOver and not fImageOver.Empty and Enabled then
  146.     Image := fImageOver
  147.   else if (ButtonState = pbsDisabled) and not fImageDisabled.Empty then
  148.     Image := fImageDisabled
  149.   else
  150.     Image := fImageNormal;
  151.   {Get the elements size}
  152.   ImageSize.cx := Image.Width;
  153.   ImageSize.cy := Image.Height;
  154.   Area := ClientRect;
  155.   if Caption <> '' then
  156.   begin
  157.     TextSize := Canvas.TextExtent(Caption);
  158.     ImageSize.cy := ImageSize.Cy + 4;
  159.   end;
  160.   {Set the elements position}
  161.   ImagePos.X := (Width - ImageSize.cx) div 2 + Slide[Pushed];
  162.   TextPos.X := (Width - TextSize.cx) div 2 + Slide[Pushed];
  163.   case ButtonLayout of
  164.     pbsImageAbove: begin
  165.       ImagePos.Y := (Height - ImageSize.cy - TextSize.cy) div 2;
  166.       TextPos.Y := ImagePos.Y + ImageSize.cy;
  167.       end;
  168.     pbsImageBellow: begin
  169.       TextPos.Y := (Height - ImageSize.cy - TextSize.cy) div 2;
  170.       ImagePos.Y := TextPos.Y + TextSize.cy;
  171.     end
  172.   end;
  173.   ImagePos.Y := ImagePos.Y + Slide[Pushed];
  174.   TextPos.Y := TextPos.Y + Slide[Pushed];
  175.   {Draws the border}
  176.   if ButtonStyle = pbsFlat then
  177.   begin
  178.     if ButtonState <> pbsDisabled then
  179.       if (Pushed) then
  180.         Frame3D(Canvas, Area, clBtnShadow, clBtnHighlight, 1)
  181.       else if IsMouseOver or (ButtonState = pbsDown) then
  182.         Frame3D(Canvas, Area, clBtnHighlight, clBtnShadow, 1)
  183.   end
  184.   else
  185.     DrawButtonFace(Canvas, Area, 1, bsNew, TRUE, Pushed, FALSE);
  186.   {Draws the elements}
  187.   Canvas.Brush.Style := bsClear;
  188.   Canvas.Draw(ImagePos.X, ImagePos.Y, Image);
  189.   if ButtonState = pbsDisabled then Canvas.Font.Color := clGrayText;
  190.   Canvas.TextRect(Area, TextPos.X, TextPos.Y, Caption)
  191. end;
  192. {Changing the button Layout property}
  193. procedure TPNGButton.SetButtonLayout(const Value: TPNGButtonLayout);
  194. begin
  195.   FButtonLayout := Value;
  196.   Repaint
  197. end;
  198. {Changing the button state property}
  199. procedure TPNGButton.SetButtonState(const Value: TPNGButtonState);
  200. begin
  201.   FButtonState := Value;
  202.   Repaint
  203. end;
  204. {Changing the button style property}
  205. procedure TPNGButton.SetButtonStyle(const Value: TPNGButtonStyle);
  206. begin
  207.   fButtonStyle := Value;
  208.   Repaint
  209. end;
  210. {Changing the caption property}
  211. procedure TPNGButton.SetCaption(const Value: String);
  212. begin
  213.   FCaption := Value;
  214.   Repaint
  215. end;
  216. {Changing the image property}
  217. procedure TPNGButton.SetImageNormal(const Value: TPNGObject);
  218. begin
  219.   fImageNormal.Assign(Value);
  220.   MakeImageHalfTransparent(fImageNormal, fImageDisabled);
  221.   Repaint
  222. end;
  223. {Setting the down image}
  224. procedure TPNGButton.SetImageDown(const Value: TPNGObject);
  225. begin
  226.   FImageDown.Assign(Value);
  227.   Repaint
  228. end;
  229. {Setting the over image}
  230. procedure TPNGButton.SetImageOver(const Value: TPNGObject);
  231. begin
  232.   fImageOver.Assign(Value);
  233.   Repaint
  234. end;
  235. {Mouse pressed}
  236. procedure TPNGButton.MouseDown(Button: TMouseButton; Shift: TShiftState; X,
  237.   Y: Integer);
  238. begin
  239.   {Changes the state and repaints}
  240.   if (ButtonState = pbsNormal) and (Button = mbLeft) then
  241.     ButtonState := pbsDown;
  242.   {Calls ancestor}
  243.   inherited
  244. end;
  245. {Being clicked}
  246. procedure TPNGButton.Click;
  247. begin
  248.   if ButtonState = pbsDown then ButtonState := pbsNormal;
  249.   inherited Click;
  250. end;
  251. {Mouse released}
  252. procedure TPNGButton.MouseUp(Button: TMouseButton; Shift: TShiftState; X,
  253.   Y: Integer);
  254. begin
  255.   {Changes the state and repaints}
  256.   if ButtonState = pbsDown then ButtonState := pbsNormal;
  257.   {Calls ancestor}
  258.   inherited
  259. end;
  260. {Mouse moving over the control}
  261. procedure TPNGButton.MouseMove(Shift: TShiftState; X, Y: Integer);
  262. begin
  263.   {In case cursor is over the button}
  264.   if (X >= 0) and (X < ClientWidth) and (Y >= 0) and (Y <= ClientHeight) and
  265.     (fMouseOverControl = False) and (ButtonState <> pbsDown)  then
  266.   begin
  267.     fMouseOverControl := True;
  268.     Repaint;
  269.   end;
  270.   {Calls ancestor}
  271.   inherited;
  272. end;
  273. {Mouse is now over the control}
  274. procedure TPNGButton.CMMouseEnter(var Message: TMessage);
  275. begin
  276.   fMouseOverControl := True;
  277.   Repaint
  278. end;
  279. {Mouse has left the control}
  280. procedure TPNGButton.CMMouseLeave(var Message: TMessage);
  281. begin
  282.   fMouseOverControl := False;
  283.   Repaint
  284. end;
  285. end.