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

📄 teeselectortool.pas

📁 TeeChart7Source 控件
💻 PAS
📖 第 1 页 / 共 2 页
字号:
{**********************************************}
{   TeeChart Selector Tool                     }
{   Copyright (c) 2001 by David Berneda        }
{**********************************************}
unit TeeSelectorTool;
{$I TeeDefs.inc}

interface

uses
  {$IFNDEF LINUX}
  Windows, Messages,
  {$ENDIF}
  SysUtils, Classes, 
  {$IFDEF CLX}
  QGraphics, QControls, QForms, QDialogs, QComCtrls, QStdCtrls, Types,
  {$ELSE}
  Graphics, Controls, Forms, Dialogs, ComCtrls, StdCtrls,
  {$ENDIF}
  TeEngine, Chart, TeeTools, TeCanvas, TeePenDlg;

type
  TSelectorTool=class(TTeeCustomTool)
  private
    FAllowDrag  : Boolean;
    FAllowResizeChart: Boolean;
    FHandleSize : Integer;
    FOnDragged  : TNotifyEvent;
    FOnDragging : TNotifyEvent;
    FOnResized  : TNotifyEvent;
    FOnResizing : TNotifyEvent;
    FOnSelected : TNotifyEvent;

    { internal }
    FAnnotation : TAnnotationTool;
    FDrawHandles: Boolean;
    FShape      : TTeeCustomShapePosition;
    FWall       : TChartWall;

    IDragging      : Boolean;
    IDragged       : Boolean;
    IDif           : TPoint;
    IResizingChart : Boolean;
    IResized       : Boolean;

    Procedure EmptySelection;
    function GetSeries: TChartSeries;
    procedure SetHandleSize(const Value: Integer);
    procedure SetAnnotation(const Value: TAnnotationTool);
    procedure SetWall(const Value: TChartWall);
    procedure SetSeries(const Value: TChartSeries);
  protected
    Procedure ChartEvent(AEvent:TChartToolEvent); override;
    Procedure ChartMouseEvent( AEvent: TChartMouseEvent;
                               Button:TMouseButton;
                               Shift: TShiftState; X, Y: Integer); override;
    Procedure DoSelected; virtual;
    class Function GetEditorClass:String; override;
  public
    Part: TChartClickedPart;
    Constructor Create(AOwner:TComponent); override;

    Procedure ClearSelection;
    Procedure StopDragging;
    Function ClickedCorner(X,Y:Integer):Boolean;
    class Function Description:String; override;
    Function SelectedTitle:TChartTitle;

    property Annotation : TAnnotationTool read FAnnotation write SetAnnotation;
    property DraggingShape: TTeeCustomShapePosition read FShape;
    property DrawHandles:Boolean read FDrawHandles write FDrawHandles;
    property Series:TChartSeries read GetSeries write SetSeries;
    property Wall: TChartWall read FWall write SetWall;
  published
    property Active;
    property AllowDrag:Boolean read FAllowDrag write FAllowDrag default True;
    property AllowResizeChart:Boolean read FAllowResizeChart write FAllowResizeChart default False;
    property Brush;
    property HandleSize:Integer read FHandleSize write SetHandleSize default 3;
    property Pen;

    property OnDragged:TNotifyEvent read FOnDragged write FOnDragged;
    property OnDragging:TNotifyEvent read FOnDragging write FOnDragging;
    property OnResized:TNotifyEvent read FOnResized write FOnResized;
    property OnResizing:TNotifyEvent read FOnResizing write FOnResizing;
    property OnSelected:TNotifyEvent read FOnSelected write FOnSelected;
  end;

  { Form Editor }
  TSelectorToolEditor = class(TForm)
    ButtonPen1: TButtonPen;
    Label1: TLabel;
    Edit1: TEdit;
    UDSize: TUpDown;
    ButtonColor1: TButtonColor;
    CBAllowDrag: TCheckBox;
    CBResizeChart: TCheckBox;
    procedure FormShow(Sender: TObject);
    procedure Edit1Change(Sender: TObject);
    procedure CBAllowDragClick(Sender: TObject);
    procedure CBResizeChartClick(Sender: TObject);
  private
    { Private declarations }
    Selector : TSelectorTool;
  public
    { Public declarations }
  end;

Const TeeMsg_SelectorTool='Selector';

implementation

{$IFNDEF CLX}
{$R *.DFM}
{$ELSE}
{$R *.xfm}
{$ENDIF}

{ TSelectorTool }
Constructor TSelectorTool.Create(AOwner: TComponent);
begin
  inherited;
  FHandleSize:=3;
  FDrawHandles:=True;
  FAllowDrag:=True;
end;

type TAxisAccess=class(TChartAxis);

