← Back to team overview

widelands-dev team mailing list archive

[Merge] lp:~widelands-dev/widelands/pass_through_infos into lp:widelands

 

SirVer has proposed merging lp:~widelands-dev/widelands/pass_through_infos into lp:widelands.

Requested reviews:
  Widelands Developers (widelands-dev)

For more details, see:
https://code.launchpad.net/~widelands-dev/widelands/pass_through_infos/+merge/329691

Further untangle Interactive* classes.

- MapView no longer has knowledge of InteractiveBase instead it takes the Map. This means that InteractiveBase contains more of its own logic (like freeze of the selection marker).
- Give the Interacitve* classes their own draw() functions. Differentiating logic of drawing (for example visibility of fields and so on) can be moved into these functions to detangle the drawing code some more. This allowed to move draw_bobs() and draw_immovables() logic out of InteractiveBase into EditorInteractive.
- InteractiveBase::map_clicked and *::node_action() takes the node_and_triangle that was clicked instead of side loading it through the current fsel position.
-- 
Your team Widelands Developers is requested to review the proposed merge of lp:~widelands-dev/widelands/pass_through_infos into lp:widelands.
=== modified file 'src/editor/editorinteractive.cc'
--- src/editor/editorinteractive.cc	2017-08-20 17:45:42 +0000
+++ src/editor/editorinteractive.cc	2017-08-27 15:50:48 +0000
@@ -164,7 +164,9 @@
 	set_display_flag(InteractiveBase::dfDebug, false);
 #endif
 
-	map_view()->fieldclicked.connect(boost::bind(&EditorInteractive::map_clicked, this, false));
+	map_view()->field_clicked.connect([this](const Widelands::NodeAndTriangle<>& node_and_triangle) {
+		map_clicked(node_and_triangle, false);
+	});
 
 	// Subscribe to changes of the resource type on a field..
 	field_resource_changed_subscriber_ =
@@ -288,9 +290,10 @@
 	end_modal<UI::Panel::Returncodes>(UI::Panel::Returncodes::kBack);
 }
 
-void EditorInteractive::map_clicked(bool should_draw) {
+void EditorInteractive::map_clicked(const Widelands::NodeAndTriangle<>& node_and_triangle,
+                                    const bool should_draw) {
 	history_->do_action(tools_->current(), tools_->use_tool, *egbase().mutable_map(),
-	                    egbase().world(), get_sel_pos(), *this, should_draw);
+	                    egbase().world(), node_and_triangle, *this, should_draw);
 	set_need_save(true);
 }
 
@@ -308,14 +311,22 @@
 	return InteractiveBase::handle_mousepress(btn, x, y);
 }
 
+void EditorInteractive::draw(RenderTarget& dst) {
+	const GameRenderer::Overlays overlays{get_text_to_draw(), {}};
+	map_view()->draw_map_view(
+	   egbase(), overlays,
+	   draw_immovables_ ? GameRenderer::DrawImmovables::kYes : GameRenderer::DrawImmovables::kNo,
+	   draw_bobs_ ? GameRenderer::DrawBobs::kYes : GameRenderer::DrawBobs::kNo, nullptr, &dst);
+}
+
 /// Needed to get freehand painting tools (hold down mouse and move to edit).
 void EditorInteractive::set_sel_pos(Widelands::NodeAndTriangle<> const sel) {
 	bool const target_changed = tools_->current().operates_on_triangles() ?
-	                               sel.triangle != get_sel_pos().triangle :
-	                               sel.node != get_sel_pos().node;
+	                               sel.triangle != sel.triangle :
+	                               sel.node != sel.node;
 	InteractiveBase::set_sel_pos(sel);
 	if (target_changed && is_painting_)
-		map_clicked(true);
+		map_clicked(sel, true);
 }
 
 void EditorInteractive::set_sel_radius_and_update_menu(uint32_t const val) {
@@ -350,15 +361,13 @@
 }
 
 void EditorInteractive::toggle_immovables() {
-	const bool value = !draw_immovables();
-	set_draw_immovables(value);
-	toggle_immovables_->set_perm_pressed(value);
+	draw_immovables_ = !draw_immovables_;
+	toggle_immovables_->set_perm_pressed(draw_immovables_);
 }
 
 void EditorInteractive::toggle_bobs() {
-	const bool value = !draw_bobs();
-	set_draw_bobs(value);
-	toggle_bobs_->set_perm_pressed(value);
+	draw_bobs_ = !draw_bobs_;
+	toggle_bobs_->set_perm_pressed(draw_bobs_);
 }
 
 bool EditorInteractive::handle_key(bool const down, SDL_Keysym const code) {

=== modified file 'src/editor/editorinteractive.h'
--- src/editor/editorinteractive.h	2017-08-17 13:37:32 +0000
+++ src/editor/editorinteractive.h	2017-08-27 15:50:48 +0000
@@ -97,7 +97,7 @@
 	void start() override;
 	void think() override;
 
-	void map_clicked(bool draw = false);
+	void map_clicked(const Widelands::NodeAndTriangle<>& node_and_triangle, bool draw);
 	void set_sel_pos(Widelands::NodeAndTriangle<>) override;
 	void set_sel_radius_and_update_menu(uint32_t);
 	void start_painting();
@@ -107,6 +107,7 @@
 	bool handle_key(bool down, SDL_Keysym) override;
 	bool handle_mousepress(uint8_t btn, int32_t x, int32_t y) override;
 	bool handle_mouserelease(uint8_t btn, int32_t x, int32_t y) override;
+	void draw(RenderTarget&) override;
 
 	void select_tool(EditorTool&, EditorTool::ToolIndex);
 
@@ -188,6 +189,9 @@
 
 	std::unique_ptr<Tools> tools_;
 	std::unique_ptr<EditorHistory> history_;
+
+	bool draw_immovables_ = true;
+	bool draw_bobs_ = true;
 };
 
 #endif  // end of include guard: WL_EDITOR_EDITORINTERACTIVE_H

