VrMeter.pas
上传用户:hbszzs
上传日期:2008-08-20
资源大小:628k
文件大小:15k
源码类别:

Delphi控件源码

开发平台:

Delphi

  1. {*****************************************************}
  2. {                                                     }
  3. {     Varian Component Workshop                       }
  4. {                                                     }
  5. {     Varian Software NL (c) 1996-2000                }
  6. {     All Rights Reserved                             }
  7. {                                                     }
  8. {*****************************************************}
  9. unit VrMeter;
  10. {$I VRLIB.INC}
  11. interface
  12. uses
  13.   Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  14.   VrClasses, VrControls, VrSysUtils;
  15. type
  16.   TVrMeter = class;
  17.   TVrMeterScale = class(TVrPersistent)
  18.   private
  19.     FColor1: TColor;
  20.     FColor2: TColor;
  21.     FColor3: TColor;
  22.     FEnlarge: Integer;
  23.     FPercent1: Integer;
  24.     FPercent2: Integer;
  25.     FTicks: Integer;
  26.     FHeightMax: Integer;
  27.     FHeightMin: Integer;
  28.     FVisible: Boolean;
  29.     Owner: TVrMeter;
  30.     procedure SetColor1(Value: TColor);
  31.     procedure SetColor2(Value: TColor);
  32.     procedure SetColor3(Value: TColor);
  33.     procedure SetEnlarge(Value: Integer);
  34.     procedure SetPercent1(Value: Integer);
  35.     procedure SetPercent2(Value: Integer);
  36.     procedure SetTicks(Value: Integer);
  37.     procedure SetHeightMax(Value: Integer);
  38.     procedure SetHeightMin(Value: Integer);
  39.     procedure SetVisible(Value: Boolean);
  40.   public
  41.     constructor Create;
  42.   published
  43.     property Color1: TColor read FColor1 write SetColor1 default clGreen;
  44.     property Color2: TColor read FColor2 write SetColor2 default clYellow;
  45.     property Color3: TColor read FColor3 write SetColor3 default clRed;
  46.     property Enlarge: Integer read FEnlarge write SetEnlarge default 5;
  47.     property Percent1: Integer read FPercent1 write SetPercent1 default 61;
  48.     property Percent2: Integer read FPercent2 write SetPercent2 default 25;
  49.     property Ticks: Integer read FTicks write SetTicks default 60;
  50.     property HeightMax: Integer read FHeightMax write SetHeightMax default 8;
  51.     property HeightMin: Integer read FHeightMin write SetHeightMin default 5;
  52.     property Visible: Boolean read FVisible write SetVisible default True;
  53.   end;
  54.   TVrMeter = class(TVrGraphicImageControl)
  55.   private
  56.     FAngle: Integer;
  57.     FScale: TVrMeterScale;
  58.     FMinValue: Integer;
  59.     FMaxValue: Integer;
  60.     FPosition: Integer;
  61.     FNeedleColor: TColor;
  62.     FNeedleWidth: Integer;
  63.     FSpacing: Integer;
  64.     FLabels: Integer;
  65.     FLabelOffsetX: Integer;
  66.     FLabelOffsetY: Integer;
  67.     FBevel: TVrBevel;
  68.     FBackImage: TBitmap;
  69.     FCenter: TPoint;
  70.     FRadius: Integer;
  71.     procedure SetAngle(Value: Integer);
  72.     procedure SetMinValue(Value: Integer);
  73.     procedure SetMaxValue(Value: Integer);
  74.     procedure SetPosition(Value: Integer);
  75.     procedure SetNeedleColor(Value: TColor);
  76.     procedure SetNeedleWidth(Value: Integer);
  77.     procedure SetBevel(Value: TVrBevel);
  78.     procedure SetSpacing(Value: Integer);
  79.     procedure SetLabels(Value: Integer);
  80.     procedure SetLabelOffsetX(Value: Integer);
  81.     procedure SetLabelOffsetY(Value: Integer);
  82.     procedure SetBackImage(Value: TBitmap);
  83.     procedure BevelChanged(Sender: TObject);
  84.     procedure ScaleChanged(Sender: TObject);
  85.     procedure BackImageChanged(Sender: TObject);
  86.     procedure CMTextChanged(var Message: TMessage); message CM_TEXTCHANGED;
  87.   protected
  88.     procedure DrawScale;
  89.     procedure DrawNeedle;
  90.     procedure DrawLabels;
  91.     procedure Paint; override;
  92.   public
  93.     constructor Create(AOwner: TComponent); override;
  94.     destructor Destroy; override;
  95.     procedure SetBounds(ALeft, ATop, AWidth, AHeight: Integer); override;
  96.   published
  97.     property MaxValue: Integer read FMaxValue write SetMaxValue default 100;
  98.     property MinValue: Integer read FMinValue write SetMinValue default 0;
  99.     property Position: Integer read FPosition write SetPosition default 0;
  100.     property Angle: Integer read FAngle write SetAngle default 40;
  101.     property Scale: TVrMeterScale read FScale write FScale;
  102.     property NeedleColor: TColor read FNeedleColor write SetNeedleColor default clSilver;
  103.     property NeedleWidth: Integer read FNeedleWidth write SetNeedleWidth default 1;
  104.     property Bevel: TVrBevel read FBevel write SetBevel;
  105.     property Spacing: Integer read FSpacing write SetSpacing default 20;
  106.     property Labels: Integer read FLabels write SetLabels default 10;
  107.     property LabelOffsetX: Integer read FLabelOffsetX write SetLabelOffsetX default 15;
  108.     property LabelOffsetY: Integer read FLabelOffsetY write SetLabelOffsetY default 10;
  109.     property BackImage: TBitmap read FBackImage write SetBackImage;
  110.     property Align;
  111. {$IFDEF VER110}
  112.     property Anchors;
  113.     property Constraints;
  114. {$ENDIF}
  115.     property Caption;
  116.     property Color;
  117.     property DragCursor;
  118. {$IFDEF VER110}
  119.     property DragKind;
  120. {$ENDIF}
  121.     property DragMode;
  122.     property Font;
  123.     property Hint;
  124.     property ParentColor;
  125.     property ParentShowHint;
  126.     property PopupMenu;
  127.     property ParentFont;
  128.     property ShowHint;
  129.     property Visible;
  130.     property OnClick;
  131. {$IFDEF VER130}
  132.     property OnContextPopup;
  133. {$ENDIF}
  134.     property OnDblClick;
  135.     property OnDragDrop;
  136.     property OnDragOver;
  137. {$IFDEF VER110}
  138.     property OnEndDock;
  139. {$ENDIF}
  140.     property OnEndDrag;
  141.     property OnMouseDown;
  142.     property OnMouseMove;
  143.     property OnMouseUp;
  144. {$IFDEF VER110}
  145.     property OnStartDock;
  146. {$ENDIF}
  147.     property OnStartDrag;
  148.   end;
  149. implementation
  150. function DegToRad(Degrees: Extended): Extended;
  151. begin
  152.   Result := Degrees * (PI / 180);
  153. end;
  154. { TVrMeterScale }
  155. constructor TVrMeterScale.Create;
  156. begin
  157.   inherited Create;
  158.   FColor1 := clGreen;
  159.   FColor2 := clYellow;
  160.   FColor3 := clRed;
  161.   FEnlarge := 5;
  162.   FPercent1 := 60;
  163.   FPercent2 := 25;
  164.   FTicks := 61;
  165.   FHeightMax := 8;
  166.   FHeightMin := 5;
  167.   FVisible := True
  168. end;
  169. procedure TVrMeterScale.SetColor1(Value: TColor);
  170. begin
  171.   if FColor1 <> Value then
  172.   begin
  173.     FColor1 := Value;
  174.     Changed;
  175.   end;
  176. end;
  177. procedure TVrMeterScale.SetColor2(Value: TColor);
  178. begin
  179.   if FColor2 <> Value then
  180.   begin
  181.     FColor2 := Value;
  182.     Changed;
  183.   end;
  184. end;
  185. procedure TVrMeterScale.SetColor3(Value: TColor);
  186. begin
  187.   if FColor3 <> Value then
  188.   begin
  189.     FColor3 := Value;
  190.     Changed;
  191.   end;
  192. end;
  193. procedure TVrMeterScale.SetEnlarge(Value: Integer);
  194. begin
  195.   if FEnlarge <> Value then
  196.   begin
  197.     FEnlarge := Value;
  198.     Changed;
  199.   end;
  200. end;
  201. procedure TVrMeterScale.SetPercent1(Value: Integer);
  202. begin
  203.   if (FPercent1 <> Value) then
  204.   begin
  205.     if not Owner.Loading then
  206.       if Value + Percent2 > 100 then Value := 100 - Percent2;
  207.     FPercent1 := Value;
  208.     Changed;
  209.   end;
  210. end;
  211. procedure TVrMeterScale.SetPercent2(Value: Integer);
  212. begin
  213.   if (FPercent2 <> Value) and (Value + Percent1 <= 100) then
  214.   begin
  215.     if not Owner.Loading then
  216.       if Value + Percent1 > 100 then Value := 100 - Percent1;
  217.     FPercent2 := Value;
  218.     Changed;
  219.   end;
  220. end;
  221. procedure TVrMeterScale.SetTicks(Value: Integer);
  222. begin
  223.   if FTicks <> Value then
  224.   begin
  225.     FTicks := Value;
  226.     Changed;
  227.   end;
  228. end;
  229. procedure TVrMeterScale.SetHeightMax(Value: Integer);
  230. begin
  231.   if FHeightMax <> Value then
  232.   begin
  233.     FHeightMax := Value;
  234.     Changed;
  235.   end;
  236. end;
  237. procedure TVrMeterScale.SetHeightMin(Value: Integer);
  238. begin
  239.   if FHeightMin <> Value then
  240.   begin
  241.     FHeightMin := Value;
  242.     Changed;
  243.   end;
  244. end;
  245. procedure TVrMeterScale.SetVisible(Value: Boolean);
  246. begin
  247.   if FVisible <> Value then
  248.   begin
  249.     FVisible := Value;
  250.     Changed;
  251.   end;
  252. end;
  253. { TVrMeter }
  254. constructor TVrMeter.Create(AOwner: TComponent);
  255. begin
  256.   inherited Create(AOwner);
  257.   ControlStyle := ControlStyle + [csOpaque];
  258.   Width := 240;
  259.   Height := 115;
  260.   Color := clBlack;
  261.   ParentColor := false;
  262.   with Font do
  263.   begin
  264.     Name := 'Arial';
  265.     Size := 8;
  266.     Color := clSilver;
  267.   end;
  268.   FAngle := 40;
  269.   FMinValue := 0;
  270.   FMaxValue := 100;
  271.   FPosition := 0;
  272.   FNeedleColor := clSilver;
  273.   FNeedleWidth := 1;
  274.   FSpacing := 20;
  275.   FLabels := 10;
  276.   FLabelOffsetX := 15;
  277.   FLabelOffsetY := 10;
  278.   FBevel := TVrBevel.Create;
  279.   with FBevel do
  280.   begin
  281.     InnerStyle := bsLowered;
  282.     InnerWidth := 2;
  283.     InnerColor := clBlack;
  284.     OnChange := BevelChanged;
  285.   end;
  286.   FScale := TVrMeterScale.Create;
  287.   FScale.Owner := Self;
  288.   FScale.OnChange := ScaleChanged;
  289.   FBackImage := TBitmap.Create;
  290.   FBackImage.OnChange := BackImageChanged;
  291. end;
  292. destructor TVrMeter.Destroy;
  293. begin
  294.   FScale.Free;
  295.   FBevel.Free;
  296.   FBackImage.Free;
  297.   inherited Destroy;
  298. end;
  299. procedure TVrMeter.SetBounds(ALeft, ATop, AWidth, AHeight: Integer);
  300. begin
  301.   FRadius := AHeight - 10;
  302.   FCenter.X := AWidth div 2;
  303.   FCenter.Y := AHeight + FSpacing;
  304.   inherited SetBounds(ALeft, ATop, AWidth, AHeight);
  305. end;
  306. procedure TVrMeter.DrawScale;
  307. var
  308.   sX, sY, eX, eY: Integer;
  309.   I, sAngle, eAngle: Integer;
  310.   Ticks, TickHeight, Enlarge: Integer;
  311.   Point, Point1, Point2: Integer;
  312.   Offset, Step: Extended;
  313. begin
  314.   Ticks := Scale.Ticks;
  315.   Enlarge := Scale.Enlarge;
  316.   sAngle := 270 + FAngle;
  317.   eAngle := sAngle + 180 - FAngle * 2;
  318.   Step := (eAngle - sAngle)/Ticks;
  319.   Point := 0;
  320.   Point1 := SolveForX(Scale.Percent1, Scale.Ticks);
  321.   Point2 := Point1 + SolveForX(Scale.Percent2, Scale.Ticks);
  322.   with BitmapCanvas do
  323.   begin
  324.     Pen.Mode := pmCOPY;
  325.     Pen.Width := 1;
  326.     for I := 0 to Ticks - 1 do
  327.     begin
  328.       Inc(Point);
  329.       if Point <= Point1 then Pen.Color := Scale.Color1
  330.       else if Point <= Point2 then Pen.Color := Scale.Color2
  331.       else Pen.Color := Scale.Color3;
  332.       if Enlarge = Scale.Enlarge then TickHeight := Scale.HeightMax
  333.       else TickHeight := Scale.HeightMin;
  334.       Offset := DegToRad(sAngle + I * Step);
  335.       sX := FCenter.X + Trunc(Sin(Offset) * (FRadius - Scale.HeightMin));
  336.       sY := FCenter.Y + Trunc(Cos(Offset) * (FRadius - Scale.HeightMin));
  337.       eX := FCenter.X + Trunc(Sin(Offset) *
  338.             (FRadius + TickHeight - Scale.HeightMin));
  339.       eY := FCenter.Y + Trunc(Cos(Offset) *
  340.             (FRadius + TickHeight - Scale.HeightMin));
  341.       MoveTo(sX, FCenter.Y * 2 - sY);
  342.       LineTo(eX, FCenter.Y * 2 - eY);
  343.       if Enlarge < Scale.Enlarge then Inc(Enlarge) else Enlarge := 1;
  344.     end;
  345.   end;
  346. end;
  347. procedure TVrMeter.DrawNeedle;
  348. var
  349.   X, Y, Ticks: Integer;
  350.   P: Integer;
  351.   Offset, Step: Extended;
  352.   sAngle, eAngle: Integer;
  353. begin
  354.   Ticks := Scale.Ticks;
  355.   sAngle := 270 + FAngle;
  356.   eAngle := sAngle + 180 - FAngle * 2;
  357.   Step := (eAngle - sAngle)/Ticks;
  358.   P := Trunc((Position / (MaxValue - MinValue)) * Pred(Ticks));
  359.   with BitmapCanvas do
  360.   begin
  361.     Pen.Mode := pmCOPY;
  362.     Pen.Color := FNeedleColor;
  363.     Pen.Width := FNeedleWidth;
  364.     Offset := DegToRad(sAngle + P * Step);
  365.     X := FCenter.X + Trunc(Sin(Offset) * FRadius);
  366.     Y := FCenter.Y + Trunc(Cos(Offset) * FRadius);
  367.     MoveTo(FCenter.X, FCenter.Y);
  368.     LineTo(X, FCenter.Y * 2 - Y);
  369.   end;
  370. end;
  371. procedure TVrMeter.DrawLabels;
  372. var
  373.   X, Y, Ticks, I, LabelCnt, LC, LV: Integer;
  374.   str: string;
  375.   Offset, Step, BaseValue: Extended;
  376.   sAngle, eAngle, Adjust: Integer;
  377.   TextSize: TSize;
  378. begin
  379.   Ticks := Scale.Ticks;
  380.   sAngle := 270 + FAngle;
  381.   eAngle := sAngle + 180 - FAngle * 2;
  382.   Step := (eAngle - sAngle) / Scale.Ticks;
  383.   BaseValue := (FMaxValue - FMinValue) / Labels;
  384.   LabelCnt := (Scale.Ticks div Labels)-1;
  385.   LC := 0;
  386.   LV := -1;
  387.   with BitmapCanvas do
  388.   begin
  389.     Font.Assign(Self.Font);
  390.     Brush.Style := bsClear;
  391.     for I := 0 to Ticks - 1 do
  392.     begin
  393.       if LC = 0 then
  394.       begin
  395.         Inc(LV);
  396.         str := IntToStr(FMinValue + Round(BaseValue * LV));
  397.         TextSize := TextExtent(str);
  398.         Offset := DegToRad(sAngle + I * Step);
  399.         X := FCenter.X + Trunc(Sin(Offset) *
  400.              (FRadius + Scale.HeightMax - Scale.HeightMin + LabelOffsetX));
  401.         Y := FCenter.Y + Trunc(Cos(Offset) *
  402.              (FRadius + Scale.HeightMax - Scale.HeightMin + LabelOffsetY));
  403.         Adjust := X - (TextSize.cX div 2);
  404.         Y := Y + (TextSize.cY div 2);
  405.         TextOut(Adjust, FCenter.Y * 2 - Y, str);
  406.       end;
  407.       if LC = 0 then LC := LabelCnt else Dec(LC);
  408.     end;
  409.   end;
  410. end;
  411. procedure TVrMeter.Paint;
  412. var
  413.   X: Integer;
  414.   BevelRect: TRect;
  415. begin
  416.   ClearBitmapCanvas;
  417.   if not FBackImage.Empty then
  418.     BitmapCanvas.StretchDraw(ClientRect, FBackImage);
  419.   if Scale.Visible then DrawScale;
  420.   if Labels > 0 then DrawLabels;
  421.   DrawNeedle;
  422.   BevelRect := ClientRect;
  423.   FBevel.GetVisibleArea(BevelRect);
  424.   with BitmapCanvas do
  425.   begin
  426.     Font.Assign(Self.Font);
  427.     X := FCenter.X - (TextWidth(Caption) div 2);
  428.     TextOut(X, BevelRect.Bottom - 10 - TextHeight(Caption), Caption);
  429.   end;
  430.   BevelRect := ClientRect;
  431.   FBevel.Paint(BitmapCanvas, BevelRect);
  432.   inherited Paint;
  433. end;
  434. procedure TVrMeter.ScaleChanged(Sender: TObject);
  435. begin
  436.   UpdateControlCanvas;
  437. end;
  438. procedure TVrMeter.SetAngle(Value: Integer);
  439. begin
  440.   if FAngle <> Value then
  441.   begin
  442.     FAngle := Value;
  443.     UpdateControlCanvas;
  444.   end;
  445. end;
  446. procedure TVrMeter.SetMinValue(Value: Integer);
  447. begin
  448.   if (FMinValue <> Value) and (Value < FMaxValue) then
  449.   begin
  450.     FMinValue := Value;
  451.     UpdateControlCanvas;
  452.   end;
  453. end;
  454. procedure TVrMeter.SetMaxValue(Value: Integer);
  455. begin
  456.   if (FMaxValue <> Value) and (Value > FMinValue) then
  457.   begin
  458.     FMaxValue := Value;
  459.     UpdateControlCanvas;
  460.   end;
  461. end;
  462. procedure TVrMeter.SetPosition(Value: Integer);
  463. begin
  464.   AdjustRange(Value, FMinValue, FMaxValue);
  465.   if (FPosition <> Value) then
  466.   begin
  467.     FPosition := Value;
  468.     UpdateControlCanvas;
  469.   end;
  470. end;
  471. procedure TVrMeter.SetNeedleColor(Value: TColor);
  472. begin
  473.   if FNeedleColor <> Value then
  474.   begin
  475.     FNeedleColor := Value;
  476.     UpdateControlCanvas;
  477.   end;
  478. end;
  479. procedure TVrMeter.SetNeedleWidth(Value: Integer);
  480. begin
  481.   if FNeedleWidth <> Value then
  482.   begin
  483.     FNeedleWidth := Value;
  484.     UpdateControlCanvas;
  485.   end;
  486. end;
  487. procedure TVrMeter.SetBevel(Value: TVrBevel);
  488. begin
  489.   FBevel.Assign(Value);
  490. end;
  491. procedure TVrMeter.BevelChanged(Sender: TObject);
  492. begin
  493.   UpdateControlCanvas;
  494. end;
  495. procedure TVrMeter.SetSpacing(Value: Integer);
  496. begin
  497.   if FSpacing <> Value then
  498.   begin
  499.     FSpacing := Value;
  500.     FCenter.Y := Height + Value;
  501.     UpdateControlCanvas;
  502.   end;
  503. end;
  504. procedure TVrMeter.SetLabels(Value: Integer);
  505. begin
  506.   if FLabels <> Value then
  507.   begin
  508.     FLabels := Value;
  509.     UpdateControlCanvas;
  510.   end;
  511. end;
  512. procedure TVrMeter.SetLabelOffsetX(Value: Integer);
  513. begin
  514.   if FLabelOffsetX <> Value then
  515.   begin
  516.     FLabelOffsetX := Value;
  517.     UpdateControlCanvas;
  518.   end;
  519. end;
  520. procedure TVrMeter.SetLabelOffsetY(Value: Integer);
  521. begin
  522.   if FLabelOffsetY <> Value then
  523.   begin
  524.     FLabelOffsetY := Value;
  525.     UpdateControlCanvas;
  526.   end;
  527. end;
  528. procedure TVrMeter.CMTextChanged(var Message: TMessage);
  529. begin
  530.   inherited;
  531.   UpdateControlCanvas;
  532. end;
  533. procedure TVrMeter.BackImageChanged(Sender: TObject);
  534. begin
  535.   UpdateControlCanvas;
  536. end;
  537. procedure TVrMeter.SetBackImage(Value: TBitmap);
  538. begin
  539.   FBackImage.Assign(Value);
  540. end;
  541. end.