Skip to content

Commit 25edae0

Browse files
committedNov 3, 2013
Reworked formspecs and kahrl's hexcolor parser
1 parent 0b78889 commit 25edae0

File tree

5 files changed

+259
-69
lines changed

5 files changed

+259
-69
lines changed
 

Diff for: ‎builtin/mm_menubar.lua

+2-2
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,8 @@ end
3030

3131
--------------------------------------------------------------------------------
3232
function menubar.refresh()
33-
menubar.formspec = "box[-0.3,5.625;12.4,1.3;000000]" ..
34-
"box[-0.3,5.6;12.4,0.05;FFFFFF]"
33+
menubar.formspec = "box[-0.3,5.625;12.4,1.3;#000000]" ..
34+
"box[-0.3,5.6;12.4,0.05;#FFFFFF]"
3535
menubar.buttons = {}
3636

3737
local button_base = -0.25

Diff for: ‎builtin/modstore.lua

+3-3
Original file line numberDiff line numberDiff line change
@@ -183,9 +183,9 @@ function modstore.getmodlist(list)
183183
retval = retval .. "label[10,-0.4;" .. fgettext("Page $1 of $2", list.page+1, list.pagecount) .. "]"
184184

185185
retval = retval .. "button[11.6,-0.1;0.5,0.5;btn_modstore_page_up;^]"
186-
retval = retval .. "box[11.6,0.35;0.28,8.6;000000]"
186+
retval = retval .. "box[11.6,0.35;0.28,8.6;#000000]"
187187
local scrollbarpos = 0.35 + (8.1/(list.pagecount-1)) * list.page
188-
retval = retval .. "box[11.6," ..scrollbarpos .. ";0.28,0.5;32CD32]"
188+
retval = retval .. "box[11.6," ..scrollbarpos .. ";0.28,0.5;#32CD32]"
189189
retval = retval .. "button[11.6,9.0;0.5,0.5;btn_modstore_page_down;v]"
190190

191191

@@ -206,7 +206,7 @@ function modstore.getmodlist(list)
206206
if details ~= nil then
207207
local screenshot_ypos = (i-1 - (list.page * modstore.modsperpage))*1.9 +0.2
208208

209-
retval = retval .. "box[0," .. screenshot_ypos .. ";11.4,1.75;FFFFFF]"
209+
retval = retval .. "box[0," .. screenshot_ypos .. ";11.4,1.75;#FFFFFF]"
210210

211211
--screenshot
212212
if details.screenshot_url ~= nil and

Diff for: ‎doc/lua_api.txt

+41-4
Original file line numberDiff line numberDiff line change
@@ -873,6 +873,22 @@ list[<inventory location>;<list name>;<X>,<Y>;<W>,<H>;]
873873
list[<inventory location>;<list name>;<X>,<Y>;<W>,<H>;<starting item index>]
874874
^ Show an inventory list
875875

876+
listcolors[<slot_bg_normal>;<slot_bg_hover>]
877+
^ Sets background color of slots in HEX-Color format
878+
^ Sets background color of slots on mouse hovering
879+
880+
listcolors[<slot_bg_normal>;<slot_bg_hover>;<slot_border>]
881+
^ Sets background color of slots in HEX-Color format
882+
^ Sets background color of slots on mouse hovering
883+
^ Sets color of slots border
884+
885+
listcolors[<slot_bg_normal>;<slot_bg_hover>;<slot_border>;<tooltip_bgcolor>;<tooltip_fontcolor>]
886+
^ Sets background color of slots in HEX-Color format
887+
^ Sets background color of slots on mouse hovering
888+
^ Sets color of slots border
889+
^ Sets background color of tooltips
890+
^ Sets font color of tooltips
891+
876892
image[<X>,<Y>;<W>,<H>;<texture name>]
877893
^ Show an image
878894
^ Position and size units are inventory slots
@@ -881,11 +897,21 @@ item_image[<X>,<Y>;<W>,<H>;<item name>]
881897
^ Show an inventory image of registered item/node
882898
^ Position and size units are inventory slots
883899

