Category: Firemonkey

TMS FNC Maps v2.1: Introducing OverlayViews



The new TMS FNC Maps update includes support for OverlayViews. This is a heavily improved equivalent of the Marker Labels functionality in TMS VCL WebGMaps and TMS FMX WebGMaps. OverlayViews are a Google Maps API specific functionality and therefore currently only available in TTMSFNCGoogleMaps. OverlayViews can be positioned anywhere on the map and support HTML tags.

3 ways to use OverlayViews

1. Connected to a Marker

The OverlayView is automatically displayed below an existing Marker and functions as a Marker Label. 

In code, adding a call to AddOverlayView on an existing Marker with the text that goes in to the OverlayView as a parameter value is all that is needed.

var
  m: TTMSFNCGoogleMapsMarker;
begin
  TMSFNCGoogleMaps1.BeginUpdate;

  m := TTMSFNCGoogleMapsMarker(TMSFNCGoogleMaps1.AddMarker(TMSFNCGoogleMaps1.Options.DefaultLatitude, TMSFNCGoogleMaps1.Options.DefaultLongitude));
  m.AddOverlayView('Hello <font color="red">World</font>!<br>This is an <b>OverlayView</b>.');

  TMSFNCGoogleMaps1.EndUpdate;

2. Positioned at a fixed Coordinate

The OverlayView is positioned at a fixed coordinate on the map. The size of the OverlayView remains fixed regardless of the map’s zoom level.

In code, setting the Latitude and Longitude coordinates will position the OverlayView at that exact location on the map.

var
  ov: TTMSFNCGoogleMapsOverlayView;
begin
  TMSFNCGoogleMaps1.BeginUpdate;

  ov := TMSFNCGoogleMaps1.AddOverlayView;
  ov.CoordinatePosition := cpCenterCenter;
  ov.Coordinate.Latitude := TMSFNCGoogleMaps1.Options.DefaultLatitude;
  ov.Coordinate.Longitude := TMSFNCGoogleMaps1.Options.DefaultLongitude;
  ov.Padding := 5;
  ov.Width := 500;

  ov.Text := '' +
      '<h1 id="firstHeading" class="firstHeading">Uluru</h1>'+
      '<div id="bodyContent">'+
      '<p><b>Uluru</b>, also referred to as <b>Ayers Rock</b>, is a large ' +
      'sandstone rock formation in the southern part of the '+
      'Northern Territory, central Australia. It lies 335 km (208 mi) '+
      'south west of the nearest large town, Alice Springs; 450 km '+
      '(280 mi) by road. Kata Tjuta and Uluru are the two major '+
      'features of the Uluru - Kata Tjuta National Park. Uluru is '+
      'sacred to the Pitjantjatjara and Yankunytjatjara, the '+
      'Aboriginal people of the area. It has many springs, waterholes, '+
      'rock caves and ancient paintings. Uluru is listed as a World '+
      'Heritage Site.</p>'+
      '<img src="https://www.tripsavvy.com/thmb/XHi4Ec428VJFk_bsvNtv6fx5-bE=/2000x1500/filters:fill(auto,1)/GettyImages-675746097-5a8b94a427364afc89f054f71ceda86f.jpg" width="200"></img>' +
      '<p>Attribution: Uluru, <a target="_blank" href="https://en.wikipedia.org/w/index.php?title=Uluru&oldid=297882194">'+
      'https://en.wikipedia.org/w/index.php?title=Uluru</a> '+
      '(last visited June 22, 2021).</p>'+
      '</div>';

  TMSFNCGoogleMaps1.EndUpdate;

3. Positioned between preset Bounds

The OverlayView is positioned between fixed Bounds coordinates on the map and the size changes depending on the map’s zoom level.

When the map is zoomed out, the size of the OverlayView image automatically adapts to keep it inside the Bounds coordinates.

In code, set the OverlayView Mode to omBounds to keep it positioned and sized between the Bounds coordinates.
In this example an image is used to display a different style of map at that location. To make sure the image fills the entire available space,  it’s width and height must be set to 100%. Optionally the Padding, BackgroundColor, BorderColor and other configuration settings can be added.

var
  ov: TTMSFNCGoogleMapsOverlayView;
begin
  TMSFNCGoogleMaps1.BeginUpdate;

  ov := TMSFNCGoogleMaps1.AddOverlayView;
  ov.Mode := omBounds;
  ov.Text := '<img src="https://storage.googleapis.com/geo-devrel-public-buckets/newark_nj_1922-661x516.jpeg" style="position:absolute;width:100%;height:100%;">';
  ov.Bounds.NorthEast.Latitude := 40.773941;
  ov.Bounds.NorthEast.Longitude := -74.12544;
  ov.Bounds.SouthWest.Latitude := 40.712216;
  ov.Bounds.SouthWest.Longitude := -74.22655;
  ov.Padding := 0;
  ov.BackgroundColor := gcNull;
  ov.BorderColor := gcNull;

  TMSFNCGoogleMaps1.EndUpdate;

