no-toolbars: misclicks should be fixed
This commit is contained in:
200
src/window.cpp
200
src/window.cpp
@@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user