PDA

Voir la version complète : Préréglages de paramètres



César Vonc
22/11/2013, 13h26
Bonjour,


J'ai un petit problème de logique : j'ai créé un générateur de type ObjectData avec plusieurs paramètres, ainsi qu'un menu déroulant de préréglages pour tous les modifier.

Jusque là, tout va bien, lorsque le préréglage a une certaine valeur, tous les autres paramètres se modifient, mais du coup, je ne peux plus rien modifier car le préréglage prend le dessus et les re-modifie instantanément !


Il faudrait que la valeur de préréglage aille sur une valeur comme « Personnalisée » lorsqu'on modifie un paramètre autre que le préréglage, mais comment détecter quel paramètre l'utilisateur modifie...



J'ai essayé avec la fonction Message, mais le seul type de message qui renvoie le paramètre touché est
MSG_DESCRIPTION_COMMAND, réservé aux boutons, d'après mes essais. Donc je suis un peu bloqué. : /


Quelqu'un a une idée ?

valkaari
22/11/2013, 18h49
je te dirais bien de regarder avec les fonctions GetDDescription, GetDParameter et SetDParameter

... sauf qu'elles ne sont pas implémentée en python :sweatdrop:

xs_yann
22/11/2013, 20h36
Salut,

Bizarrement on dirait qu'il n'y a pas moyen de récupérer l'id d'un élément de description qui n'est pas un bouton...
A défaut d'avoir une solution plus propre, tu peux toujours faire un test après chaque modification de paramètres, genre :


class PluginObject(c4d.plugins.ObjectData):

__preset = {c4d.PLUGIN_PARAM1: 10, c4d.PLUGIN_PARAM2: 3}

def Init(self, node):
# Init preset
for id, value in self.__preset.items():
node[id] = value
return True

def _isPreset(self, node):
for id, value in self.__preset.items():
if node[id] != value:
return False
return True

def Message(self, node, type, data):
if type == c4d.MSG_DESCRIPTION_VALIDATE:
if self._isPreset(node):
print "preset"
else:
print "something changed"
return True

def GetVirtualObjects(self, op, hh):
pass

En utilisant c4d.MSG_DESCRIPTION_VALIDATE ou c4d.MSG_DESCRIPTION_USERINTERACTION_END qui sont envoyés après chaque modification de paramètre.

César Vonc
22/11/2013, 21h56
Ah zut !

Si je comprends bien, ta fonction permet de vérifier si les paramètres après les avoir modifiés sont les mêmes que ceux du préréglage.

Donc on s'en servirait pour vérifier s'il faut ou non modifier les paramètres lorsque le préréglage est sélectionné et les params différentes, d'accord, je vois le truc.


Sinon, je viens de penser à plus simple : comparer la valeur du préréglage actuel avec celle précédente, si pareil, ne rien faire et passer en mode personnalisé, sinon charger le préréglage.

C'est certes léger mais à la moindre modif, même identique, on passe en mode perso.


Enfin, je crois avoir tous les éléments, merci à vous. ^^

xs_yann
22/11/2013, 22h49
Tiens j'ai développer un peu le code, ça a l'air de marcher :


class PluginObject(c4d.plugins.ObjectData):

_currentPreset = None

_presets = { ids.PLUGIN_PRESET_1: { ids.PLUGIN_PARAM1: 10, ids.PLUGIN_PARAM2: 5 },
ids.PLUGIN_PRESET_2: { ids.PLUGIN_PARAM1: 20, ids.PLUGIN_PARAM2: 10 }
}

def _applyPreset(self, node, preset_id):
"""Apply the preset corresponding to preset_id.
"""
preset = self._presets[preset_id]
for id, value in preset.items():
node[id] = value
self._currentPreset = preset_id

def _isPreset(self, node, preset_id):
"""Return true if the preset 'preset_id' is set.
"""
preset = self._presets[preset_id]
for id, value in preset.items():
if node[id] != value:
return False
return True

def _managePresets(self, node):
"""Manage presets.
"""
preset = node[ids.PLUGIN_PRESET]
if preset in self._presets:
if self._currentPreset != preset:
self._applyPreset(node, preset)
elif not self._isPreset(node, preset):
self._currentPreset = ids.PLUGIN_PRESET_CUSTOM
node[ids.PLUGIN_PRESET] = ids.PLUGIN_PRESET_CUSTOM


def Message(self, node, type, data):
if type == c4d.MSG_DESCRIPTION_VALIDATE:
self._managePresets(node)
return True

