J'avais dit que je ferais une classe BoutonRadio et un systeme équivalent à une groupBox, c'est fait!

Voici les deux images nécessaires pour l'affichage des boutons radios :
BoutonRadioContour.png
BoutonRadioCentre.png

Voici la classe BoutonRadio :

GUI_ButtonRadio.hGUI_ButtonRadio.cppGUI_ButtonRadioControl.hGUI_ButtonRadioControl.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#ifndef GUI_BUTTONRADIO_H
#define GUI_BUTTONRADIO_H

#include "IGUIElement.h"
#include "IGUIImage.h"
#include "IGUIStaticText.h"
#include "ITexture.h"

using namespace irr;
using namespace gui;
using namespace core;
using namespace video;

/**
Utilisation :

    #include "GUI_ButtonRadio.h"

    /// création
    ButtonRadio *BRadio0 = new ButtonRadio(mGUI, position2di(25,25), mTab1, L"../MEDIAS/Systeme/GUI/", false);

    /// destruction
    BRadio->remove();

    Il s'utilisent plus fréquemment avec ButtonRadioControl
**/


class ButtonRadio : public IGUIElement
{
    public:
        ButtonRadio(IGUIEnvironment *gui, position2di position=position2di(0,0), IGUIElement *parent=NULL, const wchar_t* pathImage=0, bool selected=false);
        virtual ~ButtonRadio();
        bool OnEvent(const SEvent& event);

        //! se détache de son parent et se détruit
        void remove();
        //! mets le bouton radio dans l'état voulu
        void setSelected(bool selected);
        //! renvoie l'état du bouton radio
        bool isSelected();

    protected:
        bool Checked;
        IGUIImage *IContour, *ICentre;

        bool Pressed;

    private:
        static int compteurInstance;
        static ITexture *TContour;
        static ITexture *TCentre;
};

#endif // GUI_BUTTONRADIO_H
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
#include "GUI_ButtonRadio.h"

#include "IGUIEnvironment.h"
#include "IVideoDriver.h"

/// initilisation des membres statiques
int ButtonRadio::compteurInstance=0;
ITexture* ButtonRadio::TContour=NULL;
ITexture* ButtonRadio::TCentre=NULL;

ButtonRadio::ButtonRadio(IGUIEnvironment *gui, position2di position, IGUIElement *parent, const wchar_t* pathImage, bool selected)
: IGUIElement(EGUIET_ELEMENT, gui, (parent!=0)?parent:gui->getRootGUIElement(), -1, recti(position, position+position2di(16,16))), Checked(selected)
{
    #ifdef _DEBUG
    setDebugName("ButtonRadio");
    #endif

    /// this element can be tabbed into
    setTabStop(true);
    setTabOrder(-1);

    /// si c'est la première instance on charge les textures
    if(compteurInstance < 1)
    {
        TContour = Environment->getVideoDriver()->getTexture(stringw(pathImage)+"BoutonRadioContour.png");
        TCentre = Environment->getVideoDriver()->getTexture(stringw(pathImage)+"BoutonRadioCentre.png");
    }
    /// incrémente le compteur d'instance
    compteurInstance++;
    /// image du contour
    IContour = Environment->addImage(TContour, position2di(0,0), true, this);
    /// Image du centre
    ICentre = Environment->addImage(TCentre, position2di(0,0), true, this);
    ICentre->setVisible(Checked);

}

ButtonRadio::~ButtonRadio()
{
    /// décrémente le compteur d'instance
    compteurInstance--;
    /// libération des ressources
    /// retire les textures si on en a plus besoin
    if(compteurInstance < 1)
    {
        if(TContour)  { Environment->getVideoDriver()->removeTexture(TContour); TContour = NULL; }
        if(TCentre) { Environment->getVideoDriver()->removeTexture(TCentre); TCentre = NULL; }
    }
}

bool ButtonRadio::OnEvent(const SEvent& event)
{
    if (isEnabled())
    {
        if(event.EventType == EET_MOUSE_INPUT_EVENT)
        {
            if(!Checked)
            {
                if (event.MouseInput.Event == EMIE_LMOUSE_PRESSED_DOWN)
                {
                    Pressed = true;
                    Environment->setFocus(this);
                    return true;
                }
                else
                if (event.MouseInput.Event == EMIE_LMOUSE_LEFT_UP)
                {
                    bool wasPressed = Pressed;
                    Environment->removeFocus(this);
                    Pressed = false;

                    if (wasPressed && Parent)
                    {
                        if ( !AbsoluteClippingRect.isPointInside( position2di(event.MouseInput.X, event.MouseInput.Y) ) )
                        {
                            Pressed = false;
                            return true;
                        }
                        SEvent newEvent;
                        newEvent.EventType = EET_GUI_EVENT;
                        newEvent.GUIEvent.Caller = this;
                        newEvent.GUIEvent.Element = 0;
                        setSelected(true);
                        newEvent.GUIEvent.EventType = EGET_CHECKBOX_CHANGED;
                        Parent->OnEvent(newEvent);
                    }
                    return true;
                }
            }
        }
    }
    /// si aucun événement n'a été traité
    return IGUIElement::OnEvent(event);
}

