Working on portrait mode

This commit is contained in:
Vladislav Khorev committed 2026-06-25 17:30:58 +03:00
1 parent 6b39cfca3b
commit 0b4df8ab2d
13 files changed
+1558 -28

No files matched your search

+5
View File
@@ -934,10 +934,15 @@ namespace ZL
if (event.type == SDL_WINDOWEVENT && event.window.event == SDL_WINDOWEVENT_RESIZED) {
// Обновляем размеры и сбрасываем кеш текстов, т.к. меши хранятся в пикселях
const bool wasPortrait = Environment::width < Environment::height;
Environment::width = event.window.data1;
Environment::height = event.window.data2;
Environment::computeProjectionDimensions();
const bool isPortrait = Environment::width < Environment::height;
menuManager.uiManager.updateAllLayouts();
if (wasPortrait != isPortrait) {
menuManager.onOrientationChanged();
}
std::cout << "Window resized: " << Environment::width << "x" << Environment::height << std::endl;
//space.clearTextRendererCache();
+99 -28
View File
@@ -126,17 +126,29 @@ namespace ZL {
hudCutsceneRoot_ = loadUiFromFile("resources/w/ui/hud_cutscene.json", renderer, zipFile);
hudTopHintRoot_ = loadUiFromFile("resources/w/ui/hud_top_hint01.json", renderer, zipFile);
phoneMainRoot = loadUiFromFile("resources/w/ui/screen_phone.json", renderer, zipFile);
phoneMainHintARoot = loadUiFromFile("resources/w/ui/screen_phone_hint001.json", renderer, zipFile);
phoneMainHintBRoot = loadUiFromFile("resources/w/ui/screen_phone_hint002.json", renderer, zipFile);
phoneMainHintABRoot = loadUiFromFile("resources/w/ui/screen_phone_hint001_002.json", renderer, zipFile);
phoneMainRoot = loadUiFromFile("resources/w/ui/screen_phone.json", renderer, zipFile);
phoneMainHintARoot = loadUiFromFile("resources/w/ui/screen_phone_hint001.json", renderer, zipFile);
phoneMainHintBRoot = loadUiFromFile("resources/w/ui/screen_phone_hint002.json", renderer, zipFile);
phoneMainHintABRoot = loadUiFromFile("resources/w/ui/screen_phone_hint001_002.json", renderer, zipFile);
phoneBankRoot = loadUiFromFile("resources/w/ui/screen_phone_bank.json", renderer, zipFile);
phoneVideoRoot = loadUiFromFile("resources/w/ui/screen_phone_video.json", renderer, zipFile);
phoneMapDormRoot = loadUiFromFile("resources/w/ui/screen_phone_map_dorm.json", renderer, zipFile);
phoneMapUniRoot = loadUiFromFile("resources/w/ui/screen_phone_map_uni.json", renderer, zipFile);
phoneChatListRoot = loadUiFromFile("resources/w/ui/screen_phone_chat_list.json", renderer, zipFile);
phoneChatListHintRoot = loadUiFromFile("resources/w/ui/screen_phone_chat_list_hint001.json", renderer, zipFile);
phoneBankRoot = loadUiFromFile("resources/w/ui/screen_phone_bank.json", renderer, zipFile);
phoneVideoRoot = loadUiFromFile("resources/w/ui/screen_phone_video.json", renderer, zipFile);
phoneMapDormRoot = loadUiFromFile("resources/w/ui/screen_phone_map_dorm.json", renderer, zipFile);
phoneMapUniRoot = loadUiFromFile("resources/w/ui/screen_phone_map_uni.json", renderer, zipFile);
verticalPhoneMainRoot = loadUiFromFile("resources/w/ui/portrait_screen_phone.json", renderer, zipFile);
verticalPhoneMainHintARoot = loadUiFromFile("resources/w/ui/portrait_screen_phone_hint001.json", renderer, zipFile);
verticalPhoneMainHintBRoot = loadUiFromFile("resources/w/ui/portrait_screen_phone_hint002.json", renderer, zipFile);
verticalPhoneMainHintABRoot= loadUiFromFile("resources/w/ui/portrait_screen_phone_hint001_002.json", renderer, zipFile);
verticalPhoneBankRoot = loadUiFromFile("resources/w/ui/portrait_screen_phone_bank.json", renderer, zipFile);
verticalPhoneVideoRoot = loadUiFromFile("resources/w/ui/portrait_screen_phone_video.json", renderer, zipFile);
verticalPhoneMapDormRoot = loadUiFromFile("resources/w/ui/portrait_screen_phone_map_dorm.json", renderer, zipFile);
verticalPhoneMapUniRoot = loadUiFromFile("resources/w/ui/portrait_screen_phone_map_uni.json", renderer, zipFile);
phoneChatListRoot = loadUiFromFile("resources/w/ui/screen_phone_chat_list.json", renderer, zipFile);
phoneChatListHintRoot = loadUiFromFile("resources/w/ui/screen_phone_chat_list_hint001.json", renderer, zipFile);
verticalPhoneChatListRoot = loadUiFromFile("resources/w/ui/portrait_screen_phone_chat_list.json", renderer, zipFile);
verticalPhoneChatListHintRoot = loadUiFromFile("resources/w/ui/portrait_screen_phone_chat_list_hint001.json", renderer, zipFile);
phoneChat1Root = loadUiFromFile("resources/w/ui/screen_phone_chat1.json", renderer, zipFile);
phoneChat2Root = loadUiFromFile("resources/w/ui/screen_phone_chat2.json", renderer, zipFile);
phoneChat3Root = loadUiFromFile("resources/w/ui/screen_phone_chat3.json", renderer, zipFile);
@@ -161,7 +173,6 @@ namespace ZL {
renderer.textureManager.LoadFromPng("resources/w/ui/img/toast/quest_completed001.png", zipFile, true);
renderer.textureManager.LoadFromPng("resources/w/ui/img/toast/quest_failed001.png", zipFile, true);
gameState_.questJournal.onQuestUnlocked = [this](const std::string& id) {
const Quest::QuestState* q = gameState_.questJournal.findQuest(id);
if (q) showToast("resources/w/ui/img/toast/quest_new001.png", q->definition.title);
@@ -567,21 +578,24 @@ namespace ZL {
void MenuManager::openPhoneScreen() {
uiState_ = GameUiState::PhoneScreen;
currentPhoneSubScreen_ = PhoneSubScreen::Main;
if (gameState_.tutorialNeedOpenTaxiScreen && (gameState_.tutorialPhoneChatScreenOpened == false))
{
if (isPortraitMode()) {
if (gameState_.tutorialNeedOpenTaxiScreen && (gameState_.tutorialPhoneChatScreenOpened == false))
uiManager.pushMenuFromSavedRoot(verticalPhoneMainHintABRoot);
else if (gameState_.tutorialNeedOpenTaxiScreen)
uiManager.pushMenuFromSavedRoot(verticalPhoneMainHintBRoot);
else if (gameState_.tutorialPhoneChatScreenOpened == false)
uiManager.pushMenuFromSavedRoot(verticalPhoneMainHintARoot);
else
uiManager.pushMenuFromSavedRoot(verticalPhoneMainRoot);
} else if (gameState_.tutorialNeedOpenTaxiScreen && (gameState_.tutorialPhoneChatScreenOpened == false)) {
uiManager.pushMenuFromSavedRoot(phoneMainHintABRoot);
}
else if (gameState_.tutorialNeedOpenTaxiScreen)
{
} else if (gameState_.tutorialNeedOpenTaxiScreen) {
uiManager.pushMenuFromSavedRoot(phoneMainHintBRoot);
}
else if (gameState_.tutorialPhoneChatScreenOpened == false)
{
} else if (gameState_.tutorialPhoneChatScreenOpened == false) {
uiManager.pushMenuFromSavedRoot(phoneMainHintARoot);
}
else
{
} else {
uiManager.pushMenuFromSavedRoot(phoneMainRoot);
}
@@ -625,14 +639,15 @@ namespace ZL {
}
void MenuManager::openPhoneMessenger() {
currentPhoneSubScreen_ = PhoneSubScreen::ChatList;
if (gameState_.tutorialPhoneChatScreenOpened)
{
uiManager.pushMenuFromSavedRoot(phoneChatListRoot);
uiManager.pushMenuFromSavedRoot(isPortraitMode() ? verticalPhoneChatListRoot : phoneChatListRoot);
}
else
{
uiManager.pushMenuFromSavedRoot(phoneChatListHintRoot);
uiManager.pushMenuFromSavedRoot(isPortraitMode() ? verticalPhoneChatListHintRoot : phoneChatListHintRoot);
}
refreshChatUnreadIndicators();
@@ -680,7 +695,8 @@ namespace ZL {
void MenuManager::openPhoneBank() {
uiManager.pushMenuFromSavedRoot(phoneBankRoot);
currentPhoneSubScreen_ = PhoneSubScreen::Bank;
uiManager.pushMenuFromSavedRoot(isPortraitMode() ? verticalPhoneBankRoot : phoneBankRoot);
uiManager.setText("balanceText", formatMoney(gameState_.money));
uiManager.setButtonCallback("phoneExitButton", [this](const std::string&) {
@@ -693,7 +709,8 @@ namespace ZL {
}
void MenuManager::openPhoneVideo() {
uiManager.pushMenuFromSavedRoot(phoneVideoRoot);
currentPhoneSubScreen_ = PhoneSubScreen::Video;
uiManager.pushMenuFromSavedRoot(isPortraitMode() ? verticalPhoneVideoRoot : phoneVideoRoot);
uiManager.setButtonCallback("phoneExitButton", [this](const std::string&) {
closePhoneEntirely();
@@ -729,9 +746,11 @@ namespace ZL {
closePhoneEntirely();
if (startDialogueFunc) startDialogueFunc("dialog_taxi003");
} else if (gameState_.currentLocationName == "uni_exterior") {
openPhoneMapScreen(phoneMapUniRoot);
currentPhoneSubScreen_ = PhoneSubScreen::MapUni;
openPhoneMapScreen(isPortraitMode() ? verticalPhoneMapUniRoot : phoneMapUniRoot);
} else {
openPhoneMapScreen(phoneMapDormRoot);
currentPhoneSubScreen_ = PhoneSubScreen::MapDorm;
openPhoneMapScreen(isPortraitMode() ? verticalPhoneMapDormRoot : phoneMapDormRoot);
}
}
@@ -760,6 +779,7 @@ namespace ZL {
void MenuManager::openPhoneChatFromList(int chatIndex, std::shared_ptr<UiNode> chatRoot) {
activeChatIndex_ = chatIndex;
currentPhoneSubScreen_ = PhoneSubScreen::Chat;
phoneChatVisibleBubbles_.clear();
gameState_.tutorialPhoneChatScreenOpened = true;
uiManager.pushMenuFromSavedRoot(chatRoot);
@@ -786,6 +806,7 @@ namespace ZL {
trimChatPreview(gameState_.chatHistory[activeChatIndex_].back().text);
}
activeChatIndex_ = -1;
currentPhoneSubScreen_ = PhoneSubScreen::ChatList;
phoneChatVisibleBubbles_.clear();
uiManager.popMenu();
uiManager.updateAllLayouts();
@@ -808,6 +829,7 @@ namespace ZL {
trimChatPreview(gameState_.chatHistory[activeChatIndex_].back().text);
}
activeChatIndex_ = -1;
currentPhoneSubScreen_ = PhoneSubScreen::None;
uiState_ = GameUiState::Gameplay;
phoneChatVisibleBubbles_.clear();
const int depth = uiManager.menuStackSize();
@@ -1550,4 +1572,53 @@ namespace ZL {
}
}
bool MenuManager::isPortraitMode() const {
return Environment::projectionWidth < Environment::projectionHeight;
}
void MenuManager::onOrientationChanged() {
if (uiState_ != GameUiState::PhoneScreen) return;
const PhoneSubScreen savedSubScreen = currentPhoneSubScreen_;
const int savedChatIndex = activeChatIndex_;
// Collapse all stacked phone menus and reopen in the new orientation.
activeChatIndex_ = -1;
phoneChatVisibleBubbles_.clear();
const int depth = uiManager.menuStackSize();
for (int i = 0; i < depth; ++i) uiManager.popMenu();
uiState_ = GameUiState::Gameplay;
switch (savedSubScreen) {
case PhoneSubScreen::Bank:
openPhoneScreen();
openPhoneBank();
break;
case PhoneSubScreen::Video:
openPhoneScreen();
openPhoneVideo();
break;
case PhoneSubScreen::MapDorm:
openPhoneScreen();
openPhoneMapScreen(isPortraitMode() ? verticalPhoneMapDormRoot : phoneMapDormRoot);
currentPhoneSubScreen_ = PhoneSubScreen::MapDorm;
break;
case PhoneSubScreen::MapUni:
openPhoneScreen();
openPhoneMapScreen(isPortraitMode() ? verticalPhoneMapUniRoot : phoneMapUniRoot);
currentPhoneSubScreen_ = PhoneSubScreen::MapUni;
break;
case PhoneSubScreen::ChatList:
case PhoneSubScreen::Chat:
openPhoneScreen();
openPhoneMessenger();
break;
default:
openPhoneScreen();
break;
}
uiManager.updateAllLayouts();
}
} // namespace ZL
+22
View File
@@ -93,6 +93,9 @@ namespace ZL {
void onCutsceneFinished();
bool cutsceneHudActive_ = false;
// Called by Game when the window is resized and orientation has changed.
void onOrientationChanged();
void saveSettings();
void loadSettings();
@@ -190,8 +193,20 @@ namespace ZL {
std::shared_ptr<UiNode> phoneVideoRoot;
std::shared_ptr<UiNode> phoneMapDormRoot;
std::shared_ptr<UiNode> phoneMapUniRoot;
// Portrait-mode (vertical) equivalents for screens that have a portrait layout
std::shared_ptr<UiNode> verticalPhoneMainRoot;
std::shared_ptr<UiNode> verticalPhoneMainHintARoot;
std::shared_ptr<UiNode> verticalPhoneMainHintBRoot;
std::shared_ptr<UiNode> verticalPhoneMainHintABRoot;
std::shared_ptr<UiNode> verticalPhoneBankRoot;
std::shared_ptr<UiNode> verticalPhoneVideoRoot;
std::shared_ptr<UiNode> verticalPhoneMapDormRoot;
std::shared_ptr<UiNode> verticalPhoneMapUniRoot;
std::shared_ptr<UiNode> phoneChatListRoot;
std::shared_ptr<UiNode> phoneChatListHintRoot;
std::shared_ptr<UiNode> verticalPhoneChatListRoot;
std::shared_ptr<UiNode> verticalPhoneChatListHintRoot;
std::shared_ptr<UiNode> phoneChat1Root;
std::shared_ptr<UiNode> phoneChat2Root;
std::shared_ptr<UiNode> phoneChat3Root;
@@ -216,6 +231,13 @@ namespace ZL {
void applyCurrentHealthBar();
bool isPortraitMode() const;
// Tracks which phone sub-screen is currently shown so onOrientationChanged()
// can reopen the correct screen after swapping roots.
enum class PhoneSubScreen { None, Main, Bank, Video, MapDorm, MapUni, ChatList, Chat };
PhoneSubScreen currentPhoneSubScreen_ = PhoneSubScreen::None;
// Phone chat UI state (transient — rebuilt from gameState_.chatHistory on open)
struct PhoneChatBubbleInfo {
std::string nodeName;