def Init(self, node):
node[ids.PLUGIN_PRESET] = ids.PLUGIN_PRESET_1
self._applyPreset(node, ids.PLUGIN_PRESET_1)
return True

def GetVirtualObjects(self, op, hh):
pass

Qui correspond à une description dans ce style :


COMBOBOX PLUGIN_PRESET
{
PLUGIN_PRESET_1,
PLUGIN_PRESET_2,
PLUGIN_PRESET_CUSTOM

}

LONG PLUGIN_PARAM1
LONG PLUGIN_PARAM2

Le principe : si le menu déroulant est sur un preset, on vérifie sur quoi il était avant. S'il était sur un autre preset ou sur personnalisé, on applique le preset.
S'il était déjà sur ce preset, on vérifie les valeurs des paramètres. Si elles correspondent au preset on ne fait rien sinon on met sur personnalisé.

Et a priori le c4d.MSG_DESCRIPTION_COMMAND fonctionne pour les boutons et les boutons bitmaps (à partir de la R14), mais pas plus d'infos.

César Vonc
22/11/2013, 23h29
C'est pour l'éventuel lecteur anglophone qui se serait perdu sur la toile que t'écris tes commentaires et fonctions en anglais, Yann ? :icon_mrgreen:


J'en demandais pas tant, encore merci !

xs_yann
23/11/2013, 00h09
C'est pour l'éventuel lecteur anglophone qui se serait perdu sur la toile que t'écris tes commentaires et fonctions en anglais, Yann ? :icon_mrgreen:

Non c'est par habitude, j'ai même pas fait attention...

Bon sur un bout de code comme ça, ça sert à rien (c'est plus cours juste) mais à mon avis tes sources y a pas que des francophones qui les regardent. ;)

Je t'ai fais une version spéciale :icon_mrgreen: :


class ObjetPlugin(c4d.plugins.ObjectData):

_prereglageCourrant = None

_prereglages = { ids.PLUGIN_PREREGLAGE_1: { ids.PLUGIN_PARAM1: 10, ids.PLUGIN_PARAM2: 5 },
ids.PLUGIN_PREREGLAGE_2: { ids.PLUGIN_PARAM1: 20, ids.PLUGIN_PARAM2: 10 }
}

def _appliquerPrereglage(moi, noeud, identifiant_prereglage):
"""Applique le préréglage correspondant à 'identifiant_prereglage'.
"""
prereglage = moi._prereglages[identifiant_prereglage]
for id, valeur in prereglage.items():
noeud[id] = valeur
moi._prereglageCourrant = identifiant_prereglage

def _estPrereglage(moi, noeud, identifiant_prereglage):
"""Retourne True si le préréglage 'identifiant_prereglage' est défini.
"""
prereglage = moi._prereglages[identifiant_prereglage]
for id, valeur in prereglage.items():
if noeud[id] != valeur:
return False
return True

def _gererPrereglages(moi, noeud):
"""Gère les préréglages.
"""
prereglage = noeud[ids.PLUGIN_PREREGLAGE]
if prereglage in moi._prereglages:
if moi._prereglageCourrant != prereglage:
moi._appliquerPrereglage(noeud, prereglage)
elif not moi._estPrereglage(noeud, prereglage):
moi._prereglageCourrant = ids.PLUGIN_PREREGLAGE_PERSONNALISE
noeud[ids.PLUGIN_PREREGLAGE] = ids.PLUGIN_PREREGLAGE_PERSONNALISE


def Message(moi, noeud, type, donnee):
if type == c4d.MSG_DESCRIPTION_VALIDATE:
moi._gererPrereglages(noeud)
return True

def Init(moi, noeud):
noeud[ids.PLUGIN_PREREGLAGE] = ids.PLUGIN_PREREGLAGE_1
moi._appliquerPrereglage(noeud, ids.PLUGIN_PREREGLAGE_1)
return True

def GetVirtualObjects(moi, op, hh):
pass



J'en demandais pas tant, encore merci !

Pas de soucis. ;)

César Vonc
23/11/2013, 12h14
Bon sur un bout de code comme ça, ça sert à rien (c'est plus cours juste) mais à mon avis tes sources y a pas que des francophones qui les regardent. ;)

Et pour l'instant aucun ne s'en est plaint. :icon_mrgreen:


Ah, c'est quand même plus clair ! ^^ Même si j'aurais mis « soi » plutôt que « moi ».