mirror of https://github.com/OpenTTD/OpenTTD
(svn r18273) -Codechange: do not require widget numbers for default widgets (close, sticky, resize buttons and the caption), except when you want to use SetStringParameter for the caption ofcourse. Also remove the requirement for some of the WDF flags; no need to test for both the flag whether a feature is used and whether the feature is in action.
parent
75bd985876
commit
8371be352b
|
@ -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)
|
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);
|
if (index >= 0) this->SetIndex(index);
|
||||||
this->SetMinimalSize(0, 0);
|
this->SetMinimalSize(0, 0);
|
||||||
this->SetResize(0, 0);
|
this->SetResize(0, 0);
|
||||||
|
|
|
@ -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.
|
* Child widgets must have a index bigger than the parent index.
|
||||||
* @ingroup NestedWidgetParts
|
* @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;
|
NWidgetPart part;
|
||||||
|
|
||||||
|
|
198
src/window.cpp
198
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)
|
static void DispatchLeftClickEvent(Window *w, int x, int y, bool double_click)
|
||||||
{
|
{
|
||||||
int widget_index = 0;
|
const NWidgetCore *nw = w->nested_root->GetWidgetFromPos(x, y);
|
||||||
if (w->desc_flags & WDF_DEF_WIDGET) {
|
WidgetType widget_type = (nw != NULL) ? nw->type : WWT_EMPTY;
|
||||||
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;
|
bool focused_widget_changed = false;
|
||||||
/* If clicked on a window that previously did dot have focus */
|
/* If clicked on a window that previously did dot have focus */
|
||||||
if (_focused_window != w &&
|
if (_focused_window != w && // We already have focus, right?
|
||||||
(w->desc_flags & WDF_NO_FOCUS) == 0 && // Don't lose focus to toolbars
|
(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
|
widget_type != WWT_CLOSEBOX) { // Don't change focused window if 'X' (close button) was clicked
|
||||||
focused_widget_changed = true;
|
focused_widget_changed = true;
|
||||||
if (_focused_window != NULL) {
|
if (_focused_window != NULL) {
|
||||||
_focused_window->OnFocusLost();
|
_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. */
|
/* 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);
|
if (w->window_class != WC_OSK) DeleteWindowById(WC_OSK, 0);
|
||||||
}
|
}
|
||||||
SetFocusedWindow(w);
|
SetFocusedWindow(w);
|
||||||
w->OnFocus();
|
w->OnFocus();
|
||||||
|
}
|
||||||
|
|
||||||
|
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 */
|
||||||
|
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_index < 0) return; // exit if clicked outside of widgets
|
/* 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);
|
||||||
|
}
|
||||||
|
|
||||||
/* don't allow any interaction if the button has been disabled */
|
/* Close any child drop down menus. If the button pressed was the drop down
|
||||||
if (w->IsWidgetDisabled(widget_index)) return;
|
* list's own button, then we should not process the click any further. */
|
||||||
|
if (HideDropDownMenu(w) == widget_index && widget_index >= 0) return;
|
||||||
|
|
||||||
/* Clicked on a widget that is not disabled.
|
switch (widget_type) {
|
||||||
* So unless the clicked widget is the caption bar, change focus to this widget */
|
/* special widget handling for buttons*/
|
||||||
if (widget_type != WWT_CAPTION) {
|
case WWT_PANEL | WWB_PUSHBUTTON: // WWT_PUSHBTN
|
||||||
/* Close the OSK window if a edit box loses focus */
|
case WWT_IMGBTN | WWB_PUSHBUTTON: // WWT_PUSHIMGBTN
|
||||||
if ((w->nested_root != NULL && w->nested_focus != NULL && w->nested_focus->type == WWT_EDITBOX &&
|
case WWT_TEXTBTN | WWB_PUSHBUTTON: // WWT_PUSHTXTBTN
|
||||||
w->nested_focus != nw && w->window_class != WC_OSK)) {
|
w->HandleButtonClick(widget_index);
|
||||||
DeleteWindowById(WC_OSK, 0);
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
/* focused_widget_changed is 'now' only true if the window this widget
|
case WWT_SCROLLBAR:
|
||||||
* is in gained focus. In that case it must remain true, also if the
|
case WWT_SCROLL2BAR:
|
||||||
* local widget focus did not change. As such it's the logical-or of
|
case WWT_HSCROLLBAR:
|
||||||
* 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
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) {
|
|
||||||
ScrollbarClickHandler(w, nw, x, y);
|
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
|
break;
|
||||||
/* Open the OSK window if clicked on an edit box */
|
|
||||||
QueryStringBaseWindow *qs = dynamic_cast<QueryStringBaseWindow *>(w);
|
case WWT_EDITBOX:
|
||||||
if (qs != NULL) {
|
if (!focused_widget_changed) { // Only open the OSK window if clicking on an already focused edit box
|
||||||
qs->OnOpenOSKWindow(widget_index);
|
/* 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
|
case WWT_CLOSEBOX: // 'X'
|
||||||
* list's own button, then we should not process the click any further. */
|
delete w;
|
||||||
if (HideDropDownMenu(w) == widget_index) return;
|
return;
|
||||||
|
|
||||||
if (w->desc_flags & WDF_STD_BTN) {
|
case WWT_CAPTION: // 'Title bar'
|
||||||
if (widget_type == WWT_CLOSEBOX) { // 'X'
|
StartWindowDrag(w);
|
||||||
delete w;
|
return;
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (widget_type == WWT_CAPTION) { // 'Title bar'
|
case WWT_RESIZEBOX:
|
||||||
StartWindowDrag(w);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((w->desc_flags & WDF_RESIZABLE) && widget_type == WWT_RESIZEBOX) {
|
|
||||||
/* When the resize widget is on the left size of the window
|
/* When the resize widget is on the left size of the window
|
||||||
* we assume that that button is used to resize to the left. */
|
* we assume that that button is used to resize to the left. */
|
||||||
int left_pos = nw->pos_x;
|
StartWindowSizing(w, (int)nw->pos_x < (w->width / 2));
|
||||||
StartWindowSizing(w, left_pos < (w->width / 2));
|
nw->SetDirty(w);
|
||||||
w->SetWidgetDirty(widget_index);
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
if ((w->desc_flags & WDF_STICKY_BUTTON) && widget_type == WWT_STICKYBOX) {
|
case WWT_STICKYBOX:
|
||||||
w->flags4 ^= WF_STICKY;
|
w->flags4 ^= WF_STICKY;
|
||||||
w->SetWidgetDirty(widget_index);
|
nw->SetDirty(w);
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Widget has no index, so the window is not interested in it. */
|
||||||
|
if (widget_index < 0) return;
|
||||||
|
|
||||||
Point pt = { x, y };
|
Point pt = { x, y };
|
||||||
|
|
||||||
if (double_click) {
|
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)
|
static void DispatchRightClickEvent(Window *w, int x, int y)
|
||||||
{
|
{
|
||||||
int widget = 0;
|
NWidgetCore *wid = w->nested_root->GetWidgetFromPos(x, y);
|
||||||
|
|
||||||
/* default tooltips handler? */
|
/* No widget to handle */
|
||||||
if (w->desc_flags & WDF_STD_TOOLTIPS) {
|
if (wid == NULL) return;
|
||||||
NWidgetCore *wid = w->nested_root->GetWidgetFromPos(x, y);
|
|
||||||
if (wid == NULL || wid->index < 0) return;
|
|
||||||
widget = wid->index;
|
|
||||||
StringID tooltip = wid->tool_tip;
|
|
||||||
|
|
||||||
if (tooltip != 0) {
|
/* Show the tooltip if there is any */
|
||||||
GuiShowTooltips(tooltip);
|
if (wid->tool_tip != 0) {
|
||||||
return;
|
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 };
|
Point pt = { x, y };
|
||||||
w->OnRightClick(pt, widget);
|
w->OnRightClick(pt, wid->index);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dispatch the mousewheel-action to the window.
|
* 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
|
* The window will scroll any compatible scrollbars if the mouse is pointed over the bar or its contents
|
||||||
* @param w Window
|
* @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
|
* @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;
|
if (nwid == NULL) return;
|
||||||
|
|
||||||
Scrollbar *sb = NULL;
|
|
||||||
if (w->nested_array != NULL && (uint)widget < w->nested_array_size) sb = w->GetWidget<NWidgetCore>(widget)->FindScrollbar(w);
|
|
||||||
|
|
||||||
|
Scrollbar *sb = nwid->FindScrollbar(w);
|
||||||
if (sb != NULL && sb->GetCount() > sb->GetCapacity()) {
|
if (sb != NULL && sb->GetCount() > sb->GetCapacity()) {
|
||||||
sb->UpdatePosition(wheel);
|
sb->UpdatePosition(wheel);
|
||||||
w->SetDirty();
|
w->SetDirty();
|
||||||
|
@ -604,7 +603,6 @@ void DeleteWindowById(WindowClass cls, WindowNumber number, bool force)
|
||||||
{
|
{
|
||||||
Window *w = FindWindowById(cls, number);
|
Window *w = FindWindowById(cls, number);
|
||||||
if (force || w == NULL ||
|
if (force || w == NULL ||
|
||||||
(w->desc_flags & WDF_STICKY_BUTTON) == 0 ||
|
|
||||||
(w->flags4 & WF_STICKY) == 0) {
|
(w->flags4 & WF_STICKY) == 0) {
|
||||||
delete w;
|
delete w;
|
||||||
}
|
}
|
||||||
|
@ -2001,7 +1999,7 @@ static void MouseLoop(MouseClick click, int mousewheel)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Dispatch a MouseWheelEvent for widgets if it is not a viewport */
|
/* 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) {
|
if (vp != NULL) {
|
||||||
|
|
Loading…
Reference in New Issue