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

Scaled CanvasLayer reports wrong area to child nodes #36166

Open
cgbeutler opened this issue Feb 12, 2020 · 5 comments
Open

Scaled CanvasLayer reports wrong area to child nodes #36166

cgbeutler opened this issue Feb 12, 2020 · 5 comments

Comments

@cgbeutler
Copy link

Godot version:
3.2

OS/device including version:
Windows 10

Issue description:
When a CanvasLayer is scaled, it's children get the viewport size when requesting their parent's area size. This means that a scaled CanvasLayer's children will anchor wrong.
CanvasLayerBug

Steps to reproduce:

  1. Create a 2DNode scene
  2. Add a CanvasLayer with scale set to (2,2)
  3. Add a Control as a child of the CanvasLayer and set it's Layout to Full Rect
    Note that the control is now twice the size of the actual viewport.

Minimal reproduction project:
https://github.com/cgbeutler/godot_bugs_CanvasLayerScaleAnchorsBug

@cgbeutler
Copy link
Author

Seems like a CanvasLayers' area should be what is visible. In other words, it seems like the CanvasLayer should report it's area as Viewport / scale.
If the above is intended behavior, I will probably propose a feature to add a Scale Area var that can be set to the inverse of the scale option. Without it, anchors are kinda useless for children of CanvasLayers.

@cgbeutler
Copy link
Author

A quick fix is to make a root control node inside the CanvasLayer and whenever the CanvasLayer scale is set, anchor the right and bottom of the root control to the inverse of the scale. Something like:

$CanvasLayer.scale = value
$CanvasLayer.RootControl.anchor_right = 1/value.x
$CanvasLayer.RootControl.anchor_bottom = 1/value.y

@cgbeutler
Copy link
Author

cgbeutler commented Apr 18, 2020

A control calls the method scene/gui/Control.cpp > get_parent_anchorable_rect() to find it's anchor starting point. Since CanvasLayer is not a CanvasItem, it isn't actually used at all for these calculations. Instead, the function falls back to calling get_viewport()->get_visible_rect(). This gives you the viewport's visible rect without the canvas' transform applied at all. Not really sure the cleanest/simplest way to fix this.

@cgbeutler
Copy link
Author

cgbeutler commented Apr 19, 2020

I figured out a minimal fix.
Basically, in get_parent_anchorable_rect(), the following line could be changed to use the global transform with canvas:

// Code was:
parent_rect = get_viewport()->get_visible_rect();
// Changed to:
parent_rect = get_global_transform_with_canvas().affine_inverse().xform(get_viewport()->get_visible_rect());

Not sure if there's a better way.

@cgbeutler
Copy link
Author

cgbeutler commented Apr 21, 2020

Seems like the canvas layer transforms are left out all over the place. When opening a popup, the popup is clamped to a non-translated rect. There's also my other submitted bug: #35965

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants