mirror of
https://github.com/vcmi/vcmi.git
synced 2025-08-10 22:31:40 +02:00
Merge pull request #5543 from kambala-decapitator/ios-portrait-mode
[iOS] enable portrait mode
This commit is contained in:
@@ -237,7 +237,7 @@ void InputHandler::preprocessEvent(const SDL_Event & ev)
|
||||
#endif
|
||||
break;
|
||||
case SDL_WINDOWEVENT_SIZE_CHANGED:
|
||||
#ifdef VCMI_ANDROID
|
||||
#ifdef VCMI_MOBILE
|
||||
{
|
||||
boost::mutex::scoped_lock interfaceLock(GH.interfaceMutex);
|
||||
GH.onScreenResize(true);
|
||||
|
@@ -53,10 +53,5 @@
|
||||
<true/>
|
||||
<key>UIStatusBarHidden</key>
|
||||
<true/>
|
||||
<key>UISupportedInterfaceOrientations</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
||||
|
@@ -31,6 +31,11 @@ if(APPLE_IOS)
|
||||
ios/revealdirectoryinfiles.mm
|
||||
ios/selectdirectory.h
|
||||
ios/selectdirectory.mm
|
||||
prepare_ios.mm
|
||||
)
|
||||
elseif(ANDROID)
|
||||
list(APPEND launcher_SRCS
|
||||
prepare_android.cpp
|
||||
)
|
||||
endif()
|
||||
|
||||
@@ -55,6 +60,7 @@ set(launcher_HEADERS
|
||||
helper.h
|
||||
innoextract.h
|
||||
prepare.h
|
||||
prepare_p.h
|
||||
)
|
||||
|
||||
set(launcher_FORMS
|
||||
|
@@ -9,75 +9,17 @@
|
||||
*/
|
||||
#include "StdInc.h"
|
||||
#include "prepare.h"
|
||||
#include "prepare_p.h"
|
||||
#include "../vcmiqt/launcherdirs.h"
|
||||
|
||||
#include <QDir>
|
||||
#include <QFile>
|
||||
#include <QFileInfo>
|
||||
|
||||
#ifdef VCMI_ANDROID
|
||||
#include "../lib/CAndroidVMHelper.h"
|
||||
|
||||
#include <QAndroidJniEnvironment>
|
||||
#include <QAndroidJniObject>
|
||||
#include <QtAndroid>
|
||||
|
||||
namespace
|
||||
{
|
||||
// https://gist.github.com/ssendeavour/7324701
|
||||
bool copyRecursively(const QString &srcFilePath, const QString &tgtFilePath)
|
||||
{
|
||||
QFileInfo srcFileInfo{srcFilePath};
|
||||
if(srcFileInfo.isDir()) {
|
||||
QDir targetDir{tgtFilePath};
|
||||
targetDir.cdUp();
|
||||
if(!targetDir.mkpath(QFileInfo{tgtFilePath}.fileName()))
|
||||
return false;
|
||||
targetDir.setPath(tgtFilePath);
|
||||
|
||||
QDir sourceDir{srcFilePath};
|
||||
const auto fileNames = sourceDir.entryList(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot | QDir::Hidden | QDir::System);
|
||||
for(const auto & fileName : fileNames) {
|
||||
const auto newSrcFilePath = sourceDir.filePath(fileName);
|
||||
const auto newTgtFilePath = targetDir.filePath(fileName);
|
||||
if(!copyRecursively(newSrcFilePath, newTgtFilePath))
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if(!QFile::copy(srcFilePath, tgtFilePath))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void prepareAndroid()
|
||||
{
|
||||
QAndroidJniEnvironment jniEnv;
|
||||
CAndroidVMHelper::initClassloader(static_cast<JNIEnv *>(jniEnv));
|
||||
|
||||
const bool justLaunched = QtAndroid::androidActivity().getField<jboolean>("justLaunched") == JNI_TRUE;
|
||||
if(!justLaunched)
|
||||
return;
|
||||
|
||||
// copy core data to internal directory
|
||||
const auto vcmiDir = QAndroidJniObject::callStaticObjectMethod<jstring>("eu/vcmi/vcmi/NativeMethods", "internalDataRoot").toString();
|
||||
for(auto vcmiFilesResource : {QLatin1String{"config"}, QLatin1String{"Mods"}})
|
||||
{
|
||||
QDir destDir = QString{"%1/%2"}.arg(vcmiDir, vcmiFilesResource);
|
||||
destDir.removeRecursively();
|
||||
copyRecursively(QString{":/%1"}.arg(vcmiFilesResource), destDir.absolutePath());
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
namespace launcher
|
||||
{
|
||||
void prepare()
|
||||
{
|
||||
#ifdef VCMI_ANDROID
|
||||
prepareAndroid();
|
||||
#elif defined(VCMI_IOS)
|
||||
prepareIos();
|
||||
#endif
|
||||
|
||||
CLauncherDirs::prepare();
|
||||
|
71
launcher/prepare_android.cpp
Normal file
71
launcher/prepare_android.cpp
Normal file
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* prepare_android.cpp, part of VCMI engine
|
||||
*
|
||||
* Authors: listed in file AUTHORS in main folder
|
||||
*
|
||||
* License: GNU General Public License v2.0 or later
|
||||
* Full text of license available in license.txt file, in main folder
|
||||
*
|
||||
*/
|
||||
#include "StdInc.h"
|
||||
#include "prepare_p.h"
|
||||
#include "../lib/CAndroidVMHelper.h"
|
||||
|
||||
#include <QDir>
|
||||
#include <QFile>
|
||||
#include <QFileInfo>
|
||||
|
||||
#include <QAndroidJniEnvironment>
|
||||
#include <QAndroidJniObject>
|
||||
#include <QtAndroid>
|
||||
|
||||
namespace
|
||||
{
|
||||
// https://gist.github.com/ssendeavour/7324701
|
||||
bool copyRecursively(const QString & srcFilePath, const QString & tgtFilePath)
|
||||
{
|
||||
QFileInfo srcFileInfo{srcFilePath};
|
||||
if(srcFileInfo.isDir()) {
|
||||
QDir targetDir{tgtFilePath};
|
||||
targetDir.cdUp();
|
||||
if(!targetDir.mkpath(QFileInfo{tgtFilePath}.fileName()))
|
||||
return false;
|
||||
targetDir.setPath(tgtFilePath);
|
||||
|
||||
QDir sourceDir{srcFilePath};
|
||||
const auto fileNames = sourceDir.entryList(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot | QDir::Hidden | QDir::System);
|
||||
for(const auto & fileName : fileNames) {
|
||||
const auto newSrcFilePath = sourceDir.filePath(fileName);
|
||||
const auto newTgtFilePath = targetDir.filePath(fileName);
|
||||
if(!copyRecursively(newSrcFilePath, newTgtFilePath))
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if(!QFile::copy(srcFilePath, tgtFilePath))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
namespace launcher
|
||||
{
|
||||
void prepareAndroid()
|
||||
{
|
||||
QAndroidJniEnvironment jniEnv;
|
||||
CAndroidVMHelper::initClassloader(static_cast<JNIEnv *>(jniEnv));
|
||||
|
||||
const bool justLaunched = QtAndroid::androidActivity().getField<jboolean>("justLaunched") == JNI_TRUE;
|
||||
if(!justLaunched)
|
||||
return;
|
||||
|
||||
// copy core data to internal directory
|
||||
const auto vcmiDir = QAndroidJniObject::callStaticObjectMethod<jstring>("eu/vcmi/vcmi/NativeMethods", "internalDataRoot").toString();
|
||||
for(auto vcmiFilesResource : {QLatin1String{"config"}, QLatin1String{"Mods"}})
|
||||
{
|
||||
QDir destDir = QString{"%1/%2"}.arg(vcmiDir, vcmiFilesResource);
|
||||
destDir.removeRecursively();
|
||||
copyRecursively(QString{":/%1"}.arg(vcmiFilesResource), destDir.absolutePath());
|
||||
}
|
||||
}
|
||||
}
|
40
launcher/prepare_ios.mm
Normal file
40
launcher/prepare_ios.mm
Normal file
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* prepare_ios.mm, part of VCMI engine
|
||||
*
|
||||
* Authors: listed in file AUTHORS in main folder
|
||||
*
|
||||
* License: GNU General Public License v2.0 or later
|
||||
* Full text of license available in license.txt file, in main folder
|
||||
*
|
||||
*/
|
||||
#include "StdInc.h"
|
||||
#include "prepare_p.h"
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
#include <objc/runtime.h>
|
||||
|
||||
namespace
|
||||
{
|
||||
UIInterfaceOrientationMask swizzled_supportedInterfaceOrientationsForWindow
|
||||
(id __unused self, SEL __unused _cmd, UIApplication * __unused application, UIWindow * __unused _Nullable window)
|
||||
{
|
||||
if(UIDevice.currentDevice.userInterfaceIdiom == UIUserInterfaceIdiomPad)
|
||||
return UIInterfaceOrientationMaskAll;
|
||||
return UIInterfaceOrientationMaskLandscape;
|
||||
}
|
||||
}
|
||||
|
||||
namespace launcher
|
||||
{
|
||||
void prepareIos()
|
||||
{
|
||||
auto sel = @selector(application:supportedInterfaceOrientationsForWindow:);
|
||||
auto methodDesc = protocol_getMethodDescription(@protocol(UIApplicationDelegate), sel, NO, YES);
|
||||
auto appDelegateClass = object_getClass(UIApplication.sharedApplication.delegate);
|
||||
[[maybe_unused]] auto existingImp = class_replaceMethod(
|
||||
appDelegateClass, sel, (IMP)swizzled_supportedInterfaceOrientationsForWindow, methodDesc.types);
|
||||
// also check implementation in qtbase - src/plugins/platforms/ios/qiosapplicationdelegate.mm
|
||||
NSCAssert(existingImp == nullptr, @"original app delegate has this method, don't ignore it");
|
||||
}
|
||||
}
|
19
launcher/prepare_p.h
Normal file
19
launcher/prepare_p.h
Normal file
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* prepare_p.h, part of VCMI engine
|
||||
*
|
||||
* Authors: listed in file AUTHORS in main folder
|
||||
*
|
||||
* License: GNU General Public License v2.0 or later
|
||||
* Full text of license available in license.txt file, in main folder
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
namespace launcher
|
||||
{
|
||||
#ifdef VCMI_ANDROID
|
||||
void prepareAndroid();
|
||||
#elif defined(VCMI_IOS)
|
||||
void prepareIos();
|
||||
#endif
|
||||
}
|
@@ -120,6 +120,8 @@ void CSettingsView::loadSettings()
|
||||
ui->labelHapticFeedback->hide();
|
||||
ui->labelResetTutorialTouchscreen->hide();
|
||||
ui->pushButtonResetTutorialTouchscreen->hide();
|
||||
ui->labelAllowPortrait->hide();
|
||||
ui->buttonAllowPortrait->hide();
|
||||
if (settings["video"]["realFullscreen"].Bool())
|
||||
ui->comboBoxFullScreen->setCurrentIndex(2);
|
||||
else
|
||||
@@ -128,8 +130,6 @@ void CSettingsView::loadSettings()
|
||||
#ifndef VCMI_ANDROID
|
||||
ui->buttonHandleBackRightMouseButton->hide();
|
||||
ui->labelHandleBackRightMouseButton->hide();
|
||||
ui->buttonAllowPortrait->hide();
|
||||
ui->labelAllowPortrait->hide();
|
||||
#endif
|
||||
fillValidScalingRange();
|
||||
|
||||
|
Reference in New Issue
Block a user