]> git.lizzy.rs Git - minetest.git/blobdiff - src/guiFormSpecMenu.cpp
Use single box for halo mesh
[minetest.git] / src / guiFormSpecMenu.cpp
index d6cd61a8df5a3d7eb5cf8f3a869d1eefebfeced5..226cc6cf0e771f5714b36089cdc4917249a994e6 100644 (file)
@@ -300,7 +300,7 @@ void GUIFormSpecMenu::parseSize(parserData* data,std::string element)
 void GUIFormSpecMenu::parseList(parserData* data,std::string element)
 {
        if (m_gamedef == 0) {
-               errorstream<<"WARNING: invalid use of 'list' with m_gamedef==0"<<std::endl;
+               warningstream<<"invalid use of 'list' with m_gamedef==0"<<std::endl;
                return;
        }
 
@@ -345,7 +345,7 @@ void GUIFormSpecMenu::parseList(parserData* data,std::string element)
                }
 
                if(!data->explicit_size)
-                       errorstream<<"WARNING: invalid use of list without a size[] element"<<std::endl;
+                       warningstream<<"invalid use of list without a size[] element"<<std::endl;
                m_inventorylists.push_back(ListDrawSpec(loc, listname, pos, geom, start_i));
                return;
        }
@@ -450,7 +450,7 @@ void GUIFormSpecMenu::parseScrollBar(parserData* data, std::string 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 name = parts[3];
                std::string value = parts[4];
 
                MY_CHECKPOS("scrollbar",0);
@@ -525,7 +525,7 @@ void GUIFormSpecMenu::parseImage(parserData* data,std::string element)
                geom.Y = stof(v_geom[1]) * (float)imgsize.Y;
 
                if(!data->explicit_size)
-                       errorstream<<"WARNING: invalid use of image without a size[] element"<<std::endl;
+                       warningstream<<"invalid use of image without a size[] element"<<std::endl;
                m_images.push_back(ImageDrawSpec(name, pos, geom));
                return;
        }
@@ -541,7 +541,7 @@ void GUIFormSpecMenu::parseImage(parserData* data,std::string element)
                pos.Y += stof(v_pos[1]) * (float) spacing.Y;
 
                if(!data->explicit_size)
-                       errorstream<<"WARNING: invalid use of image without a size[] element"<<std::endl;
+                       warningstream<<"invalid use of image without a size[] element"<<std::endl;
                m_images.push_back(ImageDrawSpec(name, pos));
                return;
        }
@@ -571,8 +571,8 @@ void GUIFormSpecMenu::parseItemImage(parserData* data,std::string element)
                geom.Y = stof(v_geom[1]) * (float)imgsize.Y;
 
                if(!data->explicit_size)
-                       errorstream<<"WARNING: invalid use of item_image without a size[] element"<<std::endl;
-               m_itemimages.push_back(ImageDrawSpec(name, pos, geom));
+                       warningstream<<"invalid use of item_image without a size[] element"<<std::endl;
+               m_itemimages.push_back(ImageDrawSpec("", name, pos, geom));
                return;
        }
        errorstream<< "Invalid ItemImage element(" << parts.size() << "): '" << element << "'"  << std::endl;
@@ -607,7 +607,7 @@ void GUIFormSpecMenu::parseButton(parserData* data,std::string element,
                                                pos.X + geom.X, pos.Y + m_btn_height);
 
                if(!data->explicit_size)
-                       errorstream<<"WARNING: invalid use of button without a size[] element"<<std::endl;
+                       warningstream<<"invalid use of button without a size[] element"<<std::endl;
 
                label = unescape_string(label);
 
@@ -666,7 +666,7 @@ void GUIFormSpecMenu::parseBackground(parserData* data,std::string element)
                }
 
                if(!data->explicit_size)
-                       errorstream<<"WARNING: invalid use of background without a size[] element"<<std::endl;
+                       warningstream<<"invalid use of background without a size[] element"<<std::endl;
                m_backgrounds.push_back(ImageDrawSpec(name, pos, geom));
                return;
        }
