From 230b7a896ce66c75474dc655b19ca4eccbc4ae91 Mon Sep 17 00:00:00 2001 From: pyrolink Date: Sat, 21 Jan 2006 11:07:25 +0000 Subject: [PATCH] Right click/double click support in main GUI handler, minimap updates-drag and order issuing This was SVN commit r3381. --- source/gui/CGUI.cpp | 40 +++++++++++- source/gui/GUIbase.h | 2 + source/gui/IGUIObject.cpp | 3 +- source/gui/IGUIObject.h | 3 + source/gui/MiniMap.cpp | 134 ++++++++++++++++++++++++++++---------- source/gui/MiniMap.h | 6 ++ 6 files changed, 151 insertions(+), 37 deletions(-) diff --git a/source/gui/CGUI.cpp b/source/gui/CGUI.cpp index 0bfa6ddb23..5a53a6557c 100755 --- a/source/gui/CGUI.cpp +++ b/source/gui/CGUI.cpp @@ -39,10 +39,11 @@ gee@pyro.nu #include "scripting/ScriptingHost.h" #include "Hotkey.h" #include "ps/Globals.h" +#include "lib/timer.h" // namespaces used using namespace std; - +const double SELECT_DBLCLICK_RATE = 0.5; #include "ps/CLogger.h" #define LOG_CATEGORY "gui" @@ -202,8 +203,41 @@ InReaction CGUI::HandleEvent(const SDL_Event* ev) case SDL_BUTTON_LEFT: if (pNearest) { - pNearest->HandleMessage(SGUIMessage(GUIM_MOUSE_RELEASE_LEFT)); - pNearest->ScriptEvent("mouseleftrelease"); + double timeElapsed = get_time() - pNearest->m_LastClickTime[SDL_BUTTON_LEFT]; + pNearest->m_LastClickTime[SDL_BUTTON_LEFT] = get_time(); + + //Double click? + if (timeElapsed < SELECT_DBLCLICK_RATE) + { + pNearest->HandleMessage(SGUIMessage(GUIM_MOUSE_DBLCLICK_LEFT)); + pNearest->ScriptEvent("mouseleftdoubleclick"); + } + else + { + pNearest->HandleMessage(SGUIMessage(GUIM_MOUSE_RELEASE_LEFT)); + pNearest->ScriptEvent("mouseleftrelease"); + } + + ret = IN_HANDLED; + } + break; + case SDL_BUTTON_RIGHT: + if (pNearest) + { + double timeElapsed = get_time() - pNearest->m_LastClickTime[SDL_BUTTON_RIGHT]; + pNearest->m_LastClickTime[SDL_BUTTON_RIGHT] = get_time(); + + //Double click? + if (timeElapsed < SELECT_DBLCLICK_RATE) + { + pNearest->HandleMessage(SGUIMessage(GUIM_MOUSE_DBLCLICK_RIGHT)); + //pNearest->ScriptEvent("mouserightdoubleclick"); + } + else + { + pNearest->HandleMessage(SGUIMessage(GUIM_MOUSE_RELEASE_RIGHT)); + //pNearest->ScriptEvent("mouserightrelease"); + } ret = IN_HANDLED; } diff --git a/source/gui/GUIbase.h b/source/gui/GUIbase.h index d619c34ab6..a21376bff9 100755 --- a/source/gui/GUIbase.h +++ b/source/gui/GUIbase.h @@ -68,6 +68,8 @@ enum EGUIMessageType GUIM_MOUSE_PRESS_RIGHT, GUIM_MOUSE_DOWN_LEFT, GUIM_MOUSE_DOWN_RIGHT, + GUIM_MOUSE_DBLCLICK_LEFT, + GUIM_MOUSE_DBLCLICK_RIGHT, GUIM_MOUSE_RELEASE_LEFT, GUIM_MOUSE_RELEASE_RIGHT, GUIM_MOUSE_WHEEL_UP, diff --git a/source/gui/IGUIObject.cpp b/source/gui/IGUIObject.cpp index 6dd938c2a9..f3dbe5b666 100755 --- a/source/gui/IGUIObject.cpp +++ b/source/gui/IGUIObject.cpp @@ -47,7 +47,8 @@ IGUIObject::IGUIObject() : GUI::SetSetting(this, "absolute", true); - + for (int i=0; i<6; i++) + m_LastClickTime[i]=0; bool hidden=true; GUI::GetSetting(this, "hidden", hidden); diff --git a/source/gui/IGUIObject.h b/source/gui/IGUIObject.h index 801c1c8d19..559fd7c505 100755 --- a/source/gui/IGUIObject.h +++ b/source/gui/IGUIObject.h @@ -494,6 +494,9 @@ protected: // Pointer to parent IGUIObject *m_pParent; + + //This represents the last click time for each mouse button + double m_LastClickTime[6]; /** * This is an array of true or false, each element is associated with diff --git a/source/gui/MiniMap.cpp b/source/gui/MiniMap.cpp index 31f2b4153a..fd0369d9a0 100755 --- a/source/gui/MiniMap.cpp +++ b/source/gui/MiniMap.cpp @@ -13,11 +13,14 @@ #include "Entity.h" #include "Bound.h" #include "Model.h" +#include "scripting/GameEvents.h" #include "Terrain.h" #include "Profile.h" #include "LOSManager.h" #include "graphics/GameView.h" #include "renderer/WaterManager.h" +#include "Interact.h" +#include "ps/Network/NetMessage.h" bool g_TerrainModified = false; @@ -27,6 +30,7 @@ bool g_TerrainModified = false; // static data instead of a class member. that is no longer the case, // but we leave it because this is slightly more efficient. static float m_scaleX, m_scaleY; +extern bool g_mouse_buttons[1]; static unsigned int ScaleColor(unsigned int color, float x) @@ -44,6 +48,7 @@ CMiniMap::CMiniMap() AddSetting(GUIST_CColor, "fov_wedge_color"); AddSetting(GUIST_CStr, "tooltip"); AddSetting(GUIST_CStr, "tooltip_style"); + m_Clicking = false; } CMiniMap::~CMiniMap() @@ -57,47 +62,110 @@ void CMiniMap::HandleMessage(const SGUIMessage &Message) { case GUIM_MOUSE_PRESS_LEFT: { - CTerrain *MMTerrain=g_Game->GetWorld()->GetTerrain(); - CVector3D CamOrient=m_Camera->m_Orientation.GetTranslation(); - - //get center point of screen - int x = (int)g_Renderer.GetWidth()/2.f, y = (int)g_Renderer.GetHeight()/2.f; - CVector3D ScreenMiddle=m_Camera->GetWorldCoordinates(x,y); - - //Get Vector required to go from camera position to ScreenMiddle - CVector3D TransVector; - TransVector.X=CamOrient.X-ScreenMiddle.X; - TransVector.Z=CamOrient.Z-ScreenMiddle.Z; - //world position of where mouse clicked - CVector3D Destination; - //X and Z according to proportion of mouse position and minimap - Destination.X=(CELL_SIZE*m_MapSize)* - ((g_mouse_x-m_CachedActualSize.left)/m_CachedActualSize.GetWidth()); - Destination.Z=(CELL_SIZE*m_MapSize)*((m_CachedActualSize.bottom-g_mouse_y) - /m_CachedActualSize.GetHeight()); - - m_Camera->m_Orientation._14=Destination.X; - m_Camera->m_Orientation._34=Destination.Z; - m_Camera->m_Orientation._14+=TransVector.X; - m_Camera->m_Orientation._34+=TransVector.Z; - - //Lock Y coord. No risk of zoom exceeding limit-Y does not increase - float Height=MMTerrain->getExactGroundLevel( - m_Camera->m_Orientation._14, m_Camera->m_Orientation._34) + g_YMinOffset; - - if (m_Camera->m_Orientation._24 < Height) - { - m_Camera->m_Orientation._24=Height; - } - m_Camera->UpdateFrustum(); + SetCameraPos(); + m_Clicking = true; + break; } + case GUIM_MOUSE_RELEASE_LEFT: + { + SetCameraPos(); + m_Clicking = false; break; + } + case GUIM_MOUSE_ENTER: + { + g_Selection.m_mouseOverMM = true; + break; + } + case GUIM_MOUSE_LEAVE: + { + g_Selection.m_mouseOverMM = false; + break; + } + + case GUIM_MOUSE_RELEASE_RIGHT: + { + CMiniMap::FireWorldClickEvent(SDL_BUTTON_RIGHT, 1); + break; + } + case GUIM_MOUSE_DBLCLICK_RIGHT: + { + CMiniMap::FireWorldClickEvent(SDL_BUTTON_RIGHT, 2); + break; + } + case GUIM_MOUSE_MOTION: + { + if (m_Clicking) + SetCameraPos(); + break; + } default: break; } // switch } +void CMiniMap::SetCameraPos() +{ + CTerrain *MMTerrain=g_Game->GetWorld()->GetTerrain(); + CVector3D CamOrient=m_Camera->m_Orientation.GetTranslation(); + + //get center point of screen + int x = (int)g_Renderer.GetWidth()/2.f, y = (int)g_Renderer.GetHeight()/2.f; + CVector3D ScreenMiddle=m_Camera->GetWorldCoordinates(x,y); + + //Get Vector required to go from camera position to ScreenMiddle + CVector3D TransVector; + TransVector.X=CamOrient.X-ScreenMiddle.X; + TransVector.Z=CamOrient.Z-ScreenMiddle.Z; + //world position of where mouse clicked + CVector3D Destination; + CPos MousePos = GetMousePos(); + //X and Z according to proportion of mouse position and minimap + Destination.X = CELL_SIZE * m_MapSize * + ( (MousePos.x - m_CachedActualSize.left) / m_CachedActualSize.GetWidth() ); + Destination.Z = CELL_SIZE * m_MapSize * ( (m_CachedActualSize.bottom - MousePos.y) / + m_CachedActualSize.GetHeight() ); + + m_Camera->m_Orientation._14=Destination.X; + m_Camera->m_Orientation._34=Destination.Z; + m_Camera->m_Orientation._14+=TransVector.X; + m_Camera->m_Orientation._34+=TransVector.Z; + + //Lock Y coord. No risk of zoom exceeding limit-Y does not increase + float Height=MMTerrain->getExactGroundLevel( + m_Camera->m_Orientation._14, m_Camera->m_Orientation._34) + g_YMinOffset; + + if (m_Camera->m_Orientation._24 < Height) + { + m_Camera->m_Orientation._24=Height; + } + m_Camera->UpdateFrustum(); +} +void CMiniMap::FireWorldClickEvent(uint button, int clicks) +{ + //debug_printf("FireWorldClickEvent: button %d, clicks %d\n", button, clicks); + + CPos MousePos = GetMousePos(); + CVector2D Destination; + //X and Z according to proportion of mouse position and minimap + Destination.x = CELL_SIZE * m_MapSize * + ( (MousePos.x - m_CachedActualSize.left) / m_CachedActualSize.GetWidth() ); + Destination.y = CELL_SIZE * m_MapSize * ( (m_CachedActualSize.bottom - MousePos.y) / + m_CachedActualSize.GetHeight() ); + + g_JSGameEvents.FireWorldClick( + button, + clicks, + NMT_Goto, + -1, + NMT_Run, + -1, + NULL, + Destination.x, + Destination.y); +} + // render view rect : John M. Mena // This sets up and draws the rectangle on the mini-map // which represents the view of the camera in the world. diff --git a/source/gui/MiniMap.h b/source/gui/MiniMap.h index 660c054c59..2c6b932d1a 100755 --- a/source/gui/MiniMap.h +++ b/source/gui/MiniMap.h @@ -33,6 +33,9 @@ protected: // destroy and free any memory and textures void Destroy(); + void SetCameraPos(); + + void FireWorldClickEvent(uint button, int clicks); // calculate the relative heightmap space coordinates // for a units world position @@ -46,6 +49,9 @@ protected: // not const: camera is moved by clicking on minimap CCamera* m_Camera; + + //Whether or not the mouse is currently down + bool m_Clicking; // minimap texture handles u32 m_TerrainTexture;