--- 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);
}