@@ -111,21 +111,25 @@ void BaseGraphicalRenderer::subMenuRender(MenuItem* rootItem, uint8_t& locRedraw
111111}
112112
113113GridPositionRowCacheEntry* BaseGraphicalRenderer::findMenuEntryAndDimensions (const Coord& screenPos, Coord& localStart, Coord& localSize) {
114+ // 1. Bail out if a modal dialog is active or display has been taken over
114115 if ((dialog!=nullptr && dialog->isRenderNeeded ()) || displayTakenMode != NOT_TAKEN_OVER ) {
115116 return nullptr ;
116117 }
117118
119+ // 2. Handle runtime list rendering mode (lists manage their own row/title coordinates)
118120 if (currentRootMenu && currentRootMenu->getMenuType () == MENUTYPE_RUNTIME_LIST ) {
119121 auto * runList = reinterpret_cast <ListRuntimeMenuItem*>(currentRootMenu);
120122 auto * itemProps = getDisplayPropertiesFactory ().configFor (runList, ItemDisplayProperties::COMPTYPE_ITEM );
121123 auto * titleProps = getDisplayPropertiesFactory ().configFor (runList, ItemDisplayProperties::COMPTYPE_TITLE );
122124 int titleHeight = titleProps->getRequiredHeight () + titleProps->getSpaceAfter ();
123125 int rowHeight = itemProps->getRequiredHeight () + + itemProps->getSpaceAfter ();
124126 if (screenPos.y < titleHeight) {
127+ // Touch landed within list title area
125128 cachedEntryItem = GridPositionRowCacheEntry (runList, GridPosition (GridPosition::DRAW_TITLE_ITEM , GridPosition::JUSTIFY_TITLE_LEFT_VALUE_RIGHT , 0 , titleHeight), titleProps);
126129 return &cachedEntryItem;
127130 }
128131 else {
132+ // Touch landed within list items: calculate zero-based row index clamped to list size
129133 auto rowNum = internal_min (int ((screenPos.y - titleHeight) / rowHeight), int (runList->getNumberOfRows () - 1 ));
130134 cachedEntryItem = GridPositionRowCacheEntry (runList, GridPosition (GridPosition::DRAW_TEXTUAL_ITEM , GridPosition::JUSTIFY_TITLE_LEFT_VALUE_RIGHT , rowNum + 1 , titleHeight), titleProps);
131135 return &cachedEntryItem;
@@ -136,7 +140,7 @@ GridPositionRowCacheEntry* BaseGraphicalRenderer::findMenuEntryAndDimensions(con
136140 return nullptr ;
137141 }
138142
139- // if we are in title always mode, then the title must always be calculated
143+ // 3. If title is pinned at the top (TITLE_ALWAYS), calculate title height and check if touched
140144 int rowStartY = 0 ;
141145 if (titleMode == TITLE_ALWAYS ) {
142146 auto * titleProps = getDisplayPropertiesFactory ().configFor (nullptr , ItemDisplayProperties::COMPTYPE_TITLE );
@@ -146,45 +150,47 @@ GridPositionRowCacheEntry* BaseGraphicalRenderer::findMenuEntryAndDimensions(con
146150 }
147151 }
148152
153+ // 4a. Set up the iteration for the below, and get the width of the edit/select icon (if any)
149154 auto * icon = getDisplayPropertiesFactory ().iconForMenuItem (SPECIAL_ID_ACTIVE_ICON );
150155 int iconWidth = icon ? icon->getDimensions ().x : 0 ;
151156 uint8_t currentRow = -1 ;
152157
153- for (bsize_t i=lastOffset; i<itemOrderByRow.count (); i++) {
158+ // 4b. Iterate over items from drawingLocation offset to find which row contains screenPos.y
159+ for (bsize_t i=drawingLocation.getCurrentOffset (); i<itemOrderByRow.count (); i++) {
154160 auto * pEntry = itemOrderByRow.itemAtIndex (i);
155161 int rowHeight = heightOfRow (pEntry->getPosition ().getRow ());
156162 int rowEndY = rowStartY + rowHeight;
157163
158- // this seems odd but we are only doing this loop to find the heights, so we
159- // only check all the first entries in the row. There is code further down to
160- // deal with columns.
164+ // Skip subsequent items on the same row when computing vertical geometry (only process first item per row)
161165 if (pEntry->getPosition ().getRow () == currentRow) continue ;
162- currentRow = i ;
166+ currentRow = pEntry-> getPosition (). getRow () ;
163167
164- // if we are within the y bounds of of item
168+ // 5. Check if screen touch Y position falls within the current row bounds [rowStartY, rowEndY]
165169 if (screenPos.y > rowStartY && screenPos.y < rowEndY) {
166170 localStart.y = rowStartY;
167171 localSize.y = rowHeight;
168172 if (pEntry->getPosition ().getGridSize () == 1 ) {
169- // single column row, so we must be within the item
173+ // Single column: entire row width belongs to this item (adjusted for active icon)
170174 auto iconAdjust = iconWidth + pEntry->getDisplayProperties ()->getPadding ().left ;
171175 localStart.x = iconAdjust;
172176 localSize.x = int (width) - iconAdjust;
173177 return pEntry;
174178 }
175179 else {
176- // multi column row, so we must work out which column we are in.
180+ // Multi column: divide total width into equal segments based on gridSize
181+ // Calculate zero-based column index from screenPos.x, then lookup 1-based col key (column + 1)
177182 int colWidth = int (width) / pEntry->getPosition ().getGridSize ();
178183 int column = (screenPos.x / colWidth);
179184 localStart.x = column * colWidth;
180185 localSize.x = colWidth;
181186 return itemOrderByRow.getByKey (rowCol (pEntry->getPosition ().getRow (), column + 1 ));
182187 }
183188 }
189+ // Advance rowStartY past this row and its trailing margin
184190 rowStartY += rowHeight + pEntry->getDisplayProperties ()->getSpaceAfter ();
185191 }
186192
187- // we did not find anything at that point.
193+ // 6. No item matched at given screen coordinate
188194 return nullptr ;
189195}
190196
0 commit comments