Fix crash when widget is cleared and old spinner widget received callback
This commit is contained in:
parent
10af6f7a80
commit
b1bcfd94a1
@ -143,6 +143,18 @@ void OptionsScreenUI::loadedFromFile()
|
|||||||
font_size->m_properties[GUIEngine::PROP_MIN_VALUE] = "1";
|
font_size->m_properties[GUIEngine::PROP_MIN_VALUE] = "1";
|
||||||
font_size->m_properties[GUIEngine::PROP_MAX_VALUE] = "5";
|
font_size->m_properties[GUIEngine::PROP_MAX_VALUE] = "5";
|
||||||
}
|
}
|
||||||
|
font_size->setValueUpdatedCallback([this](SpinnerWidget* spinner)
|
||||||
|
{
|
||||||
|
// Add a special value updated callback so font size is updated when
|
||||||
|
// it's pressed instead of release to prevent multiple event
|
||||||
|
bool right = spinner->isButtonSelected(true/*right*/);
|
||||||
|
UserConfigParams::m_font_size = spinner->getValue();
|
||||||
|
m_reload_option = std::unique_ptr<ReloadOption>(new ReloadOption);
|
||||||
|
m_reload_option->m_reload_font = true;
|
||||||
|
m_reload_option->m_reload_skin = false;
|
||||||
|
m_reload_option->m_focus_name = "font_size";
|
||||||
|
m_reload_option->m_focus_right = right;
|
||||||
|
});
|
||||||
} // loadedFromFile
|
} // loadedFromFile
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
@ -357,45 +369,15 @@ void OptionsScreenUI::eventCallback(Widget* widget, const std::string& name, con
|
|||||||
const core::stringw selectedSkin = skinSelector->getStringValue();
|
const core::stringw selectedSkin = skinSelector->getStringValue();
|
||||||
bool right = skinSelector->isButtonSelected(true/*right*/);
|
bool right = skinSelector->isButtonSelected(true/*right*/);
|
||||||
UserConfigParams::m_skin_file = m_skins[selectedSkin];
|
UserConfigParams::m_skin_file = m_skins[selectedSkin];
|
||||||
irr_driver->unsetMaxTextureSize();
|
|
||||||
bool prev_icon_theme = GUIEngine::getSkin()->hasIconTheme();
|
|
||||||
bool prev_font = GUIEngine::getSkin()->hasFont();
|
bool prev_font = GUIEngine::getSkin()->hasFont();
|
||||||
|
irr_driver->unsetMaxTextureSize();
|
||||||
GUIEngine::reloadSkin();
|
GUIEngine::reloadSkin();
|
||||||
if (GUIEngine::getSkin()->hasIconTheme() != prev_icon_theme ||
|
// Reload GUIEngine will clear widgets so we don't do that in eventCallback
|
||||||
prev_font != GUIEngine::getSkin()->hasFont())
|
m_reload_option = std::unique_ptr<ReloadOption>(new ReloadOption);
|
||||||
{
|
m_reload_option->m_reload_font = prev_font != GUIEngine::getSkin()->hasFont();
|
||||||
if (prev_font != GUIEngine::getSkin()->hasFont())
|
m_reload_option->m_reload_skin = true;
|
||||||
{
|
m_reload_option->m_focus_name = "skinchoice";
|
||||||
GUIEngine::clear();
|
m_reload_option->m_focus_right = right;
|
||||||
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);
|
|
||||||
// Need to use new widget pointer
|
|
||||||
skinSelector =
|
|
||||||
OptionsScreenUI::getInstance()->getWidget<GUIEngine::SpinnerWidget>("skinchoice");
|
|
||||||
skinSelector->setFocusForPlayer(PLAYER_ID_GAME_MASTER);
|
|
||||||
skinSelector->setSelectedButton(right);
|
|
||||||
}
|
|
||||||
irr_driver->setMaxTextureSize();
|
|
||||||
}
|
}
|
||||||
else if (name == "minimap")
|
else if (name == "minimap")
|
||||||
{
|
{
|
||||||
@ -409,27 +391,12 @@ void OptionsScreenUI::eventCallback(Widget* widget, const std::string& name, con
|
|||||||
assert( font_size != NULL );
|
assert( font_size != NULL );
|
||||||
bool right = font_size->isButtonSelected(true/*right*/);
|
bool right = font_size->isButtonSelected(true/*right*/);
|
||||||
UserConfigParams::m_font_size = font_size->getValue();
|
UserConfigParams::m_font_size = font_size->getValue();
|
||||||
GUIEngine::clear();
|
// Reload GUIEngine will clear widgets so we don't do that in eventCallback
|
||||||
GUIEngine::cleanUp();
|
m_reload_option = std::unique_ptr<ReloadOption>(new ReloadOption);
|
||||||
GUIEngine::clearScreenCache();
|
m_reload_option->m_reload_font = true;
|
||||||
delete font_manager;
|
m_reload_option->m_reload_skin = false;
|
||||||
font_manager = new FontManager();
|
m_reload_option->m_focus_name = "font_size";
|
||||||
font_manager->loadFonts();
|
m_reload_option->m_focus_right = right;
|
||||||
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);
|
|
||||||
// Need to use new widget pointer
|
|
||||||
font_size =
|
|
||||||
OptionsScreenUI::getInstance()->getWidget<GUIEngine::SpinnerWidget>("font_size");
|
|
||||||
font_size->setFocusForPlayer(PLAYER_ID_GAME_MASTER);
|
|
||||||
font_size->setSelectedButton(right);
|
|
||||||
}
|
}
|
||||||
else if (name == "splitscreen_method")
|
else if (name == "splitscreen_method")
|
||||||
{
|
{
|
||||||
@ -494,6 +461,62 @@ void OptionsScreenUI::eventCallback(Widget* widget, const std::string& name, con
|
|||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void OptionsScreenUI::onUpdate(float delta)
|
||||||
|
{
|
||||||
|
if (m_reload_option)
|
||||||
|
reloadGUIEngine();
|
||||||
|
} // onUpdate
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void OptionsScreenUI::reloadGUIEngine()
|
||||||
|
{
|
||||||
|
bool reload_font = m_reload_option->m_reload_font;
|
||||||
|
bool reload_skin = m_reload_option->m_reload_skin;
|
||||||
|
std::string focus_name = m_reload_option->m_focus_name;
|
||||||
|
bool focus_right = m_reload_option->m_focus_right;
|
||||||
|
|
||||||
|
if (reload_skin || reload_font)
|
||||||
|
{
|
||||||
|
if (reload_font)
|
||||||
|
{
|
||||||
|
GUIEngine::clear();
|
||||||
|
GUIEngine::cleanUp();
|
||||||
|
}
|
||||||
|
|
||||||
|
GUIEngine::clearScreenCache();
|
||||||
|
|
||||||
|
if (reload_font)
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
GUIEngine::SpinnerWidget* spinner = OptionsScreenUI::getInstance()
|
||||||
|
->getWidget<GUIEngine::SpinnerWidget>(focus_name.c_str());
|
||||||
|
spinner->setFocusForPlayer(PLAYER_ID_GAME_MASTER);
|
||||||
|
spinner->setSelectedButton(focus_right);
|
||||||
|
}
|
||||||
|
if (reload_skin)
|
||||||
|
{
|
||||||
|
irr_driver->setMaxTextureSize();
|
||||||
|
}
|
||||||
|
OptionsScreenUI::getInstance()->m_reload_option = nullptr;
|
||||||
|
} // reloadGUIEngine
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
void OptionsScreenUI::tearDown()
|
void OptionsScreenUI::tearDown()
|
||||||
{
|
{
|
||||||
Screen::tearDown();
|
Screen::tearDown();
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
#ifndef __HEADER_OPTIONS_SCREEN_UI_HPP__
|
#ifndef __HEADER_OPTIONS_SCREEN_UI_HPP__
|
||||||
#define __HEADER_OPTIONS_SCREEN_UI_HPP__
|
#define __HEADER_OPTIONS_SCREEN_UI_HPP__
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "guiengine/screen.hpp"
|
#include "guiengine/screen.hpp"
|
||||||
@ -33,6 +34,14 @@ struct Input;
|
|||||||
*/
|
*/
|
||||||
class OptionsScreenUI : public GUIEngine::Screen, public GUIEngine::ScreenSingleton<OptionsScreenUI>
|
class OptionsScreenUI : public GUIEngine::Screen, public GUIEngine::ScreenSingleton<OptionsScreenUI>
|
||||||
{
|
{
|
||||||
|
struct ReloadOption
|
||||||
|
{
|
||||||
|
bool m_reload_font;
|
||||||
|
bool m_reload_skin;
|
||||||
|
std::string m_focus_name;
|
||||||
|
bool m_focus_right;
|
||||||
|
};
|
||||||
|
std::unique_ptr<ReloadOption> m_reload_option;
|
||||||
OptionsScreenUI();
|
OptionsScreenUI();
|
||||||
bool m_inited;
|
bool m_inited;
|
||||||
|
|
||||||
@ -56,6 +65,10 @@ public:
|
|||||||
|
|
||||||
/** \brief implement optional callback from parent class GUIEngine::Screen */
|
/** \brief implement optional callback from parent class GUIEngine::Screen */
|
||||||
virtual void unloaded() OVERRIDE;
|
virtual void unloaded() OVERRIDE;
|
||||||
|
|
||||||
|
virtual void onUpdate(float delta) OVERRIDE;
|
||||||
|
|
||||||
|
void reloadGUIEngine();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user