Pages: 1 2
Hello,
la dernière solution proposée par lilive me parait au final la meilleure point de vue implémentation dans la logique de cette application mais demande une refonte du code que je vais m'épargner
Alors j'ai mis en place deux solutions (merci à lilive pour m'avoir mis sur la voie) :
1) la solution de lilive proposée au post #10 fonctionne. Elle permet d'obtenir un ID en relation avec le gui intégrant le bouton cliqué.
On peut alors manipuler les widgets de ce canvas et/ou appeler des fonctions du projecteur lié à ce canvas.
Ci dessous un exemple qui active le premier toggle du canvas (en haut, ce toggle permet de sélectionner le projecteur)
if(e.widget->getName() == "MUTE ON") { int ID = -1; for( int i = 0; i < commandGUI.size(); ++i){ if( e.widget->getParent() == commandGUI[i] ){ ID = i; } } cout << ID << endl; ofxUILabelButton *btn = (ofxUILabelButton *)commandGUI[ID]->getWidget((projectors[ID]->getProjectorName())); btn->setValue(true); }
2) une autre solution : affecter un ID au canvas à sa création en utilisant l'index du vector et en l'affectant avec la méthode gui->setName(); On peut ensuite le réutiliser dans les events.
Dans cette solution, il faut évidement convertir l'index du canvas en string pour l'affecter en nom de canvas et inversement pour le réutiliser en index dans l'event.
à la création du gui
ofxUICanvas *gui = new ofxUICanvas(300,0,length-xInit,150); ... ostringstream canvasId; canvasId << commandGUI.size(); gui->setName(canvasId.str()); ... commandGUI.push_back(gui); ofAddListener(gui->newGUIEvent, this, &testApp::guiEvent);
et dans l'event :
else if(e.widget->getName() == "MUTE ON") { int ID = atoi((e.widget->getParent()->getName()).c_str()); ... }
Je ne sais pas si c'est très propre mais ça a l'air de fonctionner.
Je ne sais pas non plus quelle est la solution la plus efficace.
Je vais voir si je trouve d'autres astuces et mettre l'une d'entre elle en place... on verra à l'usage.
Merci vraiment à tous.
Hors ligne
Pour les ofxUILabelButtons et ofxUILabelToggle, il est bien possible de dissocier le Name du texte affiché par le Widget (le label). Cela fonctionne.
Le Name est initialisé par :
gui1->addLabelButton("Nom du Widget", false, length-xInit);
Tu peux changer le label par :
((ofxUILabelButton* ) widget)->setLabelText("coucou");
Le truc est de retrouver le bon pointeur sur le widget. J'y arrive en itérant sur la liste des widgets de la gui. La liste est donnée par :
vector<ofxUIWidget *> &gui1Widgets = gui1->getWidgets();
Il y a peut être plus simple et général à toutes les widgets. les ofxUIWidget disposent en effet d'un champ ID modifiable et lisible.
Hors ligne
oui j'avais vu que le nom et label pour les labelButton et labelToggle sont deux infos différentes, seulement il faudrait que ce soit le cas pour tous les widgets.
Pour les ID oui j'ai vu que dans la définition de la classe ofxUIWidget il y a effectivement un ID. On a bien un getID() mais rien en setID. D'ailleurs j'ai fait un test mais, sauf erreur de ma part, je trouve toujours un ID = -1 quand je lis l'ID d'un widget. Je ne vois pas trop à quoi cela sert.
Hors ligne
Marty a écrit:
Pour les ID oui j'ai vu que dans la définition de la classe ofxUIWidget il y a effectivement un ID. On a bien un getID() mais rien en setID. D'ailleurs j'ai fait un test mais, sauf erreur de ma part, je trouve toujours un ID = -1 quand je lis l'ID d'un widget. Je ne vois pas trop à quoi cela sert.
Strange, j'ai bien des valeurs différentes d'ID pour chaque widget. Tu es sûr que tu ramènes bien l'ID de la widget, pas celle du canvas ? En fait à chaque instanciation d'une nouvelle widget, celle-ci se voit attribuer une ID incrémentée de 1 par rapport à la précédente. Et il y a bien une fonction setID pour les widgets.
Check this :
vector<ofxUIWidget *> &gui1Widgets = gui1->getWidgets(); int i_widgets;ofxUIWidget* currentWidget; int id; for( i_widgets = 0; i_widgets < gui1Widgets.size(); i_widgets++){ currentWidget = gui1Widgets[i_widgets]; currentWidget->setID(20-currentWidget->getID()); id = currentWidget->getID(); }
Hors ligne
Pardon pour le petit retour en arrière, mais en relisant j'accroche sur ça :
Marty a écrit:
void testApp::guiEvent(ofxUIEventArgs &e) { if(e.widget->getName() == "SELECT ALL") { int i = 0; vector<ofxUICanvas *>::iterator it; for(it = commandGUI.begin(); it != commandGUI.end(); it++) { ofxUILabelButton *btn = (ofxUILabelButton *)(*it)->getWidget((projectors[i]->getProjectorName())); btn->setValue(true); projectors[i]->setSelectedValue(true); i++; } } else if(e.widget->getName() == "SELECT NONE") { int i = 0; vector<ofxUICanvas *>::iterator it; for(it = commandGUI.begin(); it != commandGUI.end(); it++) { ofxUILabelButton *btn = (ofxUILabelButton *)(*it)->getWidget((projectors[i]->getProjectorName())); btn->setValue(false); projectors[i]->setSelectedValue(false); i++; } } }
Sauf erreur de ma part, quand on clique sur SELECT ALL, qui est je pense un LabelButton, ce code s'execute 2 fois: une première quand on enfonce le bouton de la souris, une seconde quand on le relâche. A vérifier, mais je crois qu'il vaudrait mieux vérifier le getValue() du bouton avant de rentrer dans la boucle qui fait les projectors[i]->setSelectedValue(true);
Idem pour SELECT NONE.
Hors ligne
@_thierry_ : au temps pour moi, c'est moi qui ai fait une boulette et qui est mal lu. Il était 2h du matin il ya a effectivement ce qu'il faut pour les ID dans les widgets.
Ceci dit après réflexion cela ne m'est guerre utile. Ce qu'il me faut surtout c'est pouvoir dire "quand clic sur bouton du PROJECTEUR 1, se connecter à l'ADRESSE IP 1". Il vaut mieux dans ce cas partir sur une numérotation des canvas et pas des widgets.
@lilive : oui effectivement tu as raison. Je fais bien un test avec getValue() sur d'autres bouton. Je t'avoue que la a force de bidouiller à droite et à gauche je n'ai pas fait attention. Une fois que les solutions sont trouvées et fonctionnelles, j'implémente le tout proprement et je repasse dessus pour revérifier et nettoyer. Merci pour l'info.
Hors ligne
Bonjour Marty,
Je t'ai mis un petit exemple fonctionnel de gestion dynamique des canvas avec récupération des données.
J'ai parcouru ton programme et il serait judicieux pour toi d'utiliser les classes pour une meilleure lisibilité de ton code.
Bon courage.
Hors ligne
Salut,
Extra Mushussu ! merci pour l'exemple c'est très sympa !
La je suis en pleine implémentation des fonctions mais l'idée finale est effectivement de pouvoir ajouter/supprimer des projecteurs à la volée.
Quand tu dis qu'il serait judicieux d'utiliser les classes... que veux tu dire ? Parceque je pensais justement utiliser la classe dans ce que je fais !
Il y a encore pas mal à faire, pour l'instant je bloque sur la connexion TCP qui bloque le programme quand l'adresse IP n'est pas bonne.
Le programme peut sembler complexe, et d'ailleurs il l'est probablement, je n'ai pas tous les bons réflexes des vrais développeurs ! Et il y a pas mal de contraintes (des fois que quelqu'un puisse m'aider ) :
- Régler le problème de blocage des connexions TCP. Parait-il qu'il faudrait mettre les connexions en Thread dédié !?
- initialiser les valeurs en interrogeant les projecteurs : Nom, ON/OFF, heures des lampes etc... évidement tant que le premier problème n'est pas réglé....
- Permettre la création dynamique de projecteurs
- du coup, en conséquence, il faudrait aussi pouvoir sauvegarder les valeurs : nombre de projecteurs, leurs IP etc... J'ai vu qu'il y avait l'addon ofXMLSettings pour cela...
De plus, le parc de projecteurs est assez hétérogène ce qui fait qu'il y a plusieurs protocoles à gérer. Quand le PJLINK est dispo j'utilise ce type de commandes, dans le cas contraire il faut utiliser des commandes spécifiques à chaque constructeur/modèle.
bref j'ai pas encore fini !
Dernière modification par Marty (2013-05-27 19:41:49)
Hors ligne
Pages: 1 2