| 314 | }}; |
| 315 | |
| 316 | void OnMouseLoop() override |
| 317 | { |
| 318 | if (this->click_delay != 0 && --this->click_delay == 0) { |
| 319 | /* Close the dropdown, so it doesn't affect new window placement. |
| 320 | * Also mark it dirty in case the callback deals with the screen. (e.g. screenshots). */ |
| 321 | if (!this->options.Test(DropDownOption::Persist)) this->Close(); |
| 322 | this->parent->OnDropdownSelect(this->parent_button, this->selected_result, this->selected_click_result); |
| 323 | return; |
| 324 | } |
| 325 | |
| 326 | if (this->drag_mode) { |
| 327 | int result, click_result; |
| 328 | |
| 329 | if (!_left_button_clicked) { |
| 330 | this->drag_mode = false; |
| 331 | if (!this->GetDropDownItem(result, click_result)) { |
| 332 | if (this->options.Test(DropDownOption::InstantClose)) this->Close(); |
| 333 | return; |
| 334 | } |
| 335 | this->click_delay = 2; |
| 336 | } else { |
| 337 | if (_cursor.pos.y <= this->top + WidgetDimensions::scaled.dropdownlist.top) { |
| 338 | /* Cursor is above the list, set scroll up */ |
| 339 | this->scrolling = -1; |
| 340 | return; |
| 341 | } else if (_cursor.pos.y >= this->top + this->height - WidgetDimensions::scaled.dropdownlist.bottom) { |
| 342 | /* Cursor is below list, set scroll down */ |
| 343 | this->scrolling = 1; |
| 344 | return; |
| 345 | } |
| 346 | |
| 347 | if (!this->GetDropDownItem(result, click_result)) return; |
| 348 | } |
| 349 | |
| 350 | if (this->selected_result != result || this->selected_click_result != click_result) { |
| 351 | this->selected_result = result; |
| 352 | this->selected_click_result = click_result; |
| 353 | this->SetDirty(); |
| 354 | } |
| 355 | } |
| 356 | } |
| 357 | |
| 358 | void ReplaceList(DropDownList &&list, std::optional<int> selected_result) |
| 359 | { |
nothing calls this directly
no test coverage detected