Browse Source

Support for changing resolution without game restart

Ivan Savenko 2 years ago
parent
commit
fd3933e589

+ 5 - 3
client/CMT.cpp

@@ -547,7 +547,7 @@ static void handleEvent(SDL_Event & ev)
 		case EUserEvent::FULLSCREEN_TOGGLED:
 			{
 				boost::unique_lock<boost::recursive_mutex> lock(*CPlayerInterface::pim);
-				GH.windowHandler().onFullscreenChanged();
+				GH.windowHandler().onScreenResize();
 				break;
 			}
 		default:
@@ -564,7 +564,7 @@ static void handleEvent(SDL_Event & ev)
 #ifndef VCMI_IOS
 			{
 				boost::unique_lock<boost::recursive_mutex> lock(*CPlayerInterface::pim);
-				GH.windowHandler().onFullscreenChanged();
+				GH.windowHandler().onScreenResize();
 			}
 #endif
 			break;
@@ -593,8 +593,10 @@ static void handleEvent(SDL_Event & ev)
 
 static void mainLoop()
 {
-	SettingsListener resChanged = settings.listen["video"]["fullscreen"];
+	SettingsListener resChanged = settings.listen["video"]["resolution"];
+	SettingsListener fsChanged = settings.listen["video"]["fullscreen"];
 	resChanged([](const JsonNode &newState){  CGuiHandler::pushUserEvent(EUserEvent::FULLSCREEN_TOGGLED); });
+	fsChanged([](const JsonNode &newState){  CGuiHandler::pushUserEvent(EUserEvent::FULLSCREEN_TOGGLED); });
 
 	inGuiThread.reset(new bool(true));
 	assert(GH.mainFPSmng);

+ 16 - 0
client/adventureMap/CAdventureMapInterface.cpp

@@ -799,3 +799,19 @@ void CAdventureMapInterface::hotkeySwitchMapLevel()
 {
 	widget->getMapView()->onMapLevelSwitched();
 }
+
+void CAdventureMapInterface::onScreenResize()
+{
+	OBJ_CONSTRUCTION_CAPTURING_ALL_NO_DISPOSE;
+	widget.reset();
+	pos.x = pos.y = 0;
+	pos.w = GH.screenDimensions().x;
+	pos.h = GH.screenDimensions().y;
+
+	widget = std::make_shared<CAdventureMapWidget>(shortcuts);
+	widget->setState(EGameState::MAKING_TURN);
+	widget->getMapView()->onViewMapActivated();
+
+	if (isActive())
+		widget->activate();
+}

+ 2 - 0
client/adventureMap/CAdventureMapInterface.h

@@ -87,6 +87,8 @@ protected:
 
 	void keyPressed(EShortcut key) override;
 
+	void onScreenResize() override;
+
 public:
 	CAdventureMapInterface();
 

+ 14 - 0
client/gui/CGuiHandler.cpp

@@ -811,6 +811,20 @@ IWindowHandler & CGuiHandler::windowHandler()
 	return *windowHandlerInstance;
 }
 
+void CGuiHandler::onScreenResize()
+{
+	for (auto const & entry : listInt)
+	{
+		auto intObject = std::dynamic_pointer_cast<CIntObject>(entry);
+
+		if (intObject)
+			intObject->onScreenResize();
+	}
+
+	totalRedraw();
+}
+
+
 CFramerateManager::CFramerateManager(int newRate)
 	: rate(0)
 	, rateticks(0)

+ 3 - 0
client/gui/CGuiHandler.h

@@ -160,6 +160,9 @@ public:
 	void totalRedraw(); //forces total redraw (using showAll), sets a flag, method gets called at the end of the rendering
 	void simpleRedraw(); //update only top interface and draw background from buffer, sets a flag, method gets called at the end of the rendering
 
+	/// called whenever user selects different resolution, requiring to center/resize all windows
+	void onScreenResize();
+
 	void pushInt(std::shared_ptr<IShowActivatable> newInt); //deactivate old top interface, activates this one and pushes to the top
 	template <typename T, typename ... Args>
 	void pushIntT(Args && ... args)

+ 5 - 0
client/gui/CIntObject.cpp

@@ -294,6 +294,11 @@ void CIntObject::redraw()
 	}
 }
 
+void CIntObject::onScreenResize()
+{
+	center(pos, true);
+}
+
 const Rect & CIntObject::center( const Rect &r, bool propagate )
 {
 	pos.w = r.w;

+ 4 - 0
client/gui/CIntObject.h

@@ -160,6 +160,10 @@ public:
 	//request complete redraw of this object
 	void redraw() override;
 
+	/// called only for windows whenever screen size changes
+	/// default behavior is to re-center, can be overriden
+	virtual void onScreenResize();
+
 	const Rect & center(const Rect &r, bool propagate = true); //sets pos so that r will be in the center of screen, assigns sizes of r to pos, returns new position
 	const Rect & center(const Point &p, bool propagate = true);  //moves object so that point p will be in its center
 	const Rect & center(bool propagate = true); //centers when pos.w and pos.h are set, returns new position

+ 1 - 1
client/render/IWindowHandler.h

@@ -20,7 +20,7 @@ public:
 	virtual ~IWindowHandler() = default;
 
 	/// Updates window state after fullscreen state has been changed in settings
-	virtual void onFullscreenChanged() = 0;
+	virtual void onScreenResize() = 0;
 
 	/// De-initializes window state
 	virtual void close() = 0;

+ 2 - 2
client/renderSDL/WindowHandler.cpp

@@ -306,14 +306,14 @@ SDL_Window * WindowHandler::createWindow()
 #endif
 }
 
-void WindowHandler::onFullscreenChanged()
+void WindowHandler::onScreenResize()
 {
 	if(!recreateWindow())
 	{
 		//will return false and report error if video mode is not supported
 		return;
 	}
-	GH.totalRedraw();
+	GH.onScreenResize();
 }
 
 void WindowHandler::validateSettings()

+ 1 - 1
client/renderSDL/WindowHandler.h

@@ -68,7 +68,7 @@ public:
 	WindowHandler();
 
 	/// Updates and potentially recreates target screen to match selected fullscreen status
-	void onFullscreenChanged() final;
+	void onScreenResize() final;
 
 	/// De-initializes and destroys screen, window and SDL state
 	void close() final;