src/viewport.cpp
branchNewGRF_ports
changeset 10724 68a692eacf22
parent 10310 c8b1eafc56bd
child 10731 67db0d431d5e
--- a/src/viewport.cpp	Fri Apr 25 02:15:34 2008 +0000
+++ b/src/viewport.cpp	Mon May 26 20:45:25 2008 +0000
@@ -1,6 +1,6 @@
 /* $Id$ */
 
-/** @file viewport.cpp
+/** @file viewport.cpp Handling of all viewports.
  *
  * \verbatim
  * The in-game coordinate system looks like this *
@@ -46,6 +46,9 @@
 #include "station_func.h"
 #include "core/alloc_type.hpp"
 #include "misc/smallvec.h"
+#include "window_func.h"
+#include "tilehighlight_func.h"
+#include "window_gui.h"
 
 #include "table/sprites.h"
 #include "table/strings.h"
@@ -143,8 +146,6 @@
 static TileInfo *_cur_ti;
 bool _draw_bounding_boxes = false;
 
-extern void SmallMapCenterOnCurrentPos(Window *w);
-
 static Point MapXYZToViewport(const ViewPort *vp, uint x, uint y, uint z)
 {
 	Point p = RemapCoords(x, y, z);
@@ -155,7 +156,7 @@
 
 void DeleteWindowViewport(Window *w)
 {
-	w->viewport->width = 0;
+	free(w->viewport);
 	w->viewport = NULL;
 }
 
@@ -176,7 +177,7 @@
 {
 	assert(w->viewport == NULL);
 
-	ViewPort *vp = &(WP(w, vp_d).vp_data);
+	ViewportData *vp = CallocT<ViewportData>(1);
 
 	vp->left = x + w->left;
 	vp->top = y + w->top;
@@ -193,21 +194,21 @@
 	if (follow_flags & 0x80000000) {
 		const Vehicle *veh;
 
-		WP(w, vp_d).follow_vehicle = (VehicleID)(follow_flags & 0xFFFF);
-		veh = GetVehicle(WP(w, vp_d).follow_vehicle);
+		vp->follow_vehicle = (VehicleID)(follow_flags & 0xFFFF);
+		veh = GetVehicle(vp->follow_vehicle);
 		pt = MapXYZToViewport(vp, veh->x_pos, veh->y_pos, veh->z_pos);
 	} else {
 		uint x = TileX(follow_flags) * TILE_SIZE;
 		uint y = TileY(follow_flags) * TILE_SIZE;
 
-		WP(w, vp_d).follow_vehicle = INVALID_VEHICLE;
+		vp->follow_vehicle = INVALID_VEHICLE;
 		pt = MapXYZToViewport(vp, x, y, GetSlopeZ(x, y));
 	}
 
-	WP(w, vp_d).scrollpos_x = pt.x;
-	WP(w, vp_d).scrollpos_y = pt.y;
-	WP(w, vp_d).dest_scrollpos_x = pt.x;
-	WP(w, vp_d).dest_scrollpos_y = pt.y;
+	vp->scrollpos_x = pt.x;
+	vp->scrollpos_y = pt.y;
+	vp->dest_scrollpos_x = pt.x;
+	vp->dest_scrollpos_y = pt.y;
 
 	w->viewport = vp;
 	vp->virtual_left = 0;//pt.x;
@@ -425,9 +426,7 @@
 Point GetTileZoomCenterWindow(bool in, Window * w)
 {
 	int x, y;
-	ViewPort * vp;
-
-	vp = w->viewport;
+	ViewPort *vp = w->viewport;
 
 	if (in) {
 		x = ((_cursor.pos.x - vp->left) >> 1) + (vp->width >> 2);
@@ -1563,17 +1562,17 @@
 	ViewportDrawChk(vp, left, top, right, bottom);
 }
 
-void DrawWindowViewport(const Window *w)
+void Window::DrawViewport() const
 {
 	DrawPixelInfo *dpi = _cur_dpi;
 
-	dpi->left += w->left;
-	dpi->top += w->top;
-
-	ViewportDraw(w->viewport, dpi->left, dpi->top, dpi->left + dpi->width, dpi->top + dpi->height);
-
-	dpi->left -= w->left;
-	dpi->top -= w->top;
+	dpi->left += this->left;
+	dpi->top += this->top;
+
+	ViewportDraw(this->viewport, dpi->left, dpi->top, dpi->left + dpi->width, dpi->top + dpi->height);
+
+	dpi->left -= this->left;
+	dpi->top -= this->top;
 }
 
 static inline void ClampViewportToMap(const ViewPort *vp, int &x, int &y)
@@ -1604,33 +1603,33 @@
 {
 	const ViewPort *vp = w->viewport;
 
-	if (WP(w, vp_d).follow_vehicle != INVALID_VEHICLE) {
-		const Vehicle* veh = GetVehicle(WP(w, vp_d).follow_vehicle);
+	if (w->viewport->follow_vehicle != INVALID_VEHICLE) {
+		const Vehicle* veh = GetVehicle(w->viewport->follow_vehicle);
 		Point pt = MapXYZToViewport(vp, veh->x_pos, veh->y_pos, veh->z_pos);
 
 		SetViewportPosition(w, pt.x, pt.y);
 	} else {
 		/* Ensure the destination location is within the map */
