ソースを参照

Implemented resolutions selector in Launcher using SDL

Ivan Savenko 2 年 前
コミット
cc68ce9d8b

+ 4 - 0
launcher/CMakeLists.txt

@@ -133,6 +133,10 @@ if(APPLE)
 	set_property(GLOBAL PROPERTY AUTOGEN_TARGETS_FOLDER vcmilauncher)
 endif()
 
+if (NOT APPLE_IOS AND NOT ANDROID)
+	target_link_libraries(vcmilauncher SDL2::SDL2)
+endif()
+
 target_link_libraries(vcmilauncher ${VCMI_LIB_TARGET} Qt${QT_VERSION_MAJOR}::Widgets Qt${QT_VERSION_MAJOR}::Network)
 target_include_directories(vcmilauncher
 	PUBLIC	${CMAKE_CURRENT_SOURCE_DIR}

+ 0 - 1
launcher/mainwindow_moc.cpp

@@ -110,7 +110,6 @@ MainWindow::MainWindow(QWidget * parent)
 	else
 		enterSetup();
 
-	ui->settingsView->isExtraResolutionsModEnabled = ui->modlistView->isExtraResolutionsModEnabled();
 	ui->settingsView->setDisplayList();
 	connect(ui->modlistView, &CModListView::extraResolutionsEnabledChanged,
 		ui->settingsView, &CSettingsView::fillValidResolutions);

+ 52 - 40
launcher/settingsView/csettingsview_moc.cpp

@@ -25,6 +25,10 @@
 #include "../../lib/CConfigHandler.h"
 #include "../../lib/VCMIDirs.h"
 
+#ifndef VCMI_MOBILE
+#include <SDL2/SDL.h>
+#endif
+
 namespace
 {
 QString resolutionToString(const QSize & resolution)
@@ -67,9 +71,9 @@ void CSettingsView::loadSettings()
 {
 	ui->comboBoxShowIntro->setCurrentIndex(settings["video"]["showIntro"].Bool());
 
-#ifdef Q_OS_IOS
-	ui->comboBoxFullScreen->setCurrentIndex(1);
-	ui->comboBoxFullScreen->setDisabled(true);
+#ifdef VCMI_MOBILE
+	ui->comboBoxFullScreen->hide();
+	ui->labelFullScreen->hide();
 #else
 	if (settings["video"]["realFullscreen"].Bool())
 		ui->comboBoxFullScreen->setCurrentIndex(2);
@@ -106,54 +110,54 @@ void CSettingsView::loadSettings()
 	ui->comboBoxCursorType->setCurrentIndex((int)cursorTypeIndex);
 }
 
-void CSettingsView::fillValidResolutions(bool isExtraResolutionsModEnabled)
+void CSettingsView::fillValidResolutions()
 {
-	this->isExtraResolutionsModEnabled = isExtraResolutionsModEnabled;
 	fillValidResolutionsForScreen(ui->comboBoxDisplayIndex->isVisible() ? ui->comboBoxDisplayIndex->currentIndex() : 0);
 }
 
-void CSettingsView::fillValidResolutionsForScreen(int screenIndex)
+#ifndef VCMI_MOBILE
+
+static QVector<QSize> findAvailableResolutions(int displayIndex)
 {
-	ui->comboBoxResolution->blockSignals(true); // avoid saving wrong resolution after adding first item from the list
-	ui->comboBoxResolution->clear();
+	// Ugly workaround since we don't actually need SDL in Launcher
+	// However Qt at the moment provides no way to query list of available resolutions
+	QVector<QSize> result;
+	SDL_Init(SDL_INIT_VIDEO);
+
+	int modesCount = SDL_GetNumDisplayModes(displayIndex);
 
-	// TODO: read available resolutions from all mods
-	QVariantList resolutions;
-	if(isExtraResolutionsModEnabled)
+	for (int i =0; i < modesCount; ++i)
 	{
-		const auto extrasResolutionsPath = settings["launcher"]["extraResolutionsModPath"].String().c_str();
-		const auto extrasResolutionsJson = JsonUtils::JsonFromFile(CLauncherDirs::get().modsPath() + extrasResolutionsPath);
-		resolutions = extrasResolutionsJson.toMap().value(QLatin1String{"GUISettings"}).toList();
+		SDL_DisplayMode mode;
+		if (SDL_GetDisplayMode(displayIndex, i, &mode) != 0)
+			continue;
+
+		QSize resolution(mode.w, mode.h);
+
+		result.push_back(resolution);
 	}
-	if(resolutions.isEmpty())
+
+	boost::range::sort(result, [](const auto & left, const auto & right)
 	{
-		ui->comboBoxResolution->blockSignals(false);
-		ui->comboBoxResolution->addItem(resolutionToString({800, 600}));
-		return;
-	}
+		return left.height() * left.width() < right.height() * right.width();
+	});
 
-	const auto screens = qGuiApp->screens();
-	const auto currentScreen = screenIndex < screens.size() ? screens[screenIndex] : qGuiApp->primaryScreen();
-	[[maybe_unused]] const auto screenSize = currentScreen->size();
+	result.erase(boost::unique(result).end(), result.end());
 
-	for(const auto & entry : resolutions)
-	{
-		const auto resolutionMap = entry.toMap().value(QLatin1String{"resolution"}).toMap();
-		if(resolutionMap.isEmpty())
-			continue;
+	SDL_Quit();
 
-		const auto widthValue = resolutionMap[QLatin1String{"x"}];
-		const auto heightValue = resolutionMap[QLatin1String{"y"}];
-		if(!widthValue.isValid() || !heightValue.isValid())
-			continue;
+	return result;
+}
 
-		const QSize resolution{widthValue.toInt(), heightValue.toInt()};
-#ifndef VCMI_IOS
-		if(screenSize.width() < resolution.width() || screenSize.height() < resolution.height())
-			continue;
-#endif
-		ui->comboBoxResolution->addItem(resolutionToString(resolution));
-	}
+void CSettingsView::fillValidResolutionsForScreen(int screenIndex)
+{
+	ui->comboBoxResolution->blockSignals(true); // avoid saving wrong resolution after adding first item from the list
+	ui->comboBoxResolution->clear();
+
+	QVector<QSize> resolutions = findAvailableResolutions(screenIndex);
+
+	for(const auto & entry : resolutions)
+		ui->comboBoxResolution->addItem(resolutionToString(entry));
 
 	int resX = settings["video"]["resolution"]["width"].Integer();
 	int resY = settings["video"]["resolution"]["height"].Integer();
@@ -162,10 +166,18 @@ void CSettingsView::fillValidResolutionsForScreen(int screenIndex)
 
 	ui->comboBoxResolution->blockSignals(false);
 
-	// if selected resolution no longer exists, force update value to the first resolution
+	// if selected resolution no longer exists, force update value to the largest (last) resolution
 	if(resIndex == -1)
-		ui->comboBoxResolution->setCurrentIndex(0);
+		ui->comboBoxResolution->setCurrentIndex(ui->comboBoxResolution->count() - 1);
+}
+#else
+void CSettingsView::fillValidResolutionsForScreen(int screenIndex)
+{
+	// resolutions are not selectable on mobile platforms
+	ui->comboBoxResolution->hide();
+	ui->labelResolution->hide();
 }
+#endif
 
 CSettingsView::CSettingsView(QWidget * parent)
 	: QWidget(parent), ui(new Ui::CSettingsView)

+ 1 - 3
launcher/settingsView/csettingsview_moc.h

@@ -29,10 +29,8 @@ public:
 	void changeEvent(QEvent *event) override;
 	void showEvent(QShowEvent * event) override;
 
-	bool isExtraResolutionsModEnabled{};
-
 public slots:
-	void fillValidResolutions(bool isExtraResolutionsModEnabled);
+	void fillValidResolutions();
 
 private slots:
 	void on_comboBoxResolution_currentTextChanged(const QString & arg1);

+ 5 - 5
launcher/settingsView/csettingsview_moc.ui

@@ -112,9 +112,9 @@
       <property name="geometry">
        <rect>
         <x>0</x>
-        <y>0</y>
+        <y>-107</y>
         <width>620</width>
-        <height>793</height>
+        <height>745</height>
        </rect>
       </property>
       <layout class="QGridLayout" name="gridLayout" columnstretch="3,0,0,0">
@@ -253,17 +253,17 @@
          </property>
          <item>
           <property name="text">
-           <string>Off</string>
+           <string>Windowed</string>
           </property>
          </item>
          <item>
           <property name="text">
-           <string>On</string>
+           <string>Borderless fullscreen</string>
           </property>
          </item>
          <item>
           <property name="text">
-           <string>Real</string>
+           <string>Exclusive fullscreen</string>
           </property>
          </item>
         </widget>