summaryrefslogtreecommitdiff
path: root/src/gui
diff options
context:
space:
mode:
authorAndrei Karas <akaras@inbox.ru>2014-03-09 13:23:07 +0300
committerAndrei Karas <akaras@inbox.ru>2014-03-09 14:44:09 +0300
commitc66e0863ecc24145c57261987eb8e25776c303ce (patch)
tree17bb98deebd60463cb01bad865a92b766272efed /src/gui
parent4c90395b1b42d436545b33a855ef431f5ede6a9b (diff)
downloadmv-c66e0863ecc24145c57261987eb8e25776c303ce.tar.gz
mv-c66e0863ecc24145c57261987eb8e25776c303ce.tar.bz2
mv-c66e0863ecc24145c57261987eb8e25776c303ce.tar.xz
mv-c66e0863ecc24145c57261987eb8e25776c303ce.zip
Add support for long mouse press event.
Enabled by default on Android.
Diffstat (limited to 'src/gui')
-rw-r--r--src/gui/gui.cpp10
-rw-r--r--src/gui/gui.h5
-rw-r--r--src/gui/viewport.cpp275
-rw-r--r--src/gui/viewport.h8
-rw-r--r--src/gui/widgets/tabs/setup_players.cpp5
5 files changed, 190 insertions, 113 deletions
diff --git a/src/gui/gui.cpp b/src/gui/gui.cpp
index 55da1b9e3..554c1ff42 100644
--- a/src/gui/gui.cpp
+++ b/src/gui/gui.cpp
@@ -1436,3 +1436,13 @@ void Gui::handleModalFocusReleased()
parent = swap->getParent();
}
}
+
+int Gui::getMousePressLength()
+{
+ if (!mLastMousePressTimeStamp)
+ return 0;
+ int ticks = SDL_GetTicks();
+ if (ticks > mLastMousePressTimeStamp)
+ return ticks - mLastMousePressTimeStamp;
+ return mLastMousePressTimeStamp - ticks;
+}
diff --git a/src/gui/gui.h b/src/gui/gui.h
index 4536ee553..f7c913752 100644
--- a/src/gui/gui.h
+++ b/src/gui/gui.h
@@ -302,6 +302,11 @@ class Gui final
*/
void removeGlobalKeyListener(KeyListener *const keyListener);
+ bool isLongPress()
+ { return getMousePressLength() > 250; }
+
+ int getMousePressLength();
+
protected:
void handleMouseMoved(const MouseInput &mouseInput);
diff --git a/src/gui/viewport.cpp b/src/gui/viewport.cpp
index 7ae209b92..9b31d6e13 100644
--- a/src/gui/viewport.cpp
+++ b/src/gui/viewport.cpp
@@ -61,6 +61,8 @@ Viewport::Viewport() :
mScrollCenterOffsetX(config.getIntValue("ScrollCenterOffsetX")),
mScrollCenterOffsetY(config.getIntValue("ScrollCenterOffsetY")),
mMouseDirectionMove(config.getBoolValue("mouseDirectionMove")),
+ mLongMouseClick(config.getBoolValue("longmouseclick")),
+ mMouseClicked(false),
mMouseX(0),
mMouseY(0),
mPixelViewX(0),
@@ -91,6 +93,7 @@ Viewport::Viewport() :
config.addListener("selfMouseHeal", this);
config.addListener("enableLazyScrolling", this);
config.addListener("mouseDirectionMove", this);
+ config.addListener("longmouseclick", this);
setFocusable(true);
}
@@ -356,11 +359,132 @@ void Viewport::_drawPath(Graphics *const graphics, const Path &path,
}
}
+bool Viewport::openContextMenu(MouseEvent &event)
+{
+ mPlayerFollowMouse = false;
+ const int eventX = event.getX();
+ const int eventY = event.getY();
+ if (mHoverBeing)
+ {
+ validateSpeed();
+ if (actorManager)
+ {
+ std::vector<ActorSprite*> beings;
+ const int x = mMouseX + mPixelViewX;
+ const int y = mMouseY + mPixelViewY;
+ actorManager->findBeingsByPixel(beings, x, y, true);
+ if (beings.size() > 1)
+ mPopupMenu->showPopup(eventX, eventY, beings);
+ else
+ mPopupMenu->showPopup(eventX, eventY, mHoverBeing);
+ mHoverBeing = nullptr;
+ return true;
+ }
+ }
+ else if (mHoverItem)
+ {
+ validateSpeed();
+ mPopupMenu->showPopup(eventX, eventY, mHoverItem);
+ mHoverItem = nullptr;
+ return true;
+ }
+ else if (mHoverSign)
+ {
+ validateSpeed();
+ mPopupMenu->showPopup(eventX, eventY, mHoverSign);
+ mHoverSign = nullptr;
+ return true;
+ }
+ else if (mCameraMode)
+ {
+ mPopupMenu->showMapPopup(eventX, eventY,
+ (mMouseX + mPixelViewX) / mMap->getTileWidth(),
+ (mMouseY + mPixelViewY) / mMap->getTileHeight());
+ return true;
+ }
+ return false;
+}
+
+bool Viewport::leftMouseAction(MouseEvent &event)
+{
+ // Interact with some being
+ if (mHoverBeing)
+ {
+ if (!mHoverBeing->isAlive())
+ return true;
+
+ if (mHoverBeing->canTalk())
+ {
+ validateSpeed();
+ mHoverBeing->talkTo();
+ return true;
+ }
+ else
+ {
+ if (mHoverBeing->getType() == ActorSprite::PLAYER)
+ {
+ validateSpeed();
+ if (actorManager)
+ {
+ if (player_node != mHoverBeing || mSelfMouseHeal)
+ actorManager->heal(mHoverBeing);
+ if (player_node == mHoverBeing && mHoverItem)
+ player_node->pickUp(mHoverItem);
+ return true;
+ }
+ }
+ else if (player_node->withinAttackRange(mHoverBeing) ||
+ inputManager.isActionActive(static_cast<int>(
+ Input::KEY_ATTACK)))
+ {
+ validateSpeed();
+ if (player_node != mHoverBeing)
+ {
+ player_node->attack(mHoverBeing,
+ !inputManager.isActionActive(
+ static_cast<int>(Input::KEY_STOP_ATTACK)));
+ return true;
+ }
+ }
+ else if (!inputManager.isActionActive(static_cast<int>(
+ Input::KEY_ATTACK)))
+ {
+ validateSpeed();
+ if (player_node != mHoverBeing)
+ {
+ player_node->setGotoTarget(mHoverBeing);
+ return true;
+ }
+ }
+ }
+ }
+ // Picks up a item if we clicked on one
+ if (mHoverItem)
+ {
+ validateSpeed();
+ player_node->pickUp(mHoverItem);
+ }
+ // Just walk around
+ else if (!inputManager.isActionActive(static_cast<int>(
+ Input::KEY_ATTACK)))
+ {
+ validateSpeed();
+ player_node->stopAttack();
+ player_node->cancelFollow();
+ mPlayerFollowMouse = true;
+
+ // Make the player go to the mouse position
+ _followMouse();
+ }
+ return false;
+}
+
void Viewport::mousePressed(MouseEvent &event)
{
if (event.getSource() != this)
return;
+ mMouseClicked = true;
// Check if we are alive and kickin'
if (!mMap || !player_node)
return;
@@ -379,47 +503,8 @@ void Viewport::mousePressed(MouseEvent &event)
// Right click might open a popup
if (eventButton == MouseEvent::RIGHT)
{
- mPlayerFollowMouse = false;
- if (mHoverBeing)
- {
- validateSpeed();
- if (actorManager)
- {
- std::vector<ActorSprite*> beings;
- const int x = mMouseX + mPixelViewX;
- const int y = mMouseY + mPixelViewY;
- actorManager->findBeingsByPixel(beings, x, y, true);
- if (beings.size() > 1)
- {
- mPopupMenu->showPopup(eventX, eventY, beings);
- return;
- }
- else
- {
- mPopupMenu->showPopup(eventX, eventY, mHoverBeing);
- return;
- }
- }
- }
- else if (mHoverItem)
- {
- validateSpeed();
- mPopupMenu->showPopup(eventX, eventY, mHoverItem);
+ if (openContextMenu(event))
return;
- }
- else if (mHoverSign)
- {
- validateSpeed();
- mPopupMenu->showPopup(eventX, eventY, mHoverSign);
- return;
- }
- else if (mCameraMode)
- {
- mPopupMenu->showMapPopup(eventX, eventY,
- (mMouseX + mPixelViewX) / mMap->getTileWidth(),
- (mMouseY + mPixelViewY) / mMap->getTileHeight());
- return;
- }
}
// If a popup is active, just remove it
@@ -431,77 +516,10 @@ void Viewport::mousePressed(MouseEvent &event)
}
// Left click can cause different actions
- if (eventButton == MouseEvent::LEFT)
+ if (!mLongMouseClick && eventButton == MouseEvent::LEFT)
{
- // Interact with some being
- if (mHoverBeing)
- {
- if (!mHoverBeing->isAlive())
- return;
-
- if (mHoverBeing->canTalk())
- {
- validateSpeed();
- mHoverBeing->talkTo();
- return;
- }
- else
- {
- if (mHoverBeing->getType() == ActorSprite::PLAYER)
- {
- validateSpeed();
- if (actorManager)
- {
- if (player_node != mHoverBeing || mSelfMouseHeal)
- actorManager->heal(mHoverBeing);
- if (player_node == mHoverBeing && mHoverItem)
- player_node->pickUp(mHoverItem);
- return;
- }
- }
- else if (player_node->withinAttackRange(mHoverBeing) ||
- inputManager.isActionActive(static_cast<int>(
- Input::KEY_ATTACK)))
- {
- validateSpeed();
- if (player_node != mHoverBeing)
- {
- player_node->attack(mHoverBeing,
- !inputManager.isActionActive(
- static_cast<int>(Input::KEY_STOP_ATTACK)));
- return;
- }
- }
- else if (!inputManager.isActionActive(static_cast<int>(
- Input::KEY_ATTACK)))
- {
- validateSpeed();
- if (player_node != mHoverBeing)
- {
- player_node->setGotoTarget(mHoverBeing);
- return;
- }
- }
- }
- }
- // Picks up a item if we clicked on one
- if (mHoverItem)
- {
- validateSpeed();
- player_node->pickUp(mHoverItem);
- }
- // Just walk around
- else if (!inputManager.isActionActive(static_cast<int>(
- Input::KEY_ATTACK)))
- {
- validateSpeed();
- player_node->stopAttack();
- player_node->cancelFollow();
- mPlayerFollowMouse = true;
-
- // Make the player go to the mouse position
- _followMouse();
- }
+ if (leftMouseAction(event))
+ return;
}
else if (eventButton == MouseEvent::MIDDLE)
{
@@ -519,11 +537,10 @@ void Viewport::mousePressed(MouseEvent &event)
}
}
-void Viewport::mouseDragged(MouseEvent &event)
+void Viewport::walkByMouse(MouseEvent &event)
{
if (!mMap || !player_node)
return;
-
if (mPlayerFollowMouse && !inputManager.isActionActive(
Input::KEY_STOP_ATTACK) && !inputManager.isActionActive(
Input::KEY_UNTARGET))
@@ -640,10 +657,40 @@ void Viewport::mouseDragged(MouseEvent &event)
}
}
-void Viewport::mouseReleased(MouseEvent &event A_UNUSED)
+void Viewport::mouseDragged(MouseEvent &event)
+{
+ if (mLongMouseClick)
+ return;
+
+ walkByMouse(event);
+}
+
+void Viewport::mouseReleased(MouseEvent &event)
{
mPlayerFollowMouse = false;
mLocalWalkTime = -1;
+ if (mLongMouseClick && mMouseClicked)
+ {
+ mMouseClicked = false;
+ const unsigned int eventButton = event.getButton();
+ if (eventButton == MouseEvent::LEFT)
+ {
+ // long button press
+ if (gui && gui->isLongPress())
+ {
+ openContextMenu(event);
+ gui->resetClickCount();
+ }
+ else
+ {
+ if (leftMouseAction(event))
+ return;
+ if (event.getSource() != this)
+ return;
+ walkByMouse(event);
+ }
+ }
+ }
}
void Viewport::showPopup(Window *const parent, const int x, const int y,
@@ -790,6 +837,8 @@ void Viewport::optionChanged(const std::string &name)
mEnableLazyScrolling = config.getBoolValue("enableLazyScrolling");
else if (name == "mouseDirectionMove")
mMouseDirectionMove = config.getBoolValue("mouseDirectionMove");
+ else if (name == "longmouseclick")
+ mLongMouseClick = config.getBoolValue("longmouseclick");
}
void Viewport::mouseMoved(MouseEvent &event A_UNUSED)
diff --git a/src/gui/viewport.h b/src/gui/viewport.h
index 16d0e4e34..50a79ee15 100644
--- a/src/gui/viewport.h
+++ b/src/gui/viewport.h
@@ -300,6 +300,12 @@ class Viewport final : public WindowContainer,
void _drawPath(Graphics *const graphics, const Path &path,
const Color &color = Color(255, 0, 0)) const;
+ bool leftMouseAction(MouseEvent &event);
+
+ bool openContextMenu(MouseEvent &event);
+
+ void walkByMouse(MouseEvent &event);
+
/**
* Make the player go to the mouse position.
*/
@@ -315,6 +321,8 @@ class Viewport final : public WindowContainer,
int mScrollCenterOffsetX;
int mScrollCenterOffsetY;
bool mMouseDirectionMove;
+ bool mLongMouseClick;
+ bool mMouseClicked;
int mMouseX; /**< Current mouse position in pixels. */
int mMouseY; /**< Current mouse position in pixels. */
int mPixelViewX; /**< Current viewpoint in pixels. */
diff --git a/src/gui/widgets/tabs/setup_players.cpp b/src/gui/widgets/tabs/setup_players.cpp
index 01bb60f53..b04a25e22 100644
--- a/src/gui/widgets/tabs/setup_players.cpp
+++ b/src/gui/widgets/tabs/setup_players.cpp
@@ -100,5 +100,10 @@ Setup_Players::Setup_Players(const Widget2 *const widget) :
new SetupItemCheckBox(_("Use special diagonal speed in players moving"),
"", "useDiagonalSpeed", this, "useDiagonalSpeedEvent");
+ // TRANSLATORS: settings option
+ new SetupItemCheckBox(_("Emulate right mouse button by long mouse click"
+ " (usefull for touch interfaces)"),
+ "", "longmouseclick", this, "longmouseclickEvent");
+
setDimension(Rect(0, 0, 550, 350));
}