mirror of
https://github.com/minetest/minetest.git
synced 2024-11-30 03:23: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"
|
-- ^ See "HUD Element Types"
|
||||||
size = { x=100, y=100 }, -- default {x=0, y=0}
|
size = { x=100, y=100 }, -- default {x=0, y=0}
|
||||||
-- ^ Size of element in pixels
|
-- ^ 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 = 0,
|
||||||
-- Z index : lower z-index HUDs are displayed behind higher z-index HUDs
|
-- 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
|
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;
|
v2f pos, scale;
|
||||||
std::string name;
|
std::string name;
|
||||||
std::string text, text2;
|
std::string text, text2;
|
||||||
u32 number, item, dir;
|
u32 number, item, dir, style;
|
||||||
v2f align, offset;
|
v2f align, offset;
|
||||||
v3f world_pos;
|
v3f world_pos;
|
||||||
v2s32 size;
|
v2s32 size;
|
||||||
|
@ -2730,6 +2730,7 @@ void Game::handleClientEvent_HudAdd(ClientEvent *event, CameraOrientation *cam)
|
|||||||
e->size = event->hudadd->size;
|
e->size = event->hudadd->size;
|
||||||
e->z_index = event->hudadd->z_index;
|
e->z_index = event->hudadd->z_index;
|
||||||
e->text2 = event->hudadd->text2;
|
e->text2 = event->hudadd->text2;
|
||||||
|
e->style = event->hudadd->style;
|
||||||
m_hud_server_to_client[server_id] = player->addHud(e);
|
m_hud_server_to_client[server_id] = player->addHud(e);
|
||||||
|
|
||||||
delete event->hudadd;
|
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_Z_INDEX, z_index, data);
|
||||||
|
|
||||||
CASE_SET(HUD_STAT_TEXT2, text2, sdata);
|
CASE_SET(HUD_STAT_TEXT2, text2, sdata);
|
||||||
|
|
||||||
|
CASE_SET(HUD_STAT_STYLE, style, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef CASE_SET
|
#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)
|
void Hud::drawLuaElements(const v3s16 &camera_offset)
|
||||||
{
|
{
|
||||||
u32 text_height = g_fontengine->getTextHeight();
|
const u32 text_height = g_fontengine->getTextHeight();
|
||||||
irr::gui::IGUIFont* font = g_fontengine->getFont();
|
gui::IGUIFont *const font = g_fontengine->getFont();
|
||||||
|
|
||||||
// Reorder elements by z_index
|
// Reorder elements by z_index
|
||||||
std::vector<HudElement*> elems;
|
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));
|
floor(e->pos.Y * (float) m_screensize.Y + 0.5));
|
||||||
switch (e->type) {
|
switch (e->type) {
|
||||||
case HUD_ELEM_TEXT: {
|
case HUD_ELEM_TEXT: {
|
||||||
irr::gui::IGUIFont *textfont = font;
|
|
||||||
unsigned int font_size = g_fontengine->getDefaultFontSize();
|
unsigned int font_size = g_fontengine->getDefaultFontSize();
|
||||||
|
|
||||||
if (e->size.X > 0)
|
if (e->size.X > 0)
|
||||||
font_size *= e->size.X;
|
font_size *= e->size.X;
|
||||||
|
|
||||||
if (font_size != g_fontengine->getDefaultFontSize())
|
#ifdef __ANDROID__
|
||||||
textfont = g_fontengine->getFont(font_size);
|
// 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,
|
video::SColor color(255, (e->number >> 16) & 0xFF,
|
||||||
(e->number >> 8) & 0xFF,
|
(e->number >> 8) & 0xFF,
|
||||||
(e->number >> 0) & 0xFF);
|
(e->number >> 0) & 0xFF);
|
||||||
std::wstring text = unescape_translate(utf8_to_wide(e->text));
|
std::wstring text = unescape_translate(utf8_to_wide(e->text));
|
||||||
core::dimension2d<u32> textsize = textfont->getDimension(text.c_str());
|
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),
|
v2s32 offset((e->align.X - 1.0) * (textsize.Width / 2),
|
||||||
(e->align.Y - 1.0) * (textsize.Height / 2));
|
(e->align.Y - 1.0) * (textsize.Height / 2));
|
||||||
core::rect<s32> size(0, 0, e->scale.X * m_scale_factor,
|
core::rect<s32> size(0, 0, e->scale.X * m_scale_factor,
|
||||||
text_height * e->scale.Y * m_scale_factor);
|
text_height * e->scale.Y * m_scale_factor);
|
||||||
v2s32 offs(e->offset.X * m_scale_factor,
|
v2s32 offs(e->offset.X * m_scale_factor,
|
||||||
e->offset.Y * 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);
|
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_SIZE, "size"},
|
||||||
{HUD_STAT_Z_INDEX, "z_index"},
|
{HUD_STAT_Z_INDEX, "z_index"},
|
||||||
{HUD_STAT_TEXT2, "text2"},
|
{HUD_STAT_TEXT2, "text2"},
|
||||||
|
{HUD_STAT_STYLE, "style"},
|
||||||
{0, NULL},
|
{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_LOWER 1
|
||||||
#define HUD_CORNER_CENTER 2
|
#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
|
// 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
|
// actually drawn, but rather, whether to draw the item should the rest
|
||||||
// of the game state permit it.
|
// of the game state permit it.
|
||||||
@ -78,6 +82,7 @@ enum HudElementStat {
|
|||||||
HUD_STAT_SIZE,
|
HUD_STAT_SIZE,
|
||||||
HUD_STAT_Z_INDEX,
|
HUD_STAT_Z_INDEX,
|
||||||
HUD_STAT_TEXT2,
|
HUD_STAT_TEXT2,
|
||||||
|
HUD_STAT_STYLE,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum HudCompassDir {
|
enum HudCompassDir {
|
||||||
@ -102,6 +107,7 @@ struct HudElement {
|
|||||||
v2s32 size;
|
v2s32 size;
|
||||||
s16 z_index = 0;
|
s16 z_index = 0;
|
||||||
std::string text2;
|
std::string text2;
|
||||||
|
u32 style;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern const EnumString es_HudElementType[];
|
extern const EnumString es_HudElementType[];
|
||||||
|
@ -1061,6 +1061,7 @@ void Client::handleCommand_HudAdd(NetworkPacket* pkt)
|
|||||||
v2s32 size;
|
v2s32 size;
|
||||||
s16 z_index = 0;
|
s16 z_index = 0;
|
||||||
std::string text2;
|
std::string text2;
|
||||||
|
u32 style = 0;
|
||||||
|
|
||||||
*pkt >> server_id >> type >> pos >> name >> scale >> text >> number >> item
|
*pkt >> server_id >> type >> pos >> name >> scale >> text >> number >> item
|
||||||
>> dir >> align >> offset;
|
>> dir >> align >> offset;
|
||||||
@ -1069,6 +1070,7 @@ void Client::handleCommand_HudAdd(NetworkPacket* pkt)
|
|||||||
*pkt >> size;
|
*pkt >> size;
|
||||||
*pkt >> z_index;
|
*pkt >> z_index;
|
||||||
*pkt >> text2;
|
*pkt >> text2;
|
||||||
|
*pkt >> style;
|
||||||
} catch(PacketError &e) {};
|
} catch(PacketError &e) {};
|
||||||
|
|
||||||
ClientEvent *event = new ClientEvent();
|
ClientEvent *event = new ClientEvent();
|
||||||
@ -1089,6 +1091,7 @@ void Client::handleCommand_HudAdd(NetworkPacket* pkt)
|
|||||||
event->hudadd->size = size;
|
event->hudadd->size = size;
|
||||||
event->hudadd->z_index = z_index;
|
event->hudadd->z_index = z_index;
|
||||||
event->hudadd->text2 = text2;
|
event->hudadd->text2 = text2;
|
||||||
|
event->hudadd->style = style;
|
||||||
m_client_event_queue.push(event);
|
m_client_event_queue.push(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1123,7 +1126,7 @@ void Client::handleCommand_HudChange(NetworkPacket* pkt)
|
|||||||
*pkt >> sdata;
|
*pkt >> sdata;
|
||||||
else if (stat == HUD_STAT_WORLD_POS)
|
else if (stat == HUD_STAT_WORLD_POS)
|
||||||
*pkt >> v3fdata;
|
*pkt >> v3fdata;
|
||||||
else if (stat == HUD_STAT_SIZE )
|
else if (stat == HUD_STAT_SIZE)
|
||||||
*pkt >> v2s32data;
|
*pkt >> v2s32data;
|
||||||
else
|
else
|
||||||
*pkt >> intdata;
|
*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();
|
elem->world_pos = lua_istable(L, -1) ? read_v3f(L, -1) : v3f();
|
||||||
lua_pop(L, 1);
|
lua_pop(L, 1);
|
||||||
|
|
||||||
|
elem->style = getintfield_default(L, 2, "style", 0);
|
||||||
|
|
||||||
/* check for known deprecated element usage */
|
/* check for known deprecated element usage */
|
||||||
if ((elem->type == HUD_ELEM_STATBAR) && (elem->size == v2s32()))
|
if ((elem->type == HUD_ELEM_STATBAR) && (elem->size == v2s32()))
|
||||||
log_deprecated(L,"Deprecated usage of statbar without size!");
|
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_pushstring(L, elem->text2.c_str());
|
||||||
lua_setfield(L, -2, "text2");
|
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)
|
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);
|
elem->text2 = luaL_checkstring(L, 4);
|
||||||
*value = &elem->text2;
|
*value = &elem->text2;
|
||||||
break;
|
break;
|
||||||
|
case HUD_STAT_STYLE:
|
||||||
|
elem->style = luaL_checknumber(L, 4);
|
||||||
|
*value = &elem->style;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
return stat;
|
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
|
pkt << id << (u8) form->type << form->pos << form->name << form->scale
|
||||||
<< form->text << form->number << form->item << form->dir
|
<< form->text << form->number << form->item << form->dir
|
||||||
<< form->align << form->offset << form->world_pos << form->size
|
<< form->align << form->offset << form->world_pos << form->size
|
||||||
<< form->z_index << form->text2;
|
<< form->z_index << form->text2 << form->style;
|
||||||
|
|
||||||
Send(&pkt);
|
Send(&pkt);
|
||||||
}
|
}
|
||||||
@ -1673,10 +1673,7 @@ void Server::SendHUDChange(session_t peer_id, u32 id, HudElementStat stat, void
|
|||||||
case HUD_STAT_SIZE:
|
case HUD_STAT_SIZE:
|
||||||
pkt << *(v2s32 *) value;
|
pkt << *(v2s32 *) value;
|
||||||
break;
|
break;
|
||||||
case HUD_STAT_NUMBER:
|
default: // all other types
|
||||||
case HUD_STAT_ITEM:
|
|
||||||
case HUD_STAT_DIR:
|
|
||||||
default:
|
|
||||||
pkt << *(u32 *) value;
|
pkt << *(u32 *) value;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user