| 231 | // If we have imputed a character try to get the closest element to it. |
| 232 | // TODO: not too nice and doesn't deal with dashes. |
| 233 | if (m_Open && ((szChar >= SDLK_a && szChar <= SDLK_z) || szChar == SDLK_SPACE |
| 234 | || (szChar >= SDLK_0 && szChar <= SDLK_9) || (szChar >= SDLK_KP0 && szChar <= SDLK_KP9))) |
| 235 | { |
| 236 | // arbitrary 1 second limit to add to string or start fresh. |
| 237 | // maximal amount of characters is 100, which imo is far more than enough. |
| 238 | if (timer_Time() - m_TimeOfLastInput > 1.0 || m_InputBuffer.length() >= 100) |
| 239 | m_InputBuffer = szChar; |
| 240 | else |
| 241 | m_InputBuffer += szChar; |
| 242 | |
| 243 | m_TimeOfLastInput = timer_Time(); |
| 244 | |
| 245 | CGUIList *pList; |
| 246 | GUI<CGUIList>::GetSettingPointer(this, "list", pList); |
| 247 | // let's look for the closest element |
| 248 | // basically it's alphabetic order and "as many letters as we can get". |
| 249 | int closest = -1; |
| 250 | int bestIndex = -1; |
| 251 | int difference = 1250; |
| 252 | for (int i=0; i<(int)pList->m_Items.size(); ++i) |
| 253 | { |
| 254 | int indexOfDifference = 0; |
| 255 | int diff = 0; |
| 256 | for (size_t j=0; j < m_InputBuffer.length(); ++j) |
| 257 | { |
| 258 | diff = abs(pList->m_Items[i].GetOriginalString().LowerCase()[j] - (int)m_InputBuffer[j]); |
| 259 | if (diff == 0) |
| 260 | indexOfDifference = j+1; |
| 261 | else |
| 262 | break; |
| 263 | } |
| 264 | if (indexOfDifference > bestIndex || (indexOfDifference >= bestIndex && diff < difference)) |
| 265 | { |
| 266 | bestIndex = indexOfDifference; |
| 267 | closest = i; |
| 268 | difference = diff; |
| 269 | } |
| 270 | } |
| 271 | // let's select the closest element. There should basically always be one. |
| 272 | if (closest != -1) |
| 273 | { |
| 274 | GUI<int>::SetSetting(this, "selected", closest); |
| 275 | update_highlight = true; |
| 276 | GetScrollBar(0).SetPos(m_ItemsYPositions[closest] - 60); |
| 277 | } |
| 278 | } |