-		ClampViewportToMap(vp, WP(w, vp_d).dest_scrollpos_x, WP(w, vp_d).dest_scrollpos_y);
-
-		int delta_x = WP(w, vp_d).dest_scrollpos_x - WP(w, vp_d).scrollpos_x;
-		int delta_y = WP(w, vp_d).dest_scrollpos_y - WP(w, vp_d).scrollpos_y;
+		ClampViewportToMap(vp, w->viewport->dest_scrollpos_x, w->viewport->dest_scrollpos_y);
+
+		int delta_x = w->viewport->dest_scrollpos_x - w->viewport->scrollpos_x;
+		int delta_y = w->viewport->dest_scrollpos_y - w->viewport->scrollpos_y;
 
 		if (delta_x != 0 || delta_y != 0) {
 			if (_patches.smooth_scroll) {
 				int max_scroll = ScaleByMapSize1D(512);
 				/* Not at our desired positon yet... */
-				WP(w, vp_d).scrollpos_x += Clamp(delta_x / 4, -max_scroll, max_scroll);
-				WP(w, vp_d).scrollpos_y += Clamp(delta_y / 4, -max_scroll, max_scroll);
+				w->viewport->scrollpos_x += Clamp(delta_x / 4, -max_scroll, max_scroll);
+				w->viewport->scrollpos_y += Clamp(delta_y / 4, -max_scroll, max_scroll);
 			} else {
-				WP(w, vp_d).scrollpos_x = WP(w, vp_d).dest_scrollpos_x;
-				WP(w, vp_d).scrollpos_y = WP(w, vp_d).dest_scrollpos_y;
+				w->viewport->scrollpos_x = w->viewport->dest_scrollpos_x;
+				w->viewport->scrollpos_y = w->viewport->dest_scrollpos_y;
 			}
 		}
 
-		ClampViewportToMap(vp, WP(w, vp_d).scrollpos_x, WP(w, vp_d).scrollpos_y);
-
-		SetViewportPosition(w, WP(w, vp_d).scrollpos_x, WP(w, vp_d).scrollpos_y);
+		ClampViewportToMap(vp, w->viewport->scrollpos_x, w->viewport->scrollpos_y);
+
+		SetViewportPosition(w, w->viewport->scrollpos_x, w->viewport->scrollpos_y);
 	}
 }
 
@@ -2080,14 +2079,7 @@
 	_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->wndproc(w, &e);
-	}
+	if (w != NULL) w->OnPlaceObject(pt, TileVirtXY(pt.x, pt.y));
 }
 
 
