forked from Mirrorlandia_minetest/minetest
Formspec: add hypertext element
This commit is contained in:
parent
8697090b35
commit
72416a6a1f
@ -851,14 +851,9 @@ tooltip_append_itemname (Append item name) bool false
|
|||||||
# If disabled, bitmap and XML vectors fonts are used instead.
|
# If disabled, bitmap and XML vectors fonts are used instead.
|
||||||
freetype (FreeType fonts) bool true
|
freetype (FreeType fonts) bool true
|
||||||
|
|
||||||
# Path to the default font.
|
font_bold (Font bold by default) bool false
|
||||||
# If “freetype” setting is enabled: Must be a TrueType font.
|
|
||||||
# If “freetype” setting is disabled: Must be a bitmap or XML vectors font.
|
|
||||||
# The fallback font will be used if the font cannot be loaded.
|
|
||||||
font_path (Font path) filepath fonts/liberationsans.ttf
|
|
||||||
|
|
||||||
# Font size of the default font in point (pt).
|
font_italic (Font italic by default) bool false
|
||||||
font_size (Font size) int 16 1
|
|
||||||
|
|
||||||
# Shadow offset (in pixels) of the default font. If 0, then shadow will not be drawn.
|
# Shadow offset (in pixels) of the default font. If 0, then shadow will not be drawn.
|
||||||
font_shadow (Font shadow) int 1
|
font_shadow (Font shadow) int 1
|
||||||
@ -866,20 +861,31 @@ font_shadow (Font shadow) int 1
|
|||||||
# Opaqueness (alpha) of the shadow behind the default font, between 0 and 255.
|
# Opaqueness (alpha) of the shadow behind the default font, between 0 and 255.
|
||||||
font_shadow_alpha (Font shadow alpha) int 127 0 255
|
font_shadow_alpha (Font shadow alpha) int 127 0 255
|
||||||
|
|
||||||
# Path to the monospace font.
|
# Font size of the default font in point (pt).
|
||||||
|
font_size (Font size) int 16 1
|
||||||
|
|
||||||
|
# Path to the default font.
|
||||||
# If “freetype” setting is enabled: Must be a TrueType font.
|
# If “freetype” setting is enabled: Must be a TrueType font.
|
||||||
# If “freetype” setting is disabled: Must be a bitmap or XML vectors font.
|
# If “freetype” setting is disabled: Must be a bitmap or XML vectors font.
|
||||||
# This font is used for e.g. the console and profiler screen.
|
# The fallback font will be used if the font cannot be loaded.
|
||||||
mono_font_path (Monospace font path) filepath fonts/liberationmono.ttf
|
font_path (Regular font path) filepath fonts/Arimo-Regular.ttf
|
||||||
|
|
||||||
|
font_path_bold (Bold font path) filepath fonts/Arimo-Bold.ttf
|
||||||
|
font_path_italic (Italic font path) filepath fonts/Arimo-Italic.ttf
|
||||||
|
font_path_bolditalic (Bold and italic font path) filepath fonts/Arimo-BoldItalic.ttf
|
||||||
|
|
||||||
# Font size of the monospace font in point (pt).
|
# Font size of the monospace font in point (pt).
|
||||||
mono_font_size (Monospace font size) int 15 1
|
mono_font_size (Monospace font size) int 15 1
|
||||||
|
|
||||||
# Path of the fallback font.
|
# Path to the monospace font.
|
||||||
# If “freetype” setting is enabled: Must be a TrueType font.
|
# If “freetype” setting is enabled: Must be a TrueType font.
|
||||||
# If “freetype” setting is disabled: Must be a bitmap or XML vectors font.
|
# If “freetype” setting is disabled: Must be a bitmap or XML vectors font.
|
||||||
# This font will be used for certain languages or if the default font is unavailable.
|
# This font is used for e.g. the console and profiler screen.
|
||||||
fallback_font_path (Fallback font path) filepath fonts/DroidSansFallbackFull.ttf
|
mono_font_path (Monospace font path) filepath fonts/Cousine-Regular.ttf
|
||||||
|
|
||||||
|
mono_font_path_bold (Bold monospace font path) filepath fonts/Cousine-Bold.ttf
|
||||||
|
mono_font_path_italic (Italic monospace font path) filepath fonts/Cousine-Italic.ttf
|
||||||
|
mono_font_path_bolditalic (Bold and italic monospace font path) filepath fonts/Cousine-BoldItalic.ttf
|
||||||
|
|
||||||
# Font size of the fallback font in point (pt).
|
# Font size of the fallback font in point (pt).
|
||||||
fallback_font_size (Fallback font size) int 15 1
|
fallback_font_size (Fallback font size) int 15 1
|
||||||
@ -890,6 +896,12 @@ fallback_font_shadow (Fallback font shadow) int 1
|
|||||||
# Opaqueness (alpha) of the shadow behind the fallback font, between 0 and 255.
|
# Opaqueness (alpha) of the shadow behind the fallback font, between 0 and 255.
|
||||||
fallback_font_shadow_alpha (Fallback font shadow alpha) int 128 0 255
|
fallback_font_shadow_alpha (Fallback font shadow alpha) int 128 0 255
|
||||||
|
|
||||||
|
# Path of the fallback font.
|
||||||
|
# If “freetype” setting is enabled: Must be a TrueType font.
|
||||||
|
# If “freetype” setting is disabled: Must be a bitmap or XML vectors font.
|
||||||
|
# This font will be used for certain languages or if the default font is unavailable.
|
||||||
|
fallback_font_path (Fallback font path) filepath fonts/DroidSansFallbackFull.ttf
|
||||||
|
|
||||||
# Path to save screenshots at.
|
# Path to save screenshots at.
|
||||||
screenshot_path (Screenshot folder) path
|
screenshot_path (Screenshot folder) path
|
||||||
|
|
||||||
|
112
doc/lua_api.txt
112
doc/lua_api.txt
@ -2189,8 +2189,13 @@ Elements
|
|||||||
half a coordinate. With the old system, newlines are spaced 2/5 of
|
half a coordinate. With the old system, newlines are spaced 2/5 of
|
||||||
an inventory slot.
|
an inventory slot.
|
||||||
|
|
||||||
### `vertlabel[<X>,<Y>;<label>]`
|
### `hypertext[<X>,<Y>;<W>,<H>;<name>;<text>]`
|
||||||
|
* Displays a static formated text with hyperlinks.
|
||||||
|
* `x`, `y`, `w` and `h` work as per field
|
||||||
|
* `name` is the name of the field as returned in fields to `on_receive_fields` in case of action in text.
|
||||||
|
* `text` is the formatted text using `markup language` described below.
|
||||||
|
|
||||||
|
### `vertlabel[<X>,<Y>;<label>]`
|
||||||
* Textual label drawn vertically
|
* Textual label drawn vertically
|
||||||
* `label` is the text on the label
|
* `label` is the text on the label
|
||||||
* **Note**: If the new coordinate system is enabled, vertlabels are
|
* **Note**: If the new coordinate system is enabled, vertlabels are
|
||||||
@ -2534,6 +2539,110 @@ Some types may inherit styles from parent types.
|
|||||||
* noclip - boolean, set to true to allow the element to exceed formspec bounds.
|
* noclip - boolean, set to true to allow the element to exceed formspec bounds.
|
||||||
* textcolor - color. Default white.
|
* textcolor - color. Default white.
|
||||||
|
|
||||||
|
Markup language
|
||||||
|
---------------
|
||||||
|
|
||||||
|
Markup language used in `hypertext[]` elements uses tag that look like HTML tags. Some
|
||||||
|
tags can enclose text, they open with `<tagname>` and close with `</tagname>`.
|
||||||
|
Tags can have attributes, in that case, attributes are in the opening tag in
|
||||||
|
form of a key/value separated with equal signs. Attribute values should not be quoted.
|
||||||
|
|
||||||
|
These are the technically basic tags but see below for usual tags. Base tags are:
|
||||||
|
|
||||||
|
`<style color=... font=... size=...>...</style>`
|
||||||
|
|
||||||
|
Changes the style of the text.
|
||||||
|
|
||||||
|
* `color`: Text color. Given color is a `colorspec`.
|
||||||
|
* `size`: Text size.
|
||||||
|
* `font`: Text font (`mono` or `normal`).
|
||||||
|
|
||||||
|
`<global background=... margin=... valign=... color=... hovercolor=... size=... font=... halign=... >`
|
||||||
|
|
||||||
|
Sets global style.
|
||||||
|
|
||||||
|
Global only styles:
|
||||||
|
* `background`: Text background, a `colorspec` or `none`.
|
||||||
|
* `margin`: Page margins in pixel.
|
||||||
|
* `valign`: Text vertical alignment (`top`, `middle`, `bottom`).
|
||||||
|
|
||||||
|
Inheriting styles (affects child elements):
|
||||||
|
* `color`: Default text color. Given color is a `colorspec`.
|
||||||
|
* `hovercolor`: Color of <action> tags when mouse is over.
|
||||||
|
* `size`: Default text size.
|
||||||
|
* `font`: Default text font (`mono` or `normal`).
|
||||||
|
* `halign`: Default text horizontal alignment (`left`, `right`, `center`, `justify`).
|
||||||
|
|
||||||
|
This tag needs to be placed only once as it changes the global settings of the
|
||||||
|
text. Anyway, if several tags are placed, each changed will be made in the order
|
||||||
|
tags appear.
|
||||||
|
|
||||||
|
`<tag name=... color=... hovercolor=... font=... size=...>`
|
||||||
|
|
||||||
|
Defines or redefines tag style. This can be used to define new tags.
|
||||||
|
* `name`: Name of the tag to define or change.
|
||||||
|
* `color`: Text color. Given color is a `colorspec`.
|
||||||
|
* `hovercolor`: Text color when element hovered (only for `action` tags). Given color is a `colorspec`.
|
||||||
|
* `size`: Text size.
|
||||||
|
* `font`: Text font (`mono` or `normal`).
|
||||||
|
|
||||||
|
Following tags are the usual tags for text layout. They are defined by default.
|
||||||
|
Other tags can be added using `<tag ...>` tag.
|
||||||
|
|
||||||
|
`<normal>...</normal>`: Normal size text
|
||||||
|
|
||||||
|
`<big>...</big>`: Big text
|
||||||
|
|
||||||
|
`<bigger>...</bigger>`: Bigger text
|
||||||
|
|
||||||
|
`<center>...</center>`: Centered text
|
||||||
|
|
||||||
|
`<left>...</left>`: Left-aligned text
|
||||||
|
|
||||||
|
`<right>...</right>`: Right-aligned text
|
||||||
|
|
||||||
|
`<justify>...</justify>`: Justified text
|
||||||
|
|
||||||
|
`<mono>...</mono>`: Monospaced font
|
||||||
|
|
||||||
|
`<b>...</b>`, `<i>...</i>`, `<u>...</u>`: Bold, italic, underline styles.
|
||||||
|
|
||||||
|
`<action name=...>...</action>`
|
||||||
|
|
||||||
|
Make that text a clickable text triggering an action.
|
||||||
|
|
||||||
|
* `name`: Name of the action (mandatory).
|
||||||
|
|
||||||
|
When clicked, the formspec is send to the server. The value of the text field
|
||||||
|
sent to `on_player_receive_fields` will be "action:" concatenated to the action
|
||||||
|
name.
|
||||||
|
|
||||||
|
`<img name=... float=... width=... height=...>`
|
||||||
|
|
||||||
|
Draws an image which is present in the client media cache.
|
||||||
|
|
||||||
|
* `name`: Name of the texture (mandatory).
|
||||||
|
* `float`: If present, makes the image floating (`left` or `right`).
|
||||||
|
* `width`: Force image width instead of taking texture width.
|
||||||
|
* `height`: Force image height instead of taking texture height.
|
||||||
|
|
||||||
|
If only width or height given, texture aspect is kept.
|
||||||
|
|
||||||
|
`<item name=... float=... width=... height=... rotate=...>`
|
||||||
|
|
||||||
|
Draws an item image.
|
||||||
|
|
||||||
|
* `name`: Item string of the item to draw (mandatory).
|
||||||
|
* `float`: If present, makes the image floating (`left` or `right`).
|
||||||
|
* `width`: Item image width.
|
||||||
|
* `height`: Item image height.
|
||||||
|
* `rotate`: Rotate item image if set to `yes` or `X,Y,Z`. X, Y and Z being
|
||||||
|
rotation speeds in percent of standard speed (-1000 to 1000). Works only if
|
||||||
|
`inventory_items_animations` is set to true.
|
||||||
|
* `angle`: Angle in which the item image is shown. Value has `X,Y,Z` form.
|
||||||
|
X, Y and Z being angles around each three axes. Works only if
|
||||||
|
`inventory_items_animations` is set to true.
|
||||||
|
|
||||||
Inventory
|
Inventory
|
||||||
=========
|
=========
|
||||||
|
|
||||||
@ -2557,7 +2666,6 @@ Player Inventory lists
|
|||||||
* Is not created automatically, use `InvRef:set_size`
|
* Is not created automatically, use `InvRef:set_size`
|
||||||
* Is only used to enhance the empty hand's tool capabilities
|
* Is only used to enhance the empty hand's tool capabilities
|
||||||
|
|
||||||
|
|
||||||
Colors
|
Colors
|
||||||
======
|
======
|
||||||
|
|
||||||
|
BIN
fonts/Arimo-Bold.ttf
Normal file
BIN
fonts/Arimo-Bold.ttf
Normal file
Binary file not shown.
BIN
fonts/Arimo-BoldItalic.ttf
Normal file
BIN
fonts/Arimo-BoldItalic.ttf
Normal file
Binary file not shown.
BIN
fonts/Arimo-Italic.ttf
Normal file
BIN
fonts/Arimo-Italic.ttf
Normal file
Binary file not shown.
BIN
fonts/Cousine-Bold.ttf
Normal file
BIN
fonts/Cousine-Bold.ttf
Normal file
Binary file not shown.
BIN
fonts/Cousine-BoldItalic.ttf
Normal file
BIN
fonts/Cousine-BoldItalic.ttf
Normal file
Binary file not shown.
BIN
fonts/Cousine-Italic.ttf
Normal file
BIN
fonts/Cousine-Italic.ttf
Normal file
Binary file not shown.
@ -41,6 +41,11 @@ static void font_setting_changed(const std::string &name, void *userdata)
|
|||||||
g_fontengine->readSettings();
|
g_fontengine->readSettings();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned int get_font_cache_index(FontMode mode, bool bold = false, bool italic = false)
|
||||||
|
{
|
||||||
|
return (mode << 2) | (bold << 1) | italic;
|
||||||
|
}
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
FontEngine::FontEngine(Settings* main_settings, gui::IGUIEnvironment* env) :
|
FontEngine::FontEngine(Settings* main_settings, gui::IGUIEnvironment* env) :
|
||||||
m_settings(main_settings),
|
m_settings(main_settings),
|
||||||
@ -59,7 +64,12 @@ FontEngine::FontEngine(Settings* main_settings, gui::IGUIEnvironment* env) :
|
|||||||
|
|
||||||
if (m_currentMode == FM_Standard) {
|
if (m_currentMode == FM_Standard) {
|
||||||
m_settings->registerChangedCallback("font_size", font_setting_changed, NULL);
|
m_settings->registerChangedCallback("font_size", font_setting_changed, NULL);
|
||||||
|
m_settings->registerChangedCallback("font_bold", font_setting_changed, NULL);
|
||||||
|
m_settings->registerChangedCallback("font_italic", font_setting_changed, NULL);
|
||||||
m_settings->registerChangedCallback("font_path", font_setting_changed, NULL);
|
m_settings->registerChangedCallback("font_path", font_setting_changed, NULL);
|
||||||
|
m_settings->registerChangedCallback("font_path_bold", font_setting_changed, NULL);
|
||||||
|
m_settings->registerChangedCallback("font_path_italic", font_setting_changed, NULL);
|
||||||
|
m_settings->registerChangedCallback("font_path_bolditalic", font_setting_changed, NULL);
|
||||||
m_settings->registerChangedCallback("font_shadow", font_setting_changed, NULL);
|
m_settings->registerChangedCallback("font_shadow", font_setting_changed, NULL);
|
||||||
m_settings->registerChangedCallback("font_shadow_alpha", font_setting_changed, NULL);
|
m_settings->registerChangedCallback("font_shadow_alpha", font_setting_changed, NULL);
|
||||||
}
|
}
|
||||||
@ -96,7 +106,8 @@ void FontEngine::cleanCache()
|
|||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
irr::gui::IGUIFont* FontEngine::getFont(unsigned int font_size, FontMode mode)
|
irr::gui::IGUIFont *FontEngine::getFont(unsigned int font_size, FontMode mode,
|
||||||
|
bool bold, bool italic)
|
||||||
{
|
{
|
||||||
if (mode == FM_Unspecified) {
|
if (mode == FM_Unspecified) {
|
||||||
mode = m_currentMode;
|
mode = m_currentMode;
|
||||||
@ -110,22 +121,30 @@ irr::gui::IGUIFont* FontEngine::getFont(unsigned int font_size, FontMode mode)
|
|||||||
if (font_size == FONT_SIZE_UNSPECIFIED)
|
if (font_size == FONT_SIZE_UNSPECIFIED)
|
||||||
font_size = m_default_size[mode];
|
font_size = m_default_size[mode];
|
||||||
|
|
||||||
const auto &cache = m_font_cache[mode];
|
unsigned int cache_index = get_font_cache_index(mode, bold, italic);
|
||||||
|
|
||||||
|
const auto &cache = m_font_cache[cache_index];
|
||||||
|
|
||||||
if (cache.find(font_size) == cache.end()) {
|
if (cache.find(font_size) == cache.end()) {
|
||||||
if (mode == FM_Simple || mode == FM_SimpleMono)
|
if (mode == FM_Simple || mode == FM_SimpleMono)
|
||||||
initSimpleFont(font_size, mode);
|
initSimpleFont(font_size, mode);
|
||||||
else
|
else
|
||||||
initFont(font_size, mode);
|
initFont(font_size, mode, bold, italic);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (m_font_cache[cache_index].find(font_size) ==
|
||||||
|
m_font_cache[cache_index].end())
|
||||||
|
initFont(font_size, mode, bold, italic);
|
||||||
|
|
||||||
const auto &font = cache.find(font_size);
|
const auto &font = cache.find(font_size);
|
||||||
return font != cache.end() ? font->second : nullptr;
|
return font != cache.end() ? font->second : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
unsigned int FontEngine::getTextHeight(unsigned int font_size, FontMode mode)
|
unsigned int FontEngine::getTextHeight(unsigned int font_size, FontMode mode,
|
||||||
|
bool bold, bool italic)
|
||||||
{
|
{
|
||||||
irr::gui::IGUIFont* font = getFont(font_size, mode);
|
irr::gui::IGUIFont *font = getFont(font_size, mode, bold, italic);
|
||||||
|
|
||||||
// use current skin font as fallback
|
// use current skin font as fallback
|
||||||
if (font == NULL) {
|
if (font == NULL) {
|
||||||
@ -138,9 +157,9 @@ unsigned int FontEngine::getTextHeight(unsigned int font_size, FontMode mode)
|
|||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
unsigned int FontEngine::getTextWidth(const std::wstring& text,
|
unsigned int FontEngine::getTextWidth(const std::wstring& text,
|
||||||
unsigned int font_size, FontMode mode)
|
unsigned int font_size, FontMode mode, bool bold, bool italic)
|
||||||
{
|
{
|
||||||
irr::gui::IGUIFont* font = getFont(font_size, mode);
|
irr::gui::IGUIFont *font = getFont(font_size, mode, bold, italic);
|
||||||
|
|
||||||
// use current skin font as fallback
|
// use current skin font as fallback
|
||||||
if (font == NULL) {
|
if (font == NULL) {
|
||||||
@ -153,9 +172,10 @@ unsigned int FontEngine::getTextWidth(const std::wstring& text,
|
|||||||
|
|
||||||
|
|
||||||
/** get line height for a specific font (including empty room between lines) */
|
/** get line height for a specific font (including empty room between lines) */
|
||||||
unsigned int FontEngine::getLineHeight(unsigned int font_size, FontMode mode)
|
unsigned int FontEngine::getLineHeight(unsigned int font_size, FontMode mode,
|
||||||
|
bool bold, bool italic)
|
||||||
{
|
{
|
||||||
irr::gui::IGUIFont* font = getFont(font_size, mode);
|
irr::gui::IGUIFont *font = getFont(font_size, mode, bold, italic);
|
||||||
|
|
||||||
// use current skin font as fallback
|
// use current skin font as fallback
|
||||||
if (font == NULL) {
|
if (font == NULL) {
|
||||||
@ -183,6 +203,10 @@ void FontEngine::readSettings()
|
|||||||
|
|
||||||
m_currentMode = is_yes(gettext("needs_fallback_font")) ?
|
m_currentMode = is_yes(gettext("needs_fallback_font")) ?
|
||||||
FM_Fallback : FM_Standard;
|
FM_Fallback : FM_Standard;
|
||||||
|
|
||||||
|
m_default_bold = m_settings->getBool("font_bold");
|
||||||
|
m_default_italic = m_settings->getBool("font_italic");
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
m_currentMode = FM_Simple;
|
m_currentMode = FM_Simple;
|
||||||
}
|
}
|
||||||
@ -226,14 +250,17 @@ void FontEngine::updateFontCache()
|
|||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
void FontEngine::initFont(unsigned int basesize, FontMode mode)
|
void FontEngine::initFont(unsigned int basesize, FontMode mode,
|
||||||
|
bool bold, bool italic)
|
||||||
{
|
{
|
||||||
assert(mode != FM_Unspecified);
|
assert(mode != FM_Unspecified);
|
||||||
assert(basesize != FONT_SIZE_UNSPECIFIED);
|
assert(basesize != FONT_SIZE_UNSPECIFIED);
|
||||||
|
|
||||||
if (m_font_cache[mode].find(basesize) != m_font_cache[mode].end())
|
int cache_index = get_font_cache_index(mode, bold, italic);
|
||||||
return;
|
|
||||||
|
|
||||||
|
if (m_font_cache[cache_index].find(basesize) !=
|
||||||
|
m_font_cache[cache_index].end())
|
||||||
|
return;
|
||||||
|
|
||||||
std::string setting_prefix = "";
|
std::string setting_prefix = "";
|
||||||
|
|
||||||
@ -249,8 +276,13 @@ void FontEngine::initFont(unsigned int basesize, FontMode mode)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string setting_suffix = (bold) ?
|
||||||
|
((italic) ? "_bold_italic" : "_bold") :
|
||||||
|
((italic) ? "_italic" : "");
|
||||||
|
|
||||||
u32 size = std::floor(RenderingEngine::getDisplayDensity() *
|
u32 size = std::floor(RenderingEngine::getDisplayDensity() *
|
||||||
m_settings->getFloat("gui_scaling") * basesize);
|
m_settings->getFloat("gui_scaling") * basesize);
|
||||||
|
|
||||||
if (size == 0) {
|
if (size == 0) {
|
||||||
errorstream << "FontEngine: attempt to use font size 0" << std::endl;
|
errorstream << "FontEngine: attempt to use font size 0" << std::endl;
|
||||||
errorstream << " display density: " << RenderingEngine::getDisplayDensity() << std::endl;
|
errorstream << " display density: " << RenderingEngine::getDisplayDensity() << std::endl;
|
||||||
@ -260,10 +292,14 @@ void FontEngine::initFont(unsigned int basesize, FontMode mode)
|
|||||||
u16 font_shadow = 0;
|
u16 font_shadow = 0;
|
||||||
u16 font_shadow_alpha = 0;
|
u16 font_shadow_alpha = 0;
|
||||||
g_settings->getU16NoEx(setting_prefix + "font_shadow", font_shadow);
|
g_settings->getU16NoEx(setting_prefix + "font_shadow", font_shadow);
|
||||||
g_settings->getU16NoEx(setting_prefix + "font_shadow_alpha", font_shadow_alpha);
|
g_settings->getU16NoEx(setting_prefix + "font_shadow_alpha",
|
||||||
|
font_shadow_alpha);
|
||||||
|
|
||||||
|
std::string wanted_font_path;
|
||||||
|
wanted_font_path = g_settings->get(setting_prefix + "font_path" + setting_suffix);
|
||||||
|
|
||||||
std::string fallback_settings[] = {
|
std::string fallback_settings[] = {
|
||||||
m_settings->get(setting_prefix + "font_path"),
|
wanted_font_path,
|
||||||
m_settings->get("fallback_font_path"),
|
m_settings->get("fallback_font_path"),
|
||||||
m_settings->getDefault(setting_prefix + "font_path")
|
m_settings->getDefault(setting_prefix + "font_path")
|
||||||
};
|
};
|
||||||
@ -275,7 +311,7 @@ void FontEngine::initFont(unsigned int basesize, FontMode mode)
|
|||||||
font_shadow_alpha);
|
font_shadow_alpha);
|
||||||
|
|
||||||
if (font) {
|
if (font) {
|
||||||
m_font_cache[mode][basesize] = font;
|
m_font_cache[cache_index][basesize] = font;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -365,5 +401,5 @@ void FontEngine::initSimpleFont(unsigned int basesize, FontMode mode)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (font)
|
if (font)
|
||||||
m_font_cache[mode][basesize] = font;
|
m_font_cache[get_font_cache_index(mode)][basesize] = font;
|
||||||
}
|
}
|
||||||
|
@ -48,29 +48,62 @@ public:
|
|||||||
~FontEngine();
|
~FontEngine();
|
||||||
|
|
||||||
/** get Font */
|
/** get Font */
|
||||||
|
irr::gui::IGUIFont *getFont(unsigned int font_size, FontMode mode,
|
||||||
|
bool bold, bool italic);
|
||||||
|
|
||||||
irr::gui::IGUIFont *getFont(unsigned int font_size=FONT_SIZE_UNSPECIFIED,
|
irr::gui::IGUIFont *getFont(unsigned int font_size=FONT_SIZE_UNSPECIFIED,
|
||||||
FontMode mode=FM_Unspecified);
|
FontMode mode=FM_Unspecified)
|
||||||
|
{
|
||||||
|
return getFont(font_size, mode, m_default_bold, m_default_italic);
|
||||||
|
}
|
||||||
|
|
||||||
/** get text height for a specific font */
|
/** get text height for a specific font */
|
||||||
unsigned int getTextHeight(unsigned int font_size=FONT_SIZE_UNSPECIFIED,
|
unsigned int getTextHeight(unsigned int font_size, FontMode mode,
|
||||||
FontMode mode=FM_Unspecified);
|
bool bold, bool italic);
|
||||||
|
|
||||||
/** get text width if a text for a specific font */
|
/** get text width if a text for a specific font */
|
||||||
unsigned int getTextWidth(const std::string& text,
|
unsigned int getTextHeight(
|
||||||
unsigned int font_size=FONT_SIZE_UNSPECIFIED,
|
unsigned int font_size=FONT_SIZE_UNSPECIFIED,
|
||||||
FontMode mode=FM_Unspecified)
|
FontMode mode=FM_Unspecified)
|
||||||
{
|
{
|
||||||
return getTextWidth(utf8_to_wide(text));
|
return getTextHeight(font_size, mode, m_default_bold, m_default_italic);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned int getTextWidth(const std::wstring& text,
|
||||||
|
unsigned int font_size, FontMode mode, bool bold, bool italic);
|
||||||
|
|
||||||
/** get text width if a text for a specific font */
|
/** get text width if a text for a specific font */
|
||||||
unsigned int getTextWidth(const std::wstring& text,
|
unsigned int getTextWidth(const std::wstring& text,
|
||||||
unsigned int font_size=FONT_SIZE_UNSPECIFIED,
|
unsigned int font_size=FONT_SIZE_UNSPECIFIED,
|
||||||
FontMode mode=FM_Unspecified);
|
FontMode mode=FM_Unspecified)
|
||||||
|
{
|
||||||
|
return getTextWidth(text, font_size, mode, m_default_bold,
|
||||||
|
m_default_italic);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int getTextWidth(const std::string& text,
|
||||||
|
unsigned int font_size, FontMode mode, bool bold, bool italic)
|
||||||
|
{
|
||||||
|
return getTextWidth(utf8_to_wide(text), font_size, mode, bold, italic);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int getTextWidth(const std::string& text,
|
||||||
|
unsigned int font_size=FONT_SIZE_UNSPECIFIED,
|
||||||
|
FontMode mode=FM_Unspecified)
|
||||||
|
{
|
||||||
|
return getTextWidth(utf8_to_wide(text), font_size, mode, m_default_bold,
|
||||||
|
m_default_italic);
|
||||||
|
}
|
||||||
|
|
||||||
/** get line height for a specific font (including empty room between lines) */
|
/** get line height for a specific font (including empty room between lines) */
|
||||||
|
unsigned int getLineHeight(unsigned int font_size, FontMode mode, bool bold,
|
||||||
|
bool italic);
|
||||||
|
|
||||||
unsigned int getLineHeight(unsigned int font_size=FONT_SIZE_UNSPECIFIED,
|
unsigned int getLineHeight(unsigned int font_size=FONT_SIZE_UNSPECIFIED,
|
||||||
FontMode mode=FM_Unspecified);
|
FontMode mode=FM_Unspecified)
|
||||||
|
{
|
||||||
|
return getLineHeight(font_size, mode, m_default_bold, m_default_italic);
|
||||||
|
}
|
||||||
|
|
||||||
/** get default font size */
|
/** get default font size */
|
||||||
unsigned int getDefaultFontSize();
|
unsigned int getDefaultFontSize();
|
||||||
@ -86,7 +119,11 @@ private:
|
|||||||
void updateFontCache();
|
void updateFontCache();
|
||||||
|
|
||||||
/** initialize a new font */
|
/** initialize a new font */
|
||||||
void initFont(unsigned int basesize, FontMode mode=FM_Unspecified);
|
void initFont(
|
||||||
|
unsigned int basesize,
|
||||||
|
FontMode mode,
|
||||||
|
bool bold,
|
||||||
|
bool italic);
|
||||||
|
|
||||||
/** initialize a font without freetype */
|
/** initialize a font without freetype */
|
||||||
void initSimpleFont(unsigned int basesize, FontMode mode);
|
void initSimpleFont(unsigned int basesize, FontMode mode);
|
||||||
@ -104,11 +141,15 @@ private:
|
|||||||
gui::IGUIEnvironment* m_env = nullptr;
|
gui::IGUIEnvironment* m_env = nullptr;
|
||||||
|
|
||||||
/** internal storage for caching fonts of different size */
|
/** internal storage for caching fonts of different size */
|
||||||
std::map<unsigned int, irr::gui::IGUIFont*> m_font_cache[FM_MaxMode];
|
std::map<unsigned int, irr::gui::IGUIFont*> m_font_cache[FM_MaxMode << 2];
|
||||||
|
|
||||||
/** default font size to use */
|
/** default font size to use */
|
||||||
unsigned int m_default_size[FM_MaxMode];
|
unsigned int m_default_size[FM_MaxMode];
|
||||||
|
|
||||||
|
/** default bold and italic */
|
||||||
|
bool m_default_bold;
|
||||||
|
bool m_default_italic;
|
||||||
|
|
||||||
/** current font engine mode */
|
/** current font engine mode */
|
||||||
FontMode m_currentMode = FM_Standard;
|
FontMode m_currentMode = FM_Standard;
|
||||||
|
|
||||||
|
@ -608,23 +608,24 @@ void Hud::resizeHotbar() {
|
|||||||
|
|
||||||
struct MeshTimeInfo {
|
struct MeshTimeInfo {
|
||||||
u64 time;
|
u64 time;
|
||||||
scene::IMesh *mesh;
|
scene::IMesh *mesh = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
void drawItemStack(video::IVideoDriver *driver,
|
void drawItemStack(
|
||||||
|
video::IVideoDriver *driver,
|
||||||
gui::IGUIFont *font,
|
gui::IGUIFont *font,
|
||||||
const ItemStack &item,
|
const ItemStack &item,
|
||||||
const core::rect<s32> &rect,
|
const core::rect<s32> &rect,
|
||||||
const core::rect<s32> *clip,
|
const core::rect<s32> *clip,
|
||||||
Client *client,
|
Client *client,
|
||||||
ItemRotationKind rotation_kind)
|
ItemRotationKind rotation_kind,
|
||||||
|
const v3s16 &angle,
|
||||||
|
const v3s16 &rotation_speed)
|
||||||
{
|
{
|
||||||
static MeshTimeInfo rotation_time_infos[IT_ROT_NONE];
|
static MeshTimeInfo rotation_time_infos[IT_ROT_NONE];
|
||||||
static thread_local bool enable_animations =
|
|
||||||
g_settings->getBool("inventory_items_animations");
|
|
||||||
|
|
||||||
if (item.empty()) {
|
if (item.empty()) {
|
||||||
if (rotation_kind < IT_ROT_NONE) {
|
if (rotation_kind < IT_ROT_NONE && rotation_kind != IT_ROT_OTHER) {
|
||||||
rotation_time_infos[rotation_kind].mesh = NULL;
|
rotation_time_infos[rotation_kind].mesh = NULL;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
@ -639,7 +640,7 @@ void drawItemStack(video::IVideoDriver *driver,
|
|||||||
s32 delta = 0;
|
s32 delta = 0;
|
||||||
if (rotation_kind < IT_ROT_NONE) {
|
if (rotation_kind < IT_ROT_NONE) {
|
||||||
MeshTimeInfo &ti = rotation_time_infos[rotation_kind];
|
MeshTimeInfo &ti = rotation_time_infos[rotation_kind];
|
||||||
if (mesh != ti.mesh) {
|
if (mesh != ti.mesh && rotation_kind != IT_ROT_OTHER) {
|
||||||
ti.mesh = mesh;
|
ti.mesh = mesh;
|
||||||
ti.time = porting::getTimeMs();
|
ti.time = porting::getTimeMs();
|
||||||
} else {
|
} else {
|
||||||
@ -677,9 +678,16 @@ void drawItemStack(video::IVideoDriver *driver,
|
|||||||
core::matrix4 matrix;
|
core::matrix4 matrix;
|
||||||
matrix.makeIdentity();
|
matrix.makeIdentity();
|
||||||
|
|
||||||
|
static thread_local bool enable_animations =
|
||||||
|
g_settings->getBool("inventory_items_animations");
|
||||||
|
|
||||||
if (enable_animations) {
|
if (enable_animations) {
|
||||||
float timer_f = (float) delta / 5000.0;
|
float timer_f = (float) delta / 5000.f;
|
||||||
matrix.setRotationDegrees(core::vector3df(0, 360 * timer_f, 0));
|
matrix.setRotationDegrees(v3f(
|
||||||
|
angle.X + rotation_speed.X * 3.60f * timer_f,
|
||||||
|
angle.Y + rotation_speed.Y * 3.60f * timer_f,
|
||||||
|
angle.Z + rotation_speed.Z * 3.60f * timer_f)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
driver->setTransform(video::ETS_WORLD, matrix);
|
driver->setTransform(video::ETS_WORLD, matrix);
|
||||||
@ -695,15 +703,18 @@ void drawItemStack(video::IVideoDriver *driver,
|
|||||||
// because these meshes are not buffered.
|
// because these meshes are not buffered.
|
||||||
assert(buf->getHardwareMappingHint_Vertex() == scene::EHM_NEVER);
|
assert(buf->getHardwareMappingHint_Vertex() == scene::EHM_NEVER);
|
||||||
video::SColor c = basecolor;
|
video::SColor c = basecolor;
|
||||||
|
|
||||||
if (imesh->buffer_colors.size() > j) {
|
if (imesh->buffer_colors.size() > j) {
|
||||||
ItemPartColor *p = &imesh->buffer_colors[j];
|
ItemPartColor *p = &imesh->buffer_colors[j];
|
||||||
if (p->override_base)
|
if (p->override_base)
|
||||||
c = p->color;
|
c = p->color;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (imesh->needs_shading)
|
if (imesh->needs_shading)
|
||||||
colorizeMeshBuffer(buf, &c);
|
colorizeMeshBuffer(buf, &c);
|
||||||
else
|
else
|
||||||
setMeshBufferColor(buf, c);
|
setMeshBufferColor(buf, c);
|
||||||
|
|
||||||
video::SMaterial &material = buf->getMaterial();
|
video::SMaterial &material = buf->getMaterial();
|
||||||
material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
|
material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
|
||||||
material.Lighting = false;
|
material.Lighting = false;
|
||||||
@ -726,12 +737,12 @@ void drawItemStack(video::IVideoDriver *driver,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(def.type == ITEM_TOOL && item.wear != 0)
|
if (def.type == ITEM_TOOL && item.wear != 0) {
|
||||||
{
|
|
||||||
// Draw a progressbar
|
// Draw a progressbar
|
||||||
float barheight = rect.getHeight() / 16;
|
float barheight = rect.getHeight() / 16;
|
||||||
float barpad_x = rect.getWidth() / 16;
|
float barpad_x = rect.getWidth() / 16;
|
||||||
float barpad_y = rect.getHeight() / 16;
|
float barpad_y = rect.getHeight() / 16;
|
||||||
|
|
||||||
core::rect<s32> progressrect(
|
core::rect<s32> progressrect(
|
||||||
rect.UpperLeftCorner.X + barpad_x,
|
rect.UpperLeftCorner.X + barpad_x,
|
||||||
rect.LowerRightCorner.Y - barpad_y - barheight,
|
rect.LowerRightCorner.Y - barpad_y - barheight,
|
||||||
@ -739,7 +750,7 @@ void drawItemStack(video::IVideoDriver *driver,
|
|||||||
rect.LowerRightCorner.Y - barpad_y);
|
rect.LowerRightCorner.Y - barpad_y);
|
||||||
|
|
||||||
// Shrink progressrect by amount of tool damage
|
// Shrink progressrect by amount of tool damage
|
||||||
float wear = item.wear / 65535.0;
|
float wear = item.wear / 65535.0f;
|
||||||
int progressmid =
|
int progressmid =
|
||||||
wear * progressrect.UpperLeftCorner.X +
|
wear * progressrect.UpperLeftCorner.X +
|
||||||
(1 - wear) * progressrect.LowerRightCorner.X;
|
(1 - wear) * progressrect.LowerRightCorner.X;
|
||||||
@ -751,6 +762,7 @@ void drawItemStack(video::IVideoDriver *driver,
|
|||||||
video::SColor color(255, 255, 255, 255);
|
video::SColor color(255, 255, 255, 255);
|
||||||
int wear_i = MYMIN(std::floor(wear * 600), 511);
|
int wear_i = MYMIN(std::floor(wear * 600), 511);
|
||||||
wear_i = MYMIN(wear_i + 10, 511);
|
wear_i = MYMIN(wear_i + 10, 511);
|
||||||
|
|
||||||
if (wear_i <= 255)
|
if (wear_i <= 255)
|
||||||
color.set(255, wear_i, 255, 0);
|
color.set(255, wear_i, 255, 0);
|
||||||
else
|
else
|
||||||
@ -766,8 +778,7 @@ void drawItemStack(video::IVideoDriver *driver,
|
|||||||
driver->draw2DRectangle(color, progressrect2, clip);
|
driver->draw2DRectangle(color, progressrect2, clip);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(font != NULL && item.count >= 2)
|
if (font != NULL && item.count >= 2) {
|
||||||
{
|
|
||||||
// Get the item count as a string
|
// Get the item count as a string
|
||||||
std::string text = itos(item.count);
|
std::string text = itos(item.count);
|
||||||
v2u32 dim = font->getDimension(utf8_to_wide(text).c_str());
|
v2u32 dim = font->getDimension(utf8_to_wide(text).c_str());
|
||||||
@ -787,3 +798,16 @@ void drawItemStack(video::IVideoDriver *driver,
|
|||||||
font->draw(text.c_str(), rect2, color, false, false, clip);
|
font->draw(text.c_str(), rect2, color, false, false, clip);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void drawItemStack(
|
||||||
|
video::IVideoDriver *driver,
|
||||||
|
gui::IGUIFont *font,
|
||||||
|
const ItemStack &item,
|
||||||
|
const core::rect<s32> &rect,
|
||||||
|
const core::rect<s32> *clip,
|
||||||
|
Client *client,
|
||||||
|
ItemRotationKind rotation_kind)
|
||||||
|
{
|
||||||
|
drawItemStack(driver, font, item, rect, clip, client, rotation_kind,
|
||||||
|
v3s16(0, 0, 0), v3s16(0, 100, 0));
|
||||||
|
}
|
||||||
|
@ -122,6 +122,7 @@ enum ItemRotationKind
|
|||||||
IT_ROT_SELECTED,
|
IT_ROT_SELECTED,
|
||||||
IT_ROT_HOVERED,
|
IT_ROT_HOVERED,
|
||||||
IT_ROT_DRAGGED,
|
IT_ROT_DRAGGED,
|
||||||
|
IT_ROT_OTHER,
|
||||||
IT_ROT_NONE, // Must be last, also serves as number
|
IT_ROT_NONE, // Must be last, also serves as number
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -133,4 +134,15 @@ void drawItemStack(video::IVideoDriver *driver,
|
|||||||
Client *client,
|
Client *client,
|
||||||
ItemRotationKind rotation_kind);
|
ItemRotationKind rotation_kind);
|
||||||
|
|
||||||
|
void drawItemStack(
|
||||||
|
video::IVideoDriver *driver,
|
||||||
|
gui::IGUIFont *font,
|
||||||
|
const ItemStack &item,
|
||||||
|
const core::rect<s32> &rect,
|
||||||
|
const core::rect<s32> *clip,
|
||||||
|
Client *client,
|
||||||
|
ItemRotationKind rotation_kind,
|
||||||
|
const v3s16 &angle,
|
||||||
|
const v3s16 &rotation_speed);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -292,9 +292,17 @@ void set_default_settings(Settings *settings)
|
|||||||
#if USE_FREETYPE
|
#if USE_FREETYPE
|
||||||
settings->setDefault("freetype", "true");
|
settings->setDefault("freetype", "true");
|
||||||
settings->setDefault("font_path", porting::getDataPath("fonts" DIR_DELIM "Arimo-Regular.ttf"));
|
settings->setDefault("font_path", porting::getDataPath("fonts" DIR_DELIM "Arimo-Regular.ttf"));
|
||||||
|
settings->setDefault("font_path_italic", porting::getDataPath("fonts" DIR_DELIM "Arimo-Italic.ttf"));
|
||||||
|
settings->setDefault("font_path_bold", porting::getDataPath("fonts" DIR_DELIM "Arimo-Bold.ttf"));
|
||||||
|
settings->setDefault("font_path_bold_italic", porting::getDataPath("fonts" DIR_DELIM "Arimo-BoldItalic.ttf"));
|
||||||
|
settings->setDefault("font_bold", "false");
|
||||||
|
settings->setDefault("font_italic", "false");
|
||||||
settings->setDefault("font_shadow", "1");
|
settings->setDefault("font_shadow", "1");
|
||||||
settings->setDefault("font_shadow_alpha", "127");
|
settings->setDefault("font_shadow_alpha", "127");
|
||||||
settings->setDefault("mono_font_path", porting::getDataPath("fonts" DIR_DELIM "Cousine-Regular.ttf"));
|
settings->setDefault("mono_font_path", porting::getDataPath("fonts" DIR_DELIM "Cousine-Regular.ttf"));
|
||||||
|
settings->setDefault("mono_font_path_italic", porting::getDataPath("fonts" DIR_DELIM "Cousine-Italic.ttf"));
|
||||||
|
settings->setDefault("mono_font_path_bold", porting::getDataPath("fonts" DIR_DELIM "Cousine-Bold.ttf"));
|
||||||
|
settings->setDefault("mono_font_path_bold_italic", porting::getDataPath("fonts" DIR_DELIM "Cousine-BoldItalic.ttf"));
|
||||||
settings->setDefault("fallback_font_path", porting::getDataPath("fonts" DIR_DELIM "DroidSansFallbackFull.ttf"));
|
settings->setDefault("fallback_font_path", porting::getDataPath("fonts" DIR_DELIM "DroidSansFallbackFull.ttf"));
|
||||||
|
|
||||||
settings->setDefault("fallback_font_shadow", "1");
|
settings->setDefault("fallback_font_shadow", "1");
|
||||||
|
@ -11,6 +11,7 @@ set(gui_SRCS
|
|||||||
${CMAKE_CURRENT_SOURCE_DIR}/guiScrollBar.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/guiScrollBar.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/guiSkin.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/guiSkin.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/guiTable.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/guiTable.cpp
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/guiHyperText.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/guiVolumeChange.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/guiVolumeChange.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/intlGUIEditBox.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/intlGUIEditBox.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/modalMenu.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/modalMenu.cpp
|
||||||
|
@ -57,6 +57,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
#include "client/guiscalingfilter.h"
|
#include "client/guiscalingfilter.h"
|
||||||
#include "guiEditBoxWithScrollbar.h"
|
#include "guiEditBoxWithScrollbar.h"
|
||||||
#include "intlGUIEditBox.h"
|
#include "intlGUIEditBox.h"
|
||||||
|
#include "guiHyperText.h"
|
||||||
|
|
||||||
#define MY_CHECKPOS(a,b) \
|
#define MY_CHECKPOS(a,b) \
|
||||||
if (v_pos.size() != 2) { \
|
if (v_pos.size() != 2) { \
|
||||||
@ -162,9 +163,8 @@ void GUIFormSpecMenu::removeChildren()
|
|||||||
if (m_tooltip_element) {
|
if (m_tooltip_element) {
|
||||||
m_tooltip_element->remove();
|
m_tooltip_element->remove();
|
||||||
m_tooltip_element->drop();
|
m_tooltip_element->drop();
|
||||||
m_tooltip_element = NULL;
|
m_tooltip_element = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GUIFormSpecMenu::setInitialFocus()
|
void GUIFormSpecMenu::setInitialFocus()
|
||||||
@ -1318,7 +1318,6 @@ void GUIFormSpecMenu::parseSimpleField(parserData* data,
|
|||||||
void GUIFormSpecMenu::parseTextArea(parserData* data, std::vector<std::string>& parts,
|
void GUIFormSpecMenu::parseTextArea(parserData* data, std::vector<std::string>& parts,
|
||||||
const std::string &type)
|
const std::string &type)
|
||||||
{
|
{
|
||||||
|
|
||||||
std::vector<std::string> v_pos = split(parts[0],',');
|
std::vector<std::string> v_pos = split(parts[0],',');
|
||||||
std::vector<std::string> v_geom = split(parts[1],',');
|
std::vector<std::string> v_geom = split(parts[1],',');
|
||||||
std::string name = parts[2];
|
std::string name = parts[2];
|
||||||
@ -1402,6 +1401,59 @@ void GUIFormSpecMenu::parseField(parserData* data, const std::string &element,
|
|||||||
errorstream<< "Invalid field element(" << parts.size() << "): '" << element << "'" << std::endl;
|
errorstream<< "Invalid field element(" << parts.size() << "): '" << element << "'" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GUIFormSpecMenu::parseHyperText(parserData *data, const std::string &element)
|
||||||
|
{
|
||||||
|
std::vector<std::string> parts = split(element, ';');
|
||||||
|
|
||||||
|
if (parts.size() != 4 && m_formspec_version < FORMSPEC_API_VERSION) {
|
||||||
|
errorstream << "Invalid text element(" << parts.size() << "): '" << element << "'" << std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> v_pos = split(parts[0], ',');
|
||||||
|
std::vector<std::string> v_geom = split(parts[1], ',');
|
||||||
|
std::string name = parts[2];
|
||||||
|
std::string text = parts[3];
|
||||||
|
|
||||||
|
MY_CHECKPOS("hypertext", 0);
|
||||||
|
MY_CHECKGEOM("hypertext", 1);
|
||||||
|
|
||||||
|
v2s32 pos;
|
||||||
|
v2s32 geom;
|
||||||
|
|
||||||
|
if (data->real_coordinates) {
|
||||||
|
pos = getRealCoordinateBasePos(false, v_pos);
|
||||||
|
geom = getRealCoordinateGeometry(v_geom);
|
||||||
|
} else {
|
||||||
|
pos = getElementBasePos(false, &v_pos);
|
||||||
|
pos -= padding;
|
||||||
|
|
||||||
|
pos.X += stof(v_pos[0]) * spacing.X;
|
||||||
|
pos.Y += stof(v_pos[1]) * spacing.Y + (m_btn_height * 2);
|
||||||
|
|
||||||
|
geom.X = (stof(v_geom[0]) * spacing.X) - (spacing.X - imgsize.X);
|
||||||
|
geom.Y = (stof(v_geom[1]) * imgsize.Y) - (spacing.Y - imgsize.Y);
|
||||||
|
}
|
||||||
|
|
||||||
|
core::rect<s32> rect = core::rect<s32>(pos.X, pos.Y, pos.X + geom.X, pos.Y + geom.Y);
|
||||||
|
|
||||||
|
if(m_form_src)
|
||||||
|
text = m_form_src->resolveText(text);
|
||||||
|
|
||||||
|
FieldSpec spec(
|
||||||
|
name,
|
||||||
|
utf8_to_wide(unescape_string(text)),
|
||||||
|
L"",
|
||||||
|
258 + m_fields.size()
|
||||||
|
);
|
||||||
|
|
||||||
|
spec.ftype = f_Unknown;
|
||||||
|
new GUIHyperText(
|
||||||
|
spec.flabel.c_str(), Environment, this, spec.fid, rect, m_client, m_tsrc);
|
||||||
|
|
||||||
|
m_fields.push_back(spec);
|
||||||
|
}
|
||||||
|
|
||||||
void GUIFormSpecMenu::parseLabel(parserData* data, const std::string &element)
|
void GUIFormSpecMenu::parseLabel(parserData* data, const std::string &element)
|
||||||
{
|
{
|
||||||
std::vector<std::string> parts = split(element,';');
|
std::vector<std::string> parts = split(element,';');
|
||||||
@ -2293,6 +2345,11 @@ void GUIFormSpecMenu::parseElement(parserData* data, const std::string &element)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (type == "hypertext") {
|
||||||
|
parseHyperText(data,description);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (type == "label") {
|
if (type == "label") {
|
||||||
parseLabel(data,description);
|
parseLabel(data,description);
|
||||||
return;
|
return;
|
||||||
@ -2879,8 +2936,8 @@ void GUIFormSpecMenu::drawList(const ListDrawSpec &s, int layer,
|
|||||||
if (!item.empty()) {
|
if (!item.empty()) {
|
||||||
// Draw item stack
|
// Draw item stack
|
||||||
drawItemStack(driver, m_font, item,
|
drawItemStack(driver, m_font, item,
|
||||||
rect, &AbsoluteClippingRect, m_client,
|
rect, &AbsoluteClippingRect, m_client, rotation_kind);
|
||||||
rotation_kind);
|
|
||||||
// Draw tooltip
|
// Draw tooltip
|
||||||
if (hovering && !m_selected_item) {
|
if (hovering && !m_selected_item) {
|
||||||
std::string tooltip = item.getDescription(m_client->idef());
|
std::string tooltip = item.getDescription(m_client->idef());
|
||||||
@ -2900,8 +2957,8 @@ void GUIFormSpecMenu::drawSelectedItem()
|
|||||||
|
|
||||||
if (!m_selected_item) {
|
if (!m_selected_item) {
|
||||||
drawItemStack(driver, m_font, ItemStack(),
|
drawItemStack(driver, m_font, ItemStack(),
|
||||||
core::rect<s32>(v2s32(0, 0), v2s32(0, 0)),
|
core::rect<s32>(v2s32(0, 0), v2s32(0, 0)), NULL,
|
||||||
NULL, m_client, IT_ROT_DRAGGED);
|
m_client, IT_ROT_DRAGGED);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3482,9 +3539,10 @@ bool GUIFormSpecMenu::preprocessEvent(const SEvent& event)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Mouse wheel events: send to hovered element instead of focused
|
// Mouse wheel and move events: send to hovered element instead of focused
|
||||||
if(event.EventType==EET_MOUSE_INPUT_EVENT
|
if (event.EventType == EET_MOUSE_INPUT_EVENT &&
|
||||||
&& event.MouseInput.Event == EMIE_MOUSE_WHEEL) {
|
(event.MouseInput.Event == EMIE_MOUSE_WHEEL ||
|
||||||
|
event.MouseInput.Event == EMIE_MOUSE_MOVED)) {
|
||||||
s32 x = event.MouseInput.X;
|
s32 x = event.MouseInput.X;
|
||||||
s32 y = event.MouseInput.Y;
|
s32 y = event.MouseInput.Y;
|
||||||
gui::IGUIElement *hovered =
|
gui::IGUIElement *hovered =
|
||||||
@ -3492,7 +3550,7 @@ bool GUIFormSpecMenu::preprocessEvent(const SEvent& event)
|
|||||||
core::position2d<s32>(x, y));
|
core::position2d<s32>(x, y));
|
||||||
if (hovered && isMyChild(hovered)) {
|
if (hovered && isMyChild(hovered)) {
|
||||||
hovered->OnEvent(event);
|
hovered->OnEvent(event);
|
||||||
return true;
|
return event.MouseInput.Event == EMIE_MOUSE_WHEEL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4041,8 +4099,8 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event)
|
|||||||
}
|
}
|
||||||
m_old_pointer = m_pointer;
|
m_old_pointer = m_pointer;
|
||||||
}
|
}
|
||||||
if (event.EventType == EET_GUI_EVENT) {
|
|
||||||
|
|
||||||
|
if (event.EventType == EET_GUI_EVENT) {
|
||||||
if (event.GUIEvent.EventType == gui::EGET_TAB_CHANGED
|
if (event.GUIEvent.EventType == gui::EGET_TAB_CHANGED
|
||||||
&& isVisible()) {
|
&& isVisible()) {
|
||||||
// find the element that was clicked
|
// find the element that was clicked
|
||||||
@ -4128,6 +4186,11 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event)
|
|||||||
s.fdefault = L"Changed";
|
s.fdefault = L"Changed";
|
||||||
acceptInput(quit_mode_no);
|
acceptInput(quit_mode_no);
|
||||||
s.fdefault = L"";
|
s.fdefault = L"";
|
||||||
|
} else if ((s.ftype == f_Unknown) &&
|
||||||
|
(s.fid == event.GUIEvent.Caller->getID())) {
|
||||||
|
s.send = true;
|
||||||
|
acceptInput();
|
||||||
|
s.send = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -469,6 +469,7 @@ protected:
|
|||||||
video::SColor m_default_tooltip_bgcolor;
|
video::SColor m_default_tooltip_bgcolor;
|
||||||
video::SColor m_default_tooltip_color;
|
video::SColor m_default_tooltip_color;
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
IFormSource *m_form_src;
|
IFormSource *m_form_src;
|
||||||
TextDest *m_text_dst;
|
TextDest *m_text_dst;
|
||||||
@ -529,6 +530,7 @@ private:
|
|||||||
void parseSimpleField(parserData* data,std::vector<std::string> &parts);
|
void parseSimpleField(parserData* data,std::vector<std::string> &parts);
|
||||||
void parseTextArea(parserData* data,std::vector<std::string>& parts,
|
void parseTextArea(parserData* data,std::vector<std::string>& parts,
|
||||||
const std::string &type);
|
const std::string &type);
|
||||||
|
void parseHyperText(parserData *data, const std::string &element);
|
||||||
void parseLabel(parserData* data, const std::string &element);
|
void parseLabel(parserData* data, const std::string &element);
|
||||||
void parseVertLabel(parserData* data, const std::string &element);
|
void parseVertLabel(parserData* data, const std::string &element);
|
||||||
void parseImageButton(parserData* data, const std::string &element,
|
void parseImageButton(parserData* data, const std::string &element,
|
||||||
|
1137
src/gui/guiHyperText.cpp
Normal file
1137
src/gui/guiHyperText.cpp
Normal file
File diff suppressed because it is too large
Load Diff
229
src/gui/guiHyperText.h
Normal file
229
src/gui/guiHyperText.h
Normal file
@ -0,0 +1,229 @@
|
|||||||
|
/*
|
||||||
|
Minetest
|
||||||
|
Copyright (C) 2019 EvicenceBKidscode / Pierre-Yves Rollo <dev@pyrollo.com>
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2.1 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public License along
|
||||||
|
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "config.h" // for USE_FREETYPE
|
||||||
|
|
||||||
|
using namespace irr;
|
||||||
|
|
||||||
|
class ISimpleTextureSource;
|
||||||
|
class Client;
|
||||||
|
|
||||||
|
#if USE_FREETYPE
|
||||||
|
#include "irrlicht_changes/CGUITTFont.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
class ParsedText
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ParsedText(const wchar_t *text);
|
||||||
|
~ParsedText();
|
||||||
|
|
||||||
|
enum ElementType
|
||||||
|
{
|
||||||
|
ELEMENT_TEXT,
|
||||||
|
ELEMENT_SEPARATOR,
|
||||||
|
ELEMENT_IMAGE,
|
||||||
|
ELEMENT_ITEM
|
||||||
|
};
|
||||||
|
|
||||||
|
enum BackgroundType
|
||||||
|
{
|
||||||
|
BACKGROUND_NONE,
|
||||||
|
BACKGROUND_COLOR
|
||||||
|
};
|
||||||
|
|
||||||
|
enum FloatType
|
||||||
|
{
|
||||||
|
FLOAT_NONE,
|
||||||
|
FLOAT_RIGHT,
|
||||||
|
FLOAT_LEFT
|
||||||
|
};
|
||||||
|
|
||||||
|
enum HalignType
|
||||||
|
{
|
||||||
|
HALIGN_CENTER,
|
||||||
|
HALIGN_LEFT,
|
||||||
|
HALIGN_RIGHT,
|
||||||
|
HALIGN_JUSTIFY
|
||||||
|
};
|
||||||
|
|
||||||
|
enum ValignType
|
||||||
|
{
|
||||||
|
VALIGN_MIDDLE,
|
||||||
|
VALIGN_TOP,
|
||||||
|
VALIGN_BOTTOM
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef std::unordered_map<std::string, std::string> StyleList;
|
||||||
|
typedef std::unordered_map<std::string, std::string> AttrsList;
|
||||||
|
|
||||||
|
struct Tag
|
||||||
|
{
|
||||||
|
std::string name;
|
||||||
|
AttrsList attrs;
|
||||||
|
StyleList style;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Element
|
||||||
|
{
|
||||||
|
std::list<Tag *> tags;
|
||||||
|
ElementType type;
|
||||||
|
core::stringw text = "";
|
||||||
|
|
||||||
|
core::dimension2d<u32> dim;
|
||||||
|
core::position2d<s32> pos;
|
||||||
|
s32 drawwidth;
|
||||||
|
|
||||||
|
FloatType floating = FLOAT_NONE;
|
||||||
|
|
||||||
|
ValignType valign;
|
||||||
|
|
||||||
|
#if USE_FREETYPE
|
||||||
|
gui::CGUITTFont *font;
|
||||||
|
#else
|
||||||
|
gui::IGUIFont *font;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
irr::video::SColor color;
|
||||||
|
irr::video::SColor hovercolor;
|
||||||
|
bool underline;
|
||||||
|
|
||||||
|
s32 baseline = 0;
|
||||||
|
|
||||||
|
// img & item specific attributes
|
||||||
|
std::string name;
|
||||||
|
v3s16 angle{0, 0, 0};
|
||||||
|
v3s16 rotation{0, 0, 0};
|
||||||
|
|
||||||
|
s32 margin = 10;
|
||||||
|
|
||||||
|
void setStyle(StyleList &style);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Paragraph
|
||||||
|
{
|
||||||
|
std::vector<Element> elements;
|
||||||
|
HalignType halign;
|
||||||
|
s32 margin = 10;
|
||||||
|
|
||||||
|
void setStyle(StyleList &style);
|
||||||
|
};
|
||||||
|
|
||||||
|
std::vector<Paragraph> m_paragraphs;
|
||||||
|
|
||||||
|
// Element style
|
||||||
|
s32 margin = 3;
|
||||||
|
ValignType valign = VALIGN_TOP;
|
||||||
|
BackgroundType background_type = BACKGROUND_NONE;
|
||||||
|
irr::video::SColor background_color;
|
||||||
|
|
||||||
|
Tag m_root_tag;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// Parser functions
|
||||||
|
void enterElement(ElementType type);
|
||||||
|
void endElement();
|
||||||
|
void enterParagraph();
|
||||||
|
void endParagraph();
|
||||||
|
void pushChar(wchar_t c);
|
||||||
|
ParsedText::Tag *newTag(const std::string &name, const AttrsList &attrs);
|
||||||
|
ParsedText::Tag *openTag(const std::string &name, const AttrsList &attrs);
|
||||||
|
bool closeTag(const std::string &name);
|
||||||
|
void parseGenericStyleAttr(const std::string &name, const std::string &value,
|
||||||
|
StyleList &style);
|
||||||
|
void parseStyles(const AttrsList &attrs, StyleList &style);
|
||||||
|
void globalTag(const ParsedText::AttrsList &attrs);
|
||||||
|
u32 parseTag(const wchar_t *text, u32 cursor);
|
||||||
|
void parse(const wchar_t *text);
|
||||||
|
|
||||||
|
std::unordered_map<std::string, StyleList> m_elementtags;
|
||||||
|
std::unordered_map<std::string, StyleList> m_paragraphtags;
|
||||||
|
|
||||||
|
std::vector<Tag *> m_tags;
|
||||||
|
std::list<Tag *> m_active_tags;
|
||||||
|
|
||||||
|
// Current values
|
||||||
|
StyleList m_style;
|
||||||
|
Element *m_element;
|
||||||
|
Paragraph *m_paragraph;
|
||||||
|
};
|
||||||
|
|
||||||
|
class TextDrawer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TextDrawer(const wchar_t *text, Client *client, gui::IGUIEnvironment *environment,
|
||||||
|
ISimpleTextureSource *tsrc);
|
||||||
|
|
||||||
|
void place(const core::rect<s32> &dest_rect);
|
||||||
|
inline s32 getHeight() { return m_height; };
|
||||||
|
void draw(const core::rect<s32> &dest_rect,
|
||||||
|
const core::position2d<s32> &dest_offset);
|
||||||
|
ParsedText::Element *getElementAt(core::position2d<s32> pos);
|
||||||
|
ParsedText::Tag *m_hovertag;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
struct RectWithMargin
|
||||||
|
{
|
||||||
|
core::rect<s32> rect;
|
||||||
|
s32 margin;
|
||||||
|
};
|
||||||
|
|
||||||
|
ParsedText m_text;
|
||||||
|
Client *m_client;
|
||||||
|
gui::IGUIEnvironment *m_environment;
|
||||||
|
s32 m_height;
|
||||||
|
s32 m_voffset;
|
||||||
|
std::vector<RectWithMargin> m_floating;
|
||||||
|
};
|
||||||
|
|
||||||
|
class GUIHyperText : public gui::IGUIElement
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
//! constructor
|
||||||
|
GUIHyperText(const wchar_t *text, gui::IGUIEnvironment *environment,
|
||||||
|
gui::IGUIElement *parent, s32 id,
|
||||||
|
const core::rect<s32> &rectangle, Client *client,
|
||||||
|
ISimpleTextureSource *tsrc);
|
||||||
|
|
||||||
|
//! destructor
|
||||||
|
virtual ~GUIHyperText();
|
||||||
|
|
||||||
|
//! draws the element and its children
|
||||||
|
virtual void draw();
|
||||||
|
|
||||||
|
core::dimension2du getTextDimension();
|
||||||
|
|
||||||
|
bool OnEvent(const SEvent &event);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// GUI members
|
||||||
|
Client *m_client;
|
||||||
|
GUIScrollBar *m_vscrollbar;
|
||||||
|
TextDrawer m_drawer;
|
||||||
|
|
||||||
|
// Positioning
|
||||||
|
u32 m_scrollbar_width;
|
||||||
|
core::rect<s32> m_display_text_rect;
|
||||||
|
core::position2d<s32> m_text_scrollpos;
|
||||||
|
|
||||||
|
ParsedText::Element *getElementAt(s32 X, s32 Y);
|
||||||
|
void checkHover(s32 X, s32 Y);
|
||||||
|
};
|
@ -327,6 +327,8 @@ namespace gui
|
|||||||
(const wchar_t* text, scene::ISceneManager* smgr, scene::ISceneNode* parent = 0,
|
(const wchar_t* text, scene::ISceneManager* smgr, scene::ISceneNode* parent = 0,
|
||||||
const video::SColor& color = video::SColor(255, 0, 0, 0), bool center = false );
|
const video::SColor& color = video::SColor(255, 0, 0, 0), bool center = false );
|
||||||
|
|
||||||
|
inline s32 getAscender() const { return font_metrics.ascender; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool use_monochrome;
|
bool use_monochrome;
|
||||||
bool use_transparency;
|
bool use_transparency;
|
||||||
|
@ -947,3 +947,28 @@ std::wstring translate_string(const std::wstring &s) {
|
|||||||
translate_all(s, i, res);
|
translate_all(s, i, res);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a std::string from a irr::core:stringw.
|
||||||
|
*/
|
||||||
|
std::string strwtostr(const irr::core::stringw &str)
|
||||||
|
{
|
||||||
|
std::string text = core::stringc(str.c_str()).c_str();
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a irr::core:stringw from a std::string.
|
||||||
|
*/
|
||||||
|
irr::core::stringw strtostrw(const std::string &str)
|
||||||
|
{
|
||||||
|
size_t size = str.size();
|
||||||
|
// s.size() doesn't include NULL terminator
|
||||||
|
wchar_t *text = new wchar_t[size + sizeof(wchar_t)];
|
||||||
|
const char *data = &str[0];
|
||||||
|
|
||||||
|
mbsrtowcs(text, &data, size, NULL);
|
||||||
|
|
||||||
|
text[size] = L'\0';
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
@ -20,6 +20,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "irrlichttypes_bloated.h"
|
#include "irrlichttypes_bloated.h"
|
||||||
|
#include "irrString.h"
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
@ -723,3 +724,13 @@ inline std::string str_join(const std::vector<std::string> &list,
|
|||||||
}
|
}
|
||||||
return oss.str();
|
return oss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a std::string from a irr::core::stringw.
|
||||||
|
*/
|
||||||
|
std::string strwtostr(const irr::core::stringw &str);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a irr::core:stringw from a std::string.
|
||||||
|
*/
|
||||||
|
irr::core::stringw strtostrw(const std::string &str);
|
||||||
|
@ -167,6 +167,8 @@ src/gui/guiEngine.h
|
|||||||
src/gui/guiFormSpecMenu.cpp
|
src/gui/guiFormSpecMenu.cpp
|
||||||
src/gui/guiFormSpecMenu.h
|
src/gui/guiFormSpecMenu.h
|
||||||
src/gui/guiKeyChangeMenu.cpp
|
src/gui/guiKeyChangeMenu.cpp
|
||||||
|
src/gui/guiHyperText.cpp
|
||||||
|
src/gui/guiHyperText.h
|
||||||
src/gui/guiMainMenu.h
|
src/gui/guiMainMenu.h
|
||||||
src/gui/guiPasswordChange.cpp
|
src/gui/guiPasswordChange.cpp
|
||||||
src/gui/guiPathSelectMenu.cpp
|
src/gui/guiPathSelectMenu.cpp
|
||||||
|
Loading…
Reference in New Issue
Block a user