forked from Mirrorlandia_minetest/minetest
Mainmenu: Avoid the header being displayed behind the formspec (#13924)
This change keeps the current header placement code, but adds additional code to make sure the header doesn't end up behind the formspec.
This commit is contained in:
parent
6783734612
commit
4255ac3022
@ -283,11 +283,16 @@ void GUIEngine::run()
|
|||||||
else
|
else
|
||||||
drawBackground(driver);
|
drawBackground(driver);
|
||||||
|
|
||||||
drawHeader(driver);
|
|
||||||
drawFooter(driver);
|
drawFooter(driver);
|
||||||
|
|
||||||
m_rendering_engine->get_gui_env()->drawAll();
|
m_rendering_engine->get_gui_env()->drawAll();
|
||||||
|
|
||||||
|
// The header *must* be drawn after the menu because it uses
|
||||||
|
// GUIFormspecMenu::getAbsoluteRect().
|
||||||
|
// The header *can* be drawn after the menu because it never intersects
|
||||||
|
// the menu.
|
||||||
|
drawHeader(driver);
|
||||||
|
|
||||||
driver->endScene();
|
driver->endScene();
|
||||||
|
|
||||||
IrrlichtDevice *device = m_rendering_engine->get_raw_device();
|
IrrlichtDevice *device = m_rendering_engine->get_raw_device();
|
||||||
@ -478,29 +483,56 @@ void GUIEngine::drawHeader(video::IVideoDriver *driver)
|
|||||||
|
|
||||||
video::ITexture* texture = m_textures[TEX_LAYER_HEADER].texture;
|
video::ITexture* texture = m_textures[TEX_LAYER_HEADER].texture;
|
||||||
|
|
||||||
/* If no texture, draw nothing */
|
// If no texture, draw nothing
|
||||||
if(!texture)
|
if (!texture)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Calculate the maximum rectangle
|
||||||
|
*/
|
||||||
|
core::rect<s32> formspec_rect = m_menu->getAbsoluteRect();
|
||||||
|
// 4 px of padding on each side
|
||||||
|
core::rect<s32> max_rect(4, 4, screensize.Width - 8, formspec_rect.UpperLeftCorner.Y - 8);
|
||||||
|
|
||||||
|
// If no space (less than 16x16 px), draw nothing
|
||||||
|
if (max_rect.getWidth() < 16 || max_rect.getHeight() < 16)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Calculate the preferred rectangle
|
||||||
|
*/
|
||||||
f32 mult = (((f32)screensize.Width / 2.0)) /
|
f32 mult = (((f32)screensize.Width / 2.0)) /
|
||||||
((f32)texture->getOriginalSize().Width);
|
((f32)texture->getOriginalSize().Width);
|
||||||
|
|
||||||
v2s32 splashsize(((f32)texture->getOriginalSize().Width) * mult,
|
v2s32 splashsize(((f32)texture->getOriginalSize().Width) * mult,
|
||||||
((f32)texture->getOriginalSize().Height) * mult);
|
((f32)texture->getOriginalSize().Height) * mult);
|
||||||
|
|
||||||
// Don't draw the header if there isn't enough room
|
|
||||||
s32 free_space = (((s32)screensize.Height)-320)/2;
|
s32 free_space = (((s32)screensize.Height)-320)/2;
|
||||||
|
|
||||||
if (free_space > splashsize.Y) {
|
core::rect<s32> desired_rect(0, 0, splashsize.X, splashsize.Y);
|
||||||
core::rect<s32> splashrect(0, 0, splashsize.X, splashsize.Y);
|
desired_rect += v2s32((screensize.Width/2)-(splashsize.X/2),
|
||||||
splashrect += v2s32((screensize.Width/2)-(splashsize.X/2),
|
((free_space/2)-splashsize.Y/2)+10);
|
||||||
((free_space/2)-splashsize.Y/2)+10);
|
|
||||||
|
|
||||||
draw2DImageFilterScaled(driver, texture, splashrect,
|
/*
|
||||||
|
* Make the preferred rectangle fit into the maximum rectangle
|
||||||
|
*/
|
||||||
|
// 1. Scale
|
||||||
|
f32 scale = std::min((f32)max_rect.getWidth() / (f32)desired_rect.getWidth(),
|
||||||
|
(f32)max_rect.getHeight() / (f32)desired_rect.getHeight());
|
||||||
|
if (scale < 1.0f) {
|
||||||
|
v2s32 old_center = desired_rect.getCenter();
|
||||||
|
desired_rect.LowerRightCorner.X = desired_rect.UpperLeftCorner.X + desired_rect.getWidth() * scale;
|
||||||
|
desired_rect.LowerRightCorner.Y = desired_rect.UpperLeftCorner.Y + desired_rect.getHeight() * scale;
|
||||||
|
desired_rect += old_center - desired_rect.getCenter();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. Move
|
||||||
|
desired_rect.constrainTo(max_rect);
|
||||||
|
|
||||||
|
draw2DImageFilterScaled(driver, texture, desired_rect,
|
||||||
core::rect<s32>(core::position2d<s32>(0,0),
|
core::rect<s32>(core::position2d<s32>(0,0),
|
||||||
core::dimension2di(texture->getOriginalSize())),
|
core::dimension2di(texture->getOriginalSize())),
|
||||||
NULL, NULL, true);
|
NULL, NULL, true);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
@ -247,6 +247,14 @@ std::vector<std::string>* GUIFormSpecMenu::getDropDownValues(const std::string &
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This will only return a meaningful value if called after drawMenu().
|
||||||
|
core::rect<s32> GUIFormSpecMenu::getAbsoluteRect()
|
||||||
|
{
|
||||||
|
core::rect<s32> rect = AbsoluteRect;
|
||||||
|
rect.UpperLeftCorner.Y += m_tabheader_upper_edge;
|
||||||
|
return rect;
|
||||||
|
}
|
||||||
|
|
||||||
v2s32 GUIFormSpecMenu::getElementBasePos(const std::vector<std::string> *v_pos)
|
v2s32 GUIFormSpecMenu::getElementBasePos(const std::vector<std::string> *v_pos)
|
||||||
{
|
{
|
||||||
v2f32 pos_f = v2f32(padding.X, padding.Y) + pos_offset * spacing;
|
v2f32 pos_f = v2f32(padding.X, padding.Y) + pos_offset * spacing;
|
||||||
@ -2104,6 +2112,7 @@ void GUIFormSpecMenu::parseTabHeader(parserData* data, const std::string &elemen
|
|||||||
e->setActiveTab(tab_index);
|
e->setActiveTab(tab_index);
|
||||||
|
|
||||||
m_fields.push_back(spec);
|
m_fields.push_back(spec);
|
||||||
|
m_tabheader_upper_edge = MYMIN(m_tabheader_upper_edge, rect.UpperLeftCorner.Y);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GUIFormSpecMenu::parseItemImageButton(parserData* data, const std::string &element)
|
void GUIFormSpecMenu::parseItemImageButton(parserData* data, const std::string &element)
|
||||||
@ -3105,6 +3114,7 @@ void GUIFormSpecMenu::regenerateGui(v2u32 screensize)
|
|||||||
|
|
||||||
m_formspec_version = 1;
|
m_formspec_version = 1;
|
||||||
m_bgcolor = video::SColor(140, 0, 0, 0);
|
m_bgcolor = video::SColor(140, 0, 0, 0);
|
||||||
|
m_tabheader_upper_edge = 0;
|
||||||
|
|
||||||
{
|
{
|
||||||
v3f formspec_bgcolor = g_settings->getV3F("formspec_fullscreen_bg_color");
|
v3f formspec_bgcolor = g_settings->getV3F("formspec_fullscreen_bg_color");
|
||||||
|
@ -282,6 +282,9 @@ public:
|
|||||||
GUITable* getTable(const std::string &tablename);
|
GUITable* getTable(const std::string &tablename);
|
||||||
std::vector<std::string>* getDropDownValues(const std::string &name);
|
std::vector<std::string>* getDropDownValues(const std::string &name);
|
||||||
|
|
||||||
|
// This will only return a meaningful value if called after drawMenu().
|
||||||
|
core::rect<s32> getAbsoluteRect();
|
||||||
|
|
||||||
#ifdef __ANDROID__
|
#ifdef __ANDROID__
|
||||||
bool getAndroidUIInput();
|
bool getAndroidUIInput();
|
||||||
#endif
|
#endif
|
||||||
@ -499,6 +502,9 @@ private:
|
|||||||
|
|
||||||
int m_btn_height;
|
int m_btn_height;
|
||||||
gui::IGUIFont *m_font = nullptr;
|
gui::IGUIFont *m_font = nullptr;
|
||||||
|
|
||||||
|
// used by getAbsoluteRect
|
||||||
|
s32 m_tabheader_upper_edge = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class FormspecFormSource: public IFormSource
|
class FormspecFormSource: public IFormSource
|
||||||
|
Loading…
Reference in New Issue
Block a user