@@ -982,7 +982,7 @@ void GUIFormSpecMenu::parseSimpleField(parserData* data,
        core::rect<s32> rect;
 
        if(data->explicit_size)
-               errorstream<<"WARNING: invalid use of unpositioned \"field\" in inventory"<<std::endl;
+               warningstream<<"invalid use of unpositioned \"field\" in inventory"<<std::endl;
 
        v2s32 pos = padding + AbsoluteRect.UpperLeftCorner;
        pos.Y = ((m_fields.size()+2)*60);
@@ -1088,7 +1088,7 @@ void GUIFormSpecMenu::parseTextArea(parserData* data,
        core::rect<s32> rect = core::rect<s32>(pos.X, pos.Y, pos.X+geom.X, pos.Y+geom.Y);
 
        if(!data->explicit_size)
-               errorstream<<"WARNING: invalid use of positioned "<<type<<" without a size[] element"<<std::endl;
+               warningstream<<"invalid use of positioned "<<type<<" without a size[] element"<<std::endl;
 
        if(m_form_src)
                default_val = m_form_src->resolveText(default_val);
@@ -1195,7 +1195,7 @@ void GUIFormSpecMenu::parseLabel(parserData* data,std::string element)
                pos.Y += (stof(v_pos[1]) + 7.0/30.0) * (float)spacing.Y;
 
                if(!data->explicit_size)
-                       errorstream<<"WARNING: invalid use of label without a size[] element"<<std::endl;
+                       warningstream<<"invalid use of label without a size[] element"<<std::endl;
 
                text = unescape_string(text);
                std::vector<std::string> lines = split(text, '\n');
@@ -1260,7 +1260,7 @@ void GUIFormSpecMenu::parseVertLabel(parserData* data,std::string element)
                //actually text.length() would be correct but adding +1 avoids to break all mods
 
                if(!data->explicit_size)
-                       errorstream<<"WARNING: invalid use of label without a size[] element"<<std::endl;
+                       warningstream<<"invalid use of label without a size[] element"<<std::endl;
 
                std::wstring label = L"";
 
@@ -1326,7 +1326,7 @@ void GUIFormSpecMenu::parseImageButton(parserData* data,std::string element,
                core::rect<s32> rect = core::rect<s32>(pos.X, pos.Y, pos.X+geom.X, pos.Y+geom.Y);
 
                if(!data->explicit_size)
-                       errorstream<<"WARNING: invalid use of image_button without a size[] element"<<std::endl;
+                       warningstream<<"invalid use of image_button without a size[] element"<<std::endl;
 
                image_name = unescape_string(image_name);
                pressed_image_name = unescape_string(pressed_image_name);
@@ -1449,9 +1449,8 @@ 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;
+               warningstream << "invalid use of item_image_button with m_gamedef==0"
+                       << std::endl;
                return;
        }
 
@@ -1479,12 +1478,11 @@ void GUIFormSpecMenu::parseItemImageButton(parserData* data,std::string element)
                core::rect<s32> rect = core::rect<s32>(pos.X, pos.Y, pos.X+geom.X, pos.Y+geom.Y);
 
                if(!data->explicit_size)
-                       errorstream<<"WARNING: invalid use of item_image_button without a size[] element"<<std::endl;
+                       warningstream<<"invalid use of item_image_button without a size[] element"<<std::endl;
 
                IItemDefManager *idef = m_gamedef->idef();
                ItemStack item;
                item.deSerialize(item_name, idef);
-               video::ITexture *texture = idef->getInventoryTexture(item.getDefinition(idef).name, m_gamedef);
 
                m_tooltips[name] =
                        TooltipSpec(item.getDefinition(idef).description,
@@ -1499,20 +1497,30 @@ void GUIFormSpecMenu::parseItemImageButton(parserData* data,std::string element)
                        258 + m_fields.size()
                );
 
-               gui::IGUIButton *e = Environment->addButton(rect, this, spec.fid, spec.flabel.c_str());
+               gui::IGUIButton *e = Environment->addButton(rect, this, spec.fid, L"");
 
                if (spec.fname == data->focused_fieldname) {
                        Environment->setFocus(e);
                }
 
                e->setUseAlphaChannel(true);
-               e->setImage(guiScalingImageButton(Environment->getVideoDriver(), texture, geom.X, geom.Y));
-               e->setPressedImage(guiScalingImageButton(Environment->getVideoDriver(), texture, geom.X, geom.Y));
+               e->setImage(guiScalingImageButton(Environment->getVideoDriver(), NULL, geom.X, geom.Y));
+               e->setPressedImage(guiScalingImageButton(Environment->getVideoDriver(), NULL, geom.X, geom.Y));
                e->setScaleImage(true);
                spec.ftype = f_Button;
                rect+=data->basepos-padding;
                spec.rect=rect;
                m_fields.push_back(spec);
+               pos = padding + AbsoluteRect.UpperLeftCorner;
+               pos.X += stof(v_pos[0]) * (float) spacing.X;
+               pos.Y += stof(v_pos[1]) * (float) spacing.Y;
+               m_itemimages.push_back(ImageDrawSpec("", item_name, pos, geom));
+
+               StaticTextSpec label_spec(
+                       utf8_to_wide(label),
+                       rect
+               );
+               m_static_texts.push_back(label_spec);
                return;
        }
        errorstream<< "Invalid ItemImagebutton element(" << parts.size() << "): '" << element << "'"  << std::endl;
@@ -1880,6 +1888,8 @@ void GUIFormSpecMenu::regenerateGui(v2u32 screensize)
        m_fields.clear();
        m_boxes.clear();
        m_tooltips.clear();
+       m_inventory_rings.clear();
+       m_static_texts.clear();
 
        // Set default values (fits old formspec values)
        m_bgcolor = video::SColor(140,0,0,0);
@@ -2151,13 +2161,14 @@ GUIFormSpecMenu::ItemSpec GUIFormSpecMenu::getItemAtPos(v2s32 p) const
        return ItemSpec(InventoryLocation(), "", -1);
 }
 
