changeset 20312:f7c13c96f7e2 draft

(svn r25264) -Feature: linkgraph overlay over main viewport (fonsinchen)
author rubidium <rubidium@openttd.org>
date Sun, 19 May 2013 14:49:25 +0000
parents 889aeb34149a
children 74125e62e4a9
files src/linkgraph/linkgraph_gui.cpp src/main_gui.cpp src/screenshot.cpp src/viewport.cpp src/viewport_func.h src/viewport_type.h src/widgets/link_graph_legend_widget.h
diffstat 7 files changed, 119 insertions(+), 18 deletions(-) [+]
line wrap: on
line diff
--- a/src/linkgraph/linkgraph_gui.cpp
+++ b/src/linkgraph/linkgraph_gui.cpp
@@ -11,6 +11,7 @@
 
 #include "../stdafx.h"
 #include "../window_gui.h"
+#include "../window_func.h"
 #include "../company_base.h"
 #include "../company_gui.h"
 #include "../date_func.h"
@@ -268,7 +269,12 @@
  */
 Point LinkGraphOverlay::GetStationMiddle(const Station *st) const
 {
-	return static_cast<const SmallMapWindow *>(this->window)->GetStationMiddle(st);
+	if (this->window->viewport != NULL) {
+		return GetViewportStationMiddle(this->window->viewport, st);
+	} else {
+		/* assume this is a smallmap */
+		return static_cast<const SmallMapWindow *>(this->window)->GetStationMiddle(st);
+	}
 }
 
 /**
@@ -393,7 +399,7 @@
 {
 	this->InitNested(desc, window_number);
 	this->InvalidateData(0);
-	//this->SetOverlay(FindWindowById(WC_MAIN_WINDOW, 0)->viewport->overlay);
+	this->SetOverlay(FindWindowById(WC_MAIN_WINDOW, 0)->viewport->overlay);
 }
 
 /**
--- a/src/main_gui.cpp
+++ b/src/main_gui.cpp
@@ -29,6 +29,7 @@
 #include "company_func.h"
 #include "toolbar_gui.h"
 #include "statusbar_gui.h"
+#include "linkgraph/linkgraph_gui.h"
 #include "tilehighlight_func.h"
 #include "hotkeys.h"
 
@@ -239,6 +240,11 @@
 
 struct MainWindow : Window
 {
+	uint refresh;
+
+	static const uint LINKGRAPH_REFRESH_PERIOD = 0xff;
+	static const uint LINKGRAPH_DELAY = 0xf;
+
 	MainWindow() : Window()
 	{
 		this->InitNested(&_main_window_desc, 0);
@@ -247,6 +253,18 @@
 
 		NWidgetViewport *nvp = this->GetWidget<NWidgetViewport>(WID_M_VIEWPORT);
 		nvp->InitializeViewport(this, TileXY(32, 32), ZOOM_LVL_VIEWPORT);
+
+		this->viewport->overlay = new LinkGraphOverlay(this, WID_M_VIEWPORT, 0, 0, 3);
+		this->refresh = LINKGRAPH_DELAY;
+	}
+
+	virtual void OnTick()
+	{
+		if (--refresh == 0) {
+			this->viewport->overlay->RebuildCache();
+			this->GetWidget<NWidgetBase>(WID_M_VIEWPORT)->SetDirty(this);
+			this->refresh = LINKGRAPH_REFRESH_PERIOD;
+		}
 	}
 
 	virtual void OnPaint()
@@ -416,6 +434,7 @@
 		this->viewport->scrollpos_y += ScaleByZoom(delta.y, this->viewport->zoom);
 		this->viewport->dest_scrollpos_x = this->viewport->scrollpos_x;
 		this->viewport->dest_scrollpos_y = this->viewport->scrollpos_y;
+		this->refresh = LINKGRAPH_DELAY;
 	}
 
 	virtual void OnMouseWheel(int wheel)
@@ -430,6 +449,7 @@
 		if (this->viewport != NULL) {
 			NWidgetViewport *nvp = this->GetWidget<NWidgetViewport>(WID_M_VIEWPORT);
 			nvp->UpdateViewportCoordinates(this);
+			this->refresh = LINKGRAPH_DELAY;
 		}
 	}
 
--- a/src/screenshot.cpp
+++ b/src/screenshot.cpp
@@ -781,6 +781,7 @@
 	vp->top = 0;
 	vp->width  = UnScaleByZoom(vp->virtual_width,  vp->zoom);
 	vp->height = UnScaleByZoom(vp->virtual_height, vp->zoom);
+	vp->overlay = NULL;
 }
 
 /**
--- a/src/viewport.cpp
+++ b/src/viewport.cpp
@@ -45,6 +45,7 @@
 #include "window_func.h"
 #include "tilehighlight_func.h"
 #include "window_gui.h"
+#include "linkgraph/linkgraph_gui.h"
 
 #include "table/strings.h"
 #include "table/palettes.h"
@@ -218,6 +219,8 @@
 	vp->dest_scrollpos_x = pt.x;
 	vp->dest_scrollpos_y = pt.y;
 
+	vp->overlay = NULL;
+
 	w->viewport = vp;
 	vp->virtual_left = 0;//pt.x;
 	vp->virtual_top = 0;//pt.y;
@@ -1399,22 +1402,8 @@
 	} while (--bottom > 0);
 }
 
-static void ViewportDrawStrings(DrawPixelInfo *dpi, const StringSpriteToDrawVector *sstdv)
+static void ViewportDrawStrings(ZoomLevel zoom, const StringSpriteToDrawVector *sstdv)
 {
-	DrawPixelInfo dp;
-	ZoomLevel zoom;
-
-	_cur_dpi = &dp;
-	dp = *dpi;
-
-	zoom = dp.zoom;
-	dp.zoom = ZOOM_LVL_NORMAL;
-
-	dp.left   = UnScaleByZoom(dp.left,   zoom);
-	dp.top    = UnScaleByZoom(dp.top,    zoom);
-	dp.width  = UnScaleByZoom(dp.width,  zoom);
-	dp.height = UnScaleByZoom(dp.height, zoom);
-
 	const StringSpriteToDraw *ssend = sstdv->End();
 	for (const StringSpriteToDraw *ss = sstdv->Begin(); ss != ssend; ++ss) {
 		TextColour colour = TC_BLACK;
@@ -1497,7 +1486,24 @@
 	if (_draw_bounding_boxes) ViewportDrawBoundingBoxes(&_vd.parent_sprites_to_sort);
 	if (_draw_dirty_blocks) ViewportDrawDirtyBlocks();
 
-	if (_vd.string_sprites_to_draw.Length() != 0) ViewportDrawStrings(&_vd.dpi, &_vd.string_sprites_to_draw);
+	DrawPixelInfo dp = _vd.dpi;
+	ZoomLevel zoom = _vd.dpi.zoom;
+	dp.zoom = ZOOM_LVL_NORMAL;
+	dp.width = UnScaleByZoom(dp.width, zoom);
+	dp.height = UnScaleByZoom(dp.height, zoom);
+	_cur_dpi = &dp;
+
+	/* translate to window coordinates */
+	dp.left = x;
+	dp.top = y;
+
+	if (vp->overlay != NULL) vp->overlay->Draw(&dp);
+
+	/* translate back to world coordinates */
+	dp.left = UnScaleByZoom(_vd.dpi.left, zoom);
+	dp.top = UnScaleByZoom(_vd.dpi.top, zoom);
+
+	if (_vd.string_sprites_to_draw.Length() != 0) ViewportDrawStrings(zoom, &_vd.string_sprites_to_draw);
 
 	_cur_dpi = old_dpi;
 
