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

📄 teetools.pas

📁 第三方控件:PaintGrid.pas 网格型仪表控件源文件 Mymeter.pas 圆型仪表控件源文件 Project1是这两个控件的使用范例。 该
💻 PAS
📖 第 1 页 / 共 5 页
字号:
    property Series;
    property StartAtMin:Boolean read FStartAtMin write FStartAtMin default True;
    property StartValue:Double read FStartValue write FStartValue;
    property Steps:Integer read FSteps write FSteps default 100;
    { events }
    property OnStep:TSeriesAnimationStep read FOnStep write FOnStep;
  end;

  TRectangleTool=class(TAnnotationTool)
  private
    FOnDragging : TNotifyEvent;
    FOnResizing : TNotifyEvent;

    P           : TPoint;
    IDrag       : Boolean;
    IEdge       : Integer;
  protected
    Procedure ChartMouseEvent( AEvent: TChartMouseEvent;
                               Button:TMouseButton;
                               Shift: TShiftState; X, Y: Integer); override;
  public
    Constructor Create(AOwner:TComponent); override;

    Function Bitmap(ChartOnly:Boolean=False):TBitmap;
    Function ClickedEdge(x,y:Integer):Integer;
    class Function Description:String; override;
  published
    property OnDragging:TNotifyEvent read FOnDragging write FOnDragging;
    property OnResizing:TNotifyEvent read FOnResizing write FOnResizing;
  end;

  TClipSeriesTool=class(TTeeCustomToolSeries)
  private
    IActive : Boolean;

    procedure AddClip(Sender: TObject);
    procedure RemoveClip(Sender: TObject);
  protected
    procedure Notification(AComponent: TComponent; Operation: TOperation); override;
    procedure SetSeries(const Value: TChartSeries); override;
  public
    class Function Description:String; override;
  published
    property Active;
    property Series;
  end;

implementation

Uses {$IFDEF CLX}
     QForms,
     {$ELSE}
     Forms,
     {$ENDIF}
     Math, TeeConst, TeeProCo;

{ TCursorTool }
Constructor TCursorTool.Create(AOwner:TComponent);
begin
  inherited;
  FClick:=TeeClickTolerance;
  FStyle:=cssBoth;
  IPoint.X:=-1;
  IPoint.Y:=-1;
  IOldSnap:=-1;
end;

Procedure TCursorTool.CalcValuePositions(X,Y:Integer);
begin
  if UseSeriesZ then
     ParentChart.Canvas.Calculate2DPosition(x,y,Z);

  Case IDragging of
    ccVertical  : IXValue:=GetHorizAxis.CalcPosPoint(X);
    ccHorizontal: IYValue:=GetVertAxis.CalcPosPoint(Y);
  else
  begin
    IXValue:=GetHorizAxis.CalcPosPoint(X);
    IYValue:=GetVertAxis.CalcPosPoint(Y);
  end;
  end;
end;

Procedure TCursorTool.CalcScreenPositions;
var tmpSnap : Integer;
begin
  if (IPoint.X=-1) or (IPoint.Y=-1) then
  begin
    With GetHorizAxis do IPoint.X:=(IStartPos+IEndPos) div 2;
    With GetVertAxis do IPoint.Y:=(IStartPos+IEndPos) div 2;

    CalcValuePositions(IPoint.X,IPoint.Y);
    tmpSnap:=SnapToPoint;
    CalcScreenPositions;
    Changed(tmpSnap);
  end
  else
  begin
    IPoint.X:=GetHorizAxis.CalcPosValue(IXValue);
    IPoint.Y:=GetVertAxis.CalcPosValue(IYValue);
  end;
end;

Procedure TCursorTool.Changed(SnapPoint:Integer);
begin
  if Assigned(FOnChange) then
     FOnChange(Self,IPoint.X,IPoint.Y,IXValue,IYValue,Series,SnapPoint);
end;

class Function TCursorTool.GetEditorClass:String;
begin
  result:='TCursorToolEditor';
end;

class Function TCursorTool.Description:String;
begin
  result:=TeeMsg_CursorTool;
end;

Function TeeGetFirstLastSeries(Series:TChartSeries;
                               Var AMin,AMax:Integer):Boolean; { 5.01 }
