Use a better way to erase top text
This commit is contained in:
parent
0fdbe5d34f
commit
44796bc8c0
@ -59,6 +59,38 @@ namespace Private
|
||||
f32 inverse_shaping, f32 scale, std::vector<std::vector<GlyphLayout> >& result);
|
||||
}
|
||||
|
||||
inline void eraseTopLargerThan(std::vector<GlyphLayout>& gls,
|
||||
f32 height_per_line, f32 max_height)
|
||||
{
|
||||
if (max_height < height_per_line * 2.0f)
|
||||
return;
|
||||
|
||||
std::vector<u32> newline_positions;
|
||||
for (unsigned i = 0; i < gls.size(); i++)
|
||||
{
|
||||
const GlyphLayout& glyph = gls[i];
|
||||
if ((glyph.flags & GLF_NEWLINE) != 0)
|
||||
{
|
||||
newline_positions.push_back(i);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// Handle the first line
|
||||
f32 total_height = height_per_line +
|
||||
(f32)newline_positions.size() * height_per_line;
|
||||
if (total_height > max_height)
|
||||
{
|
||||
u32 idx = (u32)((total_height - max_height) / height_per_line);
|
||||
if (idx < newline_positions.size())
|
||||
{
|
||||
auto end_it = gls.begin() + newline_positions[idx] + 1;
|
||||
if (end_it != gls.end())
|
||||
gls.erase(gls.begin(), end_it);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline core::dimension2d<u32> getGlyphLayoutsDimension(
|
||||
const std::vector<GlyphLayout>& gls, s32 height_per_line, f32 inverse_shaping,
|
||||
f32 scale, s32 cluster = -1)
|
||||
|
@ -1,113 +0,0 @@
|
||||
// Copyright (C) 2015 Ben Au
|
||||
// This file is part of the "Irrlicht Engine".
|
||||
// For conditions of distribution and use, see copyright notice in irrlicht.h
|
||||
|
||||
namespace irr
|
||||
{
|
||||
namespace gui
|
||||
{
|
||||
|
||||
//Here a list of characters that don't start or end a line for chinese/japanese/korean
|
||||
//Only commonly use and full width characters are included
|
||||
//You should use full width characters when writing CJK, like using "。"instead of a "."
|
||||
//You can add more characters if needed
|
||||
//For full list please visit http://webapp.docx4java.org/OnlineDemo/ecma376/WordML/kinsoku.html
|
||||
|
||||
inline bool UtfNoStarting (wchar_t c)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
case 8217: //’
|
||||
return true;
|
||||
case 8221: //”
|
||||
return true;
|
||||
case 12293: //々
|
||||
return true;
|
||||
case 12297: //〉
|
||||
return true;
|
||||
case 12299: //》
|
||||
return true;
|
||||
case 12301: //」
|
||||
return true;
|
||||
case 65373: //}
|
||||
return true;
|
||||
case 12309: //〕
|
||||
return true;
|
||||
case 65289: //)
|
||||
return true;
|
||||
case 12303: //』
|
||||
return true;
|
||||
case 12305: //】
|
||||
return true;
|
||||
case 12311: //〗
|
||||
return true;
|
||||
case 65281: //!
|
||||
return true;
|
||||
case 65285: //%
|
||||
return true;
|
||||
case 65311: //?
|
||||
return true;
|
||||
case 65344: //`
|
||||
return true;
|
||||
case 65292: //,
|
||||
return true;
|
||||
case 65306: //:
|
||||
return true;
|
||||
case 65307: //;
|
||||
return true;
|
||||
case 65294: //.
|
||||
return true;
|
||||
case 12290: //。
|
||||
return true;
|
||||
case 12289: //、
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
inline bool UtfNoEnding (wchar_t c)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
case 8216: //‘
|
||||
return true;
|
||||
case 8220: //“
|
||||
return true;
|
||||
case 12296: //〈
|
||||
return true;
|
||||
case 12298: //《
|
||||
return true;
|
||||
case 12300: //「
|
||||
return true;
|
||||
case 65371: //{
|
||||
return true;
|
||||
case 12308: //〔
|
||||
return true;
|
||||
case 65288: //(
|
||||
return true;
|
||||
case 12302: //『
|
||||
return true;
|
||||
case 12304: //【
|
||||
return true;
|
||||
case 12310: //〖
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
//Helper function
|
||||
|
||||
inline bool breakable (wchar_t c)
|
||||
{
|
||||
if ((c > 12287 && c < 40960) || //Common CJK words
|
||||
(c > 44031 && c < 55204) || //Hangul
|
||||
(c > 63743 && c < 64256) || //More Chinese
|
||||
c == 173 || c == L' ' || //Soft hyphen and white space
|
||||
c == 47 || c == 92) //Slash and blackslash
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
} // end namespace gui
|
||||
} // end namespace irr
|
@ -633,35 +633,35 @@ void ClientLobby::handleServerInfo(Event* event)
|
||||
// At least 6 bytes should remain now
|
||||
if (!checkDataSize(event, 6)) return;
|
||||
|
||||
core::stringw str, total_lines;
|
||||
if (!m_first_connect)
|
||||
{
|
||||
NetworkingLobby::getInstance()
|
||||
->addMoreServerInfo(L"--------------------");
|
||||
total_lines = L"--------------------";
|
||||
total_lines += L"\n";
|
||||
}
|
||||
m_first_connect = false;
|
||||
|
||||
NetworkString &data = event->data();
|
||||
// Add server info
|
||||
core::stringw str, each_line;
|
||||
uint8_t u_data;
|
||||
data.decodeStringW(&str);
|
||||
|
||||
//I18N: In the networking lobby
|
||||
each_line = _("Server name: %s", str);
|
||||
NetworkingLobby::getInstance()->addMoreServerInfo(each_line);
|
||||
total_lines += _("Server name: %s", str);
|
||||
total_lines += L"\n";
|
||||
|
||||
u_data = data.getUInt8();
|
||||
const core::stringw& difficulty_name =
|
||||
race_manager->getDifficultyName((RaceManager::Difficulty)u_data);
|
||||
race_manager->setDifficulty((RaceManager::Difficulty)u_data);
|
||||
//I18N: In the networking lobby
|
||||
each_line = _("Difficulty: %s", difficulty_name);
|
||||
NetworkingLobby::getInstance()->addMoreServerInfo(each_line);
|
||||
total_lines += _("Difficulty: %s", difficulty_name);
|
||||
total_lines += L"\n";
|
||||
|
||||
unsigned max_player = data.getUInt8();
|
||||
//I18N: In the networking lobby
|
||||
each_line = _("Max players: %d", (int)max_player);
|
||||
NetworkingLobby::getInstance()->addMoreServerInfo(each_line);
|
||||
total_lines += _("Max players: %d", (int)max_player);
|
||||
total_lines += L"\n";
|
||||
|
||||
// Reserved for extra spectators
|
||||
u_data = data.getUInt8();
|
||||
@ -673,8 +673,8 @@ void ClientLobby::handleServerInfo(Event* event)
|
||||
|
||||
//I18N: In the networking lobby
|
||||
core::stringw mode_name = ServerConfig::getModeName(u_data);
|
||||
each_line = _("Game mode: %s", mode_name);
|
||||
NetworkingLobby::getInstance()->addMoreServerInfo(each_line);
|
||||
total_lines += _("Game mode: %s", mode_name);
|
||||
total_lines += L"\n";
|
||||
|
||||
uint8_t extra_server_info = data.getUInt8();
|
||||
bool grand_prix_started = false;
|
||||
@ -691,8 +691,8 @@ void ClientLobby::handleServerInfo(Event* event)
|
||||
core::stringw sgt = u_data == 0 ? tl : gl;
|
||||
m_game_setup->setSoccerGoalTarget(u_data != 0);
|
||||
//I18N: In the networking lobby
|
||||
each_line = _("Soccer game type: %s", sgt);
|
||||
NetworkingLobby::getInstance()->addMoreServerInfo(each_line);
|
||||
total_lines += _("Soccer game type: %s", sgt);
|
||||
total_lines += L"\n";
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
@ -701,9 +701,9 @@ void ClientLobby::handleServerInfo(Event* event)
|
||||
grand_prix_started = cur_gp_track != 0;
|
||||
unsigned total_gp_track = data.getUInt8();
|
||||
m_game_setup->setGrandPrixTrack(total_gp_track);
|
||||
each_line = _("Grand prix progress: %d / %d", cur_gp_track,
|
||||
total_lines += _("Grand prix progress: %d / %d", cur_gp_track,
|
||||
total_gp_track);
|
||||
NetworkingLobby::getInstance()->addMoreServerInfo(each_line);
|
||||
total_lines += L"\n";
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -716,13 +716,16 @@ void ClientLobby::handleServerInfo(Event* event)
|
||||
// MOTD
|
||||
core::stringw motd;
|
||||
data.decodeString16(&motd);
|
||||
const std::vector<core::stringw>& motd_line = StringUtils::split(motd,
|
||||
'\n');
|
||||
if (!motd_line.empty())
|
||||
{
|
||||
for (const core::stringw& motd : motd_line)
|
||||
NetworkingLobby::getInstance()->addMoreServerInfo(motd);
|
||||
}
|
||||
if (!motd.empty())
|
||||
total_lines += motd;
|
||||
|
||||
// Remove last newline added, network lobby will add it back later after
|
||||
// removing old server info (with chat)
|
||||
if (total_lines[total_lines.size() - 1] == L'\n')
|
||||
total_lines.erase(total_lines.size() - 1);
|
||||
|
||||
NetworkingLobby::getInstance()->addMoreServerInfo(total_lines);
|
||||
|
||||
bool server_config = data.getUInt8() == 1;
|
||||
NetworkingLobby::getInstance()->toggleServerConfigButton(server_config);
|
||||
m_server_live_joinable = data.getUInt8() == 1;
|
||||
|
@ -23,6 +23,7 @@
|
||||
|
||||
#include "config/user_config.hpp"
|
||||
#include "config/player_manager.hpp"
|
||||
#include "font/font_manager.hpp"
|
||||
#include "graphics/irr_driver.hpp"
|
||||
#include "guiengine/CGUISpriteBank.hpp"
|
||||
#include "guiengine/scalable_font.hpp"
|
||||
@ -51,8 +52,6 @@
|
||||
#include "tracks/track.hpp"
|
||||
#include "utils/translation.hpp"
|
||||
|
||||
#include <utfwrapping.h>
|
||||
|
||||
using namespace Online;
|
||||
using namespace GUIEngine;
|
||||
|
||||
@ -234,41 +233,33 @@ void NetworkingLobby::init()
|
||||
void NetworkingLobby::addMoreServerInfo(core::stringw info)
|
||||
{
|
||||
const unsigned box_width = m_text_bubble->getDimension().Width;
|
||||
while (GUIEngine::getFont()->getDimension(info.c_str()).Width > box_width)
|
||||
{
|
||||
core::stringw brokentext = info;
|
||||
while (brokentext.size() > 0)
|
||||
{
|
||||
brokentext.erase(brokentext.size() - 1);
|
||||
if (GUIEngine::getFont()->getDimension(brokentext.c_str()).Width <
|
||||
box_width && gui::breakable(brokentext.lastChar()))
|
||||
break;
|
||||
}
|
||||
if (brokentext.size() == 0)
|
||||
break;
|
||||
m_server_info.push_back(brokentext);
|
||||
info =
|
||||
info.subString(brokentext.size(), info.size() - brokentext.size());
|
||||
}
|
||||
if (info.size() > 0)
|
||||
{
|
||||
m_server_info.push_back(info);
|
||||
}
|
||||
while ((int)m_server_info.size() * m_server_info_height >
|
||||
m_text_bubble->getDimension().Height)
|
||||
{
|
||||
m_server_info.erase(m_server_info.begin());
|
||||
}
|
||||
const float box_height = m_text_bubble->getDimension().Height;
|
||||
// For future copy text from lobby chat
|
||||
std::vector<std::u32string> text_line;
|
||||
std::vector<GlyphLayout> cur_info;
|
||||
font_manager->initGlyphLayouts(info, cur_info, &text_line);
|
||||
gui::IGUIFont* font = GUIEngine::getFont();
|
||||
gui::breakGlyphLayouts(cur_info, box_width,
|
||||
font->getInverseShaping(), font->getScale());
|
||||
m_server_info.insert(m_server_info.end(), cur_info.begin(),
|
||||
cur_info.end());
|
||||
gui::eraseTopLargerThan(m_server_info, font->getHeightPerLine(),
|
||||
box_height);
|
||||
|
||||
// Don't take the newly added newline marker int layouts for linebreaking
|
||||
// height calculation
|
||||
gui::GlyphLayout new_line = { 0 };
|
||||
new_line.flags = gui::GLF_NEWLINE;
|
||||
m_server_info.push_back(new_line);
|
||||
|
||||
if (GUIEngine::getCurrentScreen() != this)
|
||||
return;
|
||||
core::stringw total_msg;
|
||||
for (auto& string : m_server_info)
|
||||
{
|
||||
total_msg += string;
|
||||
total_msg += L"\n";
|
||||
}
|
||||
m_text_bubble->setText(total_msg, true);
|
||||
|
||||
gui::IGUIStaticText* st =
|
||||
m_text_bubble->getIrrlichtElement<gui::IGUIStaticText>();
|
||||
st->setUseGlyphLayoutsOnly(true);
|
||||
st->setGlyphLayouts(m_server_info);
|
||||
|
||||
} // addMoreServerInfo
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -451,6 +442,8 @@ void NetworkingLobby::onUpdate(float delta)
|
||||
|
||||
if (m_state == LS_ADD_PLAYERS)
|
||||
{
|
||||
m_text_bubble->getIrrlichtElement<gui::IGUIStaticText>()
|
||||
->setUseGlyphLayoutsOnly(false);
|
||||
m_text_bubble->setText(_("Everyone:\nPress the 'Select' button to "
|
||||
"join the game"), false);
|
||||
m_start_button->setVisible(false);
|
||||
@ -465,6 +458,8 @@ void NetworkingLobby::onUpdate(float delta)
|
||||
m_start_button->setVisible(false);
|
||||
if (!cl || !cl->isLobbyReady())
|
||||
{
|
||||
m_text_bubble->getIrrlichtElement<gui::IGUIStaticText>()
|
||||
->setUseGlyphLayoutsOnly(false);
|
||||
core::stringw connect_msg;
|
||||
if (m_joined_server)
|
||||
{
|
||||
|
@ -20,9 +20,9 @@
|
||||
|
||||
#include "guiengine/screen.hpp"
|
||||
#include "guiengine/widgets/text_box_widget.hpp"
|
||||
#include "GlyphLayout.h"
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <tuple>
|
||||
#include <utility>
|
||||
|
||||
class InputDevice;
|
||||
@ -69,7 +69,8 @@ private:
|
||||
uint64_t m_ping_update_timer;
|
||||
std::map<std::string, LobbyPlayer> m_player_names;
|
||||
std::shared_ptr<Server> m_joined_server;
|
||||
std::vector<core::stringw> m_server_info;
|
||||
|
||||
std::vector<gui::GlyphLayout> m_server_info;
|
||||
int m_server_info_height;
|
||||
|
||||
core::stringw m_start_text, m_ready_text, m_live_join_text,
|
||||
|
Loading…
Reference in New Issue
Block a user