mirror of
https://github.com/minetest/minetest.git
synced 2024-07-04 15:05:27 +02:00
Compare commits
14 Commits
811a9da633
...
d153c78406
Author | SHA1 | Date | |
---|---|---|---|
|
d153c78406 | ||
|
9a1501ae89 | ||
|
e211a5fa64 | ||
|
0f12a322d9 | ||
|
bab7187a23 | ||
|
f2422a2596 | ||
|
3638d93b77 | ||
|
7c25907675 | ||
|
4fcf9797aa | ||
|
b207351c41 | ||
|
14fa03172d | ||
|
b3c06bb9e5 | ||
|
4fa1b479a6 | ||
|
46bc0d5ca0 |
@ -2840,6 +2840,7 @@ Elements
|
|||||||
### `tooltip[<gui_element_name>;<tooltip_text>;<bgcolor>;<fontcolor>]`
|
### `tooltip[<gui_element_name>;<tooltip_text>;<bgcolor>;<fontcolor>]`
|
||||||
|
|
||||||
* Adds tooltip for an element
|
* Adds tooltip for an element
|
||||||
|
* It has to be declared *after* the element that is bound to
|
||||||
* `bgcolor` tooltip background color as `ColorString` (optional)
|
* `bgcolor` tooltip background color as `ColorString` (optional)
|
||||||
* `fontcolor` tooltip font color as `ColorString` (optional)
|
* `fontcolor` tooltip font color as `ColorString` (optional)
|
||||||
|
|
||||||
@ -2849,6 +2850,25 @@ Elements
|
|||||||
* `bgcolor` tooltip background color as `ColorString` (optional)
|
* `bgcolor` tooltip background color as `ColorString` (optional)
|
||||||
* `fontcolor` tooltip font color as `ColorString` (optional)
|
* `fontcolor` tooltip font color as `ColorString` (optional)
|
||||||
|
|
||||||
|
### `supertip[<gui_element_name>;<staticPos>;<width>;<name>;<text>]`
|
||||||
|
|
||||||
|
* Adds an advanced tooltip for an element. Displays a formatted text using
|
||||||
|
`Markup Language` in a tooltip.
|
||||||
|
* This supertip has to be declared *after* the element that is bound to.
|
||||||
|
* `staticPos` is an optional position of the form `posX,posY` in formspec coordinates.
|
||||||
|
If specified, the tooltip will always appear at these given formspec coordinates.
|
||||||
|
If this field is empty, the tooltip will follow the cursor.
|
||||||
|
* `width` sets the tooltip width (in formspec units).
|
||||||
|
* `name` is the name of the field.
|
||||||
|
* `text` is the formatted text using `Markup Language` described below.
|
||||||
|
|
||||||
|
### `supertip[<X>,<Y>;<W>,<H>;<staticPos>;<width>;<name>;<text>]`
|
||||||
|
|
||||||
|
* Adds an advanced tooltip for an area. Displays a formatted text using
|
||||||
|
`Markup Language` in a tooltip.
|
||||||
|
* `X`, `Y`, `W` and `H` set the cursor hover area that allows the tooltip to pop-up.
|
||||||
|
* `staticPos`, `width`, `name`, `text`: See above.
|
||||||
|
|
||||||
### `image[<X>,<Y>;<W>,<H>;<texture name>;<middle>]`
|
### `image[<X>,<Y>;<W>,<H>;<texture name>;<middle>]`
|
||||||
|
|
||||||
* Show an image.
|
* Show an image.
|
||||||
@ -3412,6 +3432,7 @@ Some types may inherit styles from parent types.
|
|||||||
* model
|
* model
|
||||||
* pwdfield, inherits from field
|
* pwdfield, inherits from field
|
||||||
* scrollbar
|
* scrollbar
|
||||||
|
* supertip
|
||||||
* tabheader
|
* tabheader
|
||||||
* table
|
* table
|
||||||
* textarea
|
* textarea
|
||||||
@ -3512,6 +3533,13 @@ Some types may inherit styles from parent types.
|
|||||||
* sound - a sound to be played when triggered.
|
* sound - a sound to be played when triggered.
|
||||||
* scrollbar
|
* scrollbar
|
||||||
* 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.
|
||||||
|
* supertip
|
||||||
|
* noclip - boolean, set to true to allow the element to exceed formspec bounds.
|
||||||
|
* bgcolor - color, sets background color.
|
||||||
|
* border - boolean, draw border. Set to false to hide the bevelled tooltip pane. Default true.
|
||||||
|
* bgimg - standard background image. Defaults to none.
|
||||||
|
* bgimg_middle - Makes the bgimg textures render in 9-sliced mode and defines the middle rect.
|
||||||
|
See background9[] documentation for more details.
|
||||||
* tabheader
|
* tabheader
|
||||||
* 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.
|
||||||
* sound - a sound to be played when a different tab is selected.
|
* sound - a sound to be played when a different tab is selected.
|
||||||
|
@ -468,6 +468,51 @@ mouse control = true]
|
|||||||
background9[0,0;0,0;testformspec_bg_9slice.png;true;4,6]
|
background9[0,0;0,0;testformspec_bg_9slice.png;true;4,6]
|
||||||
background[1,1;0,0;testformspec_bg.png;true]
|
background[1,1;0,0;testformspec_bg.png;true]
|
||||||
]],
|
]],
|
||||||
|
|
||||||
|
-- Tooltip
|
||||||
|
[[
|
||||||
|
formspec_version[7]
|
||||||
|
size[12,13]
|
||||||
|
label[1,0.5;Hover a red box or a button for a tooltip.]
|
||||||
|
|
||||||
|
box[1,1;1,1;#ff000080]
|
||||||
|
tooltip[1,1;1,1;Normal tooltip in an area]
|
||||||
|
|
||||||
|
button[2.5,1;3,1;tt_btn;HOVERME]
|
||||||
|
tooltip[tt_btn;Normal tooltip on a button]
|
||||||
|
|
||||||
|
box[1,3;1,1;#ff000080]
|
||||||
|
box[2.4,3.4;0.2,0.2;#ffffff80]
|
||||||
|
supertip[1,3;1,1;2.5,3.5;5;supertip_static;<big>Simple supertip (<i>static</i>)</big>
|
||||||
|
This one should always appear at the tiny white square.]
|
||||||
|
|
||||||
|
box[1,5;1,1;#ff000080]
|
||||||
|
supertip[1,5;1,1;;5;supertip_dynamic;<big>Simple supertip (<i>dynamic</i>)</big>
|
||||||
|
This should appear at the cursor.]
|
||||||
|
|
||||||
|
button[2.5,5;3,1;st_btn;HOVERME]
|
||||||
|
supertip[st_btn;;5;supertip_dynamic_btn;<big>Simple supertip (<i>dynamic</i>)</big>
|
||||||
|
This should appear at the cursor when hovering the button.]
|
||||||
|
|
||||||
|
box[1,7;1,1;#ff000080]
|
||||||
|
supertip[1,7;1,1;;5;supertip_dynamic_complex;]]..minetest.formspec_escape([[<big>Complex supertip (<i>dynamic</i>)</big>
|
||||||
|
<img name=testformspec_node.png float=right width=64 height=64>
|
||||||
|
<left>Left align</left>
|
||||||
|
<center>Right align</center>
|
||||||
|
<right>Right align</right>
|
||||||
|
<b>Bold</b> <i>Italic</i> <u>Underline</u> <mono>Mono</mono>
|
||||||
|
Item:
|
||||||
|
<item name=testformspec:node>]])..[[]
|
||||||
|
|
||||||
|
box[1,9;1,1;#ff000080]
|
||||||
|
supertip[1,9;1,1;;5;supertip_stone;]]..minetest.formspec_escape([[<global color=#333 background=#aaa margin=20>
|
||||||
|
<item name=testformspec:node float=left width=64 height=64>
|
||||||
|
<big><b><center>Formspec Test Node</center></b></big>
|
||||||
|
The <b>Formspec Test Node</b> is a dummy node to display an item in the <mono>testformspec</mono> mod.
|
||||||
|
|
||||||
|
• <b>Max. stack size:</b> 99
|
||||||
|
• <b>Drops:</b> <i>itself</i> <item name=testformspec:node width=32 height=32>]])..
|
||||||
|
"]"
|
||||||
}
|
}
|
||||||
|
|
||||||
local page_id = 2
|
local page_id = 2
|
||||||
@ -477,7 +522,7 @@ local function show_test_formspec(pname)
|
|||||||
page = page()
|
page = page()
|
||||||
end
|
end
|
||||||
|
|
||||||
local fs = page .. "tabheader[0,0;11,0.65;maintabs;Real Coord,Styles,Noclip,Hypertext,Tabs,Invs,Window,Anim,Model,ScrollC,Sound,Background,Unsized;" .. page_id .. ";false;false]"
|
local fs = page .. "tabheader[0,0;11,0.65;maintabs;Real Coord,Styles,Noclip,Hypertext,Tabs,Invs,Window,Anim,Model,ScrollC,Sound,Background,Unsized,Tooltip;" .. page_id .. ";false;false]"
|
||||||
|
|
||||||
minetest.show_formspec(pname, "testformspec:formspec", fs)
|
minetest.show_formspec(pname, "testformspec:formspec", fs)
|
||||||
end
|
end
|
||||||
|
@ -129,9 +129,9 @@ EM_BOOL CIrrDeviceSDL::MouseLeaveCallback(int eventType, const EmscriptenMouseEv
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
bool CIrrDeviceSDL::keyIsKnownSpecial(EKEY_CODE key)
|
bool CIrrDeviceSDL::keyIsKnownSpecial(EKEY_CODE irrlichtKey)
|
||||||
{
|
{
|
||||||
switch (key) {
|
switch (irrlichtKey) {
|
||||||
// keys which are known to have safe special character interpretation
|
// keys which are known to have safe special character interpretation
|
||||||
// could need changes over time (removals and additions!)
|
// could need changes over time (removals and additions!)
|
||||||
case KEY_RETURN:
|
case KEY_RETURN:
|
||||||
@ -189,24 +189,68 @@ bool CIrrDeviceSDL::keyIsKnownSpecial(EKEY_CODE key)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int CIrrDeviceSDL::findCharToPassToIrrlicht(int assumedChar, EKEY_CODE key)
|
int CIrrDeviceSDL::findCharToPassToIrrlicht(uint32_t sdlKey, EKEY_CODE irrlichtKey, bool numlock)
|
||||||
{
|
{
|
||||||
|
switch (irrlichtKey) {
|
||||||
// special cases that always return a char regardless of how the SDL keycode
|
// special cases that always return a char regardless of how the SDL keycode
|
||||||
// looks
|
// looks
|
||||||
switch (key) {
|
|
||||||
case KEY_RETURN:
|
case KEY_RETURN:
|
||||||
case KEY_ESCAPE:
|
case KEY_ESCAPE:
|
||||||
return (int)key;
|
return (int)irrlichtKey;
|
||||||
|
|
||||||
|
// This is necessary for keys on the numpad because they don't use the same
|
||||||
|
// keycodes as their non-numpad versions (whose keycodes correspond to chars),
|
||||||
|
// but have their own SDL keycodes and their own Irrlicht keycodes (which
|
||||||
|
// don't correspond to chars).
|
||||||
|
case KEY_MULTIPLY:
|
||||||
|
return '*';
|
||||||
|
case KEY_ADD:
|
||||||
|
return '+';
|
||||||
|
case KEY_SUBTRACT:
|
||||||
|
return '-';
|
||||||
|
case KEY_DIVIDE:
|
||||||
|
return '/';
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (numlock) {
|
||||||
|
// Number keys on the numpad are also affected, but we only want them
|
||||||
|
// to produce number chars when numlock is enabled.
|
||||||
|
switch (irrlichtKey) {
|
||||||
|
case KEY_NUMPAD0:
|
||||||
|
return '0';
|
||||||
|
case KEY_NUMPAD1:
|
||||||
|
return '1';
|
||||||
|
case KEY_NUMPAD2:
|
||||||
|
return '2';
|
||||||
|
case KEY_NUMPAD3:
|
||||||
|
return '3';
|
||||||
|
case KEY_NUMPAD4:
|
||||||
|
return '4';
|
||||||
|
case KEY_NUMPAD5:
|
||||||
|
return '5';
|
||||||
|
case KEY_NUMPAD6:
|
||||||
|
return '6';
|
||||||
|
case KEY_NUMPAD7:
|
||||||
|
return '7';
|
||||||
|
case KEY_NUMPAD8:
|
||||||
|
return '8';
|
||||||
|
case KEY_NUMPAD9:
|
||||||
|
return '9';
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// SDL in-place ORs values with no character representation with 1<<30
|
// SDL in-place ORs values with no character representation with 1<<30
|
||||||
// https://wiki.libsdl.org/SDL2/SDLKeycodeLookup
|
// https://wiki.libsdl.org/SDL2/SDLKeycodeLookup
|
||||||
if (assumedChar & (1 << 30))
|
// This also affects the numpad keys btw.
|
||||||
|
if (sdlKey & (1 << 30))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
switch (key) {
|
switch (irrlichtKey) {
|
||||||
case KEY_PRIOR:
|
case KEY_PRIOR:
|
||||||
case KEY_NEXT:
|
case KEY_NEXT:
|
||||||
case KEY_HOME:
|
case KEY_HOME:
|
||||||
@ -218,7 +262,7 @@ int CIrrDeviceSDL::findCharToPassToIrrlicht(int assumedChar, EKEY_CODE key)
|
|||||||
case KEY_NUMLOCK:
|
case KEY_NUMLOCK:
|
||||||
return 0;
|
return 0;
|
||||||
default:
|
default:
|
||||||
return assumedChar;
|
return sdlKey;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -825,7 +869,8 @@ bool CIrrDeviceSDL::run()
|
|||||||
irrevent.KeyInput.PressedDown = (SDL_event.type == SDL_KEYDOWN);
|
irrevent.KeyInput.PressedDown = (SDL_event.type == SDL_KEYDOWN);
|
||||||
irrevent.KeyInput.Shift = (SDL_event.key.keysym.mod & KMOD_SHIFT) != 0;
|
irrevent.KeyInput.Shift = (SDL_event.key.keysym.mod & KMOD_SHIFT) != 0;
|
||||||
irrevent.KeyInput.Control = (SDL_event.key.keysym.mod & KMOD_CTRL) != 0;
|
irrevent.KeyInput.Control = (SDL_event.key.keysym.mod & KMOD_CTRL) != 0;
|
||||||
irrevent.KeyInput.Char = findCharToPassToIrrlicht(mp.SDLKey, key);
|
irrevent.KeyInput.Char = findCharToPassToIrrlicht(mp.SDLKey, key,
|
||||||
|
(SDL_event.key.keysym.mod & KMOD_NUM) != 0);
|
||||||
postEventFromUser(irrevent);
|
postEventFromUser(irrevent);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
@ -273,10 +273,10 @@ class CIrrDeviceSDL : public CIrrDeviceStub
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
// Check if a key is a known special character with no side effects on text boxes.
|
// Check if a key is a known special character with no side effects on text boxes.
|
||||||
static bool keyIsKnownSpecial(EKEY_CODE key);
|
static bool keyIsKnownSpecial(EKEY_CODE irrlichtKey);
|
||||||
|
|
||||||
// Return the Char that should be sent to Irrlicht for the given key (either the one passed in or 0).
|
// Return the Char that should be sent to Irrlicht for the given key (either the one passed in or 0).
|
||||||
static int findCharToPassToIrrlicht(int assumedChar, EKEY_CODE key);
|
static int findCharToPassToIrrlicht(uint32_t sdlKey, EKEY_CODE irrlichtKey, bool numlock);
|
||||||
|
|
||||||
// Check if a text box is in focus. Enable or disable SDL_TEXTINPUT events only if in focus.
|
// Check if a text box is in focus. Enable or disable SDL_TEXTINPUT events only if in focus.
|
||||||
void resetReceiveTextInputEvents();
|
void resetReceiveTextInputEvents();
|
||||||
|
@ -65,7 +65,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
#include "guiInventoryList.h"
|
#include "guiInventoryList.h"
|
||||||
#include "guiItemImage.h"
|
#include "guiItemImage.h"
|
||||||
#include "guiScrollContainer.h"
|
#include "guiScrollContainer.h"
|
||||||
#include "guiHyperText.h"
|
|
||||||
#include "guiScene.h"
|
#include "guiScene.h"
|
||||||
|
|
||||||
#define MY_CHECKPOS(a,b) \
|
#define MY_CHECKPOS(a,b) \
|
||||||
@ -1755,6 +1754,118 @@ void GUIFormSpecMenu::parseHyperText(parserData *data, const std::string &elemen
|
|||||||
m_fields.push_back(spec);
|
m_fields.push_back(spec);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GUIFormSpecMenu::parseSuperTip(parserData *data, const std::string &element)
|
||||||
|
{
|
||||||
|
std::vector<std::string> parts;
|
||||||
|
|
||||||
|
if (!precheckElement("supertip", element, 5, 6, parts))
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Get mode and check size
|
||||||
|
bool rect_mode = parts[0].find(',') != std::string::npos;
|
||||||
|
size_t base_size = rect_mode ? 6 : 5;
|
||||||
|
if (parts.size() != base_size && parts.size() != base_size + 2) {
|
||||||
|
errorstream << "Invalid supertip element(" << parts.size() << "): '"
|
||||||
|
<< element << "'" << std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> v_stpos;
|
||||||
|
bool floating = true;
|
||||||
|
size_t i = rect_mode ? 2 : 1;
|
||||||
|
|
||||||
|
if (parts[i] != "") {
|
||||||
|
v_stpos = split(parts[i], ',');
|
||||||
|
if (v_stpos.size() != i) {
|
||||||
|
errorstream << "Invalid staticPos in supertip element(" << parts.size() <<
|
||||||
|
"): \"" << parts[2] << "\"" << std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
floating = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string name = parts[rect_mode ? 4 : 3];
|
||||||
|
std::string text = parts[rect_mode ? 5 : 4];
|
||||||
|
|
||||||
|
if (m_form_src)
|
||||||
|
text = m_form_src->resolveText(text);
|
||||||
|
|
||||||
|
FieldSpec spec(
|
||||||
|
name,
|
||||||
|
translate_string(utf8_to_wide(unescape_string(text))),
|
||||||
|
L"",
|
||||||
|
258 + m_fields.size()
|
||||||
|
);
|
||||||
|
|
||||||
|
m_fields.push_back(spec);
|
||||||
|
|
||||||
|
if (rect_mode) {
|
||||||
|
std::vector<std::string> v_pos = split(parts[0], ',');
|
||||||
|
std::vector<std::string> v_geom = split(parts[1], ',');
|
||||||
|
|
||||||
|
MY_CHECKPOS("supertip", 0);
|
||||||
|
MY_CHECKGEOM("supertip", 1);
|
||||||
|
|
||||||
|
s32 width = stof(parts[3]) * spacing.Y;
|
||||||
|
v2s32 pos;
|
||||||
|
v2s32 geom;
|
||||||
|
v2s32 stpos;
|
||||||
|
|
||||||
|
if (data->real_coordinates) {
|
||||||
|
pos = getRealCoordinateBasePos(v_pos);
|
||||||
|
geom = getRealCoordinateGeometry(v_geom);
|
||||||
|
|
||||||
|
if (!floating)
|
||||||
|
stpos = getRealCoordinateBasePos(v_stpos);
|
||||||
|
} else {
|
||||||
|
pos = getElementBasePos(&v_pos);
|
||||||
|
geom.X = stof(v_geom[0]) * spacing.X;
|
||||||
|
geom.Y = stof(v_geom[1]) * spacing.Y;
|
||||||
|
|
||||||
|
if (!floating)
|
||||||
|
stpos = getElementBasePos(&v_stpos);
|
||||||
|
}
|
||||||
|
|
||||||
|
core::rect<s32> rect(pos, pos + geom);
|
||||||
|
|
||||||
|
GUIHyperText *e = new GUIHyperText(spec.flabel.c_str(), Environment,
|
||||||
|
data->current_parent, spec.fid, rect, m_client, m_tsrc);
|
||||||
|
|
||||||
|
auto style = getStyleForElement("supertip", spec.fname);
|
||||||
|
e->setStyles(style);
|
||||||
|
|
||||||
|
SuperTipSpec geospec(name, "", text, e->getAbsoluteClippingRect(), stpos, width, floating);
|
||||||
|
|
||||||
|
m_supertips.emplace_back(e, geospec);
|
||||||
|
|
||||||
|
e->setVisible(false);
|
||||||
|
e->drop();
|
||||||
|
} else {
|
||||||
|
std::string fieldname = parts[0];
|
||||||
|
core::rect<s32> rect;
|
||||||
|
|
||||||
|
for (const auto &f : m_fields) {
|
||||||
|
if (f.fname == fieldname) {
|
||||||
|
auto *e = getElementFromId(f.fid, true);
|
||||||
|
rect = e->getAbsoluteClippingRect();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
s32 width = stof(parts[2]) * spacing.Y;
|
||||||
|
v2s32 stpos;
|
||||||
|
|
||||||
|
if (!floating) {
|
||||||
|
if (data->real_coordinates)
|
||||||
|
stpos = getRealCoordinateBasePos(v_stpos);
|
||||||
|
else
|
||||||
|
stpos = getElementBasePos(&v_stpos);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_supertip_map[fieldname] = SuperTipSpec(name, fieldname, text, rect, stpos, width, floating);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void GUIFormSpecMenu::parseLabel(parserData* data, const std::string &element)
|
void GUIFormSpecMenu::parseLabel(parserData* data, const std::string &element)
|
||||||
{
|
{
|
||||||
std::vector<std::string> parts;
|
std::vector<std::string> parts;
|
||||||
@ -2958,6 +3069,11 @@ void GUIFormSpecMenu::parseElement(parserData* data, const std::string &element)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (type == "supertip") {
|
||||||
|
parseSuperTip(data,description);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (type == "label") {
|
if (type == "label") {
|
||||||
parseLabel(data,description);
|
parseLabel(data,description);
|
||||||
return;
|
return;
|
||||||
@ -3110,6 +3226,8 @@ void GUIFormSpecMenu::regenerateGui(v2u32 screensize)
|
|||||||
m_scrollbars.clear();
|
m_scrollbars.clear();
|
||||||
m_fields.clear();
|
m_fields.clear();
|
||||||
m_tooltips.clear();
|
m_tooltips.clear();
|
||||||
|
m_supertips.clear();
|
||||||
|
m_supertip_map.clear();
|
||||||
m_tooltip_rects.clear();
|
m_tooltip_rects.clear();
|
||||||
m_inventory_rings.clear();
|
m_inventory_rings.clear();
|
||||||
m_dropdowns.clear();
|
m_dropdowns.clear();
|
||||||
@ -3639,6 +3757,19 @@ void GUIFormSpecMenu::drawMenu()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Draw rect_mode supertip
|
||||||
|
*/
|
||||||
|
for (const auto &pair : m_supertips) {
|
||||||
|
if (m_supertip_map.count(pair.second.parent_name) == 0) {
|
||||||
|
const auto &hover_rect = pair.second.hover_rect;
|
||||||
|
if (hover_rect.getArea() > 0 && hover_rect.isPointInside(m_pointer)) {
|
||||||
|
showSuperTip(pair.first, pair.second);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Some elements are only visible while being drawn
|
// Some elements are only visible while being drawn
|
||||||
for (gui::IGUIElement *e : m_clickthrough_elements)
|
for (gui::IGUIElement *e : m_clickthrough_elements)
|
||||||
e->setVisible(true);
|
e->setVisible(true);
|
||||||
@ -3668,6 +3799,10 @@ void GUIFormSpecMenu::drawMenu()
|
|||||||
NULL, m_client, IT_ROT_HOVERED);
|
NULL, m_client, IT_ROT_HOVERED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (const auto &pair : m_supertips)
|
||||||
|
if (pair.first->isVisible())
|
||||||
|
pair.first->setVisible(false);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Draw fields/buttons tooltips and update the mouse cursor
|
Draw fields/buttons tooltips and update the mouse cursor
|
||||||
*/
|
*/
|
||||||
@ -3718,9 +3853,39 @@ void GUIFormSpecMenu::drawMenu()
|
|||||||
|
|
||||||
if (delta >= m_tooltip_show_delay) {
|
if (delta >= m_tooltip_show_delay) {
|
||||||
const std::wstring &text = m_tooltips[field.fname].tooltip;
|
const std::wstring &text = m_tooltips[field.fname].tooltip;
|
||||||
if (!text.empty())
|
if (!text.empty()) {
|
||||||
|
/* Tooltips get the priority over supertips */
|
||||||
showTooltip(text, m_tooltips[field.fname].color,
|
showTooltip(text, m_tooltips[field.fname].color,
|
||||||
m_tooltips[field.fname].bgcolor);
|
m_tooltips[field.fname].bgcolor);
|
||||||
|
} else if (m_supertip_map.count(field.fname) != 0) {
|
||||||
|
auto &spec = m_supertip_map[field.fname];
|
||||||
|
|
||||||
|
if (!spec.bound) {
|
||||||
|
spec.bound = true;
|
||||||
|
auto *parent_element = getElementFromId(field.fid, true);
|
||||||
|
auto txt = translate_string(utf8_to_wide(unescape_string(spec.text)));
|
||||||
|
|
||||||
|
GUIHyperText *e = new GUIHyperText(
|
||||||
|
txt.c_str(), Environment,
|
||||||
|
parent_element->getParent(), field.fid,
|
||||||
|
spec.hover_rect, m_client, m_tsrc);
|
||||||
|
|
||||||
|
auto style = getStyleForElement("supertip", spec.name);
|
||||||
|
e->setStyles(style);
|
||||||
|
|
||||||
|
m_supertips.emplace_back(e, spec);
|
||||||
|
|
||||||
|
e->setVisible(false);
|
||||||
|
e->drop();
|
||||||
|
} else {
|
||||||
|
for (const auto &pair : m_supertips) {
|
||||||
|
if (field.fname == pair.second.parent_name) {
|
||||||
|
showSuperTip(pair.first, pair.second);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cursor_control &&
|
if (cursor_control &&
|
||||||
@ -3797,6 +3962,56 @@ void GUIFormSpecMenu::showTooltip(const std::wstring &text,
|
|||||||
bringToFront(m_tooltip_element);
|
bringToFront(m_tooltip_element);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GUIFormSpecMenu::showSuperTip(GUIHyperText *e, const SuperTipSpec &spec)
|
||||||
|
{
|
||||||
|
// Supertip size and offset
|
||||||
|
s32 tooltip_width = spec.width;
|
||||||
|
s32 tooltip_height = e->getTextHeight() + 5;
|
||||||
|
s32 tooltip_x, tooltip_y;
|
||||||
|
|
||||||
|
v2u32 screenSize = Environment->getVideoDriver()->getScreenSize();
|
||||||
|
|
||||||
|
// Calculate and set the tooltip position
|
||||||
|
if (spec.floating) {
|
||||||
|
/* Dynamic tooltip position, relative to cursor */
|
||||||
|
int tooltip_offset_x = m_btn_height;
|
||||||
|
int tooltip_offset_y = m_btn_height;
|
||||||
|
|
||||||
|
if (m_pointer_type == PointerType::Touch) {
|
||||||
|
tooltip_offset_x *= 3;
|
||||||
|
tooltip_offset_y = 0;
|
||||||
|
if (m_pointer.X > (s32)screenSize.X / 2)
|
||||||
|
tooltip_offset_x = -(tooltip_offset_x + tooltip_width);
|
||||||
|
}
|
||||||
|
|
||||||
|
v2s32 basePos = getBasePos();
|
||||||
|
|
||||||
|
tooltip_x = (m_pointer.X - basePos.X) + tooltip_offset_x*2;
|
||||||
|
tooltip_y = (m_pointer.Y - basePos.Y) + tooltip_offset_y*2;
|
||||||
|
} else {
|
||||||
|
/* Static tooltip position, using formspec coordinates */
|
||||||
|
tooltip_x = spec.stpos[0];
|
||||||
|
tooltip_y = spec.stpos[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tooltip_x + tooltip_width > (s32)screenSize.X)
|
||||||
|
tooltip_x = (s32)screenSize.X - tooltip_width - m_btn_height;
|
||||||
|
if (tooltip_y + tooltip_height > (s32)screenSize.Y)
|
||||||
|
tooltip_y = (s32)screenSize.Y - tooltip_height - m_btn_height;
|
||||||
|
|
||||||
|
e->setRelativePosition(
|
||||||
|
core::rect<s32>(
|
||||||
|
core::position2d<s32>(tooltip_x, tooltip_y),
|
||||||
|
core::dimension2d<s32>(tooltip_width, tooltip_height)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
// Display the supertip
|
||||||
|
e->setVisible(true);
|
||||||
|
bringToFront(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void GUIFormSpecMenu::updateSelectedItem()
|
void GUIFormSpecMenu::updateSelectedItem()
|
||||||
{
|
{
|
||||||
// Don't update when dragging an item
|
// Don't update when dragging an item
|
||||||
|
@ -32,6 +32,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
#include "guiInventoryList.h"
|
#include "guiInventoryList.h"
|
||||||
#include "guiScrollBar.h"
|
#include "guiScrollBar.h"
|
||||||
#include "guiTable.h"
|
#include "guiTable.h"
|
||||||
|
#include "guiHyperText.h"
|
||||||
#include "network/networkprotocol.h"
|
#include "network/networkprotocol.h"
|
||||||
#include "client/joystick_controller.h"
|
#include "client/joystick_controller.h"
|
||||||
#include "util/string.h"
|
#include "util/string.h"
|
||||||
@ -165,6 +166,36 @@ class GUIFormSpecMenu : public GUIModalMenu
|
|||||||
irr::video::SColor color;
|
irr::video::SColor color;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct SuperTipSpec
|
||||||
|
{
|
||||||
|
SuperTipSpec() = default;
|
||||||
|
SuperTipSpec(const std::string &a_name,
|
||||||
|
const std::string &a_parent_name,
|
||||||
|
const std::string &a_text,
|
||||||
|
const core::rect<s32> &a_rect,
|
||||||
|
v2s32 a_stpos,
|
||||||
|
s32 a_width,
|
||||||
|
bool a_floating) :
|
||||||
|
name(a_name),
|
||||||
|
parent_name(a_parent_name),
|
||||||
|
text(a_text),
|
||||||
|
hover_rect(a_rect),
|
||||||
|
stpos(a_stpos),
|
||||||
|
width(a_width),
|
||||||
|
floating(a_floating)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string name;
|
||||||
|
std::string parent_name;
|
||||||
|
std::string text;
|
||||||
|
core::rect<s32> hover_rect;
|
||||||
|
v2s32 stpos;
|
||||||
|
s32 width;
|
||||||
|
bool floating;
|
||||||
|
bool bound = false;
|
||||||
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
GUIFormSpecMenu(JoystickController *joystick,
|
GUIFormSpecMenu(JoystickController *joystick,
|
||||||
gui::IGUIElement* parent, s32 id,
|
gui::IGUIElement* parent, s32 id,
|
||||||
@ -348,6 +379,8 @@ class GUIFormSpecMenu : public GUIModalMenu
|
|||||||
std::vector<std::pair<FieldSpec, GUITable *>> m_tables;
|
std::vector<std::pair<FieldSpec, GUITable *>> m_tables;
|
||||||
std::vector<std::pair<FieldSpec, gui::IGUICheckBox *>> m_checkboxes;
|
std::vector<std::pair<FieldSpec, gui::IGUICheckBox *>> m_checkboxes;
|
||||||
std::map<std::string, TooltipSpec> m_tooltips;
|
std::map<std::string, TooltipSpec> m_tooltips;
|
||||||
|
std::vector<std::pair<GUIHyperText *, SuperTipSpec>> m_supertips;
|
||||||
|
std::map<std::string, SuperTipSpec> m_supertip_map;
|
||||||
std::vector<std::pair<gui::IGUIElement *, TooltipSpec>> m_tooltip_rects;
|
std::vector<std::pair<gui::IGUIElement *, TooltipSpec>> m_tooltip_rects;
|
||||||
std::vector<std::pair<FieldSpec, GUIScrollBar *>> m_scrollbars;
|
std::vector<std::pair<FieldSpec, GUIScrollBar *>> m_scrollbars;
|
||||||
std::vector<std::pair<FieldSpec, std::vector<std::string>>> m_dropdowns;
|
std::vector<std::pair<FieldSpec, std::vector<std::string>>> m_dropdowns;
|
||||||
@ -469,6 +502,7 @@ class GUIFormSpecMenu : public GUIModalMenu
|
|||||||
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 parseHyperText(parserData *data, const std::string &element);
|
||||||
|
void parseSuperTip(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,
|
||||||
@ -499,6 +533,7 @@ class GUIFormSpecMenu : public GUIModalMenu
|
|||||||
|
|
||||||
void showTooltip(const std::wstring &text, const irr::video::SColor &color,
|
void showTooltip(const std::wstring &text, const irr::video::SColor &color,
|
||||||
const irr::video::SColor &bgcolor);
|
const irr::video::SColor &bgcolor);
|
||||||
|
void showSuperTip(GUIHyperText *e, const SuperTipSpec &spec);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* In formspec version < 2 the elements were not ordered properly. Some element
|
* In formspec version < 2 the elements were not ordered properly. Some element
|
||||||
|
@ -29,12 +29,11 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
#include "irrlicht_changes/CGUITTFont.h"
|
#include "irrlicht_changes/CGUITTFont.h"
|
||||||
#include "mainmenumanager.h"
|
#include "mainmenumanager.h"
|
||||||
#include "porting.h"
|
#include "porting.h"
|
||||||
|
#include "client/guiscalingfilter.h"
|
||||||
using namespace irr::gui;
|
|
||||||
|
|
||||||
static bool check_color(const std::string &str)
|
static bool check_color(const std::string &str)
|
||||||
{
|
{
|
||||||
irr::video::SColor color;
|
video::SColor color;
|
||||||
return parseColorString(str, color, false);
|
return parseColorString(str, color, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -372,7 +371,7 @@ void ParsedText::globalTag(const AttrsList &attrs)
|
|||||||
else if (attr.second == "middle")
|
else if (attr.second == "middle")
|
||||||
valign = ParsedText::VALIGN_MIDDLE;
|
valign = ParsedText::VALIGN_MIDDLE;
|
||||||
} else if (attr.first == "background") {
|
} else if (attr.first == "background") {
|
||||||
irr::video::SColor color;
|
video::SColor color;
|
||||||
if (attr.second == "none") {
|
if (attr.second == "none") {
|
||||||
background_type = BACKGROUND_NONE;
|
background_type = BACKGROUND_NONE;
|
||||||
} else if (parseColorString(attr.second, color, false)) {
|
} else if (parseColorString(attr.second, color, false)) {
|
||||||
@ -643,7 +642,7 @@ TextDrawer::TextDrawer(const wchar_t *text, Client *client,
|
|||||||
if (e.font) {
|
if (e.font) {
|
||||||
e.dim.Width = e.font->getDimension(e.text.c_str()).Width;
|
e.dim.Width = e.font->getDimension(e.text.c_str()).Width;
|
||||||
e.dim.Height = e.font->getDimension(L"Yy").Height;
|
e.dim.Height = e.font->getDimension(L"Yy").Height;
|
||||||
if (e.font->getType() == irr::gui::EGFT_CUSTOM) {
|
if (e.font->getType() == gui::EGFT_CUSTOM) {
|
||||||
CGUITTFont *tmp = static_cast<CGUITTFont*>(e.font);
|
CGUITTFont *tmp = static_cast<CGUITTFont*>(e.font);
|
||||||
e.baseline = e.dim.Height - 1 - tmp->getAscender() / 64;
|
e.baseline = e.dim.Height - 1 - tmp->getAscender() / 64;
|
||||||
}
|
}
|
||||||
@ -940,18 +939,49 @@ void TextDrawer::place(const core::rect<s32> &dest_rect)
|
|||||||
m_voffset = 0;
|
m_voffset = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TextDrawer::drawBackgroundImage(
|
||||||
|
video::IVideoDriver *driver, const ParsedText &m_text, const core::rect<s32> &clip_rect)
|
||||||
|
{
|
||||||
|
auto size = m_text.background_image->getOriginalSize();
|
||||||
|
|
||||||
|
if (m_text.background_middle.getArea() > 0) {
|
||||||
|
draw2DImage9Slice(driver, m_text.background_image, clip_rect,
|
||||||
|
core::rect<s32>(0, 0, size.Width, size.Height), m_text.background_middle);
|
||||||
|
} else {
|
||||||
|
const video::SColor color(255, 255, 255, 255);
|
||||||
|
const video::SColor colors[] = {color, color, color, color};
|
||||||
|
|
||||||
|
draw2DImageFilterScaled(driver, m_text.background_image, clip_rect,
|
||||||
|
core::rect<s32>(0, 0, size.Width, size.Height), nullptr, colors, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Draw text in a rectangle with a given offset. Items are actually placed in
|
// Draw text in a rectangle with a given offset. Items are actually placed in
|
||||||
// relative (to upper left corner) coordinates.
|
// relative (to upper left corner) coordinates.
|
||||||
void TextDrawer::draw(const core::rect<s32> &clip_rect,
|
void TextDrawer::draw(const core::rect<s32> &clip_rect,
|
||||||
const core::position2d<s32> &dest_offset)
|
const core::position2d<s32> &dest_offset)
|
||||||
{
|
{
|
||||||
irr::video::IVideoDriver *driver = m_guienv->getVideoDriver();
|
video::IVideoDriver *driver = m_guienv->getVideoDriver();
|
||||||
core::position2d<s32> offset = dest_offset;
|
core::position2d<s32> offset = dest_offset;
|
||||||
offset.Y += m_voffset;
|
offset.Y += m_voffset;
|
||||||
|
|
||||||
if (m_text.background_type == ParsedText::BACKGROUND_COLOR)
|
if (m_text.background_type == ParsedText::BACKGROUND_COLOR)
|
||||||
driver->draw2DRectangle(m_text.background_color, clip_rect);
|
driver->draw2DRectangle(m_text.background_color, clip_rect);
|
||||||
|
|
||||||
|
if (m_text.border) {
|
||||||
|
const video::SColor color(255,0,0,0);
|
||||||
|
const auto &UpperLeft = clip_rect.UpperLeftCorner;
|
||||||
|
const auto &LowerRight = clip_rect.LowerRightCorner;
|
||||||
|
|
||||||
|
driver->draw2DLine(UpperLeft, core::position2di(LowerRight.X, UpperLeft.Y), color);
|
||||||
|
driver->draw2DLine(core::position2di(LowerRight.X, UpperLeft.Y), LowerRight, color);
|
||||||
|
driver->draw2DLine(LowerRight, core::position2di(UpperLeft.X, LowerRight.Y), color);
|
||||||
|
driver->draw2DLine(core::position2di(UpperLeft.X, LowerRight.Y), UpperLeft, color);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_text.background_image)
|
||||||
|
drawBackgroundImage(driver, m_text, clip_rect);
|
||||||
|
|
||||||
for (auto &p : m_text.m_paragraphs) {
|
for (auto &p : m_text.m_paragraphs) {
|
||||||
for (auto &el : p.elements) {
|
for (auto &el : p.elements) {
|
||||||
core::rect<s32> rect(el.pos + offset, el.dim);
|
core::rect<s32> rect(el.pos + offset, el.dim);
|
||||||
@ -961,7 +991,7 @@ void TextDrawer::draw(const core::rect<s32> &clip_rect,
|
|||||||
switch (el.type) {
|
switch (el.type) {
|
||||||
case ParsedText::ELEMENT_SEPARATOR:
|
case ParsedText::ELEMENT_SEPARATOR:
|
||||||
case ParsedText::ELEMENT_TEXT: {
|
case ParsedText::ELEMENT_TEXT: {
|
||||||
irr::video::SColor color = el.color;
|
video::SColor color = el.color;
|
||||||
|
|
||||||
for (auto tag : el.tags)
|
for (auto tag : el.tags)
|
||||||
if (&(*tag) == m_hovertag)
|
if (&(*tag) == m_hovertag)
|
||||||
@ -992,9 +1022,9 @@ void TextDrawer::draw(const core::rect<s32> &clip_rect,
|
|||||||
m_tsrc->getTexture(
|
m_tsrc->getTexture(
|
||||||
stringw_to_utf8(el.text));
|
stringw_to_utf8(el.text));
|
||||||
if (texture != 0)
|
if (texture != 0)
|
||||||
m_guienv->getVideoDriver()->draw2DImage(
|
driver->draw2DImage(
|
||||||
texture, rect,
|
texture, rect,
|
||||||
irr::core::rect<s32>(
|
core::rect<s32>(
|
||||||
core::position2d<s32>(0, 0),
|
core::position2d<s32>(0, 0),
|
||||||
texture->getOriginalSize()),
|
texture->getOriginalSize()),
|
||||||
&clip_rect, 0, true);
|
&clip_rect, 0, true);
|
||||||
@ -1006,7 +1036,7 @@ void TextDrawer::draw(const core::rect<s32> &clip_rect,
|
|||||||
ItemStack item;
|
ItemStack item;
|
||||||
item.deSerialize(stringw_to_utf8(el.text), idef);
|
item.deSerialize(stringw_to_utf8(el.text), idef);
|
||||||
|
|
||||||
drawItemStack(m_guienv->getVideoDriver(),
|
drawItemStack(driver,
|
||||||
g_fontengine->getFont(), item, rect, &clip_rect, m_client,
|
g_fontengine->getFont(), item, rect, &clip_rect, m_client,
|
||||||
IT_ROT_OTHER, el.angle, el.rotation);
|
IT_ROT_OTHER, el.angle, el.rotation);
|
||||||
}
|
}
|
||||||
@ -1032,13 +1062,13 @@ GUIHyperText::GUIHyperText(const wchar_t *text, IGUIEnvironment *environment,
|
|||||||
setDebugName("GUIHyperText");
|
setDebugName("GUIHyperText");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
IGUISkin *skin = 0;
|
IGUISkin *skin = nullptr;
|
||||||
if (Environment)
|
if (Environment)
|
||||||
skin = Environment->getSkin();
|
skin = Environment->getSkin();
|
||||||
|
|
||||||
m_scrollbar_width = skin ? skin->getSize(gui::EGDS_SCROLLBAR_SIZE) : 16;
|
m_scrollbar_width = skin ? skin->getSize(gui::EGDS_SCROLLBAR_SIZE) : 16;
|
||||||
|
|
||||||
core::rect<s32> rect = irr::core::rect<s32>(
|
core::rect<s32> rect = core::rect<s32>(
|
||||||
RelativeRect.getWidth() - m_scrollbar_width, 0,
|
RelativeRect.getWidth() - m_scrollbar_width, 0,
|
||||||
RelativeRect.getWidth(), RelativeRect.getHeight());
|
RelativeRect.getWidth(), RelativeRect.getHeight());
|
||||||
|
|
||||||
@ -1084,6 +1114,25 @@ void GUIHyperText::checkHover(s32 X, s32 Y)
|
|||||||
cursor_control->setActiveIcon(m_drawer.m_hovertag ? gui::ECI_HAND : gui::ECI_NORMAL);
|
cursor_control->setActiveIcon(m_drawer.m_hovertag ? gui::ECI_HAND : gui::ECI_NORMAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GUIHyperText::setStyles(const std::array<StyleSpec, StyleSpec::NUM_STATES> &styles)
|
||||||
|
{
|
||||||
|
StyleSpec::State state = StyleSpec::STATE_DEFAULT;
|
||||||
|
StyleSpec style = StyleSpec::getStyleFromStatePropagation(styles, state);
|
||||||
|
|
||||||
|
ParsedText &text = m_drawer.getText();
|
||||||
|
text.background_middle = style.getRect(StyleSpec::BGIMG_MIDDLE, core::rect<s32>());
|
||||||
|
text.border = style.getBool(StyleSpec::BORDER, true);
|
||||||
|
setNotClipped(style.getBool(StyleSpec::NOCLIP, true));
|
||||||
|
|
||||||
|
if (text.background_type != text.BackgroundType::BACKGROUND_COLOR) {
|
||||||
|
text.background_type = text.BackgroundType::BACKGROUND_COLOR;
|
||||||
|
text.background_color = style.getColor(StyleSpec::BGCOLOR, video::SColor(255,110,130,60));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (style.isNotDefault(StyleSpec::BGIMG))
|
||||||
|
text.background_image = style.getTexture(StyleSpec::BGIMG, m_tsrc);
|
||||||
|
}
|
||||||
|
|
||||||
bool GUIHyperText::OnEvent(const SEvent &event)
|
bool GUIHyperText::OnEvent(const SEvent &event)
|
||||||
{
|
{
|
||||||
// Scroll bar
|
// Scroll bar
|
||||||
@ -1187,8 +1236,11 @@ void GUIHyperText::draw()
|
|||||||
m_vscrollbar->setPos(0);
|
m_vscrollbar->setPos(0);
|
||||||
m_vscrollbar->setVisible(false);
|
m_vscrollbar->setVisible(false);
|
||||||
}
|
}
|
||||||
|
if (m_drawer_ready) {
|
||||||
m_drawer.draw(AbsoluteClippingRect,
|
m_drawer.draw(AbsoluteClippingRect,
|
||||||
m_display_text_rect.UpperLeftCorner + m_text_scrollpos);
|
m_display_text_rect.UpperLeftCorner + m_text_scrollpos);
|
||||||
|
} else
|
||||||
|
m_drawer_ready = true;
|
||||||
|
|
||||||
// draw children
|
// draw children
|
||||||
IGUIElement::draw();
|
IGUIElement::draw();
|
||||||
|
@ -24,8 +24,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include "irrlichttypes_extrabloated.h"
|
#include "irrlichttypes_extrabloated.h"
|
||||||
|
#include "StyleSpec.h"
|
||||||
using namespace irr;
|
|
||||||
|
|
||||||
class ISimpleTextureSource;
|
class ISimpleTextureSource;
|
||||||
class Client;
|
class Client;
|
||||||
@ -99,8 +98,8 @@ class ParsedText
|
|||||||
|
|
||||||
gui::IGUIFont *font;
|
gui::IGUIFont *font;
|
||||||
|
|
||||||
irr::video::SColor color;
|
video::SColor color;
|
||||||
irr::video::SColor hovercolor;
|
video::SColor hovercolor;
|
||||||
bool underline;
|
bool underline;
|
||||||
|
|
||||||
s32 baseline = 0;
|
s32 baseline = 0;
|
||||||
@ -130,7 +129,10 @@ class ParsedText
|
|||||||
s32 margin = 3;
|
s32 margin = 3;
|
||||||
ValignType valign = VALIGN_TOP;
|
ValignType valign = VALIGN_TOP;
|
||||||
BackgroundType background_type = BACKGROUND_NONE;
|
BackgroundType background_type = BACKGROUND_NONE;
|
||||||
irr::video::SColor background_color;
|
video::SColor background_color;
|
||||||
|
video::ITexture *background_image = nullptr;
|
||||||
|
core::rect<s32> background_middle;
|
||||||
|
bool border = false;
|
||||||
|
|
||||||
Tag m_root_tag;
|
Tag m_root_tag;
|
||||||
|
|
||||||
@ -177,6 +179,8 @@ class TextDrawer
|
|||||||
inline s32 getHeight() { return m_height; };
|
inline s32 getHeight() { return m_height; };
|
||||||
void draw(const core::rect<s32> &clip_rect,
|
void draw(const core::rect<s32> &clip_rect,
|
||||||
const core::position2d<s32> &dest_offset);
|
const core::position2d<s32> &dest_offset);
|
||||||
|
void drawBackgroundImage(video::IVideoDriver *driver, const ParsedText &m_text, const core::rect<s32> &clip_rect);
|
||||||
|
ParsedText &getText() { return m_text; }
|
||||||
ParsedText::Element *getElementAt(core::position2d<s32> pos);
|
ParsedText::Element *getElementAt(core::position2d<s32> pos);
|
||||||
ParsedText::Tag *m_hovertag;
|
ParsedText::Tag *m_hovertag;
|
||||||
|
|
||||||
@ -211,10 +215,13 @@ class GUIHyperText : public gui::IGUIElement
|
|||||||
//! draws the element and its children
|
//! draws the element and its children
|
||||||
virtual void draw();
|
virtual void draw();
|
||||||
|
|
||||||
core::dimension2du getTextDimension();
|
//! Returns the height of the text in pixels when it is drawn.
|
||||||
|
s32 getTextHeight() { return m_drawer.getHeight(); }
|
||||||
|
|
||||||
bool OnEvent(const SEvent &event);
|
bool OnEvent(const SEvent &event);
|
||||||
|
|
||||||
|
void setStyles(const std::array<StyleSpec, StyleSpec::NUM_STATES> &styles);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// GUI members
|
// GUI members
|
||||||
ISimpleTextureSource *m_tsrc;
|
ISimpleTextureSource *m_tsrc;
|
||||||
@ -228,4 +235,6 @@ class GUIHyperText : public gui::IGUIElement
|
|||||||
|
|
||||||
ParsedText::Element *getElementAt(s32 X, s32 Y);
|
ParsedText::Element *getElementAt(s32 X, s32 Y);
|
||||||
void checkHover(s32 X, s32 Y);
|
void checkHover(s32 X, s32 Y);
|
||||||
|
|
||||||
|
bool m_drawer_ready = false;
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user