begin
  AMin:=Series.FirstValueIndex;
  if AMin<0 then AMin:=0;

  AMax:=Series.LastValueIndex;
  if AMax<0 then AMax:=Series.Count-1
  else
  if AMax>=Series.Count then AMax:=Series.Count-1; { 5.03 }

  result:=(Series.Count>0) and (AMin<=Series.Count) and (AMax<=Series.Count);
end;

Function TCursorTool.NearestPoint(AStyle:TCursorToolStyle;
                                  Var Difference:Double):Integer;
var t      : Integer;
    tmpDif : Double;
    tmpMin : Integer;
    tmpMax : Integer;
begin
  result:=-1;
  Difference:=-1;

  if TeeGetFirstLastSeries(Series,tmpMin,tmpMax) then
  for t:=tmpMin to tmpMax do
  begin
    With Series do
    Case AStyle of
      cssHorizontal: tmpDif:=Abs(IYValue-YValues.Value[t]);
      cssVertical  : tmpDif:=Abs(IXValue-XValues.Value[t]);
    else
      tmpDif:=Sqrt(Sqr(IXValue-XValues.Value[t])+Sqr(IYValue-YValues.Value[t]));
    end;

    if (Difference=-1) or (tmpDif<Difference) then
    begin
      Difference:=tmpDif;
      result:=t;
    end;
  end;
end;

Function TCursorTool.SnapToPoint:Integer;
var Difference : Double;
begin
  if Assigned(Series) and FSnap then result:=NearestPoint(FStyle,Difference)
                                else result:=-1;

  if result<>-1 then
  Case FStyle of
    cssHorizontal: IYValue:=Series.YValues.Value[result];
    cssVertical  : IXValue:=Series.XValues.Value[result];
  else
    begin
      IXValue:=Series.XValues.Value[result];
      IYValue:=Series.YValues.Value[result]
    end;
  end;
end;

Function TCursorTool.GetAxisRect:TRect;
begin
  if UseChartRect then result:=ParentChart.ChartRect
  else
  begin
    With GetHorizAxis do
    begin
      result.Left:=IStartPos;
      result.Right:=IEndPos;
    end;
    With GetVertAxis do
    begin
      result.Top:=IStartPos;
      result.Bottom:=IEndPos;
    end;
    if Assigned(FOnGetAxisRect) then FOnGetAxisRect(Self,result);
  end;
end;

Function TCursorTool.Z:Integer;
begin
  if UseSeriesZ and Assigned(Series) then
     result:=Series.StartZ
  else
     result:=0;
end;

procedure TCursorTool.RedrawCursor;

  Procedure DrawCursorLines(Draw3D:Boolean; Const R:TRect; X,Y:Integer);

    Procedure DrawHorizontal;
    begin
      With ParentChart.Canvas do
      if Draw3D then HorizLine3D(R.Left,R.Right,Y,Z)
                else DoHorizLine(R.Left,R.Right,Y);
    end;

    Procedure DrawVertical;
    begin
      With ParentChart.Canvas do
      if Draw3D then VertLine3D(X,R.Top,R.Bottom,Z)
                else DoVertLine(X,R.Top,R.Bottom);
    end;

  begin
    Case FStyle of
      cssHorizontal: DrawHorizontal;
      cssVertical  : DrawVertical;
    else
    begin
      DrawHorizontal;
      DrawVertical;
    end;
    end;
  end;

var tmpColor : TColor;
begin
  if Assigned(ParentChart) then
  begin
    tmpColor:=ParentChart.Color;
    if tmpColor=clTeeColor then tmpColor:=clBtnFace;

    With ParentChart.Canvas do
    begin
      AssignVisiblePenColor(Self.Pen,Self.Pen.Color xor ColorToRGB(tmpColor));
      Brush.Style:=bsClear;
      Pen.Mode:=pmXor;
      DrawCursorLines(ParentChart.View3D,GetAxisRect,IPoint.X,IPoint.Y);
      Pen.Mode:=pmCopy;
      ParentChart.Canvas.Invalidate;
    end;
  end;
end;

Function TCursorTool.InAxisRectangle(x,y:Integer):Boolean;
begin
  if UseSeriesZ then
     ParentChart.Canvas.Calculate2DPosition(x,y,Z);

  result:=PointInRect(GetAxisRect,x,y);
