1
0
Fork 0

Codechange: improve dropdown mouse interactions to fix hovering when not using instant-close and also make logic more readable

pull/11338/head
Micael Dias 2024-09-27 22:50:51 +01:00
parent 20fdf410d6
commit daf96d4c4f
1 changed files with 30 additions and 38 deletions

View File

@ -74,7 +74,6 @@ struct DropdownWindow : Window {
Rect wi_rect; ///< Rect of the button that opened the dropdown.
DropDownList list; ///< List with dropdown menu items.
int selected_result; ///< Result value of the selected item in the list.
uint8_t click_delay = 0; ///< Timer to delay selection.
bool drag_mode = true;
bool instant_close; ///< Close the window when the mouse button is raised.
bool persist; ///< Persist dropdown menu.
@ -281,12 +280,7 @@ struct DropdownWindow : Window {
void OnClick([[maybe_unused]] Point pt, WidgetID widget, [[maybe_unused]] int click_count) override
{
if (widget != WID_DM_ITEMS) return;
int item;
if (this->GetDropDownItem(item)) {
this->click_delay = 4;
this->selected_result = item;
this->SetDirty();
}
this->drag_mode = true;
}
/** Rate limit how fast scrolling happens. */
@ -300,43 +294,41 @@ struct DropdownWindow : Window {
void OnMouseLoop() override
{
if (this->click_delay != 0 && --this->click_delay == 0) {
/* Close the dropdown, so it doesn't affect new window placement.
* Also mark it dirty in case the callback deals with the screen. (e.g. screenshots). */
if (!this->persist) this->Close();
this->parent->OnDropdownSelect(this->parent_button, this->selected_result);
return;
}
if (this->drag_mode) {
int item;
if (!_left_button_clicked) {
this->drag_mode = false;
if (!this->GetDropDownItem(item)) {
if (this->instant_close) this->Close();
return;
}
this->click_delay = 2;
} else {
/* Scrolling logic */
if (_cursor.pos.y <= this->top + WidgetDimensions::scaled.dropdownlist.top) {
/* Cursor is above the list, set scroll up */
this->scrolling = -1;
return;
} else if (_cursor.pos.y >= this->top + this->height - WidgetDimensions::scaled.dropdownlist.bottom) {
/* Cursor is below list, set scroll down */
this->scrolling = 1;
return;
}
if (!this->GetDropDownItem(item)) return;
}
if (this->selected_result != item) {
/* Hover item under the cursor */
int item = -1;
const bool item_is_valid = this->GetDropDownItem(item);
if (item_is_valid) {
if (item != this->selected_result) {
this->selected_result = item;
this->SetDirty();
}
}
/* Select option logic */
if (!_left_button_clicked) {
bool released_on_item = false;
if (this->drag_mode) {
this->drag_mode = false;
if ((instant_close || item_is_valid) && !this->persist) {
this->Close();
}
if (item_is_valid) {
this->parent->OnDropdownSelect(this->parent_button, this->selected_result);
}
}
}
}
void ReplaceList(DropDownList &&list)