-
Content Count
60 -
Joined
-
Last visited
-
Days Won
1
Alexander Halser last won the day on September 17 2023
Alexander Halser had the most liked content!
Community Reputation
21 ExcellentRecent Profile Visitors
The recent visitors block is disabled and is not being shown to other users.
-
Loading and Saving PNG into TBitmap changes the image
Alexander Halser replied to XylemFlow's topic in FMX
The Windows D2D implementation in FMX in FMX.Canvas.D2D.pas always assumes a premultiplied alpha. This is probably the source of the problem. Anders Melander can perhaps comment on that with more expertise than I have. D2D1_ALPHA_MODE (dcommon.h) - Win32 apps | Microsoft Learn One option to solve it would be to write a TCustomBitmapCodec for raw PNG data and load/save your PNGs through this codec exclusively. If SKIA is an option for you, install SKIA and enable it for your app. SKIA effectively implements its own canvas and its own image codecs, leaving your PNG file as it is. I tested your example image with SKIA enabled and the bitmap stays the same, no matter how often it is loaded and saved. Obviously, the SKIA codecs do a better job. -
IMO the gestures are designed for real touchscreens and not for touchpads. I believe this has never worked with touchpads. Anyway, I have implemented a solution for myself by patching FMX.Platform.Mac, which was already patched anyway to work around the Sonoma scaling bug on MacOS. This is certainly not for everyone, but works like a charm. It uses the Angle parameter for an alternative zoom gesture (Angle is used in rotation gestures, for zoom it's always zero). Your app needs to respond to this accordingly. Most importantly, it doesn't break regular zoom gestures coming from real touch screens. procedure TFMXViewBase.magnifyWithEvent(event: NSEvent); var ... begin ... if FGestureControl <> nil then begin LTouches := event.touchesMatchingPhase(NSTouchPhaseTouching, NSView(Super)); if LTouches.count >= 2 then begin LTouchesArray := LTouches.allObjects; LTouch := TNSTouch.Wrap(LTouchesArray.objectAtIndex(0)); LDeviceSize := LTouch.deviceSize; FEventInfo.Distance := 0; //reset the distance // Find the greatest distance between the touches. for I := 0 to LTouches.count - 2 do begin LTouch := TNSTouch.Wrap(LTouchesArray.objectAtIndex(I)); LPoint := LTouch.normalizedPosition; for J := 1 to LTouches.count - 1 do begin LTouch := TNSTouch.Wrap(LTouchesArray.objectAtIndex(J)); LPoint2 := LTouch.normalizedPosition; Distance := Round(Sqrt(Sqr(LPoint.x * LDeviceSize.width - LPoint2.x * LDeviceSize.width) + Sqr(LPoint.y * LDeviceSize.height - LPoint2.y * LDeviceSize.height))); if Distance > FEventInfo.Distance then FEventInfo.Distance := Distance; end; FEventInfo.GestureID := igiZoom; if Supports(FGestureControl, IGestureControl, GestureObj) then GestureObj.CMGesture(FEventInfo); FEventInfo.Flags := []; end end {ECS/ALEX} else if LTouches.count = 0 then begin FEventInfo.Distance := 0; FEventInfo.Angle := event.magnification; FEventInfo.GestureID := igiZoom; if Supports(FGestureControl, IGestureControl, GestureObj) then GestureObj.CMGesture(FEventInfo); FEventInfo.Flags := []; end; end {ECS/ALEX} else //send the message up the responder chain NSView(Super).magnifyWithEvent(event); end;
-
No, I haven't. But the magnifyWithEvent comes reliably and this is what Delphi actually evaluates. I am not that deep into native MacOS development, so I rather stay with the methods that Delphi already implements.
-
The problem is in FMX.Platform.Mac: procedure TFMXViewBase.magnifyWithEvent(event: NSEvent); var ... begin ... if FGestureControl <> nil then begin LTouches := event.touchesMatchingPhase(NSTouchPhaseTouching, NSView(Super)); {ECS/ALEX Here comes our problem: LTouches.count is zero, that's why the gesture event is not fired. I assume that we have to deal with "event.magnification" to determine "FEventInfo.Distance". } if LTouches.count >= 2 then begin LTouchesArray := LTouches.allObjects; LTouch := TNSTouch.Wrap(LTouchesArray.objectAtIndex(0)); LDeviceSize := LTouch.deviceSize; ... I am currently experimenting with the event.magnification value (which is a float value), to match FEventInfo.Distance in a way that the example from the official docs keeps working the way it promises, but doesn't. However, I have a hard time to believe that this has never worked. If Emba has dedicated examples, there must have been a time when this did work properly. It perhaps depends on the MacOS version. My own version of MacOS that I'm using for testing is relatively old (Big Sur), with a second Mac used by one of my colleagues running Sonoma. The gesture is not fired on either machine, but may have been working on OS versions < Big Sur. If it has never worked with touchpad gestures, it might have worked and still work with a real touch screen. Is anyone competent to comment on that - does the igiZoom gesture work as advertised with touch screen Mac (we don't have them here, so I cannot test this)?
-
Yes, rotate works as described in the docs. Zoom and pan do not. There's no event at all for these. The pan gesture (swiping up or down with 2 fingers) obviously gets translated into a mouse wheel message.
-
So, it's officially broken, despite documentation says the opposite? Gestures in FireMonkey - RAD Studio (embarcadero.com)
-
I wonder if you found a solution for this. The rotate gesture seems to be the only gesture that works with a MacOS trackpad. Everything else - simply broken.
-
Firemonkey form not included in "Also snap to screen"
Alexander Halser replied to Alexander Halser's topic in FMX
Sure. Winapi.Windows.pas and SetWindowLong would be difficult to compile anyway for MacOS, iOS and Android 😉 Are there any other negative side effects known? -
Firemonkey form not included in "Also snap to screen"
Alexander Halser replied to Alexander Halser's topic in FMX
Partial answer: in VCL the behavior is triggered by MainFormOnTaskbar := true; More detailed answer: it is the param WS_EX_APPWINDOW in the window GWL_EXSTYLE that makes the window appear (automatically set by MainFormOnTaskbar). In FMX, the main form can be made visible in the selection list by setting the form's (Windows) window handle manually: procedure TForm1.Button1Click(Sender: TObject); var WND: HWND; begin wnd := FmxHandleToHWND(self.handle); SetWindowLong(wnd, GWL_EXSTYLE, GetWindowLong(wnd, GWL_EXSTYLE) or WS_EX_APPWINDOW); //now the form is visible in the "Also snap..." list end; New question: Any known downside or side effects due to this modification? -
When pressing the Windows key plus the right or left arrow key simultaneously, the window is moved to fill the right or left half of the screen, respectively. This works for FMX forms as well, out of the box. At least with D11, not sure about older FMX versions. However, when you release the Win key, Windows usually offers (if enabled in global settings) a list of windows to fill the other half of the screen. And this is the issue I am wondering about: A VCL form is shown in this "also snap..." list. An FMX form is not shown. I assume that either a param in CreateParams is responsible for this behavior, or a Windows message needs to be handled to enable it (which is implemented in VCL but not in FMX for Windows). Does anyone know what causes the FMX window to be hidden and how to overcome it?
-
Not that I know of, but MS Edge keeps installing new stuff on it's own...
-
Nope. Delphi 11.3 without Skia, just FMX with GDI+. WebP works on MacOS as well, probably iOS, too.
-
I just realized, more or less by accident, that an FMX TBitmap can load WebP image files. I tested a few of them, but they seem to be all perfectly fine. bmp := TBitmap.create; bmp.LoadFromFile('C:\Users\Alexander\Pictures\_test.webp'); bmp.SaveToFile('C:\Users\Alexander\Pictures\_test.png'); //works bmp.SaveToFile('C:\Users\Alexander\Pictures\_test.webp'); //this fails! The load dialog in the IDE does not include webp, so you cannot select it. You can rename a webp image to ".bmp" and load it though. Internally, the TFixedMultiResBitmap converts it to PNG data, which heavily increases the binary image data stored in the form. It's like you had used a PNG in the first place. So, when using webP for UI display, it probably makes sense to store them as RC_DATA resources and load from a resource stream at runtime. Saving WebP fails with an error. The webp feature seems to come from the operating system. GDI+ explicitly mentions WEBP among other formats: Image File Format Constants (Gdiplusimaging.h) - Win32 apps | Microsoft Learn Does anyone know since when GDI+ supports WebP? Was this implemented in Windows 8 or Windows 10? I am pretty sure that Windows 7 GDI+ did not support it. Which means that an FMX app that runs on Win7 would not be able to load it at runtime.
-
Place 2 images inside the button and make them visible/invisible at runtime.
-
Registration of the url scheme will open your app, when such a link is being clicked (e.g. "myregisteredprotocol://this&is&url&data=whatever"). However, to receive and decode the url part, your application must implement the IURLEventHandler interface and add an event handler. Send me a PM if you need code for that.