end;

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

  Procedure MouseMove;
  var tmpSnap : Integer;
      tmp     : TCursorClicked;
  begin
    { if mouse button is pressed and dragging then... }
    if ((IDragging<>ccNone) or FollowMouse) and InAxisRectangle(X,Y) then
    begin
      RedrawCursor;      { hide the cursor }
      CalcValuePositions(X,Y);

      tmpSnap:=SnapToPoint;  { snap to the nearest point of SnapSeries }

      { draw again the cursor at the new position }
      CalcScreenPositions;
      RedrawCursor;
      Changed(tmpSnap);

      if Assigned(FOnSnapChange) and (IOldSnap<>tmpSnap) then  // 7.0
         FOnSnapChange(Self,IPoint.X,IPoint.Y,IXValue,IYValue,Series,tmpSnap);

      IOldSnap:=tmpSnap;
    end
    else
    begin  { mouse button is not pressed, user is not dragging the cursor }
           { change the mouse cursor when passing over the Cursor }
      tmp:=Clicked(x,y);
      case tmp of
         ccHorizontal : ParentChart.Cursor:=crVSplit;
         ccVertical   : ParentChart.Cursor:=crHSplit;
         ccBoth       : ParentChart.Cursor:=crSizeAll;
      end;

      ParentChart.CancelMouse:=tmp<>ccNone;
    end;
  end;

begin
  Case AEvent of
      cmeUp: IDragging:=ccNone;
    cmeMove: MouseMove;
    cmeDown: if not FFollowMouse then
             begin
               IDragging:=Clicked(x,y);
               if IDragging<>ccNone then ParentChart.CancelMouse:=True;
             end;
  end;
end;

Function TCursorTool.Clicked(x,y:Integer):TCursorClicked;
var tmp : TPoint;
begin
  result:=ccNone;

  if InAxisRectangle(x,y) then
  begin
    tmp:=IPoint;

    if UseSeriesZ then
       ParentChart.Canvas.Calculate2DPosition(x,y,Z);

    if (FStyle=cssBoth) and (Abs(Y-tmp.Y)<=ClickTolerance)
                        and (Abs(X-tmp.X)<=ClickTolerance) then
       result:=ccBoth
    else
    if ((FStyle=cssHorizontal) or (FStyle=cssBoth))
            and (Abs(Y-tmp.Y)<=ClickTolerance) then
       result:=ccHorizontal
    else
    if ((FStyle=cssVertical) or (FStyle=cssBoth))
            and (Abs(X-tmp.X)<=ClickTolerance) then
       result:=ccVertical
  end;
end;

Procedure TCursorTool.SetStyle(Value:TCursorToolStyle);
begin
  if FStyle<>Value then
  begin
    FStyle:=Value;
    SnapToPoint;
    Repaint;
  end;
end;

procedure TCursorTool.SetSeries(const Value: TChartSeries);
begin
  inherited;

  IOldSnap:=-1;

  if Assigned(Series) and (not (csLoading in ComponentState)) then
  begin
    SnapToPoint;
    Repaint;
  end;
end;

procedure TCursorTool.ChartEvent(AEvent: TChartToolEvent);
begin
  inherited;

  if (AEvent=cteAfterDraw) then
  begin
    CalcScreenPositions;
    RedrawCursor;
  end;
end;

procedure TCursorTool.SetXValue(const Value: Double);
begin
  if IXValue<>Value then
  begin
    IXValue:=Value;
    IOldSnap:=-1;
    DoChange;
  end;
end;

procedure TCursorTool.DoChange;
begin
  CalcScreenPositions;
  Changed(-1);
  Repaint;
end;

procedure TCursorTool.SetYValue(const Value: Double);
begin
  if IYValue<>Value then
  begin
    IYValue:=Value;
    IOldSnap:=-1;
    DoChange;
  end;
end;

procedure TCursorTool.SetUseChartRect(const Value: Boolean);
begin
  SetBooleanProperty(FUseChartRect,Value);
end;

procedure TCursorTool.SetUseSeriesZ(const Value: Boolean);
begin
  SetBooleanProperty(FUseSeriesZ,Value);
end;

{ TDragMarksTool }
class function TDragMarksTool.Description: String;
begin
  result:=TeeMsg_DragMarksTool;
end;

Procedure TDragMarksTool.ChartMouseEvent( AEvent: TChartMouseEvent;

⌨️ 快捷键说明

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