]> git.lizzy.rs Git - minetest.git/commitdiff
Android: Implement Autohiding button bars to cleanup screen
authorSapier <sapier@does.not.have.an.email>
Sun, 13 Dec 2015 22:00:05 +0000 (23:00 +0100)
committerSapier <sapier AT gmx dot net>
Fri, 18 Dec 2015 19:35:54 +0000 (20:35 +0100)
src/game.cpp
src/modalMenu.h
src/touchscreengui.cpp
src/touchscreengui.h
textures/base/pack/drop_btn.png
textures/base/pack/gear_icon.png [new file with mode: 0644]
textures/base/pack/rare_controls.png [new file with mode: 0644]

index f6d59e4e38ddce7b7f36e171ea91481e297d7a4d..3f025f6de6b11d3ce2bd728e8de60a0c1d13b4b1 100644 (file)
@@ -2173,7 +2173,7 @@ bool Game::initGui()
 #ifdef HAVE_TOUCHSCREENGUI
 
        if (g_touchscreengui)
-               g_touchscreengui->init(texture_src, porting::getDisplayDensity());
+               g_touchscreengui->init(texture_src);
 
 #endif
 
@@ -2570,7 +2570,7 @@ void Game::processUserInput(VolatileRunFlags *flags,
                        || guienv->hasFocus(gui_chat_console)) {
                input->clear();
 #ifdef HAVE_TOUCHSCREENGUI
-               g_touchscreengui->Hide();
+               g_touchscreengui->hide();
 #endif
        }
 #ifdef HAVE_TOUCHSCREENGUI
index 72ecedcb9ca7e32e286548457b2cfff6734cc872..d5e975a87d5242b429fba5fb6fc6c475a28a2cd7 100644 (file)
@@ -108,7 +108,7 @@ class GUIModalMenu : public gui::IGUIElement
                this->remove();
 #ifdef HAVE_TOUCHSCREENGUI
                if (g_touchscreengui)
-                       g_touchscreengui->Show();
+                       g_touchscreengui->show();
 #endif
        }
 
index f0ad002d6e11680b04a25b7ffb4d355f8a58ea67..f51b2d5fa37561a05fccc6dc8761706e46b58773 100644 (file)
@@ -44,17 +44,8 @@ const char** touchgui_button_imagenames = (const char*[]) {
        "down_arrow.png",
        "left_arrow.png",
        "right_arrow.png",
-       "inventory_btn.png",
-       "drop_btn.png",
        "jump_btn.png",
-       "down.png",
-       "fly_btn.png",
-       "noclip_btn.png",
-       "fast_btn.png",
-       "debug_btn.png",
-       "chat_btn.png",
-       "camera_btn.png",
-       "rangeview_btn.png"
+       "down.png"
 };
 
 static irr::EKEY_CODE id2keycode(touch_gui_button_id id)
@@ -113,29 +104,13 @@ static irr::EKEY_CODE id2keycode(touch_gui_button_id id)
 
 TouchScreenGUI *g_touchscreengui;
 
