お知らせ

電子会議

ライブラリ

パレット

Delphi FAQ検索

Delphi FAQ一覧

サンプル蔵





FDelphi FAQ
16番会議室「玉石混淆みんなで作るSample蔵」に寄せられたサンプル

"ダイアルボタンコンポーネント"



    

近頃「ぐりぐり」がはやってるようなので、あるソフトに搭載予定のぐりぐり
ぼたん、もとい(^^; 'TDialBtn'コンポーネントをアップします。

カメラやビデオの、シャッターボタンと、セレクタースイッチのコンボをイ
メージして作りました。センターボタンでは、OnClick イベントが、セレク
ター部では、OnChange イベントが発生します、追加したプロパティはご覧に
なればわかるでしょう。(^^) なんかありましたら、8番あたりでどうぞ。

でわでわ。~\(^^)

                                 Yukimi Sake GHE01746@nifty.ne.jp

unit DialBtn;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls,ExtCtrls,
  Math;
type
  TDialBtn = class(TPaintBox)
  private
    FDivide,FCount,FNotchLen,PrevCount:integer;
    FNotchClr:TColor;
    origin:Tpoint;
    AryS,AryC:array[0..23] of extended ;
    ox,oy,r:extended;
    drag,inButton,init:Boolean;
    FOnChange: TNotifyEvent;
  protected
    procedure MouseDown( Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer); override ;
    procedure MouseUp( Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer); override;
    procedure MouseMove(Shift: TShiftState; X,
      Y: Integer); override;
    procedure Paint;override;
    procedure DrawGuage(N:integer;R,L:extended;canvas:TCanvas);
    procedure Change; dynamic;
    property Canvas;
  public
    constructor Create(AOwner: TComponent); override;
  published
    procedure Click;override;
    property Color default clBtnFace;
    property Width default 64;
    property Height default 64;
    property NDivide:integer read Fdivide write FDivide;
    property Position :integer read FCount write Fcount Default 0;
    property NotchLength : integer read FNotchLen write FNotchLen
              Default 4;
    property NotchColor :TColor read FNotchClr write FNotchClr
              default clBlack;
    property OnChange: TNotifyEvent read FOnChange write FOnChange;
end;

procedure Register;

implementation

constructor TDialBtn.Create(AOwner: TComponent);
begin
  inherited create(AOwner);
  Color := clBtnFace;
  Width := 64 ;
  Height := 64;
  FDivide := 24;
  FCount := 0;
  FNotchLen := 4;
  FNotchClr := clBlack;
  inButton := false;
  init := true;
end;

procedure TDialBtn.Change;
begin
  if Assigned(FOnChange) then FOnChange(Self);
end;

procedure TDialBtn.Click;
begin
if  inButton then
  inherited Click;
end;

procedure TdialBtn.Paint;
var
  i,n:integer;
begin
  if Fcount <> PrevCount then
  begin
    PrevCount := Fcount mod FDivide;
  end;
  with Self.Canvas do
  begin
    ox := width/2 ; oy := height/2; r := width/2-8;
  for i := 0 to FDivide-1 do
    sincos(i* Pi/FDivide,AryS[i],AryC[i]) ;
    Brush.Style:= bsSolid;
    brush.Color := Color;
    ellipse( 4,4,width-4,height-4);
    pen.Width:=1;
    pen.Color:= cl3DDkShadow;
    Arc(4,4,width-4,height-4,0,0,0,0);
    Arc(width div 4+2,height div 4+2,width div 4*3-2,height div 4*3-2,
        0,0,0,0);
    pen.Color:= clWhite;
    Arc(5,5,width-5,height-5,width,0,0,height);
    Arc(6,6,width-6,height-6,width,0,0,height);
    Arc(width div 4+1,height div 4+1,width div 4*3-1,height div 4*3-1,
        0,width,height,0);
    Arc(width div 4+3,height div 4+3,width div 4*3-3,height div 4*3-3,
        width,0,0,height);
    pen.Color:= clBtnShadow;
    Arc(5,5,width-5,height-5,0,width,height,0);
    Arc(6,6,width-6,height-6,0,width,height,0);
    Arc(width div 4+1,height div 4+1,width div 4*3-1,height div 4*3-1,
        width,0,0,height);
    Arc(width div 4+3,height div 4+3,width div 4*3-3,height div 4*3-3,
        0,width,height,0);
    canvas.Pen.Color := clBlack;
    canvas.Pen.width := 1;
    for n:= 0 to FDivide-1 do
    begin
      DrawGuage(n,r+5,3,canvas);
    end;
    canvas.Pen.Color := FNotchClr;
    DrawGuage(PrevCount,r+1,-FNotchLen,canvas);
  end;
end;

procedure TDialBtn.MouseDown(Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
var
  dx,dy,etha:extended;
begin
  inButton := false;
  with Self.Canvas do
  begin
    dx := X-width/2; dy := Y-height/2 ;
    etha := sqr(dx) + sqr(dy);
    if sqr( width/4-2) >= etha then
    begin
      pen.Color := clBtnHighlight;
      brush.Color := clBtnHighlight;
      brush.Style := bsSolid;
      ellipse(width div 4+3,height div 4+3,width div 4*3-3,height
              div 4*3-3);
      inButton := true;
    end
    else if  sqr(width/2-2) >= etha then
    begin
      origin.x:= round(dx); origin.y:= round(dy); drag := true;
    end;
  end;
end;

procedure TDialBtn.MouseUp( Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  PrevCount := FCount;
  drag := false;
  Self.refresh;
end;

procedure TDialBtn.MouseMove( Shift: TShiftState; X,
  Y: Integer);
var
  theta:extended;
  n:Integer;
begin
  if drag then
  begin
    theta :=ArcTan2(origin.y,origin.x)-Arctan2(Y-height/2,X-width/2);
    n := round(Theta/(2*pi/FDivide));
    canvas.Pen.width := 1;
    canvas.Pen.Color := FNotchClr;
    canvas.Pen.Mode := pmNotXor;
    DrawGuage(FCount,r+1,-FNotchLen,Canvas);//前の線消去
    //-FDivide/2 < FCount <= FDivide/2 にする
    FCount := (n+PrevCount) mod FDivide;
    if (Fcount > NDivide/2) or (FCount <= -NDivide/2) then
      FCount := Fcount - NDivide*round(FCount/abs(FCount));
    DrawGuage(FCount,r+1,-FNotchLen,Canvas);//改めて線描画
    canvas.Pen.Mode := pmCopy;
    Change;
  end;
end;

procedure TDialBtn.DrawGuage(N:integer;R,L:extended;canvas:TCanvas);
var S,C:extended;
begin
  sincos(N*2*pi/FDivide,S,C);
  canvas.moveto(round(ox+r*C),round(oy-r*S)) ;
  canvas.LineTo(round(ox+(R+L)*C),round(oy-(R+L)*S));
end;

procedure Register;
begin
  RegisterComponents('Samples', [TDialBtn]);
end;

end.

Original document by 雪見酒          氏 ID:(GHE01746)


ここにあるドキュメントは NIFTY SERVEの Delphi Users' Forum の16番会議室「玉石混淆みんなで作るSample蔵」に投稿されたサンプルです。これらのサンプルはボーランド株式会社がサポートする公式のものではありません。また、必ずしも動作が検証されているものではありません。これらのサンプルを使用したことに起因するいかなる損害も投稿者、およびフォーラムスタッフはその責めを負いません。使用者のリスクの範疇でご使用下さい。

Copyright 1996-2002 Delphi Users' Forum