Add resizing of GUIEngine (only works with some screen)
This commit is contained in:
parent
d7695cb0a7
commit
da1d41bf85
@ -633,6 +633,11 @@ video::IVideoModeList* CIrrDeviceSDL::getVideoModeList()
|
||||
//! Sets if the window should be resizable in windowed mode.
|
||||
void CIrrDeviceSDL::setResizable(bool resize)
|
||||
{
|
||||
#if SDL_VERSION_ATLEAST(2, 0, 5)
|
||||
if (CreationParams.Fullscreen)
|
||||
return;
|
||||
SDL_SetWindowResizable(Window, resize ? SDL_TRUE : SDL_FALSE);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
@ -82,6 +82,7 @@ FontWithFace::~FontWithFace()
|
||||
*/
|
||||
void FontWithFace::init()
|
||||
{
|
||||
m_glyph_max_height = 0;
|
||||
setDPI();
|
||||
#ifndef SERVER_ONLY
|
||||
if (GUIEngine::isNoGraphics())
|
||||
|
@ -20,7 +20,10 @@
|
||||
#include "challenges/story_mode_timer.hpp"
|
||||
#include "config/player_manager.hpp"
|
||||
#include "config/user_config.hpp"
|
||||
#include "font/bold_face.hpp"
|
||||
#include "font/digit_face.hpp"
|
||||
#include "font/font_manager.hpp"
|
||||
#include "font/regular_face.hpp"
|
||||
#include "graphics/2dutils.hpp"
|
||||
#include "graphics/b3d_mesh_loader.hpp"
|
||||
#include "graphics/camera.hpp"
|
||||
@ -54,6 +57,8 @@
|
||||
#include "guiengine/modaldialog.hpp"
|
||||
#include "guiengine/scalable_font.hpp"
|
||||
#include "guiengine/screen.hpp"
|
||||
#include "guiengine/screen_keyboard.hpp"
|
||||
#include "guiengine/skin.hpp"
|
||||
#include "io/file_manager.hpp"
|
||||
#include "items/item_manager.hpp"
|
||||
#include "items/powerup_manager.hpp"
|
||||
@ -1982,6 +1987,24 @@ void IrrDriver::doScreenShot()
|
||||
image->drop();
|
||||
} // doScreenShot
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void IrrDriver::handleWindowResize()
|
||||
{
|
||||
if (m_actual_screen_size != m_video_driver->getCurrentRenderTargetSize())
|
||||
{
|
||||
// Don't update when dialog is opened
|
||||
if (GUIEngine::ModalDialog::isADialogActive() ||
|
||||
GUIEngine::ScreenKeyboard::isActive() ||
|
||||
StateManager::get()->getGameState() != GUIEngine::MENU)
|
||||
return;
|
||||
|
||||
m_actual_screen_size = m_video_driver->getCurrentRenderTargetSize();
|
||||
UserConfigParams::m_width = m_actual_screen_size.Width;
|
||||
UserConfigParams::m_height = m_actual_screen_size.Height;
|
||||
resizeWindow();
|
||||
}
|
||||
} // handleWindowResize
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Update, called once per frame.
|
||||
* \param dt Time since last update
|
||||
@ -1990,18 +2013,23 @@ void IrrDriver::doScreenShot()
|
||||
*/
|
||||
void IrrDriver::update(float dt, bool is_loading)
|
||||
{
|
||||
bool show_dialog_yes = m_resolution_changing == RES_CHANGE_YES;
|
||||
bool show_dialog_warn = m_resolution_changing == RES_CHANGE_YES_WARN;
|
||||
// If the resolution should be switched, do it now. This will delete the
|
||||
// old device and create a new one.
|
||||
if (m_resolution_changing!=RES_CHANGE_NONE)
|
||||
{
|
||||
applyResolutionSettings(m_resolution_changing != RES_CHANGE_SAME);
|
||||
if(m_resolution_changing==RES_CHANGE_YES)
|
||||
new ConfirmResolutionDialog(false);
|
||||
else if(m_resolution_changing==RES_CHANGE_YES_WARN)
|
||||
new ConfirmResolutionDialog(true);
|
||||
m_resolution_changing = RES_CHANGE_NONE;
|
||||
}
|
||||
|
||||
handleWindowResize();
|
||||
|
||||
if (show_dialog_yes)
|
||||
new ConfirmResolutionDialog(false);
|
||||
else if (show_dialog_warn)
|
||||
new ConfirmResolutionDialog(true);
|
||||
|
||||
m_wind->update();
|
||||
|
||||
PropertyAnimator::get()->update(dt);
|
||||
@ -2301,3 +2329,35 @@ void IrrDriver::resetDebugModes()
|
||||
SP::sp_debug_view = false;
|
||||
#endif
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void IrrDriver::resizeWindow()
|
||||
{
|
||||
// Reload fonts
|
||||
font_manager->getFont<BoldFace>()->init();
|
||||
font_manager->getFont<DigitFace>()->init();
|
||||
font_manager->getFont<RegularFace>()->init();
|
||||
// Reload GUIEngine
|
||||
GUIEngine::reloadForNewSize();
|
||||
|
||||
#ifdef ENABLE_RECORDER
|
||||
ogrDestroy();
|
||||
RecorderConfig cfg;
|
||||
cfg.m_triple_buffering = 1;
|
||||
cfg.m_record_audio = 1;
|
||||
cfg.m_width = m_actual_screen_size.Width;
|
||||
cfg.m_height = m_actual_screen_size.Height;
|
||||
int vf = UserConfigParams::m_video_format;
|
||||
cfg.m_video_format = (VideoFormat)vf;
|
||||
cfg.m_audio_format = OGR_AF_VORBIS;
|
||||
cfg.m_audio_bitrate = UserConfigParams::m_audio_bitrate;
|
||||
cfg.m_video_bitrate = UserConfigParams::m_video_bitrate;
|
||||
cfg.m_record_fps = UserConfigParams::m_record_fps;
|
||||
cfg.m_record_jpg_quality = UserConfigParams::m_recorder_jpg_quality;
|
||||
if (ogrInitConfig(&cfg) == 0)
|
||||
{
|
||||
Log::error("irr_driver",
|
||||
"RecorderConfig is invalid, use the default one.");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -194,7 +194,8 @@ private:
|
||||
/** Used to visualise skeletons. */
|
||||
std::vector<irr::scene::IAnimatedMeshSceneNode*> m_debug_meshes;
|
||||
#endif
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
void resizeWindow();
|
||||
public:
|
||||
void doScreenShot();
|
||||
public:
|
||||
@ -534,6 +535,8 @@ public:
|
||||
// ------------------------------------------------------------------------
|
||||
u32 getDefaultFramebuffer() const
|
||||
{ return m_video_driver->getDefaultFramebuffer(); }
|
||||
// ------------------------------------------------------------------------
|
||||
void handleWindowResize();
|
||||
}; // IrrDriver
|
||||
|
||||
extern IrrDriver *irr_driver;
|
||||
|
@ -295,7 +295,8 @@ void AbstractStateManager::resetAndSetStack(Screen* screens[])
|
||||
assert(!ModalDialog::isADialogActive());
|
||||
assert(!ScreenKeyboard::isActive());
|
||||
|
||||
if (m_game_mode != GAME) getCurrentScreen()->tearDown();
|
||||
if (m_game_mode != GAME && getCurrentScreen())
|
||||
getCurrentScreen()->tearDown();
|
||||
m_menu_stack.clear();
|
||||
|
||||
for (int n=0; screens[n] != NULL; n++)
|
||||
@ -311,3 +312,21 @@ void AbstractStateManager::resetAndSetStack(Screen* screens[])
|
||||
onTopMostScreenChanged();
|
||||
} // resetAndSetStack
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
void AbstractStateManager::onResize()
|
||||
{
|
||||
// Happens in the first resize in main.cpp
|
||||
if (m_menu_stack.empty())
|
||||
return;
|
||||
|
||||
std::vector<std::function<Screen*()> > screen_function;
|
||||
for (auto& p : m_menu_stack)
|
||||
screen_function.push_back(p.second->getNewScreenPointer());
|
||||
clearScreenCache();
|
||||
std::vector<Screen*> new_screen;
|
||||
for (auto& screen : screen_function)
|
||||
new_screen.push_back(screen());
|
||||
new_screen.push_back(NULL);
|
||||
resetAndSetStack(new_screen.data());
|
||||
} // onResize
|
||||
|
@ -110,6 +110,11 @@ namespace GUIEngine
|
||||
*/
|
||||
void resetAndSetStack(Screen* screens[]);
|
||||
|
||||
/**
|
||||
* \brief Called when resizing of stk window
|
||||
*/
|
||||
void onResize();
|
||||
|
||||
/**
|
||||
* \brief Used in no graphics STK to enter menu screen (when server is
|
||||
* idle state)
|
||||
|
@ -1176,6 +1176,18 @@ namespace GUIEngine
|
||||
assert(g_skin->getReferenceCount() == 1);
|
||||
} // reloadSkin
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
void reloadForNewSize()
|
||||
{
|
||||
g_skin->resetBackgroundImage();
|
||||
Private::font_height = g_font->getDimension( L"X" ).Height;
|
||||
Private::large_font_height = g_large_font->getDimension( L"X" ).Height;
|
||||
Private::small_font_height = g_small_font->getDimension( L"X" ).Height;
|
||||
Private::title_font_height =
|
||||
g_title_font->getDimension( L"X" ).Height;
|
||||
StateManager::get()->onResize();
|
||||
} // reloadForNewSize
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
void addGUIFunctionBeforeRendering(std::function<void()> func)
|
||||
{
|
||||
|
@ -257,6 +257,11 @@ namespace GUIEngine
|
||||
*/
|
||||
void reloadSkin();
|
||||
|
||||
/**
|
||||
* \brief call when screen size changed
|
||||
*/
|
||||
void reloadForNewSize();
|
||||
|
||||
/**
|
||||
* \brief Add gui-related function before rendering GUI (from other thread)
|
||||
*/
|
||||
|
@ -102,8 +102,9 @@ protected:
|
||||
/** A pointer to the Container for the Message */
|
||||
SkinWidgetContainer* m_container;
|
||||
|
||||
/** Font used to detect if re-initialization is needed */
|
||||
/** Font and screen size used to detect if re-initialization is needed */
|
||||
gui::IGUIFont* m_font;
|
||||
core::dimension2du m_screen_size;
|
||||
public:
|
||||
TextMessage(MessageQueue::MessageType mt, const core::stringw &message) :
|
||||
Message(5.0f, message)
|
||||
@ -135,8 +136,9 @@ public:
|
||||
{
|
||||
const GUIEngine::BoxRenderParams &brp =
|
||||
GUIEngine::getSkin()->getBoxRenderParams(m_render_type);
|
||||
const unsigned width = irr_driver->getActualScreenSize().Width;
|
||||
const unsigned height = irr_driver->getActualScreenSize().Height;
|
||||
m_screen_size = irr_driver->getActualScreenSize();
|
||||
const unsigned width = m_screen_size.Width;
|
||||
const unsigned height = m_screen_size.Height;
|
||||
m_font = GUIEngine::getFont();
|
||||
m_font->initGlyphLayouts(m_message, m_gls);
|
||||
// Reserve space for 3 lines of text, it will occupy the circle
|
||||
@ -204,7 +206,8 @@ public:
|
||||
Message::draw(dt);
|
||||
// This happen when GUIEngine is reset (when font size changed for
|
||||
// example)
|
||||
if (m_font != GUIEngine::getFont())
|
||||
if (m_font != GUIEngine::getFont() ||
|
||||
m_screen_size != irr_driver->getActualScreenSize())
|
||||
init();
|
||||
int pos_transform = 0;
|
||||
if (m_container == g_container.get())
|
||||
|
@ -39,9 +39,10 @@ using namespace irr;
|
||||
#include "guiengine/event_handler.hpp"
|
||||
#include "guiengine/widget.hpp"
|
||||
#include "input/input.hpp"
|
||||
#include "utils/leak_check.hpp"
|
||||
#include "utils/ptr_vector.hpp"
|
||||
|
||||
#include "utils/leak_check.hpp"
|
||||
#include <functional>
|
||||
|
||||
/**
|
||||
* \ingroup guiengine
|
||||
@ -58,7 +59,6 @@ namespace GUIEngine
|
||||
{
|
||||
protected:
|
||||
static SCREEN* singleton;
|
||||
|
||||
public:
|
||||
|
||||
~ScreenSingleton()
|
||||
@ -71,12 +71,14 @@ namespace GUIEngine
|
||||
if (singleton == NULL)
|
||||
{
|
||||
singleton = new SCREEN();
|
||||
std::function<SCREEN*()> new_screen_function = []()
|
||||
{ return ScreenSingleton::getInstance(); };
|
||||
singleton->setScreenPointerFunction(new_screen_function);
|
||||
GUIEngine::addScreenToList(singleton);
|
||||
}
|
||||
|
||||
return singleton;
|
||||
}
|
||||
|
||||
};
|
||||
template <typename SCREEN> SCREEN*
|
||||
ScreenSingleton<SCREEN>::singleton = nullptr;
|
||||
@ -118,6 +120,8 @@ namespace GUIEngine
|
||||
*/
|
||||
bool m_update_in_background;
|
||||
|
||||
/** For runtime screen reloading without template */
|
||||
std::function<Screen*()> m_screen_func;
|
||||
protected:
|
||||
bool m_throttle_FPS;
|
||||
|
||||
@ -137,6 +141,12 @@ namespace GUIEngine
|
||||
PtrVector<Widget>& append_to,
|
||||
irr::gui::IGUIElement* parent = NULL);
|
||||
|
||||
/** Save the function before GUIEngine::clearScreenCache, call it after
|
||||
* to get the new screen instance pointer
|
||||
*/
|
||||
std::function<Screen*()> getNewScreenPointer() const { return m_screen_func; }
|
||||
|
||||
void setScreenPointerFunction(const std::function<Screen*()>& f) { m_screen_func = f; }
|
||||
|
||||
Screen(bool pause_race=true);
|
||||
|
||||
|
@ -334,6 +334,7 @@ namespace GUIEngine
|
||||
|
||||
~Skin();
|
||||
|
||||
void resetBackgroundImage() { m_bg_image = NULL; }
|
||||
static video::SColor getColor(const std::string &name);
|
||||
void renderSections(PtrVector<Widget>* within_vector=NULL);
|
||||
void drawBgImage();
|
||||
|
@ -2152,6 +2152,8 @@ int main(int argc, char *argv[])
|
||||
#ifndef SERVER_ONLY
|
||||
if (!GUIEngine::isNoGraphics())
|
||||
{
|
||||
// The screen size may change after loading
|
||||
irr_driver->handleWindowResize();
|
||||
// Some Android devices have only 320x240 and height >= 480 is bare
|
||||
// minimum to make the GUI working as expected.
|
||||
if (irr_driver->getActualScreenSize().Height < 480)
|
||||
|
Loading…
x
Reference in New Issue
Block a user