mirror of https://github.com/OpenTTD/OpenTTD.git
(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.
This commit is contained in:
parent
935434333b
commit
d24442ae8b
|
@ -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[] = {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
432
src/window.cpp
432
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;
|
||||
|
|
172
src/window_gui.h
172
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);
|
||||
|
||||
|
|
Loading…
Reference in New Issue