@@ -46,6 +46,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
46
46
#include " gettime.h"
47
47
#include " gettext.h"
48
48
#include " scripting_game.h"
49
+ #include " porting.h"
49
50
50
51
#define MY_CHECKPOS (a,b ) \
51
52
if (v_pos.size() != 2 ) { \
@@ -91,6 +92,12 @@ GUIFormSpecMenu::GUIFormSpecMenu(irr::IrrlichtDevice* dev,
91
92
current_keys_pending.key_enter = false ;
92
93
current_keys_pending.key_escape = false ;
93
94
95
+ m_doubleclickdetect[0 ].time = 0 ;
96
+ m_doubleclickdetect[1 ].time = 0 ;
97
+
98
+ m_doubleclickdetect[0 ].pos = v2s32 (0 , 0 );
99
+ m_doubleclickdetect[1 ].pos = v2s32 (0 , 0 );
100
+
94
101
}
95
102
96
103
GUIFormSpecMenu::~GUIFormSpecMenu ()
@@ -1171,9 +1178,9 @@ void GUIFormSpecMenu::parseImageButton(parserData* data,std::string element,
1171
1178
if (parts[6 ] == " false" )
1172
1179
drawborder = false ;
1173
1180
}
1174
-
1181
+
1175
1182
std::string pressed_image_name = " " ;
1176
-
1183
+
1177
1184
if ((parts.size () == 8 )) {
1178
1185
pressed_image_name = parts[7 ];
1179
1186
}
@@ -1265,9 +1272,11 @@ void GUIFormSpecMenu::parseTabHeader(parserData* data,std::string element)
1265
1272
geom.X = data->screensize .Y ;
1266
1273
geom.Y = 30 ;
1267
1274
1268
- core::rect<s32> rect = core::rect<s32>(pos.X , pos.Y , pos.X +geom.X , pos.Y +geom.Y );
1275
+ core::rect<s32> rect = core::rect<s32>(pos.X , pos.Y , pos.X +geom.X ,
1276
+ pos.Y +geom.Y );
1269
1277
1270
- gui::IGUITabControl *e = Environment->addTabControl (rect,this ,show_background,show_border,spec.fid );
1278
+ gui::IGUITabControl *e = Environment->addTabControl (rect, this ,
1279
+ show_background, show_border, spec.fid );
1271
1280
1272
1281
if (spec.fname == data->focused_fieldname ) {
1273
1282
Environment->setFocus (e);
@@ -1276,7 +1285,7 @@ void GUIFormSpecMenu::parseTabHeader(parserData* data,std::string element)
1276
1285
e->setNotClipped (true );
1277
1286
1278
1287
for (unsigned int i=0 ; i< buttons.size (); i++) {
1279
- e->addTab (narrow_to_wide (buttons[i]).c_str (),-1 );
1288
+ e->addTab (narrow_to_wide (buttons[i]).c_str (), -1 );
1280
1289
}
1281
1290
1282
1291
if ((tab_index >= 0 ) &&
@@ -1287,14 +1296,17 @@ void GUIFormSpecMenu::parseTabHeader(parserData* data,std::string element)
1287
1296
m_fields.push_back (spec);
1288
1297
return ;
1289
1298
}
1290
- errorstream<< " Invalid TabHeader element(" << parts.size () << " ): '" << element << " '" << std::endl;
1299
+ errorstream << " Invalid TabHeader element(" << parts.size () << " ): '"
1300
+ << element << " '" << std::endl;
1291
1301
}
1292
1302
1293
1303
void GUIFormSpecMenu::parseItemImageButton (parserData* data,std::string element)
1294
1304
{
1295
1305
1296
1306
if (m_gamedef == 0 ) {
1297
- errorstream<<" WARNING: invalid use of item_image_button with m_gamedef==0" <<std::endl;
1307
+ errorstream <<
1308
+ " WARNING: invalid use of item_image_button with m_gamedef==0"
1309
+ << std::endl;
1298
1310
return ;
1299
1311
}
1300
1312
@@ -1414,7 +1426,7 @@ void GUIFormSpecMenu::parseListColors(parserData* data,std::string element)
1414
1426
if ((parts.size () == 2 ) || (parts.size () == 3 ) || (parts.size () == 5 )) {
1415
1427
parseColor (parts[0 ], m_slotbg_n, false );
1416
1428
parseColor (parts[1 ], m_slotbg_h, false );
1417
-
1429
+
1418
1430
if (parts.size () >= 3 ) {
1419
1431
if (parseColor (parts[2 ], m_slotbordercolor, false )) {
1420
1432
m_slotborder = true ;
@@ -1628,9 +1640,9 @@ void GUIFormSpecMenu::regenerateGui(v2u32 screensize)
1628
1640
// A proceed button is added if there is no size[] element
1629
1641
mydata.bp_set = 0 ;
1630
1642
1631
-
1643
+
1632
1644
/* Convert m_init_draw_spec to m_inventorylists */
1633
-
1645
+
1634
1646
m_inventorylists.clear ();
1635
1647
m_images.clear ();
1636
1648
m_backgrounds.clear ();
@@ -1710,7 +1722,7 @@ void GUIFormSpecMenu::regenerateGui(v2u32 screensize)
1710
1722
GUIFormSpecMenu::ItemSpec GUIFormSpecMenu::getItemAtPos (v2s32 p) const
1711
1723
{
1712
1724
core::rect<s32> imgrect (0 ,0 ,imgsize.X ,imgsize.Y );
1713
-
1725
+
1714
1726
for (u32 i=0 ; i<m_inventorylists.size (); i++)
1715
1727
{
1716
1728
const ListDrawSpec &s = m_inventorylists[i];
@@ -1741,7 +1753,7 @@ void GUIFormSpecMenu::drawList(const ListDrawSpec &s, int phase)
1741
1753
gui::IGUISkin* skin = Environment->getSkin ();
1742
1754
if (skin)
1743
1755
font = skin->getFont ();
1744
-
1756
+
1745
1757
Inventory *inv = m_invmgr->getInventory (s.inventoryloc );
1746
1758
if (!inv){
1747
1759
infostream<<" GUIFormSpecMenu::drawList(): WARNING: "
@@ -1758,9 +1770,9 @@ void GUIFormSpecMenu::drawList(const ListDrawSpec &s, int phase)
1758
1770
<<std::endl;
1759
1771
return ;
1760
1772
}
1761
-
1773
+
1762
1774
core::rect<s32> imgrect (0 ,0 ,imgsize.X ,imgsize.Y );
1763
-
1775
+
1764
1776
for (s32 i=0 ; i<s.geom .X *s.geom .Y ; i++)
1765
1777
{
1766
1778
s32 item_i = i + s.start_item_i ;
@@ -1855,7 +1867,7 @@ void GUIFormSpecMenu::drawSelectedItem()
1855
1867
gui::IGUISkin* skin = Environment->getSkin ();
1856
1868
if (skin)
1857
1869
font = skin->getFont ();
1858
-
1870
+
1859
1871
Inventory *inv = m_invmgr->getInventory (m_selected_item->inventoryloc );
1860
1872
assert (inv);
1861
1873
InventoryList *list = inv->getList (m_selected_item->listname );
@@ -1886,7 +1898,7 @@ void GUIFormSpecMenu::drawMenu()
1886
1898
if (!skin)
1887
1899
return ;
1888
1900
video::IVideoDriver* driver = Environment->getVideoDriver ();
1889
-
1901
+
1890
1902
v2u32 screenSize = driver->getScreenSize ();
1891
1903
core::rect<s32> allbg (0 , 0 , screenSize.X , screenSize.Y );
1892
1904
if (m_bgfullscreen)
@@ -1930,7 +1942,7 @@ void GUIFormSpecMenu::drawMenu()
1930
1942
errorstream << " \t " << spec.name << std::endl;
1931
1943
}
1932
1944
}
1933
-
1945
+
1934
1946
/*
1935
1947
Draw Boxes
1936
1948
*/
@@ -1979,7 +1991,7 @@ void GUIFormSpecMenu::drawMenu()
1979
1991
errorstream << " \t " << spec.name << std::endl;
1980
1992
}
1981
1993
}
1982
-
1994
+
1983
1995
/*
1984
1996
Draw item images
1985
1997
*/
@@ -2004,7 +2016,7 @@ void GUIFormSpecMenu::drawMenu()
2004
2016
core::dimension2di (texture->getOriginalSize ())),
2005
2017
NULL /* &AbsoluteClippingRect*/ , colors, true );
2006
2018
}
2007
-
2019
+
2008
2020
/*
2009
2021
Draw items
2010
2022
Phase 0: Item slot rectangles
@@ -2021,7 +2033,7 @@ void GUIFormSpecMenu::drawMenu()
2021
2033
Call base class
2022
2034
*/
2023
2035
gui::IGUIElement::draw ();
2024
-
2036
+
2025
2037
/*
2026
2038
Draw fields/buttons tooltips
2027
2039
*/
@@ -2046,7 +2058,7 @@ void GUIFormSpecMenu::drawMenu()
2046
2058
}
2047
2059
}
2048
2060
}
2049
-
2061
+
2050
2062
/*
2051
2063
Draw dragged item stack
2052
2064
*/
@@ -2276,6 +2288,17 @@ void GUIFormSpecMenu::acceptInput(FormspecQuitMode quitmode=quit_mode_no)
2276
2288
}
2277
2289
}
2278
2290
2291
+ static bool isChild (gui::IGUIElement * tocheck, gui::IGUIElement * parent)
2292
+ {
2293
+ while (tocheck != NULL ) {
2294
+ if (tocheck == parent) {
2295
+ return true ;
2296
+ }
2297
+ tocheck = tocheck->getParent ();
2298
+ }
2299
+ return false ;
2300
+ }
2301
+
2279
2302
bool GUIFormSpecMenu::preprocessEvent (const SEvent& event)
2280
2303
{
2281
2304
// Fix Esc/Return key being eaten by checkboxen and tables
@@ -2306,6 +2329,64 @@ bool GUIFormSpecMenu::preprocessEvent(const SEvent& event)
2306
2329
}
2307
2330
}
2308
2331
2332
+ if (event.EventType == EET_MOUSE_INPUT_EVENT) {
2333
+ s32 x = event.MouseInput .X ;
2334
+ s32 y = event.MouseInput .Y ;
2335
+ gui::IGUIElement *hovered =
2336
+ Environment->getRootGUIElement ()->getElementFromPoint (
2337
+ core::position2d<s32>(x, y));
2338
+
2339
+ if (!isChild (hovered,this )) {
2340
+ if (DoubleClickDetection (event)) {
2341
+ return true ;
2342
+ }
2343
+ }
2344
+ }
2345
+
2346
+ return false ;
2347
+ }
2348
+
2349
+ /* *****************************************************************************/
2350
+ bool GUIFormSpecMenu::DoubleClickDetection (const SEvent event)
2351
+ {
2352
+ if (event.MouseInput .Event == EMIE_LMOUSE_PRESSED_DOWN) {
2353
+ m_doubleclickdetect[0 ].pos = m_doubleclickdetect[1 ].pos ;
2354
+ m_doubleclickdetect[0 ].time = m_doubleclickdetect[1 ].time ;
2355
+
2356
+ m_doubleclickdetect[1 ].pos = m_pointer;
2357
+ m_doubleclickdetect[1 ].time = getTimeMs ();
2358
+ }
2359
+ else if (event.MouseInput .Event == EMIE_LMOUSE_LEFT_UP) {
2360
+ u32 delta = porting::getDeltaMs (m_doubleclickdetect[0 ].time , getTimeMs ());
2361
+ if (delta > 400 ) {
2362
+ return false ;
2363
+ }
2364
+
2365
+ double squaredistance =
2366
+ m_doubleclickdetect[0 ].pos
2367
+ .getDistanceFromSQ (m_doubleclickdetect[1 ].pos );
2368
+
2369
+ if (squaredistance > (30 *30 )) {
2370
+ return false ;
2371
+ }
2372
+
2373
+ SEvent* translated = new SEvent ();
2374
+ assert (translated != 0 );
2375
+ // translate doubleclick to escape
2376
+ memset (translated, 0 , sizeof (SEvent));
2377
+ translated->EventType = irr::EET_KEY_INPUT_EVENT;
2378
+ translated->KeyInput .Key = KEY_ESCAPE;
2379
+ translated->KeyInput .Control = false ;
2380
+ translated->KeyInput .Shift = false ;
2381
+ translated->KeyInput .PressedDown = true ;
2382
+ translated->KeyInput .Char = 0 ;
2383
+ OnEvent (*translated);
2384
+
2385
+ // no need to send the key up event as we're already deleted
2386
+ // and no one else did notice this event
2387
+ delete translated;
2388
+ return true ;
2389
+ }
2309
2390
return false ;
2310
2391
}
2311
2392
0 commit comments