Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TouchScreenGUI: Fix only 9 hotbar slots being usable #13698

Merged
merged 3 commits into from
Aug 24, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
8 changes: 8 additions & 0 deletions src/client/game.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2168,6 +2168,14 @@ void Game::processItemSelection(u16 *new_playeritem)
}
}

#ifdef HAVE_TOUCHSCREENGUI
if (g_touchscreengui) {
std::optional<u16> selection = g_touchscreengui->getHotbarSelection();
if (selection)
*new_playeritem = *selection;
}
#endif

// Clamp selection again in case it wasn't changed but max_item was
*new_playeritem = MYMIN(*new_playeritem, max_item);
}
Expand Down
39 changes: 21 additions & 18 deletions src/client/hud.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -223,16 +223,12 @@ void Hud::drawItem(const ItemStack &item, const core::rect<s32>& rect,
client, selected ? IT_ROT_SELECTED : IT_ROT_NONE);
}

//NOTE: selectitem = 0 -> no selected; selectitem 1-based
// NOTE: selectitem = 0 -> no selected; selectitem is 1-based
// mainlist can be NULL, but draw the frame anyway.
void Hud::drawItems(v2s32 upperleftpos, v2s32 screen_offset, s32 itemcount,
s32 inv_offset, InventoryList *mainlist, u16 selectitem, u16 direction)
s32 inv_offset, InventoryList *mainlist, u16 selectitem, u16 direction,
bool is_hotbar)
{
#ifdef HAVE_TOUCHSCREENGUI
if (g_touchscreengui && inv_offset == 0)
g_touchscreengui->resetHud();
#endif

s32 height = m_hotbar_imagesize + m_padding * 2;
s32 width = (itemcount - inv_offset) * (m_hotbar_imagesize + m_padding * 2);

Expand Down Expand Up @@ -292,11 +288,13 @@ void Hud::drawItems(v2s32 upperleftpos, v2s32 screen_offset, s32 itemcount,
break;
}

drawItem(mainlist->getItem(i), (imgrect + pos + steppos), (i + 1) == selectitem);
core::rect<s32> item_rect = imgrect + pos + steppos;

drawItem(mainlist->getItem(i), item_rect, (i + 1) == selectitem);

#ifdef HAVE_TOUCHSCREENGUI
if (g_touchscreengui)
g_touchscreengui->registerHudItem(i, (imgrect + pos + steppos));
if (is_hotbar && g_touchscreengui)
g_touchscreengui->registerHotbarRect(i, item_rect);
#endif
}
}
Expand Down Expand Up @@ -406,7 +404,7 @@ void Hud::drawLuaElements(const v3s16 &camera_offset)
if (!inv)
warningstream << "HUD: Unknown inventory list. name=" << e->text << std::endl;
drawItems(pos, v2s32(e->offset.X, e->offset.Y), e->number, 0,
inv, e->item, e->dir);
inv, e->item, e->dir, false);
break; }
case HUD_ELEM_WAYPOINT: {
if (!calculateScreenPos(camera_offset, e, &pos))
Expand Down Expand Up @@ -739,16 +737,21 @@ void Hud::drawStatbar(v2s32 pos, u16 corner, u16 drawdir,
}


void Hud::drawHotbar(u16 playeritem) {

v2s32 centerlowerpos(m_displaycenter.X, m_screensize.Y);
void Hud::drawHotbar(u16 playeritem)
{
#ifdef HAVE_TOUCHSCREENGUI
if (g_touchscreengui)
g_touchscreengui->resetHotbarRects();
#endif

InventoryList *mainlist = inventory->getList("main");
if (mainlist == NULL) {
//silently ignore this we may not be initialized completely
// Silently ignore this. We may not be initialized completely.
return;
}

v2s32 centerlowerpos(m_displaycenter.X, m_screensize.Y);

s32 hotbar_itemcount = player->hud_hotbar_itemcount;
s32 width = hotbar_itemcount * (m_hotbar_imagesize + m_padding * 2);
v2s32 pos = centerlowerpos - v2s32(width / 2, m_hotbar_imagesize + m_padding * 3);
Expand All @@ -757,7 +760,7 @@ void Hud::drawHotbar(u16 playeritem) {
if ((float) width / (float) window_size.X <=
g_settings->getFloat("hud_hotbar_max_width")) {
if (player->hud_flags & HUD_FLAG_HOTBAR_VISIBLE) {
drawItems(pos, v2s32(0, 0), hotbar_itemcount, 0, mainlist, playeritem + 1, 0);
drawItems(pos, v2s32(0, 0), hotbar_itemcount, 0, mainlist, playeritem + 1, 0, true);
}
} else {
pos.X += width/4;
Expand All @@ -767,9 +770,9 @@ void Hud::drawHotbar(u16 playeritem) {

if (player->hud_flags & HUD_FLAG_HOTBAR_VISIBLE) {
drawItems(pos, v2s32(0, 0), hotbar_itemcount / 2, 0,
mainlist, playeritem + 1, 0);
mainlist, playeritem + 1, 0, true);
drawItems(secondpos, v2s32(0, 0), hotbar_itemcount,
hotbar_itemcount / 2, mainlist, playeritem + 1, 0);
hotbar_itemcount / 2, mainlist, playeritem + 1, 0, true);
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/client/hud.h
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ class Hud

void drawItems(v2s32 upperleftpos, v2s32 screen_offset, s32 itemcount,
s32 inv_offset, InventoryList *mainlist, u16 selectitem,
u16 direction);
u16 direction, bool is_hotbar);

void drawItem(const ItemStack &item, const core::rect<s32> &rect, bool selected);

Expand Down
39 changes: 21 additions & 18 deletions src/gui/touchscreengui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -583,25 +583,28 @@ touch_gui_button_id TouchScreenGUI::getButtonID(size_t eventID)
return after_last_element_id;
}

bool TouchScreenGUI::isHUDButton(const SEvent &event)
bool TouchScreenGUI::isHotbarButton(const SEvent &event)
{
// check if hud item is pressed
for (auto &hud_rect : m_hud_rects) {
if (hud_rect.second.isPointInside(v2s32(event.TouchInput.X, event.TouchInput.Y))) {
SEvent translated{};
translated.EventType = irr::EET_KEY_INPUT_EVENT;
translated.KeyInput.Key = (irr::EKEY_CODE) (KEY_KEY_1 + hud_rect.first);
translated.KeyInput.Control = false;
translated.KeyInput.Shift = false;
translated.KeyInput.PressedDown = true;
m_receiver->OnEvent(translated);
m_hud_ids[event.TouchInput.ID] = translated.KeyInput.Key;
const v2s32 touch_pos = v2s32(event.TouchInput.X, event.TouchInput.Y);
// check if hotbar item is pressed
for (auto &[index, rect] : m_hotbar_rects) {
if (rect.isPointInside(touch_pos)) {
// We can't just emit a keypress event because the number keys
// range from 1 to 9, but there may be more hotbar items.
m_hotbar_selection = index;
return true;
}
}
return false;
}

std::optional<u16> TouchScreenGUI::getHotbarSelection()
{
auto selection = m_hotbar_selection;
m_hotbar_selection = std::nullopt;
return selection;
}

void TouchScreenGUI::handleButtonEvent(touch_gui_button_id button,
size_t eventID, bool action)
{
Expand Down Expand Up @@ -745,10 +748,10 @@ void TouchScreenGUI::translateEvent(const SEvent &event)
handleButtonEvent(button, eventID, true);
m_settings_bar.deactivate();
m_rare_controls_bar.deactivate();
} else if (isHUDButton(event)) {
} else if (isHotbarButton(event)) {
m_settings_bar.deactivate();
m_rare_controls_bar.deactivate();
// already handled in isHUDButton()
// already handled in isHotbarButton()
} else if (m_settings_bar.isButton(event)) {
m_rare_controls_bar.deactivate();
// already handled in isSettingsBarButton()
Expand Down Expand Up @@ -1071,14 +1074,14 @@ void TouchScreenGUI::step(float dtime)
m_rare_controls_bar.step(dtime);
}

void TouchScreenGUI::resetHud()
void TouchScreenGUI::resetHotbarRects()
{
m_hud_rects.clear();
m_hotbar_rects.clear();
}

void TouchScreenGUI::registerHudItem(int index, const rect<s32> &rect)
void TouchScreenGUI::registerHotbarRect(u16 index, const rect<s32> &rect)
{
m_hud_rects[index] = rect;
m_hotbar_rects[index] = rect;
}

void TouchScreenGUI::setVisible(bool visible)
Expand Down
20 changes: 12 additions & 8 deletions src/gui/touchscreengui.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include <IGUIEnvironment.h>
#include <IrrlichtDevice.h>

#include <map>
#include <memory>
#include <optional>
#include <unordered_map>
#include <vector>

#include "client/tile.h"
Expand Down Expand Up @@ -186,14 +187,16 @@ class TouchScreenGUI
float getMovementSpeed() { return m_joystick_speed; }

void step(float dtime);
void resetHud();
void registerHudItem(int index, const rect<s32> &rect);
inline void setUseCrosshair(bool use_crosshair) { m_draw_crosshair = use_crosshair; }

void setVisible(bool visible);
void hide();
void show();

void resetHotbarRects();
void registerHotbarRect(u16 index, const rect<s32> &rect);
std::optional<u16> getHotbarSelection();

private:
bool m_initialized = false;
IrrlichtDevice *m_device;
Expand All @@ -203,10 +206,11 @@ class TouchScreenGUI
v2u32 m_screensize;
s32 button_size;
double m_touchscreen_threshold;
std::map<int, rect<s32>> m_hud_rects;
std::map<size_t, EKEY_CODE> m_hud_ids;
bool m_visible; // is the whole touch screen gui visible

std::unordered_map<u16, rect<s32>> m_hotbar_rects;
std::optional<u16> m_hotbar_selection = std::nullopt;

// value in degree
double m_camera_yaw_change = 0.0;
double m_camera_pitch = 0.0;
Expand Down Expand Up @@ -272,8 +276,8 @@ class TouchScreenGUI
// handle a button event
void handleButtonEvent(touch_gui_button_id bID, size_t eventID, bool action);

// handle pressed hud buttons
bool isHUDButton(const SEvent &event);
// handle pressing hotbar items
bool isHotbarButton(const SEvent &event);

// do a right-click
bool doRightClick();
Expand All @@ -285,7 +289,7 @@ class TouchScreenGUI
void applyJoystickStatus();

// array for saving last known position of a pointer
std::map<size_t, v2s32> m_pointer_pos;
std::unordered_map<size_t, v2s32> m_pointer_pos;

// settings bar
AutoHideButtonBar m_settings_bar;
Expand Down