#include <cstdlib>
#include <algorithm>
#include <iterator>
-#include <sstream>
#include <limits>
+#include <sstream>
#include "guiFormSpecMenu.h"
#include "constants.h"
#include "gamedef.h"
"",
L"",
L"",
- 258 + m_fields.size()
+ 258 + m_fields.size(),
+ 3
);
v2s32 pos;
name,
L"",
L"",
- 258 + m_fields.size()
+ 258 + m_fields.size(),
+ 1
);
core::rect<s32> rect(pos, pos + geom);
gui::IGUIImage *e = Environment->addImage(rect, this, spec.fid, 0, true);
"",
L"",
L"",
- 258 + m_fields.size()
+ 258 + m_fields.size(),
+ 2
);
spec.ftype = f_ItemImage;
"",
wlabel_colors,
L"",
- 258 + m_fields.size()
+ 258 + m_fields.size(),
+ 4
);
gui::IGUIStaticText *e = gui::StaticText::add(Environment,
spec.flabel.c_str(), rect, false, false, this, spec.fid);
name,
utf8_to_wide(label),
utf8_to_wide(item_name),
- 258 + m_fields.size()
+ 258 + m_fields.size(),
+ 2
);
gui::IGUIButton *e_btn = GUIButton::addButton(Environment, rect, this, spec_btn.fid, L"");
// the spec for the item-image
FieldSpec spec_img(
- "",
+ name,
L"",
L"",
- 258 + m_fields.size()
+ 258 + m_fields.size(),
+ 2
);
GUIItemImage *e_img = new GUIItemImage(Environment, e_btn, spec_img.fid,
"",
L"",
L"",
- 258 + m_fields.size()
+ 258 + m_fields.size(),
+ -2
);
spec.ftype = f_Box;
void GUIFormSpecMenu::legacySortElements(core::list<IGUIElement *>::Iterator from)
{
/*
- * The order was:
- * (0. background colors and backgrounds)
- * 1. boxes
- * 2. all normal elements (like buttons)
- * 3. images
- * 4. item images
- * 5. item lists (TODO)
- */
+ Draw order for formspec_version <= 2:
+ -3 bgcolor
+ -2 background
+ -1 box
+ 0 All other elements
+ 1 image
+ 2 item_image, item_image_button
+ 3 list
+ 4 label
+ */
if (from == Children.end())
from = Children.begin();
from++;
core::list<IGUIElement *>::Iterator to = Children.end();
-
- // step 1: move all boxes to back and all images to front
- // (drawn in back = drawn first = in front of list)
- for (auto i = from; i != to;) {
- if (getTypeByID((*i)->getID()) == f_Box && i != from) {
- auto e = *i;
- i = Children.erase(i);
- Children.insert_before(from, e);
- } else if ((*i)->hasType(gui::EGUIET_IMAGE)) {
- auto e = *i;
- i = Children.erase(i);
- Children.push_back(e);
- if (to == Children.end())
- to = Children.getLast(); // do not touch sorted back
- if (i == Children.end())
- break;
- } else {
- i++;
- }
- }
-
- // step 2: move all item images to front
- for (auto i = from; i != to;) {
- if (getTypeByID((*i)->getID()) == f_ItemImage) {
- auto e = *i;
- i = Children.erase(i);
- Children.push_back(e);
- if (to == Children.end())
- to = Children.getLast(); // do not touch sorted back
- if (i == Children.end())
- break;
- } else {
- i++;
- }
+ // 1: Copy into a sortable container
+ std::vector<IGUIElement *> elements;
+ for (auto it = from; it != to; ++it)
+ elements.emplace_back(*it);
+
+ // 2: Sort the container
+ std::sort(elements.begin(), elements.end(),
+ [this] (const IGUIElement *a, const IGUIElement *b) -> bool {
+ const FieldSpec *spec_a = getSpecByID(a->getID());
+ const FieldSpec *spec_b = getSpecByID(b->getID());
+ return spec_a && spec_b &&
+ spec_a->priority < spec_b->priority;
+ });
+
+ // 3: Re-assign the pointers
+ for (auto e : elements) {
+ *from = e;
+ from++;
}
-
- // step 3: move all item lists to front
- // TODO when item lists are drawn in order
}
#ifdef __ANDROID__
}
-FormspecFieldType GUIFormSpecMenu::getTypeByID(s32 id)
+const GUIFormSpecMenu::FieldSpec *GUIFormSpecMenu::getSpecByID(s32 id)
{
for (FieldSpec &spec : m_fields) {
if (spec.fid == id)
- return spec.ftype;
+ return &spec;
}
- return f_Unknown;
+ return nullptr;
}
/**
FieldSpec() = default;
FieldSpec(const std::string &name, const std::wstring &label,
- const std::wstring &default_text, int id) :
+ const std::wstring &default_text, s32 id, int priority = 0) :
fname(name),
flabel(label),
fdefault(unescape_enriched(translate_string(default_text))),
fid(id),
send(false),
ftype(f_Unknown),
- is_exit(false)
+ is_exit(false),
+ priority(priority)
{
}
std::string fname;
std::wstring flabel;
std::wstring fdefault;
- int fid;
+ s32 fid;
bool send;
FormspecFieldType ftype;
bool is_exit;
+ // Draw priority for formspec version < 3
+ int priority;
core::rect<s32> rect;
};
}
std::wstring getLabelByID(s32 id);
std::string getNameByID(s32 id);
- FormspecFieldType getTypeByID(s32 id);
+ const FieldSpec *getSpecByID(s32 id);
v2s32 getElementBasePos(const std::vector<std::string> *v_pos);
v2s32 getRealCoordinateBasePos(const std::vector<std::string> &v_pos);
v2s32 getRealCoordinateGeometry(const std::vector<std::string> &v_geom);