diff options
-rw-r--r-- | src/widget.cpp | 2 | ||||
-rw-r--r-- | src/widget_type.h | 2 | ||||
-rw-r--r-- | src/window.cpp | 198 |
3 files changed, 100 insertions, 102 deletions
diff --git a/src/widget.cpp b/src/widget.cpp index cebfefc81..728a95adc 100644 --- a/src/widget.cpp +++ b/src/widget.cpp @@ -1693,7 +1693,7 @@ Dimension NWidgetLeaf::closebox_dimension = {0, 0}; */ NWidgetLeaf::NWidgetLeaf(WidgetType tp, Colours colour, int index, uint16 data, StringID tip) : NWidgetCore(tp, colour, 1, 1, data, tip) { - assert(index >= 0 || tp == WWT_LABEL || tp == WWT_TEXT); + assert(index >= 0 || tp == WWT_LABEL || tp == WWT_TEXT || tp == WWT_CAPTION || tp == WWT_RESIZEBOX || tp == WWT_STICKYBOX || tp == WWT_CLOSEBOX); if (index >= 0) this->SetIndex(index); this->SetMinimalSize(0, 0); this->SetResize(0, 0); diff --git a/src/widget_type.h b/src/widget_type.h index 0d8db9ec9..9f90e8339 100644 --- a/src/widget_type.h +++ b/src/widget_type.h @@ -737,7 +737,7 @@ static inline NWidgetPart SetPIP(uint8 pre, uint8 inter, uint8 post) * Child widgets must have a index bigger than the parent index. * @ingroup NestedWidgetParts */ -static inline NWidgetPart NWidget(WidgetType tp, Colours col, int16 idx) +static inline NWidgetPart NWidget(WidgetType tp, Colours col, int16 idx = -1) { NWidgetPart part; diff --git a/src/window.cpp b/src/window.cpp index 02645f29c..a5a057cfc 100644 --- a/src/window.cpp +++ b/src/window.cpp @@ -228,106 +228,108 @@ static void StartWindowSizing(Window *w, bool to_left); */ static void DispatchLeftClickEvent(Window *w, int x, int y, bool double_click) { - int widget_index = 0; - if (w->desc_flags & WDF_DEF_WIDGET) { - const NWidgetCore *nw = w->nested_root->GetWidgetFromPos(x, y); - widget_index = (nw != NULL) ? nw->index : -1; - WidgetType widget_type = (widget_index >= 0) ? nw->type : WWT_EMPTY; - - bool focused_widget_changed = false; - /* If clicked on a window that previously did dot have focus */ - if (_focused_window != w && - (w->desc_flags & WDF_NO_FOCUS) == 0 && // Don't lose focus to toolbars - !((w->desc_flags & WDF_STD_BTN) && widget_type == WWT_CLOSEBOX)) { // Don't change focused window if 'X' (close button) was clicked - focused_widget_changed = true; - if (_focused_window != NULL) { - _focused_window->OnFocusLost(); - - /* The window that lost focus may have had opened a OSK, window so close it, unless the user has clicked on the OSK window. */ - if (w->window_class != WC_OSK) DeleteWindowById(WC_OSK, 0); - } - SetFocusedWindow(w); - w->OnFocus(); + const NWidgetCore *nw = w->nested_root->GetWidgetFromPos(x, y); + WidgetType widget_type = (nw != NULL) ? nw->type : WWT_EMPTY; + + bool focused_widget_changed = false; + /* If clicked on a window that previously did dot have focus */ + if (_focused_window != w && // We already have focus, right? + (w->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 + focused_widget_changed = true; + if (_focused_window != NULL) { + _focused_window->OnFocusLost(); + + /* The window that lost focus may have had opened a OSK, window so close it, unless the user has clicked on the OSK window. */ + if (w->window_class != WC_OSK) DeleteWindowById(WC_OSK, 0); } + SetFocusedWindow(w); + w->OnFocus(); + } - if (widget_index < 0) return; // exit if clicked outside of widgets + if (nw == NULL) return; // exit if clicked outside of widgets - /* don't allow any interaction if the button has been disabled */ - if (w->IsWidgetDisabled(widget_index)) return; + /* don't allow any interaction if the button has been disabled */ + if (nw->IsDisabled()) return; - /* Clicked on a widget that is not disabled. - * So unless the clicked widget is the caption bar, change focus to this widget */ - if (widget_type != WWT_CAPTION) { - /* Close the OSK window if a edit box loses focus */ - if ((w->nested_root != NULL && w->nested_focus != NULL && w->nested_focus->type == WWT_EDITBOX && - w->nested_focus != nw && w->window_class != WC_OSK)) { - DeleteWindowById(WC_OSK, 0); - } + int widget_index = nw->index; ///< Index of the widget - /* 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). - */ - focused_widget_changed |= w->SetFocusedWidget(widget_index); + /* Clicked on a widget that is not disabled. + * So unless the clicked widget is the caption bar, change focus to this widget */ + if (widget_type != WWT_CAPTION) { + /* Close the OSK window if a edit box loses focus */ + if ((w->nested_root != NULL && w->nested_focus != NULL && w->nested_focus->type == WWT_EDITBOX && + w->nested_focus != nw && w->window_class != WC_OSK)) { + DeleteWindowById(WC_OSK, 0); } - if (widget_type & WWB_PUSHBUTTON) { - /* special widget handling for buttons*/ - switch (widget_type) { - default: NOT_REACHED(); - case WWT_PANEL | WWB_PUSHBUTTON: // WWT_PUSHBTN - case WWT_IMGBTN | WWB_PUSHBUTTON: // WWT_PUSHIMGBTN - case WWT_TEXTBTN | WWB_PUSHBUTTON: // WWT_PUSHTXTBTN - w->HandleButtonClick(widget_index); - break; - } - } else if (widget_type == WWT_SCROLLBAR || widget_type == WWT_SCROLL2BAR || widget_type == WWT_HSCROLLBAR) { + /* 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). + */ + focused_widget_changed |= w->SetFocusedWidget(widget_index); + } + + /* 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; + + switch (widget_type) { + /* special widget handling for buttons*/ + case WWT_PANEL | WWB_PUSHBUTTON: // WWT_PUSHBTN + case WWT_IMGBTN | WWB_PUSHBUTTON: // WWT_PUSHIMGBTN + case WWT_TEXTBTN | WWB_PUSHBUTTON: // WWT_PUSHTXTBTN + w->HandleButtonClick(widget_index); + break; + + case WWT_SCROLLBAR: + case WWT_SCROLL2BAR: + case WWT_HSCROLLBAR: ScrollbarClickHandler(w, nw, x, y); - } else if (widget_type == WWT_EDITBOX && !focused_widget_changed) { // Only open the OSK window if clicking on an already focused edit box - /* Open the OSK window if clicked on an edit box */ - QueryStringBaseWindow *qs = dynamic_cast<QueryStringBaseWindow *>(w); - if (qs != NULL) { - qs->OnOpenOSKWindow(widget_index); + break; + + case WWT_EDITBOX: + if (!focused_widget_changed) { // Only open the OSK window if clicking on an already focused edit box + /* Open the OSK window if clicked on an edit box */ + QueryStringBaseWindow *qs = dynamic_cast<QueryStringBaseWindow *>(w); + if (qs != NULL) { + qs->OnOpenOSKWindow(widget_index); + } } - } + break; - /* 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) return; - - if (w->desc_flags & WDF_STD_BTN) { - if (widget_type == WWT_CLOSEBOX) { // 'X' - delete w; - return; - } + case WWT_CLOSEBOX: // 'X' + delete w; + return; - if (widget_type == WWT_CAPTION) { // 'Title bar' - StartWindowDrag(w); - return; - } - } + case WWT_CAPTION: // 'Title bar' + StartWindowDrag(w); + return; - if ((w->desc_flags & WDF_RESIZABLE) && widget_type == WWT_RESIZEBOX) { + 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. */ - int left_pos = nw->pos_x; - StartWindowSizing(w, left_pos < (w->width / 2)); - w->SetWidgetDirty(widget_index); + StartWindowSizing(w, (int)nw->pos_x < (w->width / 2)); + nw->SetDirty(w); return; - } - if ((w->desc_flags & WDF_STICKY_BUTTON) && widget_type == WWT_STICKYBOX) { + case WWT_STICKYBOX: w->flags4 ^= WF_STICKY; - w->SetWidgetDirty(widget_index); + nw->SetDirty(w); return; - } + + default: + break; } + /* Widget has no index, so the window is not interested in it. */ + if (widget_index < 0) return; + Point pt = { x, y }; if (double_click) { @@ -345,39 +347,36 @@ static void DispatchLeftClickEvent(Window *w, int x, int y, bool double_click) */ static void DispatchRightClickEvent(Window *w, int x, int y) { - int widget = 0; + NWidgetCore *wid = w->nested_root->GetWidgetFromPos(x, y); - /* default tooltips handler? */ - if (w->desc_flags & WDF_STD_TOOLTIPS) { - NWidgetCore *wid = w->nested_root->GetWidgetFromPos(x, y); - if (wid == NULL || wid->index < 0) return; - widget = wid->index; - StringID tooltip = wid->tool_tip; + /* No widget to handle */ + if (wid == NULL) return; - if (tooltip != 0) { - GuiShowTooltips(tooltip); - return; - } + /* Show the tooltip if there is any */ + if (wid->tool_tip != 0) { + GuiShowTooltips(wid->tool_tip); + return; } + /* Widget has no index, so the window is not interested in it. */ + if (wid->index < 0) return; + Point pt = { x, y }; - w->OnRightClick(pt, widget); + w->OnRightClick(pt, wid->index); } /** * Dispatch the mousewheel-action to the window. * The window will scroll any compatible scrollbars if the mouse is pointed over the bar or its contents * @param w Window - * @param widget the widget where the scrollwheel was used + * @param nwid the widget where the scrollwheel was used * @param wheel scroll up or down */ -static void DispatchMouseWheelEvent(Window *w, int widget, int wheel) +static void DispatchMouseWheelEvent(Window *w, const NWidgetCore *nwid, int wheel) { - if (widget < 0) return; - - Scrollbar *sb = NULL; - if (w->nested_array != NULL && (uint)widget < w->nested_array_size) sb = w->GetWidget<NWidgetCore>(widget)->FindScrollbar(w); + if (nwid == NULL) return; + Scrollbar *sb = nwid->FindScrollbar(w); if (sb != NULL && sb->GetCount() > sb->GetCapacity()) { sb->UpdatePosition(wheel); w->SetDirty(); @@ -604,7 +603,6 @@ void DeleteWindowById(WindowClass cls, WindowNumber number, bool force) { Window *w = FindWindowById(cls, number); if (force || w == NULL || - (w->desc_flags & WDF_STICKY_BUTTON) == 0 || (w->flags4 & WF_STICKY) == 0) { delete w; } @@ -2001,7 +1999,7 @@ static void MouseLoop(MouseClick click, int mousewheel) } /* Dispatch a MouseWheelEvent for widgets if it is not a viewport */ - if (vp == NULL) DispatchMouseWheelEvent(w, GetWidgetFromPos(w, x - w->left, y - w->top), mousewheel); + if (vp == NULL) DispatchMouseWheelEvent(w, w->nested_root->GetWidgetFromPos(x - w->left, y - w->top), mousewheel); } if (vp != NULL) { |