=== modified file 'src/graphic/game_renderer.cc'
--- src/graphic/game_renderer.cc	2017-08-19 22:22:20 +0000
+++ src/graphic/game_renderer.cc	2017-08-27 15:50:48 +0000
@@ -279,32 +279,13 @@
 GameRenderer::~GameRenderer() {
 }
 
-void GameRenderer::rendermap(const Widelands::EditorGameBase& egbase,
-                             const Vector2f& viewpoint,
-                             const float zoom,
-                             const Widelands::Player& player,
-                             const Overlays& overlays,
-                             RenderTarget* dst) {
-	draw(egbase, viewpoint, zoom, overlays, DrawImmovables::kYes, DrawBobs::kYes, &player, dst);
-}
-
-void GameRenderer::rendermap(const Widelands::EditorGameBase& egbase,
-                             const Vector2f& viewpoint,
-                             const float zoom,
-                             const Overlays& overlays,
-                             const DrawImmovables& draw_immovables,
-                             const DrawBobs& draw_bobs,
-                             RenderTarget* dst) {
-	draw(egbase, viewpoint, zoom, overlays, draw_immovables, draw_bobs, nullptr, dst);
-}
-
-void GameRenderer::draw(const EditorGameBase& egbase,
+void GameRenderer::render(const EditorGameBase& egbase,
                         const Vector2f& viewpoint,
                         const float zoom,
+                        const Player* player,
                         const Overlays& overlays,
                         const DrawImmovables& draw_immovables,
                         const DrawBobs& draw_bobs,
-                        const Player* player,
                         RenderTarget* dst) {
 	assert(viewpoint.x >= 0);  // divisions involving negative numbers are bad
 	assert(viewpoint.y >= 0);

=== modified file 'src/graphic/game_renderer.h'
--- src/graphic/game_renderer.h	2017-08-16 08:59:09 +0000
+++ src/graphic/game_renderer.h	2017-08-27 15:50:48 +0000
@@ -49,39 +49,20 @@
 	GameRenderer();
 	~GameRenderer();
 
-	// Renders the map from a player's point of view into the given drawing
-	// window. The 'viewpoint' is the top left screens pixel map pixel and
-	// 'scale' is the magnification of the view.
-	void rendermap(const Widelands::EditorGameBase& egbase,
-	               const Vector2f& viewpoint,
-	               float scale,
-	               const Widelands::Player& player,
-	               const Overlays& overlays,
-	               RenderTarget* dst);
-
-	// Renders the map from an omniscient perspective. This is used
-	// for spectators, players that see all, and in the editor. Only in the editor we allow toggling
-	// of immovables and bobs.
-	void rendermap(const Widelands::EditorGameBase& egbase,
-	               const Vector2f& viewpoint,
-	               float scale,
-	               const Overlays& overlays,
-	               const DrawImmovables& draw_immovables,
-	               const DrawBobs& draw_bobs,
-	               RenderTarget* dst);
-
-private:
-	// Draw the map for the given parameters (see rendermap). 'player'
-	// can be nullptr in which case the whole map is drawn.
-	void draw(const Widelands::EditorGameBase& egbase,
+	// Renders the map from a 'player's point of view (or omniscient if nullptr)
+	// into the given drawing window. The 'viewpoint' is the top left screens
+	// pixel map pixel and 'scale' is the magnification of the view.
+	void render(const Widelands::EditorGameBase& egbase,
 	          const Vector2f& viewpoint,
-	          float scale,
+	          float zoom,
+	          const Widelands::Player* player,
 	          const Overlays& overlays,
 	          const DrawImmovables& draw_immovables,
 	          const DrawBobs& draw_bobs,
-	          const Widelands::Player* player,
 	          RenderTarget* dst);
 
+private:
+
 	// This is owned and handled by us, but handed to the RenderQueue, so we
 	// basically promise that this stays valid for one frame.
 	FieldsToDraw fields_to_draw_;

=== modified file 'src/logic/map_objects/tribes/ship.h'
--- src/logic/map_objects/tribes/ship.h	2017-08-16 14:30:17 +0000
+++ src/logic/map_objects/tribes/ship.h	2017-08-27 15:50:48 +0000
@@ -59,7 +59,7 @@
 
 	Serial serial;
 
-	enum class Action { kRefresh, kClose, kNoPortLeft };
+	enum class Action { kClose, kNoPortLeft };
 	const Action action;
 
 	NoteShipWindow(Serial init_serial, const Action& init_action)

=== modified file 'src/scripting/lua_ui.cc'
--- src/scripting/lua_ui.cc	2017-08-18 02:28:27 +0000
+++ src/scripting/lua_ui.cc	2017-08-27 15:50:48 +0000
@@ -575,9 +575,12 @@
       :type field: :class:`wl.map.Field`
 */
 int LuaMapView::click(lua_State* L) {
-	get()->map_view()->mouse_to_field(
-	   (*get_user_class<LuaMaps::LuaField>(L, 2))->coords(), MapView::Transition::Jump);
-	get()->map_view()->fieldclicked();
+	const auto field = *get_user_class<LuaMaps::LuaField>(L, 2);
+	get()->map_view()->mouse_to_field(field->coords(), MapView::Transition::Jump);
+
+	Widelands::NodeAndTriangle<> node_and_triangle;
+	node_and_triangle.node = field->coords();
+	get()->map_view()->field_clicked(node_and_triangle);
 	return 0;
 }
 

=== modified file 'src/wui/CMakeLists.txt'
--- src/wui/CMakeLists.txt	2017-08-11 20:01:03 +0000
+++ src/wui/CMakeLists.txt	2017-08-27 15:50:48 +0000
@@ -111,7 +111,6 @@
     logic_widelands_geometry
     ui_basic
     widelands_ball_of_mud
-    wui
     wui_mapview_pixelfunctions
 )
 

=== modified file 'src/wui/fieldaction.cc'
--- src/wui/fieldaction.cc	2017-08-19 22:22:20 +0000
+++ src/wui/fieldaction.cc	2017-08-27 15:50:48 +0000
@@ -255,7 +255,6 @@
      workarea_preview_overlay_id_(0),
      attack_box_(nullptr) {
 	ib->set_sel_freeze(true);
-
 	set_center_panel(&tabpanel_);
 }
 

=== modified file 'src/wui/interactive_base.cc'
--- src/wui/interactive_base.cc	2017-08-19 22:22:20 +0000
+++ src/wui/interactive_base.cc	2017-08-27 15:50:48 +0000
@@ -67,8 +67,7 @@
 InteractiveBase::InteractiveBase(EditorGameBase& the_egbase, Section& global_s)
    : UI::Panel(nullptr, 0, 0, g_gr->get_xres(), g_gr->get_yres()),
      show_workarea_preview_(global_s.get_bool("workareapreview", true)),
-     // TODO(sirver): MapView should no longer have knowledge of InteractiveBase.
-     map_view_(this, 0, 0, g_gr->get_xres(), g_gr->get_yres(), *this),
+     map_view_(this, the_egbase.map(), 0, 0, g_gr->get_xres(), g_gr->get_yres()),
      // Initialize chatoveraly before the toolbar so it is below
      chat_overlay_(new ChatOverlay(this, 10, 25, get_w() / 2, get_h() - 25)),
      toolbar_(this, 0, 0, UI::Box::Horizontal),
@@ -83,8 +82,6 @@
      lastframe_(SDL_GetTicks()),
      frametime_(0),
      avg_usframetime_(0),
-     draw_immovables_(true),
-     draw_bobs_(true),
      road_buildhelp_overlay_jobid_(0),
      buildroad_(nullptr),
      road_build_player_(0),
@@ -115,6 +112,14 @@
 
 	toolbar_.set_layout_toplevel(true);
 	map_view_.changeview.connect([this] { mainview_move(); });
+	map_view()->field_clicked.connect([this](const Widelands::NodeAndTriangle<>& node_and_triangle) {
+		set_sel_pos(node_and_triangle);
+	});
+	map_view_.track_selection.connect([this](const Widelands::NodeAndTriangle<>& node_and_triangle) {
+		if (!sel_.freeze) {
+			set_sel_pos(node_and_triangle);
+		}
+	});
 
 	set_border_snap_distance(global_s.get_int("border_snap_distance", 0));
 	set_panel_snap_distance(global_s.get_int("panel_snap_distance", 10));
@@ -202,6 +207,19 @@
 	sel_.pic = image;
 	set_sel_pos(get_sel_pos());  //  redraw
 }
+
+TextToDraw InteractiveBase::get_text_to_draw() const {
+	TextToDraw text_to_draw = TextToDraw::kNone;
+	auto display_flags = get_display_flags();
+	if (display_flags & InteractiveBase::dfShowCensus) {
+		text_to_draw = text_to_draw | TextToDraw::kCensus;
+	}
+	if (display_flags & InteractiveBase::dfShowStatistics) {
+		text_to_draw = text_to_draw | TextToDraw::kStatistics;
+	}
+	return text_to_draw;
+}
+
 void InteractiveBase::unset_sel_picture() {
 	set_sel_picture(g_gr->images().get("images/ui_basic/fsel.png"));
 }
@@ -215,22 +233,6 @@
 	on_buildhelp_changed(t);
 }
 