@@ -1613,6 +1619,7 @@
 		int delta_x = w->viewport->dest_scrollpos_x - w->viewport->scrollpos_x;
 		int delta_y = w->viewport->dest_scrollpos_y - w->viewport->scrollpos_y;
 
+		bool update_overlay = false;
 		if (delta_x != 0 || delta_y != 0) {
 			if (_settings_client.gui.smooth_scroll) {
 				int max_scroll = ScaleByMapSize1D(512 * ZOOM_LVL_BASE);
@@ -1623,11 +1630,14 @@
 				w->viewport->scrollpos_x = w->viewport->dest_scrollpos_x;
 				w->viewport->scrollpos_y = w->viewport->dest_scrollpos_y;
 			}
+			update_overlay = (w->viewport->scrollpos_x == w->viewport->dest_scrollpos_x &&
+								w->viewport->scrollpos_y == w->viewport->dest_scrollpos_y);
 		}
 
 		ClampViewportToMap(vp, w->viewport->scrollpos_x, w->viewport->scrollpos_y);
 
 		SetViewportPosition(w, w->viewport->scrollpos_x, w->viewport->scrollpos_y);
+		if (update_overlay) RebuildViewportOverlay(w);
 	}
 }
 
@@ -1987,6 +1997,15 @@
 	return result;
 }
 
