src/window.cpp
changeset 6432 226650eb2ef3
parent 6296 a6bed59002c6
child 6443 63fbe9f76801
equal deleted inserted replaced
6431:137965651de7 6432:226650eb2ef3
    16 #include "variables.h"
    16 #include "variables.h"
    17 #include "table/sprites.h"
    17 #include "table/sprites.h"
    18 #include "genworld.h"
    18 #include "genworld.h"
    19 #include "helpers.hpp"
    19 #include "helpers.hpp"
    20 
    20 
    21 // delta between mouse cursor and upper left corner of dragged window
    21 /* delta between mouse cursor and upper left corner of dragged window */
    22 static Point _drag_delta;
    22 static Point _drag_delta;
    23 
    23 
    24 static Window _windows[25];
    24 static Window _windows[25];
    25 Window *_z_windows[lengthof(_windows)];
    25 Window *_z_windows[lengthof(_windows)];
    26 Window **_last_z_window; ///< always points to the next free space in the z-array
    26 Window **_last_z_window; ///< always points to the next free space in the z-array
    99 	e.we.click.pt.y = y;
    99 	e.we.click.pt.y = y;
   100 	e.event = WE_CLICK;
   100 	e.event = WE_CLICK;
   101 
   101 
   102 	if (w->desc_flags & WDF_DEF_WIDGET) {
   102 	if (w->desc_flags & WDF_DEF_WIDGET) {
   103 		e.we.click.widget = GetWidgetFromPos(w, x, y);
   103 		e.we.click.widget = GetWidgetFromPos(w, x, y);
   104 		if (e.we.click.widget < 0) return; /* exit if clicked outside of widgets */
   104 		if (e.we.click.widget < 0) return; // exit if clicked outside of widgets
   105 
   105 
   106 		/* don't allow any interaction if the button has been disabled */
   106 		/* don't allow any interaction if the button has been disabled */
   107 		if (IsWindowWidgetDisabled(w, e.we.click.widget)) return;
   107 		if (IsWindowWidgetDisabled(w, e.we.click.widget)) return;
   108 
   108 
   109 		wi = &w->widget[e.we.click.widget];
   109 		wi = &w->widget[e.we.click.widget];
   155 
   155 
   156 	/* default tooltips handler? */
   156 	/* default tooltips handler? */
   157 	if (w->desc_flags & WDF_STD_TOOLTIPS) {
   157 	if (w->desc_flags & WDF_STD_TOOLTIPS) {
   158 		e.we.click.widget = GetWidgetFromPos(w, x, y);
   158 		e.we.click.widget = GetWidgetFromPos(w, x, y);
   159 		if (e.we.click.widget < 0)
   159 		if (e.we.click.widget < 0)
   160 			return; /* exit if clicked outside of widgets */
   160 			return; // exit if clicked outside of widgets
   161 
   161 
   162 		if (w->widget[e.we.click.widget].tooltips != 0) {
   162 		if (w->widget[e.we.click.widget].tooltips != 0) {
   163 			GuiShowTooltips(w->widget[e.we.click.widget].tooltips);
   163 			GuiShowTooltips(w->widget[e.we.click.widget].tooltips);
   164 			return;
   164 			return;
   165 		}
   165 		}
   594 		w = FindDeletableWindow();
   594 		w = FindDeletableWindow();
   595 		if (w == NULL) w = ForceFindDeletableWindow();
   595 		if (w == NULL) w = ForceFindDeletableWindow();
   596 		DeleteWindow(w);
   596 		DeleteWindow(w);
   597 	}
   597 	}
   598 
   598 
   599 	// Set up window properties
   599 	/* Set up window properties */
   600 	memset(w, 0, sizeof(*w));
   600 	memset(w, 0, sizeof(*w));
   601 	w->window_class = cls;
   601 	w->window_class = cls;
   602 	w->flags4 = WF_WHITE_BORDER_MASK; // just opened windows have a white border
   602 	w->flags4 = WF_WHITE_BORDER_MASK; // just opened windows have a white border
   603 	w->caption_color = 0xFF;
   603 	w->caption_color = 0xFF;
   604 	w->left = x;
   604 	w->left = x;
   683 	bottom = _awap_r.height + top;
   683 	bottom = _awap_r.height + top;
   684 
   684 
   685 	if (left < 0 || top < 22 || right > _screen.width || bottom > _screen.height)
   685 	if (left < 0 || top < 22 || right > _screen.width || bottom > _screen.height)
   686 		return false;
   686 		return false;
   687 
   687 
   688 	// Make sure it is not obscured by any window.
   688 	/* Make sure it is not obscured by any window. */
   689 	FOR_ALL_WINDOWS(wz) {
   689 	FOR_ALL_WINDOWS(wz) {
   690 		const Window *w = *wz;
   690 		const Window *w = *wz;
   691 		if (w->window_class == WC_MAIN_WINDOW) continue;
   691 		if (w->window_class == WC_MAIN_WINDOW) continue;
   692 
   692 
   693 		if (right > w->left &&
   693 		if (right > w->left &&
   712 	height = _awap_r.height;
   712 	height = _awap_r.height;
   713 
   713 
   714 	if (left < -(width>>2) || left > _screen.width - (width>>1)) return false;
   714 	if (left < -(width>>2) || left > _screen.width - (width>>1)) return false;
   715 	if (top < 22 || top > _screen.height - (height>>2)) return false;
   715 	if (top < 22 || top > _screen.height - (height>>2)) return false;
   716 
   716 
   717 	// Make sure it is not obscured by any window.
   717 	/* Make sure it is not obscured by any window. */
   718 	FOR_ALL_WINDOWS(wz) {
   718 	FOR_ALL_WINDOWS(wz) {
   719 		const Window *w = *wz;
   719 		const Window *w = *wz;
   720 		if (w->window_class == WC_MAIN_WINDOW) continue;
   720 		if (w->window_class == WC_MAIN_WINDOW) continue;
   721 
   721 
   722 		if (left + width > w->left &&
   722 		if (left + width > w->left &&
   934 	Window *w;
   934 	Window *w;
   935 	Window* const *wz;
   935 	Window* const *wz;
   936 
   936 
   937 	for (wz = _last_z_window; wz != _z_windows;) {
   937 	for (wz = _last_z_window; wz != _z_windows;) {
   938 		w = *--wz;
   938 		w = *--wz;
   939 		// Unclick scrollbar buttons if they are pressed.
   939 		/* Unclick scrollbar buttons if they are pressed. */
   940 		if (w->flags4 & (WF_SCROLL_DOWN | WF_SCROLL_UP)) {
   940 		if (w->flags4 & (WF_SCROLL_DOWN | WF_SCROLL_UP)) {
   941 			w->flags4 &= ~(WF_SCROLL_DOWN | WF_SCROLL_UP);
   941 			w->flags4 &= ~(WF_SCROLL_DOWN | WF_SCROLL_UP);
   942 			SetWindowDirty(w);
   942 			SetWindowDirty(w);
   943 		}
   943 		}
   944 		CallWindowEventNP(w, WE_MOUSELOOP);
   944 		CallWindowEventNP(w, WE_MOUSELOOP);
   991 	w = GetCallbackWnd();
   991 	w = GetCallbackWnd();
   992 
   992 
   993 	ResetObjectToPlace();
   993 	ResetObjectToPlace();
   994 
   994 
   995 	if (w != NULL) {
   995 	if (w != NULL) {
   996 		// send an event in client coordinates.
   996 		/* send an event in client coordinates. */
   997 		e.event = WE_DRAGDROP;
   997 		e.event = WE_DRAGDROP;
   998 		e.we.dragdrop.pt.x = _cursor.pos.x - w->left;
   998 		e.we.dragdrop.pt.x = _cursor.pos.x - w->left;
   999 		e.we.dragdrop.pt.y = _cursor.pos.y - w->top;
   999 		e.we.dragdrop.pt.y = _cursor.pos.y - w->top;
  1000 		e.we.dragdrop.widget = GetWidgetFromPos(w, e.we.dragdrop.pt.x, e.we.dragdrop.pt.y);
  1000 		e.we.dragdrop.widget = GetWidgetFromPos(w, e.we.dragdrop.pt.x, e.we.dragdrop.pt.y);
  1001 		w->wndproc(w, &e);
  1001 		w->wndproc(w, &e);
  1036 	WindowEvent e;
  1036 	WindowEvent e;
  1037 	static Window *last_w = NULL;
  1037 	static Window *last_w = NULL;
  1038 
  1038 
  1039 	w = FindWindowFromPt(_cursor.pos.x, _cursor.pos.y);
  1039 	w = FindWindowFromPt(_cursor.pos.x, _cursor.pos.y);
  1040 
  1040 
  1041 	// We changed window, put a MOUSEOVER event to the last window
  1041 	/* We changed window, put a MOUSEOVER event to the last window */
  1042 	if (last_w != NULL && last_w != w) {
  1042 	if (last_w != NULL && last_w != w) {
  1043 		e.event = WE_MOUSEOVER;
  1043 		e.event = WE_MOUSEOVER;
  1044 		e.we.mouseover.pt.x = -1;
  1044 		e.we.mouseover.pt.x = -1;
  1045 		e.we.mouseover.pt.y = -1;
  1045 		e.we.mouseover.pt.y = -1;
  1046 		if (last_w->wndproc) last_w->wndproc(last_w, &e);
  1046 		if (last_w->wndproc) last_w->wndproc(last_w, &e);
  1047 	}
  1047 	}
  1048 	last_w = w;
  1048 	last_w = w;
  1049 
  1049 
  1050 	if (w != NULL) {
  1050 	if (w != NULL) {
  1051 		// send an event in client coordinates.
  1051 		/* send an event in client coordinates. */
  1052 		e.event = WE_MOUSEOVER;
  1052 		e.event = WE_MOUSEOVER;
  1053 		e.we.mouseover.pt.x = _cursor.pos.x - w->left;
  1053 		e.we.mouseover.pt.x = _cursor.pos.x - w->left;
  1054 		e.we.mouseover.pt.y = _cursor.pos.y - w->top;
  1054 		e.we.mouseover.pt.y = _cursor.pos.y - w->top;
  1055 		if (w->widget != NULL) {
  1055 		if (w->widget != NULL) {
  1056 			e.we.mouseover.widget = GetWidgetFromPos(w, e.we.mouseover.pt.x, e.we.mouseover.pt.y);
  1056 			e.we.mouseover.widget = GetWidgetFromPos(w, e.we.mouseover.pt.x, e.we.mouseover.pt.y);
  1057 		}
  1057 		}
  1058 		w->wndproc(w, &e);
  1058 		w->wndproc(w, &e);
  1059 	}
  1059 	}
  1060 
  1060 
  1061 	// Mouseover never stops execution
  1061 	/* Mouseover never stops execution */
  1062 	return true;
  1062 	return true;
  1063 }
  1063 }
  1064 
  1064 
  1065 /** Update all the widgets of a window based on their resize flags
  1065 /** Update all the widgets of a window based on their resize flags
  1066  * Both the areas of the old window and the new sized window are set dirty
  1066  * Both the areas of the old window and the new sized window are set dirty
  1115 static bool _dragging_window;
  1115 static bool _dragging_window;
  1116 
  1116 
  1117 static bool HandleWindowDragging()
  1117 static bool HandleWindowDragging()
  1118 {
  1118 {
  1119 	Window* const *wz;
  1119 	Window* const *wz;
  1120 	// Get out immediately if no window is being dragged at all.
  1120 	/* Get out immediately if no window is being dragged at all. */
  1121 	if (!_dragging_window) return true;
  1121 	if (!_dragging_window) return true;
  1122 
  1122 
  1123 	// Otherwise find the window...
  1123 	/* Otherwise find the window... */
  1124 	FOR_ALL_WINDOWS(wz) {
  1124 	FOR_ALL_WINDOWS(wz) {
  1125 		Window *w = *wz;
  1125 		Window *w = *wz;
  1126 
  1126 
  1127 		if (w->flags4 & WF_DRAGGING) {
  1127 		if (w->flags4 & WF_DRAGGING) {
  1128 			const Widget *t = &w->widget[1]; // the title bar ... ugh
  1128 			const Widget *t = &w->widget[1]; // the title bar ... ugh
  1130 			int x;
  1130 			int x;
  1131 			int y;
  1131 			int y;
  1132 			int nx;
  1132 			int nx;
  1133 			int ny;
  1133 			int ny;
  1134 
  1134 
  1135 			// Stop the dragging if the left mouse button was released
  1135 			/* Stop the dragging if the left mouse button was released */
  1136 			if (!_left_button_down) {
  1136 			if (!_left_button_down) {
  1137 				w->flags4 &= ~WF_DRAGGING;
  1137 				w->flags4 &= ~WF_DRAGGING;
  1138 				break;
  1138 				break;
  1139 			}
  1139 			}
  1140 
  1140 
  1156 					const Window *v = *vz;
  1156 					const Window *v = *vz;
  1157 
  1157 
  1158 					if (v == w) continue; // Don't snap at yourself
  1158 					if (v == w) continue; // Don't snap at yourself
  1159 
  1159 
  1160 					if (y + w->height > v->top && y < v->top + v->height) {
  1160 					if (y + w->height > v->top && y < v->top + v->height) {
  1161 						// Your left border <-> other right border
  1161 						/* Your left border <-> other right border */
  1162 						delta = abs(v->left + v->width - x);
  1162 						delta = abs(v->left + v->width - x);
  1163 						if (delta <= hsnap) {
  1163 						if (delta <= hsnap) {
  1164 							nx = v->left + v->width;
  1164 							nx = v->left + v->width;
  1165 							hsnap = delta;
  1165 							hsnap = delta;
  1166 						}
  1166 						}
  1167 
  1167 
  1168 						// Your right border <-> other left border
  1168 						/* Your right border <-> other left border */
  1169 						delta = abs(v->left - x - w->width);
  1169 						delta = abs(v->left - x - w->width);
  1170 						if (delta <= hsnap) {
  1170 						if (delta <= hsnap) {
  1171 							nx = v->left - w->width;
  1171 							nx = v->left - w->width;
  1172 							hsnap = delta;
  1172 							hsnap = delta;
  1173 						}
  1173 						}
  1174 					}
  1174 					}
  1175 
  1175 
  1176 					if (w->top + w->height >= v->top && w->top <= v->top + v->height) {
  1176 					if (w->top + w->height >= v->top && w->top <= v->top + v->height) {
  1177 						// Your left border <-> other left border
  1177 						/* Your left border <-> other left border */
  1178 						delta = abs(v->left - x);
  1178 						delta = abs(v->left - x);
  1179 						if (delta <= hsnap) {
  1179 						if (delta <= hsnap) {
  1180 							nx = v->left;
  1180 							nx = v->left;
  1181 							hsnap = delta;
  1181 							hsnap = delta;
  1182 						}
  1182 						}
  1183 
  1183 
  1184 						// Your right border <-> other right border
  1184 						/* Your right border <-> other right border */
  1185 						delta = abs(v->left + v->width - x - w->width);
  1185 						delta = abs(v->left + v->width - x - w->width);
  1186 						if (delta <= hsnap) {
  1186 						if (delta <= hsnap) {
  1187 							nx = v->left + v->width - w->width;
  1187 							nx = v->left + v->width - w->width;
  1188 							hsnap = delta;
  1188 							hsnap = delta;
  1189 						}
  1189 						}
  1190 					}
  1190 					}
  1191 
  1191 
  1192 					if (x + w->width > v->left && x < v->left + v->width) {
  1192 					if (x + w->width > v->left && x < v->left + v->width) {
  1193 						// Your top border <-> other bottom border
  1193 						/* Your top border <-> other bottom border */
  1194 						delta = abs(v->top + v->height - y);
  1194 						delta = abs(v->top + v->height - y);
  1195 						if (delta <= vsnap) {
  1195 						if (delta <= vsnap) {
  1196 							ny = v->top + v->height;
  1196 							ny = v->top + v->height;
  1197 							vsnap = delta;
  1197 							vsnap = delta;
  1198 						}
  1198 						}
  1199 
  1199 
  1200 						// Your bottom border <-> other top border
  1200 						/* Your bottom border <-> other top border */
  1201 						delta = abs(v->top - y - w->height);
  1201 						delta = abs(v->top - y - w->height);
  1202 						if (delta <= vsnap) {
  1202 						if (delta <= vsnap) {
  1203 							ny = v->top - w->height;
  1203 							ny = v->top - w->height;
  1204 							vsnap = delta;
  1204 							vsnap = delta;
  1205 						}
  1205 						}
  1206 					}
  1206 					}
  1207 
  1207 
  1208 					if (w->left + w->width >= v->left && w->left <= v->left + v->width) {
  1208 					if (w->left + w->width >= v->left && w->left <= v->left + v->width) {
  1209 						// Your top border <-> other top border
  1209 						/* Your top border <-> other top border */
  1210 						delta = abs(v->top - y);
  1210 						delta = abs(v->top - y);
  1211 						if (delta <= vsnap) {
  1211 						if (delta <= vsnap) {
  1212 							ny = v->top;
  1212 							ny = v->top;
  1213 							vsnap = delta;
  1213 							vsnap = delta;
  1214 						}
  1214 						}
  1215 
  1215 
  1216 						// Your bottom border <-> other bottom border
  1216 						/* Your bottom border <-> other bottom border */
  1217 						delta = abs(v->top + v->height - y - w->height);
  1217 						delta = abs(v->top + v->height - y - w->height);
  1218 						if (delta <= vsnap) {
  1218 						if (delta <= vsnap) {
  1219 							ny = v->top + v->height - w->height;
  1219 							ny = v->top + v->height - w->height;
  1220 							vsnap = delta;
  1220 							vsnap = delta;
  1221 						}
  1221 						}
  1222 					}
  1222 					}
  1223 				}
  1223 				}
  1224 			}
  1224 			}
  1225 
  1225 
  1226 			// Make sure the window doesn't leave the screen
  1226 			/* Make sure the window doesn't leave the screen
  1227 			// 13 is the height of the title bar
  1227 			 * 13 is the height of the title bar */
  1228 			nx = clamp(nx, 13 - t->right, _screen.width - 13 - t->left);
  1228 			nx = clamp(nx, 13 - t->right, _screen.width - 13 - t->left);
  1229 			ny = clamp(ny, 0, _screen.height - 13);
  1229 			ny = clamp(ny, 0, _screen.height - 13);
  1230 
  1230 
  1231 			// Make sure the title bar isn't hidden by behind the main tool bar
  1231 			/* Make sure the title bar isn't hidden by behind the main tool bar */
  1232 			v = FindWindowById(WC_MAIN_TOOLBAR, 0);
  1232 			v = FindWindowById(WC_MAIN_TOOLBAR, 0);
  1233 			if (v != NULL) {
  1233 			if (v != NULL) {
  1234 				int v_bottom = v->top + v->height;
  1234 				int v_bottom = v->top + v->height;
  1235 				int v_right = v->left + v->width;
  1235 				int v_right = v->left + v->width;
  1236 				if (ny + t->top >= v->top && ny + t->top < v_bottom) {
  1236 				if (ny + t->top >= v->top && ny + t->top < v_bottom) {
  1343 	Window* const *wz;
  1343 	Window* const *wz;
  1344 	int i;
  1344 	int i;
  1345 	int pos;
  1345 	int pos;
  1346 	Scrollbar *sb;
  1346 	Scrollbar *sb;
  1347 
  1347 
  1348 	// Get out quickly if no item is being scrolled
  1348 	/* Get out quickly if no item is being scrolled */
  1349 	if (!_scrolling_scrollbar) return true;
  1349 	if (!_scrolling_scrollbar) return true;
  1350 
  1350 
  1351 	// Find the scrolling window
  1351 	/* Find the scrolling window */
  1352 	FOR_ALL_WINDOWS(wz) {
  1352 	FOR_ALL_WINDOWS(wz) {
  1353 		Window *w = *wz;
  1353 		Window *w = *wz;
  1354 
  1354 
  1355 		if (w->flags4 & WF_SCROLL_MIDDLE) {
  1355 		if (w->flags4 & WF_SCROLL_MIDDLE) {
  1356 			// Abort if no button is clicked any more.
  1356 			/* Abort if no button is clicked any more. */
  1357 			if (!_left_button_down) {
  1357 			if (!_left_button_down) {
  1358 				w->flags4 &= ~WF_SCROLL_MIDDLE;
  1358 				w->flags4 &= ~WF_SCROLL_MIDDLE;
  1359 				SetWindowDirty(w);
  1359 				SetWindowDirty(w);
  1360 				break;
  1360 				break;
  1361 			}
  1361 			}
  1369 			} else {
  1369 			} else {
  1370 				sb = &w->vscroll;
  1370 				sb = &w->vscroll;
  1371 				i = _cursor.pos.y - _cursorpos_drag_start.y;
  1371 				i = _cursor.pos.y - _cursorpos_drag_start.y;
  1372 			}
  1372 			}
  1373 
  1373 
  1374 			// Find the item we want to move to and make sure it's inside bounds.
  1374 			/* Find the item we want to move to and make sure it's inside bounds. */
  1375 			pos = min(max(0, i + _scrollbar_start_pos) * sb->count / _scrollbar_size, max(0, sb->count - sb->cap));
  1375 			pos = min(max(0, i + _scrollbar_start_pos) * sb->count / _scrollbar_size, max(0, sb->count - sb->cap));
  1376 			if (pos != sb->pos) {
  1376 			if (pos != sb->pos) {
  1377 				sb->pos = pos;
  1377 				sb->pos = pos;
  1378 				SetWindowDirty(w);
  1378 				SetWindowDirty(w);
  1379 			}
  1379 			}
  1480 	if (bring_to_front) BringWindowToFront(w);
  1480 	if (bring_to_front) BringWindowToFront(w);
  1481 	return true;
  1481 	return true;
  1482 }
  1482 }
  1483 
  1483 
  1484 /** Send a message from one window to another. The receiving window is found by
  1484 /** Send a message from one window to another. The receiving window is found by
  1485  * @param w @see Window pointer pointing to the other window
  1485  * @param w see Window pointer pointing to the other window
  1486  * @param msg Specifies the message to be sent
  1486  * @param msg Specifies the message to be sent
  1487  * @param wparam Specifies additional message-specific information
  1487  * @param wparam Specifies additional message-specific information
  1488  * @param lparam Specifies additional message-specific information
  1488  * @param lparam Specifies additional message-specific information
  1489  */
  1489  */
  1490 static void SendWindowMessageW(Window *w, uint msg, uint wparam, uint lparam)
  1490 static void SendWindowMessageW(Window *w, uint msg, uint wparam, uint lparam)
  1498 
  1498 
  1499 	w->wndproc(w, &e);
  1499 	w->wndproc(w, &e);
  1500 }
  1500 }
  1501 
  1501 
  1502 /** Send a message from one window to another. The receiving window is found by
  1502 /** Send a message from one window to another. The receiving window is found by
  1503  * @param wnd_class @see WindowClass class AND
  1503  * @param wnd_class see WindowClass class AND
  1504  * @param wnd_num @see WindowNumber number, mostly 0
  1504  * @param wnd_num see WindowNumber number, mostly 0
  1505  * @param msg Specifies the message to be sent
  1505  * @param msg Specifies the message to be sent
  1506  * @param wparam Specifies additional message-specific information
  1506  * @param wparam Specifies additional message-specific information
  1507  * @param lparam Specifies additional message-specific information
  1507  * @param lparam Specifies additional message-specific information
  1508  */
  1508  */
  1509 void SendWindowMessage(WindowClass wnd_class, WindowNumber wnd_num, int msg, int wparam, int lparam)
  1509 void SendWindowMessage(WindowClass wnd_class, WindowNumber wnd_num, int msg, int wparam, int lparam)
  1512 	if (w != NULL) SendWindowMessageW(w, msg, wparam, lparam);
  1512 	if (w != NULL) SendWindowMessageW(w, msg, wparam, lparam);
  1513 }
  1513 }
  1514 
  1514 
  1515 /** Send a message from one window to another. The message will be sent
  1515 /** Send a message from one window to another. The message will be sent
  1516  * to ALL windows of the windowclass specified in the first parameter
  1516  * to ALL windows of the windowclass specified in the first parameter
  1517  * @param wnd_class @see WindowClass class
  1517  * @param wnd_class see WindowClass class
  1518  * @param msg Specifies the message to be sent
  1518  * @param msg Specifies the message to be sent
  1519  * @param wparam Specifies additional message-specific information
  1519  * @param wparam Specifies additional message-specific information
  1520  * @param lparam Specifies additional message-specific information
  1520  * @param lparam Specifies additional message-specific information
  1521  */
  1521  */
  1522 void SendWindowMessageClass(WindowClass wnd_class, int msg, int wparam, int lparam)
  1522 void SendWindowMessageClass(WindowClass wnd_class, int msg, int wparam, int lparam)
  1549 	* This is not necessary either, as the only events that
  1549 	* This is not necessary either, as the only events that
  1550 	* can be handled are the 'close application' events
  1550 	* can be handled are the 'close application' events
  1551 	*/
  1551 	*/
  1552 	if (!IsGeneratingWorld()) _current_player = _local_player;
  1552 	if (!IsGeneratingWorld()) _current_player = _local_player;
  1553 
  1553 
  1554 	// Setup event
  1554 	/* Setup event */
  1555 	e.event = WE_KEYPRESS;
  1555 	e.event = WE_KEYPRESS;
  1556 	e.we.keypress.key     = GB(key,  0, 16);
  1556 	e.we.keypress.key     = GB(key,  0, 16);
  1557 	e.we.keypress.keycode = GB(key, 16, 16);
  1557 	e.we.keypress.keycode = GB(key, 16, 16);
  1558 	e.we.keypress.cont = true;
  1558 	e.we.keypress.cont = true;
  1559 
  1559 
  1560 	// check if we have a query string window open before allowing hotkeys
  1560 	/* check if we have a query string window open before allowing hotkeys */
  1561 	if (FindWindowById(WC_QUERY_STRING,       0) != NULL ||
  1561 	if (FindWindowById(WC_QUERY_STRING,       0) != NULL ||
  1562 			FindWindowById(WC_SEND_NETWORK_MSG,   0) != NULL ||
  1562 			FindWindowById(WC_SEND_NETWORK_MSG,   0) != NULL ||
  1563 			FindWindowById(WC_GENERATE_LANDSCAPE, 0) != NULL ||
  1563 			FindWindowById(WC_GENERATE_LANDSCAPE, 0) != NULL ||
  1564 			FindWindowById(WC_CONSOLE,            0) != NULL ||
  1564 			FindWindowById(WC_CONSOLE,            0) != NULL ||
  1565 			FindWindowById(WC_SAVELOAD,           0) != NULL) {
  1565 			FindWindowById(WC_SAVELOAD,           0) != NULL) {
  1566 		query_open = true;
  1566 		query_open = true;
  1567 	}
  1567 	}
  1568 
  1568 
  1569 	// Call the event, start with the uppermost window.
  1569 	/* Call the event, start with the uppermost window. */
  1570 	for (wz = _last_z_window; wz != _z_windows;) {
  1570 	for (wz = _last_z_window; wz != _z_windows;) {
  1571 		Window *w = *--wz;
  1571 		Window *w = *--wz;
  1572 
  1572 
  1573 		// if a query window is open, only call the event for certain window types
  1573 		/* if a query window is open, only call the event for certain window types */
  1574 		if (query_open &&
  1574 		if (query_open &&
  1575 				w->window_class != WC_QUERY_STRING &&
  1575 				w->window_class != WC_QUERY_STRING &&
  1576 				w->window_class != WC_SEND_NETWORK_MSG &&
  1576 				w->window_class != WC_SEND_NETWORK_MSG &&
  1577 				w->window_class != WC_GENERATE_LANDSCAPE &&
  1577 				w->window_class != WC_GENERATE_LANDSCAPE &&
  1578 				w->window_class != WC_CONSOLE &&
  1578 				w->window_class != WC_CONSOLE &&
  1583 		if (!e.we.keypress.cont) break;
  1583 		if (!e.we.keypress.cont) break;
  1584 	}
  1584 	}
  1585 
  1585 
  1586 	if (e.we.keypress.cont) {
  1586 	if (e.we.keypress.cont) {
  1587 		Window *w = FindWindowById(WC_MAIN_TOOLBAR, 0);
  1587 		Window *w = FindWindowById(WC_MAIN_TOOLBAR, 0);
  1588 		// When there is no toolbar w is null, check for that
  1588 		/* When there is no toolbar w is null, check for that */
  1589 		if (w != NULL) w->wndproc(w, &e);
  1589 		if (w != NULL) w->wndproc(w, &e);
  1590 	}
  1590 	}
  1591 }
  1591 }
  1592 
  1592 
  1593 extern void UpdateTileSelection();
  1593 extern void UpdateTileSelection();
  1614 		if (w == NULL || w->flags4 & WF_DISABLE_VP_SCROLL) return;
  1614 		if (w == NULL || w->flags4 & WF_DISABLE_VP_SCROLL) return;
  1615 		vp = IsPtInWindowViewport(w, x, y);
  1615 		vp = IsPtInWindowViewport(w, x, y);
  1616 		if (vp != NULL) {
  1616 		if (vp != NULL) {
  1617 			x -= vp->left;
  1617 			x -= vp->left;
  1618 			y -= vp->top;
  1618 			y -= vp->top;
  1619 			//here allows scrolling in both x and y axis
  1619 			/* here allows scrolling in both x and y axis */
  1620 #define scrollspeed 3
  1620 #define scrollspeed 3
  1621 			if (x - 15 < 0) {
  1621 			if (x - 15 < 0) {
  1622 				WP(w, vp_d).scrollpos_x += (x - 15) * scrollspeed << vp->zoom;
  1622 				WP(w, vp_d).scrollpos_x += (x - 15) * scrollspeed << vp->zoom;
  1623 			} else if (15 - (vp->width - x) > 0) {
  1623 			} else if (15 - (vp->width - x) > 0) {
  1624 				WP(w, vp_d).scrollpos_x += (15 - (vp->width - x)) * scrollspeed << vp->zoom;
  1624 				WP(w, vp_d).scrollpos_x += (15 - (vp->width - x)) * scrollspeed << vp->zoom;
  1683 		if (scrollwheel_scrolling) click = 2; // we are using the scrollwheel in a viewport, so we emulate right mouse button
  1683 		if (scrollwheel_scrolling) click = 2; // we are using the scrollwheel in a viewport, so we emulate right mouse button
  1684 		switch (click) {
  1684 		switch (click) {
  1685 			case 1:
  1685 			case 1:
  1686 				DEBUG(misc, 2, "Cursor: 0x%X (%d)", _cursor.sprite, _cursor.sprite);
  1686 				DEBUG(misc, 2, "Cursor: 0x%X (%d)", _cursor.sprite, _cursor.sprite);
  1687 				if (_thd.place_mode != 0 &&
  1687 				if (_thd.place_mode != 0 &&
  1688 						// query button and place sign button work in pause mode
  1688 						/* query button and place sign button work in pause mode */
  1689 						_cursor.sprite != SPR_CURSOR_QUERY &&
  1689 						_cursor.sprite != SPR_CURSOR_QUERY &&
  1690 						_cursor.sprite != SPR_CURSOR_SIGN &&
  1690 						_cursor.sprite != SPR_CURSOR_SIGN &&
  1691 						_pause_game != 0 &&
  1691 						_pause_game != 0 &&
  1692 						!_cheats.build_in_pause.value) {
  1692 						!_cheats.build_in_pause.value) {
  1693 					return;
  1693 					return;
  1734 	 * This is not necessary either, as the only events that
  1734 	 * This is not necessary either, as the only events that
  1735 	 * can be handled are the 'close application' events
  1735 	 * can be handled are the 'close application' events
  1736 	 */
  1736 	 */
  1737 	if (!IsGeneratingWorld()) _current_player = _local_player;
  1737 	if (!IsGeneratingWorld()) _current_player = _local_player;
  1738 
  1738 
  1739 	// Mouse event?
  1739 	/* Mouse event? */
  1740 	click = 0;
  1740 	click = 0;
  1741 	if (_left_button_down && !_left_button_clicked) {
  1741 	if (_left_button_down && !_left_button_clicked) {
  1742 		_left_button_clicked = true;
  1742 		_left_button_clicked = true;
  1743 		click = 1;
  1743 		click = 1;
  1744 		_input_events_this_tick++;
  1744 		_input_events_this_tick++;
  1791 
  1791 
  1792 	FOR_ALL_WINDOWS(wz) {
  1792 	FOR_ALL_WINDOWS(wz) {
  1793 		if ((*wz)->viewport != NULL) UpdateViewportPosition(*wz);
  1793 		if ((*wz)->viewport != NULL) UpdateViewportPosition(*wz);
  1794 	}
  1794 	}
  1795 	DrawTextMessage();
  1795 	DrawTextMessage();
  1796 	// Redraw mouse cursor in case it was hidden
  1796 	/* Redraw mouse cursor in case it was hidden */
  1797 	DrawMouseCursor();
  1797 	DrawMouseCursor();
  1798 }
  1798 }
  1799 
  1799 
  1800 
  1800 
  1801 int GetMenuItemIndex(const Window *w, int x, int y)
  1801 int GetMenuItemIndex(const Window *w, int x, int y)