-bool InteractiveBase::draw_bobs() const {
-	return draw_bobs_;
-}
-
-void InteractiveBase::set_draw_bobs(const bool value) {
-	draw_bobs_ = value;
-}
-
-bool InteractiveBase::draw_immovables() const {
-	return draw_immovables_;
-}
-
-void InteractiveBase::set_draw_immovables(const bool value) {
-	draw_immovables_ = value;
-}
-
 void InteractiveBase::toggle_buildhelp() {
 	show_buildhelp(!field_overlay_manager_->buildhelp());
 }
@@ -344,10 +346,6 @@
 	UI::Panel::think();
 }
 
-void InteractiveBase::draw(RenderTarget& dst) {
-	map_view_.draw(dst);
-}
-
 bool InteractiveBase::handle_mousepress(uint8_t btn, int32_t x, int32_t y) {
 	return map_view_.handle_mousepress(btn, x, y);
 }

=== modified file 'src/wui/interactive_base.h'
--- src/wui/interactive_base.h	2017-08-17 15:34:45 +0000
+++ src/wui/interactive_base.h	2017-08-27 15:50:48 +0000
@@ -85,7 +85,6 @@
 	virtual Widelands::Player* get_player() const = 0;
 
 	void think() override;
-	void draw(RenderTarget&) override;
 	bool handle_mousepress(uint8_t btn, int32_t x, int32_t y) override;
 	bool handle_mouserelease(uint8_t btn, int32_t x, int32_t y) override;
 	bool
@@ -97,9 +96,6 @@
 	const Widelands::NodeAndTriangle<>& get_sel_pos() const {
 		return sel_.pos;
 	}
-	bool get_sel_freeze() const {
-		return sel_.freeze;
-	}
 
 	// Returns true if the buildhelp is currently displayed.
 	bool buildhelp() const;
@@ -107,14 +103,6 @@
 	// Sets if the buildhelp should be displayed. Will also call on_buildhelp_changed().
 	void show_buildhelp(bool t);
 
-	// Returns true if bobs or immovables should be rendered.
-	bool draw_bobs() const;
-	bool draw_immovables() const;
-
-	// Sets if bobs or immovables should be rendered.
-	void set_draw_bobs(bool value);
-	void set_draw_immovables(bool value);
-
 	/**
 	 * sel_triangles determines whether the mouse pointer selects triangles.
 	 * (False meas that it selects nodes.)
@@ -224,10 +212,14 @@
 	ChatOverlay* chat_overlay() {
 		return chat_overlay_;
 	}
+
 	UI::Box* toolbar() {
 		return &toolbar_;
 	}
 
+	// Returns the information which overlay text should currently be drawn.
+	TextToDraw get_text_to_draw() const;
+
 private:
 	int32_t stereo_position(Widelands::Coords position_map);
 	void resize_chat_overlay();
@@ -284,8 +276,6 @@
 	uint32_t lastframe_;        //  system time (milliseconds)
 	uint32_t frametime_;        //  in millseconds
 	uint32_t avg_usframetime_;  //  in microseconds!
-	bool draw_immovables_;
-	bool draw_bobs_;
 
 	FieldOverlayManager::OverlayId road_buildhelp_overlay_jobid_;
 	Widelands::CoordPath* buildroad_;  //  path for the new road

=== modified file 'src/wui/interactive_gamebase.h'
--- src/wui/interactive_gamebase.h	2017-08-13 18:02:53 +0000
+++ src/wui/interactive_gamebase.h	2017-08-27 15:50:48 +0000
@@ -67,7 +67,13 @@
 	virtual bool can_act(Widelands::PlayerNumber) const = 0;
 	virtual Widelands::PlayerNumber player_number() const = 0;
 
-	virtual void node_action() = 0;
+	// Only the 'InteractiveGameBase' has all information of what should be
+	// drawn into a map_view (i.e. which overlays are available). The
+	// 'WatchWindow' does not have this information, but needs to draw
+	// 'map_views', hence this function.
+	virtual void draw_map_view(MapView* map_view, RenderTarget* dst) = 0;
+
+	virtual void node_action(const Widelands::NodeAndTriangle<>& node_and_triangle) = 0;
 	const PlayerType& get_playertype() const {
 		return playertype_;
 	}

=== modified file 'src/wui/interactive_player.cc'
--- src/wui/interactive_player.cc	2017-08-18 02:28:27 +0000
+++ src/wui/interactive_player.cc	2017-08-27 15:50:48 +0000
@@ -114,7 +114,9 @@
 	};
 
 	set_player_number(plyn);
-	map_view()->fieldclicked.connect(boost::bind(&InteractivePlayer::node_action, this));
+	map_view()->field_clicked.connect([this](const Widelands::NodeAndTriangle<>& node_and_triangle) {
+			node_action(node_and_triangle);
+	});
 
 	adjust_toolbar_position();
 
@@ -169,6 +171,21 @@
 	}
 }
 
+void InteractivePlayer::draw(RenderTarget& dst) {
+	// Bail out if the game isn't actually loaded.
+	// This fixes a crash with displaying an error dialog during loading.
+	if (!game().is_loaded())
+		return;
+
+	draw_map_view(map_view(), &dst);
+}
+
+void InteractivePlayer::draw_map_view(MapView* map_view, RenderTarget* dst) {
+	const GameRenderer::Overlays overlays{get_text_to_draw(), road_building_preview()};
+	map_view->draw_map_view(egbase(), overlays, GameRenderer::DrawImmovables::kYes,
+	                        GameRenderer::DrawBobs::kYes, &player(), dst);
+}
+
 void InteractivePlayer::popup_message(Widelands::MessageId const id,
                                       const Widelands::Message& message) {
 	message_menu_.create();
@@ -191,13 +208,13 @@
 }
 
 /// Player has clicked on the given node; bring up the context menu.
-void InteractivePlayer::node_action() {
+void InteractivePlayer::node_action(const Widelands::NodeAndTriangle<>& node_and_triangle) {
 	const Map& map = egbase().map();
-	if (1 < player().vision(Map::get_index(get_sel_pos().node, map.get_width()))) {
+	if (1 < player().vision(Map::get_index(node_and_triangle.node, map.get_width()))) {
 		// Special case for buildings
-		if (upcast(Building, building, map.get_immovable(get_sel_pos().node)))
+		if (upcast(Building, building, map.get_immovable(node_and_triangle.node)))
 			if (can_see(building->owner().player_number())) {
-				show_building_window(get_sel_pos().node, false);
+				show_building_window(node_and_triangle.node, false);
 				return;
 			}
 

=== modified file 'src/wui/interactive_player.h'
--- src/wui/interactive_player.h	2017-08-13 18:02:53 +0000
+++ src/wui/interactive_player.h	2017-08-27 15:50:48 +0000
@@ -51,8 +51,9 @@
 	bool can_see(Widelands::PlayerNumber) const override;
 	bool can_act(Widelands::PlayerNumber) const override;
 	Widelands::PlayerNumber player_number() const override;
+	void draw_map_view(MapView* map_view, RenderTarget* dst) override;
 
-	void node_action() override;
+	void node_action(const Widelands::NodeAndTriangle<>& node_and_triangle) override;
 
 	bool handle_key(bool down, SDL_Keysym) override;
 
@@ -70,6 +71,7 @@
 	// For load
 	void cleanup_for_load() override;
 	void think() override;
+	void draw(RenderTarget& dst) override;
 
 	void set_flag_to_connect(const Widelands::Coords& location) {
 		flag_to_connect_ = location;

=== modified file 'src/wui/interactive_spectator.cc'
--- src/wui/interactive_spectator.cc	2017-08-18 02:28:27 +0000
+++ src/wui/interactive_spectator.cc	2017-08-27 15:50:48 +0000
@@ -95,7 +95,23 @@
 	adjust_toolbar_position();
 
 	// Setup all screen elements
-	map_view()->fieldclicked.connect(boost::bind(&InteractiveSpectator::node_action, this));
+	map_view()->field_clicked.connect([this](const Widelands::NodeAndTriangle<>& node_and_triangle) {
+		node_action(node_and_triangle);
+	});
+}
+
+void InteractiveSpectator::draw(RenderTarget& dst) {
+	// This fixes a crash with displaying an error dialog during loading.
+	if (!game().is_loaded())
+		return;
+
+	draw_map_view(map_view(), &dst);
+}
+
+void InteractiveSpectator::draw_map_view(MapView* map_view, RenderTarget* dst) {
+	const GameRenderer::Overlays overlays{get_text_to_draw(), road_building_preview()};
+	map_view->draw_map_view(egbase(), overlays, GameRenderer::DrawImmovables::kYes,
+	                        GameRenderer::DrawBobs::kYes, nullptr, dst);
 }
 
 /**
@@ -140,10 +156,10 @@
 /**
  * Observer has clicked on the given node; bring up the context menu.
  */