Available now

The TMS FNC Maps v2.1 update is available now. You can download the latest version and start using the new OverlayViews feature right away!

Read More

Read More

Arrange the list in the VertScrollBox1 fmx

I have an issue To add object a well-arranged to VertScrollBox1 example I add 1 then 2 then 3 but in my case when I add the first item it became in the first place -ok- but when I add the second item it placed in the first place and the the first item Go to the second Place like this 3 2 1 see image bellow my code is recadmin := TAdmin.Create(self); recadmin.admin.Align := TAlignLayout.Top; recadmin.txtAdmin.Text := edtxt; self.AddObject(recadmin.admin); self is VertScrollBox1 image
Read More

PNG in Firemonkey : how to specify Compression and 8-bit

VCL allows me to specify a PNG's Compression level (not referring to Quality level). How do I specify the Compression level of a PNG in FireMonkey? Is there a way to save the PNG as 8-bit instead of 32-bit? I'm using TBitmapCodecManager. I only need 8-bit because the colors are only black/white (with some anti-aliasing). Note: I cannot use an external PNG library as this has to be integrated in my code. begin var oStream := TMemoryStream.Create; var Surface := TBitmapSurface.Create; try BitmapCodecSaveParams.Quality := 100; // PNG is 100% loss-less, how can we specify the Compression level? Surface.Assign(aBitmap); TBitmapCodecManager.SaveToStream(oStream, Surface, '.png', @BitmapCodecSaveParams); finally oMemoryStream.Free; Surf.Free; end; end;
Read More

Delphi – ANDROID – Error Cannot create EGL PBuffer Surface. Error code: 12297

I receive the following error message: raised exception class EContext3DException with message 'Cannot create EGL PBuffer Surface. Error code: 12297.'. This error occurs when the form "quality" property is set to HighQuality. Among 10 smartphone models tested, one accused this error. How can I detect if the smartphone supports this feature? I imagine it would be something like this: Override InitializeNewForm procedure Tform.InitializeNewForm begin if suported then //how to check?? Quality := TCanvasQuality.HighQuality else Quality := TCanvasQuality.SystemDefault; inherited; end;
Read More

FMX TMemo is painfully slow

I was writing a Firemonkey application and ran into a problem: TMemo is painfully slow. It needs 12+ seconds to load a 3 mb file, VCL TMemo only needs 400 ms Here is my test code: uses System.Threading, System.Diagnostics; procedure TForm1.FormCreate(Sender: TObject); begin TTask.Run( procedure begin Sleep(100); var stopwatch := TStopwatch.Create; TThread.Synchronize(nil, procedure begin stopwatch.Start; Memo1.Lines.LoadFromFile('../../../DemoData.json'); end); TThread.Synchronize(nil, procedure begin stopwatch.Stop; Caption := stopwatch.ElapsedMilliseconds.ToString; end) end); end; The entire test project (including JSON file) can be found here: https://borrisholt.dk/Delphi/MemoDemo.zip Or your can of course use your own 3mb text file. Can anything be done or is it just the way it is with FMX?
Read More

Playing sounds as Android Service with Delphi FMX

Have a project which accumulates data from a 3 Party Device to android Tablets / Phones this is set to beep when a data packet is accepted and works fine until the App goes to the background I thought that if I Created a service to make the sound this would be over come however I have found that I cant Address the FMX components from the Service so the present way that I am implementing the sound is not available in the main app I Used procedure PlayMedia(aFile: String); var l_mp: TMediaPlayer; begin l_mp := TMediaPlayer.Create(Application); l_mp.FileName := System.IOUtils.TPath.Combine(System.IOUtils.TPath.GetDocumentsPath, aFile); l_mp.Play; end; In the Service I Tried procedure TDMSounds.PlaySound(afile: String); var Volume: Integer; StreamType: Integer; ToneType: Integer; ToneGenerator: JToneGenerator; RingToneMgr:JRingToneManager; RingTone:JRingtone; begin Volume := TJToneGenerator.JavaClass.MAX_VOLUME; StreamType := TJAudioManager.JavaClass.STREAM_SYSTEM; ToneType := TJToneGenerator.JavaClass.TONE_DTMF_9; ToneGenerator := TJToneGenerator.JavaClass.init(StreamType, Volume); ToneGenerator.startTone(ToneType, 1000); end; carn't seem to get a result from the service any Ideas Greatly Appreciated
Read More

FMX: TScrollBar MouseDown and MouseUp events not triggering

