vrgauge.pas

来自「作工控的好控件」· PAS 代码 · 共 496 行

PAS
496
字号
{*****************************************************}
{                                                     }
{     Varian Component Workshop                       }
{                                                     }
{     Varian Software NL (c) 1996-2000                }
{     All Rights Reserved                             }
{                                                     }
{*****************************************************}

unit VrGauge;

{$I VRLIB.INC}

interface

uses
  Windows, Forms, Messages, SysUtils, Classes, Graphics, Controls, Dialogs,
  VrTypes, VrClasses, VrControls, VrSysUtils;

type
  TVrGaugeImages = array[0..1] of TBitmap;
  TVrGauge = class(TVrGraphicImageControl)
  private
    FMaxValue: Integer;
    FMinValue: Integer;
    FPosition: Integer;
    FOrientation: TVrOrientation;
    FPalette: TVrPalette;
    FTickHeight: Integer;
    FSpacing: Integer;
    FSolidFill: Boolean;
    FBevel: TVrBevel;
    FStyle: TVrProgressStyle;
    FActiveClick: Boolean;
    FStep: Integer;
    FOnChange: TNotifyEvent;
    FOnMinValue: TNotifyEvent;
    FOnMaxValue: TNotifyEvent;
    FViewPort: TRect;
    TickStep, Ticks: Integer;
    FImages: TVrGaugeImages;
    OrgSize: TPoint;
    function GetPercentDone: Longint;
    procedure SetMaxValue(Value: Integer);
    procedure SetMinValue(Value: Integer);
    procedure SetPosition(Value: Integer);
    procedure SetOrientation(Value: TVrOrientation);
    procedure SetTickHeight(Value: Integer);
    procedure SetSpacing(Value: Integer);
    procedure SetSolidFill(Value: Boolean);
    procedure SetStyle(Value: TVrProgressStyle);
    procedure SetPalette(Value: TVrPalette);
    procedure SetBevel(Value: TVrBevel);
    procedure DrawHori;
    procedure DrawVert;
    procedure PaletteModified(Sender: TObject);
    procedure BevelChanged(Sender: TObject);
  protected
    procedure CreateBitmaps;
    procedure DestroyBitmaps;
    procedure CalcPaintParams;
    procedure Paint; override;
    procedure Change; dynamic;
    procedure MoveTo(X, Y: Integer);
    procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
    procedure StepIt;
    procedure StepBy(Delta: Integer);
    property PercentDone: Longint read GetPercentDone;
  published
    property MaxValue: Integer read FMaxValue write SetMaxValue default 100;
    property MinValue: Integer read FMinValue write SetMinValue default 0;
    property Position: Integer read FPosition write SetPosition default 0;
    property Palette: TVrPalette read FPalette write SetPalette;
    property Bevel: TVrBevel read FBevel write SetBevel;
    property Orientation: TVrOrientation read FOrientation write SetOrientation default voVertical;
    property TickHeight: Integer read FTickHeight write SetTickHeight default 1;
    property Spacing: Integer read FSpacing write SetSpacing default 1;
    property SolidFill: Boolean read FSolidFill write SetSolidFill default false;
    property Style: TVrProgressStyle read FStyle write SetStyle default psBottomLeft;
    property ActiveClick: Boolean read FActiveClick write FActiveClick default false;
    property Step: Integer read FStep write FStep default 10;
    property OnChange: TNotifyEvent read FOnChange write FOnChange;
    property OnMinValue: TNotifyEvent read FOnMinValue write FOnMinValue;
    property OnMaxValue: TNotifyEvent read FOnMaxValue write FOnMaxValue;
{$IFDEF VER110}
    property Anchors;
    property Constraints;
{$ENDIF}
    property Color default clBlack;
    property DragCursor;
{$IFDEF VER110}
    property DragKind;
{$ENDIF}
    property DragMode;
    property ParentColor default false;
    property ParentShowHint;
    property PopupMenu;
    property ShowHint;
    property Visible;
    property OnClick;
{$IFDEF VER130}
    property OnContextPopup;
{$ENDIF}    
    property OnDblClick;
    property OnDragDrop;
    property OnDragOver;
{$IFDEF VER110}
    property OnEndDock;
{$ENDIF}
    property OnEndDrag;
    property OnMouseDown;
    property OnMouseMove;
    property OnMouseUp;
{$IFDEF VER110}
    property OnStartDock;
{$ENDIF}
    property OnStartDrag;
  end;


implementation


{ TVrGauge }