void ButtonRadio::remove()
{
    if(Parent) Parent->removeChild(this);
    delete this;
}

void ButtonRadio::setSelected(bool selected)
{
    Checked = selected;
    ICentre->setVisible(Checked);
}

bool ButtonRadio::isSelected()
{
    return Checked;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
#ifndef GUI_BUTTONRADIOCONTROL_H
#define GUI_BUTTONRADIOCONTROL_H

#include "GUI_ButtonRadio.h"

class ButtonRadio;

/**
PathImage doit pointer le dossier dans lequel se trouve les images nécessaires
aux ButtonRadio.

Utilisation :

    #include "GUI_ButtonRadioControl.h"

    /// création du controleur de bouton radio
    BRC0 = new ButtonRadioControl(recti(0,25,290,75), mGUI, L"../MEDIAS/Systeme/GUI/", mBR_0);

    /// ajout de boutons radio
    ButtonRadio *bouton = BRC0->addButton(position2di(5,5));
    BRC0->addButton(position2di(25,5));
    BRC0->addButton(position2di(45,5));

**/


class ButtonRadioControl : public IGUIElement
{
    public:
        ButtonRadioControl(rect<s32> rectangle, IGUIEnvironment* environment, stringw pathImage, IGUIElement* parent=0, s32 id=-1);
        virtual ~ButtonRadioControl();
        bool OnEvent(const SEvent& event);

        //! se détache de son parent et se détruit
        void remove();
        //! ajoute un bouton radio à la liste
        ButtonRadio* addButton(position2di position=position2di(0,0));
        //! retire et détruit un bouton radio de la liste
        void removeButton(ButtonRadio* button);
        //! renvoie l'ID du bouton sélectionné ou -1 s'il n'y en a pas
        int getSelected();

    protected:
        void select(u32 newSelect);

        /// MEMBRES ///
        array<ButtonRadio*> mListButton;
        u32 Select;

        stringw PathImage;

    private:

};

#endif // GUI_BUTTONRADIOCONTROL_H
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
#include "GUI_ButtonRadioControl.h"

#include "IGUIEnvironment.h"
#include "IVideoDriver.h"


ButtonRadioControl::ButtonRadioControl(rect<s32> rectangle, IGUIEnvironment* gui, stringw pathImage, IGUIElement* parent, s32 id)
: IGUIElement(EGUIET_ELEMENT, gui, (parent!=0)?parent:gui->getRootGUIElement(), -1, rectangle), Select(0), PathImage(pathImage)
{
    #ifdef _DEBUG
    setDebugName("ButtonRadio");
    #endif

    /// initialisation des membres
    mListButton.clear();
}

ButtonRadioControl::~ButtonRadioControl()
{
    /// détruit les boutons de la liste
    for(u32 a=0; a < mListButton.size(); ++a)
        mListButton[a]->remove();
    /// vide la liste
    mListButton.clear();
}

bool ButtonRadioControl::OnEvent(const SEvent& event)
{
    if (isEnabled())
    {
        /// événements de la gui
        if (event.EventType == EET_GUI_EVENT)
        {
            if (event.GUIEvent.EventType == EGET_CHECKBOX_CHANGED)
            {
                for(u32 a=0; a < mListButton.size(); ++a)
                {
                    if(event.GUIEvent.Caller == mListButton[a])
                    {
                        select(a);
                        return true;
                    }
                }
            }
        }
    }
    /// si aucun événement n'a été traité par BoxRetractable
    return IGUIElement::OnEvent(event);
}

void ButtonRadioControl::remove()
{
    if(Parent) Parent->removeChild(this);
    delete this;
}

ButtonRadio* ButtonRadioControl::addButton(position2di position)
{
    if( mListButton.empty() ) mListButton.push_back( new ButtonRadio(Environment, position, this, PathImage.c_str(), true) );
    else mListButton.push_back( new ButtonRadio(Environment, position, this) );
    return mListButton.getLast();
}

void ButtonRadioControl::removeButton(ButtonRadio* button)
{
    for(u32 a=0; a < mListButton.size(); ++a)
        if(mListButton[a] == button)
        {
            button->remove();
            mListButton.erase(a);
            return;
        }
}

int ButtonRadioControl::getSelected()
{
    return mListButton.empty()?-1:Select;
}

void ButtonRadioControl::select(u32 newSelect)
{
    if(Select < mListButton.size())
    {
        /// met à false l'ancien selected
        if(Select < mListButton.size()) mListButton[Select]->setSelected(false);
        /// met à true le nouveau selected
        mListButton[newSelect]->setSelected(true);
        /// met à jour l'index du selected
        Select = newSelect;
    }
}


Voilà, rien de bien compliqué mais ça peut être utile.
A plus!