I've created the following class to try to improve the response of a scroll bar. The reason is that if the code in the scrollbar's onchange event is even slightly slow then updates don't take effect until you stop dragging the thumb. This is annoying if redrawing a canvas in the onchange event for example. However, updating the canvas in a TTimer event is smooth. My guess is that this has something to do with the TScrollBar OnChange events being synchronous, whereas the TTimer events are asynchronous. My code attempts to solve the TScrollBar problem by triggering the event using a TTimer, which is enabled using the MouseDown event and disabled using the MouseUp event. The issue is that the OnMouseDown event doesn't trigger at all. I also tried just adding a TScrollBar component to the form at design time and then checking if its MouseDown or MouseUp events get triggered, but they don't either. I managed to find a similar question from 2013, which was never answered. https://codeverge.com/embarcadero.delphi.firemonkey/help-how-to-trap-mouse-down-mou/1057945 So is there a reason why these events are not triggered? How can I get them to trigger? Also, if there's another way to improve the response of a standard TScrollBar then please let me know? I'm using Delphi 10.4. unit ScrollBarSmoothUnit; interface uses System.Classes, System.UITypes, FMX.StdCtrls, FMX.Types; type TScrollBarSmooth = class(TScrollBar) private FTimer : TTimer; FLastValue : Single; procedure ScrollMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Single); procedure ScrollMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Single); procedure DoChange(Sender: TObject); public OnChangeSmooth : TNotifyEvent; constructor Create(AOwner: TComponent); override; end; implementation constructor TScrollBarSmooth.Create(AOwner: TComponent); begin inherited Create(AOwner); AutoCapture := True; HitTest := True; OnMouseDown := ScrollMouseDown; OnMouseUp := ScrollMouseUp; FTimer := TTimer.Create(Self); FTimer.Interval := 40; FTimer.Enabled := False; FTimer.OnTimer := DoChange; FLastValue := -1; end; procedure TScrollBarSmooth.ScrollMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Single); begin FTimer.Enabled := True; end; procedure TScrollBarSmooth.ScrollMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Single); begin FTimer.Enabled := False; DoChange(Self); end; procedure TScrollBarSmooth.DoChange(Sender: TObject); begin if Value = FLastValue then Exit; // No change FLastValue := Value; if Assigned(OnChangeSmooth) then OnChangeSmooth(Self); end; end.
Read More

FMX ViewPort3D performance drop when filled with a large number of 3D shapes

I have a ViewPort3D element in a multi-device application form that being filled with a large number of TRectangle3D elements (anywhere from 1 to 10000) with LightMaterialSource applied to them, which all need to be rendered dynamically since I'm also rotating the camera using the following procedure: procedure TForm3.Viewport3D1MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Single); var I: IViewport3D; begin if ssRight in shift then begin I:=ViewPort3D1; with tdummy(I.CurrentCamera.Parent) do RotationAngle.X:=RotAng.X - Y; with tdummy(I.CurrentCamera.Parent.Parent) do RotationAngle.Y:=RotAng.Y + X; end; end; However the performance of the ViewPort3D begins to drop noticeably when the number of rectangles rendered approaches at least several dozen. The camera rotation gets slower and more unresponsive the more rectangles are added to the viewport up to the point of becoming a slideshow. Is there a way to improve performance of the ViewPort3D without deleting said rectangles? I've tried using setting the Multisample property to "none": ViewPort3d1.Context.SetMultisample(TMultisample.None) as well as removing MaterialSource from all the rectangles. While it did help a little with the performance, it didn't solve the problem entirely.
Read More

Deploying FMX Delphi Sydney 10.4.2 to IOS Simulator Error ( xcode 12.5 / IOS 14.5 )

I tried my first test to deploy a simple FMX app to the Apple world. I have MacBook Pro Intel i5 with MacOS BigSur 11.5.2 installed ( upgraded from Mojave ) and installed xcode from Apple store 12.5 ( supporting IOS 14.5 ) . Deploying to the 64bit macOS itself worked. Now I try to deploy to IOS Simulator but I got error ‘/Applications/PAServer-21.0.app/Contents/MacOS/db…’ unable to create process.
I can’t find the full error on delphi side ( not more info in output or build messages ). running the PA server in verbose gives as last command “Applications/PAServer-21.0.app/Contents/MacOS/dbkosx_27_0” – listen.

I’m new to this so unsure if these versions combinations ( MacOS BigSur 11.5.2 / XCode 12.5 / IOS 14.5 ) should work or not. And if not, what combination should work. To test, I installed IOS 13.7 support on Xcode / simulators and devices screen and created a new device. But I don’t know to get delphi downloading the SDK for this from the Mac. It’s still using IOS 14.5 SDK also for this device.
If I try to start the app directly on the mac , I get an error that seems to hint that it would be a 32bit application ????

I see that build process is using ‘dccios32.exe’ ?

Read More

Read More