summaryrefslogtreecommitdiff
path: root/plugins/!NotAdopted/Chess4Net/lib/PNGImage/pngextra.pas
blob: c219e7e22e929ff33397bcb09cbf02050110b377 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
unit pngextra;

interface

uses
  Windows, Graphics, Messages, SysUtils, Classes, Controls, pngimage, Buttons,
  ExtCtrls;

type
  TPNGButtonStyle = (pbsDefault, pbsFlat, pbsNoFrame);
  TPNGButtonLayout = (pbsImageAbove, pbsImageBellow, pbsImageLeft,
    pbsImageRight);
  TPNGButtonState = (pbsNormal, pbsDown, pbsDisabled);

  TPNGButton = class(TGraphicControl)
  private
    {Holds the property values}
    fButtonStyle: TPNGButtonStyle;
    fMouseOverControl: Boolean;
    FCaption: String;
    FButtonLayout: TPNGButtonLayout;
    FButtonState: TPNGButtonState;
    FImageDown: TPNGObject;
    fImageNormal: TPNGObject;
    fImageDisabled: TPNGObject;
    fImageOver: TPNGObject;
    fOnMouseEnter, fOnMouseExit: TNotifyEvent;
    {Procedures for setting the property values}
    procedure SetButtonStyle(const Value: TPNGButtonStyle);
    procedure SetCaption(const Value: String);
    procedure SetButtonLayout(const Value: TPNGButtonLayout);
    procedure SetButtonState(const Value: TPNGButtonState);
    procedure SetImageNormal(const Value: TPNGObject);
    procedure SetImageDown(const Value: TPNGObject);
    procedure SetImageOver(const Value: TPNGObject);
  published
    {Published properties}
    property Font;
    property Visible;
    property ButtonLayout: TPNGButtonLayout read FButtonLayout write SetButtonLayout;
    property Caption: String read FCaption write SetCaption;
    property ImageNormal: TPNGObject read fImageNormal write SetImageNormal;
    property ImageDown: TPNGObject read FImageDown write SetImageDown;
    property ImageOver: TPNGObject read FImageOver write SetImageOver;
    property ButtonStyle: TPNGButtonStyle read fButtonStyle
      write SetButtonStyle;
    property Enabled;
    property ParentShowHint;
    property ShowHint;
    {Default events}
    property OnMouseDown;
    property OnClick;
    property OnMouseUp;
    property OnMouseMove;
    property OnDblClick;
    property OnMouseEnter: TNotifyEvent read fOnMouseEnter write fOnMouseEnter;
    property OnMouseExit:  TNotifyEvent read fOnMouseExit  write fOnMouseExit;
  public
    {Public properties}
    property ButtonState: TPNGButtonState read FButtonState write SetButtonState;
  protected
    {Being painted}
    procedure Paint; override;
    {Clicked}
    procedure Click; override;
    {Mouse pressed}
    procedure MouseDown(Button: TMouseButton; Shift: TShiftState;
      X, Y: Integer); override;
    procedure MouseUp(Button: TMouseButton; Shift: TShiftState;
      X, Y: Integer); override;
    procedure MouseMove(Shift: TShiftState; X, Y: Integer); override;
    {Mouse entering or leaving}
    procedure CMMouseEnter(var Message: TMessage); message CM_MOUSEENTER;
    procedure CMMouseLeave(var Message: TMessage); message CM_MOUSELEAVE;
    {Being enabled or disabled}
    procedure CMEnabledChanged(var Message: TMessage);
      message CM_ENABLEDCHANGED;
  public
    {Returns if the mouse is over the control}
    property IsMouseOver: Boolean read fMouseOverControl;
    {Constructor and destructor}
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
  end;

procedure Register;
procedure MakeImageHalfTransparent(Source, Dest: TPNGObject);

implementation

procedure Register;
begin
  RegisterComponents('Samples', [TPNGButton]);
end;

procedure MakeImageHalfTransparent(Source, Dest: TPNGObject);
var
  i, j: Integer;
