#include "gettime.h"
#include "gettext.h"
#include "scripting_game.h"
+#include "porting.h"
#define MY_CHECKPOS(a,b) \
if (v_pos.size() != 2) { \
current_keys_pending.key_enter = false;
current_keys_pending.key_escape = false;
+ m_doubleclickdetect[0].time = 0;
+ m_doubleclickdetect[1].time = 0;
+
+ m_doubleclickdetect[0].pos = v2s32(0, 0);
+ m_doubleclickdetect[1].pos = v2s32(0, 0);
+
}
GUIFormSpecMenu::~GUIFormSpecMenu()
if (parts[6] == "false")
drawborder = false;
}
-
+
std::string pressed_image_name = "";
-
+
if ((parts.size() == 8)) {
pressed_image_name = parts[7];
}
geom.X = data->screensize.Y;
geom.Y = 30;
- core::rect<s32> rect = core::rect<s32>(pos.X, pos.Y, pos.X+geom.X, pos.Y+geom.Y);
+ core::rect<s32> rect = core::rect<s32>(pos.X, pos.Y, pos.X+geom.X,
+ pos.Y+geom.Y);
- gui::IGUITabControl *e = Environment->addTabControl(rect,this,show_background,show_border,spec.fid);
+ gui::IGUITabControl *e = Environment->addTabControl(rect, this,
+ show_background, show_border, spec.fid);
if (spec.fname == data->focused_fieldname) {
Environment->setFocus(e);
e->setNotClipped(true);
for (unsigned int i=0; i< buttons.size(); i++) {
- e->addTab(narrow_to_wide(buttons[i]).c_str(),-1);
+ e->addTab(narrow_to_wide(buttons[i]).c_str(), -1);
}
if ((tab_index >= 0) &&
m_fields.push_back(spec);
return;
}
- errorstream<< "Invalid TabHeader element(" << parts.size() << "): '" << element << "'" << std::endl;
+ errorstream << "Invalid TabHeader element(" << parts.size() << "): '"
+ << element << "'" << std::endl;
}
void GUIFormSpecMenu::parseItemImageButton(parserData* data,std::string element)
{
if (m_gamedef == 0) {
- errorstream<<"WARNING: invalid use of item_image_button with m_gamedef==0"<<std::endl;
+ errorstream <<
+ "WARNING: invalid use of item_image_button with m_gamedef==0"
+ << std::endl;
return;
}
if ((parts.size() == 2) || (parts.size() == 3) || (parts.size() == 5)) {
parseColor(parts[0], m_slotbg_n, false);
parseColor(parts[1], m_slotbg_h, false);
-
+
if (parts.size() >= 3) {
if (parseColor(parts[2], m_slotbordercolor, false)) {
m_slotborder = true;
// A proceed button is added if there is no size[] element
mydata.bp_set = 0;
-
+
/* Convert m_init_draw_spec to m_inventorylists */
-
+
m_inventorylists.clear();
m_images.clear();
m_backgrounds.clear();
GUIFormSpecMenu::ItemSpec GUIFormSpecMenu::getItemAtPos(v2s32 p) const
{
core::rect<s32> imgrect(0,0,imgsize.X,imgsize.Y);
-
+
for(u32 i=0; i<m_inventorylists.size(); i++)
{
const ListDrawSpec &s = m_inventorylists[i];
gui::IGUISkin* skin = Environment->getSkin();
if (skin)
font = skin->getFont();
-
+
Inventory *inv = m_invmgr->getInventory(s.inventoryloc);
if(!inv){
infostream<<"GUIFormSpecMenu::drawList(): WARNING: "
<<std::endl;
return;
}
-
+
core::rect<s32> imgrect(0,0,imgsize.X,imgsize.Y);
-
+
for(s32 i=0; i<s.geom.X*s.geom.Y; i++)
{
s32 item_i = i + s.start_item_i;
gui::IGUISkin* skin = Environment->getSkin();
if (skin)
font = skin->getFont();
-
+
Inventory *inv = m_invmgr->getInventory(m_selected_item->inventoryloc);
assert(inv);
InventoryList *list = inv->getList(m_selected_item->listname);
if (!skin)
return;
video::IVideoDriver* driver = Environment->getVideoDriver();
-
+
v2u32 screenSize = driver->getScreenSize();
core::rect<s32> allbg(0, 0, screenSize.X , screenSize.Y);
if (m_bgfullscreen)
errorstream << "\t" << spec.name << std::endl;
}
}
-
+
/*
Draw Boxes
*/
errorstream << "\t" << spec.name << std::endl;
}
}
-
+
/*
Draw item images
*/
core::dimension2di(texture->getOriginalSize())),
NULL/*&AbsoluteClippingRect*/, colors, true);
}
-
+
/*
Draw items
Phase 0: Item slot rectangles
Call base class
*/
gui::IGUIElement::draw();
-
+
/*
Draw fields/buttons tooltips
*/
}
}
}
-
+
/*
Draw dragged item stack
*/
}
}
+static bool isChild(gui::IGUIElement * tocheck, gui::IGUIElement * parent)
+{
+ while(tocheck != NULL) {
+ if (tocheck == parent) {
+ return true;
+ }
+ tocheck = tocheck->getParent();
+ }
+ return false;
+}
+
bool GUIFormSpecMenu::preprocessEvent(const SEvent& event)
{
// Fix Esc/Return key being eaten by checkboxen and tables
}
}
+ if (event.EventType == EET_MOUSE_INPUT_EVENT) {
+ s32 x = event.MouseInput.X;
+ s32 y = event.MouseInput.Y;
+ gui::IGUIElement *hovered =
+ Environment->getRootGUIElement()->getElementFromPoint(
+ core::position2d<s32>(x, y));
+
+ if (!isChild(hovered,this)) {
+ if (DoubleClickDetection(event)) {
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
+/******************************************************************************/
+bool GUIFormSpecMenu::DoubleClickDetection(const SEvent event)
+{
+ if (event.MouseInput.Event == EMIE_LMOUSE_PRESSED_DOWN) {
+ m_doubleclickdetect[0].pos = m_doubleclickdetect[1].pos;
+ m_doubleclickdetect[0].time = m_doubleclickdetect[1].time;
+
+ m_doubleclickdetect[1].pos = m_pointer;
+ m_doubleclickdetect[1].time = getTimeMs();
+ }
+ else if (event.MouseInput.Event == EMIE_LMOUSE_LEFT_UP) {
+ u32 delta = porting::getDeltaMs(m_doubleclickdetect[0].time, getTimeMs());
+ if (delta > 400) {
+ return false;
+ }
+
+ double squaredistance =
+ m_doubleclickdetect[0].pos
+ .getDistanceFromSQ(m_doubleclickdetect[1].pos);
+
+ if (squaredistance > (30*30)) {
+ return false;
+ }
+
+ SEvent* translated = new SEvent();
+ assert(translated != 0);
+ //translate doubleclick to escape
+ memset(translated, 0, sizeof(SEvent));
+ translated->EventType = irr::EET_KEY_INPUT_EVENT;
+ translated->KeyInput.Key = KEY_ESCAPE;
+ translated->KeyInput.Control = false;
+ translated->KeyInput.Shift = false;
+ translated->KeyInput.PressedDown = true;
+ translated->KeyInput.Char = 0;
+ OnEvent(*translated);
+
+ // no need to send the key up event as we're already deleted
+ // and no one else did notice this event
+ delete translated;
+ return true;
+ }
return false;
}
v2s32 geom;
bool scale;
};
-
+
struct FieldSpec
{
FieldSpec()
m_current_inventory_location = current_inventory_location;
regenerateGui(m_screensize_old);
}
-
+
// form_src is deleted by this GUIFormSpecMenu
void setFormSource(IFormSource *form_src)
{
Remove and re-add (or reposition) stuff
*/
void regenerateGui(v2u32 screensize);
-
+
ItemSpec getItemAtPos(v2s32 p) const;
void drawList(const ListDrawSpec &s, int phase);
void drawSelectedItem();
v2s32 spacing;
v2s32 imgsize;
v2s32 offset;
-
+
irr::IrrlichtDevice* m_device;
InventoryManager *m_invmgr;
IGameDef *m_gamedef;
ItemSpec *m_selected_item;
u32 m_selected_amount;
bool m_selected_dragging;
-
+
// WARNING: BLACK MAGIC
// Used to guess and keep up with some special things the server can do.
// If name is "", no guess exists.
void parseBox(parserData* data,std::string element);
void parseBackgroundColor(parserData* data,std::string element);
void parseListColors(parserData* data,std::string element);
+
+ /**
+ * check if event is part of a double click
+ * @param event event to evaluate
+ * @return true/false if a doubleclick was detected
+ */
+ bool DoubleClickDetection(const SEvent event);
+
+ struct clickpos
+ {
+ v2s32 pos;
+ s32 time;
+ };
+ clickpos m_doubleclickdetect[2];
};
class FormspecFormSource: public IFormSource