forked from Mirrorlandia_minetest/minetest
GameUI refactor (part 2/X): Move Game::guitext to GameUI + enhancements on StaticText
Other enhancements: * C++ friendlyness for addStaticText() -> move to static StaticText::add()
This commit is contained in:
parent
0ebaed430a
commit
3a772e7ed6
@ -19,7 +19,55 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
*/
|
||||
|
||||
#include "gameui.h"
|
||||
#include "settings.h"
|
||||
#include <irrlicht_changes/static_text.h>
|
||||
#include "gui/mainmenumanager.h"
|
||||
#include "client.h"
|
||||
#include "fontengine.h"
|
||||
#include "clientmap.h"
|
||||
#include "version.h"
|
||||
#include "renderingengine.h"
|
||||
|
||||
void GameUI::init()
|
||||
{
|
||||
// First line of debug text
|
||||
m_guitext = gui::StaticText::add(guienv, utf8_to_wide(PROJECT_NAME_C).c_str(),
|
||||
core::rect<s32>(0, 0, 0, 0), false, false, guiroot);
|
||||
}
|
||||
|
||||
void GameUI::update(const RunStats &stats, Client *client,
|
||||
const MapDrawControl *draw_control)
|
||||
{
|
||||
if (m_flags.show_debug) {
|
||||
static float drawtime_avg = 0;
|
||||
drawtime_avg = drawtime_avg * 0.95 + stats.drawtime * 0.05;
|
||||
u16 fps = 1.0 / stats.dtime_jitter.avg;
|
||||
|
||||
std::ostringstream os(std::ios_base::binary);
|
||||
os << std::fixed
|
||||
<< PROJECT_NAME_C " " << g_version_hash
|
||||
<< ", FPS: " << fps
|
||||
<< std::setprecision(0)
|
||||
<< ", drawtime: " << drawtime_avg << "ms"
|
||||
<< std::setprecision(1)
|
||||
<< ", dtime jitter: "
|
||||
<< (stats.dtime_jitter.max_fraction * 100.0) << "%"
|
||||
<< std::setprecision(1)
|
||||
<< ", view range: "
|
||||
<< (draw_control->range_all ? "All" : itos(draw_control->wanted_range))
|
||||
<< std::setprecision(3)
|
||||
<< ", RTT: " << client->getRTT() << "s";
|
||||
setStaticText(m_guitext, utf8_to_wide(os.str()).c_str());
|
||||
m_guitext->setVisible(true);
|
||||
} else {
|
||||
m_guitext->setVisible(false);
|
||||
}
|
||||
|
||||
if (m_guitext->isVisible()) {
|
||||
v2u32 screensize = RenderingEngine::get_instance()->getWindowSize();
|
||||
m_guitext->setRelativePosition(core::rect<s32>(5, 5, screensize.X,
|
||||
5 + g_fontengine->getTextHeight()));
|
||||
}
|
||||
}
|
||||
|
||||
void GameUI::initFlags()
|
||||
{
|
||||
@ -29,7 +77,7 @@ void GameUI::initFlags()
|
||||
m_flags.show_debug = g_settings->getBool("show_debug");
|
||||
}
|
||||
|
||||
void GameUI::showMinimap(const bool show)
|
||||
void GameUI::showMinimap(bool show)
|
||||
{
|
||||
m_flags.show_minimap = show;
|
||||
}
|
||||
|
@ -20,9 +20,12 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "IGUIEnvironment.h"
|
||||
#include <IGUIEnvironment.h>
|
||||
#include "game.h"
|
||||
|
||||
using namespace irr;
|
||||
class Client;
|
||||
struct MapDrawControl;
|
||||
|
||||
class GameUI
|
||||
{
|
||||
@ -30,6 +33,9 @@ class GameUI
|
||||
friend class Game;
|
||||
|
||||
public:
|
||||
GameUI() = default;
|
||||
~GameUI() = default;
|
||||
|
||||
// Flags that can, or may, change during main game loop
|
||||
struct Flags
|
||||
{
|
||||
@ -42,16 +48,19 @@ public:
|
||||
bool disable_camera_update;
|
||||
};
|
||||
|
||||
void init();
|
||||
void update(const RunStats &stats, Client *client, const MapDrawControl *draw_control);
|
||||
|
||||
void initFlags();
|
||||
const Flags &getFlags() const { return m_flags; }
|
||||
|
||||
void showMinimap(const bool show);
|
||||
void showMinimap(bool show);
|
||||
|
||||
private:
|
||||
Flags m_flags;
|
||||
|
||||
gui::IGUIStaticText *m_guitext; // First line of debug text
|
||||
// @TODO future move
|
||||
// gui::IGUIStaticText *m_guitext; // First line of debug text
|
||||
// gui::IGUIStaticText *m_guitext2; // Second line of debug text
|
||||
// gui::IGUIStaticText *m_guitext_info; // At the middle of the screen
|
||||
// gui::IGUIStaticText *m_guitext_status;
|
||||
|
60
src/game.cpp
60
src/game.cpp
@ -1174,16 +1174,6 @@ struct GameRunData {
|
||||
float time_of_day_smooth;
|
||||
};
|
||||
|
||||
struct Jitter {
|
||||
f32 max, min, avg, counter, max_sample, min_sample, max_fraction;
|
||||
};
|
||||
|
||||
struct RunStats {
|
||||
u32 drawtime;
|
||||
|
||||
Jitter dtime_jitter, busy_time_jitter;
|
||||
};
|
||||
|
||||
class Game;
|
||||
|
||||
struct ClientEventHandler
|
||||
@ -1452,7 +1442,6 @@ private:
|
||||
|
||||
/* GUI stuff
|
||||
*/
|
||||
gui::IGUIStaticText *guitext; // First line of debug text
|
||||
gui::IGUIStaticText *guitext2; // Second line of debug text
|
||||
gui::IGUIStaticText *guitext_info; // At the middle of the screen
|
||||
gui::IGUIStaticText *guitext_status;
|
||||
@ -1998,34 +1987,30 @@ bool Game::createClient(const std::string &playername,
|
||||
|
||||
bool Game::initGui()
|
||||
{
|
||||
// First line of debug text
|
||||
guitext = addStaticText(guienv,
|
||||
utf8_to_wide(PROJECT_NAME_C).c_str(),
|
||||
core::rect<s32>(0, 0, 0, 0),
|
||||
false, false, guiroot);
|
||||
m_game_ui->init();
|
||||
|
||||
// Second line of debug text
|
||||
guitext2 = addStaticText(guienv,
|
||||
guitext2 = gui::StaticText::add(guienv,
|
||||
L"",
|
||||
core::rect<s32>(0, 0, 0, 0),
|
||||
false, false, guiroot);
|
||||
|
||||
// At the middle of the screen
|
||||
// Object infos are shown in this
|
||||
guitext_info = addStaticText(guienv,
|
||||
guitext_info = gui::StaticText::add(guienv,
|
||||
L"",
|
||||
core::rect<s32>(0, 0, 400, g_fontengine->getTextHeight() * 5 + 5) + v2s32(100, 200),
|
||||
false, true, guiroot);
|
||||
|
||||
// Status text (displays info when showing and hiding GUI stuff, etc.)
|
||||
guitext_status = addStaticText(guienv,
|
||||
guitext_status = gui::StaticText::add(guienv,
|
||||
L"<Status>",
|
||||
core::rect<s32>(0, 0, 0, 0),
|
||||
false, false, guiroot);
|
||||
guitext_status->setVisible(false);
|
||||
|
||||
// Chat text
|
||||
guitext_chat = addStaticText(
|
||||
guitext_chat = gui::StaticText::add(
|
||||
guienv,
|
||||
L"",
|
||||
core::rect<s32>(0, 0, 0, 0),
|
||||
@ -2048,7 +2033,7 @@ bool Game::initGui()
|
||||
}
|
||||
|
||||
// Profiler text (size is updated when text is updated)
|
||||
guitext_profiler = addStaticText(guienv,
|
||||
guitext_profiler = gui::StaticText::add(guienv,
|
||||
L"<Profiler>",
|
||||
core::rect<s32>(0, 0, 0, 0),
|
||||
false, false, guiroot);
|
||||
@ -4410,38 +4395,7 @@ void Game::updateGui(const RunStats &stats, f32 dtime, const CameraOrientation &
|
||||
LocalPlayer *player = client->getEnv().getLocalPlayer();
|
||||
v3f player_position = player->getPosition();
|
||||
|
||||
if (m_game_ui->m_flags.show_debug) {
|
||||
static float drawtime_avg = 0;
|
||||
drawtime_avg = drawtime_avg * 0.95 + stats.drawtime * 0.05;
|
||||
u16 fps = 1.0 / stats.dtime_jitter.avg;
|
||||
|
||||
std::ostringstream os(std::ios_base::binary);
|
||||
os << std::fixed
|
||||
<< PROJECT_NAME_C " " << g_version_hash
|
||||
<< ", FPS: " << fps
|
||||
<< std::setprecision(0)
|
||||
<< ", drawtime: " << drawtime_avg << "ms"
|
||||
<< std::setprecision(1)
|
||||
<< ", dtime jitter: "
|
||||
<< (stats.dtime_jitter.max_fraction * 100.0) << "%"
|
||||
<< std::setprecision(1)
|
||||
<< ", view range: "
|
||||
<< (draw_control->range_all ? "All" : itos(draw_control->wanted_range))
|
||||
<< std::setprecision(3)
|
||||
<< ", RTT: " << client->getRTT() << "s";
|
||||
setStaticText(guitext, utf8_to_wide(os.str()).c_str());
|
||||
guitext->setVisible(true);
|
||||
} else {
|
||||
guitext->setVisible(false);
|
||||
}
|
||||
|
||||
if (guitext->isVisible()) {
|
||||
core::rect<s32> rect(
|
||||
5, 5,
|
||||
screensize.X, 5 + g_fontengine->getTextHeight()
|
||||
);
|
||||
guitext->setRelativePosition(rect);
|
||||
}
|
||||
m_game_ui->update(stats, client, draw_control);
|
||||
|
||||
if (m_game_ui->m_flags.show_debug) {
|
||||
std::ostringstream os(std::ios_base::binary);
|
||||
|
10
src/game.h
10
src/game.h
@ -26,6 +26,16 @@ class InputHandler;
|
||||
class ChatBackend; /* to avoid having to include chat.h */
|
||||
struct SubgameSpec;
|
||||
|
||||
struct Jitter {
|
||||
f32 max, min, avg, counter, max_sample, min_sample, max_fraction;
|
||||
};
|
||||
|
||||
struct RunStats {
|
||||
u32 drawtime;
|
||||
|
||||
Jitter dtime_jitter, busy_time_jitter;
|
||||
};
|
||||
|
||||
void the_game(bool *kill,
|
||||
bool random_input,
|
||||
InputHandler *input,
|
||||
|
@ -149,9 +149,8 @@ GUIEngine::GUIEngine(JoystickController *joystick,
|
||||
g_fontengine->getTextHeight());
|
||||
rect += v2s32(4, 0);
|
||||
|
||||
m_irr_toplefttext =
|
||||
addStaticText(RenderingEngine::get_gui_env(), m_toplefttext,
|
||||
rect, false, true, 0, -1);
|
||||
m_irr_toplefttext = gui::StaticText::add(RenderingEngine::get_gui_env(),
|
||||
m_toplefttext, rect, false, true, 0, -1);
|
||||
|
||||
//create formspecsource
|
||||
m_formspecgui = new FormspecFormSource("");
|
||||
@ -560,9 +559,8 @@ void GUIEngine::updateTopLeftTextSize()
|
||||
rect += v2s32(4, 0);
|
||||
|
||||
m_irr_toplefttext->remove();
|
||||
m_irr_toplefttext =
|
||||
addStaticText(RenderingEngine::get_gui_env(), m_toplefttext,
|
||||
rect, false, true, 0, -1);
|
||||
m_irr_toplefttext = gui::StaticText::add(RenderingEngine::get_gui_env(),
|
||||
m_toplefttext, rect, false, true, 0, -1);
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
@ -950,12 +950,12 @@ void GUIFormSpecMenu::parsePwdField(parserData* data, const std::string &element
|
||||
Environment->setFocus(e);
|
||||
}
|
||||
|
||||
if (label.length() >= 1)
|
||||
{
|
||||
if (label.length() >= 1) {
|
||||
int font_height = g_fontengine->getTextHeight();
|
||||
rect.UpperLeftCorner.Y -= font_height;
|
||||
rect.LowerRightCorner.Y = rect.UpperLeftCorner.Y + font_height;
|
||||
addStaticText(Environment, spec.flabel.c_str(), rect, false, true, this, 0);
|
||||
gui::StaticText::add(Environment, spec.flabel.c_str(), rect, false, true,
|
||||
this, 0);
|
||||
}
|
||||
|
||||
e->setPasswordBox(true,L'*');
|
||||
@ -1017,7 +1017,8 @@ void GUIFormSpecMenu::parseSimpleField(parserData* data,
|
||||
|
||||
if (name.empty()) {
|
||||
// spec field id to 0, this stops submit searching for a value that isn't there
|
||||
addStaticText(Environment, spec.flabel.c_str(), rect, false, true, this, spec.fid);
|
||||
gui::StaticText::add(Environment, spec.flabel.c_str(), rect, false, true, this,
|
||||
spec.fid);
|
||||
} else {
|
||||
spec.send = true;
|
||||
gui::IGUIElement *e;
|
||||
@ -1050,7 +1051,8 @@ void GUIFormSpecMenu::parseSimpleField(parserData* data,
|
||||
int font_height = g_fontengine->getTextHeight();
|
||||
rect.UpperLeftCorner.Y -= font_height;
|
||||
rect.LowerRightCorner.Y = rect.UpperLeftCorner.Y + font_height;
|
||||
addStaticText(Environment, spec.flabel.c_str(), rect, false, true, this, 0);
|
||||
gui::StaticText::add(Environment, spec.flabel.c_str(), rect, false, true,
|
||||
this, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1162,7 +1164,8 @@ void GUIFormSpecMenu::parseTextArea(parserData* data, std::vector<std::string>&
|
||||
int font_height = g_fontengine->getTextHeight();
|
||||
rect.UpperLeftCorner.Y -= font_height;
|
||||
rect.LowerRightCorner.Y = rect.UpperLeftCorner.Y + font_height;
|
||||
addStaticText(Environment, spec.flabel.c_str(), rect, false, true, this, 0);
|
||||
gui::StaticText::add(Environment, spec.flabel.c_str(), rect, false, true,
|
||||
this, 0);
|
||||
}
|
||||
|
||||
if (parts.size() >= 6) {
|
||||
@ -1237,11 +1240,9 @@ void GUIFormSpecMenu::parseLabel(parserData* data, const std::string &element)
|
||||
L"",
|
||||
258+m_fields.size()
|
||||
);
|
||||
gui::IGUIStaticText *e =
|
||||
addStaticText(Environment, spec.flabel.c_str(),
|
||||
rect, false, false, this, spec.fid);
|
||||
e->setTextAlignment(gui::EGUIA_UPPERLEFT,
|
||||
gui::EGUIA_CENTER);
|
||||
gui::IGUIStaticText *e = gui::StaticText::add(Environment,
|
||||
spec.flabel.c_str(), rect, false, false, this, spec.fid);
|
||||
e->setTextAlignment(gui::EGUIA_UPPERLEFT, gui::EGUIA_CENTER);
|
||||
m_fields.push_back(spec);
|
||||
}
|
||||
|
||||
@ -1291,8 +1292,8 @@ void GUIFormSpecMenu::parseVertLabel(parserData* data, const std::string &elemen
|
||||
L"",
|
||||
258+m_fields.size()
|
||||
);
|
||||
gui::IGUIStaticText *t =
|
||||
addStaticText(Environment, spec.flabel.c_str(), rect, false, false, this, spec.fid);
|
||||
gui::IGUIStaticText *t = gui::StaticText::add(Environment, spec.flabel.c_str(),
|
||||
rect, false, false, this, spec.fid);
|
||||
t->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_CENTER);
|
||||
m_fields.push_back(spec);
|
||||
return;
|
||||
@ -2024,7 +2025,8 @@ void GUIFormSpecMenu::regenerateGui(v2u32 screensize)
|
||||
{
|
||||
assert(!m_tooltip_element);
|
||||
// Note: parent != this so that the tooltip isn't clipped by the menu rectangle
|
||||
m_tooltip_element = addStaticText(Environment, L"",core::rect<s32>(0,0,110,18));
|
||||
m_tooltip_element = gui::StaticText::add(Environment, L"",
|
||||
core::rect<s32>(0,0,110,18));
|
||||
m_tooltip_element->enableOverrideColor(true);
|
||||
m_tooltip_element->setBackgroundColor(m_default_tooltip_bgcolor);
|
||||
m_tooltip_element->setDrawBackground(true);
|
||||
|
@ -42,6 +42,59 @@ namespace gui
|
||||
//! destructor
|
||||
virtual ~StaticText();
|
||||
|
||||
static irr::gui::IGUIStaticText *add(
|
||||
irr::gui::IGUIEnvironment *guienv,
|
||||
const EnrichedString &text,
|
||||
const core::rect< s32 > &rectangle,
|
||||
bool border = false,
|
||||
bool wordWrap = true,
|
||||
irr::gui::IGUIElement *parent = NULL,
|
||||
s32 id = -1,
|
||||
bool fillBackground = false)
|
||||
{
|
||||
if (parent == NULL) {
|
||||
// parent is NULL, so we must find one, or we need not to drop
|
||||
// result, but then there will be a memory leak.
|
||||
//
|
||||
// What Irrlicht does is to use guienv as a parent, but the problem
|
||||
// is that guienv is here only an IGUIEnvironment, while it is a
|
||||
// CGUIEnvironment in Irrlicht, which inherits from both IGUIElement
|
||||
// and IGUIEnvironment.
|
||||
//
|
||||
// A solution would be to dynamic_cast guienv to a
|
||||
// IGUIElement*, but Irrlicht is shipped without rtti support
|
||||
// in some distributions, causing the dymanic_cast to segfault.
|
||||
//
|
||||
// Thus, to find the parent, we create a dummy StaticText and ask
|
||||
// for its parent, and then remove it.
|
||||
irr::gui::IGUIStaticText *dummy_text =
|
||||
guienv->addStaticText(L"", rectangle, border, wordWrap,
|
||||
parent, id, fillBackground);
|
||||
parent = dummy_text->getParent();
|
||||
dummy_text->remove();
|
||||
}
|
||||
irr::gui::IGUIStaticText *result = new irr::gui::StaticText(
|
||||
text, border, guienv, parent,
|
||||
id, rectangle, fillBackground);
|
||||
|
||||
result->setWordWrap(wordWrap);
|
||||
result->drop();
|
||||
return result;
|
||||
}
|
||||
|
||||
static irr::gui::IGUIStaticText *add(
|
||||
irr::gui::IGUIEnvironment *guienv,
|
||||
const wchar_t *text,
|
||||
const core::rect< s32 > &rectangle,
|
||||
bool border = false,
|
||||
bool wordWrap = true,
|
||||
irr::gui::IGUIElement *parent = NULL,
|
||||
s32 id = -1,
|
||||
bool fillBackground = false)
|
||||
{
|
||||
return add(guienv, EnrichedString(text), rectangle, border, wordWrap, parent, id, fillBackground);
|
||||
}
|
||||
|
||||
//! draws the element and its children
|
||||
virtual void draw();
|
||||
|
||||
@ -171,46 +224,6 @@ namespace gui
|
||||
|
||||
} // end namespace irr
|
||||
|
||||
inline irr::gui::IGUIStaticText *addStaticText(
|
||||
irr::gui::IGUIEnvironment *guienv,
|
||||
const EnrichedString &text,
|
||||
const core::rect< s32 > &rectangle,
|
||||
bool border = false,
|
||||
bool wordWrap = true,
|
||||
irr::gui::IGUIElement *parent = NULL,
|
||||
s32 id = -1,
|
||||
bool fillBackground = false)
|
||||
{
|
||||
if (parent == NULL) {
|
||||
// parent is NULL, so we must find one, or we need not to drop
|
||||
// result, but then there will be a memory leak.
|
||||
//
|
||||
// What Irrlicht does is to use guienv as a parent, but the problem
|
||||
// is that guienv is here only an IGUIEnvironment, while it is a
|
||||
// CGUIEnvironment in Irrlicht, which inherits from both IGUIElement
|
||||
// and IGUIEnvironment.
|
||||
//
|
||||
// A solution would be to dynamic_cast guienv to a
|
||||
// IGUIElement*, but Irrlicht is shipped without rtti support
|
||||
// in some distributions, causing the dymanic_cast to segfault.
|
||||
//
|
||||
// Thus, to find the parent, we create a dummy StaticText and ask
|
||||
// for its parent, and then remove it.
|
||||
irr::gui::IGUIStaticText *dummy_text =
|
||||
guienv->addStaticText(L"", rectangle, border, wordWrap,
|
||||
parent, id, fillBackground);
|
||||
parent = dummy_text->getParent();
|
||||
dummy_text->remove();
|
||||
}
|
||||
irr::gui::IGUIStaticText *result = new irr::gui::StaticText(
|
||||
text, border, guienv, parent,
|
||||
id, rectangle, fillBackground);
|
||||
|
||||
result->setWordWrap(wordWrap);
|
||||
result->drop();
|
||||
return result;
|
||||
}
|
||||
|
||||
inline void setStaticText(irr::gui::IGUIStaticText *static_text, const EnrichedString &text)
|
||||
{
|
||||
// dynamic_cast not possible due to some distributions shipped
|
||||
@ -245,18 +258,6 @@ inline void setStaticText(irr::gui::IGUIStaticText *static_text, const EnrichedS
|
||||
|
||||
#endif
|
||||
|
||||
inline irr::gui::IGUIStaticText *addStaticText(
|
||||
irr::gui::IGUIEnvironment *guienv,
|
||||
const wchar_t *text,
|
||||
const core::rect< s32 > &rectangle,
|
||||
bool border = false,
|
||||
bool wordWrap = true,
|
||||
irr::gui::IGUIElement *parent = NULL,
|
||||
s32 id = -1,
|
||||
bool fillBackground = false) {
|
||||
return addStaticText(guienv, EnrichedString(text), rectangle, border, wordWrap, parent, id, fillBackground);
|
||||
}
|
||||
|
||||
inline void setStaticText(irr::gui::IGUIStaticText *static_text, const wchar_t *text)
|
||||
{
|
||||
setStaticText(static_text, EnrichedString(text));
|
||||
|
@ -47,11 +47,14 @@ void TestGameUI::testInit()
|
||||
gui.initFlags();
|
||||
UASSERT(gui.getFlags().show_chat)
|
||||
UASSERT(gui.getFlags().show_hud)
|
||||
|
||||
// @TODO verify if we can create non UI nulldevice to test this function
|
||||
gui.init();
|
||||
}
|
||||
|
||||
void TestGameUI::testFlagSetters()
|
||||
{
|
||||
GameUI gui;
|
||||
GameUI gui{};
|
||||
gui.showMinimap(true);
|
||||
UASSERT(gui.getFlags().show_minimap);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user