-void GUIFormSpecMenu::drawList(const ListDrawSpec &s, int phase)
+void GUIFormSpecMenu::drawList(const ListDrawSpec &s, int phase,
+               bool &item_hovered)
 {
        video::IVideoDriver* driver = Environment->getVideoDriver();
 
        Inventory *inv = m_invmgr->getInventory(s.inventoryloc);
        if(!inv){
-               infostream<<"GUIFormSpecMenu::drawList(): WARNING: "
+               warningstream<<"GUIFormSpecMenu::drawList(): "
                                <<"The inventory location "
                                <<"\""<<s.inventoryloc.dump()<<"\" doesn't exist"
                                <<std::endl;
@@ -2165,7 +2176,7 @@ void GUIFormSpecMenu::drawList(const ListDrawSpec &s, int phase)
        }
        InventoryList *ilist = inv->getList(s.listname);
        if(!ilist){
-               infostream<<"GUIFormSpecMenu::drawList(): WARNING: "
+               warningstream<<"GUIFormSpecMenu::drawList(): "
                                <<"The inventory list \""<<s.listname<<"\" @ \""
                                <<s.inventoryloc.dump()<<"\" doesn't exist"
                                <<std::endl;
@@ -2192,13 +2203,16 @@ void GUIFormSpecMenu::drawList(const ListDrawSpec &s, int phase)
                        && m_selected_item->listname == s.listname
                        && m_selected_item->i == item_i;
                bool hovering = rect.isPointInside(m_pointer);
+               ItemRotationKind rotation_kind = selected ? IT_ROT_SELECTED :
+                       (hovering ? IT_ROT_HOVERED : IT_ROT_NONE);
 
-               if(phase == 0)
-               {
-                       if(hovering)
+               if (phase == 0) {
+                       if (hovering) {
+                               item_hovered = true;
                                driver->draw2DRectangle(m_slotbg_h, rect, &AbsoluteClippingRect);
-                       else
+                       } else {
                                driver->draw2DRectangle(m_slotbg_n, rect, &AbsoluteClippingRect);
+                       }
                }
 
                //Draw inv slot borders
@@ -2232,7 +2246,8 @@ void GUIFormSpecMenu::drawList(const ListDrawSpec &s, int phase)
                        if(!item.empty())
                        {
                                drawItemStack(driver, m_font, item,
-                                               rect, &AbsoluteClippingRect, m_gamedef);
+                                       rect, &AbsoluteClippingRect, m_gamedef,
+                                       rotation_kind);
                        }
 
                        // Draw tooltip
@@ -2273,11 +2288,15 @@ void GUIFormSpecMenu::drawList(const ListDrawSpec &s, int phase)
 
 void GUIFormSpecMenu::drawSelectedItem()
 {
-       if(!m_selected_item)
-               return;
-
        video::IVideoDriver* driver = Environment->getVideoDriver();
 
+       if (!m_selected_item) {
+               drawItemStack(driver, m_font, ItemStack(),
+                       core::rect<s32>(v2s32(0, 0), v2s32(0, 0)),
+                       NULL, m_gamedef, IT_ROT_DRAGGED);
+               return;
+       }
+
        Inventory *inv = m_invmgr->getInventory(m_selected_item->inventoryloc);
        sanity_check(inv);
        InventoryList *list = inv->getList(m_selected_item->listname);
@@ -2287,7 +2306,7 @@ void GUIFormSpecMenu::drawSelectedItem()
 
        core::rect<s32> imgrect(0,0,imgsize.X,imgsize.Y);
        core::rect<s32> rect = imgrect + (m_pointer - imgrect.getCenter());
-       drawItemStack(driver, m_font, stack, rect, NULL, m_gamedef);
+       drawItemStack(driver, m_font, stack, rect, NULL, m_gamedef, IT_ROT_DRAGGED);
 }
 
 void GUIFormSpecMenu::drawMenu()
@@ -2369,6 +2388,12 @@ void GUIFormSpecMenu::drawMenu()
 
                driver->draw2DRectangle(todraw, rect, 0);
        }
+
+       /*
+               Call base class
+       */
+       gui::IGUIElement::draw();
+
        /*
                Draw images
        */
@@ -2413,18 +2438,12 @@ void GUIFormSpecMenu::drawMenu()
                const ImageDrawSpec &spec = m_itemimages[i];
                IItemDefManager *idef = m_gamedef->idef();
                ItemStack item;
-               item.deSerialize(spec.name, idef);
-               video::ITexture *texture = idef->getInventoryTexture(item.getDefinition(idef).name, m_gamedef);
-               // Image size on screen
+               item.deSerialize(spec.item_name, idef);
                core::rect<s32> imgrect(0, 0, spec.geom.X, spec.geom.Y);
-               // Image rectangle on screen
+               // Viewport rectangle on screen
                core::rect<s32> rect = imgrect + spec.pos;
-               const video::SColor color(255,255,255,255);
-               const video::SColor colors[] = {color,color,color,color};
-               draw2DImageFilterScaled(driver, texture, rect,
-                       core::rect<s32>(core::position2d<s32>(0,0),
-                                       core::dimension2di(texture->getOriginalSize())),
-                       NULL/*&AbsoluteClippingRect*/, colors, true);
+               drawItemStack(driver, m_font, item, rect, &AbsoluteClippingRect,
+                               m_gamedef, IT_ROT_NONE);
        }
 
        /*
@@ -2432,23 +2451,33 @@ void GUIFormSpecMenu::drawMenu()
                Phase 0: Item slot rectangles
                Phase 1: Item images; prepare tooltip
        */
