Voilà j'ai codé ça cet après-midi donc je partage.
C'est un nouveau GUIElement qui se presente sous forme de boite avec une barre de titre et qui a la particularité de pouvoir se rétracter et prendre une forme compacte (seule la barre de titre reste visible). Elle possède aussi le nécessaire pour chainer plusieurs boites les une aux autres afin que lorsque qu'une boite se rétracte elle tire la boite qui lui est associée qui elle-même tire la boite qui lui est associée... Pour les avantages, inconvénients et l'utilisation, j'ai mis ce qu'il faut dans le .h. Si quelqu'un a des idées pour améliorer, ou si quelqu'un l'améliore de son côté qu'il poste ça, on pourrait avoir quelque chose de sympa.
#include "GUI_BoxRetractable.h"
#include "IGUIEnvironment.h"
#include "IVideoDriver.h"
#include "IGUISkin.h"
/// initilisation des membres statiques
int BoxRetractable::compteurInstance=0;
ITexture* BoxRetractable::TCaption=NULL;
ITexture* BoxRetractable::TBordure=NULL;
/**
rectangle : position et taille maximale de l'objet
title : texte affiché dans la barre de titre de la box
suivant : permet de faire une chaine de boxretractable, lorsque qu'une boite est rétractée les boites en dessous sont relevées
retractable : si dans une chaine une boite doit ne pas être rétractable
**/
BoxRetractable::BoxRetractable(rect<s32> rectangle, stringw title, IGUIEnvironment* GUI, stringw pathImage, IGUIElement* parent, BoxRetractable* suivant, bool retractable, s32 id)
: IGUIElement(EGUIET_ELEMENT, GUI, (parent!=0)?parent:GUI->getRootGUIElement(), id, rectangle), mGUI(GUI), Suivant(suivant), mRetractable(retractable)
{
#ifdef _DEBUG
setDebugName("BoxRetractable");
#endif
/// si c'est la première instance on charge les textures
if(compteurInstance < 1)
{
TCaption = mGUI->getVideoDriver()->getTexture(pathImage+"BoxRetractable_caption.jpg");
TBordure = mGUI->getVideoDriver()->getTexture(pathImage+"BoxRetractable_bord.jpg");
}
/// incrémente le compteur d'instance
compteurInstance++;
#ifdef _DEBUG
printf("Nb d'instances : %i\
", compteurInstance);
#endif
/// récupère le skin
IGUISkin* skin = mGUI->getSkin();
/// les tailles etendue et rétractée
mExtendSize = rectangle;
mRetractSize = mExtendSize;
mRetractSize.LowerRightCorner.Y = rectangle.UpperLeftCorner.Y + skin->getSize(EGDS_CHECK_BOX_WIDTH) + 2;
/// dimension relatives
ExtendSize = position2di(rectangle.LowerRightCorner.X-rectangle.UpperLeftCorner.X,rectangle.LowerRightCorner.Y-rectangle.UpperLeftCorner.Y);
RetractSize = position2di(ExtendSize.X,skin->getSize(EGDS_CHECK_BOX_WIDTH) + 2);
/// image de fond du titre
recti CaptionSize(position2di(0,0),RetractSize);
ICaption = mGUI->addImage(CaptionSize, this);
ICaption->setImage(TCaption);
ICaption->setScaleImage(true);
/// choix entre retractable ou non
if(retractable)
{
STExtend = NULL;
/// bouton "extend" pour le pliage et le dépliage et titre de l'élément
CBExtend = mGUI->addCheckBox(true, recti(position2di(1,1), CaptionSize.LowerRightCorner), this, -1, title.c_str());
}
else
{
CBExtend = NULL;
/// affiche le titre mais pas la box
STExtend = mGUI->addStaticText(title.c_str(), recti(position2di(skin->getSize(EGDS_CHECK_BOX_WIDTH)+6, 1), CaptionSize.LowerRightCorner), false, false, this);
STExtend->setTextAlignment(EGUIA_UPPERLEFT, EGUIA_CENTER);
}
/// cadre entourant la box
// bordure gauche
recti bordure_gauche(0,CaptionSize.LowerRightCorner.Y,1,ExtendSize.Y);
IGauche = mGUI->addImage(bordure_gauche, this);
IGauche->setImage(TBordure);
IGauche->setScaleImage(true);
// bordure droite
recti bordure_droite(ExtendSize.X-1,CaptionSize.LowerRightCorner.Y,ExtendSize.X,ExtendSize.Y);
IDroite = mGUI->addImage(bordure_droite, this);
IDroite->setImage(TBordure);
IDroite->setScaleImage(true);
// bordure basse
recti bordure_basse(0,ExtendSize.Y-1,ExtendSize.X,ExtendSize.Y);
IBasse = mGUI->addImage(bordure_basse, this);
IBasse->setImage(TBordure);
IBasse->setScaleImage(true);
/// calcule le décalage
mDecalage = mExtendSize.LowerRightCorner.Y - mRetractSize.LowerRightCorner.Y;
}
BoxRetractable::~BoxRetractable()
{
/// décrémente le compteur d'instance
compteurInstance--;
#ifdef _DEBUG
printf("Nb d'instances : %i\
", compteurInstance);
#endif
/// libération des ressources
if(STExtend) STExtend->remove();
if(ICaption) ICaption->remove();
if(IGauche) IGauche->remove();
if(IDroite) IDroite->remove();
if(IBasse) IBasse->remove();
if(compteurInstance < 1)
{
if(TCaption) { mGUI->getVideoDriver()->removeTexture(TCaption); TCaption = NULL; }
if(TBordure) { mGUI->getVideoDriver()->removeTexture(TBordure); TBordure = NULL; }
}
}
bool BoxRetractable::OnEvent(const SEvent& event)
{
/// événements de la GUI
if (event.EventType == EET_GUI_EVENT)
{
if (event.GUIEvent.EventType == EGET_CHECKBOX_CHANGED)
{
if(mRetractable)
{
if(event.GUIEvent.Caller == CBExtend)
{
if(CBExtend->isChecked())
{
setExtend(true);
moveSuivant(mDecalage);
}
else
{
setExtend(false);
moveSuivant(-mDecalage);
}
}
}
}
}
/// si aucun événement n'a été traité par BoxRetractable
return IGUIElement::OnEvent(event);
}
void BoxRetractable::setSuivant(BoxRetractable* suivant)
{
Suivant = suivant;
}
void BoxRetractable::setExtend(bool extend)
{
/// récupère la position
recti newPos = getRelativePosition();
/// modifie la taille de l'élément
if(extend) newPos.LowerRightCorner = newPos.UpperLeftCorner + ExtendSize;
else newPos.LowerRightCorner = newPos.UpperLeftCorner + RetractSize;
/// applique la nouvelle taille
setRelativePosition(newPos);
}
void BoxRetractable::moveSuivant(s32 decalage)
{
if(Suivant != NULL) Suivant->moveRequest(decalage);
}
void BoxRetractable::moveRequest(s32 decalage)
{
move(position2di(0,decalage));
moveSuivant(decalage);
}
Les 2 fichiers images qui servent de shin à la box : (ces fichiers sont nécessaires et il faut donner le chemin d'accès à la création de la box) Pour les enregistrer "clic droit" sur le lien, "enregistrer la cible sous" car les fichiers sont tout petits. BoxRetractable_bord.jpg BoxRetractable_caption.jpg
Voilà!
Màj 1 : chargement unique des textures et destruction automatique grace à un compteur d'instance.
Prochaines fonctionnalités à implémenter :
ajout et chainage avec des positions relatives entre les maillons; FAIT dans la v2
Voilà j'ai codé ça cet après-midi donc je partage.
C'est un nouveau GUIElement qui se presente sous forme de boite avec une barre de titre et qui a la particularité de pouvoir se rétracter et prendre une forme compacte (seule la barre de titre reste visible). Elle possède aussi le nécessaire pour chainer plusieurs boites les une aux autres afin que lorsque qu'une boite se rétracte elle tire la boite qui lui est associée qui elle-même tire la boite qui lui est associée... Pour les avantages, inconvénients et l'utilisation, j'ai mis ce qu'il faut dans le .h. Si quelqu'un a des idées pour améliorer, ou si quelqu'un l'améliore de son côté qu'il poste ça, on pourrait avoir quelque chose de sympa.
#include "GUI_BoxRetractable.h"
#include "IGUIEnvironment.h"
#include "IVideoDriver.h"
#include "IGUISkin.h"
/// initilisation des membres statiques
int BoxRetractable::compteurInstance=0;
ITexture* BoxRetractable::TCaption=NULL;
ITexture* BoxRetractable::TBordure=NULL;
/**
rectangle : position et taille maximale de l'objet
title : texte affiché dans la barre de titre de la box
suivant : permet de faire une chaine de boxretractable, lorsque qu'une boite est rétractée les boites en dessous sont relevées
retractable : si dans une chaine une boite doit ne pas être rétractable
**/
BoxRetractable::BoxRetractable(rect<s32> rectangle, stringw title, IGUIEnvironment* GUI, stringw pathImage, IGUIElement* parent, BoxRetractable* suivant, bool retractable, s32 id)
: IGUIElement(EGUIET_ELEMENT, GUI, (parent!=0)?parent:GUI->getRootGUIElement(), id, rectangle), mGUI(GUI), Suivant(suivant), mRetractable(retractable)
{
#ifdef _DEBUG
setDebugName("BoxRetractable");
#endif
/// si c'est la première instance on charge les textures
if(compteurInstance < 1)
{
TCaption = mGUI->getVideoDriver()->getTexture(pathImage+"BoxRetractable_caption.jpg");
TBordure = mGUI->getVideoDriver()->getTexture(pathImage+"BoxRetractable_bord.jpg");
}
/// incrémente le compteur d'instance
compteurInstance++;
#ifdef _DEBUG
printf("Nb d'instances : %i\
", compteurInstance);
#endif
/// récupère le skin
IGUISkin* skin = mGUI->getSkin();
/// les tailles etendue et rétractée
mExtendSize = rectangle;
mRetractSize = mExtendSize;
mRetractSize.LowerRightCorner.Y = rectangle.UpperLeftCorner.Y + skin->getSize(EGDS_CHECK_BOX_WIDTH) + 2;
/// dimension relatives
ExtendSize = position2di(rectangle.LowerRightCorner.X-rectangle.UpperLeftCorner.X,rectangle.LowerRightCorner.Y-rectangle.UpperLeftCorner.Y);
RetractSize = position2di(ExtendSize.X,skin->getSize(EGDS_CHECK_BOX_WIDTH) + 2);
/// image de fond du titre
recti CaptionSize(position2di(0,0),RetractSize);
ICaption = mGUI->addImage(CaptionSize, this);
ICaption->setImage(TCaption);
ICaption->setScaleImage(true);
/// choix entre retractable ou non
if(retractable)
{
STExtend = NULL;
/// bouton "extend" pour le pliage et le dépliage et titre de l'élément
CBExtend = mGUI->addCheckBox(true, recti(position2di(1,1), CaptionSize.LowerRightCorner), this, -1, title.c_str());
}
else
{
CBExtend = NULL;
/// affiche le titre mais pas la box
STExtend = mGUI->addStaticText(title.c_str(), recti(position2di(skin->getSize(EGDS_CHECK_BOX_WIDTH)+6, 1), CaptionSize.LowerRightCorner), false, false, this);
STExtend->setTextAlignment(EGUIA_UPPERLEFT, EGUIA_CENTER);
}
/// cadre entourant la box
// bordure gauche
recti bordure_gauche(0,CaptionSize.LowerRightCorner.Y,1,ExtendSize.Y);
IGauche = mGUI->addImage(bordure_gauche, this);
IGauche->setImage(TBordure);
IGauche->setScaleImage(true);
// bordure droite
recti bordure_droite(ExtendSize.X-1,CaptionSize.LowerRightCorner.Y,ExtendSize.X,ExtendSize.Y);
IDroite = mGUI->addImage(bordure_droite, this);
IDroite->setImage(TBordure);
IDroite->setScaleImage(true);
// bordure basse
recti bordure_basse(0,ExtendSize.Y-1,ExtendSize.X,ExtendSize.Y);
IBasse = mGUI->addImage(bordure_basse, this);
IBasse->setImage(TBordure);
IBasse->setScaleImage(true);
/// calcule le décalage
mDecalage = mExtendSize.LowerRightCorner.Y - mRetractSize.LowerRightCorner.Y;
}
BoxRetractable::~BoxRetractable()
{
/// décrémente le compteur d'instance
compteurInstance--;
#ifdef _DEBUG
printf("Nb d'instances : %i\
", compteurInstance);
#endif
/// libération des ressources
if(STExtend) STExtend->remove();
if(ICaption) ICaption->remove();
if(IGauche) IGauche->remove();
if(IDroite) IDroite->remove();
if(IBasse) IBasse->remove();
if(compteurInstance < 1)
{
if(TCaption) { mGUI->getVideoDriver()->removeTexture(TCaption); TCaption = NULL; }
if(TBordure) { mGUI->getVideoDriver()->removeTexture(TBordure); TBordure = NULL; }
}
}
bool BoxRetractable::OnEvent(const SEvent& event)
{
/// événements de la GUI
if (event.EventType == EET_GUI_EVENT)
{
if (event.GUIEvent.EventType == EGET_CHECKBOX_CHANGED)
{
if(mRetractable)
{
if(event.GUIEvent.Caller == CBExtend)
{
if(CBExtend->isChecked())
{
setExtend(true);
moveSuivant(mDecalage);
}
else
{
setExtend(false);
moveSuivant(-mDecalage);
}
}
}
}
}
/// si aucun événement n'a été traité par BoxRetractable
return IGUIElement::OnEvent(event);
}
void BoxRetractable::setSuivant(BoxRetractable* suivant)
{
Suivant = suivant;
}
void BoxRetractable::setExtend(bool extend)
{
/// récupère la position
recti newPos = getRelativePosition();
/// modifie la taille de l'élément
if(extend) newPos.LowerRightCorner = newPos.UpperLeftCorner + ExtendSize;
else newPos.LowerRightCorner = newPos.UpperLeftCorner + RetractSize;
/// applique la nouvelle taille
setRelativePosition(newPos);
}
void BoxRetractable::moveSuivant(s32 decalage)
{
if(Suivant != NULL) Suivant->moveRequest(decalage);
}
void BoxRetractable::moveRequest(s32 decalage)
{
move(position2di(0,decalage));
moveSuivant(decalage);
}
Les 2 fichiers images qui servent de shin à la box : (ces fichiers sont nécessaires et il faut donner le chemin d'accès à la création de la box) Pour les enregistrer "clic droit" sur le lien, "enregistrer la cible sous" car les fichiers sont tout petits. BoxRetractable_bord.jpg BoxRetractable_caption.jpg
Voilà!
Màj 1 : chargement unique des textures et destruction automatique grace à un compteur d'instance.
Prochaines fonctionnalités à implémenter :
ajout et chainage avec des positions relatives entre les maillons; FAIT dans la v2