teetools.pas
来自「Delphi TeeChartPro.6.01的源代码」· PAS 代码 · 共 2,188 行 · 第 1/5 页
PAS
2,188 行
Procedure TDrawLine.DrawHandles;
begin
With Parent.ParentChart.Canvas do
begin
Brush.Style:=bsSolid;
if Parent.ParentChart.Color=clBlack then Brush.Color:=clSilver
else Brush.Color:=clBlack;
Pen.Style:=psClear;
RectangleWithZ(StartHandle,0);
RectangleWithZ(EndHandle,0);
end;
end;
{ TDrawLines }
function TDrawLines.Get(Index: Integer): TDrawLine;
begin
result:=TDrawLine(inherited Items[Index]);
end;
function TDrawLines.Last: TDrawLine;
begin
if Count=0 then result:=nil else result:=Get(Count-1);
end;
procedure TDrawLines.Put(Index: Integer; const Value: TDrawLine);
begin
Items[Index].Assign(Value);
end;
{ TDrawLine }
Constructor TDrawLine.CreateXY(Collection:TCollection; const X0, Y0, X1, Y1: Double);
begin
Create(Collection);
StartPos.X:=X0;
StartPos.Y:=Y0;
EndPos.X:=X1;
EndPos.Y:=Y1;
end;
Destructor TDrawLine.Destroy; { 5.02 }
begin
if Self=Parent.ISelected then Parent.ISelected:=nil;
inherited;
end;
function TDrawLine.GetPen: TChartPen;
begin
result:=Parent.Pen;
end;
procedure TDrawLine.Assign(Source: TPersistent);
begin
if Source is TDrawLine then
With TDrawLine(Source) do
Begin
Self.StartPos :=StartPos;
Self.EndPos :=EndPos;
Self.FStyle :=FStyle;
end
else inherited;
end;
type TOwnedCollectionAccess=class(TOwnedCollection);
function TDrawLine.GetParent: TDrawLineTool;
begin
result:=TDrawLineTool(TOwnedCollectionAccess(Collection).GetOwner);
end;
function TDrawLine.GetX0: Double;
begin
result:=StartPos.X;
end;
function TDrawLine.GetX1: Double;
begin
result:=EndPos.X;
end;
function TDrawLine.GetY0: Double;
begin
result:=StartPos.Y;
end;
function TDrawLine.GetY1: Double;
begin
result:=EndPos.Y;
end;
Procedure TDrawLine.SetStyle(Value:TDrawLineStyle);
begin
if FStyle<>Value then
begin
FStyle:=Value;
Parent.Repaint;
end;
end;
procedure TDrawLine.SetX0(const Value: Double);
begin
Parent.SetDoubleProperty(StartPos.X,Value);
end;
procedure TDrawLine.SetX1(const Value: Double);
begin
Parent.SetDoubleProperty(EndPos.X,Value);
end;
procedure TDrawLine.SetY0(const Value: Double);
begin
Parent.SetDoubleProperty(StartPos.Y,Value);
end;
procedure TDrawLine.SetY1(const Value: Double);
begin
Parent.SetDoubleProperty(EndPos.Y,Value);
end;
{ TDrawLineTool }
Constructor TDrawLineTool.Create(AOwner: TComponent);
begin
inherited;
FButton:=mbLeft;
FLines:=TDrawLines.Create(Self,TDrawLine);
FEnableDraw:=True;
FEnableSelect:=True;
ISelected:=nil;
IHandle:=chNone;
end;
Destructor TDrawLineTool.Destroy;
begin
ISelected:=nil;
FLines.Free;
inherited;
end;
Procedure TDrawLineTool.DrawLine( Const StartPos,EndPos:TPoint;
AStyle:TDrawLineStyle);
begin
With ParentChart.Canvas do
if ParentChart.View3D then
begin
Case AStyle of
dlLine: begin
MoveTo3D(StartPos.X,StartPos.Y,0);
LineTo3D(EndPos.X,EndPos.Y,0);
end;
dlHorizParallel: begin
HorizLine3D(StartPos.X,EndPos.X,StartPos.Y,0);
HorizLine3D(StartPos.X,EndPos.X,EndPos.Y,0);
end;
else
begin
VertLine3D(StartPos.X,StartPos.Y,EndPos.Y,0);
VertLine3D(EndPos.X,StartPos.Y,EndPos.Y,0);
end
end;
end
else
Case AStyle of
dlLine: Line(StartPos.X,StartPos.Y,EndPos.X,EndPos.Y);
dlHorizParallel: begin
DoHorizLine(StartPos.X,EndPos.X,StartPos.Y);
DoHorizLine(StartPos.X,EndPos.X,EndPos.Y);
end;
else
begin
DoVertLine(StartPos.X,StartPos.Y,EndPos.Y);
DoVertLine(EndPos.X,StartPos.Y,EndPos.Y);
end
end;
end;
procedure TDrawLineTool.ChartEvent(AEvent: TChartToolEvent);
var t : Integer;
begin
inherited;
if (AEvent=cteAfterDraw) and (Lines.Count>0) then
begin
with ParentChart do
begin
Canvas.BackMode:=cbmTransparent;
ClipDrawingRegion;
end;
for t:=0 to Lines.Count-1 do
With Lines[t] do
begin
ParentChart.Canvas.AssignVisiblePen(Pen);
DrawLine(AxisPoint(StartPos),AxisPoint(EndPos),Style);
end;
if Assigned(ISelected) then ISelected.DrawHandles;
ParentChart.Canvas.UnClipRectangle;
end;
end;
Procedure TDrawLineTool.ClipDrawingRegion;
var R : TRect;
begin
if Assigned(Series) then
With Series do
R:=TeeRect(GetHorizAxis.IStartPos,GetVertAxis.IStartPos,
GetHorizAxis.IEndPos,GetVertAxis.IEndPos)
else
R:=ParentChart.ChartRect;
With ParentChart do
if CanClip then Canvas.ClipCube(R,0,Width3D);
end;
Function TDrawLineTool.InternalClicked(X,Y:Integer; AHandle:TDrawLineHandle):TDrawLine;
var P : TPoint;
Function ClickedLine(ALine:TDrawLine):Boolean;
var tmpStart : TPoint;
tmpEnd : TPoint;
begin
With ALine do
begin
tmpStart:=AxisPoint(StartPos);
tmpEnd:=AxisPoint(EndPos);
Case AHandle of
chStart: result:=PointInRect(StartHandle,P.X,P.Y);
chEnd : result:=PointInRect(EndHandle,P.X,P.Y);
else
Case Style of
dlLine : result:=PointInLine(P,tmpStart,tmpEnd,4);
dlHorizParallel : begin
result:=PointInLine(P,tmpStart.X,tmpStart.Y,
tmpEnd.X,tmpStart.Y,4);
if not result then
result:=PointInLine( P,tmpStart.X,tmpEnd.Y,
tmpEnd.X,tmpEnd.Y,4);
end;
else
begin
result:=PointInLine( P,tmpStart.X,tmpStart.Y,
tmpStart.X,tmpEnd.Y,4);
if not result then
result:=PointInLine( P,tmpEnd.X,tmpStart.Y,
tmpEnd.X,tmpEnd.Y,4);
end
end;
end;
end;
end;
var t : Integer;
begin
result:=nil;
// convert from 3D to 2D...
ParentChart.Canvas.Calculate2DPosition(X,Y,0);
// first, find if clicked the selected line...
P:=TeePoint(X,Y);
if Assigned(ISelected) and ClickedLine(ISelected) then
begin
result:=ISelected;
exit;
end;
// find which clicked line...
for t:=0 to Lines.Count-1 do
if ClickedLine(Lines[t]) then
begin
result:=Lines[t];
break;
end;
end;
Function TDrawLineTool.Clicked(X,Y:Integer):TDrawLine;
begin
// try first with whole line...
result:=InternalClicked(X,Y,chNone);
// try then at start and end line points...
if not Assigned(result) then result:=InternalClicked(X,Y,chStart);
if not Assigned(result) then result:=InternalClicked(X,Y,chEnd);
end;
Procedure TDrawLineTool.ChartMouseEvent( AEvent: TChartMouseEvent;
AButton:TMouseButton;
AShift: TShiftState; X, Y: Integer);
{ returns True if the mouse is over selected line ending points or over
any non-selected line.
If True, the Chart cursor is changed.
}
Function CheckCursor:Boolean;
begin
if Assigned(ISelected) and
((InternalClicked(X,Y,chStart)=ISelected) or
(InternalClicked(X,Y,chEnd)=ISelected)) then { ending points }
begin
ParentChart.Cursor:=crCross;
result:=True;
end
else
if Assigned(Clicked(X,Y)) then { over a line }
begin
ParentChart.Cursor:=crHandPoint; // set cursor
result:=True;
end
else result:=False;
end;
var tmpLine : TDrawLine;
tmpAllow : Boolean;
begin
Case AEvent of
cmeDown: if AButton=FButton then
begin
if FEnableSelect then tmpLine:=Clicked(X,Y)
else tmpLine:=nil;
if Assigned(tmpLine) then { clicked line, do select }
begin
FromPoint:=AxisPoint(tmpLine.StartPos);
ToPoint:=AxisPoint(tmpLine.EndPos);
IHandle:=chSeries;
IPoint:=TeePoint(X,Y);
if tmpLine<>ISelected then
begin
tmpAllow:=True;
if Assigned(FOnSelecting) then
FOnSelecting(Self,tmpLine,tmpAllow); { 5.03 }
if tmpAllow then
begin
{ change selected line }
if Assigned(ISelected) then
begin
ISelected:=tmpLine;
Repaint;
end
else
begin
ISelected:=tmpLine;
ISelected.DrawHandles;
end;
{ call event }
if Assigned(FOnSelect) then FOnSelect(Self);
end;
end
else
begin
{ check if clicked on ending points }
if Assigned(InternalClicked(X,Y,chStart)) then
IHandle:=chStart
else
if Assigned(InternalClicked(X,Y,chEnd)) then
IHandle:=chEnd;
end;
ParentChart.CancelMouse:=True;
end
else
begin
{ un-select }
ISelected:=nil;
if EnableDraw then
begin
IDrawing:=True;
FromPoint:=TeePoint(X,Y);
ToPoint:=FromPoint;
RedrawLine(ISelected);
ParentChart.CancelMouse:=True;
end;
end;
end;
cmeMove: if IDrawing or (IHandle<>chNone) then // drawing or dragging
begin
RedrawLine(ISelected); // hide previous line
if IDrawing then ToPoint:=TeePoint(X,Y)
else
begin
if IHandle=chStart then FromPoint:=TeePoint(X,Y)
else
if IHandle=chEnd then ToPoint:=TeePoint(X,Y)
else
if IHandle=chSeries then
begin
Inc(FromPoint.X,X-IPoint.X);
Inc(FromPoint.Y,Y-IPoint.Y);
Inc(ToPoint.X,X-IPoint.X);
Inc(ToPoint.Y,Y-IPoint.Y);
IPoint:=TeePoint(X,Y);
end;
end;
RedrawLine(ISelected); // show line at new position
ParentChart.CancelMouse:=True;
// call event
if Assigned(FOnDragLine) then FOnDragLine(Self);
end
else
if FEnableSelect then { change the cursor if mouse is over lines }
ParentChart.CancelMouse:=CheckCursor;
cmeUp: if AButton=FButton then
begin
if IHandle<>chNone then // if dragging...
begin
if (IHandle=chStart) or (IHandle=chSeries) then
ISelected.StartPos:=ScreenPoint(FromPoint);
if (IHandle=chEnd) or (IHandle=chSeries) then
ISelected.EndPos:=ScreenPoint(ToPoint);
IHandle:=chNone;
// stop dragging, repaint
Repaint;
// call event
if Assigned(FOnDraggedLine) then FOnDraggedLine(Self); { 5.01 }
end
else
if IDrawing then // drawing a new line...
begin
if (FromPoint.X<>ToPoint.X) or (FromPoint.Y<>ToPoint.Y) then
begin
// create the new drawn line...
with TeeDrawLineClass.Create(Lines) do // 5.02
begin
StartPos:=ScreenPoint(FromPoint);
EndPos :=ScreenPoint(ToPoint);
end;
// repaint chart
Repaint;
// call event
if Assigned(FOnNewLine) then FOnNewLine(Self);
end;
IDrawing:=False;
end;
end;
end;
end;
class function TDrawLineTool.Description: String;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?