procedure TSelectorTool.ChartEvent(AEvent: TChartToolEvent);

  Function RectFromPoint(X,Y:Integer):TRect;
  begin { return a rectangle few pixels around XY point }
    result:=TeeRect(X-HandleSize,Y-HandleSize,X+HandleSize,Y+HandleSize);
  end;

  Procedure DrawHandle(Const R:TRect);
  begin { draw four handles, one at each R rectangle corner }
    with ParentChart.Canvas, R do
    begin
      Rectangle(RectFromPoint(Left,Top));
      Rectangle(RectFromPoint(Left,Bottom));
      Rectangle(RectFromPoint(Right,Top));
      Rectangle(RectFromPoint(Right,Bottom));
    end;
  end;

  Procedure DrawHandleZ(Const R:TRect; Z:Integer);
  begin { draw the four handles of R corners at Z depth position }
    with ParentChart.Canvas, R do
    begin
      RectangleWithZ(RectFromPoint(Left,Top),Z);
      RectangleWithZ(RectFromPoint(Left,Bottom),Z);
      RectangleWithZ(RectFromPoint(Right,Top),Z);
      RectangleWithZ(RectFromPoint(Right,Bottom),Z);
    end;
  end;

  Procedure DoDrawHandles;

    Procedure DrawSeriesHandles(AtMarks:Boolean);
    var t: Integer;
        X: Integer;
        Y: Integer;
        tmpStep  : Integer;
        tmpLast  : Integer;
        tmpCount : Integer;
    begin
      if Assigned(Part.ASeries) then
      With Part.ASeries do
      begin
        { number of visible points }
        tmpCount:=LastValueIndex-FirstValueIndex;

        { if zero, then number of points }
        if tmpCount=0 then tmpCount:=Count;

        { calculate "step" (how many points? maximum=20) }
        if tmpCount>20 then tmpStep:=tmpCount div 20
                       else tmpStep:=1;

        { start loop to draw handles }
        t:=FirstValueIndex;
        if t=-1 then t:=0;

        { last loop value }
        tmpLast:=LastValueIndex;
        if tmpLast=-1 then tmpLast:=Count-1;

        { loop... }
        While t<=tmpLast do
        begin
          if AtMarks then
             DrawHandleZ(Marks.Positions[t].Bounds,Marks.ZPosition)
          else
          begin
            X:=CalcXPos(t);
            Y:=CalcYPos(t);
            ParentChart.Canvas.RectangleWithZ(RectFromPoint(X,Y),MiddleZ);
          end;
          Inc(t,tmpStep);
        end;
      end;
    end;

    Procedure DrawBackWallHandles;

      Procedure DrawHandlePoint(AX,AY:Integer);
      var P: TPoint;
      begin
        with ParentChart,Canvas do
        begin
          P:=Calculate3DPosition(AX,AY,Width3D);
          Rectangle(RectFromPoint(P.X,P.Y));
        end;
      end;

    begin
      with ParentChart.ChartRect do
      begin
        DrawHandlePoint(Left,Top);
        DrawHandlePoint(Right,Top);
        DrawHandlePoint(Left,Bottom);
        DrawHandlePoint(Right,Bottom);
      end;
    end;

  var R: TRect;
  begin
    R:=TeeRect(0,0,0,0);

    { calculate R corners of selected part }
    With TCustomChart(ParentChart) do
    Case Part.Part of
      cpNone    : begin R:=ClientRect; InflateRect(R,-HandleSize,-HandleSize); end;
      cpLegend  : if Legend.Visible then
                     R:=Legend.ShapeBounds;
      cpAxis    : R:=TAxisAccess(Part.AAxis).AxisRect;
      cpSeries  : DrawSeriesHandles(False);
      cpTitle   : R:=Title.TitleRect;
      cpFoot    : R:=Foot.TitleRect;
      cpSubTitle: R:=SubTitle.TitleRect;
      cpSubFoot : R:=SubFoot.TitleRect;
     cpChartRect: DrawBackWallHandles;
   cpSeriesMarks: DrawSeriesHandles(True);
    end;

    { draw four handles at rectangle R corners }
    if R.Right-R.Left>0 then
       DrawHandle(R);
  end;

begin { after drawing Chart, draw handles on selected part }
  inherited;

  if (AEvent=cteAfterDraw) and (not ParentChart.Printing) and FDrawHandles then
  begin
    { prepare Handle pen and color }
    With ParentChart.Canvas do
    begin
      AssignVisiblePen(Self.Pen);
      AssignBrush(Self.Brush,Self.Brush.Color);
    end;

    { draw handles on selected Shape rectangle corners }
    if Assigned(FShape) then
       DrawHandle(FShape.ShapeBounds)
    else
       DoDrawHandles;
  end;
end;

Function TSelectorTool.ClickedCorner(X,Y:Integer):Boolean;
begin { return True if XY is over the chart right-bottom corner }
  result:=(Abs(X-ParentChart.Width)<=8) and
          (Abs(Y-ParentChart.Height)<=8)
          // and (ParentChart.Align=alNone);
end;

procedure TSelectorTool.ChartMouseEvent(AEvent: TChartMouseEvent;
  Button: TMouseButton; Shift: TShiftState; X, Y: Integer);

⌨️ 快捷键说明

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