LazMapViewer: Add OnDrawEditMark event to TMapView allowing to custom-draw the EditMark of the viewer. Internal FMarquee* properties renamed to FRubberband*

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@9676 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
wp_xxyyzz 2025-03-12 14:28:40 +00:00
parent 12eb71ee4e
commit 201779c33c

View File

@ -43,6 +43,8 @@ Type
TDrawMissingTileEvent = TDrawTileEvent; // deprecated
TMapEditMarkDrawState = (emdsNormal, emdsActive, emdsSelected, emdsHot, emdsRubberband);
TMapViewOption =
(
mvoEditorEnabled, // Point/Track editor enabled
@ -84,6 +86,10 @@ type
TMapAreaDrawEvent = procedure(Sender: TObject;
ADrawer: TMvCustomDrawingEngine; AArea: TMapArea) of object;
TMapEditMarkDrawEvent = procedure (Sender: TObject;
ADrawer: TMvCustomDrawingEngine; APoint: TMapPoint; ARect: TRect;
AState: TMapEditMarkDrawState; var DefaultDraw: Boolean) of object;
{ TMapObjectList }
TMapObjectList = class(specialize TFPGObjectList<TObject>)
@ -572,8 +578,9 @@ type
FBeforeDrawObjectsEvent: TNotifyEvent;
FAfterDrawObjectsEvent: TNotifyEvent;
FAfterPaintEvent: TNotifyEvent;
FEditMark: TMapEditMark;
FDragger: TDragObj;
FEditMark: TMapEditMark;
FEditMarkDrawEvent: TMapEditMarkDrawEvent;
procedure CallAsyncInvalidate;
procedure DoAsyncInvalidate({%H-}Data: PtrInt);
procedure DrawObjects(const {%H-}TileId: TTileId; aLeft, aTop, aRight,aBottom: integer);
@ -787,6 +794,7 @@ type
property OnEditDrag: TNotifyEvent read FOnEditDrag write FOnEditDrag;
property OnEditEndDrag: TNotifyEvent read FOnEditEndDrag write FOnEditEndDrag;
property OnEditIsDirty: TNotifyEvent read FOnEditIsDirty write FOnEditIsDirty;
property OnDrawEditMark: TMapEditMarkDrawEvent read FEditMarkDrawEvent write FEditMarkDrawEvent;
property OnZoomChange: TNotifyEvent read FOnZoomChange write FOnZoomChange;
property OnZoomChanging: TZoomChangingEvent read FOnZoomChanging write FOnZoomChanging;
property OnMouseDown;
@ -877,6 +885,7 @@ type
FOnEndDrag: TNotifyEvent;
FOnSelectionCompleted: TNotifyEvent;
FOnStartDrag: TNotifyEvent;
FHotPt: TMapPoint;
FRealPt: TRealPoint;
FSelection: TMapObjectList;
FObservedColls: TMapObjectList;
@ -899,13 +908,14 @@ type
procedure ObserveItemColl(AItem: TObject);
function AroundPt(X, Y: Integer; APt: TPoint): Boolean;
procedure SelectFromMarquee;
procedure SelectFromRubberband;
procedure MarkDirty;
protected
FPt: TPoint;
FMarquee: Boolean;
FMarqueeRect: TRect;
FRubberband: Boolean;
FRubberbandRect: TRect;
FList: TMapObjectList;
procedure DoDraw(Sender: TObject; APoint: TMapPoint; ARect: TRect; AState: TMapEditMarkDrawState);
public
constructor Create(AMapView: TMapView);
@ -4507,14 +4517,14 @@ begin
InRange(Y, APt.Y - 5, APt.Y + 5);
end;
procedure TMapEditMark.SelectFromMarquee;
procedure TMapEditMark.SelectFromRubberband;
var
Hits: TMapObjectList;
RA: TRealArea;
O: TObject;
begin
RA.TopLeft := FMapView.ScreenToLatLon(FMarqueeRect.TopLeft);
RA.BottomRight := FMapView.ScreenToLatLon(FMarqueeRect.BottomRight);
RA.TopLeft := FMapView.ScreenToLatLon(FRubberbandRect.TopLeft);
RA.BottomRight := FMapView.ScreenToLatLon(FRubberbandRect.BottomRight);
Hits := FMapView.Layers.HitTest(RA);
if Assigned(Hits) then
try
@ -4592,7 +4602,31 @@ begin
Area.Init(FRealPt, FRealPt);
end;
procedure TMapEditmark.DoDraw(Sender: TObject; APoint: TMapPoint; ARect: TRect; AState: TMapEditMarkDrawState);
var
defaultDraw: Boolean;
view: TMapView;
DE: TMvCustomDrawingEngine;
begin
view := Sender as TMapView;
DE := view.DrawingEngine;
defaultDraw := True;
if Assigned(view.OnDrawEditMark) then
view.OnDrawEditMark(view, DE, APoint, ARect, AState, defaultDraw);
if defaultDraw then
begin
if AState = emdsNormal then
DE.Ellipse(ARect.Left, ARect.Top, ARect.Right, ARect.Bottom)
else
DE.Rectangle(ARect.Left, ARect.Top, ARect.Right, ARect.Bottom);
end;
end;
procedure TMapEditMark.Draw(AView: TObject; Area: TRealArea);
const
MARK_SIZE = 5;
var
View: TMapView;
DE: TMvCustomDrawingEngine;
@ -4600,17 +4634,23 @@ var
Ar: TMapArea;
TrkPoint: TMapPoint;
I: Integer;
MarkSize: Integer;
procedure MarkMP(P: TMapPoint);
// Draw editor point
procedure DrawMark(P: TMapPoint; ASize: Integer; AState: TMapEditMarkDrawState);
var
R: TRect;
begin
with View.LatLonToScreen(P.Latitude, P.Longitude) do
DE.Ellipse(X - 4, Y - 4, X + 4, Y + 4);
R := Rect(X - ASize, Y - ASize, X + ASize, Y + ASize);
DoDraw(AView, P, R, AState);
end;
begin
View := TMapView(AView);
DE := View.DrawingEngine;
FPt := View.LatLonToScreen(RealPt);
MarkSize := View.Scale96ToFont(MARK_SIZE);
DE.PenStyle := psSolid;
DE.PenColor := clRed;
@ -4619,8 +4659,9 @@ begin
DE.BrushStyle := bsSolid;
DE.Opacity := 1.0;
if Assigned(FList) then
DE.Rectangle(FPt.X - 5, FPt.Y - 5, FPt.X + 5, FPt.Y + 5);
// Mouse-over
if Assigned(FList) and Assigned(FHotPt) then
DrawMark(FHotPt, MarkSize, emdsHot);
if HasSelection then
begin
@ -4629,35 +4670,34 @@ begin
for Trk in FSelection.Tracks do
for I := 0 to Pred(Trk.Points.Count) do
MarkMP(Trk.Points[I]);
DrawMark(Trk.Points[I], MarkSize-1, emdsNormal);
for Ar in FSelection.Areas do
for I := 0 to Pred(Ar.Points.Count) do
MarkMP(Ar.Points[I]);
DrawMark(Ar.Points[I], MarkSize-1, emdsNormal);
DE.PenWidth := 2;
DE.BrushColor := clBlack;
DE.BrushStyle := bsSolid;
// Points in current selection
for TrkPoint in FSelection.Points.Skip(1) do
with View.LatLonToScreen(TrkPoint.Latitude, TrkPoint.Longitude) do
DE.Rectangle(X - 5, Y - 5, X + 5, Y + 5);
DrawMark(TrkPoint, MarkSize, emdsSelected);
// Current point
DE.BrushColor := clLime;
TrkPoint := (FSelection[0] as TMapPoint);
with View.LatLonToScreen(TrkPoint.Latitude, TrkPoint.Longitude) do
DE.Rectangle(X - 5, Y - 5, X + 5, Y + 5);
DrawMark(TrkPoint, MarkSize, emdsActive);
end;
if FMarquee then
// Rubberband
if FRubberband then
begin
DE.PenStyle := psSolid;
DE.PenWidth := 1;
DE.PenColor := clGray;
DE.BrushStyle := bsClear;
with FMarqueeRect do
DE.Rectangle(Left, Top, Right, Bottom);
DoDraw(AView, nil, FRubberbandRect, emdsRubberband);
end;
end;
@ -4670,12 +4710,14 @@ begin
Exit;
Lat := TMapPoint(AObjs[0]).Latitude;
Lon := TMapPoint(AObjs[0]).Longitude;
FHotPt := TMapPoint(AObjs[0]);
FList.Free;
FList := TMapObjectList.Create(AObjs);
FMapView.Invalidate;
end
else if Assigned(FList) then
begin
FHotPt := nil;
FreeAndNil(FList);
FMapView.Invalidate;
end;
@ -4766,10 +4808,10 @@ begin
Inc(I);
end;
SetLength(FOrigins, I); // why bother?
FMarquee := not AroundPt(Sender.StartX, Sender.StartY, FPt);
if FMarquee then
FRubberband := not AroundPt(Sender.StartX, Sender.StartY, FPt);
if FRubberband then
begin
FMarqueeRect := Rect(Sender.StartX, Sender.StartY, Sender.EndX, Sender.EndY);
FRubberbandRect := Rect(Sender.StartX, Sender.StartY, Sender.EndX, Sender.EndY);
Self.RealPt := FMapView.Center; // keep it in view
FMapView.Invalidate;
end;
@ -4794,10 +4836,10 @@ begin
Exit;
end;
end;
if FMarquee then
if FRubberband then
begin
FMarqueeRect := Rect(Sender.StartX, Sender.StartY, Sender.EndX, Sender.EndY);
FMarqueeRect.NormalizeRect;
FRubberbandRect := Rect(Sender.StartX, Sender.StartY, Sender.EndX, Sender.EndY);
FRubberbandRect.NormalizeRect;
FMapView.Invalidate;
Exit;
end;
@ -4818,10 +4860,10 @@ end;
procedure TMapEditMark.DoEndDrag(Sender: TDragObj);
begin
if FMarquee then
if FRubberband then
begin
SelectFromMarquee;
FMarquee := False;
SelectFromRubberband;
FRubberband := False;
end;
SetLength(FOrigins, 0);
FDragStarted := False;