Skip to content

Commit b6b6860

Browse files
committed
#254 fix for touch controller double counting title.
1 parent 41d3882 commit b6b6860

1 file changed

Lines changed: 16 additions & 10 deletions

File tree

src/graphics/BaseGraphicalRenderer.cpp

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -111,21 +111,25 @@ void BaseGraphicalRenderer::subMenuRender(MenuItem* rootItem, uint8_t& locRedraw
111111
}
112112

113113
GridPositionRowCacheEntry* 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

Comments
 (0)