| 1 | unit BGRAKnob;
|
|---|
| 2 |
|
|---|
| 3 | {$mode objfpc}{$H+}
|
|---|
| 4 |
|
|---|
| 5 | interface
|
|---|
| 6 |
|
|---|
| 7 | uses
|
|---|
| 8 | Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs,
|
|---|
| 9 | BGRAGradients, BGRABitmap, BGRABitmapTypes;
|
|---|
| 10 |
|
|---|
| 11 | type
|
|---|
| 12 | TBGRAKnobPositionType = (kptLineSquareCap, kptLineRoundCap, kptFilledCircle,
|
|---|
| 13 | kptHollowCircle);
|
|---|
| 14 | TBGRAKnobValueChangedEvent = procedure(Sender: TObject; Value: single) of object;
|
|---|
| 15 |
|
|---|
| 16 | { TBGRAKnob }
|
|---|
| 17 |
|
|---|
| 18 | TBGRAKnob = class(TGraphicControl)
|
|---|
| 19 | private
|
|---|
| 20 | { Private declarations }
|
|---|
| 21 | FPhong: TPhongShading;
|
|---|
| 22 | FCurveExponent: single;
|
|---|
| 23 | FKnobBmp: TBGRABitmap;
|
|---|
| 24 | FKnobColor: TColor;
|
|---|
| 25 | FAngularPos: single;
|
|---|
| 26 | FPositionColor: TColor;
|
|---|
| 27 | FPositionMargin: single;
|
|---|
| 28 | FPositionOpacity: byte;
|
|---|
| 29 | FPositionType: TBGRAKnobPositionType;
|
|---|
| 30 | FPositionWidth: single;
|
|---|
| 31 | FSettingAngularPos: boolean;
|
|---|
| 32 | FUsePhongLighting: boolean;
|
|---|
| 33 | FMinValue, FMaxValue: single;
|
|---|
| 34 | FOnKnobValueChange: TBGRAKnobValueChangedEvent;
|
|---|
| 35 | FStartFromBottom: boolean;
|
|---|
| 36 | procedure CreateKnobBmp;
|
|---|
| 37 | function GetLightIntensity: integer;
|
|---|
| 38 | function GetValue: single;
|
|---|
| 39 | procedure SetCurveExponent(const AValue: single);
|
|---|
| 40 | procedure SetLightIntensity(const AValue: integer);
|
|---|
| 41 | procedure SetStartFromBottom(const AValue: boolean);
|
|---|
| 42 | procedure SetValue(AValue: single);
|
|---|
| 43 | procedure SetMaxValue(AValue: single);
|
|---|
| 44 | procedure SetMinValue(AValue: single);
|
|---|
| 45 | procedure SetPositionColor(const AValue: TColor);
|
|---|
| 46 | procedure SetPositionMargin(AValue: single);
|
|---|
| 47 | procedure SetPositionOpacity(const AValue: byte);
|
|---|
| 48 | procedure SetPositionType(const AValue: TBGRAKnobPositionType);
|
|---|
| 49 | procedure SetPositionWidth(const AValue: single);
|
|---|
| 50 | procedure SetUsePhongLighting(const AValue: boolean);
|
|---|
| 51 | procedure UpdateAngularPos(X, Y: integer);
|
|---|
| 52 | procedure SetKnobColor(const AValue: TColor);
|
|---|
| 53 | protected
|
|---|
| 54 | { Protected declarations }
|
|---|
| 55 | procedure MouseDown(Button: TMouseButton; Shift: TShiftState;
|
|---|
| 56 | X, Y: integer); override;
|
|---|
| 57 | procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: integer); override;
|
|---|
| 58 | procedure MouseMove(Shift: TShiftState; X, Y: integer); override;
|
|---|
| 59 | procedure Paint; override;
|
|---|
| 60 | procedure Resize; override;
|
|---|
| 61 | function ValueCorrection(var AValue: single): boolean; virtual; overload;
|
|---|
| 62 | function ValueCorrection: boolean; virtual; overload;
|
|---|
| 63 | public
|
|---|
| 64 | { Public declarations }
|
|---|
| 65 | constructor Create(AOwner: TComponent); override;
|
|---|
| 66 | destructor Destroy; override;
|
|---|
| 67 | published
|
|---|
| 68 | { Published declarations }
|
|---|
| 69 | property Anchors;
|
|---|
| 70 | property CurveExponent: single read FCurveExponent write SetCurveExponent;
|
|---|
| 71 | property KnobColor: TColor read FKnobColor write SetKnobColor;
|
|---|
| 72 | property LightIntensity: integer read GetLightIntensity write SetLightIntensity;
|
|---|
| 73 | property PositionColor: TColor read FPositionColor write SetPositionColor;
|
|---|
| 74 | property PositionWidth: single read FPositionWidth write SetPositionWidth;
|
|---|
| 75 | property PositionOpacity: byte read FPositionOpacity write SetPositionOpacity;
|
|---|
| 76 | property PositionMargin: single read FPositionMargin write SetPositionMargin;
|
|---|
| 77 | property PositionType: TBGRAKnobPositionType
|
|---|
| 78 | read FPositionType write SetPositionType;
|
|---|
| 79 | property UsePhongLighting: boolean read FUsePhongLighting write SetUsePhongLighting;
|
|---|
| 80 | property MinValue: single read FMinValue write SetMinValue;
|
|---|
| 81 | property MaxValue: single read FMaxValue write SetMaxValue;
|
|---|
| 82 | property Value: single read GetValue write SetValue;
|
|---|
| 83 | property OnValueChanged: TBGRAKnobValueChangedEvent
|
|---|
| 84 | read FOnKnobValueChange write FOnKnobValueChange;
|
|---|
| 85 | property StartFromBottom: boolean read FStartFromBottom write SetStartFromBottom;
|
|---|
| 86 | end;
|
|---|
| 87 |
|
|---|
| 88 |
|
|---|
| 89 | procedure Register;
|
|---|
| 90 |
|
|---|
| 91 | implementation
|
|---|
| 92 |
|
|---|
| 93 | uses Math;
|
|---|
| 94 |
|
|---|
| 95 | procedure Register;
|
|---|
| 96 | begin
|
|---|
| 97 | {$I bgraknob_icon.lrs}
|
|---|
| 98 | RegisterComponents('BGRA Controls', [TBGRAKnob]);
|
|---|
| 99 | end;
|
|---|
| 100 |
|
|---|
| 101 | { TBGRAKnob }
|
|---|
| 102 |
|
|---|
| 103 | procedure TBGRAKnob.CreateKnobBmp;
|
|---|
| 104 | var
|
|---|
| 105 | tx, ty: integer;
|
|---|
| 106 | h: single;
|
|---|
| 107 | d2: single;
|
|---|
| 108 | v: TPointF;
|
|---|
| 109 | p: PBGRAPixel;
|
|---|
| 110 | center: TPointF;
|
|---|
| 111 | yb: integer;
|
|---|
| 112 | xb: integer;
|
|---|
| 113 | mask: TBGRABitmap;
|
|---|
| 114 | Map: TBGRABitmap;
|
|---|
| 115 | BGRAKnobColor: TBGRAPixel;
|
|---|
| 116 | begin
|
|---|
| 117 | tx := ClientWidth;
|
|---|
| 118 | ty := ClientHeight;
|
|---|
| 119 | if (tx = 0) or (ty = 0) then
|
|---|
| 120 | exit;
|
|---|
| 121 |
|
|---|
| 122 | FreeAndNil(FKnobBmp);
|
|---|
| 123 |
|
|---|
| 124 | FKnobBmp := TBGRABitmap.Create(tx, ty);
|
|---|
| 125 | center := PointF((tx - 1) / 2, (ty - 1) / 2);
|
|---|
| 126 | BGRAKnobColor := ColorToBGRA(ColorToRGB(KnobColor));
|
|---|
| 127 |
|
|---|
| 128 | if UsePhongLighting then
|
|---|
| 129 | begin
|
|---|
| 130 | //compute knob height map
|
|---|
| 131 | Map := TBGRABitmap.Create(tx, ty);
|
|---|
| 132 | for yb := 0 to ty - 1 do
|
|---|
| 133 | begin
|
|---|
| 134 | p := map.ScanLine[yb];
|
|---|
| 135 | for xb := 0 to tx - 1 do
|
|---|
| 136 | begin
|
|---|
| 137 | //compute vector between center and current pixel
|
|---|
| 138 | v := PointF(xb, yb) - center;
|
|---|
| 139 | //scale down to unit circle (with 1 pixel margin for soft border)
|
|---|
| 140 | v.x /= tx / 2 + 1;
|
|---|
| 141 | v.y /= ty / 2 + 1;
|
|---|
| 142 | //compute squared distance with scalar product
|
|---|
| 143 | d2 := v * v;
|
|---|
| 144 | //interpolate as quadratic curve and apply power function
|
|---|
| 145 | if d2 > 1 then
|
|---|
| 146 | h := 0
|
|---|
| 147 | else
|
|---|
| 148 | h := power(1 - d2, FCurveExponent);
|
|---|
| 149 | p^ := MapHeightToBGRA(h, 255);
|
|---|
| 150 | Inc(p);
|
|---|
| 151 | end;
|
|---|
| 152 | end;
|
|---|
| 153 | //antialiased border
|
|---|
| 154 | mask := TBGRABitmap.Create(tx, ty, BGRABlack);
|
|---|
| 155 | Mask.FillEllipseAntialias(center.x, center.y, tx / 2, ty / 2, BGRAWhite);
|
|---|
| 156 | map.ApplyMask(mask);
|
|---|
| 157 | Mask.Free;
|
|---|
| 158 |
|
|---|
| 159 | FPhong.Draw(FKnobBmp, Map, 30, 0, 0, BGRAKnobColor);
|
|---|
| 160 | Map.Free;
|
|---|
| 161 | end
|
|---|
| 162 | else
|
|---|
| 163 | begin
|
|---|
| 164 | FKnobBmp.FillEllipseAntialias(center.x, center.y, tx / 2, ty / 2, BGRAKnobColor);
|
|---|
| 165 | end;
|
|---|
| 166 |
|
|---|
| 167 | end;
|
|---|
| 168 |
|
|---|
| 169 | function TBGRAKnob.GetLightIntensity: integer;
|
|---|
| 170 | begin
|
|---|
| 171 | Result := round(FPhong.LightSourceIntensity);
|
|---|
| 172 | end;
|
|---|
| 173 |
|
|---|
| 174 | function TBGRAKnob.GetValue: single;
|
|---|
| 175 | begin
|
|---|
| 176 | Result := FAngularPos * 180 / Pi;
|
|---|
| 177 | if Result < 0 then
|
|---|
| 178 | Result += 360;
|
|---|
| 179 | Result := 270 - Result;
|
|---|
| 180 | if Result < 0 then
|
|---|
| 181 | Result += 360;
|
|---|
| 182 | end;
|
|---|
| 183 |
|
|---|
| 184 | procedure TBGRAKnob.SetCurveExponent(const AValue: single);
|
|---|
| 185 | begin
|
|---|
| 186 | if FCurveExponent = AValue then
|
|---|
| 187 | exit;
|
|---|
| 188 | FCurveExponent := AValue;
|
|---|
| 189 | FreeAndNil(FKnobBmp);
|
|---|
| 190 | Invalidate;
|
|---|
| 191 | end;
|
|---|
| 192 |
|
|---|
| 193 | procedure TBGRAKnob.SetKnobColor(const AValue: TColor);
|
|---|
| 194 | begin
|
|---|
| 195 | if FKnobColor = AValue then
|
|---|
| 196 | exit;
|
|---|
| 197 | FKnobColor := AValue;
|
|---|
| 198 | FreeAndNil(FKnobBmp);
|
|---|
| 199 | Invalidate;
|
|---|
| 200 | end;
|
|---|
| 201 |
|
|---|
| 202 | procedure TBGRAKnob.SetLightIntensity(const AValue: integer);
|
|---|
| 203 | begin
|
|---|
| 204 | if AValue <> FPhong.LightSourceIntensity then
|
|---|
| 205 | begin
|
|---|
| 206 | FPhong.LightSourceIntensity := AValue;
|
|---|
| 207 | FreeAndNil(FKnobBmp);
|
|---|
| 208 | Invalidate;
|
|---|
| 209 | end;
|
|---|
| 210 | end;
|
|---|
| 211 |
|
|---|
| 212 | procedure TBGRAKnob.SetStartFromBottom(const AValue: boolean);
|
|---|
| 213 | begin
|
|---|
| 214 | if FStartFromBottom = AValue then
|
|---|
| 215 | exit;
|
|---|
| 216 | FStartFromBottom := AValue;
|
|---|
| 217 | Invalidate;
|
|---|
| 218 | end;
|
|---|
| 219 |
|
|---|
| 220 | procedure TBGRAKnob.SetValue(AValue: single);
|
|---|
| 221 | var
|
|---|
| 222 | NewAngularPos: single;
|
|---|
| 223 | begin
|
|---|
| 224 | ValueCorrection(AValue);
|
|---|
| 225 | NewAngularPos := 3 * Pi / 2 - AValue * Pi / 180;
|
|---|
| 226 | if NewAngularPos > Pi then
|
|---|
| 227 | NewAngularPos -= 2 * Pi;
|
|---|
| 228 | if NewAngularPos < -Pi then
|
|---|
| 229 | NewAngularPos += 2 * Pi;
|
|---|
| 230 | if NewAngularPos <> FAngularPos then
|
|---|
| 231 | begin
|
|---|
| 232 | FAngularPos := NewAngularPos;
|
|---|
| 233 | Invalidate;
|
|---|
| 234 | end;
|
|---|
| 235 | end;
|
|---|
| 236 |
|
|---|
| 237 | procedure TBGRAKnob.SetMaxValue(AValue: single);
|
|---|
| 238 | begin
|
|---|
| 239 | if AValue < 0 then
|
|---|
| 240 | AValue := 0;
|
|---|
| 241 | if AValue > 360 then
|
|---|
| 242 | AValue := 360;
|
|---|
| 243 | if FMaxValue = AValue then
|
|---|
| 244 | exit;
|
|---|
| 245 | FMaxValue := AValue;
|
|---|
| 246 | if FMinValue > FMaxValue then
|
|---|
| 247 | FMinValue := FMaxValue;
|
|---|
| 248 | if ValueCorrection then
|
|---|
| 249 | Invalidate;
|
|---|
| 250 | end;
|
|---|
| 251 |
|
|---|
| 252 | procedure TBGRAKnob.SetMinValue(AValue: single);
|
|---|
| 253 | begin
|
|---|
| 254 | if AValue < 0 then
|
|---|
| 255 | AValue := 0;
|
|---|
| 256 | if AValue > 360 then
|
|---|
| 257 | AValue := 360;
|
|---|
| 258 | if FMinValue = AValue then
|
|---|
| 259 | exit;
|
|---|
| 260 | FMinValue := AValue;
|
|---|
| 261 | if FMaxValue < FMinValue then
|
|---|
| 262 | FMaxValue := FMinValue;
|
|---|
| 263 | if ValueCorrection then
|
|---|
| 264 | Invalidate;
|
|---|
| 265 | end;
|
|---|
| 266 |
|
|---|
| 267 | procedure TBGRAKnob.SetPositionColor(const AValue: TColor);
|
|---|
| 268 | begin
|
|---|
| 269 | if FPositionColor = AValue then
|
|---|
| 270 | exit;
|
|---|
| 271 | FPositionColor := AValue;
|
|---|
| 272 | Invalidate;
|
|---|
| 273 | end;
|
|---|
| 274 |
|
|---|
| 275 | procedure TBGRAKnob.SetPositionMargin(AValue: single);
|
|---|
| 276 | begin
|
|---|
| 277 | if FPositionMargin = AValue then
|
|---|
| 278 | exit;
|
|---|
| 279 | FPositionMargin := AValue;
|
|---|
| 280 | Invalidate;
|
|---|
| 281 | end;
|
|---|
| 282 |
|
|---|
| 283 | procedure TBGRAKnob.SetPositionOpacity(const AValue: byte);
|
|---|
| 284 | begin
|
|---|
| 285 | if FPositionOpacity = AValue then
|
|---|
| 286 | exit;
|
|---|
| 287 | FPositionOpacity := AValue;
|
|---|
| 288 | Invalidate;
|
|---|
| 289 | end;
|
|---|
| 290 |
|
|---|
| 291 | procedure TBGRAKnob.SetPositionType(const AValue: TBGRAKnobPositionType);
|
|---|
| 292 | begin
|
|---|
| 293 | if FPositionType = AValue then
|
|---|
| 294 | exit;
|
|---|
| 295 | FPositionType := AValue;
|
|---|
| 296 | Invalidate;
|
|---|
| 297 | end;
|
|---|
| 298 |
|
|---|
| 299 | procedure TBGRAKnob.SetPositionWidth(const AValue: single);
|
|---|
| 300 | begin
|
|---|
| 301 | if FPositionWidth = AValue then
|
|---|
| 302 | exit;
|
|---|
| 303 | FPositionWidth := AValue;
|
|---|
| 304 | Invalidate;
|
|---|
| 305 | end;
|
|---|
| 306 |
|
|---|
| 307 | procedure TBGRAKnob.SetUsePhongLighting(const AValue: boolean);
|
|---|
| 308 | begin
|
|---|
| 309 | if FUsePhongLighting = AValue then
|
|---|
| 310 | exit;
|
|---|
| 311 | FUsePhongLighting := AValue;
|
|---|
| 312 | FreeAndNil(FKnobBmp);
|
|---|
| 313 | Invalidate;
|
|---|
| 314 | end;
|
|---|
| 315 |
|
|---|
| 316 | procedure TBGRAKnob.UpdateAngularPos(X, Y: integer);
|
|---|
| 317 | var
|
|---|
| 318 | FPreviousPos, Sign: single;
|
|---|
| 319 | begin
|
|---|
| 320 | FPreviousPos := FAngularPos;
|
|---|
| 321 | if FStartFromBottom then
|
|---|
| 322 | Sign := 1
|
|---|
| 323 | else
|
|---|
| 324 | Sign := -1;
|
|---|
| 325 | FAngularPos := ArcTan2((-Sign) * (Y - ClientHeight / 2) / ClientHeight,
|
|---|
| 326 | Sign * (X - ClientWidth / 2) / ClientWidth);
|
|---|
| 327 | ValueCorrection;
|
|---|
| 328 | Invalidate;
|
|---|
| 329 | if (FPreviousPos <> FAngularPos) and Assigned(FOnKnobValueChange) then
|
|---|
| 330 | FOnKnobValueChange(Self, Value);
|
|---|
| 331 | end;
|
|---|
| 332 |
|
|---|
| 333 | procedure TBGRAKnob.MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: integer);
|
|---|
| 334 | begin
|
|---|
| 335 | inherited MouseDown(Button, Shift, X, Y);
|
|---|
| 336 | if Button = mbLeft then
|
|---|
| 337 | begin
|
|---|
| 338 | FSettingAngularPos := True;
|
|---|
| 339 | UpdateAngularPos(X, Y);
|
|---|
| 340 | end;
|
|---|
| 341 | end;
|
|---|
| 342 |
|
|---|
| 343 | procedure TBGRAKnob.MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: integer);
|
|---|
| 344 | begin
|
|---|
| 345 | inherited MouseUp(Button, Shift, X, Y);
|
|---|
| 346 | if Button = mbLeft then
|
|---|
| 347 | FSettingAngularPos := False;
|
|---|
| 348 | end;
|
|---|
| 349 |
|
|---|
| 350 | procedure TBGRAKnob.MouseMove(Shift: TShiftState; X, Y: integer);
|
|---|
| 351 | begin
|
|---|
| 352 | inherited MouseMove(Shift, X, Y);
|
|---|
| 353 | if FSettingAngularPos then
|
|---|
| 354 | UpdateAngularPos(X, Y);
|
|---|
| 355 | end;
|
|---|
| 356 |
|
|---|
| 357 | procedure TBGRAKnob.Paint;
|
|---|
| 358 | var
|
|---|
| 359 | Bmp: TBGRABitmap;
|
|---|
| 360 | Center, Pos: TPointF;
|
|---|
| 361 | PosColor: TBGRAPixel;
|
|---|
| 362 | PosLen: single;
|
|---|
| 363 | begin
|
|---|
| 364 | if (ClientWidth = 0) or (ClientHeight = 0) then
|
|---|
| 365 | exit;
|
|---|
| 366 | if FKnobBmp = nil then
|
|---|
| 367 | begin
|
|---|
| 368 | CreateKnobBmp;
|
|---|
| 369 | if FKnobBmp = nil then
|
|---|
| 370 | Exit;
|
|---|
| 371 | end;
|
|---|
| 372 | Bmp := TBGRABitmap.Create(ClientWidth, ClientHeight);
|
|---|
| 373 | Bmp.PutImage(0, 0, FKnobBmp, dmSet);
|
|---|
| 374 |
|
|---|
| 375 | //draw current position
|
|---|
| 376 | PosColor := ColorToBGRA(ColorToRGB(FPositionColor), FPositionOpacity);
|
|---|
| 377 | Center := PointF(ClientWidth / 2, ClientHeight / 2);
|
|---|
| 378 | Pos.X := Cos(FAngularPos) * (ClientWidth / 2);
|
|---|
| 379 | Pos.Y := -Sin(FAngularPos) * (ClientHeight / 2);
|
|---|
| 380 | if not FStartFromBottom then
|
|---|
| 381 | Pos := -Pos;
|
|---|
| 382 | PosLen := sqrt(Pos * Pos);
|
|---|
| 383 |
|
|---|
| 384 | Pos := Pos * ((PosLen - PositionMargin - FPositionWidth) / PosLen);
|
|---|
| 385 | Pos := Center + Pos;
|
|---|
| 386 |
|
|---|
| 387 | case PositionType of
|
|---|
| 388 | kptLineSquareCap:
|
|---|
| 389 | begin
|
|---|
| 390 | Bmp.LineCap := pecSquare;
|
|---|
| 391 | Bmp.DrawLineAntialias(Center.X, Center.Y, Pos.X, Pos.Y, PosColor, FPositionWidth);
|
|---|
| 392 | end;
|
|---|
| 393 | kptLineRoundCap:
|
|---|
| 394 | begin
|
|---|
| 395 | Bmp.LineCap := pecRound;
|
|---|
| 396 | Bmp.DrawLineAntialias(Center.X, Center.Y, Pos.X, Pos.Y, PosColor, FPositionWidth);
|
|---|
| 397 | end;
|
|---|
| 398 | kptFilledCircle:
|
|---|
| 399 | begin
|
|---|
| 400 | Bmp.FillEllipseAntialias(Pos.X, Pos.Y, FPositionWidth, FPositionWidth, PosColor);
|
|---|
| 401 | end;
|
|---|
| 402 | kptHollowCircle:
|
|---|
| 403 | begin
|
|---|
| 404 | Bmp.EllipseAntialias(Pos.X, Pos.Y, FPositionWidth * 2 / 3,
|
|---|
| 405 | FPositionWidth * 2 / 3, PosColor, FPositionWidth / 3);
|
|---|
| 406 | end;
|
|---|
| 407 | end;
|
|---|
| 408 |
|
|---|
| 409 | Bmp.Draw(Canvas, 0, 0, False);
|
|---|
| 410 | Bmp.Free;
|
|---|
| 411 | end;
|
|---|
| 412 |
|
|---|
| 413 | procedure TBGRAKnob.Resize;
|
|---|
| 414 | begin
|
|---|
| 415 | inherited Resize;
|
|---|
| 416 | if (FKnobBmp <> nil) and ((ClientWidth <> FKnobBmp.Width) or
|
|---|
| 417 | (ClientHeight <> FKnobBmp.Height)) then
|
|---|
| 418 | FreeAndNil(FKnobBmp);
|
|---|
| 419 | end;
|
|---|
| 420 |
|
|---|
| 421 | function TBGRAKnob.ValueCorrection(var AValue: single): boolean;
|
|---|
| 422 | begin
|
|---|
| 423 | if AValue < MinValue then
|
|---|
| 424 | begin
|
|---|
| 425 | AValue := MinValue;
|
|---|
| 426 | Result := True;
|
|---|
| 427 | end
|
|---|
| 428 | else
|
|---|
| 429 | if AValue > MaxValue then
|
|---|
| 430 | begin
|
|---|
| 431 | AValue := MaxValue;
|
|---|
| 432 | Result := True;
|
|---|
| 433 | end
|
|---|
| 434 | else
|
|---|
| 435 | Result := False;
|
|---|
| 436 | end;
|
|---|
| 437 |
|
|---|
| 438 | function TBGRAKnob.ValueCorrection: boolean;
|
|---|
| 439 | var
|
|---|
| 440 | LValue: single;
|
|---|
| 441 | begin
|
|---|
| 442 | LValue := Value;
|
|---|
| 443 | Result := ValueCorrection(LValue);
|
|---|
| 444 | if Result then
|
|---|
| 445 | Value := LValue;
|
|---|
| 446 | end;
|
|---|
| 447 |
|
|---|
| 448 | constructor TBGRAKnob.Create(AOwner: TComponent);
|
|---|
| 449 | begin
|
|---|
| 450 | inherited Create(AOwner);
|
|---|
| 451 | with GetControlClassDefaultSize do
|
|---|
| 452 | SetInitialBounds(0, 0, CX, CY);
|
|---|
| 453 | FPhong := TPhongShading.Create;
|
|---|
| 454 | FPhong.LightPositionZ := 100;
|
|---|
| 455 | FPhong.LightSourceIntensity := 300;
|
|---|
| 456 | FPhong.NegativeDiffusionFactor := 0.8;
|
|---|
| 457 | FPhong.AmbientFactor := 0.5;
|
|---|
| 458 | FPhong.DiffusionFactor := 0.6;
|
|---|
| 459 | FKnobBmp := nil;
|
|---|
| 460 | FCurveExponent := 0.2;
|
|---|
| 461 | FKnobColor := clBtnFace;
|
|---|
| 462 | FPositionColor := clBtnText;
|
|---|
| 463 | FPositionOpacity := 192;
|
|---|
| 464 | FPositionWidth := 4;
|
|---|
| 465 | FPositionMargin := 4;
|
|---|
| 466 | FPositionType := kptLineSquareCap;
|
|---|
| 467 | FUsePhongLighting := True;
|
|---|
| 468 | FOnKnobValueChange := nil;
|
|---|
| 469 | FStartFromBottom := True;
|
|---|
| 470 | FMinValue := 30;
|
|---|
| 471 | FMaxValue := 330;
|
|---|
| 472 | end;
|
|---|
| 473 |
|
|---|
| 474 | destructor TBGRAKnob.Destroy;
|
|---|
| 475 | begin
|
|---|
| 476 | FPhong.Free;
|
|---|
| 477 | FKnobBmp.Free;
|
|---|
| 478 | inherited Destroy;
|
|---|
| 479 | end;
|
|---|
| 480 |
|
|---|
| 481 | end.
|
|---|
| 482 |
|
|---|