Component Position Relative to UIFigure

14 views (last 30 days)
Jonathan
Jonathan on 7 Mar 2025
Answered: Deepak on 5 Jun 2025
Hi Friends,
First time posting, so go easy on me. I've got an App in App Designer with a bunch of nested grid components that I'm trying to place a uiimage over top of. So, I tried making a function that grabs the position of a component relative to the master UIFigure, as opposed to just the parent object.
function pos = getPos(app, component)
% Initialize the position as the component's position relative to its parent
pos = component.Position;
% Traverse up the parent hierarchy until we reach the UIFigure
parent = component.Parent;
while ~isa(parent, 'matlab.ui.Figure')
% If the parent is a GridLayout, adjust the position based on the grid cell
if isa(parent, 'matlab.ui.container.GridLayout')
% Get the grid layout properties
grid = parent;
row = component.Layout.Row;
col = component.Layout.Column;
% Calculate the pixel dimensions of the grid cell
cellPos = app.getGridCellPosition(grid, row, col);
% Adjust the component's position relative to the grid cell
pos(1:2) = pos(1:2) + cellPos(1:2);
else
% For non-grid parents, simply add the parent's position
pos(1:2) = pos(1:2) + parent.Position(1:2);
end
% Move up to the next parent
parent = parent.Parent;
end
end
I've also got functions now for the case of component.Parent being a GridLayout, so app.getGridCellPosition is supposed to get the position of the component's cell, and another to resolve relative sizes and convert them into pixels.
function cellPos = getGridCellPosition(app, grid, row, col)
% Get the grid's position and dimensions
gridPos = grid.Position;
gridWidth = gridPos(3);
gridHeight = gridPos(4);
% Get the row heights and column widths
rowHeights = grid.RowHeight;
colWidths = grid.ColumnWidth;
% Convert relative sizes (e.g., '1x') to absolute pixel values
rowHeights = app.resolveRelativeSizes(rowHeights, gridHeight);
colWidths = app.resolveRelativeSizes(colWidths, gridWidth);
% Calculate the x-position of the cell (left-to-right)
% Sum the widths of all columns to the left of the current column
cellX = sum(colWidths(1:col-1));
% Calculate the y-position of the cell (bottom-to-top)
% Sum the heights of all rows above the current row
cellY = gridHeight - sum(rowHeights(1:row));
% Get the width and height of the cell
cellWidth = colWidths(col);
cellHeight = rowHeights(row);
% Return the cell position [x, y, width, height]
cellPos = [cellX, cellY, cellWidth, cellHeight];
end
function sizes = resolveRelativeSizes(app, relativeSizes, totalSize)
% Convert relative sizes (e.g., '1x') to absolute pixel values
sizes = zeros(1, numel(relativeSizes));
relativeUnits = 0;
fixedUnits = 0;
% First, calculate the total size allocated to fixed units
for i = 1:numel(relativeSizes)
if isnumeric(relativeSizes{i})
fixedUnits = fixedUnits + relativeSizes{i};
elseif ischar(relativeSizes{i}) && endsWith(relativeSizes{i}, 'x')
relativeUnits = relativeUnits + str2double(relativeSizes{i}(1:end-1));
end
end
% Calculate the size per relative unit
sizePerUnit = (totalSize - fixedUnits) / relativeUnits;
% Resolve the sizes
for i = 1:numel(relativeSizes)
if isnumeric(relativeSizes{i})
sizes(i) = relativeSizes{i};
elseif ischar(relativeSizes{i}) && endsWith(relativeSizes{i}, 'x')
sizes(i) = str2double(relativeSizes{i}(1:end-1)) * sizePerUnit;
end
end
end
My issue is its getting this position way wrong - overestimating the height by almost double, and underestimating the width by almost double. Has anyone done this before? Any idea what's wrong with my current implementation?
  1 Comment
Voss
Voss on 8 Mar 2025
See getpixelposition, in particular with the optional second argument set to true.

Sign in to comment.

Answers (1)

Deepak
Deepak on 5 Jun 2025
I understand that you are trying to compute the absolute pixel position of a component inside a deeply nested "uigridlayout" in App Designer, to accurately place a "uiimage" over it. You have written a custom function to traverse up the UI hierarchy and compute positions based on grid cell sizes. However, the results are significantly off — which is likely due to manual calculations not accounting for internal spacing, padding, and layout behavior of the grid.
A more reliable and simpler alternative is to use built-in "getpixelposition" function of MATLAB, which handles all the layout math internally. To get the position of any UI component relative to the main "uifigure", you can use:
pos = getpixelposition(component, true);
The second argument (true) ensures the returned position is relative to the figure, not just the immediate parent.
Please find attached the documentation of "getpixelposition" for reference:
I hope this helps.

Categories

Find more on Develop uifigure-Based Apps in Help Center and File Exchange

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!