| 1 | { !! THIS CONTROL IS DEPRECATED! USE BCBUTTON INSTEAD !!
|
|---|
| 2 | Panel with BGRAGradient functionality
|
|---|
| 3 |
|
|---|
| 4 | Copyright (C) 2011 Krzysztof Dibowski dibowski at interia.pl
|
|---|
| 5 |
|
|---|
| 6 | This library is free software; you can redistribute it and/or modify it
|
|---|
| 7 | under the terms of the GNU Library General Public License as published by
|
|---|
| 8 | the Free Software Foundation; either version 2 of the License, or (at your
|
|---|
| 9 | option) any later version with the following modification:
|
|---|
| 10 |
|
|---|
| 11 | As a special exception, the copyright holders of this library give you
|
|---|
| 12 | permission to link this library with independent modules to produce an
|
|---|
| 13 | executable, regardless of the license terms of these independent modules,and
|
|---|
| 14 | to copy and distribute the resulting executable under terms of your choice,
|
|---|
| 15 | provided that you also meet, for each linked independent module, the terms
|
|---|
| 16 | and conditions of the license of that module. An independent module is a
|
|---|
| 17 | module which is not derived from or based on this library. If you modify
|
|---|
| 18 | this library, you may extend this exception to your version of the library,
|
|---|
| 19 | but you are not obligated to do so. If you do not wish to do so, delete this
|
|---|
| 20 | exception statement from your version.
|
|---|
| 21 |
|
|---|
| 22 | This program is distributed in the hope that it will be useful, but WITHOUT
|
|---|
| 23 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|---|
| 24 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License
|
|---|
| 25 | for more details.
|
|---|
| 26 |
|
|---|
| 27 | You should have received a copy of the GNU Library General Public License
|
|---|
| 28 | along with this library; if not, write to the Free Software Foundation,
|
|---|
| 29 | Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|---|
| 30 | }
|
|---|
| 31 | unit BGRAPanel;
|
|---|
| 32 |
|
|---|
| 33 | {$mode objfpc}{$H+}
|
|---|
| 34 |
|
|---|
| 35 | interface
|
|---|
| 36 |
|
|---|
| 37 | uses
|
|---|
| 38 | Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs,
|
|---|
| 39 | ExtCtrls, BGRABitmap, LMessages,
|
|---|
| 40 | BGRABitmapTypes, BGRAGradientScanner, BCTypes, Types;
|
|---|
| 41 |
|
|---|
| 42 | type
|
|---|
| 43 | TBGRAPanelBackStyle = (bpsColor, bpsGradient);
|
|---|
| 44 | TOnAfterPrepareBGRAPanel = procedure(Sender: TObject; const ABGRA: TBGRABitmap;
|
|---|
| 45 | ARect: TRect) of object;
|
|---|
| 46 |
|
|---|
| 47 | { TBGRAPanel }
|
|---|
| 48 |
|
|---|
| 49 | TBGRAPanel = class(TPanel)
|
|---|
| 50 | private
|
|---|
| 51 | { Private declarations }
|
|---|
| 52 | FBGRA: TBGRABitmap;
|
|---|
| 53 | FBackgroundStyle: TBGRAPanelBackStyle;
|
|---|
| 54 | FCaptionAlignment: TAlignment;
|
|---|
| 55 | FCaptionLayout: TTextLayout;
|
|---|
| 56 | FCaptionOffsetX: integer;
|
|---|
| 57 | FCaptionOffsetY: integer;
|
|---|
| 58 | FCaptionShadow: boolean;
|
|---|
| 59 | FCaptionShadowColor: TColor;
|
|---|
| 60 | FCaptionShadowRadius: integer;
|
|---|
| 61 | FCaptionShadowX: integer;
|
|---|
| 62 | FCaptionShadowY: integer;
|
|---|
| 63 | FGradient: TBCGradient;
|
|---|
| 64 | FOnAfterPrepareBGRAPanel: TOnAfterPrepareBGRAPanel;
|
|---|
| 65 | FUpdateCount: integer;
|
|---|
| 66 | procedure DrawGradient;
|
|---|
| 67 | procedure PrepareBGRA;
|
|---|
| 68 | procedure SetBackgroundStyle(const AValue: TBGRAPanelBackStyle);
|
|---|
| 69 | procedure SetCaptionAlignment(AValue: TAlignment);
|
|---|
| 70 | procedure SetCaptionLayout(AValue: TTextLayout);
|
|---|
| 71 | procedure SetCaptionOffsetX(AValue: integer);
|
|---|
| 72 | procedure SetCaptionOffsetY(AValue: integer);
|
|---|
| 73 | procedure SetCaptionShadow(AValue: boolean);
|
|---|
| 74 | procedure SetCaptionShadowColor(AValue: TColor);
|
|---|
| 75 | procedure SetCaptionShadowRadius(AValue: integer);
|
|---|
| 76 | procedure SetCaptionShadowX(AValue: integer);
|
|---|
| 77 | procedure SetCaptionShadowY(AValue: integer);
|
|---|
| 78 | procedure SetGradient(const AValue: TBCGradient);
|
|---|
| 79 | protected
|
|---|
| 80 | procedure CMChanged(var Message: TLMessage); message CM_CHANGED;
|
|---|
| 81 | procedure FontChanged(Sender: TObject); override;
|
|---|
| 82 | protected
|
|---|
| 83 | { Protected declarations }
|
|---|
| 84 | procedure Paint; override;
|
|---|
| 85 | procedure Resize; override;
|
|---|
| 86 | procedure SetEnabled(Value: boolean); override;
|
|---|
| 87 | public
|
|---|
| 88 | { Public declarations }
|
|---|
| 89 | constructor Create(TheOwner: TComponent); override;
|
|---|
| 90 | destructor Destroy; override;
|
|---|
| 91 |
|
|---|
| 92 | procedure BeginUpdate; virtual;
|
|---|
| 93 | procedure EndUpdate; virtual;
|
|---|
| 94 | published
|
|---|
| 95 | { Published declarations }
|
|---|
| 96 | property BackgroundStyle: TBGRAPanelBackStyle
|
|---|
| 97 | Read FBackgroundStyle Write SetBackgroundStyle default bpsGradient;
|
|---|
| 98 | property CaptionAlignment: TAlignment Read FCaptionAlignment
|
|---|
| 99 | Write SetCaptionAlignment default taCenter;
|
|---|
| 100 | property CaptionLayout: TTextLayout Read FCaptionLayout
|
|---|
| 101 | Write SetCaptionLayout default tlCenter;
|
|---|
| 102 | property CaptionOffsetX: integer Read FCaptionOffsetX
|
|---|
| 103 | Write SetCaptionOffsetX default 0;
|
|---|
| 104 | property CaptionOffsetY: integer Read FCaptionOffsetY
|
|---|
| 105 | Write SetCaptionOffsetY default 0;
|
|---|
| 106 | property CaptionShadow: boolean
|
|---|
| 107 | Read FCaptionShadow Write SetCaptionShadow default False;
|
|---|
| 108 | property CaptionShadowColor: TColor Read FCaptionShadowColor
|
|---|
| 109 | Write SetCaptionShadowColor default clBlack;
|
|---|
| 110 | property CaptionShadowX: integer Read FCaptionShadowX
|
|---|
| 111 | Write SetCaptionShadowX default 1;
|
|---|
| 112 | property CaptionShadowY: integer Read FCaptionShadowY
|
|---|
| 113 | Write SetCaptionShadowY default 1;
|
|---|
| 114 | property CaptionShadowRadius: integer Read FCaptionShadowRadius
|
|---|
| 115 | Write SetCaptionShadowRadius default 3;
|
|---|
| 116 | property Gradient: TBCGradient Read FGradient Write SetGradient;
|
|---|
| 117 | published
|
|---|
| 118 | { Events }
|
|---|
| 119 | property OnAfterPrepareBGRAPanel: TOnAfterPrepareBGRAPanel
|
|---|
| 120 | Read FOnAfterPrepareBGRAPanel Write FOnAfterPrepareBGRAPanel;
|
|---|
| 121 | end;
|
|---|
| 122 |
|
|---|
| 123 | procedure Register;
|
|---|
| 124 |
|
|---|
| 125 | implementation
|
|---|
| 126 |
|
|---|
| 127 | uses BCTools;
|
|---|
| 128 |
|
|---|
| 129 | procedure Register;
|
|---|
| 130 | begin
|
|---|
| 131 | {$I bgrapanel_icon.lrs}
|
|---|
| 132 | RegisterComponents('BGRA Controls', [TBGRAPanel]);
|
|---|
| 133 | end;
|
|---|
| 134 |
|
|---|
| 135 | { TBGRAPanel }
|
|---|
| 136 |
|
|---|
| 137 | procedure TBGRAPanel.SetBackgroundStyle(const AValue: TBGRAPanelBackStyle);
|
|---|
| 138 | begin
|
|---|
| 139 | if FBackgroundStyle = AValue then
|
|---|
| 140 | exit;
|
|---|
| 141 | FBackgroundStyle := AValue;
|
|---|
| 142 |
|
|---|
| 143 | Changed;
|
|---|
| 144 | Invalidate;
|
|---|
| 145 | end;
|
|---|
| 146 |
|
|---|
| 147 | procedure TBGRAPanel.SetCaptionAlignment(AValue: TAlignment);
|
|---|
| 148 | begin
|
|---|
| 149 | if FCaptionAlignment = AValue then
|
|---|
| 150 | Exit;
|
|---|
| 151 | FCaptionAlignment := AValue;
|
|---|
| 152 | Changed;
|
|---|
| 153 | Invalidate;
|
|---|
| 154 | end;
|
|---|
| 155 |
|
|---|
| 156 | procedure TBGRAPanel.SetCaptionLayout(AValue: TTextLayout);
|
|---|
| 157 | begin
|
|---|
| 158 | if FCaptionLayout = AValue then
|
|---|
| 159 | Exit;
|
|---|
| 160 | FCaptionLayout := AValue;
|
|---|
| 161 | Changed;
|
|---|
| 162 | Invalidate;
|
|---|
| 163 | end;
|
|---|
| 164 |
|
|---|
| 165 | procedure TBGRAPanel.SetCaptionOffsetX(AValue: integer);
|
|---|
| 166 | begin
|
|---|
| 167 | if FCaptionOffsetX = AValue then
|
|---|
| 168 | Exit;
|
|---|
| 169 | FCaptionOffsetX := AValue;
|
|---|
| 170 | Changed;
|
|---|
| 171 | Invalidate;
|
|---|
| 172 | end;
|
|---|
| 173 |
|
|---|
| 174 | procedure TBGRAPanel.SetCaptionOffsetY(AValue: integer);
|
|---|
| 175 | begin
|
|---|
| 176 | if FCaptionOffsetY = AValue then
|
|---|
| 177 | Exit;
|
|---|
| 178 | FCaptionOffsetY := AValue;
|
|---|
| 179 | Changed;
|
|---|
| 180 | Invalidate;
|
|---|
| 181 | end;
|
|---|
| 182 |
|
|---|
| 183 | procedure TBGRAPanel.SetCaptionShadow(AValue: boolean);
|
|---|
| 184 | begin
|
|---|
| 185 | if FCaptionShadow = AValue then
|
|---|
| 186 | Exit;
|
|---|
| 187 | FCaptionShadow := AValue;
|
|---|
| 188 | Changed;
|
|---|
| 189 | Invalidate;
|
|---|
| 190 | end;
|
|---|
| 191 |
|
|---|
| 192 | procedure TBGRAPanel.SetCaptionShadowColor(AValue: TColor);
|
|---|
| 193 | begin
|
|---|
| 194 | if FCaptionShadowColor = AValue then
|
|---|
| 195 | Exit;
|
|---|
| 196 | FCaptionShadowColor := AValue;
|
|---|
| 197 | Changed;
|
|---|
| 198 | Invalidate;
|
|---|
| 199 | end;
|
|---|
| 200 |
|
|---|
| 201 | procedure TBGRAPanel.SetCaptionShadowRadius(AValue: integer);
|
|---|
| 202 | begin
|
|---|
| 203 | if FCaptionShadowRadius = AValue then
|
|---|
| 204 | Exit;
|
|---|
| 205 | FCaptionShadowRadius := AValue;
|
|---|
| 206 | Changed;
|
|---|
| 207 | Invalidate;
|
|---|
| 208 | end;
|
|---|
| 209 |
|
|---|
| 210 | procedure TBGRAPanel.SetCaptionShadowX(AValue: integer);
|
|---|
| 211 | begin
|
|---|
| 212 | if FCaptionShadowX = AValue then
|
|---|
| 213 | Exit;
|
|---|
| 214 | FCaptionShadowX := AValue;
|
|---|
| 215 | Changed;
|
|---|
| 216 | Invalidate;
|
|---|
| 217 | end;
|
|---|
| 218 |
|
|---|
| 219 | procedure TBGRAPanel.SetCaptionShadowY(AValue: integer);
|
|---|
| 220 | begin
|
|---|
| 221 | if FCaptionShadowY = AValue then
|
|---|
| 222 | Exit;
|
|---|
| 223 | FCaptionShadowY := AValue;
|
|---|
| 224 | Changed;
|
|---|
| 225 | Invalidate;
|
|---|
| 226 | end;
|
|---|
| 227 |
|
|---|
| 228 | procedure TBGRAPanel.SetGradient(const AValue: TBCGradient);
|
|---|
| 229 | begin
|
|---|
| 230 | if FGradient = AValue then
|
|---|
| 231 | exit;
|
|---|
| 232 | FGradient.Assign(AValue);
|
|---|
| 233 | Changed;
|
|---|
| 234 | Invalidate;
|
|---|
| 235 | end;
|
|---|
| 236 |
|
|---|
| 237 | procedure TBGRAPanel.CMChanged(var Message: TLMessage);
|
|---|
| 238 | begin
|
|---|
| 239 | if FUpdateCount > 0 then
|
|---|
| 240 | Exit;
|
|---|
| 241 | PrepareBGRA;
|
|---|
| 242 | end;
|
|---|
| 243 |
|
|---|
| 244 | procedure TBGRAPanel.FontChanged(Sender: TObject);
|
|---|
| 245 | begin
|
|---|
| 246 | inherited FontChanged(Sender);
|
|---|
| 247 | Changed;
|
|---|
| 248 | Invalidate;
|
|---|
| 249 | end;
|
|---|
| 250 |
|
|---|
| 251 | procedure TBGRAPanel.DrawGradient;
|
|---|
| 252 | var
|
|---|
| 253 | sc: TBGRAGradientScanner;
|
|---|
| 254 | begin
|
|---|
| 255 | sc := CreateGradient(FGradient, ClientRect);
|
|---|
| 256 | FBGRA.Fill(sc);
|
|---|
| 257 | sc.Free;
|
|---|
| 258 | end;
|
|---|
| 259 |
|
|---|
| 260 | procedure TBGRAPanel.PrepareBGRA;
|
|---|
| 261 | var
|
|---|
| 262 | ARect: TRect;
|
|---|
| 263 | TS: TTextStyle;
|
|---|
| 264 | txt: TBGRABitmap;
|
|---|
| 265 | begin
|
|---|
| 266 | if (csCreating in FControlState) or (FUpdateCount > 0) then
|
|---|
| 267 | Exit;
|
|---|
| 268 |
|
|---|
| 269 | FBGRA.SetSize(Width, Height);
|
|---|
| 270 |
|
|---|
| 271 | if FBackgroundStyle = bpsGradient then
|
|---|
| 272 | DrawGradient
|
|---|
| 273 | else
|
|---|
| 274 | FBGRA.Fill(ColorToRGB(Color));
|
|---|
| 275 |
|
|---|
| 276 | ARect := GetClientRect;
|
|---|
| 277 |
|
|---|
| 278 | // if BevelOuter is set then draw a frame with BevelWidth
|
|---|
| 279 | if (BevelOuter <> bvNone) and (BevelWidth > 0) then
|
|---|
| 280 | FBGRA.CanvasBGRA.Frame3d(ARect, BevelWidth, BevelOuter,
|
|---|
| 281 | BGRA(255, 255, 255, 180), BGRA(0, 0, 0, 160)); // Note: Frame3D inflates ARect
|
|---|
| 282 |
|
|---|
| 283 | InflateRect(ARect, -BorderWidth, -BorderWidth);
|
|---|
| 284 |
|
|---|
| 285 | // if BevelInner is set then skip the BorderWidth and draw a frame with BevelWidth
|
|---|
| 286 | if (BevelInner <> bvNone) and (BevelWidth > 0) then
|
|---|
| 287 | FBGRA.CanvasBGRA.Frame3d(ARect, BevelWidth, BevelInner,
|
|---|
| 288 | BGRA(255, 255, 255, 160), BGRA(0, 0, 0, 160)); // Note: Frame3D inflates ARect
|
|---|
| 289 |
|
|---|
| 290 | if Caption <> '' then
|
|---|
| 291 | begin
|
|---|
| 292 | txt := TBGRABitmap.Create(FBGRA.Width, FBGRA.Height, BGRAPixelTransparent);
|
|---|
| 293 | try
|
|---|
| 294 | txt.CanvasBGRA.Font.Assign(Font);
|
|---|
| 295 | txt.Canvas.Font.Assign(Font);
|
|---|
| 296 | //FBGRA.CanvasBGRA.Font.Assign(Canvas.Font);
|
|---|
| 297 | TS := Canvas.TextStyle;
|
|---|
| 298 | TS.Alignment := FCaptionAlignment;
|
|---|
| 299 | TS.Layout := FCaptionLayout;
|
|---|
| 300 | TS.Opaque := False;
|
|---|
| 301 | TS.Clipping := False;
|
|---|
| 302 | TS.SystemFont := Canvas.Font.IsDefault;
|
|---|
| 303 | OffsetRect(ARect, FCaptionOffsetX, FCaptionOffsetY);
|
|---|
| 304 | if FCaptionShadow then
|
|---|
| 305 | begin
|
|---|
| 306 | OffsetRect(ARect, FCaptionShadowX, FCaptionShadowY);
|
|---|
| 307 | txt.CanvasBGRA.Font.BGRAColor := ColorToBGRA(FCaptionShadowColor);
|
|---|
| 308 | txt.CanvasBGRA.TextRect(ARect, ARect.Left, ARect.Top, Caption, TS);
|
|---|
| 309 | BGRAReplace(txt, txt.FilterBlurRadial(FCaptionShadowRadius, rbFast));
|
|---|
| 310 | txt.CanvasBGRA.Font.Color := Font.Color;
|
|---|
| 311 | OffsetRect(ARect, -FCaptionShadowX, -FCaptionShadowY);
|
|---|
| 312 | txt.CanvasBGRA.Font.Assign(Font);
|
|---|
| 313 | txt.Canvas.Font.Assign(Font);
|
|---|
| 314 | end;
|
|---|
| 315 | if not Enabled then
|
|---|
| 316 | begin
|
|---|
| 317 | txt.CanvasBGRA.Font.BGRAColor := BGRA(255, 255, 255, 160);
|
|---|
| 318 | OffsetRect(ARect, 1, 1);
|
|---|
| 319 | txt.CanvasBGRA.TextRect(ARect, ARect.Left, ARect.Top, Caption, TS);
|
|---|
| 320 | txt.CanvasBGRA.Font.BGRAColor := BGRA(0, 0, 0, 160);
|
|---|
| 321 | OffsetRect(ARect, -1, -1);
|
|---|
| 322 | end
|
|---|
| 323 | else
|
|---|
| 324 | txt.CanvasBGRA.Font.Color := Font.Color;
|
|---|
| 325 |
|
|---|
| 326 | txt.CanvasBGRA.TextRect(ARect, ARect.Left, ARect.Top, Caption, TS);
|
|---|
| 327 | FBGRA.PutImage(0, 0, txt, dmDrawWithTransparency);
|
|---|
| 328 | OffsetRect(ARect, -FCaptionOffsetX, -FCaptionOffsetY);
|
|---|
| 329 | finally
|
|---|
| 330 | txt.Free;
|
|---|
| 331 | end;
|
|---|
| 332 | end;
|
|---|
| 333 | if Assigned(FOnAfterPrepareBGRAPanel) then
|
|---|
| 334 | FOnAfterPrepareBGRAPanel(Self, FBGRA, ARect);
|
|---|
| 335 | end;
|
|---|
| 336 |
|
|---|
| 337 | procedure TBGRAPanel.Paint;
|
|---|
| 338 | begin
|
|---|
| 339 | if (csCreating in FControlState) or (FUpdateCount > 0) then
|
|---|
| 340 | Exit;
|
|---|
| 341 | FBGRA.Draw(Canvas, 0, 0);
|
|---|
| 342 | end;
|
|---|
| 343 |
|
|---|
| 344 | procedure TBGRAPanel.Resize;
|
|---|
| 345 | begin
|
|---|
| 346 | inherited Resize;
|
|---|
| 347 | if FBGRA <> nil then
|
|---|
| 348 | PrepareBGRA;
|
|---|
| 349 | end;
|
|---|
| 350 |
|
|---|
| 351 | procedure TBGRAPanel.SetEnabled(Value: boolean);
|
|---|
| 352 | begin
|
|---|
| 353 | inherited SetEnabled(Value);
|
|---|
| 354 | Changed;
|
|---|
| 355 | end;
|
|---|
| 356 |
|
|---|
| 357 | constructor TBGRAPanel.Create(TheOwner: TComponent);
|
|---|
| 358 | begin
|
|---|
| 359 | inherited Create(TheOwner);
|
|---|
| 360 | DisableAutoSizing;
|
|---|
| 361 | Include(FControlState, csCreating);
|
|---|
| 362 | BeginUpdate;
|
|---|
| 363 | try
|
|---|
| 364 | Self.DoubleBuffered := True;
|
|---|
| 365 | FBGRA := TBGRABitmap.Create;
|
|---|
| 366 | FGradient := TBCGradient.Create(Self);
|
|---|
| 367 | FBackgroundStyle := bpsGradient;
|
|---|
| 368 | FUpdateCount := 0;
|
|---|
| 369 | FCaptionAlignment := taCenter;
|
|---|
| 370 | FCaptionLayout := tlCenter;
|
|---|
| 371 | FCaptionOffsetX := 0;
|
|---|
| 372 | FCaptionOffsetY := 0;
|
|---|
| 373 | FCaptionShadow := False;
|
|---|
| 374 | FCaptionShadowColor := clBlack;
|
|---|
| 375 | FCaptionShadowX := 1;
|
|---|
| 376 | FCaptionShadowY := 1;
|
|---|
| 377 | FCaptionShadowRadius := 3;
|
|---|
| 378 | finally
|
|---|
| 379 | EnableAutoSizing;
|
|---|
| 380 | EndUpdate;
|
|---|
| 381 | Exclude(FControlState, csCreating);
|
|---|
| 382 | end;
|
|---|
| 383 | end;
|
|---|
| 384 |
|
|---|
| 385 | destructor TBGRAPanel.Destroy;
|
|---|
| 386 | begin
|
|---|
| 387 | FBGRA.Free;
|
|---|
| 388 | FGradient.Free;
|
|---|
| 389 | inherited Destroy;
|
|---|
| 390 | end;
|
|---|
| 391 |
|
|---|
| 392 | procedure TBGRAPanel.BeginUpdate;
|
|---|
| 393 | begin
|
|---|
| 394 | Inc(FUpdateCount);
|
|---|
| 395 | end;
|
|---|
| 396 |
|
|---|
| 397 | procedure TBGRAPanel.EndUpdate;
|
|---|
| 398 | begin
|
|---|
| 399 | if FUpdateCount > 0 then
|
|---|
| 400 | Dec(FUpdateCount);
|
|---|
| 401 | if FUpdateCount = 0 then
|
|---|
| 402 | PrepareBGRA;
|
|---|
| 403 | end;
|
|---|
| 404 |
|
|---|
| 405 | end.
|
|---|