-TouchScreenGUI::TouchScreenGUI(IrrlichtDevice *device, IEventReceiver* receiver):
-       m_device(device),
-       m_guienv(device->getGUIEnvironment()),
-       m_camera_yaw(0.0),
-       m_camera_pitch(0.0),
-       m_visible(false),
-       m_move_id(-1),
-       m_receiver(receiver)
-{
-       for (unsigned int i=0; i < after_last_element_id; i++) {
-               m_buttons[i].guibutton     =  0;
-               m_buttons[i].repeatcounter = -1;
-               m_buttons[i].repeatdelay   = BUTTON_REPEAT_DELAY;
-       }
-
-       m_screensize = m_device->getVideoDriver()->getScreenSize();
-}
-
-void TouchScreenGUI::loadButtonTexture(button_info* btn, const char* path, rect<s32> button_rect)
+static void load_button_texture(button_info* btn, const char* path,
+               rect<s32> button_rect, ISimpleTextureSource* tsrc, video::IVideoDriver *driver)
 {
        unsigned int tid;
-       video::ITexture *texture = guiScalingImageButton(m_device->getVideoDriver(),
-               m_texturesource->getTexture(path, &tid), button_rect.getWidth(), button_rect.getHeight());
+       video::ITexture *texture = guiScalingImageButton(driver,
+                       tsrc->getTexture(path, &tid), button_rect.getWidth(),
+                       button_rect.getHeight());
        if (texture) {
                btn->guibutton->setUseAlphaChannel(true);
                if (g_settings->getBool("gui_scaling_filter")) {
@@ -153,6 +128,314 @@ void TouchScreenGUI::loadButtonTexture(button_info* btn, const char* path, rect<
                }
 }
 
+AutoHideButtonBar::AutoHideButtonBar(IrrlichtDevice *device,
+               IEventReceiver* receiver) :
+                       m_texturesource(NULL),
+                       m_driver(device->getVideoDriver()),
+                       m_guienv(device->getGUIEnvironment()),
+                       m_receiver(receiver),
+                       m_active(false),
+                       m_visible(true),
+                       m_timeout(0),
+                       m_timeout_value(3),
+                       m_initialized(false),
+                       m_dir(AHBB_Dir_Right_Left)
+{
+       m_screensize = device->getVideoDriver()->getScreenSize();
+
+}
+
+void AutoHideButtonBar::init(ISimpleTextureSource* tsrc,
+               const char* starter_img, int button_id, v2s32 UpperLeft,
+               v2s32 LowerRight, autohide_button_bar_dir dir, float timeout)
+{
+       m_texturesource = tsrc;
+
+       m_upper_left = UpperLeft;
+       m_lower_right = LowerRight;
+
+       /* init settings bar */
+
+       irr::core::rect<int> current_button = rect<s32>(UpperLeft.X, UpperLeft.Y,
+                       LowerRight.X, LowerRight.Y);
+
+       m_starter.guibutton         = m_guienv->addButton(current_button, 0, button_id, L"", 0);
+       m_starter.guibutton->grab();
+       m_starter.repeatcounter     = -1;
+       m_starter.keycode           = KEY_OEM_8; // use invalid keycode as it's not relevant
+       m_starter.immediate_release = true;
+       m_starter.ids.clear();
+
+       load_button_texture(&m_starter, starter_img, current_button,
+                       m_texturesource, m_driver);
+
+       m_dir = dir;
+       m_timeout_value = timeout;
+
+       m_initialized = true;
+}
+
+AutoHideButtonBar::~AutoHideButtonBar()
+{
+       m_starter.guibutton->setVisible(false);
+       m_starter.guibutton->drop();
+}
+
+void AutoHideButtonBar::addButton(touch_gui_button_id button_id,
+               const wchar_t* caption, const char* btn_image)
+{
+
+       if (!m_initialized) {
+               errorstream << "AutoHideButtonBar::addButton not yet initialized!"
+                               << std::endl;
+               return;
+       }
+       int button_size = 0;
+
+       if ((m_dir == AHBB_Dir_Top_Bottom) || (m_dir == AHBB_Dir_Bottom_Top)) {
+               button_size = m_lower_right.X - m_upper_left.X;
+       } else {
+               button_size = m_lower_right.Y - m_upper_left.Y;
+       }
+
+       irr::core::rect<int> current_button;
+
+       if ((m_dir == AHBB_Dir_Right_Left) || (m_dir == AHBB_Dir_Left_Right)) {
+
+               int x_start = 0;
+               int x_end = 0;
+
+               if (m_dir == AHBB_Dir_Left_Right) {
+                       x_start = m_lower_right.X + (button_size * 1.25 * m_buttons.size())
+                                       + (button_size * 0.25);
+                       x_end = x_start + button_size;
+               } else {
+                       x_end = m_upper_left.X - (button_size * 1.25 * m_buttons.size())
+                                       - (button_size * 0.25);
+                       x_start = x_end - button_size;
+               }
+
+               current_button = rect<s32>(x_start, m_upper_left.Y, x_end,
+                               m_lower_right.Y);
+       } else {
+               int y_start = 0;
+               int y_end = 0;
+
+               if (m_dir == AHBB_Dir_Top_Bottom) {
+                       y_start = m_lower_right.X + (button_size * 1.25 * m_buttons.size())
+                                       + (button_size * 0.25);
+                       y_end = y_start + button_size;
+               } else {
+                       y_end = m_upper_left.X - (button_size * 1.25 * m_buttons.size())
+                                       - (button_size * 0.25);
+                       y_start = y_end - button_size;
+               }
+
+               current_button = rect<s32>(m_upper_left.X, y_start, m_lower_right.Y,
+                               y_end);
+       }
+
+       button_info* btn       = new button_info();
+       btn->guibutton         = m_guienv->addButton(current_button, 0, button_id, caption, 0);
+       btn->guibutton->grab();
+       btn->guibutton->setVisible(false);
+       btn->guibutton->setEnabled(false);
+       btn->repeatcounter     = -1;
+       btn->keycode           = id2keycode(button_id);
+       btn->immediate_release = true;
+       btn->ids.clear();
+
+       load_button_texture(btn, btn_image, current_button, m_texturesource,
+                       m_driver);
+
+       m_buttons.push_back(btn);
+}
+
+bool AutoHideButtonBar::isButton(const SEvent &event)
+{
+       IGUIElement* rootguielement = m_guienv->getRootGUIElement();
+
+       if (rootguielement == NULL) {
+               return false;
+       }
+
+       gui::IGUIElement *element = rootguielement->getElementFromPoint(
+                       core::position2d<s32>(event.TouchInput.X, event.TouchInput.Y));
+
+       if (element == NULL) {
+               return false;
+       }
+
+       if (m_active) {
+               /* check for all buttons in vector */
+
+               std::vector<button_info*>::iterator iter = m_buttons.begin();
+
+               while (iter != m_buttons.end()) {
+                       if ((*iter)->guibutton == element) {
+
+                               SEvent* translated = new SEvent();
+                               memset(translated, 0, sizeof(SEvent));
+                               translated->EventType            = irr::EET_KEY_INPUT_EVENT;
+                               translated->KeyInput.Key         = (*iter)->keycode;
+                               translated->KeyInput.Control     = false;
+                               translated->KeyInput.Shift       = false;
+                               translated->KeyInput.Char        = 0;
+
+                               /* add this event */
+                               translated->KeyInput.PressedDown = true;
+                               m_receiver->OnEvent(*translated);
+
+                               /* remove this event */
+                               translated->KeyInput.PressedDown = false;
+                               m_receiver->OnEvent(*translated);
+
+                               delete translated;
+
+                               (*iter)->ids.push_back(event.TouchInput.ID);
+
+                               m_timeout = 0;
+
+                               return true;
+                       }
+                       ++iter;
+               }
+       } else {
+               /* check for starter button only */
+               if (element == m_starter.guibutton) {
+                       m_starter.ids.push_back(event.TouchInput.ID);
+                       m_starter.guibutton->setVisible(false);
+                       m_starter.guibutton->setEnabled(false);
+                       m_active = true;
+                       m_timeout = 0;
+
+                       std::vector<button_info*>::iterator iter = m_buttons.begin();
+
+                       while (iter != m_buttons.end()) {
+                               (*iter)->guibutton->setVisible(true);
+                               (*iter)->guibutton->setEnabled(true);
+                               ++iter;
+                       }
+
+                       return true;
+               }
+       }
+       return false;
+}
+
+bool AutoHideButtonBar::isReleaseButton(int eventID)
+{
+       std::vector<int>::iterator id = std::find(m_starter.ids.begin(),
+                       m_starter.ids.end(), eventID);
+
+       if (id != m_starter.ids.end()) {
+               m_starter.ids.erase(id);
+               return true;
+       }
+
+       std::vector<button_info*>::iterator iter = m_buttons.begin();
+
+       while (iter != m_buttons.end()) {
+               std::vector<int>::iterator id = std::find((*iter)->ids.begin(),
+                               (*iter)->ids.end(), eventID);
+
+               if (id != (*iter)->ids.end()) {
+                       (*iter)->ids.erase(id);
+                       // TODO handle settings button release
+                       return true;
+               }
+               ++iter;
+       }
+
+       return false;
+}
+
+void AutoHideButtonBar::step(float dtime)
+{
+       if (m_active) {
+               m_timeout += dtime;
+
+               if (m_timeout > m_timeout_value) {
+                       deactivate();
+               }
+       }
+}
+
+void AutoHideButtonBar::deactivate()
+{
+       if (m_visible == true) {
+               m_starter.guibutton->setVisible(true);
+               m_starter.guibutton->setEnabled(true);
+       }
+       m_active = false;
+
+       std::vector<button_info*>::iterator iter = m_buttons.begin();
+
+       while (iter != m_buttons.end()) {
+                       (*iter)->guibutton->setVisible(false);
+                       (*iter)->guibutton->setEnabled(false);
+               ++iter;
+       }
+}
+
+void AutoHideButtonBar::hide()
+{
+       m_visible = false;
+       m_starter.guibutton->setVisible(false);
+       m_starter.guibutton->setEnabled(false);
+
+       std::vector<button_info*>::iterator iter = m_buttons.begin();
+
+       while (iter != m_buttons.end()) {
+               (*iter)->guibutton->setVisible(false);
+               (*iter)->guibutton->setEnabled(false);
+               ++iter;
+       }
+}
+
+void AutoHideButtonBar::show()
+{
+       m_visible = true;
+
+       if (m_active) {
+               std::vector<button_info*>::iterator iter = m_buttons.begin();
+
+               while (iter != m_buttons.end()) {
+                       (*iter)->guibutton->setVisible(true);
+                       (*iter)->guibutton->setEnabled(true);
+                       ++iter;
+               }
+       } else {
+               m_starter.guibutton->setVisible(true);
+               m_starter.guibutton->setEnabled(true);
+       }
+}
+
+TouchScreenGUI::TouchScreenGUI(IrrlichtDevice *device, IEventReceiver* receiver):
+       m_device(device),
+       m_guienv(device->getGUIEnvironment()),
+       m_camera_yaw(0.0),
+       m_camera_pitch(0.0),
+       m_visible(false),
+       m_move_id(-1),
+       m_receiver(receiver),
+       m_move_has_really_moved(false),
+       m_move_downtime(0),
+       m_move_sent_as_mouse_event(false),
+       // use some downlocation way off screen as init value  to avoid invalid behaviour
+       m_move_downlocation(v2s32(-10000, -10000)),
+       m_settingsbar(device, receiver),
+       m_rarecontrolsbar(device, receiver)
+{
+       for (unsigned int i=0; i < after_last_element_id; i++) {
+               m_buttons[i].guibutton     =  0;
+               m_buttons[i].repeatcounter = -1;
+               m_buttons[i].repeatdelay   = BUTTON_REPEAT_DELAY;
+       }
+
+       m_screensize = m_device->getVideoDriver()->getScreenSize();
+}
+
 void TouchScreenGUI::initButton(touch_gui_button_id id, rect<s32> button_rect,
                std::wstring caption, bool immediate_release, float repeat_delay)
 {
@@ -166,21 +449,27 @@ void TouchScreenGUI::initButton(touch_gui_button_id id, rect<s32> button_rect,
        btn->immediate_release = immediate_release;
        btn->ids.clear();
 
-       loadButtonTexture(btn,touchgui_button_imagenames[id], button_rect);
+       load_button_texture(btn,touchgui_button_imagenames[id],button_rect,
+                       m_texturesource, m_device->getVideoDriver());
 }
 
 static int getMaxControlPadSize(float density) {
        return 200 * density * g_settings->getFloat("hud_scaling");
 }
 
-void TouchScreenGUI::init(ISimpleTextureSource* tsrc, float density)
+int TouchScreenGUI::getGuiButtonSize()
 {
-       assert(tsrc != 0);
+       u32 control_pad_size = MYMIN((2 * m_screensize.Y) / 3,
+                       getMaxControlPadSize(porting::getDisplayDensity()));
+
+       return control_pad_size / 3;
+}
 
-       u32 control_pad_size =
-                       MYMIN((2 * m_screensize.Y) / 3,getMaxControlPadSize(density));
+void TouchScreenGUI::init(ISimpleTextureSource* tsrc)
+{
+       assert(tsrc != 0);
 
-       u32 button_size      = control_pad_size / 3;
+       u32 button_size      = getGuiButtonSize();
        m_visible            = true;
        m_texturesource      = tsrc;
        m_control_pad_rect   = rect<s32>(0, m_screensize.Y - 3 * button_size,
@@ -223,16 +512,6 @@ void TouchScreenGUI::init(ISimpleTextureSource* tsrc, float density)
                                }
                }
 
-       /* init inventory button */
-       initButton(inventory_id,
-                       rect<s32>(0, m_screensize.Y - (button_size/2),
-                                       (button_size/2), m_screensize.Y), L"inv", true);
-
-       /* init drop button */
-       initButton(drop_id,
-                       rect<s32>(2.5*button_size, m_screensize.Y - (button_size/2),
-                                       3*button_size, m_screensize.Y), L"drop", true);
-
        /* init jump button */
        initButton(jump_id,
                        rect<s32>(m_screensize.X-(1.75*button_size),
@@ -249,48 +528,37 @@ void TouchScreenGUI::init(ISimpleTextureSource* tsrc, float density)
                                        m_screensize.Y),
                        L"H",false);
 
-       /* init fly button */
-       initButton(fly_id,
-                       rect<s32>(m_screensize.X - (0.75*button_size),
-                                       m_screensize.Y - (2.25*button_size),
-                                       m_screensize.X, m_screensize.Y - (button_size*1.5)),
-                       L"fly", false, SLOW_BUTTON_REPEAT);
-
-       /* init noclip button */
-       initButton(noclip_id,
-                       rect<s32>(m_screensize.X - (0.75*button_size), 2.25*button_size,
-                                       m_screensize.X, 3*button_size),
-                       L"clip", false, SLOW_BUTTON_REPEAT);
-
-       /* init fast button */
-       initButton(fast_id,
-                       rect<s32>(m_screensize.X - (0.75*button_size), 1.5*button_size,
-                                       m_screensize.X, 2.25*button_size),
-                       L"fast", false, SLOW_BUTTON_REPEAT);
-
-       /* init debug button */
-       initButton(debug_id,
-                       rect<s32>(m_screensize.X - (0.75*button_size), 0.75*button_size,
-                                       m_screensize.X, 1.5*button_size),
-                       L"dbg", false, SLOW_BUTTON_REPEAT);
-
-       /* init chat button */
-       initButton(chat_id,
-                       rect<s32>(m_screensize.X - (0.75*button_size), 0,
-                                       m_screensize.X, 0.75*button_size),
-                       L"Chat", true);
-
-       /* init camera button */
-       initButton(camera_id,
-                       rect<s32>(m_screensize.X - (1.5*button_size), 0,
-                                       m_screensize.X - (0.75*button_size), 0.75*button_size),
-                       L"cam", false, SLOW_BUTTON_REPEAT);
-
-       /* init rangeselect button */
-       initButton(range_id,
-                       rect<s32>(m_screensize.X - (2.25*button_size), 0,
-                                       m_screensize.X - (1.5*button_size), 0.75*button_size),
-                       L"far", false, SLOW_BUTTON_REPEAT);
+       m_settingsbar.init(m_texturesource, "gear_icon.png", settings_starter_id,
+                       v2s32(m_screensize.X - (button_size / 2),
+                                       m_screensize.Y - ((SETTINGS_BAR_Y_OFFSET + 1) * button_size)
+                                                       + (button_size * 0.5)),
+                       v2s32(m_screensize.X,
+                                       m_screensize.Y - (SETTINGS_BAR_Y_OFFSET * button_size)
+                                                       + (button_size * 0.5)), AHBB_Dir_Right_Left,
+                       3.0);
+
+       m_settingsbar.addButton(fly_id,    L"fly",       "fly_btn.png");
+       m_settingsbar.addButton(noclip_id, L"noclip",    "noclip_btn.png");
+       m_settingsbar.addButton(fast_id,   L"fast",      "fast_btn.png");
+       m_settingsbar.addButton(debug_id,  L"debug",     "debug_btn.png");
+       m_settingsbar.addButton(camera_id, L"camera",    "camera_btn.png");
+       m_settingsbar.addButton(range_id,  L"rangeview", "rangeview_btn.png");
+
+       m_rarecontrolsbar.init(m_texturesource, "rare_controls.png",
+                       rare_controls_starter_id,
+                       v2s32(0,
+                                       m_screensize.Y
+                                                       - ((RARE_CONTROLS_BAR_Y_OFFSET + 1) * button_size)
+                                                       + (button_size * 0.5)),
+                       v2s32(button_size / 2,
+                                       m_screensize.Y - (RARE_CONTROLS_BAR_Y_OFFSET * button_size)
+                                                       + (button_size * 0.5)), AHBB_Dir_Left_Right,
+                       2);
+
+       m_rarecontrolsbar.addButton(chat_id,      L"Chat", "chat_btn.png");
+       m_rarecontrolsbar.addButton(inventory_id, L"inv",  "inventory_btn.png");
+       m_rarecontrolsbar.addButton(drop_id,      L"drop", "drop_btn.png");
+
 }
 
 touch_gui_button_id TouchScreenGUI::getButtonID(s32 x, s32 y)
@@ -374,7 +642,7 @@ bool TouchScreenGUI::isReleaseHUDButton(int eventID)
        return false;
 }
 
-void TouchScreenGUI::ButtonEvent(touch_gui_button_id button,
+void TouchScreenGUI::handleButtonEvent(touch_gui_button_id button,
                int eventID, bool action)
 {
        button_info* btn = &m_buttons[button];
@@ -424,11 +692,15 @@ void TouchScreenGUI::handleReleaseEvent(int evt_id)
 
        /* handle button events */
        if (button != after_last_element_id) {
-               ButtonEvent(button, evt_id, false);
+               handleButtonEvent(button, evt_id, false);
        }
        /* handle hud button events */
        else if (isReleaseHUDButton(evt_id)) {
                /* nothing to do here */
+       } else if (m_settingsbar.isReleaseButton(evt_id)) {
+               /* nothing to do here */
+       } else if (m_rarecontrolsbar.isReleaseButton(evt_id)) {
+               /* nothing to do here */
        }
        /* handle the point used for moving view */
        else if (evt_id == m_move_id) {
@@ -498,14 +770,24 @@ void TouchScreenGUI::translateEvent(const SEvent &event)
 
                /* handle button events */
                if (button != after_last_element_id) {
-                       ButtonEvent(button,eventID,true);
-               }
-               else if (isHUDButton(event))
-               {
+                       handleButtonEvent(button, eventID, true);
+                       m_settingsbar.deactivate();
+                       m_rarecontrolsbar.deactivate();
+               } else if (isHUDButton(event)) {
+                       m_settingsbar.deactivate();
+                       m_rarecontrolsbar.deactivate();
                        /* already handled in isHUDButton() */
+               } else if (m_settingsbar.isButton(event)) {
+                       m_rarecontrolsbar.deactivate();
+                       /* already handled in isSettingsBarButton() */
+               } else if (m_rarecontrolsbar.isButton(event)) {
+                       m_settingsbar.deactivate();
+                       /* already handled in isSettingsBarButton() */
                }
                /* handle non button events */
                else {
+                       m_settingsbar.deactivate();
+                       m_rarecontrolsbar.deactivate();
                        /* if we don't already have a moving point make this the moving one */
                        if (m_move_id == -1) {
                                m_move_id                  = event.TouchInput.ID;
@@ -520,7 +802,6 @@ void TouchScreenGUI::translateEvent(const SEvent &event)
        }
        else if (event.TouchInput.Event == ETIE_LEFT_UP) {
                verbosestream << "Up event for pointerid: " << event.TouchInput.ID << std::endl;
-
                handleReleaseEvent(event.TouchInput.ID);
        }
        else {
@@ -582,8 +863,7 @@ void TouchScreenGUI::translateEvent(const SEvent &event)
                                                ->getRayFromScreenCoordinates(
                                                                v2s32(event.TouchInput.X,event.TouchInput.Y));
                        }
-               }
-               else {
+               } else {
                        handleChangedButton(event);
                }
        }
@@ -596,7 +876,7 @@ void TouchScreenGUI::handleChangedButton(const SEvent &event)
                if (m_buttons[i].ids.empty()) {
                        continue;
                }
-               for(std::vector<int>::iterator iter = m_buttons[i].ids.begin();
+               for (std::vector<int>::iterator iter = m_buttons[i].ids.begin();
                                iter != m_buttons[i].ids.end(); ++iter) {
 
                        if (event.TouchInput.ID == *iter) {
@@ -609,12 +889,12 @@ void TouchScreenGUI::handleChangedButton(const SEvent &event)
                                }
 
                                /* remove old button */
-                               ButtonEvent((touch_gui_button_id) i,*iter,false);
+                               handleButtonEvent((touch_gui_button_id) i,*iter,false);
 
                                if (current_button_id == after_last_element_id) {
                                        return;
                                }
-                               ButtonEvent((touch_gui_button_id) current_button_id,*iter,true);
+                               handleButtonEvent((touch_gui_button_id) current_button_id,*iter,true);
                                return;
 
                        }
@@ -628,8 +908,11 @@ void TouchScreenGUI::handleChangedButton(const SEvent &event)
        }
 
        button_info* btn = &m_buttons[current_button_id];
-       if (std::find(btn->ids.begin(),btn->ids.end(), event.TouchInput.ID) == btn->ids.end()) {
-               ButtonEvent((touch_gui_button_id) current_button_id,event.TouchInput.ID,true);
+       if (std::find(btn->ids.begin(),btn->ids.end(), event.TouchInput.ID)
+                       == btn->ids.end())
+       {
+               handleButtonEvent((touch_gui_button_id) current_button_id,
+                               event.TouchInput.ID, true);
        }
 
 }
@@ -643,7 +926,7 @@ bool TouchScreenGUI::doubleTapDetection()
        m_key_events[1].x         = m_move_downlocation.X;
        m_key_events[1].y         = m_move_downlocation.Y;
 
-       u32 delta = porting::getDeltaMs(m_key_events[0].down_time,getTimeMs());
+       u32 delta = porting::getDeltaMs(m_key_events[0].down_time, getTimeMs());
        if (delta > 400)
                return false;
 
@@ -652,11 +935,11 @@ bool TouchScreenGUI::doubleTapDetection()
                        (m_key_events[0].y - m_key_events[1].y) * (m_key_events[0].y - m_key_events[1].y));
 
 
-       if (distance >(20 + g_settings->getU16("touchscreen_threshold")))
+       if (distance > (20 + g_settings->getU16("touchscreen_threshold")))
                return false;
 
        SEvent* translated = new SEvent();
-       memset(translated,0,sizeof(SEvent));
+       memset(translated, 0, sizeof(SEvent));
        translated->EventType               = EET_MOUSE_INPUT_EVENT;
        translated->MouseInput.X            = m_key_events[0].x;
        translated->MouseInput.Y            = m_key_events[0].y;
@@ -685,7 +968,7 @@ bool TouchScreenGUI::doubleTapDetection()
 
 TouchScreenGUI::~TouchScreenGUI()
 {
-       for (unsigned int i=0; i < after_last_element_id; i++) {
+       for (unsigned int i = 0; i < after_last_element_id; i++) {
                button_info* btn = &m_buttons[i];
                if (btn->guibutton != 0) {
                        btn->guibutton->drop();
@@ -697,7 +980,7 @@ TouchScreenGUI::~TouchScreenGUI()
 void TouchScreenGUI::step(float dtime)
 {
        /* simulate keyboard repeats */
-       for (unsigned int i=0; i < after_last_element_id; i++) {
+       for (unsigned int i = 0; i < after_last_element_id; i++) {
                button_info* btn = &m_buttons[i];
 
                if (btn->ids.size() > 0) {
@@ -711,7 +994,7 @@ void TouchScreenGUI::step(float dtime)
 
                        btn->repeatcounter              = 0;
                        SEvent translated;
-                       memset(&translated,0,sizeof(SEvent));
+                       memset(&translated, 0, sizeof(SEvent));
                        translated.EventType            = irr::EET_KEY_INPUT_EVENT;
                        translated.KeyInput.Key         = btn->keycode;
                        translated.KeyInput.PressedDown = false;
@@ -737,7 +1020,7 @@ void TouchScreenGUI::step(float dtime)
                                                        v2s32(m_move_downlocation.X,m_move_downlocation.Y));
 
                        SEvent translated;
-                       memset(&translated,0,sizeof(SEvent));
+                       memset(&translated, 0, sizeof(SEvent));
                        translated.EventType               = EET_MOUSE_INPUT_EVENT;
                        translated.MouseInput.X            = m_move_downlocation.X;
                        translated.MouseInput.Y            = m_move_downlocation.Y;
@@ -750,6 +1033,9 @@ void TouchScreenGUI::step(float dtime)
                        m_move_sent_as_mouse_event         = true;
                }
        }
+
+       m_settingsbar.step(dtime);
+       m_rarecontrolsbar.step(dtime);
 }
 
 void TouchScreenGUI::resetHud()
@@ -765,7 +1051,7 @@ void TouchScreenGUI::registerHudItem(int index, const rect<s32> &rect)
 void TouchScreenGUI::Toggle(bool visible)
 {
        m_visible = visible;
-       for (unsigned int i=0; i < after_last_element_id; i++) {
+       for (unsigned int i = 0; i < after_last_element_id; i++) {
                button_info* btn = &m_buttons[i];
                if (btn->guibutton != 0) {
                        btn->guibutton->setVisible(visible);
@@ -777,10 +1063,16 @@ void TouchScreenGUI::Toggle(bool visible)
                while (m_known_ids.size() > 0) {
                        handleReleaseEvent(m_known_ids.begin()->id);
                }
+
+               m_settingsbar.hide();
+               m_rarecontrolsbar.hide();
+       } else {
+               m_settingsbar.show();
+               m_rarecontrolsbar.show();
        }
 }
 
-void TouchScreenGUI::Hide()
+void TouchScreenGUI::hide()
 {
        if (!m_visible)
                return;
@@ -788,7 +1080,7 @@ void TouchScreenGUI::Hide()
        Toggle(false);
 }
 
-void TouchScreenGUI::Show()
+void TouchScreenGUI::show()
 {
        if (m_visible)
                return;
index 1e69a41e9cd13d82465f45a81f259026bb80733d..d8106a2600e91c663fe74a783789d22aed32105e 100644 (file)
@@ -38,26 +38,105 @@ typedef enum {
        backward_id,
        left_id,
        right_id,
-       inventory_id,
-       drop_id,
        jump_id,
        crunch_id,
+       after_last_element_id,
+       settings_starter_id,
+       rare_controls_starter_id,
        fly_id,
        noclip_id,
        fast_id,
        debug_id,
-       chat_id,
        camera_id,
        range_id,
-       after_last_element_id
+       chat_id,
+       inventory_id,
+       drop_id
 } touch_gui_button_id;
 
+typedef enum {
+       AHBB_Dir_Top_Bottom,
+       AHBB_Dir_Bottom_Top,
+       AHBB_Dir_Left_Right,
+       AHBB_Dir_Right_Left
+} autohide_button_bar_dir;
+
 #define MIN_DIG_TIME_MS 500
 #define MAX_TOUCH_COUNT 64
 #define BUTTON_REPEAT_DELAY 0.2f
 
+#define SETTINGS_BAR_Y_OFFSET 6.5
+#define RARE_CONTROLS_BAR_Y_OFFSET 4
+
 extern const char** touchgui_button_imagenames;
 
+struct button_info {
+       float            repeatcounter;
+       float            repeatdelay;
+       irr::EKEY_CODE   keycode;
+       std::vector<int> ids;
+       IGUIButton*      guibutton;
+       bool             immediate_release;
+};
+
+class AutoHideButtonBar
+{
+public:
+
+       AutoHideButtonBar( IrrlichtDevice *device, IEventReceiver* receiver );
+
+       void init(ISimpleTextureSource* tsrc, const char* starter_img,
+                       int button_id, v2s32 UpperLeft, v2s32 LowerRight,
+                       autohide_button_bar_dir dir, float timeout);
+
+       ~AutoHideButtonBar();
+
+       /* add button to be shown */
+       void addButton(touch_gui_button_id id, const wchar_t* caption,
+                       const char* btn_image);
+
+       /* detect settings bar button events */
+       bool isButton(const SEvent &event);
+
+       /* handle released hud buttons */
+       bool isReleaseButton(int eventID);
+
+       /* step handler */
+       void step(float dtime);
+
+       /* deactivate button bar */
+       void deactivate();
+
+       /* hide the whole buttonbar */
+       void hide();
+
+       /* unhide the buttonbar */
+       void show();
+
+private:
+       ISimpleTextureSource*     m_texturesource;
+       irr::video::IVideoDriver* m_driver;
+       IGUIEnvironment*          m_guienv;
+       IEventReceiver*           m_receiver;
+       v2u32                     m_screensize;
+       button_info               m_starter;
+       std::vector<button_info*> m_buttons;
+
+       v2s32                     m_upper_left;
+       v2s32                     m_lower_right;
+
+       /* show settings bar */
+       bool                      m_active;
+
+       bool                      m_visible;
+
+       /* settings bar timeout */
+       float                     m_timeout;
+       float                     m_timeout_value;
+       bool                      m_initialized;
+       autohide_button_bar_dir   m_dir;
+};
+
 class TouchScreenGUI
 {
 public:
@@ -66,7 +145,7 @@ class TouchScreenGUI
 
        void translateEvent(const SEvent &event);
 
-       void init(ISimpleTextureSource* tsrc,float density);
+       void init(ISimpleTextureSource* tsrc);
 
        double getYaw() { return m_camera_yaw; }
        double getPitch() { return m_camera_pitch; }
@@ -77,8 +156,8 @@ class TouchScreenGUI
        void registerHudItem(int index, const rect<s32> &rect);
        void Toggle(bool visible);
 
-       void Hide();
-       void Show();
+       void hide();
+       void show();
 
 private:
        IrrlichtDevice*         m_device;
@@ -104,15 +183,6 @@ class TouchScreenGUI
        bool                    m_move_sent_as_mouse_event;
        v2s32                   m_move_downlocation;
 
-       struct button_info {
-               float            repeatcounter;
-               float            repeatdelay;
-               irr::EKEY_CODE   keycode;
-               std::vector<int> ids;
-               IGUIButton*      guibutton;
-               bool             immediate_release;
-       };
-
        button_info m_buttons[after_last_element_id];
 
        /* gui button detection */
@@ -142,7 +212,7 @@ class TouchScreenGUI
        std::vector<id_status> m_known_ids;
 
        /* handle a button event */
-       void ButtonEvent(touch_gui_button_id bID, int eventID, bool action);
+       void handleButtonEvent(touch_gui_button_id bID, int eventID, bool action);
 
        /* handle pressed hud buttons */
        bool isHUDButton(const SEvent &event);
@@ -156,6 +226,9 @@ class TouchScreenGUI
        /* handle release event */
        void handleReleaseEvent(int evt_id);
 
+       /* get size of regular gui control button */
+       int getGuiButtonSize();
+
        /* doubleclick detection variables */
        struct key_event {
                unsigned int down_time;
@@ -168,6 +241,12 @@ class TouchScreenGUI
 
        /* array for doubletap detection */
        key_event m_key_events[2];
+
+       /* settings bar */
+       AutoHideButtonBar m_settingsbar;
+
+       /* rare controls bar */
+       AutoHideButtonBar m_rarecontrolsbar;
 };
 extern TouchScreenGUI *g_touchscreengui;
 #endif
index 2db4a08fcbf266e106a895d8cb42daf77aad50cd..5d777108a6dde8cbc6658b9cbe6224d996264060 100644 (file)
Binary files a/textures/base/pack/drop_btn.png and b/textures/base/pack/drop_btn.png differ
diff --git a/textures/base/pack/gear_icon.png b/textures/base/pack/gear_icon.png
new file mode 100644 (file)
index 0000000..71825eb
Binary files /dev/null and b/textures/base/pack/gear_icon.png differ
diff --git a/textures/base/pack/rare_controls.png b/textures/base/pack/rare_controls.png
new file mode 100644 (file)
index 0000000..4829649
Binary files /dev/null and b/textures/base/pack/rare_controls.png differ