no-toolbars: misclicks should be fixed

This commit is contained in:
pelya
2017-04-02 00:50:59 +03:00
committed by Sergii Pylypenko
parent eb650bf4b3
commit d0ebbd329b
2 changed files with 28 additions and 176 deletions

View File

@@ -635,8 +635,15 @@ void Window::HandleButtonClick(byte widget)
static void StartWindowDrag(Window *w);
static void StartWindowSizing(Window *w, bool to_left);
#if 0
static void DispatchLeftClickEvent(Window *w, int x, int y, int click_count)
/**
* Mouse left button down+up events trigger OnClick event for a window.
* @param w Window to dispatch event in
* @param x X coordinate of the click
* @param y Y coordinate of the click
* @param click_count Number of fast consecutive clicks at same position
* @param mouse_down Event generated on mouse button press
*/
static void DispatchLeftClickEvent(Window *w, int x, int y, int click_count, bool mouse_down)
{
NWidgetCore *nw = w->nested_root->GetWidgetFromPos(x, y);
WidgetType widget_type = (nw != NULL) ? nw->type : WWT_EMPTY;
@@ -673,6 +680,18 @@ static void DispatchLeftClickEvent(Window *w, int x, int y, int click_count)
focused_widget_changed |= w->SetFocusedWidget(widget_index);
}
if (!_settings_client.gui.windows_titlebars && mouse_down) {
if (widget_type == NWID_VSCROLLBAR || widget_type == NWID_HSCROLLBAR) {
ScrollbarClickHandler(w, nw, x, y);
_dragging_widget = true;
}
if (widget_type == WWT_RESIZEBOX) {
StartWindowSizing(w, (int)nw->pos_x < (w->width / 2));
nw->SetDirty(w);
}
return;
}
/* Close any child drop down menus. If the button pressed was the drop down
* list's own button, then we should not process the click any further. */
if (HideDropDownMenu(w) == widget_index && widget_index >= 0) return;
@@ -684,7 +703,7 @@ static void DispatchLeftClickEvent(Window *w, int x, int y, int click_count)
switch (widget_type) {
case NWID_VSCROLLBAR:
case NWID_HSCROLLBAR:
ScrollbarClickHandler(w, nw, x, y);
if (mouse_down) ScrollbarClickHandler(w, nw, x, y);
break;
case WWT_EDITBOX: {
@@ -761,173 +780,8 @@ static void DispatchLeftClickEvent(Window *w, int x, int y, int click_count)
w->OnClick(pt, widget_index, click_count);
}
#endif
/**
* Mouse left button down event changes window focus, but not always triggers OnClick event.
* @param w Window to dispatch event in
* @param x X coordinate of the click
* @param y Y coordinate of the click
*/
static void ChangeFocusedWindow(Window *w, int x, int y)
{
NWidgetCore *nw = w->nested_root->GetWidgetFromPos(x, y);
WidgetType widget_type = (nw != NULL) ? nw->type : WWT_EMPTY;
/* If clicked on a window that previously did dot have focus */
if (_focused_window != w && // We already have focus, right?
(w->window_desc->flags & WDF_NO_FOCUS) == 0 && // Don't lose focus to toolbars
widget_type != WWT_CLOSEBOX) { // Don't change focused window if 'X' (close button) was clicked
SetFocusedWindow(w);
}
if (nw == NULL) return; // exit if clicked outside of widgets
/* don't allow any interaction if the button has been disabled */
if (nw->IsDisabled()) return;
int widget_index = nw->index; ///< Index of the widget
/* Clicked on a widget that is not disabled.
* So unless the clicked widget is the caption bar, change focus to this widget.
* Exception: In the OSK we always want the editbox to stay focussed. */
if (widget_type != WWT_CAPTION && w->window_class != WC_OSK) {
/* focused_widget_changed is 'now' only true if the window this widget
* is in gained focus. In that case it must remain true, also if the
* local widget focus did not change. As such it's the logical-or of
* both changed states.
*
* If this is not preserved, then the OSK window would be opened when
* a user has the edit box focused and then click on another window and
* then back again on the edit box (to type some text).
*/
w->SetFocusedWidget(widget_index);
}
// Special cases for scrollable widgets and resize button
switch (widget_type) {
case NWID_VSCROLLBAR:
case NWID_HSCROLLBAR:
ScrollbarClickHandler(w, nw, x, y);
_dragging_widget = true;
break;
case WWT_RESIZEBOX:
/* When the resize widget is on the left size of the window
* we assume that that button is used to resize to the left. */
StartWindowSizing(w, (int)nw->pos_x < (w->width / 2));
nw->SetDirty(w);
break;
default:
break;
}
}
/**
* Mouse left button down+up events trigger OnClick event for a window.
* @param w Window to dispatch event in
* @param x X coordinate of the click
* @param y Y coordinate of the click
* @param click_count Number of fast consecutive clicks at same position
*/
static void SendLeftClickEventToWindow(Window *w, int x, int y, int click_count)
{
NWidgetCore *nw = w->nested_root->GetWidgetFromPos(x, y);
if (w->nested_focus != NULL) nw = w->GetWidget<NWidgetCore>(w->nested_focus->index);
WidgetType widget_type = (nw != NULL) ? nw->type : WWT_EMPTY;
if (nw == NULL) return; // exit if clicked outside of widgets
/* don't allow any interaction if the button has been disabled */
if (nw->IsDisabled()) return;
int widget_index = nw->index; ///< Index of the widget
/* Close any child drop down menus. If the button pressed was the drop down
* list's own button, then we should not process the click any further. */
if (HideDropDownMenu(w) == widget_index && widget_index >= 0) return;
if ((widget_type & ~WWB_PUSHBUTTON) < WWT_LAST && (widget_type & WWB_PUSHBUTTON)) w->HandleButtonClick(widget_index);
Point pt = { x, y };
switch (widget_type) {
case WWT_EDITBOX: {
QueryString *query = w->GetQueryString(widget_index);
if (query != NULL) query->ClickEditBox(w, pt, widget_index, click_count, false);
break;
}
case WWT_CLOSEBOX: // 'X'
delete w;
return;
case WWT_CAPTION: // 'Title bar'
StartWindowDrag(w);
return;
case WWT_RESIZEBOX:
/* When the resize widget is on the left size of the window
* we assume that that button is used to resize to the left. */
StartWindowSizing(w, (int)nw->pos_x < (w->width / 2));
nw->SetDirty(w);
return;
case WWT_DEFSIZEBOX: {
if (_ctrl_pressed) {
w->window_desc->pref_width = w->width;
w->window_desc->pref_height = w->height;
} else {
int16 def_width = max<int16>(min(w->window_desc->GetDefaultWidth(), _screen.width), w->nested_root->smallest_x);
int16 def_height = max<int16>(min(w->window_desc->GetDefaultHeight(), _screen.height - 50), w->nested_root->smallest_y);
int dx = (w->resize.step_width == 0) ? 0 : def_width - w->width;
int dy = (w->resize.step_height == 0) ? 0 : def_height - w->height;
/* dx and dy has to go by step.. calculate it.
* The cast to int is necessary else dx/dy are implicitly casted to unsigned int, which won't work. */
if (w->resize.step_width > 1) dx -= dx % (int)w->resize.step_width;
if (w->resize.step_height > 1) dy -= dy % (int)w->resize.step_height;
ResizeWindow(w, dx, dy, false);
}
nw->SetLowered(true);
nw->SetDirty(w);
w->SetTimeout();
break;
}
case WWT_DEBUGBOX:
w->ShowNewGRFInspectWindow();
break;
case WWT_SHADEBOX:
nw->SetDirty(w);
w->SetShaded(!w->IsShaded());
return;
case WWT_STICKYBOX:
w->flags ^= WF_STICKY;
nw->SetDirty(w);
if (_ctrl_pressed) w->window_desc->pref_sticky = (w->flags & WF_STICKY) != 0;
return;
default:
break;
}
/* Widget has no index, so the window is not interested in it. */
if (widget_index < 0) return;
/* Check if the widget is highlighted; if so, disable highlight and dispatch an event to the GameScript */
if (w->IsWidgetHighlighted(widget_index)) {
w->SetWidgetHighlight(widget_index, TC_INVALID);
Game::NewEvent(new ScriptEventWindowWidgetClick((ScriptWindow::WindowClass)w->window_class, w->window_number, widget_index));
}
w->OnClick(pt, widget_index, click_count);
}
static int _left_button_click_count = 0;
/**
* Dispatch left mouse-button (possibly double) press in window.
* @param w Window to dispatch event in
@@ -937,10 +791,8 @@ static void SendLeftClickEventToWindow(Window *w, int x, int y, int click_count)
*/
static void DispatchLeftButtonDownEvent(Window *w, int x, int y, int click_count)
{
ChangeFocusedWindow(w, x, y);
if (_settings_client.gui.windows_titlebars || click_count > 1) {
SendLeftClickEventToWindow(w, x, y, click_count);
}
_left_button_click_count = click_count;
DispatchLeftClickEvent(w, x, y, click_count, true);
}
/**
@@ -953,7 +805,7 @@ static void DispatchLeftButtonUpEvent(Window *w, int x, int y)
{
_dragging_widget = false;
if (_settings_client.gui.windows_titlebars || _dragging_window) return;
SendLeftClickEventToWindow(w, x, y, 1);
DispatchLeftClickEvent(w, x, y, _left_button_click_count, false);
}
/**