@@ -2096,42 +2088,21 @@
 {
 	/* The slope cannot be acquired outside of the map, so make sure we are always within the map. */
 	Point pt = MapXYZToViewport(w->viewport, x, y, GetSlopeZ(Clamp(x, 0, MapSizeX()), Clamp(y, 0, MapSizeY())));
-	WP(w, vp_d).follow_vehicle = INVALID_VEHICLE;
-
-	if (WP(w, vp_d).dest_scrollpos_x == pt.x && WP(w, vp_d).dest_scrollpos_y == pt.y)
+	w->viewport->follow_vehicle = INVALID_VEHICLE;
+
+	if (w->viewport->dest_scrollpos_x == pt.x && w->viewport->dest_scrollpos_y == pt.y)
 		return false;
 
 	if (instant) {
-		WP(w, vp_d).scrollpos_x = pt.x;
-		WP(w, vp_d).scrollpos_y = pt.y;
+		w->viewport->scrollpos_x = pt.x;
+		w->viewport->scrollpos_y = pt.y;
 	}
 
-	WP(w, vp_d).dest_scrollpos_x = pt.x;
-	WP(w, vp_d).dest_scrollpos_y = pt.y;
+	w->viewport->dest_scrollpos_x = pt.x;
+	w->viewport->dest_scrollpos_y = pt.y;
 	return true;
 }
 
-
-bool ScrollMainWindowTo(int x, int y, bool instant)
-{
-	Window *w;
-	bool res = ScrollWindowTo(x, y, FindWindowById(WC_MAIN_WINDOW, 0), instant);
-
-	/* If a user scrolls to a tile (via what way what so ever) and already is on
-	 *  that tile (e.g.: pressed twice), move the smallmap to that location,
-	 *  so you directly see where you are on the smallmap. */
-
-	if (res) return res;
-
-	w = FindWindowById(WC_SMALLMAP, 0);
-	if (w == NULL) return res;
-
-	SmallMapCenterOnCurrentPos(w);
-
-	return res;
-}
-
-
 bool ScrollMainWindowToTile(TileIndex tile, bool instant)
 {
 	return ScrollMainWindowTo(TileX(tile) * TILE_SIZE + TILE_SIZE / 2, TileY(tile) * TILE_SIZE + TILE_SIZE / 2, instant);
@@ -2251,7 +2222,7 @@
 }
 
 /** highlighting tiles while only going over them with the mouse */
-void VpStartPlaceSizing(TileIndex tile, ViewportPlaceMethod method, byte process)
+void VpStartPlaceSizing(TileIndex tile, ViewportPlaceMethod method, ViewportDragDropSelectionProcess process)
 {
 	_thd.select_method = method;
 	_thd.select_proc   = process;
@@ -2718,16 +2689,10 @@
 /** 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;
@@ -2735,9 +2700,7 @@
 
 	/* 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->wndproc(w, &e);
+		w->OnPlaceDrag(_thd.select_method, _thd.select_proc, GetTileBelowCursor());
 		return false;
 	}
 
@@ -2746,7 +2709,7 @@
 	_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;
@@ -2757,12 +2720,7 @@
 	}
 	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->wndproc(w, &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;
 }
@@ -2776,12 +2734,18 @@
 
 void SetObjectToPlace(CursorID icon, SpriteID pal, ViewportHighlightMode mode, WindowClass window_class, WindowNumber window_num)
 {
-	Window *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);
+		Window *w = FindWindowById(_thd.window_class, _thd.window_number);
+		if (w != NULL) {
+			/* Call the abort function, but set the window class to something
+			 * that will never be used to avoid infinite loops. Setting it to
+			 * the 'next' window class must not be done because recursion into
+			 * this function might in some cases reset the newly set object to
+			 * place or not properly reset the original selection. */
+			_thd.window_class = WC_INVALID;
+			w->OnPlaceObjectAbort();
+		}
 	}
 
 	SetTileSelectSize(1, 1);
@@ -2802,13 +2766,17 @@
 	if (mode == VHM_SPECIAL) // special tools, like tunnels or docks start with presizing mode
 		VpStartPreSizing();
 
-	if ( (int)icon < 0)
+	if ((int)icon < 0) {
 		SetAnimatedMouseCursor(_animcursors[~icon]);
-	else
+	} else {
 		SetMouseCursor(icon, pal);
+	}
+
 }
 
 void ResetObjectToPlace()
 {
+	_thd.FSMportLayout = NULL;  // ensure irregular airport support disabled
+	_thd.FSMportMask = NULL;
 	SetObjectToPlace(SPR_CURSOR_MOUSE, PAL_NONE, VHM_NONE, WC_MAIN_WINDOW, 0);
 }