From 2ac412375c68db4d037cd5de243eb7e9d1f504b7 Mon Sep 17 00:00:00 2001 From: rubidium Date: Sat, 10 May 2008 13:46:36 +0000 Subject: (svn r13029) -Codechange: more work in the road to getting the WP macros and byte[WINDOW_CUSTOM_SIZE] removed. This step changes the event handling to work directly on the Window class instead of via a function pointer and big switches while keeping backward compatability while we're rewriting the Windows to the new scheme. --- src/misc_gui.cpp | 18 +- src/osk_gui.cpp | 12 +- src/viewport.cpp | 32 +--- src/widgets/dropdown.cpp | 6 +- src/window.cpp | 432 ++++++++++++++++++++++++++++++++--------------- src/window_gui.h | 172 ++++++++++++++++++- 6 files changed, 478 insertions(+), 194 deletions(-) diff --git a/src/misc_gui.cpp b/src/misc_gui.cpp index dc224d3f4..89f76e6dc 100644 --- a/src/misc_gui.cpp +++ b/src/misc_gui.cpp @@ -80,10 +80,8 @@ class LandInfoWindow : public Window { public: char landinfo_data[LAND_INFO_LINES][LAND_INFO_LINE_BUFF_SIZE]; - virtual void HandleWindowEvent(WindowEvent *e) + virtual void HandlePaintEvent() { - if (e->event != WE_PAINT) return; - DrawWindowWidgets(this); DoDrawStringCentered(140, 16, this->landinfo_data[0], TC_LIGHT_BLUE); @@ -1008,10 +1006,7 @@ static void QueryStringWndProc(Window *w, WindowEvent *e) /* If the parent is NULL, the editbox is handled by general function * HandleOnEditText */ if (parent != NULL) { - WindowEvent e; - e.event = WE_ON_EDIT_TEXT; - e.we.edittext.str = qs->text.buf; - parent->HandleWindowEvent(&e); + parent->OnQueryTextFinished(qs->text.buf); } else { HandleOnEditText(qs->text.buf); } @@ -1036,17 +1031,12 @@ static void QueryStringWndProc(Window *w, WindowEvent *e) case WE_DESTROY: // Call cancellation of query, if we have not handled it before if (!qs->handled && w->parent != NULL) { - WindowEvent e; - Window *parent = w->parent; - qs->handled = true; - e.event = WE_ON_EDIT_TEXT; - e.we.edittext.str = NULL; - parent->HandleWindowEvent(&e); + w->parent->OnQueryTextFinished(NULL); } ClrBit(_no_scroll, SCROLL_EDIT); break; - } + } } static const Widget _query_string_widgets[] = { diff --git a/src/osk_gui.cpp b/src/osk_gui.cpp index 681762e08..f92bb16b0 100644 --- a/src/osk_gui.cpp +++ b/src/osk_gui.cpp @@ -157,11 +157,7 @@ static void OskWndProc(Window *w, WindowEvent *e) if (qs->orig == NULL || strcmp(qs->text.buf, qs->orig) != 0) { /* pass information by simulating a button press on parent window */ if (WP(w, osk_d).ok_btn != 0) { - Window *parent = w->parent; - WindowEvent e; - e.event = WE_CLICK; - e.we.click.widget = WP(w, osk_d).ok_btn; - parent->HandleWindowEvent(&e); + w->parent->OnClick(e->we.click.pt, WP(w, osk_d).ok_btn); } } delete w; @@ -169,11 +165,7 @@ static void OskWndProc(Window *w, WindowEvent *e) case OSK_WIDGET_CANCEL: if (WP(w, osk_d).cancel_btn != 0) { // pass a cancel event to the parent window - Window *parent = w->parent; - WindowEvent e; - e.event = WE_CLICK; - e.we.click.widget = WP(w, osk_d).cancel_btn; - parent->HandleWindowEvent(&e); + w->parent->OnClick(e->we.click.pt, WP(w, osk_d).cancel_btn); } 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 index fed5d26e9..499adf69f 100644 --- a/src/viewport.cpp +++ b/src/viewport.cpp @@ -2057,14 +2057,7 @@ void PlaceObject() _tile_fract_coords.y = pt.y & 0xF; w = GetCallbackWnd(); - if (w != NULL) { - WindowEvent e; - - e.event = WE_PLACE_OBJ; - e.we.place.pt = pt; - e.we.place.tile = TileVirtXY(pt.x, pt.y); - w->HandleWindowEvent(&e); - } + if (w != NULL) w->OnPlaceObject(pt, TileVirtXY(pt.x, pt.y)); } @@ -2695,16 +2688,10 @@ calc_heightdiff_single_direction:; /** while dragging */ bool VpHandlePlaceSizingDrag() { - Window *w; - WindowEvent e; - if (_special_mouse_mode != WSM_SIZING) return true; - e.we.place.select_method = _thd.select_method; - e.we.place.select_proc = _thd.select_proc; - /* stop drag mode if the window has been closed */ - w = FindWindowById(_thd.window_class, _thd.window_number); + Window *w = FindWindowById(_thd.window_class, _thd.window_number); if (w == NULL) { ResetObjectToPlace(); return false; @@ -2712,9 +2699,7 @@ bool VpHandlePlaceSizingDrag() /* while dragging execute the drag procedure of the corresponding window (mostly VpSelectTilesWithMethod() ) */ if (_left_button_down) { - e.event = WE_PLACE_DRAG; - e.we.place.pt = GetTileBelowCursor(); - w->HandleWindowEvent(&e); + w->OnPlaceDrag(_thd.select_method, _thd.select_proc, GetTileBelowCursor()); return false; } @@ -2723,7 +2708,7 @@ bool VpHandlePlaceSizingDrag() _special_mouse_mode = WSM_NONE; if (_thd.next_drawstyle == HT_RECT) { _thd.place_mode = VHM_RECT; - } else if (e.we.place.select_method == VPM_SIGNALDIRS) { // some might call this a hack... -- Dominik + } else if (_thd.select_method == VPM_SIGNALDIRS) { // some might call this a hack... -- Dominik _thd.place_mode = VHM_RECT; } else if (_thd.next_drawstyle & HT_LINE) { _thd.place_mode = VHM_RAIL; @@ -2734,12 +2719,7 @@ bool VpHandlePlaceSizingDrag() } SetTileSelectSize(1, 1); - /* and call the mouseup event. */ - e.event = WE_PLACE_MOUSEUP; - 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->HandleWindowEvent(&e); + w->OnPlaceMouseUp(_thd.select_method, _thd.select_proc, _thd.selend, TileVirtXY(_thd.selstart.x, _thd.selstart.y), TileVirtXY(_thd.selend.x, _thd.selend.y)); return false; } @@ -2758,7 +2738,7 @@ void SetObjectToPlace(CursorID icon, SpriteID pal, ViewportHighlightMode mode, W /* undo clicking on button and drag & drop */ if (_thd.place_mode != VHM_NONE || _special_mouse_mode == WSM_DRAGDROP) { w = FindWindowById(_thd.window_class, _thd.window_number); - if (w != NULL) CallWindowEventNP(w, WE_ABORT_PLACE_OBJ); + if (w != NULL) w->OnPlaceObjectAbort(); } SetTileSelectSize(1, 1); diff --git a/src/widgets/dropdown.cpp b/src/widgets/dropdown.cpp index 37f0ccdf7..6a3d26f4d 100644 --- a/src/widgets/dropdown.cpp +++ b/src/widgets/dropdown.cpp @@ -177,11 +177,7 @@ static void DropDownMenuWndProc(Window *w, WindowEvent *e) } if (WP(w, dropdown_d).click_delay != 0 && --WP(w,dropdown_d).click_delay == 0) { - WindowEvent e; - 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->HandleWindowEvent(&e); + w2->OnDropdownSelect(WP(w, dropdown_d).parent_button, WP(w, dropdown_d).selected_index); delete w; return; } diff --git a/src/window.cpp b/src/window.cpp index 5288f51f3..0697c75c8 100644 --- a/src/window.cpp +++ b/src/window.cpp @@ -49,7 +49,11 @@ byte _special_mouse_mode; /** - * Call the window event handler for handling event \a e + * Call the window event handler for handling event \a e. + * This is a temporary helper functions that will be removed + * once all windows that still rely on WindowEvent and + * WindowEventCodes have been rewritten to use the 'OnXXX' + * event handlers. * @param e Window event to handle */ void Window::HandleWindowEvent(WindowEvent *e) @@ -57,6 +61,208 @@ void Window::HandleWindowEvent(WindowEvent *e) if (wndproc != NULL) wndproc(this, e); } +void Window::OnPaint() +{ + WindowEvent e; + e.event = WE_PAINT; + this->HandleWindowEvent(&e); +} + +bool Window::OnKeyPress(uint16 key, uint16 keycode) +{ + WindowEvent e; + e.event = WE_KEYPRESS; + e.we.keypress.key = key; + e.we.keypress.keycode = keycode; + e.we.keypress.cont = true; + this->HandleWindowEvent(&e); + + return e.we.keypress.cont; +} + +bool Window::OnCTRLStateChange() +{ + WindowEvent e; + e.event = WE_CTRL_CHANGED; + e.we.ctrl.cont = true; + this->HandleWindowEvent(&e); + + return e.we.ctrl.cont; +} + +void Window::OnClick(Point pt, int widget) +{ + WindowEvent e; + e.event = WE_CLICK; + e.we.click.pt = pt; + e.we.click.widget = widget; + this->HandleWindowEvent(&e); +} + +void Window::OnDoubleClick(Point pt, int widget) +{ + WindowEvent e; + e.event = WE_DOUBLE_CLICK; + e.we.click.pt = pt; + e.we.click.widget = widget; + this->HandleWindowEvent(&e); +} + +void Window::OnRightClick(Point pt, int widget) +{ + WindowEvent e; + e.event = WE_RCLICK; + e.we.click.pt = pt; + e.we.click.widget = widget; + this->HandleWindowEvent(&e); +} + +void Window::OnDragDrop(Point pt, int widget) +{ + WindowEvent e; + e.event = WE_DRAGDROP; + e.we.click.pt = pt; + e.we.click.widget = widget; + this->HandleWindowEvent(&e); +} + +void Window::OnScroll(Point delta) +{ + WindowEvent e; + e.event = WE_SCROLL; + e.we.scroll.delta = delta; + this->HandleWindowEvent(&e); +} + +void Window::OnMouseOver(Point pt, int widget) +{ + WindowEvent e; + e.event = WE_MOUSEOVER; + e.we.click.pt = pt; + e.we.click.widget = widget; + this->HandleWindowEvent(&e); +} + +void Window::OnMouseWheel(int wheel) +{ + WindowEvent e; + e.event = WE_MOUSEWHEEL; + e.we.wheel.wheel = wheel; + this->HandleWindowEvent(&e); +} + +void Window::OnMouseLoop() +{ + WindowEvent e; + e.event = WE_MOUSELOOP; + this->HandleWindowEvent(&e); +} + +void Window::OnTick() +{ + WindowEvent e; + e.event = WE_TICK; + this->HandleWindowEvent(&e); +} + +void Window::OnHundredthTick() +{ + WindowEvent e; + e.event = WE_100_TICKS; + this->HandleWindowEvent(&e); +} + +void Window::OnTimeout() +{ + WindowEvent e; + e.event = WE_TIMEOUT; + this->HandleWindowEvent(&e); +} + +void Window::OnResize(Point new_size, Point delta) +{ + WindowEvent e; + e.event = WE_RESIZE; + e.we.sizing.size = new_size; + e.we.sizing.diff = delta; + this->HandleWindowEvent(&e); +} + +void Window::OnDropdownSelect(int widget, int index) +{ + WindowEvent e; + e.event = WE_DROPDOWN_SELECT; + e.we.dropdown.button = widget; + e.we.dropdown.index = index; + this->HandleWindowEvent(&e); +} + +void Window::OnQueryTextFinished(char *str) +{ + WindowEvent e; + e.event = WE_ON_EDIT_TEXT; + e.we.edittext.str = str; + this->HandleWindowEvent(&e); +} + +void Window::OnInvalidateData(int data) +{ + WindowEvent e; + e.event = WE_INVALIDATE_DATA; + e.we.invalidate.data = data; + this->HandleWindowEvent(&e); +} + +void Window::OnPlaceObject(Point pt, TileIndex tile) +{ + WindowEvent e; + e.event = WE_PLACE_OBJ; + e.we.place.pt = pt; + e.we.place.tile = tile; + this->HandleWindowEvent(&e); +} + +void Window::OnPlaceObjectAbort() +{ + WindowEvent e; + e.event = WE_ABORT_PLACE_OBJ; + this->HandleWindowEvent(&e); +} + + +void Window::OnPlaceDrag(ViewportPlaceMethod select_method, byte select_proc, Point pt) +{ + WindowEvent e; + e.event = WE_PLACE_DRAG; + e.we.place.select_method = select_method; + e.we.place.select_proc = select_proc; + e.we.place.pt = pt; + this->HandleWindowEvent(&e); +} + +void Window::OnPlaceMouseUp(ViewportPlaceMethod select_method, byte select_proc, Point pt, TileIndex start_tile, TileIndex end_tile) +{ + WindowEvent e; + e.event = WE_PLACE_MOUSEUP; + e.we.place.select_method = select_method; + e.we.place.select_proc = select_proc; + e.we.place.pt = pt; + e.we.place.tile = end_tile; + e.we.place.starttile = start_tile; + this->HandleWindowEvent(&e); +} + +void Window::OnPlacePresize(Point pt, TileIndex tile) +{ + WindowEvent e; + e.event = WE_PLACE_PRESIZE; + e.we.place.pt = pt; + e.we.place.tile = tile; + this->HandleWindowEvent(&e); +} + + + void CDECL Window::SetWidgetsDisabledState(bool disab_stat, int widgets, ...) { va_list wdg_list; @@ -138,19 +344,15 @@ static void StartWindowSizing(Window *w); */ static void DispatchLeftClickEvent(Window *w, int x, int y, bool double_click) { - WindowEvent e; - e.we.click.pt.x = x; - e.we.click.pt.y = y; - e.event = double_click ? WE_DOUBLE_CLICK : WE_CLICK; - + int widget = 0; if (w->desc_flags & WDF_DEF_WIDGET) { - e.we.click.widget = GetWidgetFromPos(w, x, y); - if (e.we.click.widget < 0) return; // exit if clicked outside of widgets + widget = GetWidgetFromPos(w, x, y); + if (widget < 0) return; // exit if clicked outside of widgets /* don't allow any interaction if the button has been disabled */ - if (w->IsWidgetDisabled(e.we.click.widget)) return; + if (w->IsWidgetDisabled(widget)) return; - const Widget *wi = &w->widget[e.we.click.widget]; + const Widget *wi = &w->widget[widget]; if (wi->type & WWB_MASK) { /* special widget handling for buttons*/ @@ -158,20 +360,20 @@ static void DispatchLeftClickEvent(Window *w, int x, int y, bool double_click) case WWT_PANEL | WWB_PUSHBUTTON: /* WWT_PUSHBTN */ case WWT_IMGBTN | WWB_PUSHBUTTON: /* WWT_PUSHIMGBTN */ case WWT_TEXTBTN | WWB_PUSHBUTTON: /* WWT_PUSHTXTBTN */ - w->HandleButtonClick(e.we.click.widget); + w->HandleButtonClick(widget); break; } } else if (wi->type == WWT_SCROLLBAR || wi->type == WWT_SCROLL2BAR || wi->type == WWT_HSCROLLBAR) { - ScrollbarClickHandler(w, wi, e.we.click.pt.x, e.we.click.pt.y); + ScrollbarClickHandler(w, wi, x, y); } if (w->desc_flags & WDF_STD_BTN) { - if (e.we.click.widget == 0) { /* 'X' */ + if (widget == 0) { /* 'X' */ delete w; return; } - if (e.we.click.widget == 1) { /* 'Title bar' */ + if (widget == 1) { /* 'Title bar' */ StartWindowDrag(w); return; } @@ -179,18 +381,24 @@ static void DispatchLeftClickEvent(Window *w, int x, int y, bool double_click) if (w->desc_flags & WDF_RESIZABLE && wi->type == WWT_RESIZEBOX) { StartWindowSizing(w); - w->InvalidateWidget(e.we.click.widget); + w->InvalidateWidget(widget); return; } if (w->desc_flags & WDF_STICKY_BUTTON && wi->type == WWT_STICKYBOX) { w->flags4 ^= WF_STICKY; - w->InvalidateWidget(e.we.click.widget); + w->InvalidateWidget(widget); return; } } - w->HandleWindowEvent(&e); + Point pt = { x, y }; + + if (double_click) { + w->OnDoubleClick(pt, widget); + } else { + w->OnClick(pt, widget); + } } /** @@ -201,23 +409,21 @@ static void DispatchLeftClickEvent(Window *w, int x, int y, bool double_click) */ static void DispatchRightClickEvent(Window *w, int x, int y) { - WindowEvent e; + int widget = 0; /* default tooltips handler? */ if (w->desc_flags & WDF_STD_TOOLTIPS) { - e.we.click.widget = GetWidgetFromPos(w, x, y); - if (e.we.click.widget < 0) return; // exit if clicked outside of widgets + widget = GetWidgetFromPos(w, x, y); + if (widget < 0) return; // exit if clicked outside of widgets - if (w->widget[e.we.click.widget].tooltips != 0) { - GuiShowTooltips(w->widget[e.we.click.widget].tooltips); + if (w->widget[widget].tooltips != 0) { + GuiShowTooltips(w->widget[widget].tooltips); return; } } - e.event = WE_RCLICK; - e.we.click.pt.x = x; - e.we.click.pt.y = y; - w->HandleWindowEvent(&e); + Point pt = { x, y }; + w->OnRightClick(pt, widget); } /** @@ -315,7 +521,7 @@ static void DrawOverlappedWindow(Window* const *wz, int left, int top, int right dp->pitch = _screen.pitch; dp->dst_ptr = BlitterFactoryBase::GetCurrentBlitter()->MoveTo(_screen.dst_ptr, left, top); dp->zoom = ZOOM_LVL_NORMAL; - CallWindowEventNP(*wz, WE_PAINT); + (*wz)->OnPaint(); } /** @@ -344,20 +550,6 @@ void DrawOverlappedWindowForAll(int left, int top, int right, int bottom) } } -/** - * Dispatch an event to a possibly non-existing window. - * If the window pointer w is \c NULL, the event is not dispatched - * @param w Window to dispatch the event to, may be \c NULL - * @param event Event to dispatch - */ -void CallWindowEventNP(Window *w, int event) -{ - WindowEvent e; - - e.event = event; - w->HandleWindowEvent(&e); -} - /** * Mark entire window as dirty (in need of re-paint) * @param w Window to redraw @@ -437,7 +629,9 @@ Window::~Window() /* Delete any children a window might have in a head-recursive manner */ delete FindChildWindow(this); - CallWindowEventNP(this, WE_DESTROY); + WindowEvent e; + e.event = WE_DESTROY; + this->HandleWindowEvent(&e); if (this->viewport != NULL) DeleteWindowViewport(this); this->SetDirty(); @@ -770,13 +964,13 @@ void Window::Initialize(int x, int y, int min_width, int min_height, int def_wid ResizeWindow(this, enlarge_x, enlarge_y); - WindowEvent e; - e.event = WE_RESIZE; - e.we.sizing.size.x = this->width; - e.we.sizing.size.y = this->height; - e.we.sizing.diff.x = enlarge_x; - e.we.sizing.diff.y = enlarge_y; - this->HandleWindowEvent(&e); + Point size; + Point diff; + size.x = this->width; + size.y = this->height; + diff.x = enlarge_x; + diff.y = enlarge_y; + this->OnResize(size, diff); } int nx = this->left; @@ -1072,14 +1266,14 @@ static void DecreaseWindowCounters() w->flags4 &= ~(WF_SCROLL_DOWN | WF_SCROLL_UP); w->SetDirty(); } - CallWindowEventNP(w, WE_MOUSELOOP); + w->OnMouseLoop(); } for (wz = _last_z_window; wz != _z_windows;) { Window *w = *--wz; if (w->flags4 & WF_TIMEOUT_MASK && !(--w->flags4 & WF_TIMEOUT_MASK)) { - CallWindowEventNP(w, WE_TIMEOUT); + w->OnTimeout(); if (w->desc_flags & WDF_UNCLICK_BUTTONS) w->RaiseButtons(); } } @@ -1097,15 +1291,13 @@ static void HandlePlacePresize() Window *w = GetCallbackWnd(); if (w == NULL) return; - WindowEvent e; - e.we.place.pt = GetTileBelowCursor(); - if (e.we.place.pt.x == -1) { + Point pt = GetTileBelowCursor(); + if (pt.x == -1) { _thd.selend.x = -1; return; } - e.we.place.tile = TileVirtXY(e.we.place.pt.x, e.we.place.pt.y); - e.event = WE_PLACE_PRESIZE; - w->HandleWindowEvent(&e); + + w->OnPlacePresize(pt, TileVirtXY(pt.x, pt.y)); } static bool HandleDragDrop() @@ -1117,12 +1309,10 @@ static bool HandleDragDrop() if (w != NULL) { /* send an event in client coordinates. */ - WindowEvent e; - e.event = WE_DRAGDROP; - 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->HandleWindowEvent(&e); + Point pt; + pt.x = _cursor.pos.x - w->left; + pt.y = _cursor.pos.y - w->top; + w->OnDragDrop(pt, GetWidgetFromPos(w, pt.x, pt.y)); } ResetObjectToPlace(); @@ -1137,11 +1327,8 @@ static bool HandleMouseOver() /* We changed window, put a MOUSEOVER event to the last window */ if (_mouseover_last_w != NULL && _mouseover_last_w != w) { /* Reset mouse-over coordinates of previous window */ - WindowEvent e; - e.event = WE_MOUSEOVER; - e.we.mouseover.pt.x = -1; - e.we.mouseover.pt.y = -1; - _mouseover_last_w->HandleWindowEvent(&e); + Point pt = { -1, -1 }; + _mouseover_last_w->OnMouseOver(pt, 0); } /* _mouseover_last_w will get reset when the window is deleted, see DeleteWindow() */ @@ -1149,14 +1336,12 @@ static bool HandleMouseOver() if (w != NULL) { /* send an event in client coordinates. */ - WindowEvent e; - e.event = WE_MOUSEOVER; - e.we.mouseover.pt.x = _cursor.pos.x - w->left; - e.we.mouseover.pt.y = _cursor.pos.y - w->top; + Point pt = { _cursor.pos.x - w->left, _cursor.pos.y - w->top }; + int widget = 0; if (w->widget != NULL) { - e.we.mouseover.widget = GetWidgetFromPos(w, e.we.mouseover.pt.x, e.we.mouseover.pt.y); + widget = GetWidgetFromPos(w, pt.x, pt.y); } - w->HandleWindowEvent(&e); + w->OnMouseOver(pt, widget); } /* Mouseover never stops execution */ @@ -1360,7 +1545,6 @@ static bool HandleWindowDragging() w->SetDirty(); return false; } else if (w->flags4 & WF_SIZING) { - WindowEvent e; int x, y; /* Stop the sizing if the left mouse button was released */ @@ -1397,12 +1581,13 @@ static bool HandleWindowDragging() /* ResizeWindow sets both pre- and after-size to dirty for redrawal */ ResizeWindow(w, x, y); - e.event = WE_RESIZE; - e.we.sizing.size.x = x + w->width; - e.we.sizing.size.y = y + w->height; - e.we.sizing.diff.x = x; - e.we.sizing.diff.y = y; - w->HandleWindowEvent(&e); + Point size; + Point diff; + size.x = x + w->width; + size.y = y + w->height; + diff.x = x; + diff.y = y; + w->OnResize(size, diff); return false; } } @@ -1493,8 +1678,6 @@ static bool HandleScrollbarScrolling() static bool HandleViewportScroll() { - WindowEvent e; - bool scrollwheel_scrolling = _patches.scrollwheel_scrolling == 1 && (_cursor.v_wheel != 0 || _cursor.h_wheel != 0); if (!_scrolling_viewport) return true; @@ -1514,25 +1697,25 @@ static bool HandleViewportScroll() return true; } + Point delta; if (_patches.reverse_scroll) { - e.we.scroll.delta.x = -_cursor.delta.x; - e.we.scroll.delta.y = -_cursor.delta.y; + delta.x = -_cursor.delta.x; + delta.y = -_cursor.delta.y; } else { - e.we.scroll.delta.x = _cursor.delta.x; - e.we.scroll.delta.y = _cursor.delta.y; + delta.x = _cursor.delta.x; + delta.y = _cursor.delta.y; } if (scrollwheel_scrolling) { /* We are using scrollwheels for scrolling */ - e.we.scroll.delta.x = _cursor.h_wheel; - e.we.scroll.delta.y = _cursor.v_wheel; + delta.x = _cursor.h_wheel; + delta.y = _cursor.v_wheel; _cursor.v_wheel = 0; _cursor.h_wheel = 0; } /* Create a scroll-event and send it to the window */ - e.event = WE_SCROLL; - w->HandleWindowEvent(&e); + w->OnScroll(delta); _cursor.delta.x = 0; _cursor.delta.y = 0; @@ -1592,11 +1775,10 @@ static bool MaybeBringWindowToFront(const Window *w) } /** Handle keyboard input. - * @param key Lower 8 bits contain the ASCII character, the higher 16 bits the keycode + * @param raw_key Lower 8 bits contain the ASCII character, the higher 16 bits the keycode */ -void HandleKeypress(uint32 key) +void HandleKeypress(uint32 raw_key) { - WindowEvent e; /* Stores if a window with a textfield for typing is open * If this is the case, keypress events are only passed to windows with text fields and * to thein this main toolbar. */ @@ -1614,10 +1796,8 @@ void HandleKeypress(uint32 key) if (!IsGeneratingWorld()) _current_player = _local_player; /* Setup event */ - e.event = WE_KEYPRESS; - e.we.keypress.key = GB(key, 0, 16); - e.we.keypress.keycode = GB(key, 16, 16); - e.we.keypress.cont = true; + uint16 key = GB(raw_key, 0, 16); + uint16 keycode = GB(raw_key, 16, 16); /* * The Unicode standard defines an area called the private use area. Code points in this @@ -1626,12 +1806,12 @@ void HandleKeypress(uint32 key) * on a system running OS X. We don't want these keys to show up in text fields and such, * and thus we have to clear the unicode character when we encounter such a key. */ - if (e.we.keypress.key >= 0xE000 && e.we.keypress.key <= 0xF8FF) e.we.keypress.key = 0; + if (key >= 0xE000 && key <= 0xF8FF) key = 0; /* * If both key and keycode is zero, we don't bother to process the event. */ - if (e.we.keypress.key == 0 && e.we.keypress.keycode == 0) return; + if (key == 0 && keycode == 0) return; /* check if we have a query string window open before allowing hotkeys */ if (FindWindowById(WC_QUERY_STRING, 0) != NULL || @@ -1657,15 +1837,13 @@ void HandleKeypress(uint32 key) w->window_class != WC_COMPANY_PASSWORD_WINDOW) { continue; } - w->HandleWindowEvent(&e); - if (!e.we.keypress.cont) break; + ; + if (!w->OnKeyPress(key, keycode)) return; } - 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->HandleWindowEvent(&e); - } + Window *w = FindWindowById(WC_MAIN_TOOLBAR, 0); + /* When there is no toolbar w is null, check for that */ + if (w != NULL) w->OnKeyPress(key, keycode); } /** @@ -1673,16 +1851,10 @@ void HandleKeypress(uint32 key) */ void HandleCtrlChanged() { - WindowEvent e; - - e.event = WE_CTRL_CHANGED; - e.we.ctrl.cont = true; - /* Call the event, start with the uppermost window. */ for (Window* const *wz = _last_z_window; wz != _z_windows;) { Window *w = *--wz; - w->HandleWindowEvent(&e); - if (!e.we.ctrl.cont) break; + if (!w->OnCTRLStateChange()) break; } } @@ -1775,13 +1947,8 @@ void MouseLoop(MouseClick click, int mousewheel) if (mousewheel != 0) { if (_patches.scrollwheel_scrolling == 0) { - /* Scrollwheel is in zoom mode. Make the zoom event. */ - WindowEvent e; - /* Send WE_MOUSEWHEEL event to window */ - e.event = WE_MOUSEWHEEL; - e.we.wheel.wheel = mousewheel; - w->HandleWindowEvent(&e); + w->OnMouseWheel(mousewheel); } /* Dispatch a MouseWheelEvent for widgets if it is not a viewport */ @@ -1910,7 +2077,7 @@ void UpdateWindows() if (t >= 100) { for (wz = _last_z_window; wz != _z_windows;) { - CallWindowEventNP(*--wz, WE_100_TICKS); + (*--wz)->OnHundredthTick(); } t = 0; } @@ -1987,12 +2154,7 @@ void InvalidateWindowClasses(WindowClass cls) */ void InvalidateThisWindowData(Window *w, int data) { - WindowEvent e; - - e.event = WE_INVALIDATE_DATA; - e.we.invalidate.data = data; - - w->HandleWindowEvent(&e); + w->OnInvalidateData(data); w->SetDirty(); } @@ -2030,7 +2192,7 @@ void InvalidateWindowClassesData(WindowClass cls, int data) void CallWindowTickEvent() { for (Window * const *wz = _last_z_window; wz != _z_windows;) { - CallWindowEventNP(*--wz, WE_TICK); + (*--wz)->OnTick(); } } @@ -2147,13 +2309,13 @@ void RelocateAllWindows(int neww, int newh) if (neww - w->width != 0) { ResizeWindow(w, min(neww, 640) - w->width, 0); - WindowEvent e; - e.event = WE_RESIZE; - e.we.sizing.size.x = w->width; - e.we.sizing.size.y = w->height; - e.we.sizing.diff.x = neww - w->width; - e.we.sizing.diff.y = 0; - w->HandleWindowEvent(&e); + Point size; + Point delta; + size.x = w->width; + size.y = w->height; + delta.x = neww - w->width; + delta.y = 0; + w->OnResize(size, delta); } top = w->top; diff --git a/src/window_gui.h b/src/window_gui.h index ebe2f4a49..a20c005f7 100644 --- a/src/window_gui.h +++ b/src/window_gui.h @@ -276,6 +276,7 @@ struct ResizeInfo { struct Window : ZeroedMemoryAllocator { private: WindowProc *wndproc; ///< Event handler function for the window. Do not use directly, call HandleWindowEvent() instead. + void HandleWindowEvent(WindowEvent *e); protected: void Initialize(int x, int y, int min_width, int min_height, int def_width, int def_height, @@ -336,7 +337,173 @@ public: void SetDirty() const; - virtual void HandleWindowEvent(WindowEvent *e); + /*** Event handling ***/ + + /** + * This window is currently being repainted. + */ + virtual void OnPaint(); + + + /** + * A key has been pressed. + * @param key the Unicode value of the key. + * @param keycode the untranslated key code including shift state. + * @return true if the key press has been handled and no other + * window should receive the event. + */ + virtual bool OnKeyPress(uint16 key, uint16 keycode); + + /** + * The state of the control key has changed + * @return true if the change has been handled and no other + * window should receive the event. + */ + virtual bool OnCTRLStateChange(); + + + /** + * A click with the left mouse button has been made on the window. + * @param pt the point inside the window that has been clicked. + * @param widget the clicked widget. + */ + virtual void OnClick(Point pt, int widget); + + /** + * A double click with the left mouse button has been made on the window. + * @param pt the point inside the window that has been clicked. + * @param widget the clicked widget. + */ + virtual void OnDoubleClick(Point pt, int widget); + + /** + * A click with the right mouse button has been made on the window. + * @param pt the point inside the window that has been clicked. + * @param widget the clicked widget. + */ + virtual void OnRightClick(Point pt, int widget); + + /** + * A dragged 'object' has been released. + * @param pt the point inside the window where the release took place. + * @param widget the widget where the release took place. + */ + virtual void OnDragDrop(Point pt, int widget); + + /** + * Handle the request for (viewport) scrolling. + * @param delta the amount the viewport must be scrolled. + */ + virtual void OnScroll(Point delta); + + /** + * The mouse is currently moving over the window or has just moved outside + * of the window. In the latter case pt is (-1, -1). + * @param pt the point inside the window that the mouse hovers over. + * @param widget the widget the mouse hovers over. + */ + virtual void OnMouseOver(Point pt, int widget); + + /** + * The mouse wheel has been turned. + * @param wheel the amount of movement of the mouse wheel. + */ + virtual void OnMouseWheel(int wheel); + + + /** + * Called for every mouse loop run, which is at least once per (game) tick. + */ + virtual void OnMouseLoop(); + + /** + * Called once per (game) tick. + */ + virtual void OnTick(); + + /** + * Called once every 100 (game) ticks. + */ + virtual void OnHundredthTick(); + + /** + * Called when this window's timeout has been reached. + */ + virtual void OnTimeout(); + + + /** + * Called when the window got resized. + * @param new_size the new size of the window. + * @param delta the amount of which the window size changed. + */ + virtual void OnResize(Point new_size, Point delta); + + /** + * A dropdown option associated to this window has been selected. + * @param widget the widget (button) that the dropdown is associated with. + * @param index the element in the dropdown that is selected. + */ + virtual void OnDropdownSelect(int widget, int index); + + /** + * The query window opened from this window has closed. + * @param str the new value of the string or NULL if the window + * was cancelled. + */ + virtual void OnQueryTextFinished(char *str); + + /** + * Some data on this window has become invalid. + * @param data information about the changed data. + */ + virtual void OnInvalidateData(int data = 0); + + + /** + * The user clicked some place on the map when a tile highlight mode + * has been set. + * @param pt the exact point on the map that has been clicked. + * @param tile the tile on the map that has been clicked. + */ + virtual void OnPlaceObject(Point pt, TileIndex tile); + + /** + * The user cancelled a tile highlight mode that has been set. + */ + virtual void OnPlaceObjectAbort(); + + + /** + * The user is dragging over the map when the tile highlight mode + * has been set. + * @param select_method the method of selection (allowed directions) + * @param select_proc what will be created when the drag is over. + * @param pt the exact point on the map where the mouse is. + */ + virtual void OnPlaceDrag(ViewportPlaceMethod select_method, byte select_proc, Point pt); + + /** + * The user has dragged over the map when the tile highlight mode + * has been set. + * @param select_method the method of selection (allowed directions) + * @param select_proc what should be created. + * @param pt the exact point on the map where the mouse was released. + * @param start_tile the begin tile of the drag. + * @param end_tile the end tile of the drag. + */ + virtual void OnPlaceMouseUp(ViewportPlaceMethod select_method, byte select_proc, Point pt, TileIndex start_tile, TileIndex end_tile); + + /** + * The user moves over the map when a tile highlight mode has been set + * when the special mouse mode has been set to 'PRESIZE' mode. An + * example of this is the tile highlight for dock building. + * @param pt the exact point on the map where the mouse is. + * @param tile the tile on the map where the mouse is. + */ + virtual void OnPlacePresize(Point pt, TileIndex tile); + + /*** End of the event handling ***/ }; struct menu_d { @@ -481,9 +648,6 @@ enum WindowFlags { WF_SCROLL2 = 1 << 13, }; -/* window.cpp */ -void CallWindowEventNP(Window *w, int event); - Window *BringWindowToFrontById(WindowClass cls, WindowNumber number); Window *FindWindowFromPt(int x, int y); -- cgit v1.2.3-54-g00ecf