+void RebuildViewportOverlay(Window *w)
+{
+	if (w->viewport->overlay != NULL &&
+			w->viewport->overlay->GetCompanyMask() != 0 &&
+			w->viewport->overlay->GetCargoMask() != 0) {
+		w->viewport->overlay->RebuildCache();
+		w->SetDirty();
+	}
+}
 
 /**
  * Scrolls the viewport in a window to a given location.
@@ -2010,6 +2029,7 @@
 	if (instant) {
 		w->viewport->scrollpos_x = pt.x;
 		w->viewport->scrollpos_y = pt.y;
+		RebuildViewportOverlay(w);
 	}
 
 	w->viewport->dest_scrollpos_x = pt.x;
@@ -2966,3 +2986,15 @@
 {
 	SetObjectToPlace(SPR_CURSOR_MOUSE, PAL_NONE, HT_NONE, WC_MAIN_WINDOW, 0);
 }
+
+Point GetViewportStationMiddle(const ViewPort *vp, const Station *st)
+{
+	int x = TileX(st->xy) * TILE_SIZE;
+	int y = TileY(st->xy) * TILE_SIZE;
+	int z = GetSlopePixelZ(Clamp(x, 0, MapSizeX() * TILE_SIZE - 1), Clamp(y, 0, MapSizeY() * TILE_SIZE - 1));
+
+	Point p = RemapCoords(x, y, z);
+	p.x = UnScaleByZoom(p.x - vp->virtual_left, vp->zoom) + vp->left;
+	p.y = UnScaleByZoom(p.y - vp->virtual_top, vp->zoom) + vp->top;
+	return p;
+}
--- a/src/viewport_func.h
+++ b/src/viewport_func.h
@@ -16,6 +16,7 @@
 #include "viewport_type.h"
 #include "window_type.h"
 #include "tile_type.h"
+#include "station_type.h"
 
 static const int TILE_HEIGHT_STEP = 50; ///< One Z unit tile height difference is displayed as 50m.
 
@@ -67,6 +68,8 @@
 bool ScrollWindowToTile(TileIndex tile, Window *w, bool instant = false);
 bool ScrollWindowTo(int x, int y, int z, Window *w, bool instant = false);
 
+void RebuildViewportOverlay(Window *w);
+
 bool ScrollMainWindowToTile(TileIndex tile, bool instant = false);
 bool ScrollMainWindowTo(int x, int y, int z = -1, bool instant = false);
 
@@ -76,4 +79,6 @@
 
 void MarkTileDirtyByTile(TileIndex tile);
 
+Point GetViewportStationMiddle(const ViewPort *vp, const Station *st);
+
 #endif /* VIEWPORT_FUNC_H */
--- a/src/viewport_type.h
+++ b/src/viewport_type.h
@@ -15,6 +15,8 @@
 #include "zoom_type.h"
 #include "strings_type.h"
 
+class LinkGraphOverlay;
+
 /**
  * Data structure for viewport, display of a part of the world
  */
@@ -30,6 +32,7 @@
 	int virtual_height;  ///< height << zoom
 
 	ZoomLevel zoom; ///< The zoom level of the viewport.
+	LinkGraphOverlay *overlay;
 };
 
 /** Margins for the viewport sign */
new file mode 100644
--- /dev/null
+++ b/src/widgets/link_graph_legend_widget.h
@@ -0,0 +1,34 @@
+/* $Id$ */
+
+/*
+ * This file is part of OpenTTD.
+ * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
+ * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/** @file linkgraph_legend_widget.h Types related to the linkgraph_legend widgets. */
+
+#ifndef WIDGETS_LINKGRAPH_LEGEND_WIDGET_H
+#define WIDGETS_LINKGRAPH_LEGEND_WIDGET_H
+
+/** Widgets of the WC_LINKGRAPH_LEGEND. */
+
+enum LinkGraphLegendWidgets {
+	WID_LGL_CAPTION,           ///< Caption widget.
+	WID_LGL_SATURATION,        ///< Saturation legend.
+	WID_LGL_SATURATION_FIRST,
+	WID_LGL_SATURATION_LAST = WID_LGL_SATURATION_FIRST + 11,
+	WID_LGL_COMPANIES,         ///< Company selection widget.
+	WID_LGL_COMPANY_FIRST,
+	WID_LGL_COMPANY_LAST = WID_LGL_COMPANY_FIRST + MAX_COMPANIES - 1,
+	WID_LGL_COMPANIES_ALL,
+	WID_LGL_COMPANIES_NONE,
+	WID_LGL_CARGOES,           ///< Cargo selection widget.
+	WID_LGL_CARGO_FIRST,
+	WID_LGL_CARGO_LAST = WID_LGL_CARGO_FIRST + NUM_CARGO - 1,
+	WID_LGL_CARGOES_ALL,
+	WID_LGL_CARGOES_NONE,
+};
+
+#endif /* WIDGETS_LINKGRAPH_LEGEND_WIDGET_H */