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

Functions for using screen positions in GUI component gui.set_screen_pos() #5886

Closed
AGulev opened this issue Jun 20, 2021 · 3 comments · Fixed by #6407
Closed

Functions for using screen positions in GUI component gui.set_screen_pos() #5886

AGulev opened this issue Jun 20, 2021 · 3 comments · Fixed by #6407
Labels
feature request A suggestion for a new feature gui Issues related to gui components
Projects

Comments

@AGulev
Copy link
Contributor

AGulev commented Jun 20, 2021

Is your feature request related to a problem? Please describe (REQUIRED):
For manipulations between game world and gui or between different gui components the engine should have API to convert cordinates using some universal cordinates system.
At the moment we use screen coordinates as such universal coordinates we may use for conversion.

Describe the solution you'd like (REQUIRED):
The engine has functions to get screen cordinates, but there are no functions in gui to use them.
I think the engine should have :
gui.set_screen_pos()
and
local pos = gui.convert_screen_pos_to_node_pos(node, screen_pos) (it's hard to find clear and short name here, pls suggest your variants).

Describe alternatives you've considered (REQUIRED):
I implemented these functions in the native extension, but I think it should be part of the gui.* API.
https://github.com/AGulev/set_screen_position

@AGulev AGulev added feature request A suggestion for a new feature gui Issues related to gui components labels Jun 20, 2021
@AGulev
Copy link
Contributor Author

AGulev commented Jun 20, 2021

defold/engine/gui/src/gui.cpp

Lines 4254 to 4312 in b240830

if (keep_scene_transform) {
Matrix4 node_m;
Matrix4 parent_m;
Vector4 reference_scale;
Vector4 adjust_scale;
Vector4 offset(0.0f);
// Calculate the nodes current scene transform
CalculateNodeTransform(scene, n, CalculateNodeTransformFlags(), node_m);
// Calculate the new parents scene transform
// We also need to calculate values relative to adjustments and offset
// corresponding to the values that would be used in AdjustPosScale (see reasoning below).
if (parent_node != 0x0)
{
CalculateNodeTransform(scene, parent_node, CalculateNodeTransformFlags(), parent_m);
reference_scale = parent_node->m_Node.m_LocalAdjustScale;
adjust_scale = ApplyAdjustOnReferenceScale(reference_scale, n->m_Node.m_AdjustMode);
} else {
reference_scale = CalculateReferenceScale(scene, 0x0);
adjust_scale = ApplyAdjustOnReferenceScale(reference_scale, n->m_Node.m_AdjustMode);
parent_m = Matrix4::scale(adjust_scale.getXYZ());
Vector4 parent_dims = Vector4((float) scene->m_Width, (float) scene->m_Height, 0.0f, 1.0f);
Vector4 adjusted_dims = mulPerElem(parent_dims, adjust_scale);
Vector4 ref_size = Vector4((float) scene->m_Context->m_PhysicalWidth, (float) scene->m_Context->m_PhysicalHeight, 0.0f, 1.0f);
offset = (ref_size - adjusted_dims) * 0.5f;
}
// We calculate a new position that will be the relative position once
// the node has been childed to the new parent.
Vector3 position = node_m.getCol3().getXYZ() - parent_m.getCol3().getXYZ();
// We need to perform the inverse of what AdjustPosScale will do to counteract when
// it will be applied during next call to CalculateNodeTransform.
// See AdjustPosScale for comparison on the steps being performed/inversed.
if (n->m_Node.m_XAnchor == XANCHOR_LEFT || n->m_Node.m_XAnchor == XANCHOR_RIGHT) {
offset.setX(0.0f);
}
if (n->m_Node.m_YAnchor == YANCHOR_TOP || n->m_Node.m_YAnchor == YANCHOR_BOTTOM) {
offset.setY(0.0f);
}
Vector3 scaled_position = position - offset.getXYZ();
position = mulPerElem(recipPerElem(adjust_scale.getXYZ()), scaled_position);
if (n->m_Node.m_XAnchor == dmGui::XANCHOR_LEFT || n->m_Node.m_XAnchor == dmGui::XANCHOR_RIGHT) {
position.setX(scaled_position.getX() / reference_scale.getX());
}
if (n->m_Node.m_YAnchor == dmGui::YANCHOR_BOTTOM || n->m_Node.m_YAnchor == dmGui::YANCHOR_TOP) {
position.setY(scaled_position.getY() / reference_scale.getY());
}
n->m_Node.m_Properties[dmGui::PROPERTY_POSITION] = Vector4(position, 1.0f);
n->m_Node.m_DirtyLocal = 1;
}

@AGulev AGulev changed the title Function for using screen positions in GUI component gui.set_screen_pos() Functions for using screen positions in GUI component gui.set_screen_pos() Jun 22, 2021
@britzl britzl added this to Discuss in Issue Review Jul 21, 2021
@britzl britzl added this to Needs Triage in Backlog via automation Jul 22, 2021
@Sublustris
Copy link

Sublustris commented Feb 3, 2022

Very useful feature. Sometime it is very frustrating when you need to synchronize positions of nodes in several GUIs. Aligning them according to screen coordinates is a key to this problem and gui.set_screen_pos() would be very helpful.

@AGulev
Copy link
Contributor Author

AGulev commented Feb 6, 2022

@AGulev AGulev removed this from Discuss in Issue Review Feb 6, 2022
@AGulev AGulev added this to To do in 1.3.0 via automation Feb 6, 2022
@AGulev AGulev removed this from Needs Triage in Backlog Feb 6, 2022
@britzl britzl moved this from To do to In progress in 1.3.0 Feb 16, 2022
@AGulev AGulev moved this from In progress to Review in progress in 1.3.0 Feb 17, 2022
1.3.0 automation moved this from Review in progress to Done Feb 18, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature request A suggestion for a new feature gui Issues related to gui components
Projects
No open projects
1.3.0
  
Done
Development

Successfully merging a pull request may close this issue.

2 participants