Add srollbar formspec element
This commit is contained in:
parent
903d343b08
commit
65b8b524c0
|
@ -400,6 +400,17 @@ function core.explode_textlist_event(evt)
|
||||||
return {type="INV", index=0}
|
return {type="INV", index=0}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
function core.explode_scrollbar_event(evt)
|
||||||
|
local retval = core.explode_textlist_event(evt)
|
||||||
|
|
||||||
|
retval.value = retval.index
|
||||||
|
retval.index = nil
|
||||||
|
|
||||||
|
return retval
|
||||||
|
end
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
function core.pos_to_string(pos)
|
function core.pos_to_string(pos)
|
||||||
return "(" .. pos.x .. "," .. pos.y .. "," .. pos.z .. ")"
|
return "(" .. pos.x .. "," .. pos.y .. "," .. pos.z .. ")"
|
||||||
end
|
end
|
||||||
|
|
|
@ -75,29 +75,38 @@ local function showconfirm_reset(tabview)
|
||||||
new_dlg:show()
|
new_dlg:show()
|
||||||
end
|
end
|
||||||
|
|
||||||
local function gui_scale_index()
|
local function gui_scale_to_scrollbar()
|
||||||
|
|
||||||
local current_value = tonumber(core.setting_get("gui_scaling"))
|
local current_value = tonumber(core.setting_get("gui_scaling"))
|
||||||
|
|
||||||
if (current_value == nil) then
|
if (current_value == nil) or current_value < 0.25 then
|
||||||
return 0
|
return 0
|
||||||
elseif current_value <= 0.5 then
|
|
||||||
return 1
|
|
||||||
elseif current_value <= 0.625 then
|
|
||||||
return 2
|
|
||||||
elseif current_value <= 0.75 then
|
|
||||||
return 3
|
|
||||||
elseif current_value <= 0.875 then
|
|
||||||
return 4
|
|
||||||
elseif current_value <= 1.0 then
|
|
||||||
return 5
|
|
||||||
elseif current_value <= 1.25 then
|
|
||||||
return 6
|
|
||||||
elseif current_value <= 1.5 then
|
|
||||||
return 7
|
|
||||||
else
|
|
||||||
return 8
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if current_value <= 1.25 then
|
||||||
|
return ((current_value - 0.25)/ 1.0) * 700
|
||||||
|
end
|
||||||
|
|
||||||
|
if current_value <= 6 then
|
||||||
|
return ((current_value -1.25) * 100) + 700
|
||||||
|
end
|
||||||
|
|
||||||
|
return 1000
|
||||||
|
end
|
||||||
|
|
||||||
|
local function scrollbar_to_gui_scale(value)
|
||||||
|
|
||||||
|
value = tonumber(value)
|
||||||
|
|
||||||
|
if (value <= 700) then
|
||||||
|
return ((value / 700) * 1.0) + 0.25
|
||||||
|
end
|
||||||
|
|
||||||
|
if (value <=1000) then
|
||||||
|
return ((value - 700) / 100) + 1.25
|
||||||
|
end
|
||||||
|
|
||||||
|
return 1
|
||||||
end
|
end
|
||||||
|
|
||||||
local function formspec(tabview, name, tabdata)
|
local function formspec(tabview, name, tabdata)
|
||||||
|
@ -138,8 +147,11 @@ local function formspec(tabview, name, tabdata)
|
||||||
tab_string = tab_string ..
|
tab_string = tab_string ..
|
||||||
"box[0.75,4.25;3.25,1.25;#999999]" ..
|
"box[0.75,4.25;3.25,1.25;#999999]" ..
|
||||||
"label[1,4.25;" .. fgettext("GUI scale factor") .. "]" ..
|
"label[1,4.25;" .. fgettext("GUI scale factor") .. "]" ..
|
||||||
"dropdown[1,4.75;3.0;dd_gui_scaling;0.5,0.625,0.75,0.875,1.0,1.25,1.5,2.0;"
|
"scrollbar[1,4.75;2.75,0.4;sb_gui_scaling;horizontal;" ..
|
||||||
.. gui_scale_index() .. "]"
|
gui_scale_to_scrollbar() .. "]" ..
|
||||||
|
"tooltip[sb_gui_scaling;" ..
|
||||||
|
fgettext("Scaling factor applied to menu elements: ") ..
|
||||||
|
dump(core.setting_get("gui_scaling")) .. "]"
|
||||||
|
|
||||||
if ANDROID then
|
if ANDROID then
|
||||||
tab_string = tab_string ..
|
tab_string = tab_string ..
|
||||||
|
@ -257,6 +269,16 @@ local function handle_settings_buttons(this, fields, tabname, tabdata)
|
||||||
core.show_keys_menu()
|
core.show_keys_menu()
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if fields["sb_gui_scaling"] then
|
||||||
|
local event = core.explode_scrollbar_event(fields["sb_gui_scaling"])
|
||||||
|
|
||||||
|
if event.type == "CHG" then
|
||||||
|
local tosave = string.format("%.2f",scrollbar_to_gui_scale(event.value))
|
||||||
|
core.setting_set("gui_scaling",tosave)
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
if fields["cb_touchscreen_target"] then
|
if fields["cb_touchscreen_target"] then
|
||||||
core.setting_set("touchtarget", fields["cb_touchscreen_target"])
|
core.setting_set("touchtarget", fields["cb_touchscreen_target"])
|
||||||
return true
|
return true
|
||||||
|
@ -272,10 +294,6 @@ local function handle_settings_buttons(this, fields, tabname, tabdata)
|
||||||
core.setting_set("touchscreen_threshold",fields["dd_touchthreshold"])
|
core.setting_set("touchscreen_threshold",fields["dd_touchthreshold"])
|
||||||
ddhandled = true
|
ddhandled = true
|
||||||
end
|
end
|
||||||
if fields["dd_gui_scaling"] then
|
|
||||||
core.setting_set("gui_scaling",fields["dd_gui_scaling"])
|
|
||||||
ddhandled = true
|
|
||||||
end
|
|
||||||
|
|
||||||
return ddhandled
|
return ddhandled
|
||||||
end
|
end
|
||||||
|
|
|
@ -1061,6 +1061,9 @@ box[<X>,<Y>;<W>,<H>;<color>]
|
||||||
|
|
||||||
dropdown[<X>,<Y>;<W>;<name>;<item 1>,<item 2>, ...,<item n>;<selected idx>]
|
dropdown[<X>,<Y>;<W>;<name>;<item 1>,<item 2>, ...,<item n>;<selected idx>]
|
||||||
^ show a dropdown field
|
^ show a dropdown field
|
||||||
|
^ IMPORTANT NOTE: There are two different operation modes:
|
||||||
|
^ 1) handle directly on change (only changed dropdown is submitted)
|
||||||
|
^ 2) read the value on pressing a button (all dropdown values are available)
|
||||||
^ x and y position of dropdown
|
^ x and y position of dropdown
|
||||||
^ width of dropdown
|
^ width of dropdown
|
||||||
^ fieldname data is transfered to Lua
|
^ fieldname data is transfered to Lua
|
||||||
|
@ -1075,6 +1078,18 @@ checkbox[<X>,<Y>;<name>;<label>;<selected>;<tooltip>]
|
||||||
^ selected (optional) true/false
|
^ selected (optional) true/false
|
||||||
^ tooltip (optional)
|
^ tooltip (optional)
|
||||||
|
|
||||||
|
scrollbar[<X>,<Y>;<W>,<H>;<orientation>;<name>;<value>]
|
||||||
|
^ show a scrollbar
|
||||||
|
^ there are two ways to use it:
|
||||||
|
^ 1) handle the changed event (only changed scrollbar is available)
|
||||||
|
^ 2) read the value on pressing a button (all scrollbars are available)
|
||||||
|
^ x and y position of trackbar
|
||||||
|
^ width and height
|
||||||
|
^ orientation vertical/horizontal
|
||||||
|
^ fieldname data is transfered to lua
|
||||||
|
^ value this trackbar is set to (0-1000)
|
||||||
|
^ see also minetest.explode_scrollbar_event (main menu: engine.explode_scrollbar_event)
|
||||||
|
|
||||||
table[<X>,<Y>;<W>,<H>;<name>;<cell 1>,<cell 2>,...,<cell n>;<selected idx>]
|
table[<X>,<Y>;<W>,<H>;<name>;<cell 1>,<cell 2>,...,<cell n>;<selected idx>]
|
||||||
^ show scrollable table using options defined by the previous tableoptions[]
|
^ show scrollable table using options defined by the previous tableoptions[]
|
||||||
^ displays cells as defined by the previous tablecolumns[]
|
^ displays cells as defined by the previous tablecolumns[]
|
||||||
|
@ -1472,6 +1487,9 @@ minetest.explode_table_event(string) -> table
|
||||||
minetest.explode_textlist_event(string) -> table
|
minetest.explode_textlist_event(string) -> table
|
||||||
^ returns e.g. {type="CHG", index=1}
|
^ returns e.g. {type="CHG", index=1}
|
||||||
^ type: "INV" (no row selected), "CHG" (selected) or "DCL" (double-click)
|
^ type: "INV" (no row selected), "CHG" (selected) or "DCL" (double-click)
|
||||||
|
minetest.explode_scrollbar_event(string) -> table
|
||||||
|
^ returns e.g. {type="CHG", value=500}
|
||||||
|
^ type: "INV" (something failed), "CHG" (has been changed) or "VAL" (not changed)
|
||||||
|
|
||||||
Item handling:
|
Item handling:
|
||||||
minetest.inventorycube(img1, img2, img3)
|
minetest.inventorycube(img1, img2, img3)
|
||||||
|
|
|
@ -453,6 +453,7 @@ void GUIFormSpecMenu::parseCheckbox(parserData* data,std::string element)
|
||||||
);
|
);
|
||||||
|
|
||||||
spec.ftype = f_CheckBox;
|
spec.ftype = f_CheckBox;
|
||||||
|
|
||||||
gui::IGUICheckBox* e = Environment->addCheckBox(fselected, rect, this,
|
gui::IGUICheckBox* e = Environment->addCheckBox(fselected, rect, this,
|
||||||
spec.fid, spec.flabel.c_str());
|
spec.fid, spec.flabel.c_str());
|
||||||
|
|
||||||
|
@ -467,6 +468,94 @@ void GUIFormSpecMenu::parseCheckbox(parserData* data,std::string element)
|
||||||
errorstream<< "Invalid checkbox element(" << parts.size() << "): '" << element << "'" << std::endl;
|
errorstream<< "Invalid checkbox element(" << parts.size() << "): '" << element << "'" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GUIFormSpecMenu::parseScrollBar(parserData* data, std::string element)
|
||||||
|
{
|
||||||
|
std::vector<std::string> parts = split(element,';');
|
||||||
|
|
||||||
|
if (parts.size() >= 5) {
|
||||||
|
std::vector<std::string> v_pos = split(parts[0],',');
|
||||||
|
std::vector<std::string> v_dim = split(parts[1],',');
|
||||||
|
std::string name = parts[2];
|
||||||
|
std::string value = parts[4];
|
||||||
|
|
||||||
|
MY_CHECKPOS("scrollbar",0);
|
||||||
|
|
||||||
|
v2s32 pos = padding;
|
||||||
|
pos.X += stof(v_pos[0]) * (float) spacing.X;
|
||||||
|
pos.Y += stof(v_pos[1]) * (float) spacing.Y;
|
||||||
|
|
||||||
|
if (v_dim.size() != 2) {
|
||||||
|
errorstream<< "Invalid size for element " << "scrollbar"
|
||||||
|
<< "specified: \"" << parts[1] << "\"" << std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
v2s32 dim;
|
||||||
|
dim.X = stof(v_dim[0]) * (float) spacing.X;
|
||||||
|
dim.Y = stof(v_dim[1]) * (float) spacing.Y;
|
||||||
|
|
||||||
|
core::rect<s32> rect =
|
||||||
|
core::rect<s32>(pos.X, pos.Y, pos.X + dim.X, pos.Y + dim.Y);
|
||||||
|
|
||||||
|
FieldSpec spec(
|
||||||
|
narrow_to_wide(name.c_str()),
|
||||||
|
L"",
|
||||||
|
L"",
|
||||||
|
258+m_fields.size()
|
||||||
|
);
|
||||||
|
|
||||||
|
bool is_horizontal = true;
|
||||||
|
|
||||||
|
if (parts[2] == "vertical")
|
||||||
|
is_horizontal = false;
|
||||||
|
|
||||||
|
spec.ftype = f_ScrollBar;
|
||||||
|
spec.send = true;
|
||||||
|
gui::IGUIScrollBar* e =
|
||||||
|
Environment->addScrollBar(is_horizontal,rect,this,spec.fid);
|
||||||
|
|
||||||
|
e->setMax(1000);
|
||||||
|
e->setMin(0);
|
||||||
|
e->setPos(stoi(parts[4]));
|
||||||
|
e->setSmallStep(10);
|
||||||
|
e->setLargeStep(100);
|
||||||
|
|
||||||
|
if (!m_lock) {
|
||||||
|
core::rect<s32> relative_rect = e->getRelativePosition();
|
||||||
|
|
||||||
|
if (!is_horizontal) {
|
||||||
|
s32 original_width = relative_rect.getWidth();
|
||||||
|
s32 width = (original_width/(2.0/3.0))
|
||||||
|
* porting::getDisplayDensity()
|
||||||
|
* g_settings->getFloat("gui_scaling");
|
||||||
|
e->setRelativePosition(core::rect<s32>(
|
||||||
|
relative_rect.UpperLeftCorner.X,
|
||||||
|
relative_rect.UpperLeftCorner.Y,
|
||||||
|
relative_rect.LowerRightCorner.X + (width - original_width),
|
||||||
|
relative_rect.LowerRightCorner.Y
|
||||||
|
));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
s32 original_height = relative_rect.getHeight();
|
||||||
|
s32 height = (original_height/(2.0/3.0))
|
||||||
|
* porting::getDisplayDensity()
|
||||||
|
* g_settings->getFloat("gui_scaling");
|
||||||
|
e->setRelativePosition(core::rect<s32>(
|
||||||
|
relative_rect.UpperLeftCorner.X,
|
||||||
|
relative_rect.UpperLeftCorner.Y,
|
||||||
|
relative_rect.LowerRightCorner.X,
|
||||||
|
relative_rect.LowerRightCorner.Y + (height - original_height)
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_scrollbars.push_back(std::pair<FieldSpec,gui::IGUIScrollBar*>(spec,e));
|
||||||
|
m_fields.push_back(spec);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
errorstream<< "Invalid scrollbar element(" << parts.size() << "): '" << element << "'" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
void GUIFormSpecMenu::parseImage(parserData* data,std::string element)
|
void GUIFormSpecMenu::parseImage(parserData* data,std::string element)
|
||||||
{
|
{
|
||||||
std::vector<std::string> parts = split(element,';');
|
std::vector<std::string> parts = split(element,';');
|
||||||
|
@ -1731,6 +1820,11 @@ void GUIFormSpecMenu::parseElement(parserData* data, std::string element)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (type == "scrollbar") {
|
||||||
|
parseScrollBar(data, description);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Ignore others
|
// Ignore others
|
||||||
infostream
|
infostream
|
||||||
<< "Unknown DrawSpec: type="<<type<<", data=\""<<description<<"\""
|
<< "Unknown DrawSpec: type="<<type<<", data=\""<<description<<"\""
|
||||||
|
@ -1798,6 +1892,7 @@ void GUIFormSpecMenu::regenerateGui(v2u32 screensize)
|
||||||
m_itemimages.clear();
|
m_itemimages.clear();
|
||||||
m_tables.clear();
|
m_tables.clear();
|
||||||
m_checkboxes.clear();
|
m_checkboxes.clear();
|
||||||
|
m_scrollbars.clear();
|
||||||
m_fields.clear();
|
m_fields.clear();
|
||||||
m_boxes.clear();
|
m_boxes.clear();
|
||||||
m_tooltips.clear();
|
m_tooltips.clear();
|
||||||
|
@ -2513,6 +2608,24 @@ void GUIFormSpecMenu::acceptInput(FormspecQuitMode quitmode=quit_mode_no)
|
||||||
fields[name] = "false";
|
fields[name] = "false";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (s.ftype == f_ScrollBar) {
|
||||||
|
// no dynamic cast possible due to some distributions shipped
|
||||||
|
// without rtti support in irrlicht
|
||||||
|
IGUIElement * element = getElementFromId(s.fid);
|
||||||
|
gui::IGUIScrollBar *e = NULL;
|
||||||
|
if ((element) && (element->getType() == gui::EGUIET_SCROLL_BAR)) {
|
||||||
|
e = static_cast<gui::IGUIScrollBar*>(element);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (e != 0) {
|
||||||
|
std::stringstream os;
|
||||||
|
os << e->getPos();
|
||||||
|
if (s.fdefault == L"Changed")
|
||||||
|
fields[name] = "CHG:" + os.str();
|
||||||
|
else
|
||||||
|
fields[name] = "VAL:" + os.str();
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
IGUIElement* e = getElementFromId(s.fid);
|
IGUIElement* e = getElementFromId(s.fid);
|
||||||
|
@ -3120,7 +3233,8 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event)
|
||||||
}
|
}
|
||||||
if((event.GUIEvent.EventType == gui::EGET_BUTTON_CLICKED) ||
|
if((event.GUIEvent.EventType == gui::EGET_BUTTON_CLICKED) ||
|
||||||
(event.GUIEvent.EventType == gui::EGET_CHECKBOX_CHANGED) ||
|
(event.GUIEvent.EventType == gui::EGET_CHECKBOX_CHANGED) ||
|
||||||
(event.GUIEvent.EventType == gui::EGET_COMBO_BOX_CHANGED)) {
|
(event.GUIEvent.EventType == gui::EGET_COMBO_BOX_CHANGED) ||
|
||||||
|
(event.GUIEvent.EventType == gui::EGET_SCROLL_BAR_CHANGED)) {
|
||||||
unsigned int btn_id = event.GUIEvent.Caller->getID();
|
unsigned int btn_id = event.GUIEvent.Caller->getID();
|
||||||
|
|
||||||
if (btn_id == 257) {
|
if (btn_id == 257) {
|
||||||
|
@ -3157,7 +3271,7 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ((s.ftype == f_DropDown) &&
|
else if ((s.ftype == f_DropDown) &&
|
||||||
(s.fid == event.GUIEvent.Caller->getID())) {
|
(s.fid == event.GUIEvent.Caller->getID())) {
|
||||||
// only send the changed dropdown
|
// only send the changed dropdown
|
||||||
for(u32 i=0; i<m_fields.size(); i++) {
|
for(u32 i=0; i<m_fields.size(); i++) {
|
||||||
|
@ -3179,8 +3293,16 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event)
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
else if ((s.ftype == f_ScrollBar) &&
|
||||||
|
(s.fid == event.GUIEvent.Caller->getID()))
|
||||||
|
{
|
||||||
|
s.fdefault = L"Changed";
|
||||||
|
acceptInput(quit_mode_no);
|
||||||
|
s.fdefault = L"";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(event.GUIEvent.EventType == gui::EGET_EDITBOX_ENTER) {
|
if(event.GUIEvent.EventType == gui::EGET_EDITBOX_ENTER) {
|
||||||
if(event.GUIEvent.Caller->getID() > 257) {
|
if(event.GUIEvent.Caller->getID() > 257) {
|
||||||
|
|
||||||
|
|
|
@ -40,6 +40,7 @@ typedef enum {
|
||||||
f_TabHeader,
|
f_TabHeader,
|
||||||
f_CheckBox,
|
f_CheckBox,
|
||||||
f_DropDown,
|
f_DropDown,
|
||||||
|
f_ScrollBar,
|
||||||
f_Unknown
|
f_Unknown
|
||||||
} FormspecFieldType;
|
} FormspecFieldType;
|
||||||
|
|
||||||
|
@ -306,6 +307,7 @@ protected:
|
||||||
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::wstring, TooltipSpec> m_tooltips;
|
std::map<std::wstring, TooltipSpec> m_tooltips;
|
||||||
|
std::vector<std::pair<FieldSpec,gui::IGUIScrollBar*> > m_scrollbars;
|
||||||
|
|
||||||
ItemSpec *m_selected_item;
|
ItemSpec *m_selected_item;
|
||||||
u32 m_selected_amount;
|
u32 m_selected_amount;
|
||||||
|
@ -397,6 +399,7 @@ private:
|
||||||
void parseListColors(parserData* data,std::string element);
|
void parseListColors(parserData* data,std::string element);
|
||||||
void parseTooltip(parserData* data,std::string element);
|
void parseTooltip(parserData* data,std::string element);
|
||||||
bool parseVersionDirect(std::string data);
|
bool parseVersionDirect(std::string data);
|
||||||
|
void parseScrollBar(parserData* data, std::string element);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* check if event is part of a double click
|
* check if event is part of a double click
|
||||||
|
|
Loading…
Reference in New Issue