Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add CustomPopupPlacementCallback support #15233

Open
actipro-admin opened this issue Apr 4, 2024 · 3 comments · May be fixed by #15667
Open

Add CustomPopupPlacementCallback support #15233

actipro-admin opened this issue Apr 4, 2024 · 3 comments · May be fixed by #15667

Comments

@actipro-admin
Copy link

Is your feature request related to a problem? Please describe.

WPF has a CustomPopupPlacementCallback delegate that can be assigned to their Popup and when Popup.Placement == PlacementMode.Custom, that delegate is used to supply dynamic options for placement via callback. The options are returned in an array of CustomPopupPlacement objects, and the one that appears first and allows the popup to fit best on screen is the one that is used.

We have a requirement where an Avalonia Control that has a ToolTip needs to display that tip in a certain location relative to the target control. However, that relative location changes based on the current state of the target control and other controls around it at the time popup shows. Thus, we cannot use the simple Placement properties on Popup and need the use of a dynamic callback like in WPF to allow us to alter things on the fly.

Describe the solution you'd like

While we don't necessarily need the API to match WPF's CustomPopupPlacementCallback and CustomPopupPlacement exactly (they are slightly difficult to grasp when first learning them), we do need a callback function that can tell a popup like a ToolTip to display at some location relative to the target control.

The Avalonia Popup already has some slight differences and enhancements over WPF popups, so we are happy to have a discussion on API implementation for this callback feature that would fit into the Avalonia model.

Describe alternatives you've considered

No response

Additional context

No response

@kekekeks
Copy link
Member

kekekeks commented Apr 4, 2024

The API is designed to be Wayland-compatible and is designed against xdg_positioner object from xdg-shell protocol.
Any placement API that requires access to global screen coordinates won't be Wayland-compatible.

To position your popup relative to the top-left corner of a control use OffsetX/OffsetY properties with TopLeft anchor and BottomRight gravity.

@kekekeks kekekeks closed this as completed Apr 4, 2024
@kekekeks kekekeks reopened this Apr 4, 2024
@kekekeks
Copy link
Member

kekekeks commented Apr 4, 2024

We can, however, introduce a callback that would allow to modify offset/anchor/gravity properties right before the popup is shown

@billhenn
Copy link
Contributor

billhenn commented Apr 4, 2024

Just to clarify, the callback in WPF doesn't use screen coordinates. It is all coordinates relative to the target element. So a (0,0) placement value would mean upper left of the target control.

The WPF callback allows us to look at things like target element size, popup size, and horizontal/vertical offsets, and then return target element-relative placement options. I would think that should be Wayland-compatible since it's not global screen coordinates.

The WPF way would not make us alter the actual HorizontalOffset and VerticalOffset values since it expected the callback result's placements to specify a target element-relative location and axis. See the WPF CustomPopupPlacement for what the result there includes. Keep in mind that since it's using a PlacementMode.Custom setting for this, the Placement property is not even considered.


I admittedly don't know the nuts and bolts of how Avalonia implemented popup positioning very well but when searching around, I happened to see a PopupPositionerParameters class, which looks like a promising possible result for a callback.

If you guys are initializing a PopupPositionerParameters based on current props, what if we added a callback delegate property to Popup (or could be done via an event I suppose too) and if specified, it would pass in the PopupPositionerParameters you built but would allow us to tweak it further before it was actually used? The callback would need to have access to the target anchor element (to see it and its size), the popup (to see it and some of its properties).

If we could alter the PopupPositionerParameters before it was used, that would allow us to dynamically change popup positioning based on the current state of the target element. And if the callback wasn't specified, or it did nothing in its logic, your current default positioning parameters would be used. Does that sound reasonable?

@maxkatz6 maxkatz6 added help-wanted api API addition labels Apr 6, 2024
@maxkatz6 maxkatz6 linked a pull request May 9, 2024 that will close this issue
3 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants