Une classe GUIDraggableWidget pour permettre de déplacer une GUIWidget

lnh5ycp0amwjyttfhg4x

Intro :

Parfois nous avons besoin qu’une GUIWidget puisse être déplaçable à volonté tout en restant appuyé dessus la souris.

Prérequis :

– Avoir compris la classe GUIWidget

Contenu :

Voici le contenu GUIDraggableWidget.h :

#ifndef GUI_DRAGGABLE_WIGET_H
#define GUI_DRAGGABLE_WIGET_H

#include <iostream>
#include <d3dx10math.h>

#include "GUIImage.h"
#include "GUIButton.h"

class GUIDraggableWiget : public GUIImage
{
public:
    enum DraggableBoxState
    {
        NON_ACTIVE,
        DRAGGING
    };

    GUIDraggableWiget(const std::string& sName, const std::string& sTextureFileName);
    virtual ~GUIDraggableWiget();

    virtual void Update(float fTimeSinceLastFrame);

    virtual void SetPosition(unsigned int x, unsigned int y);
    virtual void SetSize(unsigned int iWidth, unsigned int iHeight);

    void DisableDragging();
    void EnableDragging();

private:
    bool IsCollidingWithDraggableBox(int x, int y);
    bool IsCollidingWithCloseBox(int x, int y);

    void SetBoxesPositions(unsigned int x, unsigned int y);

    D3DXVECTOR2 GetDraggableBoxPosition();

    DraggableBoxState GetDraggableBoxState();
    void SetDraggableBoxState(DraggableBoxState state);

    void SetImageSize(unsigned int iWidth, unsigned int iHeight);

private:
    AABB m_draggableBoxAABB;
    AABB m_closeBoxAABB;

    DraggableBoxState m_state;

    int xPos;
    int yPos;

    int sx;
    int sy;

    bool m_bDragging;
    bool m_bDraggingEnabled;
};

#endif

 

Voici le fichier GUIDraggableWidget.cpp :

#include "GUIDraggableWidget.h"
#include "InputManager.h"
#include "GUIManager.h"

GUIDraggableWiget::GUIDraggableWiget(const std::string& sName, const std::string& sTextureFileName) :
GUIImage(sName, sTextureFileName),
xPos(0),
yPos(0),
sx(0),
sy(0),
m_bDragging(false),
m_bDraggingEnabled(true)
{
    ZeroMemory(&m_draggableBoxAABB, sizeof(AABB));
    ZeroMemory(&m_closeBoxAABB, sizeof(AABB));

    m_draggableBoxAABB.w = (float)GetImage()->GetWidth();
    m_draggableBoxAABB.h = (float)GetImage()->GetHeight() * 0.3f;    

    m_closeBoxAABB.w = 20;
    m_closeBoxAABB.h = 20;    
}

GUIDraggableWiget::~GUIDraggableWiget()
{
}

void GUIDraggableWiget::Update(float fTimeSinceLastFrame)
{
    if (!IsVisible())
    {
        return;
    }

    GUIImage::Update(fTimeSinceLastFrame);

    int absX, absY;
    INPUT_MANAGER->GetAbsMouseLocation(absX, absY);

    int dX = absX - sx;
    int dY = absY - sy;

    if (INPUT_MANAGER->IsMouseButtonDown(MOUSE_LEFT_BUTTON_DOWN)
        && GUI_MANAGER->DoesWidgetIsOnFront(this)
        && SYSTEM->HasFocus() && IsActive())
    {
        if (IsCollidingWithDraggableBox(absX, absY) && m_bDraggingEnabled)
        {
             m_bDragging = true;
        }

        if (IsCollidingWithCloseBox(absX, absY))
        {
            SetVisible(false);
        }

        if (m_bDragging)
        {
            SetDraggableBoxState(DraggableBoxState::DRAGGING);

            xPos += dX;
            yPos += dY;

            /* Contraintes de bords */
            if (yPos <= 0)
            {
                yPos = 0;
            }

            if (xPos <= 0)
            {
                xPos = 0;
            }

            unsigned int iWidthOffset = D3D10_RENDERER->GetViewportWidth() - GetImage()->GetWidth();
            unsigned int iHeightOffset = D3D10_RENDERER->GetViewportHeight() - GetImage()->GetHeight();

            /* Contraintes de bords */
            if (xPos >= iWidthOffset)
            {
                xPos = iWidthOffset;
            }

            if (yPos >= iHeightOffset)
            {
                yPos = iHeightOffset;
            }    
            
            SetPosition(xPos, yPos);
        }
    }
    else
    {
        m_bDragging = false;
    }

    sx = absX;
    sy = absY;
}

bool GUIDraggableWiget::IsCollidingWithDraggableBox(int x, int y)
{
    return (x >= m_draggableBoxAABB.x) && (x < (m_draggableBoxAABB.x + m_draggableBoxAABB.w))
        && (y >= m_draggableBoxAABB.y) && (y < (m_draggableBoxAABB.y + m_draggableBoxAABB.h))
        && IsVisible();
}

bool GUIDraggableWiget::IsCollidingWithCloseBox(int x, int y)
{
    return (x >= m_closeBoxAABB.x) && (x < (m_closeBoxAABB.x + m_closeBoxAABB.w))
        && (y >= m_closeBoxAABB.y) && (y < (m_closeBoxAABB.y + m_closeBoxAABB.h))
        && IsVisible();
}

void GUIDraggableWiget::SetDraggableBoxState(DraggableBoxState state)
{
    m_state = state;
}
    
GUIDraggableWiget::DraggableBoxState GUIDraggableWiget::GetDraggableBoxState()
{
    return m_state;
}

void GUIDraggableWiget::SetBoxesPositions(unsigned int x, unsigned int y)
{  
    m_draggableBoxAABB.x = x;
    m_draggableBoxAABB.y = y;

    m_closeBoxAABB.x = (GetImage()->GetWidth() - m_closeBoxAABB.w) + x;
    m_closeBoxAABB.y = y;
}

D3DXVECTOR2 GUIDraggableWiget::GetDraggableBoxPosition()
{  
    return D3DXVECTOR2(m_draggableBoxAABB.x, m_draggableBoxAABB.y);
}

void GUIDraggableWiget::SetPosition(unsigned int x, unsigned int y)
{  
    SetBoxesPositions(x, y);

    xPos = x;
    yPos = y;

    GUIImage::SetPosition(x, y);
}

void GUIDraggableWiget::SetSize(unsigned int iWidth, unsigned int iHeight)
{    
    GUIImage::SetSize(iWidth, iHeight);

    m_draggableBoxAABB.w = (float)GetImage()->GetWidth();
    m_draggableBoxAABB.h = (float)GetImage()->GetHeight() * 0.3f;    
}

void GUIDraggableWiget::DisableDragging()
{
    m_bDraggingEnabled = false;
}

void GUIDraggableWiget::EnableDragging()
{
    m_bDraggingEnabled = true;
}

 

Résumé :

Nous avons décrit une classe qui représente un moyen d’afficher une GUIWidget déplaçable.

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *