← Back to team overview

widelands-dev team mailing list archive

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

 

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

Commit message:
Start to detangle MapView and InteractiveBase.

MapView was a base class of InteractiveBase, but still requires InteractiveBase to be passed. My plan is to change MapView to probably not even be a UI::Panel anymore (unclear yet), but for sure change inheritance to composition and remove more logic knowledge from MapView.

I also did a few cleanups in InteractiveBase (remove public member variables, less protected).

Requested reviews:
  Widelands Developers (widelands-dev)

For more details, see:
https://code.launchpad.net/~widelands-dev/widelands/cleanup_mapview/+merge/329206
-- 
Your team Widelands Developers is requested to review the proposed merge of lp:~widelands-dev/widelands/cleanup_mapview into lp:widelands.
=== modified file 'src/editor/editorinteractive.cc'
--- src/editor/editorinteractive.cc	2017-08-16 08:59:09 +0000
+++ src/editor/editorinteractive.cc	2017-08-17 15:38:00 +0000
@@ -113,7 +113,7 @@
 		new EditorPlayerMenu(*this, playermenu_);
 	};
 
-	toolbar_.add_space(15);
+	toolbar()->add_space(15);
 
 	toggle_buildhelp_ = add_toolbar_button(
 	   "wui/menus/menu_toggle_buildhelp", "buildhelp", _("Show Building Spaces (on/off)"));
@@ -131,7 +131,7 @@
 	toggle_resources_->set_perm_pressed(true);
 	toggle_resources_->sigclicked.connect([this]() { toggle_resources(); });
 
-	toolbar_.add_space(15);
+	toolbar()->add_space(15);
 
 	add_toolbar_button(
 	   "wui/menus/menu_toggle_minimap", "minimap", _("Minimap"), &minimap_registry(), true);
@@ -139,10 +139,11 @@
 
 	auto zoom = add_toolbar_button("wui/menus/menu_reset_zoom", "reset_zoom", _("Reset zoom"));
 	zoom->sigclicked.connect([this] {
-		zoom_around(1.f, Vector2f(get_w() / 2.f, get_h() / 2.f), MapView::Transition::Smooth);
+		map_view()->zoom_around(
+		   1.f, Vector2f(get_w() / 2.f, get_h() / 2.f), MapView::Transition::Smooth);
 	});
 
-	toolbar_.add_space(15);
+	toolbar()->add_space(15);
 
 	undo_ = add_toolbar_button("wui/editor/editor_undo", "undo", _("Undo"));
 	undo_->sigclicked.connect([this] { history_->undo_action(egbase().world()); });
@@ -150,7 +151,7 @@
 	redo_ = add_toolbar_button("wui/editor/editor_redo", "redo", _("Redo"));
 	redo_->sigclicked.connect([this] { history_->redo_action(egbase().world()); });
 
-	toolbar_.add_space(15);
+	toolbar()->add_space(15);
 
 	add_toolbar_button("ui_basic/menu_help", "help", _("Help"), &helpmenu_, true);
 	helpmenu_.open_window = [this] { new EditorHelp(*this, helpmenu_, &egbase().lua()); };
@@ -163,7 +164,7 @@
 	set_display_flag(InteractiveBase::dfDebug, false);
 #endif
 
-	fieldclicked.connect(boost::bind(&EditorInteractive::map_clicked, this, false));
+	map_view()->fieldclicked.connect(boost::bind(&EditorInteractive::map_clicked, this, false));
 
 	// Subscribe to changes of the resource type on a field..
 	field_resource_changed_subscriber_ =
@@ -658,7 +659,7 @@
 		}
 
 		// Make sure that we will start at coordinates (0,0).
-		set_view(MapView::View{Vector2f::zero(), 1.f}, Transition::Jump);
+		map_view()->set_view(MapView::View{Vector2f::zero(), 1.f}, MapView::Transition::Jump);
 		set_sel_pos(Widelands::NodeAndTriangle<>(
 		   Widelands::Coords(0, 0),
 		   Widelands::TCoords<>(Widelands::Coords(0, 0), Widelands::TCoords<>::D)));

=== modified file 'src/editor/tools/set_origin_tool.cc'
--- src/editor/tools/set_origin_tool.cc	2017-01-25 18:55:59 +0000
+++ src/editor/tools/set_origin_tool.cc	2017-08-17 15:38:00 +0000
@@ -30,7 +30,7 @@
                                                Widelands::Map* map) {
 	map->set_origin(center.node);
 	eia.map_changed(EditorInteractive::MapWas::kGloballyMutated);
-	eia.scroll_to_field(Widelands::Coords(0, 0), MapView::Transition::Jump);
+	eia.map_view()->scroll_to_field(Widelands::Coords(0, 0), MapView::Transition::Jump);
 	return 0;
 }
 
@@ -44,7 +44,7 @@
 	   map->get_width() - 1 - center.node.x, map->get_height() - 1 - center.node.y);
 	map->set_origin(nc);
 	eia.map_changed(EditorInteractive::MapWas::kGloballyMutated);
-	eia.scroll_to_field(Widelands::Coords(0, 0), MapView::Transition::Jump);
+	eia.map_view()->scroll_to_field(Widelands::Coords(0, 0), MapView::Transition::Jump);
 	return 0;
 }
 

=== modified file 'src/editor/ui_menus/player_menu.cc'
--- src/editor/ui_menus/player_menu.cc	2017-05-03 07:24:06 +0000
+++ src/editor/ui_menus/player_menu.cc	2017-08-17 15:38:00 +0000
@@ -278,7 +278,7 @@
 	//  jump to the current node
 	Widelands::Map& map = menu.egbase().map();
 	if (Widelands::Coords const sp = map.get_starting_pos(n)) {
-		menu.scroll_to_field(sp, MapView::Transition::Smooth);
+		menu.map_view()->scroll_to_field(sp, MapView::Transition::Smooth);
 	}
 
 	//  select tool set mplayer

=== modified file 'src/game_io/game_interactive_player_packet.cc'
--- src/game_io/game_interactive_player_packet.cc	2017-05-13 11:25:24 +0000
+++ src/game_io/game_interactive_player_packet.cc	2017-08-17 15:38:00 +0000
@@ -82,7 +82,7 @@
 			uint32_t const display_flags = fr.unsigned_32();
 
 			if (InteractiveBase* const ibase = game.get_ibase()) {
-				ibase->scroll_to_map_pixel(center_map_pixel, MapView::Transition::Jump);
+				ibase->map_view()->scroll_to_map_pixel(center_map_pixel, MapView::Transition::Jump);
 
 				uint32_t const loaded_df =
 				   InteractiveBase::dfShowCensus | InteractiveBase::dfShowStatistics;
@@ -136,7 +136,7 @@
 	fw.unsigned_8(iplayer ? iplayer->player_number() : 1);
 
 	if (ibase != nullptr) {
-		Vector2f center = ibase->view_area().rect().center();
+		const Vector2f center = ibase->map_view()->view_area().rect().center();
 		fw.float_32(center.x);
 		fw.float_32(center.y);
 	} else {

=== modified file 'src/game_io/game_preload_packet.cc'
--- src/game_io/game_preload_packet.cc	2017-08-09 17:53:24 +0000
+++ src/game_io/game_preload_packet.cc	2017-08-17 15:38:00 +0000
@@ -84,7 +84,7 @@
 	Profile prof;
 	Section& s = prof.create_section("global");
 
-	InteractivePlayer const* const ipl = game.get_ipl();
+	InteractivePlayer* const ipl = game.get_ipl();
 
 	s.set_int("packet_version", kCurrentPacketVersion);
 
@@ -125,8 +125,8 @@
 		   MiniMapLayer::Owner | MiniMapLayer::Building | MiniMapLayer::Terrain;
 		std::unique_ptr<Texture> texture;
 		if (ipl != nullptr) {  // Player
-			texture = draw_minimap(
-			   game, &ipl->player(), ipl->view_area().rect(), MiniMapType::kStaticViewWindow, layers);
+			texture = draw_minimap(game, &ipl->player(), ipl->map_view()->view_area().rect(),
+			                       MiniMapType::kStaticViewWindow, layers);
 		} else {  // Observer
 			texture = draw_minimap(game, nullptr, Rectf(), MiniMapType::kStaticMap, layers);
 		}

=== modified file 'src/logic/game.cc'
--- src/logic/game.cc	2017-08-16 13:23:15 +0000
+++ src/logic/game.cc	2017-08-17 15:38:00 +0000
@@ -446,9 +446,10 @@
 			}
 		}
 
-		if (get_ipl())
-			get_ipl()->scroll_to_field(
+		if (get_ipl()) {
+			get_ipl()->map_view()->scroll_to_field(
 			   map().get_starting_pos(get_ipl()->player_number()), MapView::Transition::Jump);
+		}
 
 		// Prepare the map, set default textures
 		map().recalc_default_resources(world());

=== modified file 'src/scripting/lua_game.cc'
--- src/scripting/lua_game.cc	2017-08-16 04:31:56 +0000
+++ src/scripting/lua_game.cc	2017-08-17 15:38:00 +0000
@@ -449,7 +449,7 @@
 		lua_getfield(L, 4, "field");
 		if (!lua_isnil(L, -1)) {
 			Coords c = (*get_user_class<LuaField>(L, -1))->coords();
-			game.get_ipl()->scroll_to_field(c, MapView::Transition::Jump);
+			game.get_ipl()->map_view()->scroll_to_field(c, MapView::Transition::Jump);
 		}
 		lua_pop(L, 1);
 	}

=== modified file 'src/scripting/lua_ui.cc'
--- src/scripting/lua_ui.cc	2017-06-24 10:38:19 +0000
+++ src/scripting/lua_ui.cc	2017-08-17 15:38:00 +0000
@@ -486,7 +486,7 @@
 		currently sees. This is a table containing 'x', 'y'.
 */
 int LuaMapView::get_center_map_pixel(lua_State* L) {
-	const Vector2f center = get()->view_area().rect().center();
+	const Vector2f center = get()->map_view()->view_area().rect().center();
 	lua_newtable(L);
 
 	lua_pushstring(L, "x");
@@ -558,7 +558,7 @@
 		(RO) True if this MapView is currently paning or zooming.
 */
 int LuaMapView::get_is_animating(lua_State* L) {
-	lua_pushboolean(L, get()->is_animating());
+	lua_pushboolean(L, get()->map_view()->is_animating());
 	return 1;
 }
 /*
@@ -575,9 +575,9 @@
       :type field: :class:`wl.map.Field`
 */
 int LuaMapView::click(lua_State* L) {
-	get()->mouse_to_field(
+	get()->map_view()->mouse_to_field(
 	   (*get_user_class<LuaMaps::LuaField>(L, 2))->coords(), MapView::Transition::Jump);
-	get()->fieldclicked();
+	get()->map_view()->fieldclicked();
 	return 0;
 }
 
@@ -600,7 +600,7 @@
 	Widelands::Coords starting_field =
 	   (*get_user_class<LuaMaps::LuaFlag>(L, 2))->get(L, get_egbase(L))->get_position();
 
-	me->mouse_to_field(starting_field, MapView::Transition::Jump);
+	me->map_view()->mouse_to_field(starting_field, MapView::Transition::Jump);
 	me->start_build_road(starting_field, me->get_player()->player_number());
 
 	return 0;
@@ -654,7 +654,7 @@
 	}
 
 	const Vector2f center(luaL_checkdouble(L, 2), luaL_checkdouble(L, 3));
-	get()->scroll_to_map_pixel(center, MapView::Transition::Smooth);
+	get()->map_view()->scroll_to_map_pixel(center, MapView::Transition::Smooth);
 	return 0;
 }
 
@@ -668,7 +668,7 @@
       :type field: :class:`wl.map.Field`
 */
 int LuaMapView::scroll_to_field(lua_State* L) {
-	get()->scroll_to_field(
+	get()->map_view()->scroll_to_field(
 	   (*get_user_class<LuaMaps::LuaField>(L, 2))->coords(), MapView::Transition::Smooth);
 	return 0;
 }
@@ -683,7 +683,7 @@
 */
 int LuaMapView::is_visible(lua_State* L) {
 	lua_pushboolean(
-	   L, get()->view_area().contains((*get_user_class<LuaMaps::LuaField>(L, 2))->coords()));
+	   L, get()->map_view()->view_area().contains((*get_user_class<LuaMaps::LuaField>(L, 2))->coords()));
 	return 1;
 }
 
@@ -701,7 +701,7 @@
 int LuaMapView::mouse_to_pixel(lua_State* L) {
 	int x = luaL_checkint32(L, 2);
 	int y = luaL_checkint32(L, 3);
-	get()->mouse_to_pixel(Vector2i(x, y), MapView::Transition::Smooth);
+	get()->map_view()->mouse_to_pixel(Vector2i(x, y), MapView::Transition::Smooth);
 	return 0;
 }
 
@@ -716,7 +716,7 @@
       :type field: :class:`wl.map.Field`
 */
 int LuaMapView::mouse_to_field(lua_State* L) {
-	get()->mouse_to_field(
+	get()->map_view()->mouse_to_field(
 	   (*get_user_class<LuaMaps::LuaField>(L, 2))->coords(), MapView::Transition::Smooth);
 	return 0;
 }

=== modified file 'src/wui/building_statistics_menu.cc'
--- src/wui/building_statistics_menu.cc	2017-08-16 04:31:56 +0000
+++ src/wui/building_statistics_menu.cc	2017-08-17 15:38:00 +0000
@@ -485,7 +485,7 @@
 
 	if (found) {
 		validate_pointer(&last_building_index_, stats_vector.size());
-		iplayer().scroll_to_field(
+		iplayer().map_view()->scroll_to_field(
 		   stats_vector[last_building_index_].pos, MapView::Transition::Smooth);
 	}
 	low_production_reset_focus();

=== modified file 'src/wui/buildingwindow.cc'
--- src/wui/buildingwindow.cc	2017-06-28 07:17:12 +0000
+++ src/wui/buildingwindow.cc	2017-08-17 15:38:00 +0000
@@ -491,7 +491,7 @@
  * for the corresponding button.
  */
 void BuildingWindow::clicked_goto() {
-	igbase()->scroll_to_field(building().get_position(), MapView::Transition::Smooth);
+	igbase()->map_view()->scroll_to_field(building().get_position(), MapView::Transition::Smooth);
 }
 
 void BuildingWindow::update_expedition_button(bool expedition_was_canceled) {

=== modified file 'src/wui/fieldaction.cc'
--- src/wui/fieldaction.cc	2017-06-11 20:09:05 +0000
+++ src/wui/fieldaction.cc	2017-08-17 15:38:00 +0000
@@ -529,7 +529,7 @@
 ===============
 */
 void FieldActionWindow::reset_mouse_and_die() {
-	ibase().mouse_to_field(node_, MapView::Transition::Jump);
+	ibase().map_view()->mouse_to_field(node_, MapView::Transition::Jump);
 	die();
 }
 

=== modified file 'src/wui/game_message_menu.cc'
--- src/wui/game_message_menu.cc	2017-08-16 04:31:56 +0000
+++ src/wui/game_message_menu.cc	2017-08-17 15:38:00 +0000
@@ -448,7 +448,7 @@
 	if (Message const* const message =
 	       iplayer().player().messages()[MessageId((*list)[selection])]) {
 		assert(message->position());
-		iplayer().scroll_to_field(message->position(), MapView::Transition::Smooth);
+		iplayer().map_view()->scroll_to_field(message->position(), MapView::Transition::Smooth);
 	}
 }
 

=== modified file 'src/wui/interactive_base.cc'
--- src/wui/interactive_base.cc	2017-08-16 08:59:09 +0000
+++ src/wui/interactive_base.cc	2017-08-17 15:38:00 +0000
@@ -67,22 +67,15 @@
 using Widelands::MapObject;
 using Widelands::TCoords;
 
-struct InteractiveBaseInternals {
-	MiniMap* mm;
-	MiniMap::Registry minimap;
-	std::unique_ptr<QuickNavigation> quicknavigation;
-
-	explicit InteractiveBaseInternals(QuickNavigation* qnav) : mm(nullptr), quicknavigation(qnav) {
-	}
-};
-
 InteractiveBase::InteractiveBase(EditorGameBase& the_egbase, Section& global_s)
-   : MapView(nullptr, 0, 0, g_gr->get_xres(), g_gr->get_yres(), *this),
+   : 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),
      // Initialize chatoveraly before the toolbar so it is below
-     show_workarea_preview_(global_s.get_bool("workareapreview", true)),
      chat_overlay_(new ChatOverlay(this, 10, 25, get_w() / 2, get_h() - 25)),
      toolbar_(this, 0, 0, UI::Box::Horizontal),
-     m(new InteractiveBaseInternals(new QuickNavigation(this))),
+     quick_navigation_(&map_view_),
      field_overlay_manager_(new FieldOverlayManager()),
      egbase_(the_egbase),
 #ifndef NDEBUG  //  not in releases
@@ -124,7 +117,7 @@
 	});
 
 	toolbar_.set_layout_toplevel(true);
-	changeview.connect([this] { mainview_move(); });
+	map_view_.changeview.connect([this] { mainview_move(); });
 
 	set_border_snap_distance(global_s.get_int("border_snap_distance", 0));
 	set_panel_snap_distance(global_s.get_int("panel_snap_distance", 10));
@@ -334,19 +327,19 @@
 	if (keyboard_free() && Panel::allow_user_input()) {
 		if (get_key_state(SDL_SCANCODE_UP) ||
 		    (get_key_state(SDL_SCANCODE_KP_8) && (SDL_GetModState() ^ KMOD_NUM))) {
-			pan_by(Vector2i(0, -scrollval));
+			map_view_.pan_by(Vector2i(0, -scrollval));
 		}
 		if (get_key_state(SDL_SCANCODE_DOWN) ||
 		    (get_key_state(SDL_SCANCODE_KP_2) && (SDL_GetModState() ^ KMOD_NUM))) {
-			pan_by(Vector2i(0, scrollval));
+			map_view_.pan_by(Vector2i(0, scrollval));
 		}
 		if (get_key_state(SDL_SCANCODE_LEFT) ||
 		    (get_key_state(SDL_SCANCODE_KP_4) && (SDL_GetModState() ^ KMOD_NUM))) {
-			pan_by(Vector2i(-scrollval, 0));
+			map_view_.pan_by(Vector2i(-scrollval, 0));
 		}
 		if (get_key_state(SDL_SCANCODE_RIGHT) ||
 		    (get_key_state(SDL_SCANCODE_KP_6) && (SDL_GetModState() ^ KMOD_NUM))) {
-			pan_by(Vector2i(scrollval, 0));
+			map_view_.pan_by(Vector2i(scrollval, 0));
 		}
 	}
 	egbase().think();  // Call game logic here. The game advances.
@@ -354,6 +347,27 @@
 	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);
+}
+
+bool InteractiveBase::handle_mouserelease(uint8_t btn, int32_t x, int32_t y) {
+	return map_view_.handle_mouserelease(btn, x, y);
+}
+
+bool InteractiveBase::handle_mousemove(
+   uint8_t state, int32_t x, int32_t y, int32_t xdiff, int32_t ydiff) {
+	return map_view_.handle_mousemove(state, x, y, xdiff, ydiff);
+}
+
+bool InteractiveBase::handle_mousewheel(uint32_t which, int32_t x, int32_t y) {
+	return map_view_.handle_mousewheel(which, x, y);
+}
+
 /*
 ===============
 Draw debug overlay when appropriate.
@@ -426,36 +440,37 @@
 }
 
 void InteractiveBase::mainview_move() {
-	if (m->minimap.window) {
-		m->mm->set_view(view_area().rect());
+	if (minimap_registry_.window) {
+		minimap_->set_view(map_view_.view_area().rect());
 	}
 }
 
 // Open the minimap or close it if it's open
 void InteractiveBase::toggle_minimap() {
-	if (m->minimap.window) {
-		delete m->minimap.window;
+	if (minimap_registry_.window) {
+		delete minimap_registry_.window;
 	} else {
-		m->mm = new MiniMap(*this, &m->minimap);
-		m->mm->warpview.connect(
-		   [this](const Vector2f& map_pixel) { scroll_to_map_pixel(map_pixel, Transition::Smooth); });
+		minimap_ = new MiniMap(*this, &minimap_registry_);
+		minimap_->warpview.connect([this](const Vector2f& map_pixel) {
+			map_view_.scroll_to_map_pixel(map_pixel, MapView::Transition::Smooth);
+		});
 		mainview_move();
 	}
 }
 
 const std::vector<QuickNavigation::Landmark>& InteractiveBase::landmarks() {
-	return m->quicknavigation->landmarks();
+	return quick_navigation_.landmarks();
 }
 
 void InteractiveBase::set_landmark(size_t key, const MapView::View& landmark_view) {
-	m->quicknavigation->set_landmark(key, landmark_view);
+	quick_navigation_.set_landmark(key, landmark_view);
 }
 
 /**
  * Hide the minimap if it is currently shown; otherwise, do nothing.
  */
 void InteractiveBase::hide_minimap() {
-	m->minimap.destroy();
+	minimap_registry_.destroy();
 }
 
 /**
@@ -466,7 +481,7 @@
 ===========
 */
 MiniMap::Registry& InteractiveBase::minimap_registry() {
-	return m->minimap;
+	return minimap_registry_;
 }
 
 /*
@@ -674,7 +689,7 @@
 
 	// Viewpoint is the point of the map in pixel which is shown in the upper
 	// left corner of window or fullscreen
-	const MapView::ViewArea area = view_area();
+	const MapView::ViewArea area = map_view_.view_area();
 	if (!area.contains(position_map)) {
 		return -1;
 	}
@@ -784,7 +799,7 @@
 }
 
 bool InteractiveBase::handle_key(bool const down, SDL_Keysym const code) {
-	if (m->quicknavigation->handle_key(down, code))
+	if (quick_navigation_.handle_key(down, code))
 		return true;
 
 	if (down) {
@@ -834,7 +849,7 @@
 		}
 	}
 
-	return MapView::handle_key(down, code);
+	return map_view_.handle_key(down, code);
 }
 
 void InteractiveBase::cmd_lua(const std::vector<std::string>& args) {

=== modified file 'src/wui/interactive_base.h'
--- src/wui/interactive_base.h	2017-08-14 13:54:01 +0000
+++ src/wui/interactive_base.h	2017-08-17 15:38:00 +0000
@@ -48,13 +48,12 @@
 
 class EdgeOverlayManager;
 class UniqueWindowHandler;
-struct InteractiveBaseInternals;
 
 /**
  * This is used to represent the code that InteractivePlayer and
  * EditorInteractive share.
  */
-class InteractiveBase : public MapView, public DebugConsole::Handler {
+class InteractiveBase : public UI::Panel, public DebugConsole::Handler {
 public:
 	friend class SoundHandler;
 
@@ -76,6 +75,7 @@
 	virtual void reference_player_tribe(Widelands::PlayerNumber, const void* const) {
 	}
 
+	// TODO(sirver): This should be private.
 	bool show_workarea_preview_;
 	FieldOverlayManager::OverlayId show_work_area(const WorkareaInfo& workarea_info,
 	                                              Widelands::Coords coords);
@@ -85,6 +85,13 @@
 	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
+	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;
 	virtual void postload();
 
 	const Widelands::NodeAndTriangle<>& get_sel_pos() const {
@@ -179,6 +186,10 @@
 		return road_building_preview_;
 	}
 
+	MapView* map_view() {
+		return &map_view_;
+	}
+
 protected:
 	/// Adds a toolbar button to the toolbar
 	/// \param image_basename:      File path for button image starting from 'images' and without
@@ -203,7 +214,6 @@
 	void mainview_move();
 
 	void draw_overlay(RenderTarget&) override;
-	bool handle_key(bool down, SDL_Keysym) override;
 
 	void unset_sel_picture();
 	void set_sel_picture(const Image* image);
@@ -211,14 +221,12 @@
 		toolbar_.set_pos(Vector2i((get_inner_w() - toolbar_.get_w()) >> 1, get_inner_h() - 34));
 	}
 
-	// TODO(sirver): why are these protected?
-	ChatOverlay* chat_overlay_;
-
-	// These get collected by add_toolbar_button
-	// so we can call unassign_toggle_button on them in the destructor.
-	std::vector<UI::UniqueWindow::Registry> registries_;
-
-	UI::Box toolbar_;
+	ChatOverlay* chat_overlay() {
+		return chat_overlay_;
+	}
+	UI::Box* toolbar() {
+		return &toolbar_;
+	}
 
 private:
 	int32_t stereo_position(Widelands::Coords position_map);
@@ -247,7 +255,19 @@
 		FieldOverlayManager::OverlayId jobid;
 	} sel_;
 
-	std::unique_ptr<InteractiveBaseInternals> m;
+	MapView map_view_;
+	ChatOverlay* chat_overlay_;
+
+	// These get collected by add_toolbar_button
+	// so we can call unassign_toggle_button on them in the destructor.
+	std::vector<UI::UniqueWindow::Registry> registries_;
+
+	UI::Box toolbar_;
+	// No unique_ptr on purpose: 'minimap_' is a UniqueWindow, its parent will
+	// delete it.
+	MiniMap* minimap_;
+	MiniMap::Registry minimap_registry_;
+	QuickNavigation quick_navigation_;
 
 	std::unique_ptr<FieldOverlayManager> field_overlay_manager_;
 

=== modified file 'src/wui/interactive_gamebase.cc'
--- src/wui/interactive_gamebase.cc	2017-05-21 18:15:17 +0000
+++ src/wui/interactive_gamebase.cc	2017-08-17 15:38:00 +0000
@@ -97,7 +97,7 @@
 
 void InteractiveGameBase::set_chat_provider(ChatProvider& chat) {
 	chat_provider_ = &chat;
-	chat_overlay_->set_chat_provider(chat);
+	chat_overlay()->set_chat_provider(chat);
 }
 
 ChatProvider* InteractiveGameBase::get_chat_provider() {

=== modified file 'src/wui/interactive_player.cc'
--- src/wui/interactive_player.cc	2017-08-13 18:02:53 +0000
+++ src/wui/interactive_player.cc	2017-08-17 15:38:00 +0000
@@ -75,7 +75,7 @@
 		new GameStatisticsMenu(*this, statisticsmenu_, main_windows_);
 	};
 
-	toolbar_.add_space(15);
+	toolbar()->add_space(15);
 
 	add_toolbar_button(
 	   "wui/menus/menu_toggle_minimap", "minimap", _("Minimap"), &minimap_registry(), true);
@@ -86,9 +86,10 @@
 	toggle_buildhelp_->sigclicked.connect(boost::bind(&InteractiveBase::toggle_buildhelp, this));
 	reset_zoom_ = add_toolbar_button("wui/menus/menu_reset_zoom", "reset_zoom", _("Reset zoom"));
 	reset_zoom_->sigclicked.connect([this] {
-		zoom_around(1.f, Vector2f(get_w() / 2.f, get_h() / 2.f), MapView::Transition::Smooth);
+		map_view()->zoom_around(
+		   1.f, Vector2f(get_w() / 2.f, get_h() / 2.f), MapView::Transition::Smooth);
 	});
-	toolbar_.add_space(15);
+	toolbar()->add_space(15);
 	if (multiplayer) {
 		toggle_chat_ = add_toolbar_button("wui/menus/menu_chat", "chat", _("Chat"), &chat_, true);
 		chat_.open_window = [this] {
@@ -96,7 +97,7 @@
 				GameChatMenu::create_chat_console(this, chat_, *chat_provider_);
 			}
 		};
-		toolbar_.add_space(15);
+		toolbar()->add_space(15);
 	}
 
 	add_toolbar_button(
@@ -113,7 +114,7 @@
 	};
 
 	set_player_number(plyn);
-	fieldclicked.connect(boost::bind(&InteractivePlayer::node_action, this));
+	map_view()->fieldclicked.connect(boost::bind(&InteractivePlayer::node_action, this));
 
 	adjust_toolbar_position();
 
@@ -139,7 +140,7 @@
 					//  That is not allowed. Therefore we must delete the
 					//  fieldaction window before entering roadbuilding mode here.
 					fieldaction_.destroy();
-					mouse_to_field(flag_to_connect_, MapView::Transition::Jump);
+					map_view()->mouse_to_field(flag_to_connect_, MapView::Transition::Jump);
 					set_sel_pos(Widelands::NodeAndTriangle<>(
 					   flag_to_connect_,
 					   Widelands::TCoords<>(flag_to_connect_, Widelands::TCoords<>::D)));
@@ -274,7 +275,7 @@
 				break;
 			FALLS_THROUGH;
 		case SDLK_HOME:
-			scroll_to_field(game().map().get_starting_pos(player_number_), Transition::Smooth);
+			map_view()->scroll_to_field(game().map().get_starting_pos(player_number_), MapView::Transition::Smooth);
 			return true;
 
 		case SDLK_KP_ENTER:

=== modified file 'src/wui/interactive_spectator.cc'
--- src/wui/interactive_spectator.cc	2017-08-13 18:02:53 +0000
+++ src/wui/interactive_spectator.cc	2017-08-17 15:38:00 +0000
@@ -65,7 +65,7 @@
 		new GeneralStatisticsMenu(*this, main_windows_.general_stats);
 	};
 
-	toolbar_.add_space(15);
+	toolbar()->add_space(15);
 
 	add_toolbar_button(
 	   "wui/menus/menu_toggle_minimap", "minimap", _("Minimap"), &minimap_registry(), true);
@@ -77,10 +77,10 @@
 
 	reset_zoom_ = add_toolbar_button("wui/menus/menu_reset_zoom", "reset_zoom", _("Reset zoom"));
 	reset_zoom_->sigclicked.connect([this] {
-		zoom_around(1.f, Vector2f(get_w() / 2.f, get_h() / 2.f), MapView::Transition::Smooth);
+		map_view()->zoom_around(1.f, Vector2f(get_w() / 2.f, get_h() / 2.f), MapView::Transition::Smooth);
 	});
 
-	toolbar_.add_space(15);
+	toolbar()->add_space(15);
 
 	if (is_multiplayer()) {
 		add_toolbar_button("wui/menus/menu_chat", "chat", _("Chat"), &chat_, true);
@@ -94,7 +94,7 @@
 	adjust_toolbar_position();
 
 	// Setup all screen elements
-	fieldclicked.connect(boost::bind(&InteractiveSpectator::node_action, this));
+	map_view()->fieldclicked.connect(boost::bind(&InteractiveSpectator::node_action, this));
 }
 
 /**

=== modified file 'src/wui/mapview.cc'
--- src/wui/mapview.cc	2017-08-16 08:59:09 +0000
+++ src/wui/mapview.cc	2017-08-17 15:38:00 +0000
@@ -344,7 +344,7 @@
 }
 
 void MapView::draw(RenderTarget& dst) {
-	Widelands::EditorGameBase& egbase = intbase().egbase();
+	Widelands::EditorGameBase& egbase = intbase_.egbase();
 
 	uint32_t now = SDL_GetTicks();
 	while (!view_plans_.empty()) {
@@ -393,7 +393,7 @@
 	}
 
 	TextToDraw text_to_draw = TextToDraw::kNone;
-	auto display_flags = intbase().get_display_flags();
+	auto display_flags = intbase_.get_display_flags();
 	if (display_flags & InteractiveBase::dfShowCensus) {
 		text_to_draw = text_to_draw | TextToDraw::kCensus;
 	}
@@ -401,17 +401,17 @@
 		text_to_draw = text_to_draw | TextToDraw::kStatistics;
 	}
 
-	if (upcast(InteractivePlayer const, interactive_player, &intbase())) {
+	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() ?
+		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;
+		   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);
@@ -419,7 +419,7 @@
 }
 
 void MapView::set_view(const View& target_view, const Transition& transition) {
-	const Widelands::Map& map = intbase().egbase().map();
+	const Widelands::Map& map = intbase_.egbase().map();
 	switch (transition) {
 	case Transition::Jump: {
 		view_ = target_view;
@@ -441,7 +441,7 @@
 }
 
 void MapView::scroll_to_field(const Widelands::Coords& c, const Transition& transition) {
-	const Widelands::Map& map = intbase().egbase().map();
+	const Widelands::Map& map = intbase_.egbase().map();
 	assert(0 <= c.x);
 	assert(c.x < map.get_width());
 	assert(0 <= c.y);
@@ -459,7 +459,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()), intbase_.egbase().map());
 }
 
 const MapView::View& MapView::view() const {
@@ -514,7 +514,7 @@
 		}
 	}
 
-	if (!intbase().get_sel_freeze())
+	if (!intbase_.get_sel_freeze())
 		track_sel(Vector2i(x, y));
 	return true;
 }
@@ -575,7 +575,7 @@
 void 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));
+	   intbase_.egbase().map(), p_in_map.x, p_in_map.y));
 }
 
 bool MapView::handle_key(bool down, SDL_Keysym code) {

=== modified file 'src/wui/mapview.h'
--- src/wui/mapview.h	2017-05-13 11:25:24 +0000
+++ src/wui/mapview.h	2017-08-17 15:38:00 +0000
@@ -136,6 +136,9 @@
 	// Jump, this behaves exactly like 'set_mouse_pos'.
 	void mouse_to_pixel(const Vector2i& pixel, const Transition& transition);
 
+	// Move the view by 'delta_pixels'.
+	void pan_by(Vector2i delta_pixels);
+
 	// The current view area visible in the MapView in map pixel coordinates.
 	// The returned value always has 'x' > 0 and 'y' > 0.
 	ViewArea view_area() const;
@@ -153,7 +156,6 @@
 	// True if a 'Transition::Smooth' animation is playing.
 	bool is_animating() const;
 
-	// Implementing Panel.
 	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;
@@ -162,14 +164,6 @@
 	bool handle_mousewheel(uint32_t which, int32_t x, int32_t y) override;
 	bool handle_key(bool down, SDL_Keysym code) override;
 
-protected:
-	InteractiveBase& intbase() const {
-		return intbase_;
-	}
-
-	// Move the view by 'delta_pixels'.
-	void pan_by(Vector2i delta_pixels);
-
 private:
 	void stop_dragging();
 

=== modified file 'src/wui/shipwindow.cc'
--- src/wui/shipwindow.cc	2017-06-23 12:24:54 +0000
+++ src/wui/shipwindow.cc	2017-08-17 15:38:00 +0000
@@ -279,13 +279,13 @@
 
 /// Move the main view towards the current ship location
 void ShipWindow::act_goto() {
-	igbase_.scroll_to_field(ship_.get_position(), MapView::Transition::Smooth);
+	igbase_.map_view()->scroll_to_field(ship_.get_position(), MapView::Transition::Smooth);
 }
 
 /// Move the main view towards the current destination of the ship
 void ShipWindow::act_destination() {
 	if (PortDock* destination = ship_.get_destination(igbase_.egbase())) {
-		igbase_.scroll_to_field(
+		igbase_.map_view()->scroll_to_field(
 		   destination->get_warehouse()->get_position(), MapView::Transition::Smooth);
 	}
 }

=== modified file 'src/wui/watchwindow.cc'
--- src/wui/watchwindow.cc	2017-01-25 18:55:59 +0000
+++ src/wui/watchwindow.cc	2017-08-17 15:38:00 +0000
@@ -127,7 +127,7 @@
 	mapview_.fieldclicked.connect(boost::bind(&InteractiveGameBase::node_action, &parent));
 	mapview_.changeview.connect([this] { stop_tracking_by_drag(); });
 	warp_mainview.connect([&parent](const Vector2f& map_pixel) {
-		parent.scroll_to_map_pixel(map_pixel, MapView::Transition::Smooth);
+		parent.map_view()->scroll_to_map_pixel(map_pixel, MapView::Transition::Smooth);
 	});
 }
 


Follow ups