900+
bgcolor[<color>;<fullscreen>]
901+
^ Sets background color of formspec in HEX-Color format
902+
^ If true the background color is drawn fullscreen (does not effect the size of the formspec)
903+
884904
background[<X>,<Y>;<W>,<H>;<texture name>]
885905
^ Use a background. Inventory rectangles are not drawn then.
886906
^ Position and size units are inventory slots
887907
^ Example for formspec 8x4 in 16x resolution: image shall be sized 8*16px x 4*16px
888908

909+
background[<X>,<Y>;<W>,<H>;<texture name>;<auto_clip>]
910+
^ Use a background. Inventory rectangles are not drawn then.
911+
^ Position and size units are inventory slots
912+
^ Example for formspec 8x4 in 16x resolution: image shall be sized 8*16px x 4*16px
913+
^ If true the background is clipped to formspec size (x and y are used as offset values, w and h are ignored)
914+
889915
pwdfield[<X>,<Y>;<W>,<H>;<name>;<label>]
890916
^ Textual password style field; will be sent to server when a button is clicked
891917
^ x and y position the field relative to the top left of the menu
@@ -972,15 +998,15 @@ textlist[<X>,<Y>;<W>,<H>;<name>;<listelem 1>,<listelem 2>,...,<listelem n>]
972998
^ x and y position the itemlist relative to the top left of the menu
973999
^ w and h are the size of the itemlist
9741000
^ name fieldname sent to server on doubleclick value is current selected element
975-
^ listelements can be prepended by #color in hexadecimal format RRGGBB,
1001+
^ listelements can be prepended by #color in hexadecimal format RRGGBB (only),
9761002
^ if you want a listelement to start with # write ##
9771003

9781004
textlist[<X>,<Y>;<W>,<H>;<name>;<listelem 1>,<listelem 2>,...,<listelem n>;<selected idx>;<transparent>]
9791005
^Scrollabel itemlist showing arbitrary text elements
9801006
^ x and y position the itemlist relative to the top left of the menu
9811007
^ w and h are the size of the itemlist
9821008
^ name fieldname sent to server on doubleclick value is current selected element
983-
^ listelements can be prepended by #RRGGBB in hexadecimal format
1009+
^ listelements can be prepended by #RRGGBB (only) in hexadecimal format
9841010
^ if you want a listelement to start with # write ##
9851011
^ index to be selected within textlist
9861012
^ true/false draw transparent background
@@ -998,7 +1024,7 @@ box[<X>,<Y>;<W>,<H>;<color>]
9981024
^ simple colored semitransparent box
9991025
^ x and y position the box relative to the top left of the menu
10001026
^ w and h are the size of box
1001-
^ color in hexadecimal format RRGGBB
1027+
^ color in HEX-Color format
10021028

10031029
dropdown[<X>,<Y>;<W>;<name>;<item 1>,<item 2>, ...,<item n>;<selected idx>]
10041030
^ show a dropdown field
@@ -1007,7 +1033,7 @@ dropdown[<X>,<Y>;<W>;<name>;<item 1>,<item 2>, ...,<item n>;<selected idx>]
10071033
^ fieldname data is transfered to lua
10081034
^ items to be shown in dropdown
10091035
^ index of currently selected dropdown item
1010-
^ color in hexadecimal format RRGGBB
1036+
^ color in hexadecimal format RRGGBB (only)
10111037

10121038
checkbox[<X>,<Y>;<name>;<label>;<selected>]
10131039
^ show a checkbox
@@ -1027,6 +1053,17 @@ Inventory location:
10271053
- "nodemeta:<X>,<Y>,<Z>": Any node metadata
10281054
- "detached:<name>": A detached inventory
10291055

1056+
HEX-Color
1057+
---------
1058+
#RGB
1059+
^ defines a color in hexadecimal format
1060+
#RGBA
1061+
^ defines a color in hexadecimal format and alpha channel
1062+
#RRGGBB
1063+
^ defines a color in hexadecimal format
1064+
#RRGGBBAA
1065+
^ defines a color in hexadecimal format and alpha channel
1066+
10301067
Vector helpers
10311068
---------------
10321069
vector.new([x[, y, z]]) -> vector

