diff --git a/src/misc_gui.cpp b/src/misc_gui.cpp --- a/src/misc_gui.cpp +++ b/src/misc_gui.cpp @@ -1164,7 +1164,7 @@ static void QueryStringWndProc(Window *w WindowEvent e; e.event = WE_ON_EDIT_TEXT; e.we.edittext.str = qs->text.buf; - parent->wndproc(parent, &e); + parent->HandleWindowEvent(&e); } else { HandleOnEditText(qs->text.buf); } @@ -1194,7 +1194,7 @@ static void QueryStringWndProc(Window *w qs->handled = true; e.event = WE_ON_EDIT_TEXT_CANCEL; - parent->wndproc(parent, &e); + parent->HandleWindowEvent(&e); } ClrBit(_no_scroll, SCROLL_EDIT); break; diff --git a/src/osk_gui.cpp b/src/osk_gui.cpp --- a/src/osk_gui.cpp +++ b/src/osk_gui.cpp @@ -161,7 +161,7 @@ static void OskWndProc(Window *w, Window WindowEvent e; e.event = WE_CLICK; e.we.click.widget = WP(w, osk_d).ok_btn; - parent->wndproc(parent, &e); + parent->HandleWindowEvent(&e); } } DeleteWindow(w); @@ -173,7 +173,7 @@ static void OskWndProc(Window *w, Window WindowEvent e; e.event = WE_CLICK; e.we.click.widget = WP(w, osk_d).cancel_btn; - parent->wndproc(parent, &e); + parent->HandleWindowEvent(&e); } else { // or reset to original string strcpy(qs->text.buf, WP(w, osk_d).orig); UpdateTextBufferSize(&qs->text); diff --git a/src/viewport.cpp b/src/viewport.cpp --- a/src/viewport.cpp +++ b/src/viewport.cpp @@ -2061,7 +2061,7 @@ void PlaceObject() e.event = WE_PLACE_OBJ; e.we.place.pt = pt; e.we.place.tile = TileVirtXY(pt.x, pt.y); - w->wndproc(w, &e); + w->HandleWindowEvent(&e); } } @@ -2712,7 +2712,7 @@ bool VpHandlePlaceSizingDrag() if (_left_button_down) { e.event = WE_PLACE_DRAG; e.we.place.pt = GetTileBelowCursor(); - w->wndproc(w, &e); + w->HandleWindowEvent(&e); return false; } @@ -2737,7 +2737,7 @@ bool VpHandlePlaceSizingDrag() e.we.place.pt = _thd.selend; e.we.place.tile = TileVirtXY(e.we.place.pt.x, e.we.place.pt.y); e.we.place.starttile = TileVirtXY(_thd.selstart.x, _thd.selstart.y); - w->wndproc(w, &e); + w->HandleWindowEvent(&e); return false; } diff --git a/src/widgets/dropdown.cpp b/src/widgets/dropdown.cpp --- a/src/widgets/dropdown.cpp +++ b/src/widgets/dropdown.cpp @@ -179,7 +179,7 @@ static void DropDownMenuWndProc(Window * e.event = WE_DROPDOWN_SELECT; e.we.dropdown.button = WP(w, dropdown_d).parent_button; e.we.dropdown.index = WP(w, dropdown_d).selected_index; - w2->wndproc(w2, &e); + w2->HandleWindowEvent(&e); DeleteWindow(w); return; } diff --git a/src/window.cpp b/src/window.cpp --- a/src/window.cpp +++ b/src/window.cpp @@ -47,6 +47,15 @@ bool _popup_menu_active; byte _special_mouse_mode; +/** + * Call the window event handler for handling event \a e + * @param e Window event to handle + */ +void Window::HandleWindowEvent(WindowEvent *e) +{ + if (wndproc != NULL) wndproc(this, e); +} + void CDECL Window::SetWidgetsDisabledState(bool disab_stat, int widgets, ...) { va_list wdg_list; @@ -184,7 +193,7 @@ static void DispatchLeftClickEvent(Windo } } - w->wndproc(w, &e); + w->HandleWindowEvent(&e); } /** @@ -212,7 +221,7 @@ static void DispatchRightClickEvent(Wind e.event = WE_RCLICK; e.we.click.pt.x = x; e.we.click.pt.y = y; - w->wndproc(w, &e); + w->HandleWindowEvent(&e); } /** @@ -352,7 +361,7 @@ void CallWindowEventNP(Window *w, int ev WindowEvent e; e.event = event; - w->wndproc(w, &e); + w->HandleWindowEvent(&e); } /** @@ -688,7 +697,7 @@ static Window *LocalAllocateWindow(int x DeleteWindow(w); } - w = new Window; + w = new Window(proc); /* Set up window properties */ w->window_class = cls; @@ -698,7 +707,6 @@ static Window *LocalAllocateWindow(int x w->top = y; w->width = min_width; w->height = min_height; - w->wndproc = proc; AssignWidgetToWindow(w, widget); w->resize.width = min_width; w->resize.height = min_height; @@ -734,7 +742,7 @@ static Window *LocalAllocateWindow(int x WindowEvent e; e.event = WE_CREATE; e.we.create.data = data; - w->wndproc(w, &e); + w->HandleWindowEvent(&e); /* Try to make windows smaller when our window is too small. * w->(width|height) is normally the same as min_(width|height), @@ -766,7 +774,7 @@ static Window *LocalAllocateWindow(int x e.we.sizing.size.y = w->height; e.we.sizing.diff.x = enlarge_x; e.we.sizing.diff.y = enlarge_y; - w->wndproc(w, &e); + w->HandleWindowEvent(&e); } int nx = w->left; @@ -1144,7 +1152,7 @@ static void HandlePlacePresize() } e.we.place.tile = TileVirtXY(e.we.place.pt.x, e.we.place.pt.y); e.event = WE_PLACE_PRESIZE; - w->wndproc(w, &e); + w->HandleWindowEvent(&e); } static bool HandleDragDrop() @@ -1164,7 +1172,7 @@ static bool HandleDragDrop() e.we.dragdrop.pt.x = _cursor.pos.x - w->left; e.we.dragdrop.pt.y = _cursor.pos.y - w->top; e.we.dragdrop.widget = GetWidgetFromPos(w, e.we.dragdrop.pt.x, e.we.dragdrop.pt.y); - w->wndproc(w, &e); + w->HandleWindowEvent(&e); } ResetObjectToPlace(); @@ -1194,7 +1202,7 @@ static bool HandlePopupMenu() e.we.popupmenu.pt = _cursor.pos; } - w->wndproc(w, &e); + w->HandleWindowEvent(&e); return false; } @@ -1211,7 +1219,7 @@ static bool HandleMouseOver() e.event = WE_MOUSEOVER; e.we.mouseover.pt.x = -1; e.we.mouseover.pt.y = -1; - if (_mouseover_last_w->wndproc != NULL) _mouseover_last_w->wndproc(_mouseover_last_w, &e); + _mouseover_last_w->HandleWindowEvent(&e); } /* _mouseover_last_w will get reset when the window is deleted, see DeleteWindow() */ @@ -1225,7 +1233,7 @@ static bool HandleMouseOver() if (w->widget != NULL) { e.we.mouseover.widget = GetWidgetFromPos(w, e.we.mouseover.pt.x, e.we.mouseover.pt.y); } - w->wndproc(w, &e); + w->HandleWindowEvent(&e); } /* Mouseover never stops execution */ @@ -1477,7 +1485,7 @@ static bool HandleWindowDragging() e.we.sizing.size.y = y + w->height; e.we.sizing.diff.x = x; e.we.sizing.diff.y = y; - w->wndproc(w, &e); + w->HandleWindowEvent(&e); return false; } } @@ -1608,7 +1616,7 @@ static bool HandleViewportScroll() /* Create a scroll-event and send it to the window */ e.event = WE_SCROLL; - w->wndproc(w, &e); + w->HandleWindowEvent(&e); _cursor.delta.x = 0; _cursor.delta.y = 0; @@ -1683,7 +1691,7 @@ static void SendWindowMessageW(Window *w e.we.message.wparam = wparam; e.we.message.lparam = lparam; - w->wndproc(w, &e); + w->HandleWindowEvent(&e); } /** Send a message from one window to another. The receiving window is found by @@ -1781,14 +1789,14 @@ void HandleKeypress(uint32 key) w->window_class != WC_COMPANY_PASSWORD_WINDOW) { continue; } - w->wndproc(w, &e); + w->HandleWindowEvent(&e); if (!e.we.keypress.cont) break; } if (e.we.keypress.cont) { Window *w = FindWindowById(WC_MAIN_TOOLBAR, 0); /* When there is no toolbar w is null, check for that */ - if (w != NULL) w->wndproc(w, &e); + if (w != NULL) w->HandleWindowEvent(&e); } } @@ -1805,7 +1813,7 @@ void HandleCtrlChanged() /* Call the event, start with the uppermost window. */ for (Window* const *wz = _last_z_window; wz != _z_windows;) { Window *w = *--wz; - w->wndproc(w, &e); + w->HandleWindowEvent(&e); if (!e.we.ctrl.cont) break; } } @@ -1912,7 +1920,7 @@ void MouseLoop(MouseClick click, int mou /* Send WE_MOUSEWHEEL event to window */ e.event = WE_MOUSEWHEEL; e.we.wheel.wheel = mousewheel; - w->wndproc(w, &e); + w->HandleWindowEvent(&e); } /* Dispatch a MouseWheelEvent for widgets if it is not a viewport */ @@ -2297,7 +2305,7 @@ void RelocateAllWindows(int neww, int ne e.we.sizing.size.y = w->height; e.we.sizing.diff.x = neww - w->width; e.we.sizing.diff.y = 0; - w->wndproc(w, &e); + w->HandleWindowEvent(&e); } top = w->top; diff --git a/src/window_gui.h b/src/window_gui.h --- a/src/window_gui.h +++ b/src/window_gui.h @@ -291,6 +291,12 @@ struct WindowMessage { * Data structure for an opened window */ struct Window : ZeroedMemoryAllocator { +private: + WindowProc *wndproc; ///< Event handler function for the window. Do not use directly, call HandleWindowEvent() instead. + +public: + Window(WindowProc *proc) : wndproc(proc) {} + uint16 flags4; ///< Window flags, @see WindowFlags WindowClass window_class; ///< Window class WindowNumber window_number; ///< Window number within the window class @@ -307,7 +313,6 @@ struct Window : ZeroedMemoryAllocator { byte caption_color; ///< Background color of the window caption, contains PlayerID - WindowProc *wndproc; ///< Event handler function for the window ViewPort *viewport; ///< Pointer to viewport, if present const Widget *original_widget; ///< Original widget layout, copied from WindowDesc Widget *widget; ///< Widgets of the window @@ -339,6 +344,8 @@ struct Window : ZeroedMemoryAllocator { void CDECL SetWidgetsHiddenState(bool hidden_stat, int widgets, ...); void CDECL SetWidgetsLoweredState(bool lowered_stat, int widgets, ...); void InvalidateWidget(byte widget_index) const; + + virtual void HandleWindowEvent(WindowEvent *e); }; struct menu_d {