You've already forked lazarus-ccr
LazMapViewer: Fixes issues with painting/multithreading. Issue #39063, patch by Yuliyan Ivanov.
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@9092 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
@ -23,7 +23,7 @@ interface
|
||||
|
||||
uses
|
||||
Classes, SysUtils, Controls, Graphics, FPImage, IntfGraphics, Forms, ImgList, LCLVersion,
|
||||
MvTypes, MvGPSObj, MvEngine, MvMapProvider, MvDownloadEngine, MvDrawingEngine;
|
||||
MvTypes, MvGPSObj, MvEngine, MvMapProvider, MvDownloadEngine, MvDrawingEngine, mvCache;
|
||||
|
||||
Type
|
||||
|
||||
@ -54,9 +54,7 @@ Type
|
||||
procedure CallAsyncInvalidate;
|
||||
procedure DoAsyncInvalidate({%H-}Data: PtrInt);
|
||||
procedure DrawObjects(const {%H-}TileId: TTileId; aLeft, aTop, aRight,aBottom: integer);
|
||||
procedure DrawPointOfInterest(const {%H-}Area: TRealArea; APt: TGPSPointOfInterest);
|
||||
procedure DrawPt(const {%H-}Area: TRealArea; APt: TGPSPoint);
|
||||
procedure DrawTrack(const Area: TRealArea; trk: TGPSTrack);
|
||||
procedure DrawGpsObj(const {%H-}Area: TRealArea; AObj: TGPSObj);
|
||||
function GetCacheOnDisk: boolean;
|
||||
function GetCachePath: String;
|
||||
function GetCenter: TRealPoint;
|
||||
@ -108,6 +106,7 @@ Type
|
||||
procedure DoDrawStretchedTile(const TileId: TTileID; X, Y: Integer; TileImg: TLazIntfImage; const R: TRect);
|
||||
procedure DoDrawTile(const TileId: TTileId; X,Y: integer; TileImg: TLazIntfImage);
|
||||
procedure DoDrawTileInfo(const {%H-}TileID: TTileID; X,Y: Integer);
|
||||
procedure DoTileDownloaded(const TileId: TTileId);
|
||||
function DoMouseWheel(Shift: TShiftState; WheelDelta: Integer;
|
||||
MousePos: TPoint): Boolean; override;
|
||||
procedure DoOnResize; override;
|
||||
@ -124,6 +123,9 @@ Type
|
||||
public
|
||||
constructor Create(AOwner: TComponent); override;
|
||||
destructor Destroy; override;
|
||||
procedure DrawPointOfInterest(const {%H-}Area: TRealArea; APt: TGPSPointOfInterest);
|
||||
procedure DrawPt(const {%H-}Area: TRealArea; APt: TGPSPoint);
|
||||
procedure DrawTrack(const Area: TRealArea; trk: TGPSTrack);
|
||||
procedure ClearBuffer;
|
||||
procedure GetMapProviders(lstProviders: TStrings);
|
||||
function GetVisibleArea: TRealArea;
|
||||
@ -266,13 +268,7 @@ var
|
||||
begin
|
||||
iObj := aTask-1;
|
||||
Obj := FLst[iObj];
|
||||
if Obj.InheritsFrom(TGPSTrack) then
|
||||
Viewer.DrawTrack(FArea, TGPSTrack(Obj));
|
||||
if Obj.InheritsFrom(TGPSPointOfInterest) then
|
||||
Viewer.DrawPointOfInterest(FArea, TGPSPointOfInterest(Obj))
|
||||
else
|
||||
if Obj.InheritsFrom(TGPSPoint) then
|
||||
Viewer.DrawPt(FArea, TGPSPoint(Obj));
|
||||
Viewer.DrawGpsObj(FArea, Obj);
|
||||
end;
|
||||
|
||||
function TDrawObjJob.Running: boolean;
|
||||
@ -295,8 +291,6 @@ destructor TDrawObjJob.Destroy;
|
||||
begin
|
||||
inherited Destroy;
|
||||
FreeAndNil(FLst);
|
||||
if not(Cancelled) then
|
||||
Viewer.CallAsyncInvalidate;
|
||||
end;
|
||||
|
||||
|
||||
@ -557,6 +551,7 @@ begin
|
||||
Result:=inherited DoMouseWheel(Shift, WheelDelta, MousePos);
|
||||
if IsActive then
|
||||
Engine.MouseWheel(self,Shift,WheelDelta,MousePos,Result);
|
||||
Invalidate;
|
||||
end;
|
||||
|
||||
procedure TMapView.MouseDown(Button: TMouseButton; Shift: TShiftState;
|
||||
@ -565,6 +560,7 @@ begin
|
||||
inherited MouseDown(Button, Shift, X, Y);
|
||||
if IsActive then
|
||||
Engine.MouseDown(self,Button,Shift,X,Y);
|
||||
Invalidate;
|
||||
end;
|
||||
|
||||
procedure TMapView.MouseUp(Button: TMouseButton; Shift: TShiftState;
|
||||
@ -573,6 +569,7 @@ begin
|
||||
inherited MouseUp(Button, Shift, X, Y);
|
||||
if IsActive then
|
||||
Engine.MouseUp(self,Button,Shift,X,Y);
|
||||
Invalidate;
|
||||
end;
|
||||
|
||||
procedure TMapView.MouseMove(Shift: TShiftState; X, Y: Integer);
|
||||
@ -580,6 +577,7 @@ begin
|
||||
inherited MouseMove(Shift, X, Y);
|
||||
if IsActive then
|
||||
Engine.MouseMove(self,Shift,X,Y);
|
||||
Invalidate;
|
||||
end;
|
||||
|
||||
procedure TMapView.Notification(AComponent: TComponent; Operation: TOperation);
|
||||
@ -594,6 +592,7 @@ begin
|
||||
inherited DblClick;
|
||||
if IsActive then
|
||||
Engine.DblClick(self);
|
||||
Invalidate;
|
||||
end;
|
||||
|
||||
procedure TMapView.DoOnResize;
|
||||
@ -604,13 +603,18 @@ begin
|
||||
DrawingEngine.CreateBuffer(ClientWidth, ClientHeight);
|
||||
if IsActive then
|
||||
Engine.SetSize(ClientWidth, ClientHeight);
|
||||
Invalidate;
|
||||
end;
|
||||
|
||||
procedure TMapView.Paint;
|
||||
begin
|
||||
inherited Paint;
|
||||
if IsActive then
|
||||
DrawingEngine.PaintToCanvas(Canvas)
|
||||
begin
|
||||
Engine.Redraw;
|
||||
DrawObjects(Default(TTileId), 0, 0, Canvas.Width, Canvas.Height);
|
||||
DrawingEngine.PaintToCanvas(Canvas);
|
||||
end
|
||||
else
|
||||
begin
|
||||
Canvas.Brush.Color := InactiveColor;
|
||||
@ -631,7 +635,7 @@ begin
|
||||
if hasIntersectArea(objArea, visArea) then
|
||||
begin
|
||||
Area := IntersectArea(objArea, visArea);
|
||||
Engine.Jobqueue.AddJob(TDrawObjJob.Create(self, Objs, Area), Engine);
|
||||
Invalidate;
|
||||
end
|
||||
else
|
||||
objs.Free;
|
||||
@ -654,8 +658,6 @@ begin
|
||||
if not trk.Visible or (trk.Points.Count = 0) then
|
||||
exit;
|
||||
|
||||
GPSItems.Lock;
|
||||
try
|
||||
// Determine track color
|
||||
if trk.LineColor = clDefault then
|
||||
begin
|
||||
@ -687,9 +689,6 @@ begin
|
||||
pt1 := pt2;
|
||||
iPt1 := iPt2;
|
||||
end;
|
||||
finally
|
||||
GPSItems.Unlock;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TMapView.DrawPointOfInterest(const Area: TRealArea; APt: TGPSPointOfInterest);
|
||||
@ -701,8 +700,6 @@ var
|
||||
bmp: TBitmap;
|
||||
w, h: Integer;
|
||||
begin
|
||||
GPSItems.Lock;
|
||||
try
|
||||
pt := Engine.LonLatToScreen(APt.RealPoint);
|
||||
|
||||
// Draw point as symbol from image list ...
|
||||
@ -746,9 +743,6 @@ begin
|
||||
end;
|
||||
extent := DrawingEngine.TextExtent(s);
|
||||
DrawingEngine.TextOut(pt.X - extent.CX div 2, pt.Y + 5, s);
|
||||
finally
|
||||
GPSItems.Unlock;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TMapView.DrawPt(const Area: TRealArea; APt: TGPSPoint);
|
||||
@ -758,8 +752,6 @@ var
|
||||
extent: TSize;
|
||||
s: String;
|
||||
begin
|
||||
GPSItems.Lock;
|
||||
try
|
||||
if Assigned(FOnDrawGpsPoint) then begin
|
||||
FOnDrawGpsPoint(Self, DrawingEngine, APt);
|
||||
exit;
|
||||
@ -796,6 +788,13 @@ begin
|
||||
extent := DrawingEngine.TextExtent(s);
|
||||
DrawingEngine.Textout(Pt.X - extent.CX div 2, Pt.Y + 5, s);
|
||||
|
||||
end;
|
||||
|
||||
procedure TMapView.DrawGpsObj(const Area: TRealArea; AObj: TGPSObj);
|
||||
begin
|
||||
GPSItems.Lock;
|
||||
try
|
||||
AObj.Draw(Self, Area);
|
||||
finally
|
||||
GPSItems.Unlock;
|
||||
end;
|
||||
@ -815,22 +814,25 @@ procedure TMapView.DrawObjects(const TileId: TTileId;
|
||||
var
|
||||
Area: TRealArea;
|
||||
lst: TGPSObjList;
|
||||
I: Integer;
|
||||
begin
|
||||
Area.TopLeft := Engine.ScreenToLonLat(Point(aLeft, aTop));
|
||||
Area.BottomRight := Engine.ScreenToLonLat(Point(aRight, aBottom));
|
||||
if GPSItems.Count > 0 then
|
||||
begin
|
||||
lst := GPSItems.GetObjectsInArea(Area);
|
||||
if lst.Count > 0 then
|
||||
Engine.Jobqueue.AddJob(TDrawObjJob.Create(self, lst, Area), Engine)
|
||||
else
|
||||
begin
|
||||
try
|
||||
if lst.Count > 0 then
|
||||
begin
|
||||
for I := 0 to Pred(lst.Count) do
|
||||
DrawGpsObj(Area, lst[I]);
|
||||
end;
|
||||
finally
|
||||
FreeAndNil(Lst);
|
||||
CallAsyncInvalidate;
|
||||
end;
|
||||
end
|
||||
else
|
||||
CallAsyncInvalidate;
|
||||
;
|
||||
end;
|
||||
|
||||
procedure TMapView.DoAsyncInvalidate(Data: PtrInt);
|
||||
@ -839,7 +841,7 @@ Begin
|
||||
AsyncInvalidate := false;
|
||||
end;
|
||||
|
||||
procedure TMapView.DoDrawStretchedTile(const TileId: TTileId; X, Y: Integer;
|
||||
procedure TMapView.DoDrawStretchedTile(const TileId: TTileID; X, Y: Integer;
|
||||
TileImg: TLazIntfImage; const R: TRect);
|
||||
begin
|
||||
if Assigned(TileImg) then
|
||||
@ -850,7 +852,6 @@ begin
|
||||
if FDebugTiles then
|
||||
DoDrawTileInfo(TileID, X, Y);
|
||||
|
||||
DrawObjects(TileId, X, Y, X + TILE_SIZE, Y + TILE_SIZE);
|
||||
end;
|
||||
|
||||
procedure TMapView.DoDrawTile(const TileId: TTileId; X, Y: integer;
|
||||
@ -864,7 +865,6 @@ begin
|
||||
if FDebugTiles then
|
||||
DoDrawTileInfo(TileID, X, Y);
|
||||
|
||||
DrawObjects(TileId, X, Y, X + TILE_SIZE, Y + TILE_SIZE);
|
||||
end;
|
||||
|
||||
procedure TMapView.DoDrawTileInfo(const TileID: TTileID; X, Y: Integer);
|
||||
@ -877,6 +877,12 @@ begin
|
||||
DrawingEngine.Line(X, Y + TILE_SIZE, X + TILE_SIZE, Y + TILE_SIZE);
|
||||
end;
|
||||
|
||||
procedure TMapView.DoTileDownloaded(const TileId: TTileId);
|
||||
begin
|
||||
// TODO: Include tile information to optimize redraw.
|
||||
CallAsyncInvalidate;
|
||||
end;
|
||||
|
||||
function TMapView.IsActive: Boolean;
|
||||
begin
|
||||
if not(csDesigning in ComponentState) then
|
||||
@ -911,6 +917,7 @@ begin
|
||||
FEngine.CacheOnDisk := true;
|
||||
FEngine.OnDrawTile := @DoDrawTile;
|
||||
FEngine.OnDrawStretchedTile := @DoDrawStretchedTile;
|
||||
FEngine.OnTileDownloaded := @DoTileDownloaded;
|
||||
FEngine.DrawPreviewTiles := True;
|
||||
FEngine.DrawTitleInGuiThread := false;
|
||||
FEngine.DownloadEngine := FBuiltinDownloadEngine;
|
||||
@ -1054,7 +1061,7 @@ end;
|
||||
|
||||
procedure TMapView.Redraw;
|
||||
begin
|
||||
Engine.Redraw;
|
||||
Invalidate;
|
||||
end;
|
||||
|
||||
function TMapView.GetVisibleArea: TRealArea;
|
||||
|
Reference in New Issue
Block a user