LazMapViewer: Extend TLegalNoticePlugin to support embedded links and line-breaks. Update demos.
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@9553 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
parent
230cdbbc3b
commit
2a66f07424
@ -25,8 +25,7 @@ object MainForm: TMainForm
|
|||||||
Left = 427
|
Left = 427
|
||||||
Top = 141
|
Top = 141
|
||||||
object LegalNoticePlugin: TLegalNoticePlugin
|
object LegalNoticePlugin: TLegalNoticePlugin
|
||||||
LegalNotice = '(c) OpenStreetMap and contributors'
|
LegalNotice = '[https://www.openstreetmap.org (c) OpenStreetMap and contributors]'
|
||||||
LegalNoticeURL = 'https://www.openstreetmap.org'
|
|
||||||
end
|
end
|
||||||
object DraggableMarkerPlugin: TDraggableMarkerPlugin
|
object DraggableMarkerPlugin: TDraggableMarkerPlugin
|
||||||
end
|
end
|
||||||
|
@ -26,7 +26,6 @@ object MainForm: TMainForm
|
|||||||
MapCenter.Latitude = 49
|
MapCenter.Latitude = 49
|
||||||
PluginManager = PluginManager
|
PluginManager = PluginManager
|
||||||
POIImages = ImageList1
|
POIImages = ImageList1
|
||||||
UseThreads = True
|
|
||||||
Zoom = 3
|
Zoom = 3
|
||||||
OnMouseUp = MapViewMouseUp
|
OnMouseUp = MapViewMouseUp
|
||||||
end
|
end
|
||||||
|
@ -79,7 +79,7 @@ const
|
|||||||
DELTA = 5; // Tolerance of the HitTest
|
DELTA = 5; // Tolerance of the HitTest
|
||||||
var
|
var
|
||||||
layer: TMapLayer;
|
layer: TMapLayer;
|
||||||
poi: TPointOfInterest;
|
poi: TMapPointOfInterest;
|
||||||
RP: TRealPoint;
|
RP: TRealPoint;
|
||||||
area: TRealArea;
|
area: TRealArea;
|
||||||
list: TMapObjectList;
|
list: TMapObjectList;
|
||||||
@ -97,7 +97,7 @@ begin
|
|||||||
try
|
try
|
||||||
if (list = nil) then
|
if (list = nil) then
|
||||||
begin
|
begin
|
||||||
poi := TPointOfInterest(layer.PointsOfInterest.Add);
|
poi := TMapPointOfInterest(layer.PointsOfInterest.Add);
|
||||||
poi.Caption := 'Test ' + IntToStr(layer.PointsOfInterest.Count);
|
poi.Caption := 'Test ' + IntToStr(layer.PointsOfInterest.Count);
|
||||||
poi.ImageIndex := Random(ImageList1.Count);
|
poi.ImageIndex := Random(ImageList1.Count);
|
||||||
poi.Longitude := RP.Lon;
|
poi.Longitude := RP.Lon;
|
||||||
@ -106,9 +106,9 @@ begin
|
|||||||
begin
|
begin
|
||||||
for i := list.Count-1 downto 0 do
|
for i := list.Count-1 downto 0 do
|
||||||
begin
|
begin
|
||||||
if list[i] is TPointOfInterest then
|
if list[i] is TMapPointOfInterest then
|
||||||
begin
|
begin
|
||||||
poi := TPointOfInterest(list[i]);
|
poi := TMapPointOfInterest(list[i]);
|
||||||
poi.Free;
|
poi.Free;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
@ -28,9 +28,6 @@
|
|||||||
<Item>
|
<Item>
|
||||||
<PackageName Value="lazMapViewerPkg"/>
|
<PackageName Value="lazMapViewerPkg"/>
|
||||||
</Item>
|
</Item>
|
||||||
<Item>
|
|
||||||
<PackageName Value="TAChartLazarusPkg"/>
|
|
||||||
</Item>
|
|
||||||
<Item>
|
<Item>
|
||||||
<PackageName Value="LCL"/>
|
<PackageName Value="LCL"/>
|
||||||
</Item>
|
</Item>
|
||||||
|
@ -10,7 +10,7 @@ uses
|
|||||||
athreads,
|
athreads,
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
Interfaces, // this includes the LCL widgetset
|
Interfaces, // this includes the LCL widgetset
|
||||||
Forms, tachartlazaruspkg, Unit1
|
Forms, Unit1
|
||||||
{ you can add units after this };
|
{ you can add units after this };
|
||||||
|
|
||||||
{$R *.res}
|
{$R *.res}
|
||||||
|
@ -25,10 +25,10 @@ object MainForm: TMainForm
|
|||||||
AnchorSideLeft.Side = asrBottom
|
AnchorSideLeft.Side = asrBottom
|
||||||
AnchorSideTop.Control = ParamsPanel
|
AnchorSideTop.Control = ParamsPanel
|
||||||
AnchorSideRight.Control = cmbPosition
|
AnchorSideRight.Control = cmbPosition
|
||||||
Left = 75
|
Left = 253
|
||||||
Height = 23
|
Height = 23
|
||||||
Top = 0
|
Top = 0
|
||||||
Width = 601
|
Width = 423
|
||||||
Anchors = [akTop, akLeft, akRight]
|
Anchors = [akTop, akLeft, akRight]
|
||||||
BorderSpacing.Left = 8
|
BorderSpacing.Left = 8
|
||||||
BorderSpacing.Right = 4
|
BorderSpacing.Right = 4
|
||||||
@ -37,13 +37,15 @@ object MainForm: TMainForm
|
|||||||
OnChange = edLegalNoticeChange
|
OnChange = edLegalNoticeChange
|
||||||
end
|
end
|
||||||
object lblLegalNotice: TLabel
|
object lblLegalNotice: TLabel
|
||||||
AnchorSideLeft.Control = ParamsPanel
|
AnchorSideLeft.Control = rbRightMap
|
||||||
|
AnchorSideLeft.Side = asrBottom
|
||||||
AnchorSideTop.Control = edLegalNotice
|
AnchorSideTop.Control = edLegalNotice
|
||||||
AnchorSideTop.Side = asrCenter
|
AnchorSideTop.Side = asrCenter
|
||||||
Left = 0
|
Left = 178
|
||||||
Height = 15
|
Height = 15
|
||||||
Top = 4
|
Top = 4
|
||||||
Width = 67
|
Width = 67
|
||||||
|
BorderSpacing.Left = 32
|
||||||
Caption = 'Legal notice:'
|
Caption = 'Legal notice:'
|
||||||
end
|
end
|
||||||
object btnSaveToImage: TButton
|
object btnSaveToImage: TButton
|
||||||
@ -85,10 +87,10 @@ object MainForm: TMainForm
|
|||||||
OnChange = cmbPositionChange
|
OnChange = cmbPositionChange
|
||||||
end
|
end
|
||||||
object cbShowMapCenter: TCheckBox
|
object cbShowMapCenter: TCheckBox
|
||||||
AnchorSideLeft.Control = edLegalNotice
|
AnchorSideLeft.Control = ParamsPanel
|
||||||
AnchorSideTop.Control = seOpacity
|
AnchorSideTop.Control = seOpacity
|
||||||
AnchorSideTop.Side = asrCenter
|
AnchorSideTop.Side = asrCenter
|
||||||
Left = 75
|
Left = 0
|
||||||
Height = 19
|
Height = 19
|
||||||
Top = 33
|
Top = 33
|
||||||
Width = 110
|
Width = 110
|
||||||
@ -103,7 +105,7 @@ object MainForm: TMainForm
|
|||||||
AnchorSideLeft.Side = asrBottom
|
AnchorSideLeft.Side = asrBottom
|
||||||
AnchorSideTop.Control = seOpacity
|
AnchorSideTop.Control = seOpacity
|
||||||
AnchorSideTop.Side = asrCenter
|
AnchorSideTop.Side = asrCenter
|
||||||
Left = 209
|
Left = 134
|
||||||
Height = 19
|
Height = 19
|
||||||
Top = 33
|
Top = 33
|
||||||
Width = 111
|
Width = 111
|
||||||
@ -119,7 +121,7 @@ object MainForm: TMainForm
|
|||||||
AnchorSideLeft.Side = asrBottom
|
AnchorSideLeft.Side = asrBottom
|
||||||
AnchorSideTop.Control = cbShowMapCenter
|
AnchorSideTop.Control = cbShowMapCenter
|
||||||
AnchorSideTop.Side = asrCenter
|
AnchorSideTop.Side = asrCenter
|
||||||
Left = 352
|
Left = 277
|
||||||
Height = 15
|
Height = 15
|
||||||
Top = 35
|
Top = 35
|
||||||
Width = 124
|
Width = 124
|
||||||
@ -131,10 +133,10 @@ object MainForm: TMainForm
|
|||||||
AnchorSideLeft.Side = asrBottom
|
AnchorSideLeft.Side = asrBottom
|
||||||
AnchorSideTop.Control = edLegalNotice
|
AnchorSideTop.Control = edLegalNotice
|
||||||
AnchorSideTop.Side = asrBottom
|
AnchorSideTop.Side = asrBottom
|
||||||
Left = 484
|
Left = 409
|
||||||
Height = 23
|
Height = 23
|
||||||
Top = 31
|
Top = 31
|
||||||
Width = 69
|
Width = 55
|
||||||
Alignment = taRightJustify
|
Alignment = taRightJustify
|
||||||
BorderSpacing.Left = 8
|
BorderSpacing.Left = 8
|
||||||
BorderSpacing.Top = 8
|
BorderSpacing.Top = 8
|
||||||
@ -142,10 +144,37 @@ object MainForm: TMainForm
|
|||||||
MaxValue = 100
|
MaxValue = 100
|
||||||
TabOrder = 5
|
TabOrder = 5
|
||||||
Value = 50
|
Value = 50
|
||||||
OnChange = FloatSpinEdit1Change
|
OnChange = seOpacityChange
|
||||||
|
end
|
||||||
|
object rbLeftMap: TRadioButton
|
||||||
|
AnchorSideLeft.Control = ParamsPanel
|
||||||
|
AnchorSideTop.Control = edLegalNotice
|
||||||
|
AnchorSideTop.Side = asrCenter
|
||||||
|
Left = 0
|
||||||
|
Height = 19
|
||||||
|
Top = 2
|
||||||
|
Width = 65
|
||||||
|
Caption = 'Left map'
|
||||||
|
Checked = True
|
||||||
|
TabOrder = 7
|
||||||
|
TabStop = True
|
||||||
|
OnChange = rbLeftMapChange
|
||||||
|
end
|
||||||
|
object rbRightMap: TRadioButton
|
||||||
|
AnchorSideLeft.Control = rbLeftMap
|
||||||
|
AnchorSideLeft.Side = asrBottom
|
||||||
|
AnchorSideTop.Control = edLegalNotice
|
||||||
|
AnchorSideTop.Side = asrCenter
|
||||||
|
Left = 73
|
||||||
|
Height = 19
|
||||||
|
Top = 2
|
||||||
|
Width = 73
|
||||||
|
BorderSpacing.Left = 8
|
||||||
|
Caption = 'Right map'
|
||||||
|
TabOrder = 6
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
object Bevel1: TBevel
|
object FormCenterBevel: TBevel
|
||||||
AnchorSideLeft.Control = Owner
|
AnchorSideLeft.Control = Owner
|
||||||
AnchorSideLeft.Side = asrCenter
|
AnchorSideLeft.Side = asrCenter
|
||||||
AnchorSideTop.Control = Owner
|
AnchorSideTop.Control = Owner
|
||||||
@ -157,10 +186,10 @@ object MainForm: TMainForm
|
|||||||
Anchors = [akTop, akLeft, akBottom]
|
Anchors = [akTop, akLeft, akBottom]
|
||||||
Shape = bsSpacer
|
Shape = bsSpacer
|
||||||
end
|
end
|
||||||
object Panel2: TPanel
|
object LeftPanel: TPanel
|
||||||
AnchorSideLeft.Control = Owner
|
AnchorSideLeft.Control = Owner
|
||||||
AnchorSideTop.Control = Owner
|
AnchorSideTop.Control = Owner
|
||||||
AnchorSideRight.Control = Bevel1
|
AnchorSideRight.Control = FormCenterBevel
|
||||||
AnchorSideBottom.Control = ParamsPanel
|
AnchorSideBottom.Control = ParamsPanel
|
||||||
Left = 0
|
Left = 0
|
||||||
Height = 417
|
Height = 417
|
||||||
@ -170,8 +199,8 @@ object MainForm: TMainForm
|
|||||||
BevelOuter = bvNone
|
BevelOuter = bvNone
|
||||||
TabOrder = 1
|
TabOrder = 1
|
||||||
end
|
end
|
||||||
object Panel3: TPanel
|
object RightPanel: TPanel
|
||||||
AnchorSideLeft.Control = Bevel1
|
AnchorSideLeft.Control = FormCenterBevel
|
||||||
AnchorSideLeft.Side = asrBottom
|
AnchorSideLeft.Side = asrBottom
|
||||||
AnchorSideTop.Control = Owner
|
AnchorSideTop.Control = Owner
|
||||||
AnchorSideRight.Control = Owner
|
AnchorSideRight.Control = Owner
|
||||||
|
@ -7,34 +7,40 @@ interface
|
|||||||
uses
|
uses
|
||||||
Classes, SysUtils,
|
Classes, SysUtils,
|
||||||
LCLIntf, Forms, Controls, Graphics, ExtCtrls, StdCtrls, Dialogs, Spin,
|
LCLIntf, Forms, Controls, Graphics, ExtCtrls, StdCtrls, Dialogs, Spin,
|
||||||
TAGraph, TATools,
|
|
||||||
mvMapViewer, mvPluginCore, mvPlugins;
|
mvMapViewer, mvPluginCore, mvPlugins;
|
||||||
|
|
||||||
type
|
type
|
||||||
TMainForm = class(TForm)
|
TMainForm = class(TForm)
|
||||||
Bevel1: TBevel;
|
FormCenterBevel: TBevel;
|
||||||
btnSaveToImage: TButton;
|
btnSaveToImage: TButton;
|
||||||
cbShowMapCenter: TCheckBox;
|
cbShowMapCenter: TCheckBox;
|
||||||
cbShowLegalNotice: TCheckBox;
|
cbShowLegalNotice: TCheckBox;
|
||||||
cmbPosition: TComboBox;
|
cmbPosition: TComboBox;
|
||||||
edLegalNotice: TEdit;
|
edLegalNotice: TEdit;
|
||||||
|
rbLeftMap: TRadioButton;
|
||||||
|
rbRightMap: TRadioButton;
|
||||||
seOpacity: TSpinEdit;
|
seOpacity: TSpinEdit;
|
||||||
lblLegalNotice: TLabel;
|
lblLegalNotice: TLabel;
|
||||||
lblOpacity: TLabel;
|
lblOpacity: TLabel;
|
||||||
ParamsPanel: TPanel;
|
ParamsPanel: TPanel;
|
||||||
Panel2: TPanel;
|
LeftPanel: TPanel;
|
||||||
Panel3: TPanel;
|
RightPanel: TPanel;
|
||||||
procedure btnSaveToImageClick(Sender: TObject);
|
procedure btnSaveToImageClick(Sender: TObject);
|
||||||
procedure cbShowMapCenterChange(Sender: TObject);
|
procedure cbShowMapCenterChange(Sender: TObject);
|
||||||
procedure cbShowLegalNoticeChange(Sender: TObject);
|
procedure cbShowLegalNoticeChange(Sender: TObject);
|
||||||
procedure cmbPositionChange(Sender: TObject);
|
procedure cmbPositionChange(Sender: TObject);
|
||||||
procedure edLegalNoticeChange(Sender: TObject);
|
procedure edLegalNoticeChange(Sender: TObject);
|
||||||
procedure FloatSpinEdit1Change(Sender: TObject);
|
procedure rbLeftMapChange(Sender: TObject);
|
||||||
|
procedure seOpacityChange(Sender: TObject);
|
||||||
procedure FormCreate(Sender: TObject);
|
procedure FormCreate(Sender: TObject);
|
||||||
private
|
private
|
||||||
FMapView1: TMapView;
|
FMapView1: TMapView;
|
||||||
FMapView2: TMapView;
|
FMapView2: TMapView;
|
||||||
FPluginManager: TMvPluginManager;
|
FPluginManager: TMvPluginManager;
|
||||||
|
FLegalNoticePlugin1: TLegalNoticePlugin;
|
||||||
|
FLegalNoticePlugin2: TLegalNoticePlugin;
|
||||||
|
FCenterMarkerPlugin: TCenterMarkerPlugin;
|
||||||
|
FLinkedMapsPlugin: TLinkedMapsPlugin;
|
||||||
public
|
public
|
||||||
|
|
||||||
end;
|
end;
|
||||||
@ -54,7 +60,7 @@ begin
|
|||||||
|
|
||||||
FMapView1 := TMapView.Create(self);
|
FMapView1 := TMapView.Create(self);
|
||||||
FMapView1.Align := alClient;
|
FMapView1.Align := alClient;
|
||||||
FMapView1.Parent := Panel2;
|
FMapView1.Parent := LeftPanel;
|
||||||
FMapView1.MapProvider := 'OpenStreetMap Mapnik';
|
FMapView1.MapProvider := 'OpenStreetMap Mapnik';
|
||||||
FMapView1.UseThreads := true;
|
FMapView1.UseThreads := true;
|
||||||
FMapView1.Zoom := 9;
|
FMapView1.Zoom := 9;
|
||||||
@ -65,7 +71,7 @@ begin
|
|||||||
|
|
||||||
FMapView2 := TMapView.Create(self);
|
FMapView2 := TMapView.Create(self);
|
||||||
FMapView2.Align := alClient;
|
FMapView2.Align := alClient;
|
||||||
FMapView2.Parent := Panel3;
|
FMapView2.Parent := RightPanel;
|
||||||
FMapView2.MapProvider := 'Maps for free';
|
FMapView2.MapProvider := 'Maps for free';
|
||||||
FMapView2.UseThreads := true;
|
FMapView2.UseThreads := true;
|
||||||
FMapView2.Zoom := 9;
|
FMapView2.Zoom := 9;
|
||||||
@ -74,13 +80,12 @@ begin
|
|||||||
FMapView2.Active := true;
|
FMapView2.Active := true;
|
||||||
FMapView2.PluginManager := FPluginManager;
|
FMapView2.PluginManager := FPluginManager;
|
||||||
|
|
||||||
with TLegalNoticePlugin.Create(FPluginManager) do
|
FLegalNoticePlugin1 := TLegalNoticePlugin.Create(FPluginManager);
|
||||||
|
with FLegalNoticePlugin1 do
|
||||||
begin
|
begin
|
||||||
LegalNotice := '(c) OpenStreetMap and contributors';
|
LegalNotice := 'Map data from [https://www.openstreetmap.org/copyright OpenStreetMap and contributors]';
|
||||||
LegalNoticeURL := 'https://www.openstreetmap.org/copyright';
|
Spacing := 0;
|
||||||
Spacing := 5;
|
|
||||||
Font.Size := 8;
|
Font.Size := 8;
|
||||||
Font.Color := clBlue;
|
|
||||||
BackgroundColor := clWhite;
|
BackgroundColor := clWhite;
|
||||||
MapView := FMapView1;
|
MapView := FMapView1;
|
||||||
|
|
||||||
@ -88,60 +93,79 @@ begin
|
|||||||
seOpacity.Value := round(BackgroundOpacity * 100);
|
seOpacity.Value := round(BackgroundOpacity * 100);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
with TLegalNoticePlugin.Create(FPluginManager) do
|
FLegalNoticePlugin2 := TLegalNoticePlugin.Create(FPluginManager);
|
||||||
|
with FLegalNoticePlugin2 do
|
||||||
begin
|
begin
|
||||||
LegalNotice := 'maps-for-free';
|
LegalNotice := '(c) [https://maps-for-free.com/html/about.html maps-for-free]';
|
||||||
LegalNoticeURL := 'https://maps-for-free.com/html/about.html';
|
Spacing := 0;
|
||||||
Spacing := 5;
|
|
||||||
Font.Size := 8;
|
Font.Size := 8;
|
||||||
Font.Color := clBlue;
|
Font.Color := clBlue;
|
||||||
BackgroundColor := clWhite;
|
BackgroundColor := clWhite;
|
||||||
MapView := FMapView2;
|
MapView := FMapView2;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
with TCenterMarkerPlugin.Create(FPluginManager) do
|
FCenterMarkerPlugin := TCenterMarkerPlugin.Create(FPluginManager);
|
||||||
|
with FCenterMarkerPlugin do
|
||||||
begin
|
begin
|
||||||
Size := 15;
|
Size := 15;
|
||||||
Pen.Width := 3;
|
Pen.Width := 3;
|
||||||
Pen.Color := clRed;
|
Pen.Color := clRed;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
with TLinkedMapsPlugin.Create(FPluginManager) do ;
|
FLinkedMapsPlugin := TLinkedMapsPlugin.Create(FPluginManager);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TMainForm.edLegalNoticeChange(Sender: TObject);
|
procedure TMainForm.edLegalNoticeChange(Sender: TObject);
|
||||||
begin
|
begin
|
||||||
(FPluginManager.Item[0] as TLegalNoticePlugin).LegalNotice := edLegalNotice.Text;
|
if rbLeftMap.Checked then
|
||||||
|
FLegalNoticePlugin1.LegalNotice := edLegalNotice.Text;
|
||||||
|
if rbRightMap.Checked then
|
||||||
|
FLegalNoticePlugin2.LegalNotice := edLegalNotice.Text;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TMainForm.FloatSpinEdit1Change(Sender: TObject);
|
procedure TMainForm.rbLeftMapChange(Sender: TObject);
|
||||||
begin
|
begin
|
||||||
(FPluginManager.Item[0] as TLegalNoticePlugin).BackgroundOpacity := seOpacity.Value / 100;
|
if rbLeftMap.Checked then
|
||||||
if FPluginManager.PluginList.Count > 1 then
|
edLegalNotice.Text := FLegalNoticePlugin1.LegalNotice;
|
||||||
(FPluginManager.Item[1] as TLegalNoticePlugin).BackgroundOpacity := seOpacity.Value / 100;
|
if rbRightMap.Checked then
|
||||||
|
edLegalNotice.Text := FLegalNoticePlugin2.LegalNotice;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TMainForm.seOpacityChange(Sender: TObject);
|
||||||
|
begin
|
||||||
|
if rbLeftMap.Checked then
|
||||||
|
FLegalNoticePlugin1.BackgroundOpacity := seOpacity.Value / 100;
|
||||||
|
if rbRightMap.Checked then
|
||||||
|
FLegalNoticePlugin2.BackgroundOpacity := seOpacity.Value / 100;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TMainForm.btnSaveToImageClick(Sender: TObject);
|
procedure TMainForm.btnSaveToImageClick(Sender: TObject);
|
||||||
begin
|
begin
|
||||||
|
if rbLeftMap.Checked then
|
||||||
FMapView1.SaveToFile(TPortableNetworkGraphic, 'map1.png');
|
FMapView1.SaveToFile(TPortableNetworkGraphic, 'map1.png');
|
||||||
|
if rbRightMap.Checked then
|
||||||
FMapView2.SaveToFile(TPortableNetworkGraphic, 'map2.png');
|
FMapView2.SaveToFile(TPortableNetworkGraphic, 'map2.png');
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TMainForm.cbShowMapCenterChange(Sender: TObject);
|
procedure TMainForm.cbShowMapCenterChange(Sender: TObject);
|
||||||
begin
|
begin
|
||||||
(FPluginManager.Item[2] as TCenterMarkerPlugin).Enabled := cbShowMapCenter.Checked;
|
FCenterMarkerPlugin.Enabled := cbShowMapCenter.Checked;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TMainForm.cbShowLegalNoticeChange(Sender: TObject);
|
procedure TMainForm.cbShowLegalNoticeChange(Sender: TObject);
|
||||||
begin
|
begin
|
||||||
(FPluginManager.Item[0] as TLegalNoticePlugin).Enabled := cbShowLegalNotice.Checked;
|
if rbLeftMap.Checked then
|
||||||
(FPluginManager.Item[1] as TLegalNoticePlugin).Enabled := cbShowLegalNotice.Checked;
|
FLegalNoticePlugin1.Enabled := cbShowLegalNotice.Checked;
|
||||||
|
if rbRightMap.Checked then
|
||||||
|
FLegalNoticePlugin2.Enabled := cbShowLegalNotice.Checked;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TMainForm.cmbPositionChange(Sender: TObject);
|
procedure TMainForm.cmbPositionChange(Sender: TObject);
|
||||||
begin
|
begin
|
||||||
(FPluginManager.Item[0] as TLegalNoticePlugin).Position := TLegalNoticePosition(cmbPosition.ItemIndex);
|
if rbLeftMap.Checked then
|
||||||
(FPluginManager.Item[1] as TLegalNoticePlugin).Position := TLegalNoticePosition(cmbPosition.ItemIndex);
|
FLegalNoticePlugin1.Position := TLegalNoticePosition(cmbPosition.ItemIndex);
|
||||||
|
if rbRightMap.Checked then
|
||||||
|
FLegalNoticePlugin2.Position := TLegalNoticePosition(cmbPosition.ItemIndex);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
end.
|
end.
|
||||||
|
@ -10,7 +10,7 @@ object MainForm: TMainForm
|
|||||||
OnCreate = FormCreate
|
OnCreate = FormCreate
|
||||||
object MapView: TMapView
|
object MapView: TMapView
|
||||||
Left = 0
|
Left = 0
|
||||||
Height = 257
|
Height = 261
|
||||||
Top = 0
|
Top = 0
|
||||||
Width = 451
|
Width = 451
|
||||||
Align = alClient
|
Align = alClient
|
||||||
@ -22,35 +22,48 @@ object MainForm: TMainForm
|
|||||||
PluginManager = PluginManager
|
PluginManager = PluginManager
|
||||||
end
|
end
|
||||||
object InfoPanel: TPanel
|
object InfoPanel: TPanel
|
||||||
Left = 0
|
Left = 8
|
||||||
Height = 50
|
Height = 30
|
||||||
Top = 257
|
Top = 269
|
||||||
Width = 451
|
Width = 435
|
||||||
Align = alBottom
|
Align = alBottom
|
||||||
ClientHeight = 50
|
AutoSize = True
|
||||||
ClientWidth = 451
|
BorderSpacing.Around = 8
|
||||||
|
BevelOuter = bvNone
|
||||||
|
ClientHeight = 30
|
||||||
|
ClientWidth = 435
|
||||||
TabOrder = 1
|
TabOrder = 1
|
||||||
object lblMessageLabel: TLabel
|
object lblMessageLabel: TLabel
|
||||||
AnchorSideTop.Control = InfoPanel
|
AnchorSideLeft.Control = InfoPanel
|
||||||
AnchorSideTop.Side = asrCenter
|
AnchorSideTop.Control = Label1
|
||||||
Left = 16
|
AnchorSideTop.Side = asrBottom
|
||||||
|
Left = 0
|
||||||
Height = 15
|
Height = 15
|
||||||
Top = 18
|
Top = 15
|
||||||
Width = 146
|
Width = 146
|
||||||
Caption = 'UserdefinedPlugin Message'
|
Caption = 'UserdefinedPlugin Message'
|
||||||
end
|
end
|
||||||
object lblUserdefinedPluginMessage: TLabel
|
object lblUserdefinedPluginMessage: TLabel
|
||||||
AnchorSideLeft.Control = lblMessageLabel
|
AnchorSideLeft.Control = lblMessageLabel
|
||||||
AnchorSideLeft.Side = asrBottom
|
AnchorSideLeft.Side = asrBottom
|
||||||
AnchorSideTop.Control = InfoPanel
|
AnchorSideTop.Control = lblMessageLabel
|
||||||
AnchorSideTop.Side = asrCenter
|
AnchorSideTop.Side = asrCenter
|
||||||
Left = 170
|
Left = 154
|
||||||
Height = 15
|
Height = 15
|
||||||
Top = 18
|
Top = 15
|
||||||
Width = 38
|
Width = 38
|
||||||
BorderSpacing.Left = 8
|
BorderSpacing.Left = 8
|
||||||
Caption = ' (none)'
|
Caption = ' (none)'
|
||||||
end
|
end
|
||||||
|
object Label1: TLabel
|
||||||
|
AnchorSideLeft.Control = InfoPanel
|
||||||
|
AnchorSideTop.Control = InfoPanel
|
||||||
|
Left = 0
|
||||||
|
Height = 15
|
||||||
|
Top = 0
|
||||||
|
Width = 106
|
||||||
|
Caption = 'Click into the map...'
|
||||||
|
end
|
||||||
end
|
end
|
||||||
object PluginManager: TMvPluginManager
|
object PluginManager: TMvPluginManager
|
||||||
Left = 262
|
Left = 262
|
||||||
|
@ -13,6 +13,7 @@ type
|
|||||||
{ TMainForm }
|
{ TMainForm }
|
||||||
|
|
||||||
TMainForm = class(TForm)
|
TMainForm = class(TForm)
|
||||||
|
Label1: TLabel;
|
||||||
lblMessageLabel: TLabel;
|
lblMessageLabel: TLabel;
|
||||||
lblUserdefinedPluginMessage: TLabel;
|
lblUserdefinedPluginMessage: TLabel;
|
||||||
MapView: TMapView;
|
MapView: TMapView;
|
||||||
|
@ -5,7 +5,7 @@ unit mvPlugins;
|
|||||||
interface
|
interface
|
||||||
|
|
||||||
uses
|
uses
|
||||||
Classes, SysUtils,
|
Classes, SysUtils, Contnrs,
|
||||||
Graphics, Controls, LCLIntf, //LazLoggerBase,
|
Graphics, Controls, LCLIntf, //LazLoggerBase,
|
||||||
mvMapViewer, mvDrawingEngine, mvPluginCore, mvGPSObj, mvTypes;
|
mvMapViewer, mvDrawingEngine, mvPluginCore, mvGPSObj, mvTypes;
|
||||||
|
|
||||||
@ -45,33 +45,42 @@ type
|
|||||||
|
|
||||||
TLegalNoticePosition = (lnpTopLeft, lnpTopRight, lnpBottomLeft, lnpBottomRight);
|
TLegalNoticePosition = (lnpTopLeft, lnpTopRight, lnpBottomLeft, lnpBottomRight);
|
||||||
|
|
||||||
TLegalNoticePlugin = class(TMvMultiMapsDrawPlugin)
|
TLegalNoticePlugin = class(TMvDrawPlugin)
|
||||||
private
|
private
|
||||||
const
|
const
|
||||||
DEFAULT_LEGALNOTICE_OPACITY = 0.55;
|
DEFAULT_LEGALNOTICE_OPACITY = 0.55;
|
||||||
DEFAULT_LEGALNOTICE_SPACING = 4;
|
DEFAULT_LEGALNOTICE_SPACING = 4;
|
||||||
|
type
|
||||||
|
TLegalNoticePart = class
|
||||||
|
Text: String;
|
||||||
|
URL: String;
|
||||||
|
Rect: TRect;
|
||||||
|
constructor Create(AText, AURL: String);
|
||||||
|
end;
|
||||||
|
TLegalNoticeParts = class(TFPObjectList);
|
||||||
private
|
private
|
||||||
FLegalNotice: String;
|
FLegalNotice: TCaption;
|
||||||
FLegalNoticeURL: String;
|
FLegalNoticeParts: TLegalNoticeParts;
|
||||||
FBackgroundOpacity: Single;
|
FBackgroundOpacity: Single;
|
||||||
FPosition: TLegalNoticePosition;
|
FPosition: TLegalNoticePosition;
|
||||||
FSpacing: Integer;
|
FSpacing: Integer;
|
||||||
FBackgroundColor: TColor;
|
FBackgroundColor: TColor;
|
||||||
|
FMouseOverPart: Integer;
|
||||||
|
FURLFontColor: TColor;
|
||||||
private
|
private
|
||||||
procedure SetBackgroundColor(AValue: TColor);
|
procedure SetBackgroundColor(AValue: TColor);
|
||||||
procedure SetBackgroundOpacity(AValue: Single);
|
procedure SetBackgroundOpacity(AValue: Single);
|
||||||
procedure SetLegalNotice(AValue: String);
|
procedure SetLegalNotice(AValue: TCaption);
|
||||||
procedure SetLegalNoticeURL(AValue: String);
|
|
||||||
procedure SetPosition(AValue: TLegalNoticePosition);
|
procedure SetPosition(AValue: TLegalNoticePosition);
|
||||||
procedure SetSpacing(AValue: Integer);
|
procedure SetSpacing(AValue: Integer);
|
||||||
protected
|
protected
|
||||||
procedure CalcClickableRect(AMapView: TMapView; out AClickableRect: TRect);
|
|
||||||
procedure Changed(Sender: TObject);
|
procedure Changed(Sender: TObject);
|
||||||
|
procedure ExtractLegalNoticeParts(AMapView: TMapView);
|
||||||
|
function PointInURLPart(APoint: TPoint; out URL: String): Integer;
|
||||||
protected
|
protected
|
||||||
procedure AfterDrawObjects(AMapView: TMapView; var Handled: Boolean); override;
|
procedure AfterDrawObjects(AMapView: TMapView; var Handled: Boolean); override;
|
||||||
procedure MouseDown(AMapView: TMapView; {%H-}Button: TMouseButton; {%H-}Shift: TShiftState;
|
procedure MouseDown(AMapView: TMapView; {%H-}Button: TMouseButton; {%H-}Shift: TShiftState;
|
||||||
X, Y: Integer; var Handled: Boolean); override;
|
X, Y: Integer; var Handled: Boolean); override;
|
||||||
procedure MouseEnter(AMapView: TMapView; var Handled: Boolean); override;
|
|
||||||
procedure MouseMove(AMapView: TMapView; {%H-}Shift: TShiftState; X, Y: Integer;
|
procedure MouseMove(AMapView: TMapView; {%H-}Shift: TShiftState; X, Y: Integer;
|
||||||
var Handled: Boolean); override;
|
var Handled: Boolean); override;
|
||||||
public
|
public
|
||||||
@ -81,13 +90,12 @@ type
|
|||||||
published
|
published
|
||||||
property BackgroundColor: TColor read FBackgroundColor write SetBackgroundColor default clNone;
|
property BackgroundColor: TColor read FBackgroundColor write SetBackgroundColor default clNone;
|
||||||
property BackgroundOpacity: Single read FBackgroundOpacity write SetBackgroundOpacity default DEFAULT_LEGALNOTICE_OPACITY; // 0..1
|
property BackgroundOpacity: Single read FBackgroundOpacity write SetBackgroundOpacity default DEFAULT_LEGALNOTICE_OPACITY; // 0..1
|
||||||
property LegalNotice: String read FLegalNotice write SetLegalNotice;
|
property LegalNotice: TCaption read FLegalNotice write SetLegalNotice;
|
||||||
property LegalNoticeURL: String read FLegalNoticeURL write SetLegalNoticeURL;
|
|
||||||
property Position: TLegalNoticePosition read FPosition write SetPosition default lnpBottomRight;
|
property Position: TLegalNoticePosition read FPosition write SetPosition default lnpBottomRight;
|
||||||
property Spacing: Integer read FSpacing write SetSpacing default DEFAULT_LEGALNOTICE_SPACING;
|
property Spacing: Integer read FSpacing write SetSpacing default DEFAULT_LEGALNOTICE_SPACING;
|
||||||
|
property URLFontColor: TColor read FURLFontColor write FURLFontColor default clBlue;
|
||||||
// inherited properties
|
// inherited properties
|
||||||
property Font;
|
property Font;
|
||||||
property MapView;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ TDraggableMarkerPlugin }
|
{ TDraggableMarkerPlugin }
|
||||||
@ -324,17 +332,27 @@ end;
|
|||||||
|
|
||||||
{ TLegalNoticePlugin }
|
{ TLegalNoticePlugin }
|
||||||
|
|
||||||
|
constructor TLegalNoticePlugin.TLegalNoticePart.Create(AText, AURL: String);
|
||||||
|
begin
|
||||||
|
inherited Create;
|
||||||
|
Text := AText;
|
||||||
|
URL := AURL;
|
||||||
|
end;
|
||||||
|
|
||||||
constructor TLegalNoticePlugin.Create(AOwner: TComponent);
|
constructor TLegalNoticePlugin.Create(AOwner: TComponent);
|
||||||
begin
|
begin
|
||||||
inherited Create(AOwner);
|
inherited Create(AOwner);
|
||||||
FBackgroundColor := clNone;
|
FBackgroundColor := clNone;
|
||||||
FBackgroundOpacity := DEFAULT_LEGALNOTICE_OPACITY;
|
FBackgroundOpacity := DEFAULT_LEGALNOTICE_OPACITY;
|
||||||
|
FURLFontColor := clBlue;
|
||||||
FPosition := lnpBottomRight;
|
FPosition := lnpBottomRight;
|
||||||
FSpacing := DEFAULT_LEGALNOTICE_SPACING;
|
FSpacing := DEFAULT_LEGALNOTICE_SPACING;
|
||||||
|
FLegalNoticeParts := TLegalNoticeParts.Create;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
destructor TLegalNoticePlugin.Destroy;
|
destructor TLegalNoticePlugin.Destroy;
|
||||||
begin
|
begin
|
||||||
|
FLegalNoticeParts.Free;
|
||||||
inherited;
|
inherited;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -345,72 +363,239 @@ begin
|
|||||||
FBackgroundColor := TLegalNoticePlugin(Source).BackgroundColor;
|
FBackgroundColor := TLegalNoticePlugin(Source).BackgroundColor;
|
||||||
FBackgroundOpacity := TLegalNoticePlugin(Source).BackgroundOpacity;
|
FBackgroundOpacity := TLegalNoticePlugin(Source).BackgroundOpacity;
|
||||||
FLegalNotice := TLegalNoticePlugin(Source).LegalNotice;
|
FLegalNotice := TLegalNoticePlugin(Source).LegalNotice;
|
||||||
FLegalNoticeURL := TLegalNoticePlugin(Source).LegalNoticeURL;
|
|
||||||
FPosition := TLegalNoticePlugin(Source).Position;
|
FPosition := TLegalNoticePlugin(Source).Position;
|
||||||
FSpacing := TLegalNoticePlugin(Source).Spacing;
|
FSpacing := TLegalNoticePlugin(Source).Spacing;
|
||||||
|
FURLFontColor := TLegalNoticePlugin(Source).URLFontColor;
|
||||||
end;
|
end;
|
||||||
inherited;
|
inherited;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TLegalNoticePlugin.AfterDrawObjects(AMapView: TMapView; var Handled: Boolean);
|
procedure TLegalNoticePlugin.AfterDrawObjects(AMapView: TMapView; var Handled: Boolean);
|
||||||
var
|
var
|
||||||
x, y: Integer;
|
i: Integer;
|
||||||
lClickableRect: TRect;
|
lBounds: TRect;
|
||||||
lSavedFont: TMvFont;
|
lSavedFont: TMvFont;
|
||||||
lSavedOpacity: Single;
|
lSavedOpacity: Single;
|
||||||
|
part: TLegalNoticePart;
|
||||||
begin
|
begin
|
||||||
if not Assigned(AMapView) then Exit;
|
if not Assigned(AMapView) then Exit;
|
||||||
Handled := True;
|
Handled := True;
|
||||||
CalcClickableRect(AMapView,lClickableRect);
|
|
||||||
x := lClickableRect.Left;
|
|
||||||
y := lClickableRect.Top;
|
|
||||||
lSavedFont := AMapView.DrawingEngine.GetFont;
|
lSavedFont := AMapView.DrawingEngine.GetFont;
|
||||||
lSavedOpacity := AMapView.DrawingEngine.Opacity;
|
lSavedOpacity := AMapView.DrawingEngine.Opacity;
|
||||||
try
|
try
|
||||||
|
ExtractLegalNoticeParts(AMapView);
|
||||||
|
|
||||||
|
lBounds := Rect(MaxInt, MaxInt, -MaxInt, -MaxInt);
|
||||||
|
for i := 0 to FLegalNoticeParts.Count-1 do
|
||||||
|
begin
|
||||||
|
part := TLegalNoticePart(FLegalNoticeParts[i]);
|
||||||
|
if part.Rect.Left < lBounds.Left then lBounds.Left := part.Rect.Left;
|
||||||
|
if part.Rect.Top < lBounds.Top then lBounds.Top := part.Rect.Top;
|
||||||
|
if part.Rect.Right > lBounds.Right then lBounds.Right := part.Rect.Right;
|
||||||
|
if part.Rect.Bottom > lBounds.Bottom then lBounds.Bottom := part.Rect.Bottom;
|
||||||
|
end;
|
||||||
|
|
||||||
|
// Draw the common (semi-transparent) background of all parts
|
||||||
if FBackgroundColor <> clNone then
|
if FBackgroundColor <> clNone then
|
||||||
begin
|
begin
|
||||||
AMapView.DrawingEngine.Opacity := FBackgroundOpacity;
|
AMapView.DrawingEngine.Opacity := FBackgroundOpacity;
|
||||||
AMapView.DrawingEngine.BrushStyle := bsSolid;
|
AMapView.DrawingEngine.BrushStyle := bsSolid;
|
||||||
AMapView.DrawingEngine.BrushColor := ColorToRGB(FBackgroundColor);
|
AMapView.DrawingEngine.BrushColor := ColorToRGB(FBackgroundColor);
|
||||||
with lClickableRect do
|
with lBounds do
|
||||||
AMapView.DrawingEngine.FillRect(Left, Top, Right, Bottom);
|
AMapView.DrawingEngine.FillRect(Left, Top, Right, Bottom);
|
||||||
end;
|
end;
|
||||||
AMapView.DrawingEngine.BrushStyle := bsClear;
|
AMapView.DrawingEngine.BrushStyle := bsClear;
|
||||||
|
|
||||||
|
// Draw the part texts
|
||||||
|
for i := 0 to FLegalNoticeParts.Count-1 do
|
||||||
|
begin
|
||||||
|
part := TLegalNoticePart(FLegalNoticeParts[i]);
|
||||||
|
if part.URL <> '' then
|
||||||
|
begin
|
||||||
|
if i = FMouseOverPart then
|
||||||
|
AMapView.DrawingEngine.SetFont(Font.Name, Font.Size, Font.Style + [fsUnderline], FURLFontColor)
|
||||||
|
else
|
||||||
|
AMapView.DrawingEngine.SetFont(Font.Name, Font.Size, Font.Style, FURLFontColor)
|
||||||
|
end
|
||||||
|
else
|
||||||
AMapView.DrawingEngine.SetFont(Font.Name, Font.Size, Font.Style, Font.Color);
|
AMapView.DrawingEngine.SetFont(Font.Name, Font.Size, Font.Style, Font.Color);
|
||||||
AMapView.DrawingEngine.TextOut(x, y, FLegalNotice);
|
AMapView.DrawingEngine.TextOut(part.Rect.Left, part.Rect.Top, part.Text);
|
||||||
|
end;
|
||||||
finally
|
finally
|
||||||
AMapView.DrawingEngine.Opacity := lSavedOpacity;
|
AMapView.DrawingEngine.Opacity := lSavedOpacity;
|
||||||
AMapView.DrawingEngine.SetFont(lSavedFont);
|
AMapView.DrawingEngine.SetFont(lSavedFont);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TLegalNoticePlugin.CalcClickableRect(AMapView: TMapView; out
|
{ LegalNotice can contain text and embedded URLs with text following the
|
||||||
AClickableRect: TRect);
|
wikipedia mark-down.
|
||||||
|
|
||||||
|
Line breaks allowed as #13, #10, #13#10, or '\n'
|
||||||
|
|
||||||
|
Example:
|
||||||
|
'Map data from [https://openstreetmap.org/copyright OpenStreetMap and contributors]'
|
||||||
|
displayed as "Map data from OpenStreamMap and contributors"
|
||||||
|
Embedded URL (https://openstreetmap.org/copyright) is assigned to text
|
||||||
|
"OpenStreetMap and contributors" }
|
||||||
|
procedure TLegalNoticePlugin.ExtractLegalNoticeParts(AMapView: TMapView);
|
||||||
var
|
var
|
||||||
|
P: PAnsiChar;
|
||||||
|
partType: (ptText, ptURL, ptURLText, prLineBreak);
|
||||||
|
txt: String;
|
||||||
|
url: String;
|
||||||
|
part: TLegalNoticePart;
|
||||||
|
savedFont: TMvFont;
|
||||||
|
R: TRect;
|
||||||
|
lineWidths: array of integer = nil;
|
||||||
sz: TSize;
|
sz: TSize;
|
||||||
x, y: Integer;
|
i, line, dx, dy, nLines: Integer;
|
||||||
lSavedFont: TMvFont;
|
|
||||||
begin
|
begin
|
||||||
lSavedFont := AMapView.DrawingEngine.GetFont;
|
FLegalNoticeParts.Clear;
|
||||||
|
if FLegalNotice = '' then
|
||||||
|
exit;
|
||||||
|
|
||||||
|
P := PChar(FLegalNotice);
|
||||||
|
partType := ptText;
|
||||||
|
txt := '';
|
||||||
|
url := '';
|
||||||
|
nLines := 1;
|
||||||
|
|
||||||
|
while true do
|
||||||
|
begin
|
||||||
|
case P^ of
|
||||||
|
#0 : break;
|
||||||
|
'[': begin
|
||||||
|
// entering a URL part
|
||||||
|
if partType = ptText then
|
||||||
|
begin
|
||||||
|
if (txt <> '') or (url <> '') then
|
||||||
|
begin
|
||||||
|
// Store away previously found txt and url
|
||||||
|
part := TLegalNoticePart.Create(txt, url);
|
||||||
|
FLegalNoticeParts.Add(part);
|
||||||
|
end;
|
||||||
|
partType := ptURL; // the next part will be in URL
|
||||||
|
txt := '';
|
||||||
|
url := '';
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
' ': if partType = ptURL then // in URL
|
||||||
|
begin
|
||||||
|
partType := ptURLText; // next part will be the text assigned to the URL
|
||||||
|
txt := '';
|
||||||
|
end else
|
||||||
|
txt := txt + P^;
|
||||||
|
']': if partType = ptURLText then
|
||||||
|
begin
|
||||||
|
if (txt <> '') and (url <> '') then
|
||||||
|
begin
|
||||||
|
// Store away url and its text
|
||||||
|
part := TLegalNoticePart.Create(txt, url);
|
||||||
|
FLegalNoticeParts.Add(part);
|
||||||
|
end;
|
||||||
|
partType := ptText; // next part will be normal text again
|
||||||
|
txt := '';
|
||||||
|
url := '';
|
||||||
|
end;
|
||||||
|
#13,
|
||||||
|
#10: begin
|
||||||
|
if P^ = #13 then
|
||||||
|
begin
|
||||||
|
inc(P);
|
||||||
|
if P^ <> #10 then dec(P);
|
||||||
|
end;
|
||||||
|
// Store away previously found text and url
|
||||||
|
FLegalNoticeParts.Add(TLegalNoticePart.Create(txt, url));
|
||||||
|
// Store #13 as indicator of a line break. Keep url.
|
||||||
|
FLegalNoticeParts.Add(TLegalNoticePart.Create(#13, ''));
|
||||||
|
txt := '';
|
||||||
|
inc(nLines);
|
||||||
|
end;
|
||||||
|
'\': begin
|
||||||
|
inc(P);
|
||||||
|
if (P^ in ['n', 'N']) then
|
||||||
|
begin
|
||||||
|
// Store away previously found text and url
|
||||||
|
FLegalNoticeParts.Add(TLegalNoticePart.Create(txt, url));
|
||||||
|
// Store #13 as indicator of a line break. Keep url.
|
||||||
|
FLegalNoticeParts.Add(TLegalNoticePart.Create(#13, ''));
|
||||||
|
txt := '';
|
||||||
|
inc(nLines);
|
||||||
|
end else
|
||||||
|
begin
|
||||||
|
dec(P);
|
||||||
|
txt := txt + P^;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
else
|
||||||
|
if partType = ptURL then
|
||||||
|
url := url + P^
|
||||||
|
else
|
||||||
|
txt := txt + P^;
|
||||||
|
end;
|
||||||
|
inc(P);
|
||||||
|
end;
|
||||||
|
|
||||||
|
if (partType = ptText) and (txt <> '') then
|
||||||
|
begin
|
||||||
|
part := TLegalNoticePart.Create(txt, '');
|
||||||
|
FLegalNoticeParts.Add(part);
|
||||||
|
end;
|
||||||
|
|
||||||
|
// Measure pixel size of parts
|
||||||
|
savedFont := AMapView.DrawingEngine.GetFont;
|
||||||
try
|
try
|
||||||
AMapView.DrawingEngine.SetFont(Font.Name, Font.Size, Font.Style, Font.Color);
|
AMapView.DrawingEngine.SetFont(Font.Name, Font.Size, Font.Style, Font.Color);
|
||||||
sz := AMapView.DrawingEngine.TextExtent(FLegalNotice);
|
R := Rect(0, 0, 0, 0);
|
||||||
|
SetLength(lineWidths, nLines);
|
||||||
|
line := 0;
|
||||||
|
lineWidths[line] := 0;
|
||||||
|
for i := 0 to FLegalNoticeParts.Count-1 do
|
||||||
|
begin
|
||||||
|
part := TLegalNoticePart(FLegalNoticeParts[i]);
|
||||||
|
sz := AMapView.DrawingEngine.TextExtent(part.Text);
|
||||||
|
R := Rect(R.Right, R.Top, R.Right + sz.CX, R.Top + sz.CY);
|
||||||
|
if R.Right > lineWidths[line] then
|
||||||
|
lineWidths[line] := R.Right;
|
||||||
|
if part.Text = #13 then // line break
|
||||||
|
begin
|
||||||
|
R := Rect(0, R.Bottom - sz.CY div 2, 0, R.Bottom);
|
||||||
|
inc(line);
|
||||||
|
lineWidths[line] := 0;
|
||||||
|
end;
|
||||||
|
part.Rect := R;
|
||||||
|
end;
|
||||||
|
finally
|
||||||
|
AMapView.DrawingEngine.SetFont(savedFont);
|
||||||
|
end;
|
||||||
|
|
||||||
|
// Calculate left/top corner of total text
|
||||||
case FPosition of
|
case FPosition of
|
||||||
lnpTopLeft, lnpBottomLeft:
|
lnpTopLeft, lnpBottomLeft:
|
||||||
x := FSpacing;
|
dx := FSpacing;
|
||||||
lnpTopRight, lnpBottomRight:
|
lnpTopRight, lnpBottomRight:
|
||||||
x := AMapView.Width - sz.CX - FSpacing;
|
dx := AMapView.Width - FSpacing - lineWidths[0];
|
||||||
end;
|
end;
|
||||||
case FPosition of
|
case FPosition of
|
||||||
lnpTopLeft, lnpTopRight:
|
lnpTopLeft, lnpTopRight:
|
||||||
y := FSpacing;
|
dy := FSpacing;
|
||||||
lnpBottomLeft, lnpBottomRight:
|
lnpBottomLeft, lnpBottomRight:
|
||||||
y := AMapView.Height - sz.CY - FSpacing;
|
dy := AMapView.Height - R.Bottom - FSpacing;
|
||||||
end;
|
end;
|
||||||
AClickableRect := Rect(x, y, x + sz.CX, y + sz.CY);
|
|
||||||
SetMapViewData(AMapView,AClickableRect,SizeOf(AClickableRect));
|
// Move text rectangles to correct position
|
||||||
finally
|
line := 0;
|
||||||
AMapView.DrawingEngine.SetFont(lSavedFont);
|
for i := 0 to FLegalNoticeParts.Count-1 do
|
||||||
|
begin
|
||||||
|
part := TLegalNoticePart(FLegalNoticeParts[i]);
|
||||||
|
if part.Text = #13 then
|
||||||
|
begin
|
||||||
|
inc(line);
|
||||||
|
if FPosition in [lnpTopRight, lnpBottomRight] then
|
||||||
|
dx := AMapView.Width - FSpacing - lineWidths[line];
|
||||||
|
end;
|
||||||
|
OffsetRect(part.Rect, dx, dy);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -422,53 +607,60 @@ end;
|
|||||||
procedure TLegalNoticePlugin.MouseDown(AMapView: TMapView; Button: TMouseButton;
|
procedure TLegalNoticePlugin.MouseDown(AMapView: TMapView; Button: TMouseButton;
|
||||||
Shift: TShiftState; X, Y: Integer; var Handled: Boolean);
|
Shift: TShiftState; X, Y: Integer; var Handled: Boolean);
|
||||||
var
|
var
|
||||||
pt: TPoint;
|
url: String;
|
||||||
lClickableRect : TRect;
|
|
||||||
begin
|
begin
|
||||||
|
Unused(AMapView);
|
||||||
// The button down event is consumed by a different plugin, so do nothing here
|
// The button down event is consumed by a different plugin, so do nothing here
|
||||||
if Handled then Exit;
|
if Handled then Exit;
|
||||||
pt.X := X;
|
if PointInURLPart(Point(X, Y), url) <> -1 then
|
||||||
pt.Y := Y;
|
|
||||||
if GetMapViewData(AMapView,lClickableRect,SizeOf(lClickableRect)) < SizeOf(lClickableRect) then
|
|
||||||
CalcClickableRect(AMapView,lClickableRect);
|
|
||||||
if PtInRect(lClickableRect, pt) and (FLegalNoticeURL <> '') then
|
|
||||||
begin
|
begin
|
||||||
// The button down event is consumed by this plugin
|
// The button down event is consumed by this plugin
|
||||||
OpenURL(FLegalNoticeURL);
|
OpenURL(url);
|
||||||
Handled := True;
|
Handled := True;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TLegalNoticePlugin.MouseEnter(AMapView: TMapView; var Handled: Boolean);
|
|
||||||
var
|
|
||||||
lClickableRect : TRect;
|
|
||||||
begin
|
|
||||||
inherited;
|
|
||||||
CalcClickableRect(AMapView,lClickableRect);
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure TLegalNoticePlugin.MouseMove(AMapView: TMapView; Shift: TShiftState;
|
procedure TLegalNoticePlugin.MouseMove(AMapView: TMapView; Shift: TShiftState;
|
||||||
X, Y: Integer; var Handled: Boolean);
|
X, Y: Integer; var Handled: Boolean);
|
||||||
var
|
var
|
||||||
lClickableRect : TRect;
|
url: String;
|
||||||
begin
|
begin
|
||||||
if GetMapViewData(AMapView,lClickableRect,SizeOf(lClickableRect)) < SizeOf(lClickableRect) then
|
ExtractLegalNoticeParts(AMapView);
|
||||||
CalcClickableRect(AMapView, lClickableRect);
|
|
||||||
|
|
||||||
if PtInRect(lClickableRect, Point(X, Y)) and (not AMapView.Engine.InDrag) and
|
if not (AMapView.Engine.InDrag) then
|
||||||
(FLegalNoticeURL <> '') then
|
begin
|
||||||
|
FMouseOverPart := PointInURLPart(Point(X, Y), url);
|
||||||
|
if (FMouseOverPart <> -1) then
|
||||||
|
begin
|
||||||
|
if url <> '' then
|
||||||
begin
|
begin
|
||||||
Font.Style := [fsUnderline];
|
|
||||||
AMapView.Cursor := crHandPoint;
|
AMapView.Cursor := crHandPoint;
|
||||||
Handled := true;
|
Handled := true;
|
||||||
|
end;
|
||||||
end else
|
end else
|
||||||
begin
|
|
||||||
Font.Style := [];
|
|
||||||
if not Handled then
|
if not Handled then
|
||||||
AMapView.Cursor := crDefault;
|
AMapView.Cursor := crDefault;
|
||||||
end;
|
|
||||||
Update;
|
Update;
|
||||||
end;
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TLegalNoticePlugin.PointInURLPart(APoint: TPoint; out URL: String): Integer;
|
||||||
|
var
|
||||||
|
part: TLegalNoticePart;
|
||||||
|
begin
|
||||||
|
for Result := 0 to FLegalNoticeParts.Count-1 do
|
||||||
|
begin
|
||||||
|
part := TLegalNoticePart(FLegalNoticeParts[Result]);
|
||||||
|
if PtInRect(part.Rect, APoint) and (part.URL <> '') then
|
||||||
|
begin
|
||||||
|
uRL := part.URL;
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
URL := '';
|
||||||
|
Result := -1;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure TLegalNoticePlugin.SetPosition(AValue: TLegalNoticePosition);
|
procedure TLegalNoticePlugin.SetPosition(AValue: TLegalNoticePosition);
|
||||||
begin
|
begin
|
||||||
@ -477,20 +669,13 @@ begin
|
|||||||
Update;
|
Update;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TLegalNoticePlugin.SetLegalNotice(AValue: String);
|
procedure TLegalNoticePlugin.SetLegalNotice(AValue: TCaption);
|
||||||
begin
|
begin
|
||||||
if FLegalNotice = AValue then Exit;
|
if FLegalNotice = AValue then Exit;
|
||||||
FLegalNotice := AValue;
|
FLegalNotice := AValue;
|
||||||
Update;
|
Update;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TLegalNoticePlugin.SetLegalNoticeURL(AValue: String);
|
|
||||||
begin
|
|
||||||
if FLegalNoticeURL = AValue then Exit;
|
|
||||||
FLegalNoticeURL := AValue;
|
|
||||||
Update;
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure TLegalNoticePlugin.SetBackgroundColor(AValue: TColor);
|
procedure TLegalNoticePlugin.SetBackgroundColor(AValue: TColor);
|
||||||
begin
|
begin
|
||||||
if FBackgroundColor = AValue then Exit;
|
if FBackgroundColor = AValue then Exit;
|
||||||
@ -512,6 +697,9 @@ begin
|
|||||||
Update;
|
Update;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
{ TDraggableMarkerPlugin }
|
||||||
|
|
||||||
function TDraggableMarkerPlugin.GetFirstMarkerAtMousePos(const AMapView: TMapView;
|
function TDraggableMarkerPlugin.GetFirstMarkerAtMousePos(const AMapView: TMapView;
|
||||||
const AX, AY: Integer): TGPSPoint;
|
const AX, AY: Integer): TGPSPoint;
|
||||||
var
|
var
|
||||||
|
@ -14,9 +14,9 @@ implementation
|
|||||||
{$R mvmapviewer_icons.res}
|
{$R mvmapviewer_icons.res}
|
||||||
|
|
||||||
uses
|
uses
|
||||||
ImgList,
|
Controls, ImgList,
|
||||||
mvTypes, mvGeoNames, mvMapViewer, mvDLEFpc, mvDLECache, mvPluginCore,
|
mvTypes, mvGeoNames, mvMapViewer, mvDLEFpc, mvDLECache, mvPluginCore,
|
||||||
mvMapViewerPropEdits, mvPluginEditors;
|
mvMapViewerPropEdits, mvPlugins, mvPluginEditors;
|
||||||
|
|
||||||
procedure Register;
|
procedure Register;
|
||||||
var
|
var
|
||||||
@ -55,9 +55,11 @@ begin
|
|||||||
RegisterPropertyEditor(TypeInfo(Double),
|
RegisterPropertyEditor(TypeInfo(Double),
|
||||||
TMapCenter,'Longitude', TLatLonDMSPropertyEditor);
|
TMapCenter,'Longitude', TLatLonDMSPropertyEditor);
|
||||||
|
|
||||||
|
RegisterComponentEditor(TMvPluginManager, TMvPluginManagerComponentEditor);
|
||||||
RegisterPropertyEditor(TypeInfo(TMvPluginList),
|
RegisterPropertyEditor(TypeInfo(TMvPluginList),
|
||||||
TMvPluginManager, 'PluginList', TMvPluginListPropertyEditor);
|
TMvPluginManager, 'PluginList', TMvPluginListPropertyEditor);
|
||||||
RegisterComponentEditor(TMvPluginManager, TMvPluginManagerComponentEditor);
|
RegisterPropertyEditor(TypeInfo(TCaption),
|
||||||
|
TLegalNoticePlugin, 'LegalNotice', TStringMultilinePropertyEditor);
|
||||||
|
|
||||||
for i := 0 to PluginClassRegistry.Count - 1 do
|
for i := 0 to PluginClassRegistry.Count - 1 do
|
||||||
RegisterNoIcon([TMvCustomPluginClass(PluginClassRegistry.GetClass(i))]);
|
RegisterNoIcon([TMvCustomPluginClass(PluginClassRegistry.GetClass(i))]);
|
||||||
|
@ -34,14 +34,14 @@ type
|
|||||||
FPluginManager: TMvPluginManager;
|
FPluginManager: TMvPluginManager;
|
||||||
FMapView: TMapView;
|
FMapView: TMapView;
|
||||||
FEnabled: Boolean;
|
FEnabled: Boolean;
|
||||||
procedure SetEnabled(AValue: Boolean);
|
|
||||||
procedure SetMapView(AValue: TMapView);
|
|
||||||
procedure SetPluginManager(AValue: TMvPluginManager);
|
procedure SetPluginManager(AValue: TMvPluginManager);
|
||||||
protected
|
protected
|
||||||
function GetIndex: Integer; override;
|
function GetIndex: Integer; override;
|
||||||
procedure Notification(AComponent: TComponent; Operation: TOperation); override;
|
procedure Notification(AComponent: TComponent; Operation: TOperation); override;
|
||||||
procedure ReadState(Reader: TReader); override;
|
procedure ReadState(Reader: TReader); override;
|
||||||
|
procedure SetEnabled(AValue: Boolean); virtual;
|
||||||
procedure SetIndex(AValue: Integer); override;
|
procedure SetIndex(AValue: Integer); override;
|
||||||
|
procedure SetMapView(AValue: TMapView); virtual;
|
||||||
procedure SetParentComponent(AParent: TComponent); override;
|
procedure SetParentComponent(AParent: TComponent); override;
|
||||||
procedure Update; virtual;
|
procedure Update; virtual;
|
||||||
protected
|
protected
|
||||||
@ -158,6 +158,7 @@ type
|
|||||||
destructor Destroy;override;
|
destructor Destroy;override;
|
||||||
published
|
published
|
||||||
property Enabled;
|
property Enabled;
|
||||||
|
property MapView;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ TMvMultiMapsDrawPlugin }
|
{ TMvMultiMapsDrawPlugin }
|
||||||
|
Loading…
Reference in New Issue
Block a user