Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Formspec: draw order and clipping for all elements (#8740)
  • Loading branch information
Desour authored and SmallJoker committed Nov 7, 2019
1 parent 15a030e commit 5506e97
Show file tree
Hide file tree
Showing 14 changed files with 824 additions and 454 deletions.
3 changes: 3 additions & 0 deletions build/android/jni/Android.mk
Expand Up @@ -178,12 +178,15 @@ LOCAL_SRC_FILES := \
jni/src/filesys.cpp \
jni/src/genericobject.cpp \
jni/src/gettext.cpp \
jni/src/gui/guiBackgroundImage.cpp \
jni/src/gui/guiBox.cpp \
jni/src/gui/guiButton.cpp \
jni/src/gui/guiChatConsole.cpp \
jni/src/gui/guiConfirmRegistration.cpp \
jni/src/gui/guiEditBoxWithScrollbar.cpp \
jni/src/gui/guiEngine.cpp \
jni/src/gui/guiFormSpecMenu.cpp \
jni/src/gui/guiItemImage.cpp \
jni/src/gui/guiKeyChangeMenu.cpp \
jni/src/gui/guiPasswordChange.cpp \
jni/src/gui/guiPathSelectMenu.cpp \
Expand Down
7 changes: 7 additions & 0 deletions doc/lua_api.txt
Expand Up @@ -1923,6 +1923,11 @@ When displaying text which can contain formspec code, e.g. text set by a player,
use `minetest.formspec_escape`.
For coloured text you can use `minetest.colorize`.

Since formspec version 3, elements drawn in the order they are defined. All
background elements are drawn before all other elements.
`list` elements are an exception here. They are drawn last. This, however, might
be changed at any time.

**WARNING**: do _not_ use a element name starting with `key_`; those names are
reserved to pass key press events to formspec!

Expand Down Expand Up @@ -2032,13 +2037,15 @@ Elements
be shown if the inventory list is of size 0.
* **Note**: With the new coordinate system, the spacing between inventory
slots is one-fourth the size of an inventory slot.
* **Note**: Lists are drawn after every other element. This might change at any time.

### `list[<inventory location>;<list name>;<X>,<Y>;<W>,<H>;<starting item index>]`

* Show an inventory list if it has been sent to the client. Nothing will
be shown if the inventory list is of size 0.
* **Note**: With the new coordinate system, the spacing between inventory
slots is one-fourth the size of an inventory slot.
* **Note**: Lists are drawn after every other element. This might change at any time.

### `listring[<inventory location>;<list name>]`

Expand Down
7 changes: 3 additions & 4 deletions src/client/guiscalingfilter.cpp
Expand Up @@ -171,7 +171,8 @@ void draw2DImageFilterScaled(video::IVideoDriver *driver, video::ITexture *txr,
}

void draw2DImage9Slice(video::IVideoDriver *driver, video::ITexture *texture,
const core::rect<s32> &rect, const core::rect<s32> &middle)
const core::rect<s32> &rect, const core::rect<s32> &middle,
const core::rect<s32> *cliprect)
{
const video::SColor color(255,255,255,255);
const video::SColor colors[] = {color,color,color,color};
Expand Down Expand Up @@ -222,9 +223,7 @@ void draw2DImage9Slice(video::IVideoDriver *driver, video::ITexture *texture,
break;
}

draw2DImageFilterScaled(driver, texture, dest,
src,
NULL/*&AbsoluteClippingRect*/, colors, true);
draw2DImageFilterScaled(driver, texture, dest, src, cliprect, colors, true);
}
}
}
3 changes: 2 additions & 1 deletion src/client/guiscalingfilter.h
Expand Up @@ -53,4 +53,5 @@ void draw2DImageFilterScaled(video::IVideoDriver *driver, video::ITexture *txr,
* 9-slice / segment drawing
*/
void draw2DImage9Slice(video::IVideoDriver *driver, video::ITexture *texture,
const core::rect<s32> &rect, const core::rect<s32> &middle);
const core::rect<s32> &rect, const core::rect<s32> &middle,
const core::rect<s32> *cliprect = nullptr);
3 changes: 3 additions & 0 deletions src/gui/CMakeLists.txt
@@ -1,10 +1,13 @@
set(gui_SRCS
${CMAKE_CURRENT_SOURCE_DIR}/guiBackgroundImage.cpp
${CMAKE_CURRENT_SOURCE_DIR}/guiBox.cpp
${CMAKE_CURRENT_SOURCE_DIR}/guiButton.cpp
${CMAKE_CURRENT_SOURCE_DIR}/guiChatConsole.cpp
${CMAKE_CURRENT_SOURCE_DIR}/guiConfirmRegistration.cpp
${CMAKE_CURRENT_SOURCE_DIR}/guiEditBoxWithScrollbar.cpp
${CMAKE_CURRENT_SOURCE_DIR}/guiEngine.cpp
${CMAKE_CURRENT_SOURCE_DIR}/guiFormSpecMenu.cpp
${CMAKE_CURRENT_SOURCE_DIR}/guiItemImage.cpp
${CMAKE_CURRENT_SOURCE_DIR}/guiKeyChangeMenu.cpp
${CMAKE_CURRENT_SOURCE_DIR}/guiPasswordChange.cpp
${CMAKE_CURRENT_SOURCE_DIR}/guiPathSelectMenu.cpp
Expand Down
69 changes: 69 additions & 0 deletions src/gui/guiBackgroundImage.cpp
@@ -0,0 +1,69 @@
/*
Part of Minetest
Copyright (C) 2013 RealBadAngel, Maciej Kasatkin <mk@realbadangel.pl>
Permission to use, copy, modify, and distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/

#include "guiBackgroundImage.h"
#include "client/guiscalingfilter.h"
#include "log.h"

GUIBackgroundImage::GUIBackgroundImage(gui::IGUIEnvironment *env,
gui::IGUIElement *parent, s32 id, const core::rect<s32> &rectangle,
const std::string &name, const core::rect<s32> &middle,
ISimpleTextureSource *tsrc, bool autoclip) :
gui::IGUIElement(gui::EGUIET_ELEMENT, env, parent, id, rectangle),
m_name(name), m_middle(middle), m_tsrc(tsrc), m_autoclip(autoclip)
{
}

void GUIBackgroundImage::draw()
{
if (!IsVisible)
return;

video::ITexture *texture = m_tsrc->getTexture(m_name);

if (!texture) {
errorstream << "GUIBackgroundImage::draw() Unable to load texture:"
<< std::endl;
errorstream << "\t" << m_name << std::endl;
return;
}

core::rect<s32> rect = AbsoluteRect;
if (m_autoclip)
rect.LowerRightCorner += Parent->getAbsolutePosition().getSize();

video::IVideoDriver *driver = Environment->getVideoDriver();

if (m_middle.getArea() == 0) {
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())),
nullptr, colors, true);
} else {
core::rect<s32> middle = m_middle;
// `-x` is interpreted as `w - x`
if (middle.LowerRightCorner.X < 0)
middle.LowerRightCorner.X += texture->getOriginalSize().Width;
if (middle.LowerRightCorner.Y < 0)
middle.LowerRightCorner.Y += texture->getOriginalSize().Height;
draw2DImage9Slice(driver, texture, rect, middle);
}

IGUIElement::draw();
}
38 changes: 38 additions & 0 deletions src/gui/guiBackgroundImage.h
@@ -0,0 +1,38 @@
/*
Part of Minetest
Copyright (C) 2013 RealBadAngel, Maciej Kasatkin <mk@realbadangel.pl>
Permission to use, copy, modify, and distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/

#pragma once

#include "irrlichttypes_extrabloated.h"
#include "util/string.h"
#include "client/tile.h" // ITextureSource

class GUIBackgroundImage : public gui::IGUIElement
{
public:
GUIBackgroundImage(gui::IGUIEnvironment *env, gui::IGUIElement *parent, s32 id,
const core::rect<s32> &rectangle, const std::string &name,
const core::rect<s32> &middle, ISimpleTextureSource *tsrc, bool autoclip);

virtual void draw() override;

private:
std::string m_name;
core::rect<s32> m_middle;
ISimpleTextureSource *m_tsrc;
bool m_autoclip;
};
38 changes: 38 additions & 0 deletions src/gui/guiBox.cpp
@@ -0,0 +1,38 @@
/*
Minetest
Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

#include "guiBox.h"

GUIBox::GUIBox(gui::IGUIEnvironment *env, gui::IGUIElement *parent, s32 id,
const core::rect<s32> &rectangle, const video::SColor &color) :
gui::IGUIElement(gui::EGUIET_ELEMENT, env, parent, id, rectangle),
m_color(color)
{
}

void GUIBox::draw()
{
if (!IsVisible)
return;

Environment->getVideoDriver()->draw2DRectangle(m_color, AbsoluteRect,
&AbsoluteClippingRect);

IGUIElement::draw();
}
34 changes: 34 additions & 0 deletions src/gui/guiBox.h
@@ -0,0 +1,34 @@
/*
Minetest
Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

#pragma once

#include "irrlichttypes_extrabloated.h"

class GUIBox : public gui::IGUIElement
{
public:
GUIBox(gui::IGUIEnvironment *env, gui::IGUIElement *parent, s32 id,
const core::rect<s32> &rectangle, const video::SColor &color);

virtual void draw() override;

private:
video::SColor m_color;
};

0 comments on commit 5506e97

Please sign in to comment.