⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 jvqdialbutton.pas

📁 East make Tray Icon in delphi
💻 PAS
📖 第 1 页 / 共 3 页
字号:
{******************************************************************************}
{* WARNING:  JEDI VCL To CLX Converter generated unit.                        *}
{*           Manual modifications will be lost on next release.               *}
{******************************************************************************}

{-----------------------------------------------------------------------------
The contents of this file are subject to the Mozilla Public License
Version 1.1 (the "License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.mozilla.org/MPL/MPL-1.1.html

Software distributed under the License is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See the License for
the specific language governing rights and limitations under the License.

The Original Code is: JvRadioGroup.PAS, released on 2002-07-16.

The Initial Developer of the Original Code is Rudolph Velthuis
Portions created by Rudolph Velthuis are Copyright (C) 1997 drs. Rudolph Velthuis.
All Rights Reserved.

Contributor(s):
  marcelb - renaming TJvDialButton, adding on/off state and on/off color for pointer.

You may retrieve the latest version of this file at the Project JEDI's JVCL home page,
located at http://jvcl.sourceforge.net

Description:
  TJvDialButton component, a button like the dial on a radio.

Known Issues:
-----------------------------------------------------------------------------}
// $Id: JvQDialButton.pas,v 1.16 2004/11/06 22:08:16 asnepvangers Exp $

unit JvQDialButton;

{$I jvcl.inc}

interface

uses
  QWindows, QMessages, Classes, QGraphics, QControls, QForms, QExtCtrls, QComCtrls,
  JvQComponent;

type
  TJvDialPointerShape = (psLine, psTriangle, psDot, psOwnerDraw);
  TJvTickLength = (tlShort, tlMiddle, tlLong);
  TJvDialAngle = 0..3600; // 0.0 - 360.0 deg
  TJvRepeatValue = 10..1000; // mouse repeat values
  TJvCustomDialButton = class;
  TJvDialDrawEvent = procedure(Sender: TJvCustomDialButton; ARect: TRect) of object;

  PTick = ^TTick;
  TTick = record
    Value: Integer;
    Length: Integer;
    Color: TColor;
    Changed: Boolean;
  end;

  TJvCustomDialButton = class(TJvCustomControl)
  private
    FBitmap: TBitmap;
    FBitmapRect: TRect;
    FBitmapInvalid: Boolean;
    FBorderStyle: TBorderStyle;
    FButtonEdge: Integer;
    FDefaultPos: Integer;
    FFrequency: Integer;
    FLargeChange: Integer;
    FMax: Integer;
    FMaxAngle: TJvDialAngle;
    FMin: Integer;
    FMinAngle: TJvDialAngle;
    FPointerRect: TRect;
    FPointerColor: TColor;
    FPointerColorOff: TColor;
    FPointerSize: Integer;
    FPointerShape: TJvDialPointerShape;
    FPosition: Integer;
    FRadius: Integer;
    FSize: Integer;
    FState: Boolean;
    FSmallChange: Integer;
    FTicks: TList;
    FTickStyle: TTickStyle;
    FIncrementing: Boolean;
    FRepeatTimer: TTimer;
    FRepeatRate: TJvRepeatValue;
    FRepeatDelay: TJvRepeatValue;
    FOnChange: TNotifyEvent;
    FOnDrawPointer: TJvDialDrawEvent;
    function CalcBounds(var AWidth, AHeight: Integer): Boolean;
    function GetAngle: TJvDialAngle;
    function GetCenter: TPoint;
    procedure SetAngle(Value: TJvDialAngle);
    procedure SetBorderStyle(Value: TBorderStyle);
    procedure SetButtonEdge(Value: Integer);
    procedure SetDefaultPos(Value: Integer);
    procedure SetFrequency(Value: Integer);
    procedure SetLargeChange(Value: Integer);
    procedure SetMin(Value: Integer);
    procedure SetMinAngle(Value: TJvDialAngle);
    procedure SetMax(Value: Integer);
    procedure SetMaxAngle(Value: TJvDialAngle);
    procedure SetPointerColor(Value: TColor);
    procedure SetPointerColorOff(Value: TColor);
    procedure SetPointerSize(Value: Integer);
    procedure SetPointerShape(Value: TJvDialPointerShape);
    procedure SetPosition(Value: Integer);
    procedure SetRadius(Value: Integer);
    procedure SetSmallChange(Value: Integer);
    procedure SetState(Value: Boolean);
    procedure SetTickStyle(Value: TTickStyle);
    procedure UpdateSize;
    procedure TimerExpired(Sender: TObject);
  protected
    function AngleToPos(AnAngle: TJvDialAngle): Integer;
    procedure BitmapNeeded; dynamic;
    procedure Change; dynamic;
    procedure ClearTicks;
    procedure Click; override; 
    procedure DoEnter; override;
    procedure DoExit; override;
    procedure ColorChanged; override;
    procedure ParentColorChanged; override;
    procedure DrawBorder; dynamic;
    procedure DrawButton; dynamic;
    procedure DrawPointer; dynamic;
    procedure DrawTick(ACanvas: TCanvas; var Tick: TTick); dynamic;
    procedure DrawTicks; dynamic;
    procedure KeyDown(var Key: Word; Shift: TShiftState); override;
    procedure Loaded; override;
    procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
    procedure MouseMove(Shift: TShiftState; X, Y: Integer); override;
    procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
    procedure Paint; override;
    function PosToAngle(Pos: Integer): TJvDialAngle;
    procedure SetTicks(Value: TTickStyle); virtual;

    procedure IncPos(Shift: TShiftState); dynamic;
    procedure DecPos(Shift: TShiftState); dynamic;
    property Ticks: TList read FTicks write FTicks stored True;
    // to be published later:
    property Angle: TJvDialAngle read GetAngle write SetAngle stored False;
    property BorderStyle: TBorderStyle read FBorderStyle write SetBorderStyle default bsNone;
    property ButtonEdge: Integer read FButtonEdge write SetButtonEdge default 2;
    property DefaultPos: Integer read FDefaultPos write SetDefaultPos;
    property Frequency: Integer read FFrequency write SetFrequency default 10;
    property LargeChange: Integer read FLargeChange write SetLargeChange default 2;
    property Max: Integer read FMax write SetMax default 100;
    property MaxAngle: TJvDialAngle read FMaxAngle write SetMaxAngle default 3300;
    property Min: Integer read FMin write SetMin default 0;
    property MinAngle: TJvDialAngle read FMinAngle write SetMinAngle default 300;
    property PointerColorOn: TColor read FPointerColor write SetPointerColor default clBtnText;
    property PointerColorOff: TColor read FPointerColorOff write SetPointerColorOff default clGrayText;
    property PointerSize: Integer read FPointerSize write SetPointerSize default 33;
    property PointerShape: TJvDialPointerShape read FPointerShape write SetPointerShape default psLine;
    property Position: Integer read FPosition write SetPosition default 0;
    property Radius: Integer read FRadius write SetRadius;
    property RepeatDelay: TJvRepeatValue read FRepeatDelay write FRepeatDelay default 400;
    property RepeatRate: TJvRepeatValue read FRepeatRate write FRepeatRate default 100;
    property SmallChange: Integer read FSmallChange write SetSmallChange default 1;
    property State: Boolean read FState write SetState default True;
    property TickStyle: TTickStyle read FTickStyle write SetTickStyle stored True;
    property TabStop default True;
    property OnChange: TNotifyEvent read FOnChange write FOnChange;
    property OnDrawPointer: TJvDialDrawEvent read FOnDrawPointer write FOnDrawPointer;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
    function AngleToPoint(AnAngle: TJvDialAngle; ACenter: TPoint; ARadius: Integer): TPoint;
    procedure SetAngleParams(AnAngle, AMin, AMax: TJvDialAngle); virtual;
    procedure SetBounds(ALeft, ATop, AWidth, AHeight: Integer); override;
    procedure SetParams(APosition, AMin, AMax: Integer); virtual;
    procedure SetTick(Value: Integer; Length: TJvTickLength); virtual;
    function RadToAngle(const Radian: Double): TJvDialAngle;
    function AngleToRad(AnAngle: TJvDialAngle): Double;
    property Bitmap: TBitmap read FBitmap;
    property Center: TPoint read GetCenter;
  end;

  TJvDialButton = class(TJvCustomDialButton)
  published
    // properties
    property Align;
    property Angle;
    property BorderStyle;
    property ButtonEdge;
    property Color;
    property Cursor;
    property DefaultPos; 
    property DragMode;
    property Enabled;
    property Frequency;
    property LargeChange;
    property Max;
    property MaxAngle;
    property Min;
    property MinAngle;
    property ParentColor;
    property ParentShowHint;
    property PointerColorOn;
    property PointerColorOff;
    property PointerSize;
    property PointerShape;
    property PopupMenu;
    property Position;
    property Radius;
    property RepeatDelay;
    property RepeatRate;
    property ShowHint;
    property SmallChange;
    property State;
    property TickStyle;
    property TabOrder;
    property TabStop;
    property Visible;
    // events
    property OnChange;
    property OnClick;
    property OnDblClick;
    property OnDragDrop;
    property OnDragOver;
    property OnDrawPointer;
    property OnEndDrag;
    property OnEnter;
    property OnExit;
    property OnKeyDown;
    property OnKeyPress;
    property OnKeyUp;
    property OnMouseDown;
    property OnMouseMove;
    property OnMouseUp;
    property OnStartDrag;
  end;

implementation

uses
  {$IFDEF UNITVERSIONING}
  JclUnitVersioning,
  {$ENDIF UNITVERSIONING}
  QConsts, Math,
  JvQThemes;

const
  dAngleToRadian = Pi / 1800;
  dRadianToAngle = 1800 / Pi;
  rcMaxEdge = 100;
  rcMinEdge = 0;
  rcMinRadius = 15;
  tlLongLen = 10;
  tlMiddleLen = 6;
  tlShortLen = 4;

  MinBorder = 1;
  TickBorder = tlLongLen;

function GetShiftState: TShiftState;
begin
  Result := [];
  if GetKeyState(VK_SHIFT) < 0 then
    Include(Result, ssShift);
  if GetKeyState(VK_CONTROL) < 0 then
    Include(Result, ssCtrl);
  if GetKeyState(VK_MENU) < 0 then
    Include(Result, ssAlt);
end;

constructor TJvCustomDialButton.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  ControlStyle := ControlStyle + [csClickEvents, csCaptureMouse]; 
  FTicks := TList.Create;
  FBorderStyle := bsNone;
  FButtonEdge := 5;
  FDefaultPos := 0;
  FFrequency := 10;
  FLargeChange := 2;
  FMax := 100;
  FMaxAngle := 3300;
  FMin := 0;
  FMinAngle := 300;
  FPointerColor := clBtnText;
  FPointerColorOff := clGrayText;
  FPointerSize := 33;
  FRadius := rcMinRadius;
  FSmallChange := 1;
  FState := True;
  TabStop := True;
  FTickStyle := tsAuto;
  FBitmapInvalid := True;
  FPointerRect.Left := -1; // Only on start up
  Width := 51;
  Height := 51;
  FRepeatDelay := 400;
  FRepeatRate := 100;
  SetTicks(FTickStyle);
  Position := 0;
end;

destructor TJvCustomDialButton.Destroy;
begin
  FBitmap.Free;
  ClearTicks;
  FTicks.Free;
  FRepeatTimer.Free;
  inherited Destroy;
end;

// Convert position Pos to an angle.

function TJvCustomDialButton.PosToAngle(Pos: Integer): TJvDialAngle;
begin
  Result := FMinAngle + ((FMaxAngle - FMinAngle) * (Pos - FMin) div (FMax - FMin));
end;

// Convert angle AnAngle to a position.

function TJvCustomDialButton.AngleToPos(AnAngle: TJvDialAngle): Integer;
begin
  Result := FMin + ((FMax - FMin) * (AnAngle - FMinAngle) div (FMaxAngle - FMinAngle));
end;

// Convert polar coordinates defined by AnAngle, ACenter and ARadius to a TPoint.

function TJvCustomDialButton.AngleToPoint(AnAngle: TJvDialAngle; ACenter: TPoint;
  ARadius: Integer): TPoint;
var
  RadAngle: Double;
begin
  RadAngle := AngleToRad(AnAngle);
  Result.X := ACenter.X - Round(ARadius * Sin(RadAngle));
  Result.Y := ACenter.Y + Round(ARadius * Cos(RadAngle));
end;

// Convert a APoint to an angle (relative to ACenter) in radians, where
// bottom is 0, left is Pi/2, top is Pi and so on.

function PointToRad(const APoint, ACenter: TPoint): Double;
var
  N: Integer;
begin
  N := APoint.X - ACenter.X;
  if N = 0 then
    Result := 0.5 * Pi
  else
    Result := ArcTan((ACenter.Y - APoint.Y) / N);
  if N < 0 then
    Result := Result + Pi;
  Result := 1.5 * Pi - Result;
end;

// Get current angle (from position).

function TJvCustomDialButton.GetAngle: TJvDialAngle;
begin
  Result := PosToAngle(FPosition);
end;

// Set current angle. Sets Position.

procedure TJvCustomDialButton.SetAngle(Value: TJvDialAngle);
begin
  SetAngleParams(Value, FMinAngle, FMaxAngle);
end;

// Set border style. Redraw if necessary.

procedure TJvCustomDialButton.SetBorderStyle(Value: TBorderStyle);
begin
  if Value <> FBorderStyle then
  begin
    FBorderStyle := Value;
    if HandleAllocated then
    begin 
      DrawBorder;
    end;
  end;
end;

// Set positional (Cartesian) parameters, value checked and invalidate if
// necessary.

procedure TJvCustomDialButton.SetParams(APosition, AMin, AMax: Integer);
var
  Invalid: Boolean;
  Changed: Boolean;
begin
  Changed := False;

  // Ensure minimum and maximum in right order.
  if AMax < AMin then
    raise EInvalidOperation.CreateResFmt(@SPropertyOutOfRange, [ClassName]);

  // Limit Position to Min and Max.
  if APosition < AMin then
    APosition := AMin;
  if APosition > AMax then
    APosition := AMax;

  Invalid := False;

  // Change Min if necessary and flag redrawing if so.
  if FMin <> AMin then
  begin
    FMin := AMin;
    Invalid := True;
  end;

  // Change Max if necessary and flag redrawing if so.
  if FMax <> AMax then

⌨️ 快捷键说明

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