📄 teeselectortool.pas
字号:
{**********************************************}
{ 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 + -