constructor TVrGauge.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  ControlStyle := ControlStyle + [csOpaque, csReplicatable];
  Width := 30;
  Height := 170;
  ParentColor := false;
  Color := clBlack;
  FMaxValue := 100;
  FMinValue := 0;
  FPosition := 0;
  FOrientation := voVertical;
  FTickHeight := 1;
  FSpacing := 1;
  FSolidFill := false;
  FStyle := psBottomLeft;
  FActiveClick := false;
  FStep := 10;
  FPalette := TVrPalette.Create;
  FPalette.OnChange := PaletteModified;
  FBevel := TVrBevel.Create;
  with FBevel do
  begin
    InnerStyle := bsLowered;
    InnerWidth := 2;
    InnerColor := clBlack;
    OnChange := BevelChanged;
  end;
  AllocateBitmaps(FImages);
end;

destructor TVrGauge.Destroy;
begin
  FBevel.Free;
  DestroyBitmaps;
  inherited Destroy;
end;

procedure TVrGauge.CreateBitmaps;
var
  R: TRect;
begin
  R := ClientRect;
  FBevel.GetVisibleArea(R);

  with FImages[0] do
  begin
    case FOrientation of
      voVertical:
        begin
          Height := FTickHeight;
          Width := WidthOf(R);
        end;
      voHorizontal:
        begin
          Height := HeightOf(R);
          Width := FTickHeight;
        end;
    end; //case

    if (FTickHeight > 1) and (not FSolidFill) then
      Canvas.Brush.BitMap := CreateDitherPattern(FPalette.Low, clBlack)
    else
      Canvas.Brush.Color := FPalette.Low;
    try
      R := Bounds(0, 0, Width, Height);
      Canvas.FillRect(R);
    finally
      if Canvas.Brush.BitMap <> nil then
      begin
        Canvas.Brush.BitMap.Free;
        Canvas.Brush.BitMap := nil;
      end;
    end;
  end;

  with FImages[1] do
  begin
    Width := FImages[0].Width;
    Height := FImages[0].Height;
    Canvas.Brush.Color := FPalette.High;
    Canvas.FillRect(R);
  end;

  OrgSize.X := ClientWidth;
  OrgSize.Y := ClientHeight;
end;

procedure TVrGauge.DestroyBitmaps;
begin
  DeAllocateBitmaps(FImages);
end;

procedure TVrGauge.PaletteModified(Sender: TObject);
begin
  CreateBitmaps;
  UpdateControlCanvas;
end;

procedure TVrGauge.BevelChanged(Sender: TObject);
var
  R: TRect;
begin
  if not Loading then
  begin
    R := ClientRect;
    FBevel.GetVisibleArea(R);
    InflateRect(FViewPort, R.Left, R.Top);
    BoundsRect := Bounds(Left, Top, WidthOf(FViewPort),
      HeightOf(FViewPort));
  end;
  CreateBitmaps;
  UpdateControlCanvas;
end;

procedure TVrGauge.SetMaxValue(Value: Integer);
begin
  if (FMaxValue <> Value) and (Value > FMinValue) then
  begin
    FMaxValue := Value;
    if FPosition > FMaxValue then
      Position := FMaxValue else UpdateControlCanvas;
  end;
end;

procedure TVrGauge.SetMinValue(Value: Integer);
begin
  if (FMinValue <> Value) and (Value < FMaxValue) then
  begin
    FMinValue := Value;
    if FPosition < FMinValue then
      Position := FMinValue else UpdateControlCanvas;
  end;
end;

procedure TVrGauge.SetPosition(Value: Integer);
begin
  if Value < FMinValue then Value := FMinValue;
  if Value > FMaxValue then Value := FMaxValue;
  if FPosition <> Value then
  begin
    FPosition := Value;
    UpdateControlCanvas;
    Change;
  end;
end;

procedure TVrGauge.SetOrientation(Value: TVrOrientation);
begin
  if FOrientation <> Value then
  begin
    FOrientation := Value;
    if not Loading then
      BoundsRect := Bounds(Left, Top, Height, Width);
    UpdateControlCanvas;
  end;
end;

procedure TVrGauge.SetTickHeight(Value: Integer);
begin
  if (FTickHeight <> Value) and (Value > 0) then
  begin
    FTickHeight := Value;
    CreateBitmaps;
    UpdateControlCanvas;
  end;
end;

procedure TVrGauge.SetSpacing(Value: Integer);
begin
  if FSpacing <> Value then
  begin
    FSpacing := Value;
    UpdateControlCanvas;
  end;
end;

procedure TVrGauge.SetSolidFill(Value: Boolean);
begin
  if FSolidFill <> Value then
  begin
    FSolidFill := Value;
    CreateBitmaps;
    UpdateControlCanvas;
  end;
end;

procedure TVrGauge.SetStyle(Value: TVrProgressStyle);
begin
  if FStyle <> Value then
  begin
    FStyle := Value;
    UpdateControlCanvas;
  end;
