mirror of
https://github.com/minetest/minetest.git
synced 2024-11-26 17:43:45 +01:00
Add bold, italic and monospace font styling for HUD text elements (#11478)
Co-authored-by: Elias Fleckenstein <eliasfleckenstein@web.de>
This commit is contained in:
parent
cf136914cf
commit
6e8aebf432
@ -1314,6 +1314,8 @@ It can be created via `Raycast(pos1, pos2, objects, liquids)` or
|
||||
-- ^ See "HUD Element Types"
|
||||
size = { x=100, y=100 }, -- default {x=0, y=0}
|
||||
-- ^ Size of element in pixels
|
||||
style = 0,
|
||||
-- ^ For "text" elements sets font style: bitfield with 1 = bold, 2 = italic, 4 = monospace
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -8447,6 +8447,9 @@ Used by `Player:hud_add`. Returned by `Player:hud_get`.
|
||||
|
||||
z_index = 0,
|
||||
-- Z index : lower z-index HUDs are displayed behind higher z-index HUDs
|
||||
|
||||
style = 0,
|
||||
-- For "text" elements sets font style: bitfield with 1 = bold, 2 = italic, 4 = monospace
|
||||
}
|
||||
|
||||
Particle definition
|
||||
|
81
games/devtest/mods/testhud/init.lua
Normal file
81
games/devtest/mods/testhud/init.lua
Normal file
@ -0,0 +1,81 @@
|
||||
local player_huds = {}
|
||||
|
||||
local states = {
|
||||
{0, "Normal font"},
|
||||
{1, "Bold font"},
|
||||
{2, "Italic font"},
|
||||
{3, "Bold and italic font"},
|
||||
{4, "Monospace font"},
|
||||
{5, "Bold and monospace font"},
|
||||
{7, "ZOMG all the font styles"},
|
||||
}
|
||||
|
||||
|
||||
local default_def = {
|
||||
hud_elem_type = "text",
|
||||
position = {x = 0.5, y = 0.5},
|
||||
scale = {x = 2, y = 2},
|
||||
alignment = { x = 0, y = 0 },
|
||||
}
|
||||
|
||||
local function add_hud(player, state)
|
||||
local def = table.copy(default_def)
|
||||
local statetbl = states[state]
|
||||
def.offset = {x = 0, y = 32 * state}
|
||||
def.style = statetbl[1]
|
||||
def.text = statetbl[2]
|
||||
return player:hud_add(def)
|
||||
end
|
||||
|
||||
minetest.register_on_leaveplayer(function(player)
|
||||
player_huds[player:get_player_name()] = nil
|
||||
end)
|
||||
|
||||
local etime = 0
|
||||
local state = 0
|
||||
|
||||
minetest.register_globalstep(function(dtime)
|
||||
etime = etime + dtime
|
||||
if etime < 1 then
|
||||
return
|
||||
end
|
||||
etime = 0
|
||||
for _, player in ipairs(minetest.get_connected_players()) do
|
||||
local huds = player_huds[player:get_player_name()]
|
||||
if huds then
|
||||
for i, hud_id in ipairs(huds) do
|
||||
local statetbl = states[(state + i) % #states + 1]
|
||||
player:hud_change(hud_id, "style", statetbl[1])
|
||||
player:hud_change(hud_id, "text", statetbl[2])
|
||||
end
|
||||
end
|
||||
end
|
||||
state = state + 1
|
||||
end)
|
||||
|
||||
minetest.register_chatcommand("hudfonts", {
|
||||
params = "",
|
||||
description = "Show/Hide some text on the HUD with various font options",
|
||||
func = function(name, param)
|
||||
local player = minetest.get_player_by_name(name)
|
||||
local param = tonumber(param) or 0
|
||||
param = math.min(math.max(param, 1), #states)
|
||||
if player_huds[name] == nil then
|
||||
player_huds[name] = {}
|
||||
for i = 1, param do
|
||||
table.insert(player_huds[name], add_hud(player, i))
|
||||
end
|
||||
minetest.chat_send_player(name, ("%d HUD element(s) added."):format(param))
|
||||
else
|
||||
local huds = player_huds[name]
|
||||
if huds then
|
||||
for _, hud_id in ipairs(huds) do
|
||||
player:hud_remove(hud_id)
|
||||
end
|
||||
minetest.chat_send_player(name, "All HUD elements removed.")
|
||||
end
|
||||
player_huds[name] = nil
|
||||
end
|
||||
return true
|
||||
end,
|
||||
})
|
2
games/devtest/mods/testhud/mod.conf
Normal file
2
games/devtest/mods/testhud/mod.conf
Normal file
@ -0,0 +1,2 @@
|
||||
name = testhud
|
||||
description = For testing HUD functionality
|
@ -59,7 +59,7 @@ struct ClientEventHudAdd
|
||||
v2f pos, scale;
|
||||
std::string name;
|
||||
std::string text, text2;
|
||||
u32 number, item, dir;
|
||||
u32 number, item, dir, style;
|
||||
v2f align, offset;
|
||||
v3f world_pos;
|
||||
v2s32 size;
|
||||
|
@ -2730,6 +2730,7 @@ void Game::handleClientEvent_HudAdd(ClientEvent *event, CameraOrientation *cam)
|
||||
e->size = event->hudadd->size;
|
||||
e->z_index = event->hudadd->z_index;
|
||||
e->text2 = event->hudadd->text2;
|
||||
e->style = event->hudadd->style;
|
||||
m_hud_server_to_client[server_id] = player->addHud(e);
|
||||
|
||||
delete event->hudadd;
|
||||
@ -2795,6 +2796,8 @@ void Game::handleClientEvent_HudChange(ClientEvent *event, CameraOrientation *ca
|
||||
CASE_SET(HUD_STAT_Z_INDEX, z_index, data);
|
||||
|
||||
CASE_SET(HUD_STAT_TEXT2, text2, sdata);
|
||||
|
||||
CASE_SET(HUD_STAT_STYLE, style, data);
|
||||
}
|
||||
|
||||
#undef CASE_SET
|
||||
|
@ -331,8 +331,8 @@ bool Hud::calculateScreenPos(const v3s16 &camera_offset, HudElement *e, v2s32 *p
|
||||
|
||||
void Hud::drawLuaElements(const v3s16 &camera_offset)
|
||||
{
|
||||
u32 text_height = g_fontengine->getTextHeight();
|
||||
irr::gui::IGUIFont* font = g_fontengine->getFont();
|
||||
const u32 text_height = g_fontengine->getTextHeight();
|
||||
gui::IGUIFont *const font = g_fontengine->getFont();
|
||||
|
||||
// Reorder elements by z_index
|
||||
std::vector<HudElement*> elems;
|
||||
@ -356,38 +356,34 @@ void Hud::drawLuaElements(const v3s16 &camera_offset)
|
||||
floor(e->pos.Y * (float) m_screensize.Y + 0.5));
|
||||
switch (e->type) {
|
||||
case HUD_ELEM_TEXT: {
|
||||
irr::gui::IGUIFont *textfont = font;
|
||||
unsigned int font_size = g_fontengine->getDefaultFontSize();
|
||||
|
||||
if (e->size.X > 0)
|
||||
font_size *= e->size.X;
|
||||
|
||||
if (font_size != g_fontengine->getDefaultFontSize())
|
||||
textfont = g_fontengine->getFont(font_size);
|
||||
#ifdef __ANDROID__
|
||||
// The text size on Android is not proportional with the actual scaling
|
||||
// FIXME: why do we have such a weird unportable hack??
|
||||
if (font_size > 3 && e->offset.X < -20)
|
||||
font_size -= 3;
|
||||
#endif
|
||||
auto textfont = g_fontengine->getFont(FontSpec(font_size,
|
||||
(e->style & HUD_STYLE_MONO) ? FM_Mono : FM_Unspecified,
|
||||
e->style & HUD_STYLE_BOLD, e->style & HUD_STYLE_ITALIC));
|
||||
|
||||
video::SColor color(255, (e->number >> 16) & 0xFF,
|
||||
(e->number >> 8) & 0xFF,
|
||||
(e->number >> 0) & 0xFF);
|
||||
std::wstring text = unescape_translate(utf8_to_wide(e->text));
|
||||
core::dimension2d<u32> textsize = textfont->getDimension(text.c_str());
|
||||
#ifdef __ANDROID__
|
||||
// The text size on Android is not proportional with the actual scaling
|
||||
irr::gui::IGUIFont *font_scaled = font_size <= 3 ?
|
||||
textfont : g_fontengine->getFont(font_size - 3);
|
||||
if (e->offset.X < -20)
|
||||
textsize = font_scaled->getDimension(text.c_str());
|
||||
#endif
|
||||
|
||||
v2s32 offset((e->align.X - 1.0) * (textsize.Width / 2),
|
||||
(e->align.Y - 1.0) * (textsize.Height / 2));
|
||||
core::rect<s32> size(0, 0, e->scale.X * m_scale_factor,
|
||||
text_height * e->scale.Y * m_scale_factor);
|
||||
v2s32 offs(e->offset.X * m_scale_factor,
|
||||
e->offset.Y * m_scale_factor);
|
||||
#ifdef __ANDROID__
|
||||
if (e->offset.X < -20)
|
||||
font_scaled->draw(text.c_str(), size + pos + offset + offs, color);
|
||||
else
|
||||
#endif
|
||||
|
||||
{
|
||||
textfont->draw(text.c_str(), size + pos + offset + offs, color);
|
||||
}
|
||||
|
@ -50,6 +50,7 @@ const struct EnumString es_HudElementStat[] =
|
||||
{HUD_STAT_SIZE, "size"},
|
||||
{HUD_STAT_Z_INDEX, "z_index"},
|
||||
{HUD_STAT_TEXT2, "text2"},
|
||||
{HUD_STAT_STYLE, "style"},
|
||||
{0, NULL},
|
||||
};
|
||||
|
||||
|
@ -33,6 +33,10 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
#define HUD_CORNER_LOWER 1
|
||||
#define HUD_CORNER_CENTER 2
|
||||
|
||||
#define HUD_STYLE_BOLD 1
|
||||
#define HUD_STYLE_ITALIC 2
|
||||
#define HUD_STYLE_MONO 4
|
||||
|
||||
// Note that these visibility flags do not determine if the hud items are
|
||||
// actually drawn, but rather, whether to draw the item should the rest
|
||||
// of the game state permit it.
|
||||
@ -78,6 +82,7 @@ enum HudElementStat {
|
||||
HUD_STAT_SIZE,
|
||||
HUD_STAT_Z_INDEX,
|
||||
HUD_STAT_TEXT2,
|
||||
HUD_STAT_STYLE,
|
||||
};
|
||||
|
||||
enum HudCompassDir {
|
||||
@ -102,6 +107,7 @@ struct HudElement {
|
||||
v2s32 size;
|
||||
s16 z_index = 0;
|
||||
std::string text2;
|
||||
u32 style;
|
||||
};
|
||||
|
||||
extern const EnumString es_HudElementType[];
|
||||
|
@ -1061,6 +1061,7 @@ void Client::handleCommand_HudAdd(NetworkPacket* pkt)
|
||||
v2s32 size;
|
||||
s16 z_index = 0;
|
||||
std::string text2;
|
||||
u32 style = 0;
|
||||
|
||||
*pkt >> server_id >> type >> pos >> name >> scale >> text >> number >> item
|
||||
>> dir >> align >> offset;
|
||||
@ -1069,6 +1070,7 @@ void Client::handleCommand_HudAdd(NetworkPacket* pkt)
|
||||
*pkt >> size;
|
||||
*pkt >> z_index;
|
||||
*pkt >> text2;
|
||||
*pkt >> style;
|
||||
} catch(PacketError &e) {};
|
||||
|
||||
ClientEvent *event = new ClientEvent();
|
||||
@ -1089,6 +1091,7 @@ void Client::handleCommand_HudAdd(NetworkPacket* pkt)
|
||||
event->hudadd->size = size;
|
||||
event->hudadd->z_index = z_index;
|
||||
event->hudadd->text2 = text2;
|
||||
event->hudadd->style = style;
|
||||
m_client_event_queue.push(event);
|
||||
}
|
||||
|
||||
@ -1123,7 +1126,7 @@ void Client::handleCommand_HudChange(NetworkPacket* pkt)
|
||||
*pkt >> sdata;
|
||||
else if (stat == HUD_STAT_WORLD_POS)
|
||||
*pkt >> v3fdata;
|
||||
else if (stat == HUD_STAT_SIZE )
|
||||
else if (stat == HUD_STAT_SIZE)
|
||||
*pkt >> v2s32data;
|
||||
else
|
||||
*pkt >> intdata;
|
||||
|
@ -1928,6 +1928,8 @@ void read_hud_element(lua_State *L, HudElement *elem)
|
||||
elem->world_pos = lua_istable(L, -1) ? read_v3f(L, -1) : v3f();
|
||||
lua_pop(L, 1);
|
||||
|
||||
elem->style = getintfield_default(L, 2, "style", 0);
|
||||
|
||||
/* check for known deprecated element usage */
|
||||
if ((elem->type == HUD_ELEM_STATBAR) && (elem->size == v2s32()))
|
||||
log_deprecated(L,"Deprecated usage of statbar without size!");
|
||||
@ -1982,6 +1984,9 @@ void push_hud_element(lua_State *L, HudElement *elem)
|
||||
|
||||
lua_pushstring(L, elem->text2.c_str());
|
||||
lua_setfield(L, -2, "text2");
|
||||
|
||||
lua_pushinteger(L, elem->style);
|
||||
lua_setfield(L, -2, "style");
|
||||
}
|
||||
|
||||
HudElementStat read_hud_change(lua_State *L, HudElement *elem, void **value)
|
||||
@ -2050,6 +2055,10 @@ HudElementStat read_hud_change(lua_State *L, HudElement *elem, void **value)
|
||||
elem->text2 = luaL_checkstring(L, 4);
|
||||
*value = &elem->text2;
|
||||
break;
|
||||
case HUD_STAT_STYLE:
|
||||
elem->style = luaL_checknumber(L, 4);
|
||||
*value = &elem->style;
|
||||
break;
|
||||
}
|
||||
return stat;
|
||||
}
|
||||
|
@ -1638,7 +1638,7 @@ void Server::SendHUDAdd(session_t peer_id, u32 id, HudElement *form)
|
||||
pkt << id << (u8) form->type << form->pos << form->name << form->scale
|
||||
<< form->text << form->number << form->item << form->dir
|
||||
<< form->align << form->offset << form->world_pos << form->size
|
||||
<< form->z_index << form->text2;
|
||||
<< form->z_index << form->text2 << form->style;
|
||||
|
||||
Send(&pkt);
|
||||
}
|
||||
@ -1673,10 +1673,7 @@ void Server::SendHUDChange(session_t peer_id, u32 id, HudElementStat stat, void
|
||||
case HUD_STAT_SIZE:
|
||||
pkt << *(v2s32 *) value;
|
||||
break;
|
||||
case HUD_STAT_NUMBER:
|
||||
case HUD_STAT_ITEM:
|
||||
case HUD_STAT_DIR:
|
||||
default:
|
||||
default: // all other types
|
||||
pkt << *(u32 *) value;
|
||||
break;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user