stk-code_catmod/src/states_screens/options/options_screen_ui.cpp
2019-09-21 11:48:22 +08:00

403 lines
15 KiB
C++

// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2009-2015 Marianne Gagnon
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "states_screens/options/options_screen_ui.hpp"
#include "addons/news_manager.hpp"
#include "audio/sfx_manager.hpp"
#include "audio/sfx_base.hpp"
#include "config/hardware_stats.hpp"
#include "config/player_manager.hpp"
#include "config/user_config.hpp"
#include "font/bold_face.hpp"
#include "font/font_manager.hpp"
#include "font/regular_face.hpp"
#include "graphics/irr_driver.hpp"
#include "guiengine/scalable_font.hpp"
#include "guiengine/screen.hpp"
#include "guiengine/widgets/button_widget.hpp"
#include "guiengine/widgets/check_box_widget.hpp"
#include "guiengine/widgets/dynamic_ribbon_widget.hpp"
#include "guiengine/widgets/label_widget.hpp"
#include "guiengine/widgets/list_widget.hpp"
#include "guiengine/widgets/spinner_widget.hpp"
#include "guiengine/widget.hpp"
#include "io/file_manager.hpp"
#include "online/request_manager.hpp"
#include "states_screens/main_menu_screen.hpp"
#include "states_screens/options/options_screen_audio.hpp"
#include "states_screens/options/options_screen_general.hpp"
#include "states_screens/options/options_screen_input.hpp"
#include "states_screens/options/options_screen_language.hpp"
#include "states_screens/options/options_screen_video.hpp"
#include "states_screens/state_manager.hpp"
#include "states_screens/options/user_screen.hpp"
#include "utils/log.hpp"
#include "utils/string_utils.hpp"
#include "utils/translation.hpp"
#include <algorithm>
#include <iostream>
#include <sstream>
using namespace GUIEngine;
using namespace Online;
// -----------------------------------------------------------------------------
OptionsScreenUI::OptionsScreenUI() : Screen("options_ui.stkgui")
{
m_inited = false;
} // OptionsScreenVideo
// -----------------------------------------------------------------------------
void OptionsScreenUI::loadedFromFile()
{
m_inited = false;
GUIEngine::SpinnerWidget* skinSelector = getWidget<GUIEngine::SpinnerWidget>("skinchoice");
assert( skinSelector != NULL );
skinSelector->m_properties[PROP_WRAP_AROUND] = "true";
m_skins.clear();
skinSelector->clearLabels();
std::set<std::string> skin_files;
file_manager->listFiles(skin_files /* out */, file_manager->getAsset(FileManager::SKIN,""),
true /* make full path */ );
std::set<std::string> addon_skin_files;
file_manager->listFiles(addon_skin_files /* out */, file_manager->getAddonsFile("skins/"),
true /* make full path */ );
auto lb = [](const std::set<std::string>& files, bool addon,
std::map<core::stringw, std::string>& result)->void
{
for (auto& f : files)
{
std::string stkskin = f + "/stkskin.xml";
if (file_manager->fileExists(stkskin))
{
XMLNode* root = file_manager->createXMLTree(stkskin);
if (!root)
continue;
core::stringw skin_name;
if (root->get("name", &skin_name))
{
std::string skin_id = StringUtils::getBasename(f);
if (addon)
skin_id = std::string("addon_") + skin_id;
result[skin_name] = skin_id;
}
delete root;
}
}
};
lb(skin_files, false, m_skins);
lb(addon_skin_files, true, m_skins);
if (m_skins.size() == 0)
{
Log::warn("OptionsScreenUI", "Could not find a single skin, make sure that "
"the data files are correctly installed");
skinSelector->setActive(false);
return;
}
const int skin_count = (int)m_skins.size();
for (auto& p : m_skins)
skinSelector->addLabel(p.first);
skinSelector->m_properties[GUIEngine::PROP_MIN_VALUE] = "0";
skinSelector->m_properties[GUIEngine::PROP_MAX_VALUE] = StringUtils::toString(skin_count-1);
// Setup the minimap options spinner
GUIEngine::SpinnerWidget* minimap_options = getWidget<GUIEngine::SpinnerWidget>("minimap");
assert( minimap_options != NULL );
minimap_options->m_properties[PROP_WRAP_AROUND] = "true";
minimap_options->clearLabels();
//I18N: In the UI options, minimap position in the race UI
minimap_options->addLabel( core::stringw(_("In the bottom-left")));
//I18N: In the UI options, minimap position in the race UI
minimap_options->addLabel( core::stringw(_("On the right side")));
//I18N: In the UI options, minimap position in the race UI
minimap_options->addLabel( core::stringw(_("Hidden")));
minimap_options->m_properties[GUIEngine::PROP_MIN_VALUE] = "0";
bool multitouch_enabled = (UserConfigParams::m_multitouch_active == 1 &&
irr_driver->getDevice()->supportsTouchDevice()) ||
UserConfigParams::m_multitouch_active > 1;
if (multitouch_enabled && UserConfigParams::m_multitouch_draw_gui)
{
minimap_options->m_properties[GUIEngine::PROP_MIN_VALUE] = "1";
}
minimap_options->m_properties[GUIEngine::PROP_MAX_VALUE] = "2";
GUIEngine::SpinnerWidget* font_size = getWidget<GUIEngine::SpinnerWidget>("font_size");
assert( font_size != NULL );
font_size->clearLabels();
font_size->addLabel(L"Extremely small");
//I18N: In the UI options, Very small font size
font_size->addLabel(_("Very small"));
//I18N: In the UI options, Small font size
font_size->addLabel(_("Small"));
//I18N: In the UI options, Medium font size
font_size->addLabel(_("Medium"));
//I18N: In the UI options, Large font size
font_size->addLabel(_("Large"));
//I18N: In the UI options, Very large font size
font_size->addLabel(_("Very large"));
font_size->addLabel(L"Extremely large");
if (UserConfigParams::m_artist_debug_mode)
{
// Only show extreme size in artist debug mode
font_size->m_properties[GUIEngine::PROP_MIN_VALUE] = "0";
font_size->m_properties[GUIEngine::PROP_MAX_VALUE] = "6";
}
else
{
font_size->m_properties[GUIEngine::PROP_MIN_VALUE] = "1";
font_size->m_properties[GUIEngine::PROP_MAX_VALUE] = "5";
}
} // loadedFromFile
// -----------------------------------------------------------------------------
void OptionsScreenUI::init()
{
Screen::init();
RibbonWidget* ribbon = getWidget<RibbonWidget>("options_choice");
assert(ribbon != NULL);
ribbon->setFocusForPlayer(PLAYER_ID_GAME_MASTER);
ribbon->select( "tab_ui", PLAYER_ID_GAME_MASTER );
GUIEngine::SpinnerWidget* skinSelector = getWidget<GUIEngine::SpinnerWidget>("skinchoice");
assert( skinSelector != NULL );
GUIEngine::SpinnerWidget* minimap_options = getWidget<GUIEngine::SpinnerWidget>("minimap");
assert( minimap_options != NULL );
bool multitouch_enabled = (UserConfigParams::m_multitouch_active == 1 &&
irr_driver->getDevice()->supportsTouchDevice()) ||
UserConfigParams::m_multitouch_active > 1;
if (multitouch_enabled && UserConfigParams::m_multitouch_draw_gui &&
UserConfigParams::m_minimap_display == 0)
{
UserConfigParams::m_minimap_display = 1;
}
minimap_options->setValue(UserConfigParams::m_minimap_display);
bool in_game = StateManager::get()->getGameState() == GUIEngine::INGAME_MENU;
GUIEngine::SpinnerWidget* font_size = getWidget<GUIEngine::SpinnerWidget>("font_size");
assert( font_size != NULL );
int size_int = (int)roundf(UserConfigParams::m_font_size);
if (size_int < 0 || size_int > 6)
size_int = 3;
if (!UserConfigParams::m_artist_debug_mode &&
(size_int < 1 || size_int > 5))
size_int = 3;
font_size->setValue(size_int);
UserConfigParams::m_font_size = font_size->getValue();
font_size->setActive(!in_game);
// ---- video modes
CheckBoxWidget* splitscreen_method = getWidget<CheckBoxWidget>("split_screen_horizontally");
assert(splitscreen_method != NULL);
splitscreen_method->setState(UserConfigParams::split_screen_horizontally);
//Forbid changing this setting in game
splitscreen_method->setActive(!in_game);
CheckBoxWidget* fps = getWidget<CheckBoxWidget>("showfps");
assert( fps != NULL );
fps->setState( UserConfigParams::m_display_fps );
// --- select the right skin in the spinner
bool currSkinFound = false;
const std::string& user_skin = UserConfigParams::m_skin_file;
skinSelector->setActive(!in_game);
for (int n = 0; n < skinSelector->getMax(); n++)
{
auto ret = m_skins.find(skinSelector->getStringValueFromID(n));
if (ret == m_skins.end())
continue;
const std::string skinFileName = ret->second;
if (user_skin == skinFileName)
{
skinSelector->setValue(n);
currSkinFound = true;
break;
}
}
if (!currSkinFound)
{
Log::warn("OptionsScreenUI",
"Couldn't find current skin in the list of skins!");
skinSelector->setValue(0);
irr_driver->unsetMaxTextureSize();
GUIEngine::reloadSkin();
irr_driver->setMaxTextureSize();
}
} // init
// -----------------------------------------------------------------------------
void OptionsScreenUI::eventCallback(Widget* widget, const std::string& name, const int playerID)
{
#ifndef SERVER_ONLY
if (name == "options_choice")
{
std::string selection = ((RibbonWidget*)widget)->getSelectionIDString(PLAYER_ID_GAME_MASTER);
Screen *screen = NULL;
if (selection == "tab_audio")
screen = OptionsScreenAudio::getInstance();
else if (selection == "tab_video")
screen = OptionsScreenVideo::getInstance();
else if (selection == "tab_players")
screen = TabbedUserScreen::getInstance();
else if (selection == "tab_controls")
screen = OptionsScreenInput::getInstance();
//else if (selection == "tab_ui")
// screen = OptionsScreenUI::getInstance();
else if (selection == "tab_general")
screen = OptionsScreenGeneral::getInstance();
else if (selection == "tab_language")
screen = OptionsScreenLanguage::getInstance();
if(screen)
StateManager::get()->replaceTopMostScreen(screen);
}
else if(name == "back")
{
StateManager::get()->escapePressed();
}
else if (name == "skinchoice")
{
GUIEngine::SpinnerWidget* skinSelector = getWidget<GUIEngine::SpinnerWidget>("skinchoice");
assert( skinSelector != NULL );
const core::stringw selectedSkin = skinSelector->getStringValue();
UserConfigParams::m_skin_file = m_skins[selectedSkin];
irr_driver->unsetMaxTextureSize();
bool prev_icon_theme = GUIEngine::getSkin()->hasIconTheme();
bool prev_font = GUIEngine::getSkin()->hasFont();
GUIEngine::reloadSkin();
if (GUIEngine::getSkin()->hasIconTheme() != prev_icon_theme ||
prev_font != GUIEngine::getSkin()->hasFont())
{
if (prev_font != GUIEngine::getSkin()->hasFont())
{
GUIEngine::clear();
GUIEngine::cleanUp();
}
GUIEngine::clearScreenCache();
if (prev_font != GUIEngine::getSkin()->hasFont())
{
delete font_manager;
font_manager = new FontManager();
font_manager->loadFonts();
GUIEngine::init(irr_driver->getDevice(), irr_driver->getVideoDriver(),
StateManager::get(), false/*loading*/);
}
Screen* screen_list[] =
{
MainMenuScreen::getInstance(),
OptionsScreenUI::getInstance(),
nullptr
};
GUIEngine::switchToScreen(MainMenuScreen::getInstance());
StateManager::get()->resetAndSetStack(screen_list);
}
irr_driver->setMaxTextureSize();
}
else if (name == "minimap")
{
GUIEngine::SpinnerWidget* minimap_options = getWidget<GUIEngine::SpinnerWidget>("minimap");
assert( minimap_options != NULL );
UserConfigParams::m_minimap_display = minimap_options->getValue();
}
else if (name == "font_size")
{
GUIEngine::SpinnerWidget* font_size = getWidget<GUIEngine::SpinnerWidget>("font_size");
assert( font_size != NULL );
UserConfigParams::m_font_size = font_size->getValue();
GUIEngine::clear();
GUIEngine::cleanUp();
GUIEngine::clearScreenCache();
delete font_manager;
font_manager = new FontManager();
font_manager->loadFonts();
GUIEngine::init(irr_driver->getDevice(), irr_driver->getVideoDriver(),
StateManager::get(), false/*loading*/);
Screen* screen_list[] =
{
MainMenuScreen::getInstance(),
OptionsScreenUI::getInstance(),
nullptr
};
GUIEngine::switchToScreen(MainMenuScreen::getInstance());
StateManager::get()->resetAndSetStack(screen_list);
}
else if (name == "split_screen_horizontally")
{
CheckBoxWidget* split_screen_horizontally = getWidget<CheckBoxWidget>("split_screen_horizontally");
assert(split_screen_horizontally != NULL);
UserConfigParams::split_screen_horizontally = split_screen_horizontally->getState();
}
else if (name == "showfps")
{
CheckBoxWidget* fps = getWidget<CheckBoxWidget>("showfps");
assert( fps != NULL );
UserConfigParams::m_display_fps = fps->getState();
}
#endif
} // eventCallback
// -----------------------------------------------------------------------------
void OptionsScreenUI::tearDown()
{
Screen::tearDown();
// save changes when leaving screen
user_config->saveConfig();
} // tearDown
// -----------------------------------------------------------------------------
void OptionsScreenUI::unloaded()
{
m_inited = false;
} // unloaded
// -----------------------------------------------------------------------------