end;

procedure TVrGauge.SetPalette(Value: TVrPalette);
begin
  FPalette.Assign(Value);
end;

procedure TVrGauge.SetBevel(Value: TVrBevel);
begin
  FBevel.Assign(Value);
end;

procedure TVrGauge.Change;
begin
  if Assigned(FOnChange) then FOnChange(self);
  if (Position = MinValue) and (Assigned(FOnMinValue)) then FOnMinValue(Self);
  if (Position = MaxValue) and (Assigned(FOnMaxValue)) then FOnMaxValue(Self);
end;

procedure TVrGauge.StepIt;
begin
  Position := Position + FStep;
end;

procedure TVrGauge.StepBy(Delta: Integer);
begin
  Position := Position + Delta;
end;

function TVrGauge.GetPercentDone: Longint;
begin
  Result := SolveForY(FPosition - FMinValue, FMaxValue - FMinValue);
end;

procedure TVrGauge.DrawHori;
var
  X, Y, I, Offset: Integer;
  TicksOn, TicksOff: Integer;
begin
  TicksOn := SolveForX(PercentDone, Ticks);
  TicksOff := Ticks - TicksOn;

  Y := FViewPort.Top;
  if FStyle = psBottomLeft then
  begin
    X := FViewPort.Left;
    Offset := TickStep;
  end
  else
  begin
    X := FViewPort.Right - FTickHeight;
    Offset := -TickStep;
  end;

  for I := 1 to TicksOn do
  begin
    BitmapCanvas.Draw(X, Y, FImages[1]);
    Inc(X, Offset);
  end;
  for I := 1 to TicksOff do
  begin
    BitmapCanvas.Draw(X, Y, FImages[0]);
    Inc(X, Offset);
  end;
end;

procedure TVrGauge.DrawVert;
var
  X, Y, I, Offset: Integer;
  TicksOn, TicksOff: Integer;
begin
  TicksOn := SolveForX(PercentDone, Ticks);
  TicksOff := Ticks - TicksOn;

  X := FViewPort.Left;
  if FStyle = psBottomLeft then
  begin
    Y := FViewPort.Top;
    Offset := TickStep;
  end
  else
  begin
    Y := FViewPort.Bottom - FTickHeight;
    Offset := -TickStep;
  end;

  for I := 1 to TicksOff do
  begin
    BitmapCanvas.Draw(X, Y, FImages[0]);
    Inc(Y, Offset);
  end;

  for I := 1 to TicksOn do
  begin
    BitmapCanvas.Draw(X, Y, FImages[1]);
    Inc(Y, Offset);
  end;
end;

procedure TVrGauge.Paint;
var
  R: TRect;
begin
  CalcPaintParams;

  if (OrgSize.X <> ClientWidth) or
   (OrgSize.Y <> ClientHeight) then CreateBitmaps;

  ClearBitmapCanvas;

  R := ClientRect;
  FBevel.Paint(BitmapCanvas, R);

  case FOrientation of
    voVertical: DrawVert;
    voHorizontal: DrawHori;
  end;

  inherited Paint;
end;

procedure TVrGauge.CalcPaintParams;
begin
  TickStep := FTickHeight + FSpacing;
  FViewPort := ClientRect;
  FBevel.GetVisibleArea(FViewPort);
  case Orientation of
    voVertical:
      begin
        Ticks := (HeightOf(FViewPort) + FSpacing) div TickStep;
        Height := (FViewPort.Top * 2) + (Ticks * TickStep) - FSpacing;
      end;
    voHorizontal:
      begin
        Ticks := (WidthOf(FViewPort) + FSpacing) div TickStep;
        Width := (FViewPort.Left * 2) + (Ticks * TickStep) - FSpacing;
      end;
  end;
end;

procedure TVrGauge.MoveTo(X, Y: Integer);
var
  Range: Double;
begin
  Range := FMaxValue - FMinValue;
  case FOrientation of
    voVertical:
      begin
        if FStyle = psBottomLeft then
          Y := ClientHeight - Y - FTickHeight
        else Y := Y - FTickHeight;
        Position := Round(Y * Range / HeightOf(FViewPort))-1;
      end;
    voHorizontal:
      begin
        if FStyle = psBottomLeft then
          X := X - FTickHeight
        else X := ClientWidth - X - FTickHeight;
        Position := Round(X * Range / WidthOf(FViewPort))-1;
      end;
  end;
end;

procedure TVrGauge.MouseDown(Button: TMouseButton; Shift: TShiftState;
  X, Y: Integer);
begin
  inherited;
  if (Button = mbLeft) and (FActiveClick) then
    if PtInRect(FViewPort, Point(X, Y)) then MoveTo(X, Y);
end;


end.

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?