begin
  Dest.Assign(Source);
  Dest.CreateAlpha;
  if (Dest.Header.ColorType <> COLOR_PALETTE) then
    for j := 0 to Source.Height - 1 do
      for i := 0 to Source.Width - 1 do
        Dest.AlphaScanline[j]^[i] := Dest.AlphaScanline[j]^[i] div 3;
end;

{TPNGButton implementation}

{Being created}
constructor TPNGButton.Create(AOwner: TComponent);
begin
  {Calls ancestor}
  inherited Create(AOwner);
  {Creates the TPNGObjects}
  fImageNormal := TPNGObject.Create;
  fImageDown := TPNGObject.Create;
  fImageDisabled := TPNGObject.Create;
  fImageOver := TPNGObject.Create;
  {Initial properties}
  ControlStyle := ControlStyle + [csCaptureMouse];
  SetBounds(Left, Top, 23, 23);
  fMouseOverControl := False;
  fButtonLayout := pbsImageAbove;
  fButtonState := pbsNormal
end;

destructor TPNGButton.Destroy;
begin
  {Frees the TPNGObject}
  fImageNormal.Free;
  fImageDown.Free;
  fImageDisabled.Free;
  fImageOver.Free;

  {Calls ancestor}
  inherited Destroy;
end;

{Being enabled or disabled}
procedure TPNGButton.CMEnabledChanged(var Message: TMessage);
begin
  if not Enabled then MakeImageHalfTransparent(fImageNormal, fImageDisabled);
  if Enabled then ButtonState := pbsNormal else ButtonState := pbsDisabled
end;

{Returns the largest number}
function Max(A, B: Integer): Integer;
begin
  if A > B then Result := A else Result := B
end;

{Button being painted}
procedure TPNGButton.Paint;
const
  Slide: Array[false..true] of Integer = (0, 2);
var
  Area: TRect;
  TextSize, ImageSize: TSize;
  TextPos, ImagePos: TPoint;
  Image: TPNGObject;
  Pushed: Boolean;
