summaryrefslogtreecommitdiff
path: root/src/gui
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui')
-rw-r--r--src/gui/CMakeLists.txt1
-rw-r--r--src/gui/StyleSpec.h3
-rw-r--r--src/gui/guiAnimatedImage.cpp59
-rw-r--r--src/gui/guiAnimatedImage.h25
-rw-r--r--src/gui/guiBackgroundImage.cpp18
-rw-r--r--src/gui/guiButton.cpp8
-rw-r--r--src/gui/guiButtonImage.cpp27
-rw-r--r--src/gui/guiButtonImage.h10
-rw-r--r--src/gui/guiChatConsole.cpp4
-rw-r--r--src/gui/guiConfirmRegistration.cpp281
-rw-r--r--src/gui/guiConfirmRegistration.h68
-rw-r--r--src/gui/guiEngine.cpp4
-rw-r--r--src/gui/guiEngine.h2
-rw-r--r--src/gui/guiFormSpecMenu.cpp327
-rw-r--r--src/gui/guiFormSpecMenu.h9
-rw-r--r--src/gui/guiKeyChangeMenu.cpp22
-rw-r--r--src/gui/guiKeyChangeMenu.h1
-rw-r--r--src/gui/guiMainMenu.h3
-rw-r--r--src/gui/guiPasswordChange.cpp19
-rw-r--r--src/gui/guiPasswordChange.h2
-rw-r--r--src/gui/guiPathSelectMenu.cpp3
-rw-r--r--src/gui/guiScrollContainer.cpp9
-rw-r--r--src/gui/guiTable.cpp2
-rw-r--r--src/gui/guiVolumeChange.cpp22
-rw-r--r--src/gui/guiVolumeChange.h3
-rw-r--r--src/gui/mainmenumanager.h4
-rw-r--r--src/gui/modalMenu.cpp22
-rw-r--r--src/gui/modalMenu.h1
-rw-r--r--src/gui/touchscreengui.cpp2
29 files changed, 259 insertions, 702 deletions
diff --git a/src/gui/CMakeLists.txt b/src/gui/CMakeLists.txt
index 513b13e8e..4434b14a0 100644
--- a/src/gui/CMakeLists.txt
+++ b/src/gui/CMakeLists.txt
@@ -11,7 +11,6 @@ set(gui_SRCS
${CMAKE_CURRENT_SOURCE_DIR}/guiButtonImage.cpp
${CMAKE_CURRENT_SOURCE_DIR}/guiButtonItemImage.cpp
${CMAKE_CURRENT_SOURCE_DIR}/guiChatConsole.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/guiConfirmRegistration.cpp
${CMAKE_CURRENT_SOURCE_DIR}/guiEditBox.cpp
${CMAKE_CURRENT_SOURCE_DIR}/guiEditBoxWithScrollbar.cpp
${CMAKE_CURRENT_SOURCE_DIR}/guiEngine.cpp
diff --git a/src/gui/StyleSpec.h b/src/gui/StyleSpec.h
index fc92a861b..7a45e07d1 100644
--- a/src/gui/StyleSpec.h
+++ b/src/gui/StyleSpec.h
@@ -45,6 +45,7 @@ public:
BGIMG_PRESSED, // Note: Deprecated property
FGIMG,
FGIMG_HOVERED, // Note: Deprecated property
+ FGIMG_MIDDLE,
FGIMG_PRESSED, // Note: Deprecated property
ALPHA,
CONTENT_OFFSET,
@@ -101,6 +102,8 @@ public:
return FGIMG;
} else if (name == "fgimg_hovered") {
return FGIMG_HOVERED;
+ } else if (name == "fgimg_middle") {
+ return FGIMG_MIDDLE;
} else if (name == "fgimg_pressed") {
return FGIMG_PRESSED;
} else if (name == "alpha") {
diff --git a/src/gui/guiAnimatedImage.cpp b/src/gui/guiAnimatedImage.cpp
index b1447c45f..890763e71 100644
--- a/src/gui/guiAnimatedImage.cpp
+++ b/src/gui/guiAnimatedImage.cpp
@@ -9,40 +9,37 @@
#include <vector>
GUIAnimatedImage::GUIAnimatedImage(gui::IGUIEnvironment *env, gui::IGUIElement *parent,
- s32 id, const core::rect<s32> &rectangle, const std::string &texture_name,
- s32 frame_count, s32 frame_duration, ISimpleTextureSource *tsrc) :
- gui::IGUIElement(gui::EGUIET_ELEMENT, env, parent, id, rectangle), m_tsrc(tsrc)
+ s32 id, const core::rect<s32> &rectangle) :
+ gui::IGUIElement(gui::EGUIET_ELEMENT, env, parent, id, rectangle)
{
- m_texture = m_tsrc->getTexture(texture_name);
-
- m_frame_count = std::max(frame_count, 1);
- m_frame_duration = std::max(frame_duration, 0);
-
- if (m_texture != nullptr) {
- core::dimension2d<u32> size = m_texture->getOriginalSize();
- if (size.Height < (u64)m_frame_count)
- m_frame_count = size.Height;
- } else {
- // No need to step an animation if we have nothing to draw
- m_frame_count = 1;
- }
}
void GUIAnimatedImage::draw()
{
- // Render the current frame
- if (m_texture != nullptr) {
- video::IVideoDriver *driver = Environment->getVideoDriver();
+ if (m_texture == nullptr)
+ return;
- const video::SColor color(255, 255, 255, 255);
- const video::SColor colors[] = {color, color, color, color};
+ video::IVideoDriver *driver = Environment->getVideoDriver();
+
+ core::dimension2d<u32> size = m_texture->getOriginalSize();
+
+ if ((u32)m_frame_count > size.Height)
+ m_frame_count = size.Height;
+ if (m_frame_idx >= m_frame_count)
+ m_frame_idx = m_frame_count - 1;
- core::dimension2d<u32> size = m_texture->getOriginalSize();
- size.Height /= m_frame_count;
+ size.Height /= m_frame_count;
- draw2DImageFilterScaled(driver, m_texture, AbsoluteRect,
- core::rect<s32>(core::position2d<s32>(0, size.Height * m_frame_idx), size),
- NoClip ? nullptr : &AbsoluteClippingRect, colors, true);
+ core::rect<s32> rect(core::position2d<s32>(0, size.Height * m_frame_idx), size);
+ core::rect<s32> *cliprect = NoClip ? nullptr : &AbsoluteClippingRect;
+
+ if (m_middle.getArea() == 0) {
+ const video::SColor color(255, 255, 255, 255);
+ const video::SColor colors[] = {color, color, color, color};
+ draw2DImageFilterScaled(driver, m_texture, AbsoluteRect, rect, cliprect,
+ colors, true);
+ } else {
+ draw2DImage9Slice(driver, m_texture, AbsoluteRect, rect, m_middle, cliprect);
}
// Step the animation
@@ -55,7 +52,7 @@ void GUIAnimatedImage::draw()
m_global_time = new_global_time;
// Advance by the number of elapsed frames, looping if necessary
- m_frame_idx += u32(m_frame_time / m_frame_duration);
+ m_frame_idx += (u32)(m_frame_time / m_frame_duration);
m_frame_idx %= m_frame_count;
// If 1 or more frames have elapsed, reset the frame time counter with
@@ -63,11 +60,3 @@ void GUIAnimatedImage::draw()
m_frame_time %= m_frame_duration;
}
}
-
-
-void GUIAnimatedImage::setFrameIndex(s32 frame)
-{
- s32 idx = std::max(frame, 0);
- if (idx > 0 && idx < m_frame_count)
- m_frame_idx = idx;
-}
diff --git a/src/gui/guiAnimatedImage.h b/src/gui/guiAnimatedImage.h
index f8e6a506e..885aedece 100644
--- a/src/gui/guiAnimatedImage.h
+++ b/src/gui/guiAnimatedImage.h
@@ -1,6 +1,7 @@
#pragma once
#include "irrlichttypes_extrabloated.h"
+#include <algorithm>
#include <string>
class ISimpleTextureSource;
@@ -8,21 +9,33 @@ class ISimpleTextureSource;
class GUIAnimatedImage : public gui::IGUIElement {
public:
GUIAnimatedImage(gui::IGUIEnvironment *env, gui::IGUIElement *parent,
- s32 id, const core::rect<s32> &rectangle, const std::string &texture_name,
- s32 frame_count, s32 frame_duration, ISimpleTextureSource *tsrc);
+ s32 id, const core::rect<s32> &rectangle);
virtual void draw() override;
- void setFrameIndex(s32 frame);
+ void setTexture(video::ITexture *texture) { m_texture = texture; };
+ video::ITexture *getTexture() const { return m_texture; };
+
+ void setMiddleRect(const core::rect<s32> &middle) { m_middle = middle; };
+ core::rect<s32> getMiddleRect() const { return m_middle; };
+
+ void setFrameDuration(u64 duration) { m_frame_duration = duration; };
+ u64 getFrameDuration() const { return m_frame_duration; };
+
+ void setFrameCount(s32 count) { m_frame_count = std::max(count, 1); };
+ s32 getFrameCount() const { return m_frame_count; };
+
+ void setFrameIndex(s32 frame) { m_frame_idx = std::max(frame, 0); };
s32 getFrameIndex() const { return m_frame_idx; };
private:
- ISimpleTextureSource *m_tsrc;
-
video::ITexture *m_texture = nullptr;
+
u64 m_global_time = 0;
s32 m_frame_idx = 0;
s32 m_frame_count = 1;
- u64 m_frame_duration = 1;
+ u64 m_frame_duration = 0;
u64 m_frame_time = 0;
+
+ core::rect<s32> m_middle;
};
diff --git a/src/gui/guiBackgroundImage.cpp b/src/gui/guiBackgroundImage.cpp
index 21c1e88cf..8d0d1c010 100644
--- a/src/gui/guiBackgroundImage.cpp
+++ b/src/gui/guiBackgroundImage.cpp
@@ -44,25 +44,19 @@ void GUIBackgroundImage::draw()
core::rect<s32> rect = AbsoluteRect;
if (m_autoclip)
- rect.LowerRightCorner += Parent->getAbsolutePosition().getSize();
+ rect.LowerRightCorner += Parent->getAbsoluteClippingRect().getSize();
video::IVideoDriver *driver = Environment->getVideoDriver();
+ core::rect<s32> srcrect(core::position2d<s32>(0, 0),
+ core::dimension2di(texture->getOriginalSize()));
+
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);
+ draw2DImageFilterScaled(driver, texture, rect, srcrect, 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);
+ draw2DImage9Slice(driver, texture, rect, srcrect, m_middle);
}
IGUIElement::draw();
diff --git a/src/gui/guiButton.cpp b/src/gui/guiButton.cpp
index ba95b81c3..c38d901c4 100644
--- a/src/gui/guiButton.cpp
+++ b/src/gui/guiButton.cpp
@@ -320,15 +320,9 @@ void GUIButton::draw()
sourceRect, &AbsoluteClippingRect,
image_colors, UseAlphaChannel);
} else {
- core::rect<s32> middle = BgMiddle;
- // `-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,
ScaleImage ? AbsoluteRect : core::rect<s32>(pos, sourceRect.getSize()),
- middle, &AbsoluteClippingRect, image_colors);
+ sourceRect, BgMiddle, &AbsoluteClippingRect, image_colors);
}
// END PATCH
}
diff --git a/src/gui/guiButtonImage.cpp b/src/gui/guiButtonImage.cpp
index b507ffece..4ab770a99 100644
--- a/src/gui/guiButtonImage.cpp
+++ b/src/gui/guiButtonImage.cpp
@@ -32,15 +32,15 @@ using namespace gui;
GUIButtonImage::GUIButtonImage(gui::IGUIEnvironment *environment,
gui::IGUIElement *parent, s32 id, core::rect<s32> rectangle,
ISimpleTextureSource *tsrc, bool noclip)
- : GUIButton (environment, parent, id, rectangle, tsrc, noclip)
+ : GUIButton(environment, parent, id, rectangle, tsrc, noclip)
{
- m_image = Environment->addImage(
- core::rect<s32>(0,0,rectangle.getWidth(),rectangle.getHeight()), this);
- m_image->setScaleImage(isScalingImage());
+ GUIButton::setScaleImage(true);
+ m_image = new GUIAnimatedImage(environment, this, id, rectangle);
sendToBack(m_image);
}
-void GUIButtonImage::setForegroundImage(video::ITexture *image)
+void GUIButtonImage::setForegroundImage(video::ITexture *image,
+ const core::rect<s32> &middle)
{
if (image == m_foreground_image)
return;
@@ -52,11 +52,12 @@ void GUIButtonImage::setForegroundImage(video::ITexture *image)
m_foreground_image->drop();
m_foreground_image = image;
- m_image->setImage(image);
+ m_image->setTexture(image);
+ m_image->setMiddleRect(middle);
}
//! Set element properties from a StyleSpec
-void GUIButtonImage::setFromStyle(const StyleSpec& style)
+void GUIButtonImage::setFromStyle(const StyleSpec &style)
{
GUIButton::setFromStyle(style);
@@ -67,19 +68,13 @@ void GUIButtonImage::setFromStyle(const StyleSpec& style)
getTextureSource());
setForegroundImage(guiScalingImageButton(driver, texture,
- AbsoluteRect.getWidth(), AbsoluteRect.getHeight()));
- setScaleImage(true);
+ AbsoluteRect.getWidth(), AbsoluteRect.getHeight()),
+ style.getRect(StyleSpec::FGIMG_MIDDLE, m_image->getMiddleRect()));
} else {
- setForegroundImage(nullptr);
+ setForegroundImage();
}
}
-void GUIButtonImage::setScaleImage(bool scaleImage)
-{
- GUIButton::setScaleImage(scaleImage);
- m_image->setScaleImage(scaleImage);
-}
-
GUIButtonImage *GUIButtonImage::addButton(IGUIEnvironment *environment,
const core::rect<s32> &rectangle, ISimpleTextureSource *tsrc,
IGUIElement *parent, s32 id, const wchar_t *text,
diff --git a/src/gui/guiButtonImage.h b/src/gui/guiButtonImage.h
index 59a25b4f0..554934518 100644
--- a/src/gui/guiButtonImage.h
+++ b/src/gui/guiButtonImage.h
@@ -21,6 +21,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "guiButton.h"
#include "IGUIButton.h"
+#include "guiAnimatedImage.h"
using namespace irr;
@@ -32,12 +33,11 @@ public:
s32 id, core::rect<s32> rectangle, ISimpleTextureSource *tsrc,
bool noclip = false);
- void setForegroundImage(video::ITexture *image = nullptr);
+ void setForegroundImage(video::ITexture *image = nullptr,
+ const core::rect<s32> &middle = core::rect<s32>());
//! Set element properties from a StyleSpec
- virtual void setFromStyle(const StyleSpec& style) override;
-
- virtual void setScaleImage(bool scaleImage=true) override;
+ virtual void setFromStyle(const StyleSpec &style) override;
//! Do not drop returned handle
static GUIButtonImage *addButton(gui::IGUIEnvironment *environment,
@@ -47,5 +47,5 @@ public:
private:
video::ITexture *m_foreground_image = nullptr;
- gui::IGUIImage *m_image;
+ GUIAnimatedImage *m_image;
};
diff --git a/src/gui/guiChatConsole.cpp b/src/gui/guiChatConsole.cpp
index 01e10ea2e..280f7e45b 100644
--- a/src/gui/guiChatConsole.cpp
+++ b/src/gui/guiChatConsole.cpp
@@ -76,9 +76,9 @@ GUIChatConsole::GUIChatConsole(
m_background_color.setBlue(clamp_u8(myround(console_color.Z)));
}
- u16 chat_font_size = g_settings->getU16("chat_font_size");
+ const u16 chat_font_size = g_settings->getU16("chat_font_size");
m_font = g_fontengine->getFont(chat_font_size != 0 ?
- chat_font_size : FONT_SIZE_UNSPECIFIED, FM_Mono);
+ rangelim(chat_font_size, 5, 72) : FONT_SIZE_UNSPECIFIED, FM_Mono);
if (!m_font) {
errorstream << "GUIChatConsole: Unable to load mono font" << std::endl;
diff --git a/src/gui/guiConfirmRegistration.cpp b/src/gui/guiConfirmRegistration.cpp
deleted file mode 100644
index b8887a4af..000000000
--- a/src/gui/guiConfirmRegistration.cpp
+++ /dev/null
@@ -1,281 +0,0 @@
-/*
-Minetest
-Copyright (C) 2018 srifqi, Muhammad Rifqi Priyo Susanto
- <muhammadrifqipriyosusanto@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 "guiConfirmRegistration.h"
-#include "client/client.h"
-#include "guiButton.h"
-#include <IGUICheckBox.h>
-#include <IGUIButton.h>
-#include <IGUIStaticText.h>
-#include <IGUIFont.h>
-#include "guiEditBoxWithScrollbar.h"
-#include "porting.h"
-
-#ifdef HAVE_TOUCHSCREENGUI
- #include "client/renderingengine.h"
-#endif
-
-#include "gettext.h"
-
-// Continuing from guiPasswordChange.cpp
-const int ID_confirmPassword = 262;
-const int ID_confirm = 263;
-const int ID_intotext = 264;
-const int ID_cancel = 265;
-const int ID_message = 266;
-
-GUIConfirmRegistration::GUIConfirmRegistration(gui::IGUIEnvironment *env,
- gui::IGUIElement *parent, s32 id, IMenuManager *menumgr, Client *client,
- const std::string &playername, const std::string &password,
- bool *aborted, ISimpleTextureSource *tsrc) :
- GUIModalMenu(env, parent, id, menumgr),
- m_client(client), m_playername(playername), m_password(password),
- m_aborted(aborted), m_tsrc(tsrc)
-{
-#ifdef HAVE_TOUCHSCREENGUI
- m_touchscreen_visible = false;
-#endif
-}
-
-GUIConfirmRegistration::~GUIConfirmRegistration()
-{
- removeChildren();
-}
-
-void GUIConfirmRegistration::removeChildren()
-{
- const core::list<gui::IGUIElement *> &children = getChildren();
- core::list<gui::IGUIElement *> children_copy;
- for (gui::IGUIElement *i : children)
- children_copy.push_back(i);
- for (gui::IGUIElement *i : children_copy)
- i->remove();
-}
-
-void GUIConfirmRegistration::regenerateGui(v2u32 screensize)
-{
- acceptInput();
- removeChildren();
-
- /*
- Calculate new sizes and positions
- */
-#ifdef HAVE_TOUCHSCREENGUI
- const float s = m_gui_scale * RenderingEngine::getDisplayDensity() / 2;
-#else
- const float s = m_gui_scale;
-#endif
- DesiredRect = core::rect<s32>(
- screensize.X / 2 - 600 * s / 2,
- screensize.Y / 2 - 360 * s / 2,
- screensize.X / 2 + 600 * s / 2,
- screensize.Y / 2 + 360 * s / 2
- );
- recalculateAbsolutePosition(false);
-
- v2s32 size = DesiredRect.getSize();
- v2s32 topleft_client(0, 0);
-
- const wchar_t *text;
-
- /*
- Add stuff
- */
- s32 ypos = 30 * s;
- {
- core::rect<s32> rect2(0, 0, 540 * s, 180 * s);
- rect2 += topleft_client + v2s32(30 * s, ypos);
- static const std::string info_text_template = strgettext(
- "You are about to join this server with the name \"%s\" for the "
- "first time.\n"
- "If you proceed, a new account using your credentials will be "
- "created on this server.\n"
- "Please retype your password and click 'Register and Join' to "
- "confirm account creation, or click 'Cancel' to abort.");
- char info_text_buf[1024];
- porting::mt_snprintf(info_text_buf, sizeof(info_text_buf),
- info_text_template.c_str(), m_playername.c_str());
-
- std::wstring info_text_w = utf8_to_wide(info_text_buf);
- gui::IGUIEditBox *e = new GUIEditBoxWithScrollBar(info_text_w.c_str(),
- true, Environment, this, ID_intotext, rect2, false, true);
- e->drop();
- e->setMultiLine(true);
- e->setWordWrap(true);
- e->setTextAlignment(gui::EGUIA_UPPERLEFT, gui::EGUIA_CENTER);
- }
-
- ypos += 200 * s;
- {
- core::rect<s32> rect2(0, 0, 540 * s, 30 * s);
- rect2 += topleft_client + v2s32(30 * s, ypos);
- gui::IGUIEditBox *e = Environment->addEditBox(m_pass_confirm.c_str(),
- rect2, true, this, ID_confirmPassword);
- e->setPasswordBox(true);
- Environment->setFocus(e);
- }
-
- ypos += 50 * s;
- {
- core::rect<s32> rect2(0, 0, 230 * s, 35 * s);
- rect2 = rect2 + v2s32(size.X / 2 - 220 * s, ypos);
- text = wgettext("Register and Join");
- GUIButton::addButton(Environment, rect2, m_tsrc, this, ID_confirm, text);
- delete[] text;
- }
- {
- core::rect<s32> rect2(0, 0, 120 * s, 35 * s);
- rect2 = rect2 + v2s32(size.X / 2 + 70 * s, ypos);
- text = wgettext("Cancel");
- GUIButton::addButton(Environment, rect2, m_tsrc, this, ID_cancel, text);
- delete[] text;
- }
- {
- core::rect<s32> rect2(0, 0, 500 * s, 40 * s);
- rect2 += topleft_client + v2s32(30 * s, ypos + 40 * s);
- text = wgettext("Passwords do not match!");
- IGUIElement *e = Environment->addStaticText(
- text, rect2, false, true, this, ID_message);
- e->setVisible(false);
- delete[] text;
- }
-}
-
-void GUIConfirmRegistration::drawMenu()
-{
- gui::IGUISkin *skin = Environment->getSkin();
- if (!skin)
- return;
- video::IVideoDriver *driver = Environment->getVideoDriver();
-
- video::SColor bgcolor(140, 0, 0, 0);
- driver->draw2DRectangle(bgcolor, AbsoluteRect, &AbsoluteClippingRect);
-
- gui::IGUIElement::draw();
-#ifdef __ANDROID__
- getAndroidUIInput();
-#endif
-}
-
-void GUIConfirmRegistration::closeMenu(bool goNext)
-{
- if (goNext) {
- m_client->confirmRegistration();
- } else {
- *m_aborted = true;
- infostream << "Connect aborted [Escape]" << std::endl;
- }
- quitMenu();
-}
-
-void GUIConfirmRegistration::acceptInput()
-{
- gui::IGUIElement *e;
- e = getElementFromId(ID_confirmPassword);
- if (e)
- m_pass_confirm = e->getText();
-}
-
-bool GUIConfirmRegistration::processInput()
-{
- if (utf8_to_wide(m_password) != m_pass_confirm) {
- gui::IGUIElement *e = getElementFromId(ID_message);
- if (e)
- e->setVisible(true);
- return false;
- }
- return true;
-}
-
-bool GUIConfirmRegistration::OnEvent(const SEvent &event)
-{
- if (event.EventType == EET_KEY_INPUT_EVENT) {
- // clang-format off
- if ((event.KeyInput.Key == KEY_ESCAPE ||
- event.KeyInput.Key == KEY_CANCEL) &&
- event.KeyInput.PressedDown) {
- closeMenu(false);
- return true;
- }
- // clang-format on
- if (event.KeyInput.Key == KEY_RETURN && event.KeyInput.PressedDown) {
- acceptInput();
- if (processInput())
- closeMenu(true);
- return true;
- }
- }
-
- if (event.EventType != EET_GUI_EVENT)
- return Parent ? Parent->OnEvent(event) : false;
-
- if (event.GUIEvent.EventType == gui::EGET_ELEMENT_FOCUS_LOST && isVisible()) {
- if (!canTakeFocus(event.GUIEvent.Element)) {
- infostream << "GUIConfirmRegistration: Not allowing focus change."
- << std::endl;
- // Returning true disables focus change
- return true;
- }
- } else if (event.GUIEvent.EventType == gui::EGET_BUTTON_CLICKED) {
- switch (event.GUIEvent.Caller->getID()) {
- case ID_confirm:
- acceptInput();
- if (processInput())
- closeMenu(true);
- return true;
- case ID_cancel:
- closeMenu(false);
- return true;
- }
- } else if (event.GUIEvent.EventType == gui::EGET_EDITBOX_ENTER) {
- switch (event.GUIEvent.Caller->getID()) {
- case ID_confirmPassword:
- acceptInput();
- if (processInput())
- closeMenu(true);
- return true;
- }
- }
-
- return false;
-}
-
-#ifdef __ANDROID__
-bool GUIConfirmRegistration::getAndroidUIInput()
-{
- if (!hasAndroidUIInput() || m_jni_field_name != "password")
- return false;
-
- // still waiting
- if (porting::getInputDialogState() == -1)
- return true;
-
- m_jni_field_name.clear();
-
- gui::IGUIElement *e = getElementFromId(ID_confirmPassword);
-
- if (!e || e->getType() != irr::gui::EGUIET_EDIT_BOX)
- return false;
-
- std::string text = porting::getInputDialogValue();
- e->setText(utf8_to_wide(text).c_str());
- return false;
-}
-#endif
diff --git a/src/gui/guiConfirmRegistration.h b/src/gui/guiConfirmRegistration.h
deleted file mode 100644
index d8387201d..000000000
--- a/src/gui/guiConfirmRegistration.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
-Minetest
-Copyright (C) 2018 srifqi, Muhammad Rifqi Priyo Susanto
- <muhammadrifqipriyosusanto@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"
-#include "modalMenu.h"
-#include <string>
-
-class Client;
-class ISimpleTextureSource;
-
-class GUIConfirmRegistration : public GUIModalMenu
-{
-public:
- GUIConfirmRegistration(gui::IGUIEnvironment *env, gui::IGUIElement *parent,
- s32 id, IMenuManager *menumgr, Client *client,
- const std::string &playername, const std::string &password,
- bool *aborted, ISimpleTextureSource *tsrc);
- ~GUIConfirmRegistration();
-
- void removeChildren();
- /*
- Remove and re-add (or reposition) stuff
- */
- void regenerateGui(v2u32 screensize);
-
- void drawMenu();
-
- void closeMenu(bool goNext);
-
- void acceptInput();
-
- bool processInput();
-
- bool OnEvent(const SEvent &event);
-#ifdef __ANDROID__
- bool getAndroidUIInput();
-#endif
-
-private:
- std::wstring getLabelByID(s32 id) { return L""; }
- std::string getNameByID(s32 id) { return "password"; }
-
- Client *m_client = nullptr;
- const std::string &m_playername;
- const std::string &m_password;
- bool *m_aborted = nullptr;
- std::wstring m_pass_confirm = L"";
- ISimpleTextureSource *m_tsrc;
-};
diff --git a/src/gui/guiEngine.cpp b/src/gui/guiEngine.cpp
index b65b31304..01f3f8fd5 100644
--- a/src/gui/guiEngine.cpp
+++ b/src/gui/guiEngine.cpp
@@ -622,9 +622,9 @@ void GUIEngine::updateTopLeftTextSize()
}
/******************************************************************************/
-s32 GUIEngine::playSound(const SimpleSoundSpec &spec, bool looped)
+s32 GUIEngine::playSound(const SimpleSoundSpec &spec)
{
- s32 handle = m_sound_manager->playSound(spec, looped);
+ s32 handle = m_sound_manager->playSound(spec);
return handle;
}
diff --git a/src/gui/guiEngine.h b/src/gui/guiEngine.h
index d7e6485ef..2f182ca81 100644
--- a/src/gui/guiEngine.h
+++ b/src/gui/guiEngine.h
@@ -296,7 +296,7 @@ private:
clouddata m_cloud;
/** start playing a sound and return handle */
- s32 playSound(const SimpleSoundSpec &spec, bool looped);
+ s32 playSound(const SimpleSoundSpec &spec);
/** stop playing a sound started with playSound() */
void stopSound(s32 handle);
diff --git a/src/gui/guiFormSpecMenu.cpp b/src/gui/guiFormSpecMenu.cpp
index 85bd04900..1f9914e72 100644
--- a/src/gui/guiFormSpecMenu.cpp
+++ b/src/gui/guiFormSpecMenu.cpp
@@ -127,7 +127,8 @@ GUIFormSpecMenu::GUIFormSpecMenu(JoystickController *joystick,
GUIFormSpecMenu::~GUIFormSpecMenu()
{
- removeChildren();
+ removeAllChildren();
+ removeTooltip();
for (auto &table_it : m_tables)
table_it.second->drop();
@@ -137,8 +138,6 @@ GUIFormSpecMenu::~GUIFormSpecMenu()
checkbox_it.second->drop();
for (auto &scrollbar_it : m_scrollbars)
scrollbar_it.second->drop();
- for (auto &background_it : m_backgrounds)
- background_it->drop();
for (auto &tooltip_rect_it : m_tooltip_rects)
tooltip_rect_it.first->drop();
for (auto &clickthrough_it : m_clickthrough_elements)
@@ -176,14 +175,8 @@ void GUIFormSpecMenu::create(GUIFormSpecMenu *&cur_formspec, Client *client,
}
}
-void GUIFormSpecMenu::removeChildren()
+void GUIFormSpecMenu::removeTooltip()
{
- const core::list<gui::IGUIElement*> &children = getChildren();
-
- while (!children.empty()) {
- (*children.getLast())->remove();
- }
-
if (m_tooltip_element) {
m_tooltip_element->remove();
m_tooltip_element->drop();
@@ -201,16 +194,7 @@ void GUIFormSpecMenu::setInitialFocus()
// 5. first focusable (not statictext, not tabheader)
// 6. first child element
- core::list<gui::IGUIElement*> children = getChildren();
-
- // in case "children" contains any NULL elements, remove them
- for (core::list<gui::IGUIElement*>::Iterator it = children.begin();
- it != children.end();) {
- if (*it)
- ++it;
- else
- it = children.erase(it);
- }
+ const auto& children = getChildren();
// 1. first empty editbox
for (gui::IGUIElement *it : children) {
@@ -238,8 +222,7 @@ void GUIFormSpecMenu::setInitialFocus()
}
// 4. last button
- for (core::list<gui::IGUIElement*>::Iterator it = children.getLast();
- it != children.end(); --it) {
+ for (auto it = children.rbegin(); it != children.rend(); ++it) {
if ((*it)->getType() == gui::EGUIET_BUTTON) {
Environment->setFocus(*it);
return;
@@ -259,7 +242,7 @@ void GUIFormSpecMenu::setInitialFocus()
if (children.empty())
Environment->setFocus(this);
else
- Environment->setFocus(*(children.begin()));
+ Environment->setFocus(children.front());
}
GUITable* GUIFormSpecMenu::getTable(const std::string &tablename)
@@ -784,101 +767,99 @@ void GUIFormSpecMenu::parseScrollBarOptions(parserData* data, const std::string
void GUIFormSpecMenu::parseImage(parserData* data, const std::string &element)
{
std::vector<std::string> parts;
- if (!precheckElement("image", element, 2, 3, parts))
+ if (!precheckElement("image", element, 2, 4, parts))
return;
- if (parts.size() >= 3) {
- std::vector<std::string> v_pos = split(parts[0],',');
- std::vector<std::string> v_geom = split(parts[1],',');
- std::string name = unescape_string(parts[2]);
+ size_t offset = parts.size() >= 3;
+
+ std::vector<std::string> v_pos = split(parts[0],',');
+ MY_CHECKPOS("image", 0);
- MY_CHECKPOS("image", 0);
+ std::vector<std::string> v_geom;
+ if (parts.size() >= 3) {
+ v_geom = split(parts[1],',');
MY_CHECKGEOM("image", 1);
+ }
- v2s32 pos;
- v2s32 geom;
+ std::string name = unescape_string(parts[1 + offset]);
+ video::ITexture *texture = m_tsrc->getTexture(name);
- if (data->real_coordinates) {
- pos = getRealCoordinateBasePos(v_pos);
- geom = getRealCoordinateGeometry(v_geom);
+ v2s32 pos;
+ v2s32 geom;
+
+ if (parts.size() < 3) {
+ if (texture != nullptr) {
+ core::dimension2du dim = texture->getOriginalSize();
+ geom.X = dim.Width;
+ geom.Y = dim.Height;
} else {
- pos = getElementBasePos(&v_pos);
- geom.X = stof(v_geom[0]) * (float)imgsize.X;
- geom.Y = stof(v_geom[1]) * (float)imgsize.Y;
+ geom = v2s32(0);
}
+ }
- if (!data->explicit_size)
- warningstream<<"invalid use of image without a size[] element"<<std::endl;
-
- video::ITexture *texture = m_tsrc->getTexture(name);
- if (!texture) {
- errorstream << "GUIFormSpecMenu::parseImage() Unable to load texture:"
- << std::endl << "\t" << name << std::endl;
- return;
+ if (data->real_coordinates) {
+ pos = getRealCoordinateBasePos(v_pos);
+ if (parts.size() >= 3)
+ geom = getRealCoordinateGeometry(v_geom);
+ } else {
+ pos = getElementBasePos(&v_pos);
+ if (parts.size() >= 3) {
+ geom.X = stof(v_geom[0]) * (float)imgsize.X;
+ geom.Y = stof(v_geom[1]) * (float)imgsize.Y;
}
-
- FieldSpec spec(
- name,
- L"",
- L"",
- 258 + m_fields.size(),
- 1
- );
- core::rect<s32> rect(pos, pos + geom);
- gui::IGUIImage *e = Environment->addImage(rect, data->current_parent,
- spec.fid, 0, true);
- e->setImage(texture);
- e->setScaleImage(true);
- auto style = getDefaultStyleForElement("image", spec.fname);
- e->setNotClipped(style.getBool(StyleSpec::NOCLIP, m_formspec_version < 3));
- m_fields.push_back(spec);
-
- // images should let events through
- e->grab();
- m_clickthrough_elements.push_back(e);
- return;
}
- // Else: 2 arguments in "parts"
-
- std::vector<std::string> v_pos = split(parts[0],',');
- std::string name = unescape_string(parts[1]);
-
- MY_CHECKPOS("image", 0);
-
- v2s32 pos = getElementBasePos(&v_pos);
-
if (!data->explicit_size)
- warningstream<<"invalid use of image without a size[] element"<<std::endl;
-
- video::ITexture *texture = m_tsrc->getTexture(name);
- if (!texture) {
- errorstream << "GUIFormSpecMenu::parseImage() Unable to load texture:"
- << std::endl << "\t" << name << std::endl;
- return;
- }
+ warningstream << "Invalid use of image without a size[] element" << std::endl;
FieldSpec spec(
name,
L"",
L"",
- 258 + m_fields.size()
+ 258 + m_fields.size(),
+ 1
);
- gui::IGUIImage *e = Environment->addImage(texture, pos, true,
- data->current_parent, spec.fid, 0);
+
+ core::rect<s32> rect = core::rect<s32>(pos, pos + geom);
+
+ core::rect<s32> middle;
+ if (parts.size() >= 4)
+ parseMiddleRect(parts[3], &middle);
+
+ // Temporary fix for issue #12581 in 5.6.0.
+ // Use legacy image when not rendering 9-slice image because GUIAnimatedImage
+ // uses NNAA filter which causes visual artifacts when image uses alpha blending.
+
+ gui::IGUIElement *e;
+ if (middle.getArea() > 0) {
+ GUIAnimatedImage *image = new GUIAnimatedImage(Environment, data->current_parent,
+ spec.fid, rect);
+
+ image->setTexture(texture);
+ image->setMiddleRect(middle);
+ e = image;
+ }
+ else {
+ gui::IGUIImage *image = Environment->addImage(rect, data->current_parent, spec.fid, nullptr, true);
+ image->setImage(texture);
+ image->setScaleImage(true);
+ image->grab(); // compensate for drop in addImage
+ e = image;
+ }
+
auto style = getDefaultStyleForElement("image", spec.fname);
e->setNotClipped(style.getBool(StyleSpec::NOCLIP, m_formspec_version < 3));
- m_fields.push_back(spec);
- // images should let events through
- e->grab();
+ // Animated images should let events through
m_clickthrough_elements.push_back(e);
+
+ m_fields.push_back(spec);
}
void GUIFormSpecMenu::parseAnimatedImage(parserData *data, const std::string &element)
{
std::vector<std::string> parts;
- if (!precheckElement("animated_image", element, 6, 7, parts))
+ if (!precheckElement("animated_image", element, 6, 8, parts))
return;
std::vector<std::string> v_pos = split(parts[0], ',');
@@ -904,7 +885,8 @@ void GUIFormSpecMenu::parseAnimatedImage(parserData *data, const std::string &el
}
if (!data->explicit_size)
- warningstream << "Invalid use of animated_image without a size[] element" << std::endl;
+ warningstream << "Invalid use of animated_image without a size[] element"
+ << std::endl;
FieldSpec spec(
name,
@@ -917,9 +899,17 @@ void GUIFormSpecMenu::parseAnimatedImage(parserData *data, const std::string &el
core::rect<s32> rect = core::rect<s32>(pos, pos + geom);
- GUIAnimatedImage *e = new GUIAnimatedImage(Environment, data->current_parent, spec.fid,
- rect, texture_name, frame_count, frame_duration, m_tsrc);
+ core::rect<s32> middle;
+ if (parts.size() >= 8)
+ parseMiddleRect(parts[7], &middle);
+
+ GUIAnimatedImage *e = new GUIAnimatedImage(Environment, data->current_parent,
+ spec.fid, rect);
+ e->setTexture(m_tsrc->getTexture(texture_name));
+ e->setMiddleRect(middle);
+ e->setFrameDuration(frame_duration);
+ e->setFrameCount(frame_count);
if (parts.size() >= 7)
e->setFrameIndex(stoi(parts[6]) - 1);
@@ -1044,6 +1034,35 @@ void GUIFormSpecMenu::parseButton(parserData* data, const std::string &element,
m_fields.push_back(spec);
}
+bool GUIFormSpecMenu::parseMiddleRect(const std::string &value, core::rect<s32> *parsed_rect)
+{
+ core::rect<s32> rect;
+ std::vector<std::string> v_rect = split(value, ',');
+
+ if (v_rect.size() == 1) {
+ s32 x = stoi(v_rect[0]);
+ rect.UpperLeftCorner = core::vector2di(x, x);
+ rect.LowerRightCorner = core::vector2di(-x, -x);
+ } else if (v_rect.size() == 2) {
+ s32 x = stoi(v_rect[0]);
+ s32 y = stoi(v_rect[1]);
+ rect.UpperLeftCorner = core::vector2di(x, y);
+ rect.LowerRightCorner = core::vector2di(-x, -y);
+ // `-x` is interpreted as `w - x`
+ } else if (v_rect.size() == 4) {
+ rect.UpperLeftCorner = core::vector2di(stoi(v_rect[0]), stoi(v_rect[1]));
+ rect.LowerRightCorner = core::vector2di(stoi(v_rect[2]), stoi(v_rect[3]));
+ } else {
+ warningstream << "Invalid rectangle string format: \"" << value
+ << "\"" << std::endl;
+ return false;
+ }
+
+ *parsed_rect = rect;
+
+ return true;
+}
+
void GUIFormSpecMenu::parseBackground(parserData* data, const std::string &element)
{
std::vector<std::string> parts;
@@ -1085,25 +1104,8 @@ void GUIFormSpecMenu::parseBackground(parserData* data, const std::string &eleme
}
core::rect<s32> middle;
- if (parts.size() >= 5) {
- std::vector<std::string> v_middle = split(parts[4], ',');
- if (v_middle.size() == 1) {
- s32 x = stoi(v_middle[0]);
- middle.UpperLeftCorner = core::vector2di(x, x);
- middle.LowerRightCorner = core::vector2di(-x, -x);
- } else if (v_middle.size() == 2) {
- s32 x = stoi(v_middle[0]);
- s32 y = stoi(v_middle[1]);
- middle.UpperLeftCorner = core::vector2di(x, y);
- middle.LowerRightCorner = core::vector2di(-x, -y);
- // `-x` is interpreted as `w - x`
- } else if (v_middle.size() == 4) {
- middle.UpperLeftCorner = core::vector2di(stoi(v_middle[0]), stoi(v_middle[1]));
- middle.LowerRightCorner = core::vector2di(stoi(v_middle[2]), stoi(v_middle[3]));
- } else {
- warningstream << "Invalid rectangle given to middle param of background[] element" << std::endl;
- }
- }
+ if (parts.size() >= 5)
+ parseMiddleRect(parts[4], &middle);
if (!data->explicit_size && !clip)
warningstream << "invalid use of unclipped background without a size[] element" << std::endl;
@@ -1124,17 +1126,15 @@ void GUIFormSpecMenu::parseBackground(parserData* data, const std::string &eleme
rect = core::rect<s32>(-pos, pos);
}
- GUIBackgroundImage *e = new GUIBackgroundImage(Environment, this, spec.fid,
- rect, name, middle, m_tsrc, clip);
+ GUIBackgroundImage *e = new GUIBackgroundImage(Environment, data->background_parent.get(),
+ spec.fid, rect, name, middle, m_tsrc, clip);
FATAL_ERROR_IF(!e, "Failed to create background formspec element");
e->setNotClipped(true);
- e->setVisible(false); // the element is drawn manually before all others
-
- m_backgrounds.push_back(e);
m_fields.push_back(spec);
+ e->drop();
}
void GUIFormSpecMenu::parseTableOptions(parserData* data, const std::string &element)
@@ -1686,7 +1686,7 @@ void GUIFormSpecMenu::parseField(parserData* data, const std::string &element,
void GUIFormSpecMenu::parseHyperText(parserData *data, const std::string &element)
{
- MY_CHECKCLIENT("list");
+ MY_CHECKCLIENT("hypertext");
std::vector<std::string> parts;
if (!precheckElement("hypertext", element, 4, 4, parts))
@@ -1746,25 +1746,27 @@ void GUIFormSpecMenu::parseLabel(parserData* data, const std::string &element)
return;
std::vector<std::string> v_pos = split(parts[0],',');
- std::string text = parts[1];
MY_CHECKPOS("label",0);
if(!data->explicit_size)
warningstream<<"invalid use of label without a size[] element"<<std::endl;
- std::vector<std::string> lines = split(text, '\n');
-
auto style = getDefaultStyleForElement("label", "");
gui::IGUIFont *font = style.getFont();
if (!font)
font = m_font;
- for (unsigned int i = 0; i != lines.size(); i++) {
- std::wstring wlabel_colors = translate_string(
- utf8_to_wide(unescape_string(lines[i])));
- // Without color escapes to get the font dimensions
- std::wstring wlabel_plain = unescape_enriched(wlabel_colors);
+ EnrichedString str(unescape_string(utf8_to_wide(parts[1])));
+ size_t str_pos = 0;
+
+ for (size_t i = 0; str_pos < str.size(); ++i) {
+ // Split per line
+ size_t str_nl = str.getString().find(L'\n', str_pos);
+ if (str_nl == std::wstring::npos)
+ str_nl = str.getString().size();
+ EnrichedString line = str.substr(str_pos, str_nl - str_pos);
+ str_pos += line.size() + 1;
core::rect<s32> rect;
@@ -1781,7 +1783,7 @@ void GUIFormSpecMenu::parseLabel(parserData* data, const std::string &element)
rect = core::rect<s32>(
pos.X, pos.Y,
- pos.X + font->getDimension(wlabel_plain.c_str()).Width,
+ pos.X + font->getDimension(line.c_str()).Width,
pos.Y + imgsize.Y);
} else {
@@ -1803,19 +1805,19 @@ void GUIFormSpecMenu::parseLabel(parserData* data, const std::string &element)
rect = core::rect<s32>(
pos.X, pos.Y - m_btn_height,
- pos.X + font->getDimension(wlabel_plain.c_str()).Width,
+ pos.X + font->getDimension(line.c_str()).Width,
pos.Y + m_btn_height);
}
FieldSpec spec(
"",
- wlabel_colors,
+ L"",
L"",
258 + m_fields.size(),
4
);
gui::IGUIStaticText *e = gui::StaticText::add(Environment,
- spec.flabel.c_str(), rect, false, false, data->current_parent,
+ line, rect, false, false, data->current_parent,
spec.fid);
e->setTextAlignment(gui::EGUIA_UPPERLEFT, gui::EGUIA_CENTER);
@@ -3049,7 +3051,8 @@ void GUIFormSpecMenu::regenerateGui(v2u32 screensize)
}
// Remove children
- removeChildren();
+ removeAllChildren();
+ removeTooltip();
for (auto &table_it : m_tables)
table_it.second->drop();
@@ -3059,8 +3062,6 @@ void GUIFormSpecMenu::regenerateGui(v2u32 screensize)
checkbox_it.second->drop();
for (auto &scrollbar_it : m_scrollbars)
scrollbar_it.second->drop();
- for (auto &background_it : m_backgrounds)
- background_it->drop();
for (auto &tooltip_rect_it : m_tooltip_rects)
tooltip_rect_it.first->drop();
for (auto &clickthrough_it : m_clickthrough_elements)
@@ -3082,7 +3083,6 @@ void GUIFormSpecMenu::regenerateGui(v2u32 screensize)
mydata.current_parent = this;
m_inventorylists.clear();
- m_backgrounds.clear();
m_tables.clear();
m_checkboxes.clear();
m_scrollbars.clear();
@@ -3229,8 +3229,8 @@ void GUIFormSpecMenu::regenerateGui(v2u32 screensize)
offset = v2s32(0,0);
}
- double gui_scaling = g_settings->getFloat("gui_scaling");
- double screen_dpi = RenderingEngine::getDisplayDensity() * 96;
+ const double gui_scaling = g_settings->getFloat("gui_scaling", 0.5f, 42.0f);
+ const double screen_dpi = RenderingEngine::getDisplayDensity() * 96;
double use_imgsize;
if (m_lock) {
@@ -3336,10 +3336,19 @@ void GUIFormSpecMenu::regenerateGui(v2u32 screensize)
gui::IGUIFont *old_font = skin->getFont();
skin->setFont(m_font);
+ // Add a new element that will hold all the background elements as its children.
+ // Because it is the first added element, all backgrounds will be behind all
+ // the other elements.
+ // (We use an arbitrarily big rect. The actual size is determined later by
+ // clipping to `this`.)
+ core::rect<s32> background_parent_rect(0, 0, 100000, 100000);
+ mydata.background_parent.reset(new gui::IGUIElement(EGUIET_ELEMENT, Environment,
+ this, -1, background_parent_rect));
+
pos_offset = v2f32();
// used for formspec versions < 3
- core::list<IGUIElement *>::Iterator legacy_sort_start = Children.getLast();
+ std::list<IGUIElement *>::iterator legacy_sort_start = std::prev(Children.end()); // last element
if (enable_prepends) {
// Backup the coordinates so that prepends can use the coordinates of choice.
@@ -3354,7 +3363,7 @@ void GUIFormSpecMenu::regenerateGui(v2u32 screensize)
// legacy sorting for formspec versions < 3
if (m_formspec_version >= 3)
// prepends do not need to be reordered
- legacy_sort_start = Children.getLast();
+ legacy_sort_start = std::prev(Children.end()); // last element
else if (version_backup >= 3)
// only prepends elements have to be reordered
legacySortElements(legacy_sort_start);
@@ -3435,7 +3444,7 @@ void GUIFormSpecMenu::regenerateGui(v2u32 screensize)
}
}
-void GUIFormSpecMenu::legacySortElements(core::list<IGUIElement *>::Iterator from)
+void GUIFormSpecMenu::legacySortElements(std::list<IGUIElement *>::iterator from)
{
/*
Draw order for formspec_version <= 2:
@@ -3452,17 +3461,16 @@ void GUIFormSpecMenu::legacySortElements(core::list<IGUIElement *>::Iterator fro
if (from == Children.end())
from = Children.begin();
else
- from++;
+ ++from;
- core::list<IGUIElement *>::Iterator to = Children.end();
+ std::list<IGUIElement *>::iterator to = Children.end();
// 1: Copy into a sortable container
- std::vector<IGUIElement *> elements;
- for (auto it = from; it != to; ++it)
- elements.emplace_back(*it);
+ std::vector<IGUIElement *> elements(from, to);
// 2: Sort the container
std::stable_sort(elements.begin(), elements.end(),
[this] (const IGUIElement *a, const IGUIElement *b) -> bool {
+ // TODO: getSpecByID is a linear search. It should made O(1), or cached here.
const FieldSpec *spec_a = getSpecByID(a->getID());
const FieldSpec *spec_b = getSpecByID(b->getID());
return spec_a && spec_b &&
@@ -3470,10 +3478,7 @@ void GUIFormSpecMenu::legacySortElements(core::list<IGUIElement *>::Iterator fro
});
// 3: Re-assign the pointers
- for (auto e : elements) {
- *from = e;
- from++;
- }
+ reorderChildren(from, to, elements);
}
#ifdef __ANDROID__
@@ -3591,15 +3596,6 @@ void GUIFormSpecMenu::drawMenu()
}
}
- /*
- Draw backgrounds
- */
- for (gui::IGUIElement *e : m_backgrounds) {
- e->setVisible(true);
- e->draw();
- e->setVisible(false);
- }
-
// Some elements are only visible while being drawn
for (gui::IGUIElement *e : m_clickthrough_elements)
e->setVisible(true);
@@ -3607,12 +3603,11 @@ void GUIFormSpecMenu::drawMenu()
/*
This is where all the drawing happens.
*/
- core::list<IGUIElement*>::Iterator it = Children.begin();
- for (; it != Children.end(); ++it)
- if ((*it)->isNotClipped() ||
+ for (auto child : Children)
+ if (child->isNotClipped() ||
AbsoluteClippingRect.isRectCollided(
- (*it)->getAbsolutePosition()))
- (*it)->draw();
+ child->getAbsolutePosition()))
+ child->draw();
for (gui::IGUIElement *e : m_clickthrough_elements)
e->setVisible(false);
@@ -4520,7 +4515,7 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event)
if ((s.ftype == f_TabHeader) &&
(s.fid == event.GUIEvent.Caller->getID())) {
if (!s.sound.empty() && m_sound_manager)
- m_sound_manager->playSound(s.sound, false, 1.0f);
+ m_sound_manager->playSound(SimpleSoundSpec(s.sound, 1.0f));
s.send = true;
acceptInput();
s.send = false;
@@ -4565,7 +4560,7 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event)
if (s.ftype == f_Button || s.ftype == f_CheckBox) {
if (!s.sound.empty() && m_sound_manager)
- m_sound_manager->playSound(s.sound, false, 1.0f);
+ m_sound_manager->playSound(SimpleSoundSpec(s.sound, 1.0f));
s.send = true;
if (s.is_exit) {
@@ -4590,7 +4585,7 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event)
}
}
if (!s.sound.empty() && m_sound_manager)
- m_sound_manager->playSound(s.sound, false, 1.0f);
+ m_sound_manager->playSound(SimpleSoundSpec(s.sound, 1.0f));
s.send = true;
acceptInput(quit_mode_no);
@@ -4608,7 +4603,7 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event)
s.fdefault = L"";
} else if (s.ftype == f_Unknown || s.ftype == f_HyperText) {
if (!s.sound.empty() && m_sound_manager)
- m_sound_manager->playSound(s.sound, false, 1.0f);
+ m_sound_manager->playSound(SimpleSoundSpec(s.sound, 1.0f));
s.send = true;
acceptInput();
s.send = false;
diff --git a/src/gui/guiFormSpecMenu.h b/src/gui/guiFormSpecMenu.h
index 0b4d3879d..c01ff817b 100644
--- a/src/gui/guiFormSpecMenu.h
+++ b/src/gui/guiFormSpecMenu.h
@@ -24,6 +24,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include <unordered_set>
#include "irrlichttypes_extrabloated.h"
+#include "irr_ptr.h"
#include "inventorymanager.h"
#include "modalMenu.h"
#include "guiInventoryList.h"
@@ -211,7 +212,7 @@ public:
m_lockscreensize = basescreensize;
}
- void removeChildren();
+ void removeTooltip();
void setInitialFocus();
void setFocus(const std::string &elementname)
@@ -313,7 +314,6 @@ protected:
std::vector<GUIInventoryList *> m_inventorylists;
std::vector<ListRingSpec> m_inventory_rings;
- std::vector<gui::IGUIElement *> m_backgrounds;
std::unordered_map<std::string, bool> field_close_on_enter;
std::unordered_map<std::string, bool> m_dropdown_index_event;
std::vector<FieldSpec> m_fields;
@@ -375,6 +375,7 @@ private:
GUITable::TableOptions table_options;
GUITable::TableColumns table_columns;
gui::IGUIElement *current_parent = nullptr;
+ irr_ptr<gui::IGUIElement> background_parent;
GUIInventoryList::Options inventorylist_options;
@@ -456,6 +457,8 @@ private:
void parseSetFocus(const std::string &element);
void parseModel(parserData *data, const std::string &element);
+ bool parseMiddleRect(const std::string &value, core::rect<s32> *parsed_rect);
+
void tryClose();
void showTooltip(const std::wstring &text, const irr::video::SColor &color,
@@ -466,7 +469,7 @@ private:
* types were drawn before others.
* This function sorts the elements in the old order for backwards compatibility.
*/
- void legacySortElements(core::list<IGUIElement *>::Iterator from);
+ void legacySortElements(std::list<IGUIElement *>::iterator from);
int m_btn_height;
gui::IGUIFont *m_font = nullptr;
diff --git a/src/gui/guiKeyChangeMenu.cpp b/src/gui/guiKeyChangeMenu.cpp
index 29d5138f0..021f5f0a9 100644
--- a/src/gui/guiKeyChangeMenu.cpp
+++ b/src/gui/guiKeyChangeMenu.cpp
@@ -93,7 +93,8 @@ GUIKeyChangeMenu::GUIKeyChangeMenu(gui::IGUIEnvironment* env,
GUIKeyChangeMenu::~GUIKeyChangeMenu()
{
- removeChildren();
+ removeAllChildren();
+ key_used_text = nullptr;
for (key_setting *ks : key_settings) {
delete[] ks->button_name;
@@ -102,23 +103,10 @@ GUIKeyChangeMenu::~GUIKeyChangeMenu()
key_settings.clear();
}
-void GUIKeyChangeMenu::removeChildren()
-{
- const core::list<gui::IGUIElement*> &children = getChildren();
- core::list<gui::IGUIElement*> children_copy;
- for (gui::IGUIElement*i : children) {
- children_copy.push_back(i);
- }
-
- for (gui::IGUIElement *i : children_copy) {
- i->remove();
- }
- key_used_text = nullptr;
-}
-
void GUIKeyChangeMenu::regenerateGui(v2u32 screensize)
{
- removeChildren();
+ removeAllChildren();
+ key_used_text = nullptr;
const float s = m_gui_scale;
DesiredRect = core::rect<s32>(
@@ -136,7 +124,7 @@ void GUIKeyChangeMenu::regenerateGui(v2u32 screensize)
core::rect<s32> rect(0, 0, 600 * s, 40 * s);
rect += topleft + v2s32(25 * s, 3 * s);
//gui::IGUIStaticText *t =
- const wchar_t *text = wgettext("Keybindings. (If this menu screws up, remove stuff from minetest.conf)");
+ const wchar_t *text = wgettext("Keybindings.");
Environment->addStaticText(text,
rect, false, true, this, -1);
delete[] text;
diff --git a/src/gui/guiKeyChangeMenu.h b/src/gui/guiKeyChangeMenu.h
index 1c0f40247..84a898774 100644
--- a/src/gui/guiKeyChangeMenu.h
+++ b/src/gui/guiKeyChangeMenu.h
@@ -46,7 +46,6 @@ public:
IMenuManager *menumgr, ISimpleTextureSource *tsrc);
~GUIKeyChangeMenu();
- void removeChildren();
/*
Remove and re-add (or reposition) stuff
*/
diff --git a/src/gui/guiMainMenu.h b/src/gui/guiMainMenu.h
index 1dca8bf2d..9b8ff383c 100644
--- a/src/gui/guiMainMenu.h
+++ b/src/gui/guiMainMenu.h
@@ -20,6 +20,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#pragma once
#include "irrlichttypes_extrabloated.h"
+#include "gameparams.h"
#include <string>
#include <list>
@@ -50,5 +51,7 @@ struct MainMenuData {
// Data to be passed to the script
MainMenuDataForScript script_data;
+ ELoginRegister allow_login_or_register = ELoginRegister::Any;
+
MainMenuData() = default;
};
diff --git a/src/gui/guiPasswordChange.cpp b/src/gui/guiPasswordChange.cpp
index c983260f6..c39df176b 100644
--- a/src/gui/guiPasswordChange.cpp
+++ b/src/gui/guiPasswordChange.cpp
@@ -51,23 +51,6 @@ GUIPasswordChange::GUIPasswordChange(gui::IGUIEnvironment* env,
{
}
-GUIPasswordChange::~GUIPasswordChange()
-{
- removeChildren();
-}
-
-void GUIPasswordChange::removeChildren()
-{
- const core::list<gui::IGUIElement *> &children = getChildren();
- core::list<gui::IGUIElement *> children_copy;
- for (gui::IGUIElement *i : children) {
- children_copy.push_back(i);
- }
-
- for (gui::IGUIElement *i : children_copy) {
- i->remove();
- }
-}
void GUIPasswordChange::regenerateGui(v2u32 screensize)
{
/*
@@ -78,7 +61,7 @@ void GUIPasswordChange::regenerateGui(v2u32 screensize)
/*
Remove stuff
*/
- removeChildren();
+ removeAllChildren();
/*
Calculate new sizes and positions
diff --git a/src/gui/guiPasswordChange.h b/src/gui/guiPasswordChange.h
index 7141100c0..452702add 100644
--- a/src/gui/guiPasswordChange.h
+++ b/src/gui/guiPasswordChange.h
@@ -31,9 +31,7 @@ public:
GUIPasswordChange(gui::IGUIEnvironment *env, gui::IGUIElement *parent, s32 id,
IMenuManager *menumgr, Client *client,
ISimpleTextureSource *tsrc);
- ~GUIPasswordChange();
- void removeChildren();
/*
Remove and re-add (or reposition) stuff
*/
diff --git a/src/gui/guiPathSelectMenu.cpp b/src/gui/guiPathSelectMenu.cpp
index 489927a11..9c63e06b5 100644
--- a/src/gui/guiPathSelectMenu.cpp
+++ b/src/gui/guiPathSelectMenu.cpp
@@ -32,13 +32,12 @@ GUIFileSelectMenu::GUIFileSelectMenu(gui::IGUIEnvironment* env,
GUIFileSelectMenu::~GUIFileSelectMenu()
{
- removeChildren();
setlocale(LC_NUMERIC, "C");
}
void GUIFileSelectMenu::regenerateGui(v2u32 screensize)
{
- removeChildren();
+ removeAllChildren();
m_fileOpenDialog = 0;
core::dimension2du size(600 * m_gui_scale, 400 * m_gui_scale);
diff --git a/src/gui/guiScrollContainer.cpp b/src/gui/guiScrollContainer.cpp
index 0fe4c41bd..2d71f3453 100644
--- a/src/gui/guiScrollContainer.cpp
+++ b/src/gui/guiScrollContainer.cpp
@@ -59,12 +59,11 @@ bool GUIScrollContainer::OnEvent(const SEvent &event)
void GUIScrollContainer::draw()
{
if (isVisible()) {
- core::list<IGUIElement *>::Iterator it = Children.begin();
- for (; it != Children.end(); ++it)
- if ((*it)->isNotClipped() ||
+ for (auto child : Children)
+ if (child->isNotClipped() ||
AbsoluteClippingRect.isRectCollided(
- (*it)->getAbsolutePosition()))
- (*it)->draw();
+ child->getAbsolutePosition()))
+ child->draw();
}
}
diff --git a/src/gui/guiTable.cpp b/src/gui/guiTable.cpp
index 79ae1aea3..3929d678b 100644
--- a/src/gui/guiTable.cpp
+++ b/src/gui/guiTable.cpp
@@ -84,7 +84,7 @@ GUITable::GUITable(gui::IGUIEnvironment *env,
#endif
core::rect<s32> relative_rect = m_scrollbar->getRelativePosition();
s32 width = (relative_rect.getWidth() / (2.0 / 3.0)) * density *
- g_settings->getFloat("gui_scaling");
+ g_settings->getFloat("gui_scaling", 0.5f, 20.0f);
m_scrollbar->setRelativePosition(core::rect<s32>(
relative_rect.LowerRightCorner.X-width,relative_rect.UpperLeftCorner.Y,
relative_rect.LowerRightCorner.X,relative_rect.LowerRightCorner.Y
diff --git a/src/gui/guiVolumeChange.cpp b/src/gui/guiVolumeChange.cpp
index 61ab758a1..0f6f43fe9 100644
--- a/src/gui/guiVolumeChange.cpp
+++ b/src/gui/guiVolumeChange.cpp
@@ -45,32 +45,12 @@ GUIVolumeChange::GUIVolumeChange(gui::IGUIEnvironment* env,
{
}
-GUIVolumeChange::~GUIVolumeChange()
-{
- removeChildren();
-}
-
-void GUIVolumeChange::removeChildren()
-{
- if (gui::IGUIElement *e = getElementFromId(ID_soundText))
- e->remove();
-
- if (gui::IGUIElement *e = getElementFromId(ID_soundExitButton))
- e->remove();
-
- if (gui::IGUIElement *e = getElementFromId(ID_soundSlider))
- e->remove();
-
- if (gui::IGUIElement *e = getElementFromId(ID_soundMuteButton))
- e->remove();
-}
-
void GUIVolumeChange::regenerateGui(v2u32 screensize)
{
/*
Remove stuff
*/
- removeChildren();
+ removeAllChildren();
/*
Calculate new sizes and positions
*/
diff --git a/src/gui/guiVolumeChange.h b/src/gui/guiVolumeChange.h
index 466e17f9d..ccdaca00b 100644
--- a/src/gui/guiVolumeChange.h
+++ b/src/gui/guiVolumeChange.h
@@ -31,9 +31,6 @@ public:
GUIVolumeChange(gui::IGUIEnvironment* env,
gui::IGUIElement* parent, s32 id,
IMenuManager *menumgr, ISimpleTextureSource *tsrc);
- ~GUIVolumeChange();
-
- void removeChildren();
/*
Remove and re-add (or reposition) stuff
*/
diff --git a/src/gui/mainmenumanager.h b/src/gui/mainmenumanager.h
index 102492255..76d357340 100644
--- a/src/gui/mainmenumanager.h
+++ b/src/gui/mainmenumanager.h
@@ -64,10 +64,6 @@ public:
// Remove all entries if there are duplicates
m_stack.remove(menu);
- /*core::list<GUIModalMenu*>::Iterator i = m_stack.getLast();
- assert(*i == menu);
- m_stack.erase(i);*/
-
if(!m_stack.empty())
m_stack.back()->setVisible(true);
}
diff --git a/src/gui/modalMenu.cpp b/src/gui/modalMenu.cpp
index 56a5d2cb9..cfc4d5c5a 100644
--- a/src/gui/modalMenu.cpp
+++ b/src/gui/modalMenu.cpp
@@ -40,7 +40,7 @@ GUIModalMenu::GUIModalMenu(gui::IGUIEnvironment* env, gui::IGUIElement* parent,
m_menumgr(menumgr),
m_remap_dbl_click(remap_dbl_click)
{
- m_gui_scale = g_settings->getFloat("gui_scaling");
+ m_gui_scale = std::max(g_settings->getFloat("gui_scaling"), 0.5f);
#ifdef HAVE_TOUCHSCREENGUI
float d = RenderingEngine::getDisplayDensity();
m_gui_scale *= 1.1 - 0.3 * d + 0.2 * d * d;
@@ -108,19 +108,6 @@ void GUIModalMenu::quitMenu()
#endif
}
-void GUIModalMenu::removeChildren()
-{
- const core::list<gui::IGUIElement *> &children = getChildren();
- core::list<gui::IGUIElement *> children_copy;
- for (gui::IGUIElement *i : children) {
- children_copy.push_back(i);
- }
-
- for (gui::IGUIElement *i : children_copy) {
- i->remove();
- }
-}
-
// clang-format off
bool GUIModalMenu::DoubleClickDetection(const SEvent &event)
{
@@ -265,13 +252,6 @@ bool GUIModalMenu::preprocessEvent(const SEvent &event)
return retval;
m_jni_field_name = field_name;
- /*~ Imperative, as in "Enter/type in text".
- Don't forget the space. */
- std::string message = gettext("Enter ");
- std::string label = wide_to_utf8(getLabelByID(hovered->getID()));
- if (label.empty())
- label = "text";
- message += strgettext(label) + ":";
// single line text input
int type = 2;
diff --git a/src/gui/modalMenu.h b/src/gui/modalMenu.h
index 06e78f06b..e37c41533 100644
--- a/src/gui/modalMenu.h
+++ b/src/gui/modalMenu.h
@@ -47,7 +47,6 @@ public:
bool canTakeFocus(gui::IGUIElement *e);
void draw();
void quitMenu();
- void removeChildren();
virtual void regenerateGui(v2u32 screensize) = 0;
virtual void drawMenu() = 0;
diff --git a/src/gui/touchscreengui.cpp b/src/gui/touchscreengui.cpp
index ebe1a6325..d483c136e 100644
--- a/src/gui/touchscreengui.cpp
+++ b/src/gui/touchscreengui.cpp
@@ -843,7 +843,7 @@ void TouchScreenGUI::translateEvent(const SEvent &event)
s32 dy = Y - m_pointerpos[event.TouchInput.ID].Y;
// adapt to similar behaviour as pc screen
- double d = g_settings->getFloat("mouse_sensitivity") * 3.0f;
+ const double d = g_settings->getFloat("mouse_sensitivity", 0.001f, 10.0f) * 3.0f;
m_camera_yaw_change -= dx * d;
m_camera_pitch = MYMIN(MYMAX(m_camera_pitch + (dy * d), -180), 180);