Diff for: ‎src/guiFormSpecMenu.cpp

+202-59
Original file line numberDiff line numberDiff line change
@@ -604,7 +604,7 @@ void GUIFormSpecMenu::parseButton(parserData* data,std::string element,std::stri
604604
void GUIFormSpecMenu::parseBackground(parserData* data,std::string element) {
605605
std::vector<std::string> parts = split(element,';');
606606

607-
if (parts.size() == 3) {
607+
if ((parts.size() == 3) || (parts.size() == 4)) {
608608
std::vector<std::string> v_pos = split(parts[0],',');
609609
std::vector<std::string> v_geom = split(parts[1],',');
610610
std::string name = unescape_string(parts[2]);
@@ -620,6 +620,14 @@ void GUIFormSpecMenu::parseBackground(parserData* data,std::string element) {
620620
geom.X = stof(v_geom[0]) * (float)spacing.X;
621621
geom.Y = stof(v_geom[1]) * (float)spacing.Y;
622622

623+
if (parts.size() == 4) {
624+
m_clipbackground = is_yes(parts[3]);
625+
if (m_clipbackground) {
626+
pos.X = stoi(v_pos[0]); //acts as offset
627+
pos.Y = stoi(v_pos[1]); //acts as offset
628+
}
629+
}
630+
623631
if(data->bp_set != 2)
624632
errorstream<<"WARNING: invalid use of background without a size[] element"<<std::endl;
625633
m_backgrounds.push_back(ImageDrawSpec(name, pos, geom));
@@ -686,16 +694,16 @@ void GUIFormSpecMenu::parseTextList(parserData* data,std::string element) {
686694
e->addItem(narrow_to_wide(unescape_string(items[i])).c_str() +1);
687695
}
688696
else {
689-
std::string color = items[i].substr(1,6);
697+
std::string color = items[i].substr(0,7);
690698
std::wstring toadd =
691699
narrow_to_wide(unescape_string(items[i]).c_str() + 7);
692700

693701
e->addItem(toadd.c_str());
694702

695-
irr::video::SColor toset;
703+
video::SColor tmp_color;
696704

697-
if (parseColor(color, toset))
698-
e->setItemOverrideColor(i,toset);
705+
if (parseColor(color, tmp_color, false))
706+
e->setItemOverrideColor(i,tmp_color);
699707
}
700708
}
701709
else {
@@ -1329,7 +1337,6 @@ void GUIFormSpecMenu::parseBox(parserData* data,std::string element) {
13291337
if (parts.size() == 3) {
13301338
std::vector<std::string> v_pos = split(parts[0],',');
13311339
std::vector<std::string> v_geom = split(parts[1],',');
1332-
std::string color_str = parts[2];
13331340

13341341
MY_CHECKPOS("box",0);
13351342
MY_CHECKGEOM("box",1);
@@ -1342,10 +1349,10 @@ void GUIFormSpecMenu::parseBox(parserData* data,std::string element) {
13421349
geom.X = stof(v_geom[0]) * (float)spacing.X;
13431350
geom.Y = stof(v_geom[1]) * (float)spacing.Y;
13441351

1345-
irr::video::SColor color;
1352+
video::SColor tmp_color;
13461353

1347-
if (parseColor(color_str, color)) {
1348-
BoxDrawSpec spec(pos,geom,color);
1354+
if (parseColor(parts[2], tmp_color, false)) {
1355+
BoxDrawSpec spec(pos, geom, tmp_color);
13491356

13501357
m_boxes.push_back(spec);
13511358
}
@@ -1357,6 +1364,46 @@ void GUIFormSpecMenu::parseBox(parserData* data,std::string element) {
13571364
errorstream<< "Invalid Box element(" << parts.size() << "): '" << element << "'" << std::endl;
13581365
}
13591366

1367+
void GUIFormSpecMenu::parseBackgroundColor(parserData* data,std::string element) {
1368+
std::vector<std::string> parts = split(element,';');
1369+
1370+
if ((parts.size() == 1) || (parts.size() == 2)) {
1371+
parseColor(parts[0],m_bgcolor,false);
1372+
1373+
if (parts.size() == 2) {
1374+
std::string fullscreen = parts[1];
1375+
m_bgfullscreen = is_yes(fullscreen);
1376+
}
1377+
return;
1378+
}
1379+
errorstream<< "Invalid bgcolor element(" << parts.size() << "): '" << element << "'" << std::endl;
1380+
}
1381+
1382+
void GUIFormSpecMenu::parseListColors(parserData* data,std::string element) {
1383+
std::vector<std::string> parts = split(element,';');
1384+
1385+
if (parts.size() == 2) || (parts.size() == 3) || (parts.size() == 5)) {
1386+
parseColor(parts[0], m_slotbg_n, false);
1387+
parseColor(parts[1], m_slotbg_h, false);
1388+
1389+
if (parts.size() >= 3) {
1390+
if (parseColor(parts[2], m_slotbordercolor, false)) {
1391+
m_slotborder = true;
1392+
}
1393+
}
1394+
if (parts.size() == 5) {
1395+
video::SColor tmp_color;
1396+
1397+
if (parseColor(parts[3], tmp_color, false))
1398+
m_tooltip_element->setBackgroundColor(tmp_color);
1399+
if (parseColor(parts[4], tmp_color, false))
1400+
m_tooltip_element->setOverrideColor(tmp_color);
1401+
}
1402+
return;
1403+
}
1404+
errorstream<< "Invalid listcolors element(" << parts.size() << "): '" << element << "'" << std::endl;
1405+
}
1406+
13601407
void GUIFormSpecMenu::parseElement(parserData* data,std::string element) {
13611408

13621409
//some prechecks
@@ -1467,6 +1514,16 @@ void GUIFormSpecMenu::parseElement(parserData* data,std::string element) {
14671514
return;
14681515
}
14691516

1517+
if (type == "bgcolor") {
1518+
parseBackgroundColor(data,description);
1519+
return;
1520+
}
1521+
1522+
if (type == "listcolors") {
1523+
parseListColors(data,description);
1524+
return;
1525+
}
1526+
14701527
// Ignore others
14711528
infostream
14721529
<< "Unknown DrawSpec: type="<<type<<", data=\""<<description<<"\""
@@ -1537,25 +1594,39 @@ void GUIFormSpecMenu::regenerateGui(v2u32 screensize)
15371594
m_fields.clear();
15381595
m_boxes.clear();
15391596

1597+
// Set default values (fits old formspec values)
1598+
m_bgcolor = video::SColor(140,0,0,0);
1599+
m_bgfullscreen = false;
1600+
1601+
m_slotbg_n = video::SColor(255,128,128,128);
1602+
m_slotbg_h = video::SColor(255,192,192,192);
1603+
1604+
m_slotbordercolor = video::SColor(200,0,0,0);
1605+
m_slotborder = false;
1606+
1607+
m_clipbackground = false;
1608+
// Add tooltip
1609+
{
1610+
// Note: parent != this so that the tooltip isn't clipped by the menu rectangle
1611+
m_tooltip_element = Environment->addStaticText(L"",core::rect<s32>(0,0,110,18));
1612+
m_tooltip_element->enableOverrideColor(true);
1613+
m_tooltip_element->setBackgroundColor(video::SColor(255,110,130,60));
1614+
m_tooltip_element->setDrawBackground(true);
1615+
m_tooltip_element->setDrawBorder(true);
1616+
m_tooltip_element->setOverrideColor(video::SColor(255,255,255,255));
1617+
m_tooltip_element->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_CENTER);
1618+
m_tooltip_element->setWordWrap(false);
1619+
//we're not parent so no autograb for this one!
1620+
m_tooltip_element->grab();
1621+
}
1622+
15401623

15411624
std::vector<std::string> elements = split(m_formspec_string,']');
15421625

15431626
for (unsigned int i=0;i< elements.size();i++) {
15441627
parseElement(&mydata,elements[i]);
15451628
}
15461629

1547-
// If there's inventory, put the usage string at the bottom
1548-
if (m_inventorylists.size())
1549-
{
1550-
changeCtype("");
1551-
core::rect<s32> rect(0, 0, mydata.size.X-padding.X*2, mydata.helptext_h);
1552-
rect = rect + v2s32((mydata.size.X/2 - mydata.rect.getWidth()/2) +5,
1553-
mydata.size.Y-5-mydata.helptext_h);
1554-
const wchar_t *text = wgettext("Left click: Move all items, Right click: Move single item");
1555-
Environment->addStaticText(text, rect, false, true, this, 256);
1556-
delete[] text;
1557-
changeCtype("C");
1558-
}
15591630
// If there's fields, add a Proceed button
15601631
if (m_fields.size() && mydata.bp_set != 2)
15611632
{
@@ -1583,20 +1654,6 @@ void GUIFormSpecMenu::regenerateGui(v2u32 screensize)
15831654
}
15841655
changeCtype("C");
15851656
}
1586-
// Add tooltip
1587-
{
1588-
// Note: parent != this so that the tooltip isn't clipped by the menu rectangle
1589-
m_tooltip_element = Environment->addStaticText(L"",core::rect<s32>(0,0,110,18));
1590-
m_tooltip_element->enableOverrideColor(true);
1591-
m_tooltip_element->setBackgroundColor(video::SColor(255,110,130,60));
1592-
m_tooltip_element->setDrawBackground(true);
1593-
m_tooltip_element->setDrawBorder(true);
1594-
m_tooltip_element->setOverrideColor(video::SColor(255,255,255,255));
1595-
m_tooltip_element->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_CENTER);
1596-
m_tooltip_element->setWordWrap(false);
1597-
//we're not parent so no autograb for this one!
1598-
m_tooltip_element->grab();
1599-
}
16001657

16011658
//set initial focus if parser didn't set it
16021659
focused_element = Environment->getFocus();
@@ -1681,16 +1738,31 @@ void GUIFormSpecMenu::drawList(const ListDrawSpec &s, int phase)
16811738

16821739
if(phase == 0)
16831740
{
1684-
if(hovering && m_selected_item)
1685-
{
1686-
video::SColor bgcolor(255,192,192,192);
1687-
driver->draw2DRectangle(bgcolor, rect, &AbsoluteClippingRect);
1688-
}
1741+
if(hovering)
1742+
driver->draw2DRectangle(m_slotbg_h, rect, &AbsoluteClippingRect);
16891743
else
1690-
{
1691-
video::SColor bgcolor(255,128,128,128);
1692-
driver->draw2DRectangle(bgcolor, rect, &AbsoluteClippingRect);
1693-
}
1744+
driver->draw2DRectangle(m_slotbg_n, rect, &AbsoluteClippingRect);
1745+
}
1746+
1747+
//Draw inv slot borders
1748+
if (m_slotborder) {
1749+
s32 x1 = rect.UpperLeftCorner.X;
1750+
s32 y1 = rect.UpperLeftCorner.Y;
1751+
s32 x2 = rect.LowerRightCorner.X;
1752+
s32 y2 = rect.LowerRightCorner.Y;
1753+
s32 border = 1;
1754+
driver->draw2DRectangle(m_slotbordercolor,
1755+
core::rect<s32>(v2s32(x1 - border, y1 - border),
1756+
v2s32(x2 + border, y1)), NULL);
1757+
driver->draw2DRectangle(m_slotbordercolor,
1758+
core::rect<s32>(v2s32(x1 - border, y2),
1759+
v2s32(x2 + border, y2 + border)), NULL);
1760+
driver->draw2DRectangle(m_slotbordercolor,
1761+
core::rect<s32>(v2s32(x1 - border, y1),
1762+
v2s32(x1, y2)), NULL);
1763+
driver->draw2DRectangle(m_slotbordercolor,
1764+
core::rect<s32>(v2s32(x2, y1),
1765+
v2s32(x2 + border, y2)), NULL);
16941766
}
16951767

16961768
if(phase == 1)
@@ -1771,8 +1843,12 @@ void GUIFormSpecMenu::drawMenu()
17711843
return;
17721844
video::IVideoDriver* driver = Environment->getVideoDriver();
17731845

1774-
video::SColor bgcolor(140,0,0,0);
1775-
driver->draw2DRectangle(bgcolor, AbsoluteRect, &AbsoluteClippingRect);
1846+
v2u32 screenSize = driver->getScreenSize();
1847+
core::rect<s32> allbg(0, 0, screenSize.X , screenSize.Y);
1848+
if (m_bgfullscreen)
1849+
driver->draw2DRectangle(m_bgcolor, allbg, &allbg);
1850+
else
1851+
driver->draw2DRectangle(m_bgcolor, AbsoluteRect, &AbsoluteClippingRect);
17761852

17771853
m_tooltip_element->setVisible(false);
17781854

@@ -1789,6 +1865,15 @@ void GUIFormSpecMenu::drawMenu()
17891865
core::rect<s32> imgrect(0, 0, spec.geom.X, spec.geom.Y);
17901866
// Image rectangle on screen
17911867
core::rect<s32> rect = imgrect + spec.pos;
1868+
1869+
if (m_clipbackground) {
1870+
core::dimension2d<s32> absrec_size = AbsoluteRect.getSize();
1871+
rect = core::rect<s32>(AbsoluteRect.UpperLeftCorner.X - spec.pos.X,
1872+
AbsoluteRect.UpperLeftCorner.Y - spec.pos.Y,
1873+
AbsoluteRect.UpperLeftCorner.X + absrec_size.Width + spec.pos.X*2,
1874+
AbsoluteRect.UpperLeftCorner.Y + absrec_size.Height + spec.pos.Y*2);
1875+
}
1876+
17921877
const video::SColor color(255,255,255,255);
17931878
const video::SColor colors[] = {color,color,color,color};
17941879
driver->draw2DImage(texture, rect,
@@ -1880,10 +1965,8 @@ void GUIFormSpecMenu::drawMenu()
18801965
Draw items
18811966
Phase 0: Item slot rectangles
18821967
Phase 1: Item images; prepare tooltip
1883-
If backgrounds used, do not draw Item slot rectangles
18841968
*/
18851969
int start_phase=0;
1886-
if (m_backgrounds.size() > 0) start_phase=1;
18871970
for(int phase=start_phase; phase<=1; phase++)
18881971
for(u32 i=0; i<m_inventorylists.size(); i++)
18891972
{
@@ -2643,18 +2726,78 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event)
26432726
return Parent ? Parent->OnEvent(event) : false;
26442727
}
26452728

2646-
bool GUIFormSpecMenu::parseColor(std::string color, irr::video::SColor& outcolor) {
2647-
outcolor = irr::video::SColor(0,0,0,0);
2648-
2649-
if (!string_allowed(color, "0123456789abcdefABCDEF"))
2729+
static inline bool hex_digit_decode(char hexdigit, unsigned char &value)
2730+
{
2731+
if(hexdigit >= '0' && hexdigit <= '9')
2732+
value = hexdigit - '0';
2733+
else if(hexdigit >= 'A' && hexdigit <= 'F')
2734+
value = hexdigit - 'A' + 10;
2735+
else if(hexdigit >= 'a' && hexdigit <= 'f')
2736+
value = hexdigit - 'a' + 10;
2737+
else
26502738
return false;
2739+
return true;
2740+
}
26512741

2652-
u32 color_value;
2653-
std::istringstream iss(color);
2654-
iss >> std::hex >> color_value;
2655-
2656-
outcolor = irr::video::SColor(color_value);
2742+
bool GUIFormSpecMenu::parseColor(std::string &value, video::SColor &color, bool quiet)
2743+
{
2744+
const char *hexpattern = NULL;
2745+
if (value[0] == '#') {
2746+
if (value.size() == 9)
2747+
hexpattern = "#RRGGBBAA";
2748+
else if (value.size() == 7)
2749+
hexpattern = "#RRGGBB";
2750+
else if (value.size() == 5)
2751+
hexpattern = "#RGBA";
2752+
else if (value.size() == 4)
2753+
hexpattern = "#RGB";
2754+
}
2755+
2756+
if (hexpattern) {
2757+
assert(strlen(hexpattern) == value.size());
2758+
video::SColor outcolor(255, 255, 255, 255);
2759+
for (size_t pos = 0; pos < value.size(); ++pos) {
2760+
// '#' in the pattern means skip that character
2761+
if (hexpattern[pos] == '#')
2762+
continue;
26572763

2658-
outcolor.setAlpha(255);
2659-
return true;
2764+
// Else assume hexpattern[pos] is one of 'R' 'G' 'B' 'A'
2765+
// Read one or two digits, depending on hexpattern
2766+
unsigned char c1, c2;
2767+
if (hexpattern[pos+1] == hexpattern[pos]) {
2768+
// Two digits, e.g. hexpattern == "#RRGGBB"
2769+
if (!hex_digit_decode(value[pos], c1) ||
2770+
!hex_digit_decode(value[pos+1], c2))
2771+
goto fail;
2772+
++pos;
2773+
}
2774+
else {
2775+
// One digit, e.g. hexpattern == "#RGB"
2776+
if (!hex_digit_decode(value[pos], c1))
2777+
goto fail;
2778+
c2 = c1;
2779+
}
2780+
u32 colorpart = ((c1 & 0x0f) << 4) | (c2 & 0x0f);
2781+
2782+
// Update outcolor with newly read color part
2783+
if (hexpattern[pos] == 'R')
2784+
outcolor.setRed(colorpart);
2785+
else if (hexpattern[pos] == 'G')
2786+
outcolor.setGreen(colorpart);
2787+
else if (hexpattern[pos] == 'B')
2788+
outcolor.setBlue(colorpart);
2789+
else if (hexpattern[pos] == 'A')
2790+
outcolor.setAlpha(colorpart);
2791+
}
2792+
2793+
color = outcolor;
2794+
return true;
2795+
}
2796+
2797+
// Optionally, named colors could be implemented here
2798+
2799+
fail:
2800+
if (!quiet)
2801+
errorstream<<"Invalid color: \""<<value<<"\""<<std::endl;
2802+
return false;
26602803
}

Diff for: ‎src/guiFormSpecMenu.h

+11-1
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,14 @@ class GUIFormSpecMenu : public GUIModalMenu
285285
bool m_allowclose;
286286
bool m_lock;
287287
v2u32 m_lockscreensize;
288+
289+
bool m_bgfullscreen;
290+
bool m_slotborder;
291+
bool m_clipbackground;
292+
video::SColor m_bgcolor;
293+
video::SColor m_slotbg_n;
294+
video::SColor m_slotbg_h;
295+
video::SColor m_slotbordercolor;
288296
private:
289297
typedef struct {
290298
v2s32 size;
@@ -334,8 +342,10 @@ class GUIFormSpecMenu : public GUIModalMenu
334342
void parseItemImageButton(parserData* data,std::string element);
335343
void parseTabHeader(parserData* data,std::string element);
336344
void parseBox(parserData* data,std::string element);
345+
void parseBackgroundColor(parserData* data,std::string element);
346+
void parseListColors(parserData* data,std::string element);
337347

338-
bool parseColor(std::string color, irr::video::SColor& outcolor);
348+
bool parseColor(std::string &value, video::SColor &color, bool quiet);
339349
};
340350

341351
class FormspecFormSource: public IFormSource

0 commit comments

Comments
 (0)
Please sign in to comment.