begin
  {Prepares the canvas}
  Canvas.Font.Assign(Font);

  {Determines if the button is pushed}
  Pushed := (ButtonState = pbsDown) and IsMouseOver;

  {Determines the image to use}
  if (Pushed) and not fImageDown.Empty then
    Image := fImageDown
  else if IsMouseOver and not fImageOver.Empty and Enabled then
    Image := fImageOver
  else if (ButtonState = pbsDisabled) and not fImageDisabled.Empty then
    Image := fImageDisabled
  else
    Image := fImageNormal;

  {Get the elements size}
  ImageSize.cx := Image.Width;
  ImageSize.cy := Image.Height;
  Area := ClientRect;
  if Caption <> '' then
  begin
    TextSize := Canvas.TextExtent(Caption);
    ImageSize.cy := ImageSize.Cy + 4;
  end else FillChar(TextSize, SizeOf(TextSize), #0);

  {Set the elements position}
  ImagePos.X := (Width - ImageSize.cx) div 2 + Slide[Pushed];
  TextPos.X := (Width - TextSize.cx) div 2 + Slide[Pushed];
  TextPos.Y := (Height - TextSize.cy) div 2;
  ImagePos.Y := (Height - ImageSize.cy) div 2;
  case ButtonLayout of
    pbsImageAbove: begin
      ImagePos.Y := (Height - ImageSize.cy - TextSize.cy) div 2;
      TextPos.Y := ImagePos.Y + ImageSize.cy;
      end;
    pbsImageBellow: begin
      TextPos.Y := (Height - ImageSize.cy - TextSize.cy) div 2;
      ImagePos.Y := TextPos.Y + TextSize.cy;
      end;
    pbsImageLeft: begin
      ImagePos.X := (Width - ImageSize.cx - TextSize.cx) div 2;
      TextPos.X := ImagePos.X + ImageSize.cx + 5;
      end;
    pbsImageRight: begin
      TextPos.X := (Width - ImageSize.cx - TextSize.cx) div 2;;
      ImagePos.X := TextPos.X + TextSize.cx + 5;
    end
  end;
  ImagePos.Y := ImagePos.Y + Slide[Pushed];
  TextPos.Y := TextPos.Y + Slide[Pushed];

  {Draws the border}
  if ButtonStyle = pbsFlat then
  begin
    if ButtonState <> pbsDisabled then
      if (Pushed) then
        Frame3D(Canvas, Area, clBtnShadow, clBtnHighlight, 1)
      else if IsMouseOver or (ButtonState = pbsDown) then
        Frame3D(Canvas, Area, clBtnHighlight, clBtnShadow, 1)
  end
  else if ButtonStyle = pbsDefault then
    DrawButtonFace(Canvas, Area, 1, bsNew, TRUE, Pushed, FALSE);

  {Draws the elements}
  Canvas.Brush.Style := bsClear;
  Canvas.Draw(ImagePos.X, ImagePos.Y, Image);
  if ButtonState = pbsDisabled then Canvas.Font.Color := clGrayText;
  Canvas.TextRect(Area, TextPos.X, TextPos.Y, Caption)
end;

{Changing the button Layout property}
procedure TPNGButton.SetButtonLayout(const Value: TPNGButtonLayout);
begin
  FButtonLayout := Value;
  Repaint
end;

{Changing the button state property}
procedure TPNGButton.SetButtonState(const Value: TPNGButtonState);
begin
  FButtonState := Value;
  Repaint
end;

{Changing the button style property}
procedure TPNGButton.SetButtonStyle(const Value: TPNGButtonStyle);
begin
  fButtonStyle := Value;
  Repaint
end;

{Changing the caption property}
procedure TPNGButton.SetCaption(const Value: String);
begin
  FCaption := Value;
  Repaint
end;

{Changing the image property}
procedure TPNGButton.SetImageNormal(const Value: TPNGObject);
begin
  fImageNormal.Assign(Value);
  MakeImageHalfTransparent(fImageNormal, fImageDisabled);
  Repaint
end;

{Setting the down image}
procedure TPNGButton.SetImageDown(const Value: TPNGObject);
begin
  FImageDown.Assign(Value);
  Repaint
end;

{Setting the over image}
procedure TPNGButton.SetImageOver(const Value: TPNGObject);
begin
  fImageOver.Assign(Value);
  Repaint
end;

{Mouse pressed}
procedure TPNGButton.MouseDown(Button: TMouseButton; Shift: TShiftState; X,
  Y: Integer);
begin
  {Changes the state and repaints}
  if (ButtonState = pbsNormal) and (Button = mbLeft) then
    ButtonState := pbsDown;
  {Calls ancestor}
  inherited
end;

{Being clicked}
procedure TPNGButton.Click;
begin
  if ButtonState = pbsDown then ButtonState := pbsNormal;
  inherited Click;
end;

{Mouse released}
procedure TPNGButton.MouseUp(Button: TMouseButton; Shift: TShiftState; X,
  Y: Integer);
begin
  {Changes the state and repaints}
  if ButtonState = pbsDown then ButtonState := pbsNormal;
  {Calls ancestor}
  inherited
end;

{Mouse moving over the control}
procedure TPNGButton.MouseMove(Shift: TShiftState; X, Y: Integer);
begin
  {In case cursor is over the button}
  if (X >= 0) and (X < ClientWidth) and (Y >= 0) and (Y <= ClientHeight) and
    (fMouseOverControl = False) and (ButtonState <> pbsDown)  then
  begin
    fMouseOverControl := True;
    Repaint;
  end;

  {Calls ancestor}
  inherited;

end;

{Mouse is now over the control}
procedure TPNGButton.CMMouseEnter(var Message: TMessage);
begin
  if Enabled then
  begin
    if Assigned(fOnMouseEnter) then fOnMouseEnter(Self);
    fMouseOverControl := True;
    Repaint
  end
end;

{Mouse has left the control}
procedure TPNGButton.CMMouseLeave(var Message: TMessage);
begin
  if Enabled then
  begin
    if Assigned(fOnMouseExit) then FOnMouseExit(Self);
    fMouseOverControl := False;
    Repaint
  end
end;



end.