-       int start_phase=0;
-       for(int phase=start_phase; phase<=1; phase++)
-       for(u32 i=0; i<m_inventorylists.size(); i++)
-       {
-               drawList(m_inventorylists[i], phase);
+       bool item_hovered = false;
+       int start_phase = 0;
+       for (int phase = start_phase; phase <= 1; phase++) {
+               for (u32 i = 0; i < m_inventorylists.size(); i++) {
+                       drawList(m_inventorylists[i], phase, item_hovered);
+               }
+       }
+       if (!item_hovered) {
+               drawItemStack(driver, m_font, ItemStack(),
+                       core::rect<s32>(v2s32(0, 0), v2s32(0, 0)),
+                       NULL, m_gamedef, IT_ROT_HOVERED);
        }
-
-       /*
-               Call base class
-       */
-       gui::IGUIElement::draw();
 
 /* TODO find way to show tooltips on touchscreen */
 #ifndef HAVE_TOUCHSCREENGUI
        m_pointer = m_device->getCursorControl()->getPosition();
 #endif
 
+       /*
+               Draw static text elements
+       */
+       for (u32 i = 0; i < m_static_texts.size(); i++) {
+               const StaticTextSpec &spec = m_static_texts[i]; 
+               video::SColor color(255, 255, 255, 255);
+               m_font->draw(spec.text.c_str(), spec.rect, color, true, true, &spec.rect);
+       }
+
        /*
                Draw fields/buttons tooltips
        */