1
0
Fork 0

TouchScreenGUI: handle screen resizing and fix memory leaks

(cherry picked from commit 9c5c0dcd3c)
merge-requests/1/head
Deve 2023-07-30 18:56:10 +02:00 committed by mckaygerhard
parent 9b03f0a82e
commit 4157a8c8e1
2 changed files with 166 additions and 107 deletions

View File

@ -130,7 +130,7 @@ static irr::EKEY_CODE id2keycode(touch_gui_button_id id)
TouchScreenGUI *g_touchscreengui;
static void load_button_texture(button_info *btn, const char *path,
static void load_button_texture(const button_info *btn, const char *path,
const rect<s32> &button_rect, ISimpleTextureSource *tsrc, video::IVideoDriver *driver)
{
u32 tid;
@ -252,7 +252,7 @@ void AutoHideButtonBar::addButton(touch_gui_button_id button_id,
m_lower_right.Y, y_end);
}
auto *btn = new button_info();
std::shared_ptr<button_info> btn(new button_info);
btn->guibutton = m_guienv->addButton(current_button,
nullptr, button_id, caption, nullptr);
btn->guibutton->grab();
@ -263,7 +263,7 @@ void AutoHideButtonBar::addButton(touch_gui_button_id button_id,
btn->immediate_release = true;
btn->ids.clear();
load_button_texture(btn, btn_image, current_button, m_texturesource,
load_button_texture(btn.get(), btn_image, current_button, m_texturesource,
m_driver);
m_buttons.push_back(btn);
@ -274,7 +274,7 @@ void AutoHideButtonBar::addButton(touch_gui_button_id button_id,
const char *btn_image_2)
{
addButton(button_id, caption, btn_image_1);
button_info *btn = m_buttons.back();
std::shared_ptr<button_info> btn = m_buttons.back();
btn->togglable = 1;
btn->textures.push_back(btn_image_1);
btn->textures.push_back(btn_image_2);
@ -295,15 +295,13 @@ bool AutoHideButtonBar::isButton(const SEvent &event)
if (m_active) {
// check for all buttons in vector
auto iter = m_buttons.begin();
while (iter != m_buttons.end()) {
if ((*iter)->guibutton == element) {
for (const auto &button : m_buttons) {
if (button->guibutton == element) {
auto *translated = new SEvent();
memset(translated, 0, sizeof(SEvent));
translated->EventType = irr::EET_KEY_INPUT_EVENT;
translated->KeyInput.Key = (*iter)->keycode;
translated->KeyInput.Key = button->keycode;
translated->KeyInput.Control = false;
translated->KeyInput.Shift = false;
translated->KeyInput.Char = 0;
@ -318,25 +316,24 @@ bool AutoHideButtonBar::isButton(const SEvent &event)
delete translated;
(*iter)->ids.push_back(event.TouchInput.ID);
button->ids.push_back(event.TouchInput.ID);
m_timeout = 0;
if ((*iter)->togglable == 1) {
(*iter)->togglable = 2;
load_button_texture(*iter, (*iter)->textures[1],
(*iter)->guibutton->getRelativePosition(),
if (button->togglable == 1) {
button->togglable = 2;
load_button_texture(button.get(), button->textures[1],
button->guibutton->getRelativePosition(),
m_texturesource, m_driver);
} else if ((*iter)->togglable == 2) {
(*iter)->togglable = 1;
load_button_texture(*iter, (*iter)->textures[0],
(*iter)->guibutton->getRelativePosition(),
} else if (button->togglable == 2) {
button->togglable = 1;
load_button_texture(button.get(), button->textures[0],
button->guibutton->getRelativePosition(),
m_texturesource, m_driver);
}
return true;
}
++iter;
}
} else {
// check for starter button only
@ -462,21 +459,141 @@ void TouchScreenGUI::initButton(touch_gui_button_id id, const rect<s32> &button_
m_texturesource, m_device->getVideoDriver());
}
button_info *TouchScreenGUI::initJoystickButton(touch_gui_button_id id,
std::shared_ptr<button_info> TouchScreenGUI::initJoystickButton(touch_gui_button_id id,
const rect<s32> &button_rect, s32 texture_id, bool visible)
{
auto *btn = new button_info();
std::shared_ptr<button_info> btn(new button_info);
btn->guibutton = m_guienv->addButton(button_rect, nullptr, id, L"O");
btn->guibutton->setVisible(visible && m_visible);
btn->guibutton->grab();
btn->ids.clear();
load_button_texture(btn, joystick_imagenames[texture_id],
load_button_texture(btn.get(), joystick_imagenames[texture_id],
button_rect, m_texturesource, m_device->getVideoDriver());
return btn;
}
rect<s32> TouchScreenGUI::getButtonRect(touch_gui_button_id id)
{
switch (id) {
case joystick_off_id:
if (m_fixed_joystick) {
return rect<s32>(button_size / 2,
m_screensize.Y - button_size * 4.5,
button_size * 4.5,
m_screensize.Y - button_size / 2);
} else {
return rect<s32>(button_size / 2,
m_screensize.Y - button_size * 3.5,
button_size * 3.5,
m_screensize.Y - button_size / 2);
}
case joystick_bg_id:
return rect<s32>(button_size / 2,
m_screensize.Y - button_size * 4.5,
button_size * 4.5,
m_screensize.Y - button_size / 2);
case joystick_center_id:
return rect<s32>(0, 0, button_size * 1.5, button_size * 1.5);
case jump_id:
return rect<s32>(m_screensize.X - button_size * 3.37,
m_screensize.Y - button_size * 2.75,
m_screensize.X - button_size * 1.87,
m_screensize.Y - button_size * 1.25);
case drop_id:
return rect<s32>(m_screensize.X - button_size,
m_screensize.Y / 2 - button_size * 1.5,
m_screensize.X,
m_screensize.Y / 2 - button_size / 2);
case crunch_id:
return rect<s32>(m_screensize.X - button_size * 3.38,
m_screensize.Y - button_size * 0.75,
m_screensize.X - button_size * 1.7,
m_screensize.Y);
case inventory_id:
return rect<s32>(m_screensize.X - button_size * 1.7,
m_screensize.Y - button_size * 1.5,
m_screensize.X,
m_screensize.Y);
//case zoom_id:
// return rect<s32>(m_screensize.X - (1.25 * button_size),
// m_screensize.Y - (4 * button_size),
// m_screensize.X - (0.25 * button_size),
// m_screensize.Y - (3 * button_size));
case special1_id:
return rect<s32>(m_screensize.X - button_size * 1.8,
m_screensize.Y - button_size * 4,
m_screensize.X - button_size * 0.3,
m_screensize.Y - button_size * 2.5);
case escape_id:
return rect<s32>(m_screensize.X / 2 - button_size * 2,
0,
m_screensize.X / 2 - button_size,
button_size);
case minimap_id:
return rect<s32>(m_screensize.X / 2 - button_size,
0,
m_screensize.X / 2,
button_size);
case range_id:
return rect<s32>(m_screensize.X / 2,
0,
m_screensize.X / 2 + button_size,
button_size);
case camera_id:
return rect<s32>(m_screensize.X / 2 + button_size,
0,
m_screensize.X / 2 + button_size * 2,
button_size);
case chat_id:
return rect<s32>(m_screensize.X - button_size * 1.25,
0,
m_screensize.X,
button_size);
default:
return rect<s32>(0, 0, 0, 0);
}
}
void TouchScreenGUI::updateButtons()
{
v2u32 screensize = m_device->getVideoDriver()->getScreenSize();
if (screensize != m_screensize) {
m_screensize = screensize;
button_size = std::min(m_screensize.Y / 4.5f,
RenderingEngine::getDisplayDensity() *
g_settings->getFloat("hud_scaling") * 65.0f);
for (auto &button : m_buttons) {
if (button.guibutton) {
s32 id = button.guibutton->getID();
rect<s32> rect = getButtonRect((touch_gui_button_id)id);
button.guibutton->setRelativePosition(rect);
}
}
if (m_joystick_btn_off->guibutton) {
s32 id = m_joystick_btn_off->guibutton->getID();
rect<s32> rect = getButtonRect((touch_gui_button_id)id);
m_joystick_btn_off->guibutton->setRelativePosition(rect);
}
if (m_joystick_btn_bg->guibutton) {
s32 id = m_joystick_btn_bg->guibutton->getID();
rect<s32> rect = getButtonRect((touch_gui_button_id)id);
m_joystick_btn_bg->guibutton->setRelativePosition(rect);
}
if (m_joystick_btn_center->guibutton) {
s32 id = m_joystick_btn_center->guibutton->getID();
rect<s32> rect = getButtonRect((touch_gui_button_id)id);
m_joystick_btn_center->guibutton->setRelativePosition(rect);
}
}
}
void TouchScreenGUI::init(ISimpleTextureSource *tsrc)
{
assert(tsrc);
@ -489,76 +606,36 @@ void TouchScreenGUI::init(ISimpleTextureSource *tsrc)
*/
if (m_fixed_joystick) {
m_joystick_btn_off = initJoystickButton(joystick_off_id,
rect<s32>(button_size / 2,
m_screensize.Y - button_size * 4.5,
button_size * 4.5,
m_screensize.Y - button_size / 2), 0);
getButtonRect(joystick_off_id), 0);
} else {
m_joystick_btn_off = initJoystickButton(joystick_off_id,
rect<s32>(button_size / 2,
m_screensize.Y - button_size * 3.5,
button_size * 3.5,
m_screensize.Y - button_size / 2), 0);
getButtonRect(joystick_off_id), 0);
}
m_joystick_btn_bg = initJoystickButton(joystick_bg_id,
rect<s32>(button_size / 2,
m_screensize.Y - button_size * 4.5,
button_size * 4.5,
m_screensize.Y - button_size / 2),
1, false);
getButtonRect(joystick_bg_id), 1, false);
m_joystick_btn_center = initJoystickButton(joystick_center_id,
rect<s32>(0, 0, button_size * 1.5, button_size * 1.5), 2, false);
getButtonRect(joystick_center_id), 2, false);
// init jump button
initButton(jump_id,
rect<s32>(m_screensize.X - button_size * 3.37,
m_screensize.Y - button_size * 2.75,
m_screensize.X - button_size * 1.87,
m_screensize.Y - button_size * 1.25),
L"x", false);
initButton(jump_id, getButtonRect(jump_id), L"x", false);
// init drop button
initButton(drop_id,
rect<s32>(m_screensize.X - button_size,
m_screensize.Y / 2 - button_size * 1.5,
m_screensize.X,
m_screensize.Y / 2 - button_size / 2),
L"drop", false);
initButton(drop_id, getButtonRect(drop_id), L"drop", false);
// init crunch button
initButton(crunch_id,
rect<s32>(m_screensize.X - button_size * 3.38,
m_screensize.Y - button_size * 0.75,
m_screensize.X - button_size * 1.7,
m_screensize.Y),
L"H", false);
initButton(crunch_id, getButtonRect(crunch_id), L"H", false);
// init inventory button
initButton(inventory_id,
rect<s32>(m_screensize.X - button_size * 1.7,
m_screensize.Y - button_size * 1.5,
m_screensize.X,
m_screensize.Y),
L"inv", false);
initButton(inventory_id, getButtonRect(inventory_id), L"inv", false);
// init zoom button
/* initButton(zoom_id,
rect<s32>(m_screensize.X - (1.25 * button_size),
m_screensize.Y - (4 * button_size),
m_screensize.X - (0.25 * button_size),
m_screensize.Y - (3 * button_size)),
L"z", false);*/
// initButton(zoom_id, getButtonRect(zoom_id), L"z", false);
// init special1/aux button
if (!m_joystick_triggers_special1)
initButton(special1_id,
rect<s32>(m_screensize.X - button_size * 1.8,
m_screensize.Y - button_size * 4,
m_screensize.X - button_size * 0.3,
m_screensize.Y - button_size * 2.5),
L"spc1", false);
initButton(special1_id, getButtonRect(special1_id), L"spc1", false);
/* m_settingsbar.init(m_texturesource, "gear_icon.png", settings_starter_id,
v2s32(m_screensize.X - (1.25 * button_size),
@ -593,44 +670,19 @@ void TouchScreenGUI::init(ISimpleTextureSource *tsrc)
m_rarecontrolsbar.addButton(drop_id, L"drop", "drop_btn.png");*/
// init pause button [1]
initButton(escape_id,
rect<s32>(m_screensize.X / 2 - button_size * 2,
0,
m_screensize.X / 2 - button_size,
button_size),
L"Exit", false);
initButton(escape_id, getButtonRect(escape_id), L"Exit", false);
// init minimap button [2]
initButton(minimap_id,
rect<s32>(m_screensize.X / 2 - button_size,
0,
m_screensize.X / 2,
button_size),
L"minimap", false);
initButton(minimap_id, getButtonRect(minimap_id), L"minimap", false);
// init rangeselect button [3]
initButton(range_id,
rect<s32>(m_screensize.X / 2,
0,
m_screensize.X / 2 + button_size,
button_size),
L"rangeview", false);
initButton(range_id, getButtonRect(range_id), L"rangeview", false);
// init camera button [4]
initButton(camera_id,
rect<s32>(m_screensize.X / 2 + button_size,
0,
m_screensize.X / 2 + button_size * 2,
button_size),
L"camera", false);
initButton(camera_id, getButtonRect(camera_id), L"camera", false);
// init chat button
initButton(chat_id,
rect<s32>(m_screensize.X - button_size * 1.25,
0,
m_screensize.X,
button_size),
L"Chat", false);
initButton(chat_id, getButtonRect(chat_id), L"Chat", false);
m_buttons_initialized = true;
}
@ -1161,6 +1213,8 @@ TouchScreenGUI::~TouchScreenGUI()
void TouchScreenGUI::step(float dtime)
{
updateButtons();
// simulate keyboard repeats
for (auto &button : m_buttons) {
if (!button.ids.empty()) {

View File

@ -26,6 +26,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include <IrrlichtDevice.h>
#include <map>
#include <memory>
#include <vector>
#include "client/tile.h"
@ -144,7 +145,7 @@ private:
IGUIEnvironment *m_guienv;
IEventReceiver *m_receiver;
button_info m_starter;
std::vector<button_info *> m_buttons;
std::vector<std::shared_ptr<button_info>> m_buttons;
v2s32 m_upper_left;
v2s32 m_lower_right;
@ -256,9 +257,9 @@ private:
bool m_joystick_has_really_moved = false;
bool m_fixed_joystick = false;
bool m_joystick_triggers_special1 = false;
button_info *m_joystick_btn_off = nullptr;
button_info *m_joystick_btn_bg = nullptr;
button_info *m_joystick_btn_center = nullptr;
std::shared_ptr<button_info> m_joystick_btn_off = nullptr;
std::shared_ptr<button_info> m_joystick_btn_bg = nullptr;
std::shared_ptr<button_info> m_joystick_btn_center = nullptr;
button_info m_buttons[after_last_element_id];
@ -277,10 +278,14 @@ private:
float repeat_delay = BUTTON_REPEAT_DELAY);
// initialize a joystick button
button_info *initJoystickButton(touch_gui_button_id id,
std::shared_ptr<button_info> initJoystickButton(touch_gui_button_id id,
const rect<s32> &button_rect, s32 texture_id,
bool visible = true);
rect<s32> getButtonRect(touch_gui_button_id id);
void updateButtons();
void moveJoystick(const SEvent &event, float dx, float dy);
struct id_status