Ticket #850: Ticket_850_V2.patch

File Ticket_850_V2.patch, 26.4 KB (added by Yves, 12 years ago)
  • source/gui/IGUIScrollBar.cpp

     
    7676        m_Pos = m_ScrollRange - m_ScrollSpace;
    7777}
    7878
     79void IGUIScrollBar::ResetMouseStates()
     80{
     81    IGUIObject::ResetMouseStates();
     82    SetBarPressed(false);
     83}
     84
    7985void IGUIScrollBar::HandleMessage(SGUIMessage &Message)
    8086{
    8187    switch (Message.type)
     
    120126                m_BarPressed = true;
    121127                m_BarPressedAtPos = mouse;
    122128                m_PosWhenPressed = m_Pos;
     129                m_IsCapturing = true;
    123130            }
    124131            else
    125132            // if button-minus is pressed
     
    159166    case GUIM_MOUSE_RELEASE_LEFT:
    160167        m_ButtonMinusPressed = false;
    161168        m_ButtonPlusPressed = false;
     169        m_BarPressed = false;
     170        m_IsCapturing = false;
    162171        break;
    163172
    164173    default:
  • source/gui/IGUIButtonBehavior.cpp

     
    4848            break;
    4949
    5050        m_Pressed = true;
     51        m_IsCapturing = true;
    5152    }   break;
    5253
    5354    case GUIM_MOUSE_DBLCLICK_LEFT:
    5455    case GUIM_MOUSE_RELEASE_LEFT:
    5556    {
     57        // Don't caputre anymore if the mouse button is released, regardless of the circumstances
     58        m_IsCapturing = false;
     59
    5660        bool enabled;
    5761        GUI<bool>::GetSetting(this, "enabled", enabled);
    5862   
    5963        if (!enabled)
    6064            break;
    6165
    62         if (m_Pressed)
     66        if (m_Pressed && m_MouseHovering)
    6367        {
    64             m_Pressed = false;
    6568            if (Message.type == GUIM_MOUSE_RELEASE_LEFT)
    6669            {
    6770                // Button was clicked
     
    7780                SendEvent(GUIM_DOUBLE_PRESSED, "doublepress");
    7881            }
    7982        }
     83        m_Pressed = false;
    8084    }   break;
    8185
    8286    default:
     
    116120    else return color;
    117121}
    118122
     123void IGUIButtonBehavior::ResetMouseStates()
     124{
     125    IGUIObject::ResetMouseStates();
     126    m_Pressed = false;
     127}
     128
    119129void IGUIButtonBehavior::DrawButton(const CRect &rect,
    120130                                    const float &z,
    121131                                    CGUISpriteInstance& sprite,
  • source/gui/IGUIScrollBarOwner.cpp

     
    4040    }
    4141}
    4242
    43 void IGUIScrollBarOwner::ResetStates()
     43void IGUIScrollBarOwner::ResetMouseStates()
    4444{
    45     IGUIObject::ResetStates();
     45    IGUIObject::ResetMouseStates();
    4646   
    4747    std::vector<IGUIScrollBar*>::iterator it;
    4848    for (it=m_ScrollBars.begin(); it!=m_ScrollBars.end(); ++it)
    4949    {
    50         (*it)->SetBarPressed(false);
     50        (*it)->ResetMouseStates();
    5151    }
    5252}
    5353
     
    7878
    7979void IGUIScrollBarOwner::HandleMessage(SGUIMessage &Message)
    8080{
     81    m_IsCapturing = false;
    8182    std::vector<IGUIScrollBar*>::iterator it;
    8283    for (it=m_ScrollBars.begin(); it!=m_ScrollBars.end(); ++it)
    8384    {
    8485        (*it)->HandleMessage(Message);
     86        if((*it)->IsCapturing())
     87        {
     88            m_IsCapturing = true;
     89        }
    8590    }
    8691}
    8792
  • source/gui/CList.h

     
    7272    virtual ~CList();
    7373
    7474    /**
    75      * @see IGUIObject#ResetStates()
     75     * @see IGUIObject#ResetMouseStates()
    7676     */
    77     virtual void ResetStates() { IGUIScrollBarOwner::ResetStates(); }
     77    virtual void ResetMouseStates() { IGUIScrollBarOwner::ResetMouseStates(); }
    7878
    7979    /**
    8080     * Adds an item last to the list.
  • source/gui/GUIutil.h

     
    8080    /// const version
    8181    static const IGUIObject * GetObjectPointer(const CGUI &GUIinstance, const CStr& Object);
    8282
    83     /// Wrapper for ResetStates
     83    /// Wrapper for ResetMouseStates
    8484    static void QueryResetting(IGUIObject *pObject);
    8585
    8686    static void HandleMessage(IGUIObject *pObject, SGUIMessage &message);
  • source/gui/CGUI.cpp

     
    115115        }
    116116    }
    117117
    118     // Update m_MousePos (for delayed mouse button events)
    119     CPos oldMousePos = m_MousePos;
    120     if (ev->ev.type == SDL_MOUSEBUTTONDOWN || ev->ev.type == SDL_MOUSEBUTTONUP)
    121     {
    122         m_MousePos = CPos((float)ev->ev.button.x, (float)ev->ev.button.y);
    123     }
    124 
    125     // Only one object can be hovered
     118    // Only one object can be active either because it's capturing input or because it's hovered.
     119    // Capturing takes precedence.
     120    IGUIObject *pActive = NULL;
    126121    IGUIObject *pNearest = NULL;
    127122
    128123    // TODO Gee: (2004-09-08) Big TODO, don't do the below if the SDL_Event is something like a keypress!
     
    130125    {
    131126        PROFILE( "mouse events" );
    132127        // TODO Gee: Optimizations needed!
    133         //  these two recursive function are quite overhead heavy.
     128        //  this recursive function is quite overhead heavy.
    134129
    135130        // pNearest will after this point at the hovered object, possibly NULL
    136131        pNearest = FindObjectUnderMouse();
    137 
    138         // Is placed in the UpdateMouseOver function
    139         //if (ev->ev.type == SDL_MOUSEMOTION && pNearest)
    140         //  pNearest->ScriptEvent("mousemove");
    141 
    142         // Now we'll call UpdateMouseOver on *all* objects,
    143         //  we'll input the one hovered, and they will each
    144         //  update their own data and send messages accordingly
    145132       
    146         GUI<IGUIObject*>::RecurseObject(GUIRR_HIDDEN | GUIRR_GHOST, m_BaseObject,
    147                                         &IGUIObject::UpdateMouseOver,
    148                                         pNearest);
     133        // If no GUIObject is capturing mouse input, the nearest one under the mouse(if any) becomes active
     134        if(m_pCapturingGUIObject == NULL)
     135        {
     136            pActive = pNearest;
     137            // Now we'll call UpdateMouseOver on *all* objects,
     138            //  we'll input the one hovered, and they will each
     139            //  update their own data and send messages accordingly
     140            GUI<IGUIObject*>::RecurseObject(GUIRR_HIDDEN | GUIRR_GHOST, m_BaseObject,
     141                                            &IGUIObject::UpdateMouseOver,
     142                                            pNearest);
     143        }
     144        else
     145        {
     146            pActive = m_pCapturingGUIObject;
     147            // Capturing mouse input also means that ONLY the capturing object must receive MouseOver events
     148            pActive->UpdateMouseOver(pNearest);
     149        }
    149150
    150151        if (ev->ev.type == SDL_MOUSEBUTTONDOWN)
    151152        {
     
    153154            {
    154155            case SDL_BUTTON_LEFT:
    155156                // Focus the clicked object (or focus none if nothing clicked on)
    156                 SetFocusedObject(pNearest);
     157                SetFocusedObject(pActive);
    157158
    158                 if (pNearest)
     159                if (pActive)
    159160                {
    160                     ret = pNearest->SendEvent(GUIM_MOUSE_PRESS_LEFT, "mouseleftpress");
     161                    ret = pActive->SendEvent(GUIM_MOUSE_PRESS_LEFT, "mouseleftpress");
    161162                }
    162163                break;
    163164
    164165            case SDL_BUTTON_RIGHT:
    165                 if (pNearest)
     166                if (pActive)
    166167                {
    167                     ret = pNearest->SendEvent(GUIM_MOUSE_PRESS_RIGHT, "mouserightpress");
     168                    ret = pActive->SendEvent(GUIM_MOUSE_PRESS_RIGHT, "mouserightpress");
    168169                }
    169170                break;
    170171
    171172            case SDL_BUTTON_WHEELDOWN: // wheel down
    172                 if (pNearest)
     173                if (pActive)
    173174                {
    174                     ret = pNearest->SendEvent(GUIM_MOUSE_WHEEL_DOWN, "mousewheeldown");
     175                    ret = pActive->SendEvent(GUIM_MOUSE_WHEEL_DOWN, "mousewheeldown");
    175176                }
    176177                break;
    177178
    178179            case SDL_BUTTON_WHEELUP: // wheel up
    179                 if (pNearest)
     180                if (pActive)
    180181                {
    181                     ret = pNearest->SendEvent(GUIM_MOUSE_WHEEL_UP, "mousewheelup");
     182                    ret = pActive->SendEvent(GUIM_MOUSE_WHEEL_UP, "mousewheelup");
    182183                }
    183184                break;
    184185
     
    192193            switch (ev->ev.button.button)
    193194            {
    194195            case SDL_BUTTON_LEFT:
    195                 if (pNearest)
     196                if (pActive)
    196197                {
    197                     double timeElapsed = timer_Time() - pNearest->m_LastClickTime[SDL_BUTTON_LEFT];
    198                     pNearest->m_LastClickTime[SDL_BUTTON_LEFT] = timer_Time();
    199                    
     198                    double timeElapsed = timer_Time() - pActive->m_LastClickTime[SDL_BUTTON_LEFT];
     199                    pActive->m_LastClickTime[SDL_BUTTON_LEFT] = timer_Time();
     200
    200201                    //Double click?
    201202                    if (timeElapsed < SELECT_DBLCLICK_RATE)
    202203                    {
    203                         ret = pNearest->SendEvent(GUIM_MOUSE_DBLCLICK_LEFT, "mouseleftdoubleclick");
     204                        ret = pActive->SendEvent(GUIM_MOUSE_DBLCLICK_LEFT, "mouseleftdoubleclick");
    204205                    }
    205206                    else
    206207                    {
    207                         ret = pNearest->SendEvent(GUIM_MOUSE_RELEASE_LEFT, "mouseleftrelease");
     208                        ret = pActive->SendEvent(GUIM_MOUSE_RELEASE_LEFT, "mouseleftrelease");
    208209                    }
    209210                }
    210211                break;
    211212            case SDL_BUTTON_RIGHT:
    212                 if (pNearest)
     213                if (pActive)
    213214                {
    214                     double timeElapsed = timer_Time() - pNearest->m_LastClickTime[SDL_BUTTON_RIGHT];
    215                     pNearest->m_LastClickTime[SDL_BUTTON_RIGHT] = timer_Time();
    216                    
     215                    double timeElapsed = timer_Time() - pActive->m_LastClickTime[SDL_BUTTON_RIGHT];
     216                    pActive->m_LastClickTime[SDL_BUTTON_RIGHT] = timer_Time();
     217
    217218                    //Double click?
    218219                    if (timeElapsed < SELECT_DBLCLICK_RATE)
    219220                    {
    220                         ret = pNearest->SendEvent(GUIM_MOUSE_DBLCLICK_RIGHT, "mouserightdoubleclick");
     221                        ret = pActive->SendEvent(GUIM_MOUSE_DBLCLICK_RIGHT, "mouserightdoubleclick");
    221222                    }
    222223                    else
    223224                    {
    224                         ret = pNearest->SendEvent(GUIM_MOUSE_RELEASE_RIGHT, "mouserightrelease");
     225                        ret = pActive->SendEvent(GUIM_MOUSE_RELEASE_RIGHT, "mouserightrelease");
    225226                    }
    226227                }
    227228                break;
    228229            }
    229230
    230             // Reset all states on all visible objects
    231             GUI<>::RecurseObject(GUIRR_HIDDEN, m_BaseObject,
    232                                     &IGUIObject::ResetStates);
     231        }
    233232
    234             // It will have reset the mouse over of the current hovered, so we'll
    235             //  have to restore that
    236             if (pNearest)
    237                 pNearest->m_MouseHovering = true;
     233        // Check if the active object is (still) capturing input
     234        if(pActive && pActive->IsCapturing())
     235        {
     236            m_pCapturingGUIObject = pActive;
    238237        }
     238        else
     239        {
     240            m_pCapturingGUIObject = NULL;
     241        }
    239242    }
    240243    catch (PSERROR_GUI& e)
    241244    {
     
    261264        }
    262265    }
    263266
    264     // Restore m_MousePos (for delayed mouse button events)
    265     if (ev->ev.type == SDL_MOUSEBUTTONDOWN || ev->ev.type == SDL_MOUSEBUTTONUP)
    266     {
    267         m_MousePos = oldMousePos;
    268     }
    269 
    270267    // Handle keys for input boxes
    271268    if (GetFocusedObject())
    272269    {
     
    382379    NULL, NULL, NULL, NULL
    383380};
    384381
    385 CGUI::CGUI() : m_MouseButtons(0), m_FocusedObject(NULL), m_InternalNameNumber(0)
     382CGUI::CGUI() : m_MouseButtons(0), m_FocusedObject(NULL), m_pCapturingGUIObject(NULL), m_InternalNameNumber(0)
    386383{
    387384    m_BaseObject = new CGUIDummyObject;
    388385    m_BaseObject->SetGUI(this);
     
    512509    m_Icons.clear();
    513510}
    514511
     512void CGUI::SetInactive()
     513{
     514    // This GUIObject won't reveive events anymore until it's active again.
     515    // This means that e.g. buttons would keep showing tooltips until then.
     516    // We reset the mouse-position and the mouse-states of all GUIObjects
     517    // when leaving the GUIPage to avoid this.
     518    m_MousePos = CPos();
     519    GUI<>::RecurseObject(GUIRR_HIDDEN, m_BaseObject, &IGUIObject::ResetMouseStates);
     520}
     521
     522void CGUI::SetActive(CPos MousePos)
     523{
     524    m_IsActive = true;
     525    // The mouse position would be set correctly after the first mousemotion event.
     526    // That's too late if e.g. the mouse is already on a button and the user clicks before moving it.
     527    m_MousePos = MousePos;
     528}
     529
    515530void CGUI::UpdateResolution()
    516531{
    517532    // Update ALL cached
  • source/gui/IGUIObject.h

     
    390390    void SetParent(IGUIObject *pParent) { m_pParent = pParent; }
    391391   
    392392    /**
    393      * Reset internal state of this object
    394      */
    395     virtual void ResetStates()
     393     * Reset all internal states of this object which are related to the mouse.
     394     * TODO: There are some edge-cases with keyboard-events also which are currently not handled.
     395     */
     396    virtual void ResetMouseStates()
    396397    {
    397398        m_MouseHovering = false;
     399        m_IsCapturing = false;
    398400    }
    399401
    400402public:
     
    456458    InReaction SendEvent(EGUIMessageType type, const CStr& EventName);
    457459
    458460    /**
     461     * Check if the object reqires the mouse input to be caputred.
     462     *
     463     * @return true if capturing, false if not
     464     */
     465    virtual bool IsCapturing() { return m_IsCapturing; }
     466
     467    /**
    459468     * Execute the script for a particular action.
    460469     * Does nothing if no script has been registered for that action.
    461470     * The mouse coordinates will be passed as the first argument.
     
    551560    // Is mouse hovering the object? used with the function MouseOver()
    552561    bool                                    m_MouseHovering;
    553562
     563    // Is GUIObject is currently capturing mouse input? Used with the function IsCapturing()
     564    bool m_IsCapturing;
     565
    554566    /**
    555567     * Settings pool, all an object's settings are located here
    556568     * If a derived object has got more settings that the base
  • source/gui/CCheckBox.h

     
    6464    virtual ~CCheckBox();
    6565
    6666    /**
    67      * @see IGUIObject#ResetStates()
     67     * @see IGUIObject#ResetMouseStates()
    6868     */
    69     virtual void ResetStates() { IGUIButtonBehavior::ResetStates(); }
     69    virtual void ResetMouseStates() { IGUIButtonBehavior::ResetMouseStates(); }
    7070
    7171    /**
    7272     * @see IGUIObject#HandleMessage()
  • source/gui/MiniMap.h

     
    3939
    4040    // create the minimap textures
    4141    void CreateTextures();
     42   
     43    virtual void ResetMouseStates();
    4244
    4345    // rebuild the terrain texture map
    4446    void RebuildTerrainTexture();
     
    5759   
    5860    //Whether or not the mouse is currently down
    5961    bool m_Clicking;
    60     bool m_Hovering;
    6162
    6263    // minimap texture handles
    6364    GLuint m_TerrainTexture;
  • source/gui/IGUIScrollBar.h

     
    146146 * The class does not provide all functionality to the scroll-bar, many
    147147 * things the parent of the scroll-bar, must provide. Like a combo-box.
    148148 */
    149 class IGUIScrollBar
     149class IGUIScrollBar : virtual public IGUIObject
    150150{
     151    friend class IGUIScrollBarOwner;
     152   
    151153public:
    152154    IGUIScrollBar();
    153155    virtual ~IGUIScrollBar();
     
    330332     * Call every time m_Pos has been updated.
    331333     */
    332334    void UpdatePosBoundaries();
     335   
     336    /**
     337     * Overload of the BaseClass IGUIObject
     338     */
     339    virtual void ResetMouseStates();
    333340
    334341protected:
    335342    //@}
  • source/gui/CInput.h

     
    7272    virtual ~CInput();
    7373
    7474    /**
    75      * @see IGUIObject#ResetStates()
     75     * @see IGUIObject#ResetMouseStates()
    7676     */
    77     virtual void ResetStates() { IGUIScrollBarOwner::ResetStates(); }
     77    virtual void ResetMouseStates() { IGUIScrollBarOwner::ResetMouseStates(); }
    7878
    7979    // Check where the mouse is hovering, and get the appropriate text position.
    8080    //  return is the text-position index.
  • source/gui/IGUIButtonBehavior.h

     
    108108
    109109protected:
    110110    /**
    111      * @see IGUIObject#ResetStates()
     111     * @see IGUIObject#ResetMouseStates()
    112112     */
    113     virtual void ResetStates()
    114     {
    115         m_MouseHovering = false;
    116         m_Pressed = false;
    117     }
     113    virtual void ResetMouseStates();
    118114
    119115    /**
    120116     * Everybody knows how a button works, you don't simply press it,
  • source/gui/GUIManager.cpp

     
    7272
    7373void CGUIManager::PushPage(const CStrW& pageName, CScriptVal initData)
    7474{
     75    CPos MousePos;
     76    if(m_PageStack.size() > 0)
     77    {
     78        // Get the mouse position from the last active page
     79        MousePos = m_PageStack.back().gui->GetMousePos();
     80        m_PageStack.back().gui->SetInactive();
     81    }
     82       
    7583    m_PageStack.push_back(SGUIPage());
    7684    m_PageStack.back().name = pageName;
    7785    m_PageStack.back().initData = CScriptValRooted(m_ScriptInterface.GetContext(), initData);
    7886    LoadPage(m_PageStack.back());
     87    m_PageStack.back().gui->SetActive(MousePos);
    7988}
    8089
    8190void CGUIManager::PopPage()
     
    8695        return;
    8796    }
    8897
     98    // Get the mouse position from the last active page before removing it
     99    CPos MousePos = m_PageStack.back().gui->GetMousePos();
    89100    m_PageStack.pop_back();
     101    m_PageStack.back().gui->SetActive(MousePos);
    90102}
    91103
    92104void CGUIManager::DisplayMessageBox(int width, int height, const CStrW& title, const CStrW& message)
  • source/gui/IGUIScrollBarOwner.h

     
    6060 */
    6161class IGUIScrollBarOwner : virtual public IGUIObject
    6262{
    63     friend class IGUIScrollBar;
    64 
    6563public:
    6664    IGUIScrollBarOwner();
    6765    virtual ~IGUIScrollBarOwner();
     
    7472    virtual void HandleMessage(SGUIMessage &Message);
    7573
    7674    /**
    77      * @see IGUIObject#ResetStates()
     75     * @see IGUIObject#ResetMouseStates()
    7876     */
    79     virtual void ResetStates();
     77    virtual void ResetMouseStates();
    8078
    8179    /**
    8280     * Interface for the m_ScrollBar to use.
  • source/gui/GUIutil.cpp

     
    277277
    278278void CInternalCGUIAccessorBase::QueryResetting(IGUIObject *pObject)
    279279{
    280     GUI<>::RecurseObject(0, pObject, &IGUIObject::ResetStates);
     280    GUI<>::RecurseObject(0, pObject, &IGUIObject::ResetMouseStates);
    281281}
    282282
    283283void CInternalCGUIAccessorBase::HandleMessage(IGUIObject *pObject, SGUIMessage &message)
  • source/gui/CButton.h

     
    6363    virtual ~CButton();
    6464
    6565    /**
    66      * @see IGUIObject#ResetStates()
     66     * @see IGUIObject#ResetMouseStates()
    6767     */
    68     virtual void ResetStates() { IGUIButtonBehavior::ResetStates(); }
     68    virtual void ResetMouseStates() { IGUIButtonBehavior::ResetMouseStates(); }
    6969
    7070    /**
    7171     * @see IGUIObject#HandleMessage()
  • source/gui/IGUIObject.cpp

     
    4040//-------------------------------------------------------------------
    4141//  Constructor / Destructor
    4242//-------------------------------------------------------------------
    43 IGUIObject::IGUIObject() : 
    44     m_pGUI(NULL), 
     43IGUIObject::IGUIObject() :
     44    m_pGUI(NULL),
    4545    m_pParent(NULL),
    4646    m_MouseHovering(false),
     47    m_IsCapturing(false),
    4748    m_JSObject(NULL)
    4849{
    4950    AddSetting(GUIST_bool,          "enabled");
  • source/gui/MiniMap.cpp

     
    2828#include "graphics/TerrainTextureEntry.h"
    2929#include "graphics/TerrainTextureManager.h"
    3030#include "graphics/TerritoryTexture.h"
     31#include "maths/Vector2D.h"
    3132#include "lib/ogl.h"
    3233#include "lib/external_libraries/sdl.h"
    3334#include "lib/bits.h"
     
    5960    AddSetting(GUIST_CStrW,     "tooltip");
    6061    AddSetting(GUIST_CStr,      "tooltip_style");
    6162    m_Clicking = false;
    62     m_Hovering = false;
    6363}
    6464
    6565CMiniMap::~CMiniMap()
     
    7373    {
    7474    case GUIM_MOUSE_PRESS_LEFT:
    7575        {
    76             if (m_Hovering)
     76            if (m_MouseHovering)
    7777            {
    7878                SetCameraPos();
    7979                m_Clicking = true;
     80                m_IsCapturing = true;
    8081            }
    8182            break;
    8283        }
    8384    case GUIM_MOUSE_RELEASE_LEFT:
    8485        {
    85             if(m_Hovering && m_Clicking)
     86            if(m_MouseHovering && m_Clicking)
    8687            {
    8788                SetCameraPos();
    8889            }
    8990            m_Clicking = false;
     91            m_IsCapturing = false;
    9092            break;
    9193        }
    9294    case GUIM_MOUSE_DBLCLICK_LEFT:
    9395        {
    94             if(m_Hovering && m_Clicking)
     96            if(m_MouseHovering && m_Clicking)
    9597            {
    9698                SetCameraPos();
    9799            }
     
    100102        }
    101103    case GUIM_MOUSE_ENTER:
    102104        {
    103             m_Hovering = true;
     105            m_MouseHovering = true;
    104106            break;
    105107        }
    106108    case GUIM_MOUSE_LEAVE:
    107109        {
    108             m_Clicking = false;
    109             m_Hovering = false;
     110            m_MouseHovering = false;
    110111            break;
    111112        }
    112113    case GUIM_MOUSE_RELEASE_RIGHT:
     
    121122        }
    122123    case GUIM_MOUSE_MOTION:
    123124        {
    124             if (m_Hovering && m_Clicking)
     125            if (m_Clicking)
    125126            {
    126127                SetCameraPos();
    127128            }
     
    139140
    140141void CMiniMap::GetMouseWorldCoordinates(float& x, float& z)
    141142{
    142     // Determine X and Z according to proportion of mouse position and minimap
    143 
    144143    CPos mousePos = GetMousePos();
     144    float MinimapRadius = m_CachedActualSize.GetWidth() / 2.0f;
     145    CVector2D CornerToMouse; // Vector from the bottom left corner of the minimap to the mouse-position
     146    CVector2D CenterToCorner; // Vector from the center to the bottom left corner or the minimap;
     147    CVector2D CenterToMouse; // Vector from the center of the minimap to the mouse (will be clamped at the minimap bounds)
    145148
    146     float px = (mousePos.x - m_CachedActualSize.left) / m_CachedActualSize.GetWidth();
    147     float py = (m_CachedActualSize.bottom - mousePos.y) / m_CachedActualSize.GetHeight();
     149    CornerToMouse.X = (mousePos.x - m_CachedActualSize.left);
     150    CornerToMouse.Y = (m_CachedActualSize.bottom - mousePos.y);
     151    CenterToCorner.X = CenterToCorner.Y = -MinimapRadius;
     152    CenterToMouse = CornerToMouse + CenterToCorner;
    148153
     154    // Clamp CenterToMouse at a length of the minimap radius
     155    if(CenterToMouse.Length() > MinimapRadius)
     156    {
     157        float ShrinkFactor = MinimapRadius / CenterToMouse.Length();
     158        CenterToMouse.X = CenterToMouse.X * ShrinkFactor;
     159        CenterToMouse.Y = CenterToMouse.Y * ShrinkFactor;
     160    }
     161
     162    // Recalculate CenterToMouse using the other two vectors.
     163    // It is now still pointing in the same direction (towards the mouse pointer), but clamped
     164    CornerToMouse = (-CenterToCorner) + CenterToMouse;
     165
     166    // Determine X and Z according to proportion of mouse position and minimap
     167    float px = CornerToMouse.X / m_CachedActualSize.GetWidth();
     168    float py = CornerToMouse.Y / m_CachedActualSize.GetHeight();
    149169    float angle = GetAngle();
    150170
    151171    // Scale world coordinates for shrunken square map
     
    448468    RebuildTerrainTexture();
    449469}
    450470
     471void CMiniMap::ResetMouseStates()
     472{
     473    IGUIObject::ResetMouseStates();
     474    m_Clicking = false;
     475}
    451476
    452477void CMiniMap::RebuildTerrainTexture()
    453478{
  • source/gui/CText.h

     
    6565    virtual ~CText();
    6666
    6767    /**
    68      * @see IGUIObject#ResetStates()
     68     * @see IGUIObject#ResetMouseStates()
    6969     */
    70     virtual void ResetStates() { IGUIScrollBarOwner::ResetStates(); }
     70    virtual void ResetMouseStates() { IGUIScrollBarOwner::ResetMouseStates(); }
    7171
    7272    /**
    7373     * Test if mouse position is over an icon
  • source/gui/CGUI.h

     
    167167     * within the GUI.
    168168     */
    169169    void Destroy();
     170   
     171   
     172    /**
     173     * Sets if the GUI is on the currently active GUIPage.
     174     */
     175     void SetInactive();
     176     
     177     /**
     178      * Sets if the GUI is on the currently active GUIPage.
     179      *
     180      * @param MousePos Current position of the mouse
     181      */
     182     void SetActive(CPos MousePos);
     183     
     184     /**
     185      * Some simply get-functions
     186      */
     187     CPos GetMousePos() const { return m_MousePos; };
     188     bool IsActive() const {return m_IsActive; };
     189     
    170190
    171191    /**
    172192     * The replacement of Process(), handles an SDL_Event_
     
    645665     * as followed, the value will increment.
    646666     */
    647667    int m_InternalNameNumber;
     668   
     669    /**
     670     * Value indicating if the GUI is on the currently active GUIPage.
     671     */
     672    bool m_IsActive;
    648673
    649674    /**
    650675     * Function pointers to functions that constructs
     
    677702
    678703    // Icons
    679704    std::map<CStr, SGUIIcon> m_Icons;
     705
     706    // GUIObject capturing the mouse input
     707    IGUIObject *m_pCapturingGUIObject;
    680708};
    681709
    682710#endif
  • source/graphics/Camera.cpp

     
    308308
    309309    // Clamp the water intersection to within the map's bounds, so that
    310310    // we'll always return a valid position on the map
    311     ssize_t mapSize = g_Game->GetWorld()->GetTerrain()->GetVerticesPerSide();
    312     if (gotWater)
    313     {
    314         waterPoint.X = clamp(waterPoint.X, 0.f, (float)((mapSize-1)*CELL_SIZE));
    315         waterPoint.Z = clamp(waterPoint.Z, 0.f, (float)((mapSize-1)*CELL_SIZE));
    316     }
    317311
    318312    if (gotTerrain)
    319313    {
  • binaries/data/mods/public/gui/pregame/mainmenu.js

     
    1414
    1515    // initialize currentSubmenuType with placeholder to avoid null when switching
    1616    currentSubmenuType = "submenuSinglePlayer";
     17
     18    EnableUserReport(Engine.IsUserReportEnabled());
    1719}
    1820
    1921var t0 = new Date;
     
    140142
    141143    if (Engine.IsUserReportEnabled())
    142144    {
    143         getGUIObjectByName("userReportDisabled").hidden = true;
    144         getGUIObjectByName("userReportEnabled").hidden = false;
    145 
    146         getGUIObjectByName("userReportEnabledText").caption =
    147             userReportEnabledText.replace(/\$status/,
    148                 formatUserReportStatus(Engine.GetUserReportStatus()));
     145        getGUIObjectByName("userReportEnabledText").caption = userReportEnabledText.replace(/\$status/,
     146            formatUserReportStatus(Engine.GetUserReportStatus()));
    149147    }
    150     else
    151     {
    152         getGUIObjectByName("userReportDisabled").hidden = false;
    153         getGUIObjectByName("userReportEnabled").hidden = true;
    154     }
    155148}
    156149
     150function EnableUserReport(Enabled)
     151{
     152    getGUIObjectByName("userReportDisabled").hidden = Enabled;
     153    getGUIObjectByName("userReportEnabled").hidden = !Enabled;
     154    Engine.SetUserReportEnabled(Enabled);
     155}
    157156
     157
    158158/*
    159159 * MENU FUNCTIONS
    160160 */
  • binaries/data/mods/public/gui/pregame/mainmenu.xml

     
    9797            </object>
    9898            <object type="button" style="StoneButton" size="8 100%-36 146 100%-8">
    9999                Enable feedback
    100                 <action on="Press">Engine.SetUserReportEnabled(true);</action>
     100                <action on="Press">EnableUserReport(true);</action>
    101101            </object>
    102102            <object type="button" style="StoneButton" size="100%-146 100%-36 100%-8 100%-8">
    103103                Technical details
     
    149149
    150150            <object type="button" style="StoneButton" size="8 100%-36 146 100%-8">
    151151                Disable feedback
    152                 <action on="Press">Engine.SetUserReportEnabled(false);</action>
     152                <action on="Press">EnableUserReport(false);</action>
    153153            </object>
    154154            <object type="button" style="StoneButton" size="100%-146 100%-36 100%-8 100%-8">
    155155                Technical details