From d8cc948b6a35a313d63eb3616625a3059b11a590 Mon Sep 17 00:00:00 2001 From: wp_xxyyzz Date: Mon, 10 Feb 2025 23:17:27 +0000 Subject: [PATCH] LazMapViewer: New PluginManager property MouseButtonDown, update demos. New OnHit and OnBeginChange events for the AreaSelect plugin (issue #39102), new multi demo. git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@9623 8e941d3f-bd1b-0410-a28a-d453659cc2b4 --- .../plugin_demos/areaselection_demo/main.pas | 51 ++- .../areaselection_demo.lpi | 83 +++++ .../areaselection_demo.lpr | 24 ++ .../areaselection_multi_demo/main.lfm | 66 ++++ .../areaselection_multi_demo/main.pas | 143 +++++++++ .../MousePaintOrder_Demo.lpi | 3 +- .../MousePaintOrder_Demo.lpr | 2 +- .../mousepaintorder_demo/main.lfm | 27 +- .../mousepaintorder_demo/main.pas | 54 +++- .../udragcoloreditemplugin.pas | 81 +++-- .../areaselection/mvareaselectionplugin.pas | 291 +++++++++++------- .../spreadmarkers/mvspreadmarker_plugin.pas | 72 +---- .../lazmapviewer/source/mvmapviewer.pas | 24 +- .../lazmapviewer/source/mvplugincommon.pas | 80 ++++- 14 files changed, 747 insertions(+), 254 deletions(-) create mode 100644 components/lazmapviewer/examples/plugin_demos/areaselection_multi_demo/areaselection_demo.lpi create mode 100644 components/lazmapviewer/examples/plugin_demos/areaselection_multi_demo/areaselection_demo.lpr create mode 100644 components/lazmapviewer/examples/plugin_demos/areaselection_multi_demo/main.lfm create mode 100644 components/lazmapviewer/examples/plugin_demos/areaselection_multi_demo/main.pas diff --git a/components/lazmapviewer/examples/plugin_demos/areaselection_demo/main.pas b/components/lazmapviewer/examples/plugin_demos/areaselection_demo/main.pas index 7ac8464ae..214b04b16 100644 --- a/components/lazmapviewer/examples/plugin_demos/areaselection_demo/main.pas +++ b/components/lazmapviewer/examples/plugin_demos/areaselection_demo/main.pas @@ -22,7 +22,8 @@ type procedure FormCreate(Sender: TObject); private - FAreaSelectionPlugin: TAreaSelectionPlugin; + FAreaSelectionPlugin1: TAreaSelectionPlugin; + FAreaSelectionPlugin2: TAreaSelectionPlugin; procedure OnSelectedAreaChanged(Sender: TObject); procedure OnSelectedAreaChanging(Sender: TObject; ANewArea: TRealArea; var Allow: Boolean); @@ -42,31 +43,55 @@ implementation procedure TMainForm.FormCreate(Sender: TObject); begin MapView.Active := true; - FAreaSelectionPlugin := TAreaSelectionPlugin.Create(PluginManager); - FAreaSelectionPlugin.MapView := MapView; - FAreaSelectionPlugin.OnSelectedAreaChanged := @OnSelectedAreaChanged; - FAreaSelectionPlugin.OnSelectedAreaChanging := @OnSelectedAreaChanging; - lblHeader.Caption := ' Left Top Right Bottom'; + FAreaSelectionPlugin1 := TAreaSelectionPlugin.Create(PluginManager); + FAreaSelectionPlugin1.Caption := 'Area 1'; + FAreaSelectionPlugin1.Pen.Color := clNavy; + FAreaSelectionPlugin1.BackgroundColor := clNavy; + FAreaSelectionPlugin1.Font.Color := clWhite; + FAreaSelectionPlugin1.MapView := MapView; + FAreaSelectionPlugin1.OnSelectedAreaChanged := @OnSelectedAreaChanged; + FAreaSelectionPlugin1.OnSelectedAreaChanging := @OnSelectedAreaChanging; + + FAreaSelectionPlugin2 := TAreaSelectionPlugin.Create(PluginManager); + FAreaSelectionPlugin2.Caption := 'Area 2'; + FAreaSelectionPlugin2.CaptionPosition := ascpRightBottom; + FAreaSelectionPlugin2.Pen.Color := clRed; +// FAreaSelectionPlugin2.BackgroundColor := clRed; +// FAreaSelectionPlugin2.Font.Color := clWhite; + FAreaSelectionPlugin2.MapView := MapView; + FAreaSelectionPlugin2.SelectedArea.Area.Init(-110, 40, 110, -60); + FAreaSelectionPlugin2.OnSelectedAreaChanged := @OnSelectedAreaChanged; + FAreaSelectionPlugin2.OnSelectedAreaChanging := @OnSelectedAreaChanging; + + lblHeader.Caption := ' Left Top Right Bottom'; end; procedure TMainForm.OnSelectedAreaChanged(Sender: TObject); +var + plugin: TAreaSelectionPlugin; begin - with FAreaSelectionPlugin.SelectedArea do - Memo.Lines.Add('[%s] Selected: %6.1f° %6.1f° %6.1f° %6.1f°',[ + plugin := Sender as TAreaSelectionPlugin; + with plugin.SelectedArea do + Memo.Lines.Add('[%s] %s Selected: %6.1f° %6.1f° %6.1f° %6.1f°',[ FormatDateTime('hh:nn:ss.zzz', Now()), - TopLeft.Lon, - TopLeft.Lat, - BottomRight.Lon, - BottomRight.Lat + plugin.Caption, + Area.TopLeft.Lon, + Area.TopLeft.Lat, + Area.BottomRight.Lon, + Area.BottomRight.Lat ]); end; procedure TMainForm.OnSelectedAreaChanging(Sender: TObject; ANewArea: TRealArea; var Allow: Boolean); +var + plugin: TAreaSelectionPlugin; begin + plugin := Sender as TAreaSelectionPlugin; with ANewArea do - Memo.Lines.Add('[%s] Selecting: %6.1f° %6.1f° %6.1f° %6.1f°',[ + Memo.Lines.Add('[%s] %s Selecting: %6.1f° %6.1f° %6.1f° %6.1f°',[ FormatDateTime('hh:nn:ss.zzz', Now()), + plugin.Caption, TopLeft.Lon, TopLeft.Lat, BottomRight.Lon, diff --git a/components/lazmapviewer/examples/plugin_demos/areaselection_multi_demo/areaselection_demo.lpi b/components/lazmapviewer/examples/plugin_demos/areaselection_multi_demo/areaselection_demo.lpi new file mode 100644 index 000000000..157718b66 --- /dev/null +++ b/components/lazmapviewer/examples/plugin_demos/areaselection_multi_demo/areaselection_demo.lpi @@ -0,0 +1,83 @@ + + + + + + + + + <Scaled Value="True"/> + <ResourceType Value="res"/> + <UseXPManifest Value="True"/> + <XPManifest> + <DpiAware Value="True"/> + </XPManifest> + </General> + <BuildModes> + <Item Name="Default" Default="True"/> + </BuildModes> + <PublishOptions> + <Version Value="2"/> + <UseFileFilters Value="True"/> + </PublishOptions> + <RunParams> + <FormatVersion Value="2"/> + </RunParams> + <RequiredPackages> + <Item> + <PackageName Value="lazMapViewerPkg"/> + </Item> + <Item> + <PackageName Value="LCL"/> + </Item> + </RequiredPackages> + <Units> + <Unit> + <Filename Value="areaselection_demo.lpr"/> + <IsPartOfProject Value="True"/> + </Unit> + <Unit> + <Filename Value="main.pas"/> + <IsPartOfProject Value="True"/> + <ComponentName Value="MainForm"/> + <HasResources Value="True"/> + <ResourceBaseClass Value="Form"/> + <UnitName Value="Main"/> + </Unit> + </Units> + </ProjectOptions> + <CompilerOptions> + <Version Value="11"/> + <PathDelim Value="\"/> + <Target> + <Filename Value="areaselection_demo"/> + </Target> + <SearchPaths> + <IncludeFiles Value="$(ProjOutDir)"/> + <UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/> + </SearchPaths> + <Linking> + <Debugging> + <DebugInfoType Value="dsDwarf3"/> + </Debugging> + <Options> + <Win32> + <GraphicApplication Value="True"/> + </Win32> + </Options> + </Linking> + </CompilerOptions> + <Debugging> + <Exceptions> + <Item> + <Name Value="EAbort"/> + </Item> + <Item> + <Name Value="ECodetoolError"/> + </Item> + <Item> + <Name Value="EFOpenError"/> + </Item> + </Exceptions> + </Debugging> +</CONFIG> diff --git a/components/lazmapviewer/examples/plugin_demos/areaselection_multi_demo/areaselection_demo.lpr b/components/lazmapviewer/examples/plugin_demos/areaselection_multi_demo/areaselection_demo.lpr new file mode 100644 index 000000000..ed8b7d5a7 --- /dev/null +++ b/components/lazmapviewer/examples/plugin_demos/areaselection_multi_demo/areaselection_demo.lpr @@ -0,0 +1,24 @@ +program areaselection_demo; + +{$mode objfpc}{$H+} + +uses + {$IFDEF UNIX} + cthreads, + {$ENDIF} + {$IFDEF HASAMIGA} + athreads, + {$ENDIF} + Interfaces, // this includes the LCL widgetset + Forms, Main; + +{$R *.res} + +begin + RequireDerivedFormResource:=True; + Application.Scaled:=True; + Application.Initialize; + Application.CreateForm(TMainForm, MainForm); + Application.Run; +end. + diff --git a/components/lazmapviewer/examples/plugin_demos/areaselection_multi_demo/main.lfm b/components/lazmapviewer/examples/plugin_demos/areaselection_multi_demo/main.lfm new file mode 100644 index 000000000..bf3100ca8 --- /dev/null +++ b/components/lazmapviewer/examples/plugin_demos/areaselection_multi_demo/main.lfm @@ -0,0 +1,66 @@ +object MainForm: TMainForm + Left = 324 + Height = 497 + Top = 119 + Width = 579 + Caption = 'Area Selection Plugin Demo' + ClientHeight = 497 + ClientWidth = 579 + Color = clWindow + OnCreate = FormCreate + LCLVersion = '3.6.0.0' + object MapView: TMapView + Left = 0 + Height = 346 + Top = 0 + Width = 579 + Align = alClient + Cyclic = True + DownloadEngine = MapView.BuiltInDLE + DrawingEngine = MapView.BuiltInDE + Layers = <> + Font.Color = clBlack + MapProvider = 'OpenStreetMap Standard' + PluginManager = PluginManager + end + object Memo: TMemo + Left = 0 + Height = 134 + Top = 363 + Width = 579 + Align = alBottom + BorderSpacing.InnerBorder = 2 + Font.Height = -11 + Font.Name = 'Liberation Mono' + ParentFont = False + ReadOnly = True + ScrollBars = ssAutoBoth + TabOrder = 1 + end + object Splitter1: TSplitter + Cursor = crVSplit + Left = 0 + Height = 5 + Top = 358 + Width = 579 + Align = alBottom + ResizeAnchor = akBottom + end + object lblHeader: TStaticText + Left = 0 + Height = 12 + Top = 346 + Width = 579 + Align = alBottom + Color = clDefault + Font.Height = -11 + Font.Name = 'Liberation Mono' + ParentFont = False + ParentColor = False + TabOrder = 3 + end + object PluginManager: TMvPluginManager + Left = 320 + Top = 24 + end +end diff --git a/components/lazmapviewer/examples/plugin_demos/areaselection_multi_demo/main.pas b/components/lazmapviewer/examples/plugin_demos/areaselection_multi_demo/main.pas new file mode 100644 index 000000000..8ba3c6b43 --- /dev/null +++ b/components/lazmapviewer/examples/plugin_demos/areaselection_multi_demo/main.pas @@ -0,0 +1,143 @@ +unit Main; + +{$mode objfpc}{$H+} + +interface + +uses + Classes, SysUtils, + Forms, Controls, Graphics, StdCtrls, ExtCtrls, Dialogs, + mvMapViewer, mvTypes, mvPluginCommon, mvAreaSelectionPlugin; + +type + + { TMainForm } + + TMainForm = class(TForm) + lblHeader: TStaticText; + MapView: TMapView; + Memo: TMemo; + PluginManager: TMvPluginManager; + Splitter1: TSplitter; + procedure FormCreate(Sender: TObject); + + private + FAreaSelectionPlugin: TAreaSelectionPlugin; + FAreaSelectionPlugin2: TAreaSelectionPlugin; + procedure OnSelectedAreaHit(Sender: TObject); + procedure OnSelectedAreaBeginChange(Sender: TObject); + + procedure OnSelectedAreaChanged(Sender: TObject); + procedure OnSelectedAreaChanging(Sender: TObject; ANewArea: TRealArea; var Allow: Boolean); + + public + + end; + +var + MainForm: TMainForm; + +implementation + +{$R *.lfm} + +{ TMainForm } + +procedure TMainForm.FormCreate(Sender: TObject); +var + lArea : TRealArea; +begin + MapView.Active := true; + FAreaSelectionPlugin := TAreaSelectionPlugin.Create(PluginManager); + FAreaSelectionPlugin.Name := 'FAreaSelectionPlugin'; + FAreaSelectionPlugin.MapView := MapView; + FAreaSelectionPlugin.OnSelectedAreaHit := @OnSelectedAreaHit; + FAreaSelectionPlugin.OnSelectedAreaBeginChange := @OnSelectedAreaBeginChange; + FAreaSelectionPlugin.OnSelectedAreaChanged := @OnSelectedAreaChanged; + FAreaSelectionPlugin.OnSelectedAreaChanging := @OnSelectedAreaChanging; + FAreaSelectionPlugin.Caption := '#1'; + FAreaSelectionPlugin.CaptionPosition := ascpRightTop; + lblHeader.Caption := ' Left Top Right Bottom'; + + + FAreaSelectionPlugin2 := TAreaSelectionPlugin.Create(PluginManager); + FAreaSelectionPlugin2.Name := 'FAreaSelectionPlugin2'; + FAreaSelectionPlugin2.SelectedArea.West := -150.0; + FAreaSelectionPlugin2.SelectedArea.South := -60; + FAreaSelectionPlugin2.MapView := MapView; + FAreaSelectionPlugin2.OnSelectedAreaHit := @OnSelectedAreaHit; + FAreaSelectionPlugin2.OnSelectedAreaBeginChange := @OnSelectedAreaBeginChange; + FAreaSelectionPlugin2.OnSelectedAreaChanged := @OnSelectedAreaChanged; + FAreaSelectionPlugin2.OnSelectedAreaChanging := @OnSelectedAreaChanging; + FAreaSelectionPlugin2.Caption := '#2'; + FAreaSelectionPlugin2.CaptionPosition := ascpLeftBottom; +end; + +procedure TMainForm.OnSelectedAreaHit(Sender: TObject); +var + lSelAreaPlugin : TAreaSelectionPlugin absolute Sender; + i : Integer; +begin + if not (Sender is TAreaSelectionPlugin) then Exit; + lSelAreaPlugin.Pen.Color := clGreen; + for i := 0 to PluginManager.Count-1 do + begin + if (PluginManager.Items[i] is TAreaSelectionPlugin) and + (PluginManager.Items[i] <> lSelAreaPlugin) then + begin + TAreaSelectionPlugin(PluginManager.Items[i]).Pen.Color := clNavy; + end; + end; + Memo.Lines.Add('[%s] Hit: %s',[ + FormatDateTime('hh:nn:ss.zzz', Now()), + lSelAreaPlugin.Name + ]); +end; + +procedure TMainForm.OnSelectedAreaBeginChange(Sender: TObject); +var + lSelAreaPlugin : TAreaSelectionPlugin absolute Sender; +begin + if not (Sender is TAreaSelectionPlugin) then Exit; + lSelAreaPlugin.Pen.Color := clRed; + Memo.Lines.Add('[%s] BeginChange: %s',[ + FormatDateTime('hh:nn:ss.zzz', Now()), + lSelAreaPlugin.Name + ]); +end; + +procedure TMainForm.OnSelectedAreaChanged(Sender: TObject); +var + lSelAreaPlugin : TAreaSelectionPlugin absolute Sender; +begin + if not (Sender is TAreaSelectionPlugin) then Exit; + lSelAreaPlugin.Pen.Color := clGreen; + Memo.Lines.Add('[%s] Selected: %6.1f° %6.1f° %6.1f° %6.1f°, %s',[ + FormatDateTime('hh:nn:ss.zzz', Now()), + lSelAreaPlugin.SelectedArea.North, + lSelAreaPlugin.SelectedArea.West, + lSelAreaPlugin.SelectedArea.South, + lSelAreaPlugin.SelectedArea.East, + lSelAreaPlugin.Name + ]); +end; + +procedure TMainForm.OnSelectedAreaChanging(Sender: TObject; ANewArea: TRealArea; + var Allow: Boolean); +var + lSelAreaPlugin : TAreaSelectionPlugin absolute Sender; +begin + if not (Sender is TAreaSelectionPlugin) then Exit; + with ANewArea do + Memo.Lines.Add('[%s] Selecting: %6.1f° %6.1f° %6.1f° %6.1f° %s',[ + FormatDateTime('hh:nn:ss.zzz', Now()), + TopLeft.Lon, + TopLeft.Lat, + BottomRight.Lon, + BottomRight.Lat, + lSelAreaPlugin.Name + ]); +end; + +end. + diff --git a/components/lazmapviewer/examples/plugin_demos/mousepaintorder_demo/MousePaintOrder_Demo.lpi b/components/lazmapviewer/examples/plugin_demos/mousepaintorder_demo/MousePaintOrder_Demo.lpi index 1e60b680c..e6c19ee30 100644 --- a/components/lazmapviewer/examples/plugin_demos/mousepaintorder_demo/MousePaintOrder_Demo.lpi +++ b/components/lazmapviewer/examples/plugin_demos/mousepaintorder_demo/MousePaintOrder_Demo.lpi @@ -12,7 +12,6 @@ <XPManifest> <DpiAware Value="True"/> </XPManifest> - <Icon Value="0"/> </General> <BuildModes> <Item Name="Default" Default="True"/> @@ -40,7 +39,7 @@ <Unit> <Filename Value="main.pas"/> <IsPartOfProject Value="True"/> - <ComponentName Value="Form1"/> + <ComponentName Value="MainForm"/> <HasResources Value="True"/> <ResourceBaseClass Value="Form"/> <UnitName Value="Main"/> diff --git a/components/lazmapviewer/examples/plugin_demos/mousepaintorder_demo/MousePaintOrder_Demo.lpr b/components/lazmapviewer/examples/plugin_demos/mousepaintorder_demo/MousePaintOrder_Demo.lpr index 4b08658a0..8e1b89328 100644 --- a/components/lazmapviewer/examples/plugin_demos/mousepaintorder_demo/MousePaintOrder_Demo.lpr +++ b/components/lazmapviewer/examples/plugin_demos/mousepaintorder_demo/MousePaintOrder_Demo.lpr @@ -19,7 +19,7 @@ begin RequireDerivedFormResource:=True; Application.Scaled:=True; Application.Initialize; - Application.CreateForm(TForm1, Form1); + Application.CreateForm(TMainForm, MainForm); Application.Run; end. diff --git a/components/lazmapviewer/examples/plugin_demos/mousepaintorder_demo/main.lfm b/components/lazmapviewer/examples/plugin_demos/mousepaintorder_demo/main.lfm index d15f1ec5c..5e5454292 100644 --- a/components/lazmapviewer/examples/plugin_demos/mousepaintorder_demo/main.lfm +++ b/components/lazmapviewer/examples/plugin_demos/mousepaintorder_demo/main.lfm @@ -1,25 +1,25 @@ -object Form1: TForm1 +object MainForm: TMainForm Left = 324 Height = 323 Top = 119 Width = 429 - Caption = 'Form1' + Caption = 'MainForm' ClientHeight = 323 ClientWidth = 429 LCLVersion = '4.99.0.0' OnCreate = FormCreate - object MapView1: TMapView + object MapView: TMapView Left = 0 Height = 297 Top = 0 Width = 429 Align = alClient - DownloadEngine = MapView1.BuiltInDLE - DrawingEngine = MapView1.BuiltInDE + DownloadEngine = MapView.BuiltInDLE + DrawingEngine = MapView.BuiltInDE Layers = <> Font.Color = clBlack MapProvider = 'OpenStreetMap Standard' - PluginManager = MvPluginManager1 + PluginManager = MvPluginManager end object Panel1: TPanel Left = 0 @@ -28,9 +28,22 @@ object Form1: TForm1 Width = 429 Align = alBottom Caption = 'Drag the colored items with the right mouse button' + ClientHeight = 26 + ClientWidth = 429 TabOrder = 1 + object CheckBox1: TCheckBox + Left = 4 + Height = 19 + Top = 4 + Width = 60 + Caption = 'Caption' + Checked = True + State = cbChecked + TabOrder = 0 + OnChange = CheckBox1Change + end end - object MvPluginManager1: TMvPluginManager + object MvPluginManager: TMvPluginManager Left = 320 Top = 24 end diff --git a/components/lazmapviewer/examples/plugin_demos/mousepaintorder_demo/main.pas b/components/lazmapviewer/examples/plugin_demos/mousepaintorder_demo/main.pas index e97cc3375..6335a7ca1 100644 --- a/components/lazmapviewer/examples/plugin_demos/mousepaintorder_demo/main.pas +++ b/components/lazmapviewer/examples/plugin_demos/mousepaintorder_demo/main.pas @@ -1,3 +1,8 @@ +{ This example will create 9 DragColorPlugins and allow the user to drag the + items with the right mouse button down. + The Items show different MouseCursors to identify the options + It also allows the change of the size using the mouse wheel. +} unit Main; {$mode objfpc}{$H+} @@ -5,17 +10,19 @@ unit Main; interface uses - Classes, SysUtils, Forms, Controls, Graphics, Dialogs, ExtCtrls, + Classes, SysUtils, Forms, Controls, Graphics, Dialogs, ExtCtrls, StdCtrls, mvMapViewer, mvPluginCommon, uDragColoredItemPlugin; type - { TForm1 } + { TMainForm } - TForm1 = class(TForm) - MapView1: TMapView; - MvPluginManager1: TMvPluginManager; + TMainForm = class(TForm) + CheckBox1: TCheckBox; + MapView: TMapView; + MvPluginManager: TMvPluginManager; Panel1: TPanel; + procedure CheckBox1Change(Sender: TObject); procedure FormCreate(Sender: TObject); private @@ -24,33 +31,52 @@ type end; var - Form1: TForm1; + MainForm: TMainForm; implementation {$R *.lfm} -{ TForm1 } +{ TMainForm } const - PluginColors : array[0..8] of TColor = ( - clFuchsia, clRed, $ff8c00, clYellow, clLime, clGreen, clNavy, clBlue, clAqua + PluginCount = 9; + PluginColors : array[0..PluginCount-1] of TColor = ( + clFuchsia,clRed,$ff8c00,clYellow,clLime,clGreen,clNavy,clBlue,clAqua + ); + PlugInMouseCursors : array[0..PluginCount-1] of TCursor = ( + crCross,crDrag, crNoDrop, crHSplit, + crVSplit, crMultiDrag, crSQLWait, crNo, + crSize ); -procedure TForm1.FormCreate(Sender: TObject); +procedure TMainForm.FormCreate(Sender: TObject); var lDragColoredItemPlugin : TDragColoredItemPlugin; i: Integer; begin - MapView1.Active := true; - + MapView.Active := true; for i := 0 to High(PluginColors) do begin lDragColoredItemPlugin := TDragColoredItemPlugin.Create(Self); lDragColoredItemPlugin.Color := PluginColors[i]; - lDragColoredItemPlugin.MapView := MapView1; - MvPluginManager1.AddPlugin(lDragColoredItemPlugin); + lDragColoredItemPlugin.MouseCursor := PlugInMouseCursors[i]; + lDragColoredItemPlugin.ShowCaption := CheckBox1.Checked; + lDragColoredItemPlugin.MapView := MapView; + MvPluginManager.AddPlugin(lDragColoredItemPlugin); end; end; +procedure TMainForm.CheckBox1Change(Sender: TObject); +var + i : Integer; +begin + for i := 0 to MvPluginManager.Count-1 do + begin + if MvPluginManager.Items[i] is TDragColoredItemPlugin then + TDragColoredItemPlugin(MvPluginManager.Items[i]).ShowCaption:= CheckBox1.Checked; + end; + MapView.Invalidate; +end; + end. diff --git a/components/lazmapviewer/examples/plugin_demos/mousepaintorder_demo/udragcoloreditemplugin.pas b/components/lazmapviewer/examples/plugin_demos/mousepaintorder_demo/udragcoloreditemplugin.pas index 41553edf1..ab72d9947 100644 --- a/components/lazmapviewer/examples/plugin_demos/mousepaintorder_demo/udragcoloreditemplugin.pas +++ b/components/lazmapviewer/examples/plugin_demos/mousepaintorder_demo/udragcoloreditemplugin.pas @@ -1,3 +1,11 @@ +{ The TDragColoredItemPlugin implements an example of sharing the mouse events + between different Plugins. + The Plugin will react on the three mouse events (MouseDown, MouseMove and MouseUp) + in the way that it allows the user to drag the items with the right mouse button + down. While hovering around the plugin will signalize the user the possible + drag option if the mouse is not down. +} + unit uDragColoredItemPlugin; {$mode ObjFPC}{$H+} @@ -18,6 +26,9 @@ type FCurrentCoord : TRealPoint; FRectSize : Integer; FColor : TColor; + FLastPointer : Boolean; + FMouseCursor : TCursor; + FShowCaption : Boolean; function IsAtMousePosition(const X,Y: Integer) : Boolean; procedure SetRectSize(Value : Integer); protected @@ -32,7 +43,9 @@ type AWheelDelta: Integer; AMousePos: TPoint; var Handled: Boolean); override; public property Color : TColor read FColor write FColor; + property MouseCursor : TCursor read FMouseCursor write FMouseCursor; property RectSize : Integer read FRectSize write SetRectSize; + property ShowCaption : Boolean read FShowCaption write FShowCaption; constructor Create(AOwner: TComponent); override; end; @@ -98,55 +111,69 @@ begin w2 := (FRectSize div 2); MapView.Canvas.Rectangle(ptCurrentScreen.X-w2,ptCurrentScreen.Y-w2, ptCurrentScreen.X+w2,ptCurrentScreen.Y+w2); - s := Format('Index: %d',[Index]); - MapView.Canvas.TextOut(ptCurrentScreen.X+w2, ptCurrentScreen.Y+w2, s); + if FShowCaption then + begin + s := Format('Index: %d',[Index]); + MapView.Canvas.TextOut(ptCurrentScreen.X+w2, ptCurrentScreen.Y+w2, s); + end; end; procedure TDragColoredItemPlugin.MouseMove(AMapView: TMapView; AShift: TShiftState; X, Y: Integer; var Handled: Boolean); begin + // Three different things to catch + // 1. In mouse down mode, drag the item + // 2. In mouse up mode + // 2.a) ensure that the mouse button is globally up + // 2.b) if inside the rectangle change the MouseCursor + // 2.c) if outside release the mouse pointer, but only if we changed him before + if FMouseDown then - begin - FCurrentCoord := MapView.ScreenToLatLon(Point(X,Y)); - MapView.Invalidate; - Handled := True; - MapView.Cursor := crDefault; + begin // we have the mouse down + FCurrentCoord := MapView.ScreenToLatLon(Point(X,Y)); // Move the rectangle + Handled := True; // prevent others from also operate + MapView.Invalidate; // init the new painting end - else if not Handled then - begin + else if (not Handled) and + (PluginManager.MouseButtonDown[MapView] = []) then + begin // the mouse is not down (any other operation) and the moving is not consumed if IsAtMousePosition(X,Y) then - begin - MapView.Cursor := crHandPoint; - Handled := True; + begin // inside the rectangle + MapView.Cursor := FMouseCursor; // change the cursor + FLastPointer := True; // remember we do so + Handled := True; // prevent others from changing end - else - MapView.Cursor := crDefault; + else if FLastPointer then + begin // outside the rectangle + MapView.Cursor := crDefault; // return to default cursor (might be overwirtten by the following plugins) + FLastPointer := False; // reset the flag + end; end; end; procedure TDragColoredItemPlugin.MouseUp(AMapView: TMapView; Button: TMouseButton; Shift: TShiftState; X, Y: Integer; var Handled: Boolean); begin - if Button <> mbRight then Exit; - if FMouseDown then - MapView.Invalidate; // This will remove the two circles and the text - FMouseDown := False; - MapView.Cursor := crDefault; - Handled := True; + if Button <> mbRight then Exit; // We react only on the right mouse button + if FMouseDown then // if we are in mouse down mode... + begin + FMouseDown := False; // ... we have to release the mode + MapView.Cursor := crDefault; // return to default + Handled := True; // we consumed the event (this will not change the behavior) + end; end; procedure TDragColoredItemPlugin.MouseDown(AMapView: TMapView; Button: TMouseButton; Shift: TShiftState; X, Y: Integer; var Handled: Boolean ); begin - if Button <> mbRight then Exit; - if Handled then Exit; - if IsAtMousePosition(X,Y) then + if Button <> mbRight then Exit; // We react only on the right mouse button + if Handled then Exit; // if the mouse down button has been consumed, nothing further to do + if IsAtMousePosition(X,Y) then // check the coords begin - FMouseDown := True; - FCurrentCoord := MapView.ScreenToLatLon(Point(X,Y)); - Handled := True; - MapView.Invalidate; + FMouseDown := True; // remember that we are in MouseDown mode + FCurrentCoord := MapView.ScreenToLatLon(Point(X,Y)); // store the current position + Handled := True; // prevent later plugins to consume this event end; end; diff --git a/components/lazmapviewer/source/addons/plugins/areaselection/mvareaselectionplugin.pas b/components/lazmapviewer/source/addons/plugins/areaselection/mvareaselectionplugin.pas index bb1ff3b0e..5e1d20354 100644 --- a/components/lazmapviewer/source/addons/plugins/areaselection/mvareaselectionplugin.pas +++ b/components/lazmapviewer/source/addons/plugins/areaselection/mvareaselectionplugin.pas @@ -91,7 +91,9 @@ type type TSelectedAreaChangingEvent = procedure (Sender : TObject; ANewArea : TRealArea; var Allow : Boolean) of Object; - + TAreaSelectionCaptionPosition = (ascpLeftTop, ascpCenterTop, ascpRightTop, ascpCenter, ascpLeftBottom, + ascpCenterBottom, ascpRightBottom); + { TAreaSelectionPlugin } TAreaSelectionPlugin = class(TMvDrawPlugin) private @@ -105,24 +107,24 @@ type FMouseButton : TMouseButton; FShifterXInverseMode : Boolean; // Two Flags to ease the user interface for the flat and cylindrical world FShifterYInverseMode : Boolean; - FSelectedArea : TRealArea; + FSelectedArea: TMapRealArea; FLastMouseMoveHandled : Boolean; - FPenColor : TColor; - FPenStyle : TPenStyle; - FPenWidth : Integer; FAreaInflation : Integer; FMouseMapCoords : TRealPoint; + FSelectedAreaHitEvent : TNotifyEvent; + FSelectedAreaBeginChangeEvent : TNotifyEvent; FSelectedAreaChangedEvent : TNotifyEvent; FSelectedAreaChangingEvent : TSelectedAreaChangingEvent; + FCaption : String; + FCaptionPosition : TAreaSelectionCaptionPosition; function GetCurrentItem : TMouseHitItem; function GetItemsCount: Integer; function GetItems(AIndex : Integer) : TMouseHitItem; + procedure SetCaption(Value : String); + procedure SetCaptionPosition(Value : TAreaSelectionCaptionPosition); procedure SetMouseButton(AValue: TMouseButton); - procedure SetPenColor(Value : TColor); - procedure SetPenWidth(Value : Integer); - procedure SetPenStyle(Value : TPenStyle); procedure SetSensitiveAreaInflation(Value : Integer); - procedure SetSelectedArea(Value : TRealArea); + procedure SetSelectedArea(Value: TMapRealArea); protected procedure AddSelectionArea(const ARect: TRect; const AInflate: Integer); procedure AddSelectionAreaEx(const ARect: TRect; const ARectParts: array of Integer; @@ -142,7 +144,6 @@ type property Items[AIndex : Integer] : TMouseHitItem read GetItems; { property CurrentItem returns either the Item where the Mouse is down or the one where the mouse is hovering above } property CurrentItem : TMouseHitItem read GetCurrentItem; - public constructor Create(AOwner: TComponent); override; destructor Destroy;override; @@ -151,14 +152,19 @@ type { procedure SetupRectShifter creates the mouse shifting items, must be called if the display changes needed e.g.if the size of the MapView is altered} procedure SetupRectShifter; - - property SelectedArea : TRealArea read FSelectedArea write SetSelectedArea; published + property Caption : String read FCaption write SetCaption; + property CaptionPosition : TAreaSelectionCaptionPosition read FCaptionPosition write SetCaptionPosition; property MouseButton: TMouseButton read FMouseButton write SetMouseButton default mbLeft; + property SelectedArea: TMapRealArea read FSelectedArea write SetSelectedArea; property SensitiveAreaInflation: Integer read FAreaInflation write SetSensitiveAreaInflation default DEFAULT_SENSITIVE_AREA_INFLATION; + property OnSelectedAreaHit : TNotifyEvent read FSelectedAreaHitEvent write FSelectedAreaHitEvent; + property OnSelectedAreaBeginChange : TNotifyEvent read FSelectedAreaBeginChangeEvent write FSelectedAreaBeginChangeEvent; property OnSelectedAreaChanged: TNotifyEvent read FSelectedAreaChangedEvent write FSelectedAreaChangedEvent; property OnSelectedAreaChanging: TSelectedAreaChangingEvent read FSelectedAreaChangingEvent write FSelectedAreaChangingEvent; - + property BackgroundColor default clNone; + //property BackgroundOpacity; // cannot be used because we paint in the canvas rather than the drawing engine + property Font; property Pen; end; @@ -306,11 +312,16 @@ constructor TAreaSelectionPlugin.Create(AOwner: TComponent); begin inherited; FMouseHitItems := TObjectList.Create(True); - FSelectedArea.Init(-100,50,100,-50); -// FSelectedArea.Init(0,0,0,0); + + FSelectedArea := TMapRealArea.Create(Self); + FSelectedArea.Area.Init(-100,50,100,-50); + FSelectedArea.OnChange := @Changed; + Pen.Color := DEFAULT_PEN_COLOR; Pen.Width := DEFAULT_PEN_WIDTH; Pen.Style := DEFAULT_PEN_STYLE; + BackgroundColor := clNone; + FAreaInflation := DEFAULT_SENSITIVE_AREA_INFLATION; end; @@ -342,8 +353,7 @@ begin lItem := TMouseHitItem(FMouseHitItems[i]); if lItem.ItemHit then begin - if (not Assigned(Result)) or - (Result.ZOrder < lItem.ZOrder) then + if (not Assigned(Result)) or (Result.ZOrder < lItem.ZOrder) then Result := lItem; end; end; @@ -359,42 +369,31 @@ begin Result := TMouseHitItem(FMouseHitItems[AIndex]); end; +procedure TAreaSelectionPlugin.SetCaption(Value: String); +begin + if FCaption <> Value then + begin + FCaption := Value; + Update; + end; +end; + +procedure TAreaSelectionPlugin.SetCaptionPosition( + Value: TAreaSelectionCaptionPosition); +begin + if FCaptionPosition <> Value then + begin + FCaptionPosition := Value; + Update; + end; +end; + procedure TAreaSelectionPlugin.SetMouseButton(AValue: TMouseButton); begin if FMouseButton=AValue then Exit; FMouseButton:=AValue; end; -procedure TAreaSelectionPlugin.SetPenColor(Value: TColor); -begin - if FPenColor <> Value then - begin - FPenColor := Value; - if Assigned(MapView) then - MapView.Invalidate; - end; -end; - -procedure TAreaSelectionPlugin.SetPenWidth(Value: Integer); -begin - if FPenWidth <> Value then - begin - FPenWidth := Value; - if Assigned(MapView) then - MapView.Invalidate; - end; -end; - -procedure TAreaSelectionPlugin.SetPenStyle(Value: TPenStyle); -begin - if FPenStyle <> Value then - begin - FPenStyle := Value; - if Assigned(MapView) then - MapView.Invalidate; - end; -end; - procedure TAreaSelectionPlugin.SetSensitiveAreaInflation(Value: Integer); begin if FAreaInflation <> Value then @@ -405,11 +404,12 @@ begin end; end; -procedure TAreaSelectionPlugin.SetSelectedArea(Value: TRealArea); +procedure TAreaSelectionPlugin.SetSelectedArea(Value: TMapRealArea); begin - if not FSelectedArea.Equal(Value) then + if not FSelectedArea.Area.Equal(Value.Area) then begin - FSelectedArea.Init(Value.TopLeft, Value.BottomRight); + FSelectedArea.Area := Value.Area; + if not Assigned(MapView) then Exit; MapView.Invalidate; SetupRectShifter; end; @@ -605,12 +605,57 @@ end; procedure TAreaSelectionPlugin.AfterPaint(AMapView: TMapView; var Handled: Boolean); - procedure IncRecToMinSize(var ARect : TRect); + procedure DrawRectangle(ARect : TRect); begin - if Abs(ARect.Left-ARect.Right) < FPenWidth then - Inc(ARect.Right,FPenWidth); - if Abs(ARect.Top-ARect.Bottom) < FPenWidth then - Inc(ARect.Bottom,FPenWidth); + if Abs(ARect.Left-ARect.Right) < Pen.Width then + Inc(ARect.Right,Pen.Width); + if Abs(ARect.Top-ARect.Bottom) < Pen.Width then + Inc(ARect.Bottom,Pen.Width); + + if ARect.Top > 0 then + MapView.Canvas.Line(ARect.Left,ARect.Top,ARect.Right,ARect.Top); + if ARect.Bottom < MapView.Height then + MapView.Canvas.Line(ARect.Left,ARect.Bottom,ARect.Right,ARect.Bottom); + if ARect.Left > 0 then + MapView.Canvas.Line(ARect.Left,ARect.Top,ARect.Left,ARect.Bottom); + if ARect.Right < MapView.Width then + MapView.Canvas.Line(ARect.Right,ARect.Top,ARect.Right,ARect.Bottom); + end; + + procedure PaintCaption(ARect : TRect); + var + oldFont : TFont; + sz : TSize; + dx,dy : Integer; + w, h : Integer; + pw : Integer; + begin + pw := Pen.Width; + MapView.Canvas.Font.Assign(Font); + sz := MapView.Canvas.TextExtent(FCaption); + w := ARect.Right - ARect.Left; + h := ARect.Bottom - ARect.Top; + + // Calculate left/top corner of total text + dx := ARect.Left; + case FCaptionPosition of + ascpLeftTop, ascpLeftBottom : + dx := dx + pw div 2 + 2 ; + ascpCenterTop, ascpCenter, ascpCenterBottom : + dx := dx + (w - sz.cx) div 2; + ascpRightTop, ascpRightBottom: + dx := dx + w - sz.cx - pw div 2 - 1; + end; + dy := ARect.Top; + case FCaptionPosition of + ascpLeftTop, ascpCenterTop, ascpRightTop : + dy := dy + pw div 2 + 1; + ascpCenter : + dy := dy + (h - sz.cy) div 2; + ascpLeftBottom, ascpCenterBottom, ascpRightBottom: + dy := dy + h - sz.cy - pw div 2; + end; + AMapView.Canvas.TextOut(dx,dy,FCaption) end; var @@ -621,13 +666,15 @@ var lRect : TRect; ptArr : TPointArray; pt : TPoint; + sl : TStringList; + s : String; begin Unused(AMapView, Handled); - topLeftPt := MapView.LatLonToScreen(FSelectedArea.TopLeft.Lat, FSelectedArea.TopLeft.Lon); + topLeftPt := MapView.LatLonToScreen(FSelectedArea.North, FSelectedArea.West); lRect.Top := topLeftPt.Y; lRect.Left := topLeftPt.X; - bottomRightPt := MapView.LatLonToScreen(FSelectedArea.BottomRight.Lat, FSelectedArea.BottomRight.Lon); + bottomRightPt := MapView.LatLonToScreen(FSelectedArea.South, FSelectedArea.East); lRect.Bottom := bottomRightPt.Y; lRect.Right := bottomRightPt.X; mapw := mvGeoMath.ZoomFactor(MapView.Zoom) * TileSize.CX; @@ -635,43 +682,55 @@ begin lRect.Left := lRect.Left - mapw; rectW := lRect.Right-lRect.Left; - MapView.Canvas.Brush.Style := bsClear; + if BackgroundColor = clNone then + MapView.Canvas.Brush.Style := bsClear + else + MapView.Canvas.Brush.Color := ColorToRGB(BackgroundColor); MapView.Canvas.Pen.Assign(Pen); - // Duplicate the rectangles to the dimmed doubled picture areas - ptArr := MapView.CyclicPointsOf(topLeftPt); - for pt in ptArr do - begin - r0.Left := pt.X; - r0.Top := lRect.Top; - r0.Right := pt.X+rectW; - if r0.Right > MapView.Width+FPenWidth then - r0.Right := MapView.Width+FPenWidth; - r0.Bottom := lRect.Bottom; - if r0.Bottom > MapView.Height+FPenWidth then - r0.Bottom := MapView.Height+FPenWidth; - IncRecToMinSize(r0); - MapView.Canvas.Rectangle(r0); - end; + sl := TStringList.Create; + try + sl.Sorted := True; + sl.Duplicates := dupIgnore; - // Catch the case of the missing left rectangle (draw some rectangles again) - ptArr := MapView.CyclicPointsOf(bottomRightPt); - for pt in ptArr do - begin - r0.Left := pt.X-rectW; - if r0.Left < -FPenWidth then - r0.Left := -FPenWidth; - r0.Top := lRect.Top; - if r0.Top < -FPenWidth then - r0.Top := -FPenWidth; - r0.Right := pt.X; - r0.Bottom := lRect.Bottom; - if r0.Left = r0.Right then - Inc(r0.Right); - if r0.Top = r0.Bottom then - Inc(r0.Bottom); - IncRecToMinSize(r0); - MapView.Canvas.Rectangle(r0); + // Paint rectangle and caption, in the cyclic world multiple times + ptArr := MapView.CyclicPointsOf(topLeftPt); + for pt in ptArr do + begin + r0.Left := pt.X; + // Avoid painting duplicate rectangles and captions + s := IntToStr(r0.Left); + if sl.IndexOf(s) >= 0 then Continue; + sl.Add(s); + + r0.Top := lRect.Top; + r0.Right := pt.X+rectW; + r0.Bottom := lRect.Bottom; + DrawRectangle(r0); + if Length(FCaption) > 0 then + PaintCaption(r0); + end; + + // Catch the case of the missing left rectangle and caption, + // but ignore the rectangle and captions already painted + ptArr := MapView.CyclicPointsOf(bottomRightPt); + for pt in ptArr do + begin + r0.Left := pt.X-rectW; + // Avoid painting duplicate rectangles and captions + s := IntToStr(r0.Left); + if sl.IndexOf(s) >= 0 then Continue; + sl.Add(s); + + r0.Top := lRect.Top; + r0.Right := pt.X; + r0.Bottom := lRect.Bottom; + DrawRectangle(r0); + if Length(FCaption) > 0 then + PaintCaption(r0); + end; + finally + sl.Free; end; end; @@ -769,11 +828,17 @@ var lHitItem : TMouseHitItem; ptR : TRealPoint; chgAllowed : Boolean; -var i : Integer; lItem : TMouseHitItem; begin if Handled then Exit; + + // Check if the GlobalMouseDown Flag is down, but the current item not. + // This means, that some other plugin catched the MouseDown, but not this one + if (PluginManager.MouseButtonDown[AMapView] <> []) and + Assigned(CurrentItem) and + (not CurrentItem.FMouseDownFlag) then Exit; + for i := 0 to ItemsCount-1 do begin lItem := TMouseHitItem(FMouseHitItems[i]); @@ -781,17 +846,25 @@ begin end; lHitItem := CurrentItem; Handled := Assigned(lHitItem); + // Here we have to act carefully, since we should not change the Mouse Pointer // if we not had set him. if (not Handled) and FLastMouseMoveHandled then MapView.Cursor := crDefault; // no hit, but hit previously, set the default cursor + + // fire the hit event if not hit before and not mouse down + if Handled and (not FLastMouseMoveHandled) and + (PluginManager.MouseButtonDown[AMapView] = []) and + (not lHitItem.MouseDownFlag) and Assigned(FSelectedAreaHitEvent) then + FSelectedAreaHitEvent(Self); + FLastMouseMoveHandled := Handled; if not Handled then Exit; // lHitItem will be assigned if one item is selected. MapView.Cursor := lHitItem.Cursor; // Set the cursor to the hit items kind if lHitItem.MouseDownFlag then // if the mouse is down begin - lRect0.Init(FSelectedArea.TopLeft,FSelectedArea.BottomRight); + lRect0 := FSelectedArea.Area; // Invert the axis to ease calculation lRect0.TopLeft.Lat := -lRect0.TopLeft.Lat; lRect0.BottomRight.Lat := -lRect0.BottomRight.Lat; @@ -875,7 +948,7 @@ begin if Assigned(FSelectedAreaChangingEvent) then FSelectedAreaChangingEvent(Self, lRect0, chgAllowed); if chgAllowed then - FSelectedArea.Init(lRect0.TopLeft, lRect0.BottomRight); + FSelectedArea.Area := lRect0; MapView.Invalidate; // redraw the map end; end; @@ -883,21 +956,16 @@ end; procedure TAreaSelectionPlugin.MouseUp(AMapView: TMapView; Button: TMouseButton; Shift: TShiftState; X, Y: Integer; var Handled: Boolean); var - i : Integer; - lItem : TMouseHitItem; + lMouseWasDown : Boolean; begin Unused(AMapView); - - if Handled then Exit; - if Button <> FMouseButton then Exit; - for i := 0 to ItemsCount-1 do - begin - lItem := TMouseHitItem(FMouseHitItems[i]); - lItem.OnMouseUp(Shift,X,Y); - end; + // Caution the order of the following statemens are crucial + if Button <> FMouseButton then Exit; // Exit if not the defined button + lMouseWasDown := Assigned(CurrentItem) and CurrentItem.FMouseDownFlag; // Save the information if we hold the button SetupRectShifter; // Setup the HelperClass for the current setting - Handled := True; - if Assigned(FSelectedAreaChangedEvent) then + if Handled then Exit; // if already handled by an other plugin then exit + Handled := lMouseWasDown; // set handled to true, if we holded the button + if lMouseWasDown and Assigned(FSelectedAreaChangedEvent) then // notify if we holded the button FSelectedAreaChangedEvent(Self); end; @@ -909,9 +977,9 @@ var lItem, lCurrItem : TMouseHitItem; begin Unused(AMapView); - - if Handled then Exit; if Button <> FMouseButton then Exit; + if Handled then Exit; + // Forward the MouseDown-Event to all Items for i := 0 to ItemsCount-1 do begin @@ -933,6 +1001,9 @@ begin if lItem.MouseDownFlag then lItem.FMouseDownFlag := False; end; + + if Assigned(FSelectedAreaBeginChangeEvent) then + FSelectedAreaBeginChangeEvent(Self); end; // Reset the inverters FShifterXInverseMode := False; @@ -981,10 +1052,10 @@ var begin Clear; - topLeftPt := MapView.LatLonToScreen(FSelectedArea.TopLeft.Lat, FSelectedArea.TopLeft.Lon); + topLeftPt := MapView.LatLonToScreen(FSelectedArea.North, FSelectedArea.West); lRect.Top := topLeftPt.Y; lRect.Left := topLeftPt.X; - bottomRightPt := MapView.LatLonToScreen(FSelectedArea.BottomRight.Lat, FSelectedArea.BottomRight.Lon); + bottomRightPt := MapView.LatLonToScreen(FSelectedArea.South, FSelectedArea.East); lRect.Bottom := bottomRightPt.Y; lRect.Right := bottomRightPt.X; mapw := mvGeoMath.ZoomFactor(MapView.Zoom) * TileSize.CX; diff --git a/components/lazmapviewer/source/addons/plugins/spreadmarkers/mvspreadmarker_plugin.pas b/components/lazmapviewer/source/addons/plugins/spreadmarkers/mvspreadmarker_plugin.pas index 557b102e2..3fc7a727b 100644 --- a/components/lazmapviewer/source/addons/plugins/spreadmarkers/mvspreadmarker_plugin.pas +++ b/components/lazmapviewer/source/addons/plugins/spreadmarkers/mvspreadmarker_plugin.pas @@ -39,7 +39,6 @@ type PSpreadMarkerData = ^TSpreadMarkerData; TSpreadMarkerData = record FLastMouseX, FLastMouseY : Integer; -// FMouseButtonIsDown : Boolean; FSpreadModeActive : Boolean; FSpreadMarkerArr : TSpreadMarkerArr; end; @@ -139,12 +138,8 @@ type procedure SetLinePenWidth(Value : Integer); protected -// procedure MouseDown(AMapView: TMapView; Button: TMouseButton; Shift: TShiftState; -// X, Y: Integer; var Handled: Boolean); override; procedure MouseMove(AMapView: TMapView; {%H-}AShift: TShiftState; X,Y: Integer; var {%H-}Handled: Boolean); override; -// procedure MouseUp(AMapView: TMapView; Button: TMouseButton; Shift: TShiftState; -// X, Y: Integer; var Handled: Boolean); override; procedure ZoomChange(AMapView: TMapView; var {%H-}Handled: Boolean); override; procedure AfterPaint(AMapView: TMapView; var Handled: Boolean); override; procedure AfterDrawObjects(AMapView: TMapView; var {%H-}Handled: Boolean); override; @@ -375,11 +370,20 @@ procedure TSpreadMarkerPlugin.OnMouseInactive(Sender: TObject); var sd : TSpreadMarkerPluginData; pd : PSpreadMarkerData; + mb : TMouseButtons; begin if not (Sender is TInactivityAlarmTimer) then Exit; sd := GetPluginDataFromTimer(TInactivityAlarmTimer(Sender)); if not Assigned(sd) then Exit; pd := PSpreadMarkerData(sd.GetDataPtr); + + mb := PluginManager.MouseButtonDown[sd.MapView]; + if mb <> [] then + begin + TInactivityAlarmTimer(Sender).QuitInactivityAlarm; + Exit; + end; + if pd^.FSpreadModeActive then sd.LeaveSpreadMode else @@ -401,38 +405,7 @@ begin FActiveLayersEx[8] := (smaLayer8 in Value); FActiveLayersEx[9] := (smaLayer9 in Value); end; -{ -procedure TSpreadMarkerPlugin.MouseDown(AMapView: TMapView; - Button: TMouseButton; Shift: TShiftState; X, Y: Integer; var Handled: Boolean - ); -var - sd : TSpreadMarkerPluginData; - pd : PSpreadMarkerData; - ld : TSpreadMarkerData; -begin - sd := TSpreadMarkerPluginData(MapViewDataItem[AMapView]); - if not Assigned(sd) then - begin - FillChar(ld,SizeOf(ld),0); - SetMapViewData(AMapView,ld,SizeOf(ld)); - end; - sd := TSpreadMarkerPluginData(MapViewDataItem[AMapView]); - if not Assigned(sd) then Exit; - pd := PSpreadMarkerData(sd.GetDataPtr); - // Store the last Mouse position for later use - pd^.FLastMouseX := X; - pd^.FLastMouseY := Y; -(* - if pd^.FSpreadModeActive then - begin - sd.LeaveSpreadMode; - pd^.FMouseButtonIsDown := True; - Handled := True; - end; -*) -end; -} procedure TSpreadMarkerPlugin.MouseMove(AMapView: TMapView; AShift: TShiftState; X, Y: Integer; var Handled: Boolean); var @@ -454,36 +427,11 @@ begin sd.FMouseInactivity.AliveTrigger // Trigger else sd.FMouseInactivity.Active := True; // Activate (will set the timer) -// else if (not pd^.FMouseButtonIsDown) then -// sd.FMouseInactivity.Active := True; // Activate (will set the timer) // Store the last Mouse position for later use pd^.FLastMouseX := X; pd^.FLastMouseY := Y; end; -{ -procedure TSpreadMarkerPlugin.MouseUp(AMapView: TMapView; Button: TMouseButton; - Shift: TShiftState; X, Y: Integer; var Handled: Boolean); -var - sd : TSpreadMarkerPluginData; - pd : PSpreadMarkerData; - ld : TSpreadMarkerData; -begin - sd := TSpreadMarkerPluginData(MapViewDataItem[AMapView]); - if not Assigned(sd) then - begin - FillChar(ld,SizeOf(ld),0); - SetMapViewData(AMapView,ld,SizeOf(ld)); - end; - sd := TSpreadMarkerPluginData(MapViewDataItem[AMapView]); - if not Assigned(sd) then Exit; - pd := PSpreadMarkerData(sd.GetDataPtr); - // Store the last Mouse position for later use - pd^.FLastMouseX := X; - pd^.FLastMouseY := Y; -// pd^.FMouseButtonIsDown := False; - Handled := True; -end; -} + procedure TSpreadMarkerPlugin.ZoomChange(AMapView: TMapView; var Handled: Boolean); var diff --git a/components/lazmapviewer/source/mvmapviewer.pas b/components/lazmapviewer/source/mvmapviewer.pas index 0ce86403c..271cf4b3d 100644 --- a/components/lazmapviewer/source/mvmapviewer.pas +++ b/components/lazmapviewer/source/mvmapviewer.pas @@ -219,13 +219,15 @@ type TMapLatLonElement = class(TPersistent) private FView: TMapView; + FOnChange: TNotifyEvent; function GetLatLonInDMS: Boolean; protected - function GetOwner: TPersistent; override; +// function GetOwner: TPersistent; override; procedure Update; virtual; public - constructor Create(AView: TMapView); + constructor Create(AOwner: TComponent); property LatLonInDMS: Boolean read GetLatLonInDMS; + property OnChange: TNotifyEvent read FOnChange write FOnChange; end; { TMapRealPoint } @@ -1858,23 +1860,25 @@ end; { TMapLatLonElement } -constructor TMapLatLonElement.Create(AView: TMapView); +constructor TMapLatLonElement.Create(AOwner: TComponent); begin - FView := AView; + if AOwner is TMapView then + FView := TMapView(AOwner); end; function TMapLatLonElement.GetLatLonInDMS: Boolean; begin Result := Assigned(FView) and (mvoLatLonInDMS in FView.Options); end; - +{ function TMapLatLonElement.GetOwner: TPersistent; begin Result := FView; end; - +} procedure TMapLatLonElement.Update; begin + if Assigned(FOnChange) then FOnChange(self); end; @@ -1965,8 +1969,11 @@ procedure TMapCenter.Update; var R: TRealPoint; begin - R.InitLatLon(FLatitude, FLongitude); - FView.SetCenter(R); + if Assigned(FView) then + begin + R.InitLatLon(FLatitude, FLongitude); + FView.SetCenter(R); + end; end; { TMapLayer } @@ -2696,7 +2703,6 @@ begin FPluginManager := AValue; - //FActiveToolIndex := -1; if FPluginManager <> nil then begin FreeNotification(FPluginManager); diff --git a/components/lazmapviewer/source/mvplugincommon.pas b/components/lazmapviewer/source/mvplugincommon.pas index f2c724744..6b857d55c 100644 --- a/components/lazmapviewer/source/mvplugincommon.pas +++ b/components/lazmapviewer/source/mvplugincommon.pas @@ -7,7 +7,8 @@ interface uses Classes, SysUtils, StrUtils, Contnrs, Math, LazLoggerBase, Graphics, Controls, Dialogs, - mvMapViewer, mvTypes, mvGpsObj, mvClassRegistration, mvDrawingEngine; + mvMapViewer, mvTypes, mvGpsObj, mvClassRegistration, mvDrawingEngine, + mvMapProvider, mvCache; type TMvCustomPlugin = class; @@ -15,6 +16,7 @@ type EMvPluginException = class(EMapViewerException); + { TMvIndexedComponent } TMvIndexedComponent = class(TComponent) @@ -26,6 +28,7 @@ type property Index: Integer read GetIndex write SetIndex; end; + { TMvIndexedComponentList } TMvIndexedComponentList = class(TFPList) @@ -233,6 +236,11 @@ type property Items[AIndex: Integer]: TMvCustomPlugin read GetItem write SetItem; default; end; + TMouseButtons = set of TMouseButton; + TMapViewMouseButtons = record + MapView: TMapView; + MouseButtons: TMouseButtons; + end; { TMvPluginManager } @@ -240,12 +248,14 @@ type private FPluginList: TMvPluginList; FMapList: TFPList; - FMouseButtonDown: array[TMouseButton] of Boolean; + FMouseButtonDown: array of TMapViewMouseButtons; function GetCount: Integer; function GetItems(AIndex: Integer): TMvCustomPlugin; function GetMapViewCount: Integer; function GetMapViews(AIndex: Integer): TMapView; - function GetMouseButtonDown(AIndex: TMouseButton): Boolean; + function GetMouseButtonDown(AMapView: TMapView): TMouseButtons; + procedure AddUpdateMouseButton(const AMapView: TMapView; const AMouseButton: TMouseButton; const APressed : Boolean); + procedure RemoveMouseButton(const AMapView: TMapView); protected procedure AddMapView(AMapView: TMapView); override; function HandlePlugin(APlugin: TMvCustomPlugin; AMapView: TMapView): Boolean; @@ -279,7 +289,6 @@ type function Resize(AMapView: TMapView): Boolean; override; function ZoomChange(AMapView: TMapView): Boolean; override; function ZoomChanging(AMapView: TMapView; NewZoom: Integer; var Allow: Boolean): Boolean; override; - public constructor Create(AOwner: TComponent); override; destructor Destroy; override; @@ -291,7 +300,7 @@ type property Items[AIndex: Integer]: TMvCustomPlugin read GetItems; default; property MapViews[AIndex: Integer]: TMapView read GetMapViews; property MapViewCount: Integer read GetMapViewCount; - property MouseButtonDown[AIndex: TMouseButton]: Boolean read GetMouseButtonDown; + property MouseButtonDown[AMapView: TMapView]: TMouseButtons read GetMouseButtonDown; published property PluginList: TMvPluginList read FPluginList; end; @@ -1144,9 +1153,61 @@ begin Result := TMapView(FMapList[AIndex]); end; -function TMvPluginManager.GetMouseButtonDown(AIndex: TMouseButton): Boolean; +function TMvPluginManager.GetMouseButtonDown(AMapView: TMapView): TMouseButtons; +var + i : Integer; begin - Result := FMouseButtonDown[AIndex]; + Result := []; + for i := 0 to High(FMouseButtonDown) do + if FMouseButtonDown[i].MapView = AMapView then + Exit(FMouseButtonDown[i].MouseButtons) +end; + +procedure TMvPluginManager.AddUpdateMouseButton(const AMapView: TMapView; + const AMouseButton: TMouseButton; const APressed: Boolean); +var + i : Integer; + ndx : Integer; +begin + ndx := -1; + for i := 0 to High(FMouseButtonDown) do + begin + if FMouseButtonDown[i].MapView = AMapView then + begin + ndx := i; + Break; + end; + end; + if ndx < 0 then + begin + ndx := Length(FMouseButtonDown); + SetLength(FMouseButtonDown,ndx+1); + FMouseButtonDown[ndx].MapView := AMapView; + end; + if APressed then + Include(FMouseButtonDown[ndx].MouseButtons, AMouseButton) + else + Exclude(FMouseButtonDown[ndx].MouseButtons, AMouseButton); +end; + +procedure TMvPluginManager.RemoveMouseButton(const AMapView: TMapView); +var + i : Integer; + ndx : Integer; +begin + ndx := -1; + for i := 0 to High(FMouseButtonDown) do + begin + if FMouseButtonDown[i].MapView = AMapView then + begin + ndx := i; + Break; + end; + end; + if ndx < 0 then Exit; + for i := ndx+1 to High(FMouseButtonDown) do + FMouseButtonDown[i-1] := FMouseButtonDown[i]; + SetLength(FMouseButtonDown,High(FMouseButtonDown)); end; function TMvPluginManager.GPSItemsModified(AMapView: TMapView; @@ -1184,7 +1245,7 @@ var i: Integer; plugin: TMvCustomPlugin; begin - FMouseButtonDown[AButton] := True; + AddUpdateMouseButton(AMapView,AButton,True); Result := false; for i := FPluginList.Count-1 downto 0 do begin @@ -1244,7 +1305,7 @@ var plugin: TMvCustomPlugin; begin Result := false; - FMouseButtonDown[AButton] := false; + AddUpdateMouseButton(AMapView, AButton, False); for i := FPluginList.Count-1 downto 0 do begin plugin := Items[i]; @@ -1295,6 +1356,7 @@ end; procedure TMvPluginManager.RemoveMapView(AMapView: TMapView); begin + RemoveMouseButton(AMapView); FMapList.Remove(AMapView); end;