-void InteractiveSpectator::node_action() {
+void InteractiveSpectator::node_action(const Widelands::NodeAndTriangle<>& node_and_triangle) {
 	// Special case for buildings
-	if (is_a(Widelands::Building, egbase().map().get_immovable(get_sel_pos().node))) {
-		show_building_window(get_sel_pos().node, false);
+	if (is_a(Widelands::Building, egbase().map().get_immovable(node_and_triangle.node))) {
+		show_building_window(node_and_triangle.node, false);
 		return;
 	}
 

=== modified file 'src/wui/interactive_spectator.h'
--- src/wui/interactive_spectator.h	2017-08-13 18:02:53 +0000
+++ src/wui/interactive_spectator.h	2017-08-27 15:50:48 +0000
@@ -43,6 +43,8 @@
 	Widelands::Player* get_player() const override;
 
 	bool handle_key(bool down, SDL_Keysym) override;
+	void draw(RenderTarget& dst) override;
+	void draw_map_view(MapView* map_view, RenderTarget* dst) override;
 
 private:
 	void exit_btn();
@@ -50,7 +52,7 @@
 	bool can_see(Widelands::PlayerNumber) const override;
 	bool can_act(Widelands::PlayerNumber) const override;
 	Widelands::PlayerNumber player_number() const override;
-	void node_action() override;
+	void node_action(const Widelands::NodeAndTriangle<>& node_and_triangle) override;
 
 private:
 	UI::UniqueWindow::Registry chat_;

=== modified file 'src/wui/mapview.cc'
--- src/wui/mapview.cc	2017-08-18 02:28:27 +0000
+++ src/wui/mapview.cc	2017-08-27 15:50:48 +0000
@@ -23,15 +23,11 @@
 
 #include "base/macros.h"
 #include "base/math.h"
-#include "graphic/game_renderer.h"
 #include "graphic/graphic.h"
 #include "graphic/rendertarget.h"
-#include "logic/map.h"
 #include "logic/map_objects/draw_text.h"
 #include "logic/player.h"
 #include "wlapplication.h"
-#include "wui/interactive_base.h"
-#include "wui/interactive_player.h"
 #include "wui/mapviewpixelfunctions.h"
 
 namespace {
@@ -295,10 +291,10 @@
 }
 
 MapView::MapView(
-   UI::Panel* parent, int32_t x, int32_t y, uint32_t w, uint32_t h, InteractiveBase& player)
+   UI::Panel* parent, const Widelands::Map& map, int32_t x, int32_t y, uint32_t w, uint32_t h)
    : UI::Panel(parent, x, y, w, h),
+     map_(map),
      renderer_(new GameRenderer()),
-     intbase_(player),
      view_(),
      last_mouse_pos_(Vector2i::zero()),
      dragging_(false) {
@@ -343,9 +339,12 @@
 	NEVER_HERE();
 }
 
-void MapView::draw(RenderTarget& dst) {
-	Widelands::EditorGameBase& egbase = intbase_.egbase();
-
+void MapView::draw_map_view(const Widelands::EditorGameBase& egbase,
+                            const GameRenderer::Overlays& overlays,
+                            const GameRenderer::DrawImmovables& draw_immovables,
+                            const GameRenderer::DrawBobs& draw_bobs,
+                            const Widelands::Player* player,
+                            RenderTarget* dst) {
 	uint32_t now = SDL_GetTicks();
 	while (!view_plans_.empty()) {
 		auto& plan = view_plans_.front();
@@ -385,44 +384,15 @@
 		break;
 	}
 
-	if (upcast(Widelands::Game, game, &egbase)) {
-		// Bail out if the game isn't actually loaded.
-		// This fixes a crash with displaying an error dialog during loading.
-		if (!game->is_loaded())
-			return;
-	}
-
-	TextToDraw text_to_draw = TextToDraw::kNone;
-	auto display_flags = intbase_.get_display_flags();
-	if (display_flags & InteractiveBase::dfShowCensus) {
-		text_to_draw = text_to_draw | TextToDraw::kCensus;
-	}
-	if (display_flags & InteractiveBase::dfShowStatistics) {
-		text_to_draw = text_to_draw | TextToDraw::kStatistics;
-	}
-
-	if (upcast(InteractivePlayer const, interactive_player, &intbase_)) {
-		const GameRenderer::Overlays overlays{
-		   text_to_draw, interactive_player->road_building_preview()};
-		renderer_->rendermap(
-		   egbase, view_.viewpoint, view_.zoom, interactive_player->player(), overlays, &dst);
-	} else {
-		const auto draw_immovables = intbase_.draw_immovables() ? GameRenderer::DrawImmovables::kYes :
-		                                                          GameRenderer::DrawImmovables::kNo;
-		const auto draw_bobs =
-		   intbase_.draw_bobs() ? GameRenderer::DrawBobs::kYes : GameRenderer::DrawBobs::kNo;
-		const GameRenderer::Overlays overlays{static_cast<TextToDraw>(text_to_draw), {}};
-		renderer_->rendermap(
-		   egbase, view_.viewpoint, view_.zoom, overlays, draw_immovables, draw_bobs, &dst);
-	}
+	renderer_->render(
+	   egbase, view_.viewpoint, view_.zoom, player, overlays, draw_immovables, draw_bobs, dst);
 }
 
 void MapView::set_view(const View& target_view, const Transition& transition) {
-	const Widelands::Map& map = intbase_.egbase().map();
 	switch (transition) {
 	case Transition::Jump: {
 		view_ = target_view;
-		MapviewPixelFunctions::normalize_pix(map, &view_.viewpoint);
+		MapviewPixelFunctions::normalize_pix(map_, &view_.viewpoint);
 		changeview();
 		return;
 	}
@@ -430,7 +400,7 @@
 	case Transition::Smooth: {
 		const TimestampedView current = animation_target_view();
 		const auto plan =
-		   plan_map_transition(current.t, map, current.view, target_view, get_w(), get_h());
+		   plan_map_transition(current.t, map_, current.view, target_view, get_w(), get_h());
 		if (!plan.empty()) {
 			view_plans_.push_back(plan);
 		}
@@ -440,13 +410,12 @@
 }
 
 void MapView::scroll_to_field(const Widelands::Coords& c, const Transition& transition) {
-	const Widelands::Map& map = intbase_.egbase().map();
 	assert(0 <= c.x);
-	assert(c.x < map.get_width());
+	assert(c.x < map_.get_width());
 	assert(0 <= c.y);
-	assert(c.y < map.get_height());
+	assert(c.y < map_.get_height());
 
-	const Vector2f in_mappixel = MapviewPixelFunctions::to_map_pixel(map.get_fcoords(c));
+	const Vector2f in_mappixel = MapviewPixelFunctions::to_map_pixel(map_.get_fcoords(c));
 	scroll_to_map_pixel(in_mappixel, transition);
 }
 
@@ -458,7 +427,7 @@
 }
 
 MapView::ViewArea MapView::view_area() const {
-	return ViewArea(get_view_area(view_, get_w(), get_h()), intbase_.egbase().map());
+	return ViewArea(get_view_area(view_, get_w(), get_h()), map_);
 }
 
 const MapView::View& MapView::view() const {
@@ -482,8 +451,8 @@
 bool MapView::handle_mousepress(uint8_t const btn, int32_t const x, int32_t const y) {
 	if (btn == SDL_BUTTON_LEFT) {
 		stop_dragging();
-		track_sel(Vector2i(x, y));
-		fieldclicked();
+		const auto node_and_triangle = track_sel(Vector2i(x, y));
+		field_clicked(node_and_triangle);
 	} else if (btn == SDL_BUTTON_RIGHT) {
 		dragging_ = true;
 		grab_mouse(true);
@@ -513,8 +482,7 @@
 		}
 	}
 
-	if (!intbase_.get_sel_freeze())
-		track_sel(Vector2i(x, y));
+	track_sel(Vector2i(x, y));
 	return true;
 }
 
@@ -571,10 +539,12 @@
 	return !view_plans_.empty() || !mouse_plans_.empty();
 }
 
-void MapView::track_sel(const Vector2i& p) {
+Widelands::NodeAndTriangle<> MapView::track_sel(const Vector2i& p) {
 	Vector2f p_in_map = to_map(p);
-	intbase_.set_sel_pos(MapviewPixelFunctions::calc_node_and_triangle(
-	   intbase_.egbase().map(), p_in_map.x, p_in_map.y));
+	const auto node_and_triangle =
+	   MapviewPixelFunctions::calc_node_and_triangle(map_, p_in_map.x, p_in_map.y);
+	track_selection(node_and_triangle);
+	return node_and_triangle;
 }
 
 bool MapView::handle_key(bool down, SDL_Keysym code) {

=== modified file 'src/wui/mapview.h'
--- src/wui/mapview.h	2017-08-17 15:34:45 +0000
+++ src/wui/mapview.h	2017-08-27 15:50:48 +0000
@@ -28,12 +28,12 @@
 
 #include "base/rect.h"
 #include "base/vector.h"
+#include "graphic/game_renderer.h"
 #include "logic/map.h"
 #include "logic/widelands_geometry.h"
 #include "ui_basic/panel.h"
 
 class GameRenderer;
-class InteractiveBase;
 
 /**
  * Implements a view of a map. It is used to render a valid map on the screen.
@@ -101,18 +101,21 @@
 	};
 
 	MapView(UI::Panel* const parent,
+	        const Widelands::Map& map,
 	        const int32_t x,
 	        const int32_t y,
 	        const uint32_t w,
-	        const uint32_t h,
-	        InteractiveBase&);
+	        const uint32_t h);
 	virtual ~MapView();
 
 	// Called whenever the view changed, also during automatic animations.
 	boost::signals2::signal<void()> changeview;
 
 	// Called when the user clicked on a field.
-	boost::signals2::signal<void()> fieldclicked;
+	boost::signals2::signal<void(const Widelands::NodeAndTriangle<>&)> field_clicked;
+
+	// Called when the field under the mouse cursor has changed.
+	boost::signals2::signal<void(const Widelands::NodeAndTriangle<>&)> track_selection;
 
 	// Defines if an animation should be immediate (one-frame) or nicely
 	// animated for the user to follow.
@@ -156,13 +159,18 @@
 	// True if a 'Transition::Smooth' animation is playing.
 	bool is_animating() const;
 
-	void draw(RenderTarget&) override;
-	bool handle_mousepress(uint8_t btn, int32_t x, int32_t y) override;
-	bool handle_mouserelease(uint8_t btn, int32_t x, int32_t y) override;
-	bool
-	handle_mousemove(uint8_t state, int32_t x, int32_t y, int32_t xdiff, int32_t ydiff) override;
-	bool handle_mousewheel(uint32_t which, int32_t x, int32_t y) override;
-	bool handle_key(bool down, SDL_Keysym code) override;
+	// Not overriden from UI::Panel, instead we expect to be passed the data through.
+	void draw_map_view(const Widelands::EditorGameBase& egbase,
+	                   const GameRenderer::Overlays& overlays,
+	                   const GameRenderer::DrawImmovables& draw_immovables,
+	                   const GameRenderer::DrawBobs& draw_bobs,
+	                   const Widelands::Player* player,
+	                   RenderTarget* dst);
+	bool handle_mousepress(uint8_t btn, int32_t x, int32_t y);
+	bool handle_mouserelease(uint8_t btn, int32_t x, int32_t y);
+	bool handle_mousemove(uint8_t state, int32_t x, int32_t y, int32_t xdiff, int32_t ydiff);
+	bool handle_mousewheel(uint32_t which, int32_t x, int32_t y);
+	bool handle_key(bool down, SDL_Keysym code);
 
 private:
 	void stop_dragging();
@@ -175,14 +183,14 @@
 	// current mouse) if we are not animating.
 	TimestampedMouse animation_target_mouse() const;
 
-	// Move the sel to the given mouse position. Does not honour sel freeze.
-	void track_sel(const Vector2i& m);
+	// Turns 'm' into the corresponding NodeAndTrinangle and calls 'track_selection'.
+	Widelands::NodeAndTriangle<> track_sel(const Vector2i& m);
 
 	Vector2f to_panel(const Vector2f& map_pixel) const;
 	Vector2f to_map(const Vector2i& panel_pixel) const;
 
+	const Widelands::Map& map_;
 	std::unique_ptr<GameRenderer> renderer_;
-	InteractiveBase& intbase_;
 	View view_;
 	Vector2i last_mouse_pos_;
 	bool dragging_;

=== modified file 'src/wui/watchwindow.cc'
--- src/wui/watchwindow.cc	2017-08-20 17:45:42 +0000
+++ src/wui/watchwindow.cc	2017-08-27 15:50:48 +0000
@@ -58,7 +58,7 @@
 	~WatchWindow();
 
 	Widelands::Game& game() const {
-		return dynamic_cast<InteractiveGameBase&>(*get_parent()).game();
+		return parent_.game();
 	}
 
 	boost::signals2::signal<void(Vector2f)> warp_mainview;
@@ -72,6 +72,7 @@
 protected:
 	void think() override;
 	void stop_tracking_by_drag();
+	void draw(RenderTarget&) override;
 
 private:
 	void do_follow();
@@ -79,7 +80,8 @@
 	void view_button_clicked(uint8_t index);
 	void set_current_view(uint8_t idx, bool save_previous = true);
 
-	MapView mapview_;
+	InteractiveGameBase& parent_;
+	MapView map_view_;
 	uint32_t last_visit_;
 	bool single_window_;
 	uint8_t cur_index_;
@@ -96,7 +98,8 @@
                          uint32_t const h,
                          bool const init_single_window)
    : UI::Window(&parent, "watch", x, y, w, h, _("Watch")),
-     mapview_(this, 0, 0, 200, 166, parent),
+     parent_(parent),
+     map_view_(this, game().map(), 0, 0, 200, 166),
      last_visit_(game().get_gametime()),
      single_window_(init_single_window),
      cur_index_(0) {
@@ -124,13 +127,25 @@
 		closebtn->sigclicked.connect(boost::bind(&WatchWindow::close_cur_view, this));
 	}
 
-	mapview_.fieldclicked.connect(boost::bind(&InteractiveGameBase::node_action, &parent));
-	mapview_.changeview.connect([this] { stop_tracking_by_drag(); });
+	map_view_.field_clicked.connect([&parent](const Widelands::NodeAndTriangle<>& node_and_triangle) {
+		parent.map_view()->field_clicked(node_and_triangle);
+	});
+	map_view_.track_selection.connect([&parent](const Widelands::NodeAndTriangle<>& node_and_triangle) {
+		parent.map_view()->track_selection(node_and_triangle);
+	});
+	map_view_.changeview.connect([this] { stop_tracking_by_drag(); });
 	warp_mainview.connect([&parent](const Vector2f& map_pixel) {
 		parent.map_view()->scroll_to_map_pixel(map_pixel, MapView::Transition::Smooth);
 	});
 }
 
+void WatchWindow::draw(RenderTarget& dst) {
+	UI::Window::draw(dst);
+	if (!is_minimal()) {
+		parent_.draw_map_view(&map_view_, &dst);
+	}
+}
+
 /**
  * Add a view to a watchwindow, if there is space left.
  *
@@ -141,10 +156,10 @@
 		return;
 	WatchWindowView view;
 
-	mapview_.scroll_to_field(coords, MapView::Transition::Jump);
+	map_view_.scroll_to_field(coords, MapView::Transition::Jump);
 
 	view.tracking = nullptr;
-	view.view = mapview_.view();
+	view.view = map_view_.view();
 	last_visit_ = game().get_gametime();
 
 	views_.push_back(view);
@@ -161,7 +176,7 @@
 // Saves the coordinates of a view if it was already shown (and possibly moved)
 void WatchWindow::save_coords() {
 	auto& view = views_[cur_index_];
-	view.view = mapview_.view();
+	view.view = map_view_.view();
 }
 
 // Enables/Disables buttons for views_
@@ -188,7 +203,7 @@
 		view_btns_[idx]->set_perm_pressed(true);
 	}
 	cur_index_ = idx;
-	mapview_.set_view(views_[cur_index_].view, MapView::Transition::Jump);
+	map_view_.set_view(views_[cur_index_].view, MapView::Transition::Jump);
 }
 
 WatchWindow::~WatchWindow() {
@@ -197,7 +212,7 @@
 
 /*
 ===============
-Update the mapview_ if we're tracking something.
+Update the map_view_ if we're tracking something.
 ===============
 */
 void WatchWindow::think() {
@@ -220,19 +235,19 @@
 			// Not in sight
 			views_[cur_index_].tracking = nullptr;
 		} else {
-			mapview_.scroll_to_map_pixel(pos, MapView::Transition::Jump);
+			map_view_.scroll_to_map_pixel(pos, MapView::Transition::Jump);
 		}
 	}
 }
 
 /*
 ===============
-When the user drags the mapview_, we stop tracking.
+When the user drags the map_view_, we stop tracking.
 ===============
 */
 void WatchWindow::stop_tracking_by_drag() {
 	// Disable switching while dragging
-	if (mapview_.is_dragging()) {
+	if (map_view_.is_dragging()) {
 		last_visit_ = game().get_gametime();
 		views_[cur_index_].tracking = nullptr;
 	}
@@ -251,7 +266,7 @@
 	} else {
 		//  Find the nearest bob. Other object types can not move and are
 		//  therefore not of interest.
-		Vector2f center_map_pixel = mapview_.view_area().rect().center();
+		Vector2f center_map_pixel = map_view_.view_area().rect().center();
 		const Widelands::Map& map = g.map();
 		MapviewPixelFunctions::normalize_pix(map, &center_map_pixel);
 		std::vector<Widelands::Bob*> bobs;
@@ -289,10 +304,10 @@
 /**
  * Called when the "go to" button is clicked.
  *
- * Cause the main mapview_ to jump to our current position.
+ * Cause the main map_view_ to jump to our current position.
  */
 void WatchWindow::do_goto() {
-	warp_mainview(mapview_.view_area().rect().center());
+	warp_mainview(map_view_.view_area().rect().center());
 }
 
 /**


Follow ups