Modes.py 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471
  1. #from __future__ import unicode_literals
  2. # -*- coding: utf-8 -*-
  3. """les modes d'interaction permettent l'interaction
  4. entre l'interface (l'utilisateur) et le plateau de combat.
  5. Un seul mode ne peut etre actif a la fois
  6. Cette classe doit permettre de recevoir les commandes de l'utilisateur
  7. de maniere a produire un resultat unique (cases peintes, pion deplace...)"""
  8. from PyQt4.QtCore import *
  9. from PyQt4.QtGui import *
  10. from EntreeSortie import EntreeSortie
  11. import Actions
  12. import regles
  13. class ModeBase(object):
  14. """mode de base: tous les modes heritent de cette classe"""
  15. def __init__(self, plateau):
  16. self.plateau = plateau
  17. #le mode est il active
  18. self._actif = False
  19. #le dragmode est il active sur la QGraphicsView
  20. self._activerDragMode = 0
  21. #curseur de la QGraphicsView
  22. self._sourceCurseur = ""
  23. #met le focus sur la QGraphicsView a l'activation
  24. self._focus = False
  25. def nom(self):
  26. return self.__class__.__name__
  27. def activer(self, param = None):
  28. """active le mode"""
  29. self.activerCurseur()
  30. if self._focus:
  31. self.plateau.fenetre.ui.cbt_vue.setFocus()
  32. self._actif = True
  33. def desactiver(self):
  34. """desactive le mode"""
  35. self.desactiverCurseur()
  36. self.plateau.fenetre.ui.cbt_vue.setDragMode(1)
  37. self._actif = False
  38. def reinit(self):
  39. """remet les variables a 0 et reactive le mode"""
  40. pass
  41. def activerCurseur(self):
  42. self.plateau.fenetre.ui.cbt_vue.setDragMode(self._activerDragMode)
  43. curseurPix = QPixmap(self._sourceCurseur)
  44. if not curseurPix.isNull():
  45. curseurPinceau = QCursor(curseurPix, 0, curseurPix.height())
  46. self.plateau.fenetre.ui.cbt_vue.setCursor(curseurPinceau)
  47. def desactiverCurseur(self):
  48. self.plateau.fenetre.ui.cbt_vue.setCursor(QCursor(Qt.ArrowCursor))
  49. ### gestion des evenements souris
  50. # clic gauche
  51. def clic_combattant(self, num):
  52. pass
  53. def clic_decor(self, num):
  54. pass
  55. def clic_case(self, coord):
  56. pass
  57. #double clic gauche
  58. def doubleClic_combattant(self, num):
  59. pass
  60. def doubleClic_decor(self, num):
  61. pass
  62. def doubleClic_case(self, coord):
  63. pass
  64. #survol de la souris (entree)
  65. def survol_combattant(self, num):
  66. pass
  67. def survol_decor(self, num):
  68. pass
  69. def survol_case(self, coord):
  70. pass
  71. #survol de la souris (sortie)
  72. def finSurvol_combattant(self, num):
  73. pass
  74. def finSurvol_decor(self, num):
  75. pass
  76. def finSurvol_case(self, coord):
  77. pass
  78. #survol de la souris avec clic gauche enfonce (entree)
  79. def survolClic_combattant(self, event):
  80. pass
  81. def survolClic_decor(self, event):
  82. pass
  83. def survolClic_case(self, coord):
  84. pass
  85. #autre
  86. def clicGauche(self, event):
  87. pass
  88. def finClicGauche(self, event):
  89. pass
  90. def mouvementSouris(self, event):
  91. pass
  92. def toucheClavier(self, event):
  93. pass
  94. def clicDroit(self, event):
  95. pass
  96. class ModeBaseCp(ModeBase):
  97. """mode servant de base a tous les modes lies a la creation de plateau"""
  98. def __init__(self, plateau):
  99. super(ModeBaseCp, self).__init__(plateau)
  100. self.type = "cp"
  101. def clicDroit(self, event):
  102. self.plateau.activerMode(StandardCp)
  103. class ModeBasePi(ModeBase):
  104. """mode servant de base a tous les modes lies aux actions des combattants"""
  105. def __init__(self, plateau):
  106. super(ModeBasePi, self).__init__(plateau)
  107. self.type = "pi"
  108. def clicDroit(self, event):
  109. self.plateau.activerMode(StandardPi)
  110. ### --------------------------------------- ####
  111. class StandardCp(ModeBaseCp):
  112. """mode standard en creation de plateau"""
  113. def __init__(self, plateau):
  114. super(StandardCp, self).__init__(plateau)
  115. self._sourceCurseur = ""
  116. self._focus = False
  117. self._activerDragMode = True
  118. def clic_pion(self, num):
  119. pass
  120. #doit selectionner le pion
  121. class MajCases(ModeBaseCp):
  122. """mode de mise a jour des cases (terrain, couleur, effet special)"""
  123. def __init__(self, plateau):
  124. super(MajCases, self).__init__(plateau)
  125. self._sourceCurseur = "img\\curseurPinceau.png"
  126. self._focus = True
  127. self._param = None #parametre avec lequel on mettra a jour la case
  128. def activer(self, param):
  129. """active le mode"""
  130. self.majParam(param)
  131. super(MajCases, self).activer()
  132. def desactiver(self):
  133. """desactive le mode"""
  134. self.plateau.pinceau.reinit()
  135. super(MajCases, self).desactiver()
  136. def majParam(self, param):
  137. self._param = param
  138. def param(self):
  139. return self._param
  140. def clic_case(self, coord):
  141. #demarre une operation de peinture des cases
  142. self.plateau.pinceau.demarrer(coord)
  143. def survolClic_case(self, coord):
  144. self.plateau.pinceau.maj(coord)
  145. def finClicGauche(self, event):
  146. if self.plateau.pinceau.estActif():
  147. for coord in self.plateau.pinceau.selection():
  148. if self._param.__class__.__name__ == "Terrain":
  149. self.plateau.cases[coord].majTerrain(self._param)
  150. elif self._param.__class__.__name__ == "QColor":
  151. if self._param.isValid():
  152. self.plateau.cases[coord].majTerrain(None)
  153. self.plateau.cases[coord].majCouleur(self._param)
  154. elif self._param.__class__.__name__ == "EffetCase":
  155. self.plateau.cases[coord].majEffet(self._param)
  156. self.plateau.pinceau.reinit()
  157. self.reinit()
  158. def toucheClavier(self, event):
  159. if event.key() == Qt.Key_Up:
  160. self.plateau.fenetre.ui.epaisseurPinceau.setValue(self.plateau.fenetre.ui.epaisseurPinceau.value()+1)
  161. elif event.key() == Qt.Key_Down:
  162. self.plateau.fenetre.ui.epaisseurPinceau.setValue(self.plateau.fenetre.ui.epaisseurPinceau.value()-1)
  163. class Pipette(ModeBaseCp):
  164. """mode pipette: on preleve la couleur ou le terrain d'une case"""
  165. def __init__(self, plateau):
  166. super(Pipette, self).__init__(plateau)
  167. self._sourceCurseur = "img\\curseurSeringue.png"
  168. def activerCurseur(self):
  169. super(Pipette, self).activerCurseur()
  170. def clic_case(self, coord):
  171. if len(self.plateau.cases[coord].terrain.nom) > 0:
  172. param = self.plateau.cases[coord].terrain
  173. else:
  174. param = self.plateau.cases[coord].couleur
  175. self.plateau.activerMode(MajCases, param)
  176. class ZonePlacement(ModeBaseCp):
  177. """mode de definition de la/les zones de placement des joueurs"""
  178. def __init__(self, plateau):
  179. super(ZonePlacement, self).__init__(plateau)
  180. self._sourceCurseur = "img\\curseurPinceau.png"
  181. self._focus = True
  182. def activerCurseur(self):
  183. super(ZonePlacement, self).activerCurseur()
  184. def activer(self, param = None):
  185. self.plateau.pinceau.majForme("rectP")
  186. self.plateau.pinceau.verrouillerForme(True)
  187. super(ZonePlacement, self).activer()
  188. def desactiver(self):
  189. self.plateau.pinceau.reinit()
  190. super(ZonePlacement, self).desactiver()
  191. def clic_case(self, coord):
  192. #demarre une operation de peinture des cases
  193. self.plateau.pinceau.demarrer(coord)
  194. def survolClic_case(self, coord):
  195. self.plateau.pinceau.maj(coord)
  196. def finClicGauche(self, coord):
  197. if self.plateau.pinceau.estActif():
  198. if len(self.plateau.pinceau.selection()) > 0:
  199. self.plateau.majZonePlacement(self.plateau.pinceau.selection())
  200. class EntreesSorties(ModeBaseCp):
  201. """mode de definition deentrees et sorties du plateau"""
  202. def __init__(self, plateau):
  203. super(EntreesSorties, self).__init__(plateau)
  204. self._sourceCurseur = "img\\curseurPinceau.png"
  205. self._focus = True
  206. def activerCurseur(self):
  207. super(EntreesSorties, self).activerCurseur()
  208. def activer(self, param):
  209. self.es = param
  210. self.es.creerForme()
  211. super(EntreesSorties, self).activer()
  212. def desactiver(self):
  213. if not self.es.estPositionne:
  214. self.es.prepareGeometryChange()
  215. self.es.plateau = None
  216. self.plateau.removeItem(self.es)
  217. super(EntreesSorties, self).desactiver()
  218. def mouvementSouris(self, event):
  219. if event.buttons() != Qt.LeftButton:
  220. if not self.es.estPositionne:
  221. self.es.majProjection(event.scenePos())
  222. def clicGauche(self, event):
  223. if not event.isAccepted():
  224. self.es.positionner()
  225. self.plateau.entreesSorties.append(self.es)
  226. self.desactiver()
  227. def toucheClavier(self, event):
  228. if event.key() == Qt.Key_Delete:
  229. #supprimer l'es
  230. self.desactiver()
  231. elif event.key() == Qt.Key_Right:
  232. self.es.nbRotations += 1
  233. self.es.majProjection()
  234. elif event.key() == Qt.Key_Left:
  235. self.es.nbRotations -= 1
  236. self.es.majProjection()
  237. class CreationPion(ModeBaseCp):
  238. """mode de creation de pions (combattant ou decor)"""
  239. def __init__(self, plateau):
  240. super(CreationPion, self).__init__(plateau)
  241. self._focus = True
  242. self._pion = None
  243. def activer(self, pion):
  244. self._pion = pion
  245. self.plateau.proj.creer(self._pion)
  246. super(CreationPion, self).activer()
  247. def desactiver(self):
  248. self.plateau.proj.desactiver()
  249. self._pion = None
  250. super(CreationPion, self).desactiver()
  251. def survol_case(self, coord):
  252. if self._pion:
  253. self.plateau.proj.majCoord(coord)
  254. def clic_case(self, coord):
  255. if self._pion:
  256. self.plateau.creerPion(self._pion)
  257. def toucheClavier(self, event):
  258. if self._pion:
  259. if event.key() == Qt.Key_Right:
  260. self.plateau.proj.majRotation(1)
  261. elif event.key() == Qt.Key_Left:
  262. self.plateau.proj.majRotation(-1)
  263. class SuppressionPion(ModeBaseCp):
  264. """mode de suppression de pions (combattant ou decor)"""
  265. def __init__(self, plateau):
  266. super(SuppressionPion, self).__init__(plateau)
  267. self._sourceCurseur = "img\\gomme.png"
  268. self._focus = True
  269. def clicGauche(self, event):
  270. """supprime le pion sous le clic. S'il y en a plusieurs,
  271. supprime le premier de la pile"""
  272. item = self.plateau.itemAt(event.scenePos())
  273. if item.parentItem().__class__.__name__ in ["Combattant", "Decor"]:
  274. self.plateau.pionSupprimer(item.parentItem().numero)
  275. class DeplacementPion(ModeBaseCp):
  276. """mode de deplacement de pions (combattant ou decor) en mode creation
  277. attention: different des actions de type deplacement qu'effectuent les pions en mode Combat"""
  278. def __init__(self, plateau):
  279. super(DeplacementPion, self).__init__(plateau)
  280. self._num = 0
  281. def activer(self, num):
  282. self._num = num
  283. if self._num < 10000:
  284. pion = self.plateau.combattants[self._num]
  285. else:
  286. pion = self.plateau.decors[self._num]
  287. self.plateau.proj.creer(pion)
  288. self.deplace = False
  289. super(DeplacementPion, self).activer()
  290. def desactiver(self):
  291. self.plateau.proj.desactiver()
  292. self._num = 0
  293. super(DeplacementPion, self).desactiver()
  294. def survol_case(self, coord):
  295. if self._num > 0:
  296. self.plateau.proj.majCoord(coord)
  297. self.deplace = True
  298. def clic_case(self, coord):
  299. if self._num > 0:
  300. if self.deplace:
  301. if self._num < 10000:
  302. pion = self.plateau.combattants[self._num]
  303. else:
  304. pion = self.plateau.decors[self._num]
  305. pion.majPosition(self.plateau.proj.coord(), self.plateau.proj.nbRotations())
  306. def toucheClavier(self, event):
  307. if self._num > 0:
  308. if event.key() == Qt.Key_Right:
  309. self.plateau.proj.majRotation(1)
  310. self.deplace = True
  311. elif event.key() == Qt.Key_Left:
  312. self.plateau.proj.majRotation(-1)
  313. self.deplace = True
  314. #-----------------------------------------------
  315. #-----------------------------------------------
  316. class StandardPi(ModeBasePi):
  317. """mode standard de la manipulation de pion en combat"""
  318. def __init__(self, plateau):
  319. super(StandardPi, self).__init__(plateau)
  320. self._focus = False
  321. self._activerDragMode = True
  322. def clic_combattant(self, num):
  323. self.plateau.activerMode(PionSelectionne, num)
  324. def nouvelleAction(self, action):
  325. pass
  326. class PionSelectionne(ModeBasePi):
  327. """mode active a la selection d'un pion combattant"""
  328. def __init__(self, plateau):
  329. super(PionSelectionne, self).__init__(plateau)
  330. self._focus = True
  331. self._num = None
  332. self._action = None
  333. def pion(self):
  334. """retourne la ref du pion actuellement selectionne"""
  335. retour = None
  336. if self._num in self.plateau.combattants:
  337. retour = self.plateau.combattants[self._num]
  338. return retour
  339. def activer(self, num):
  340. self._num = num
  341. #intensifie l'ombre du pion
  342. self.pion().afficheOmbreSelection(True)
  343. self.plateau.majPanneauPi()
  344. super(PionSelectionne, self).activer()
  345. def desactiver(self):
  346. if self._action:
  347. self._action.desactiver()
  348. self._action = None
  349. self.pion().afficheOmbreSelection(False)
  350. self._num = None
  351. self.plateau.majPanneauPi()
  352. super(PionSelectionne, self).desactiver()
  353. def nouvelleAction(self, action):
  354. self._action = action()
  355. self._action.activer(self.plateau, self._num)
  356. def survol_case(self, coord):
  357. if self._action:
  358. self._action.majCoordCible(coord)
  359. def clic_case(self, coord):
  360. if self._action:
  361. self._action.valider()
  362. def clicDroit(self, event):
  363. if self._action:
  364. self._action.desactiver()
  365. self._action = None
  366. else:
  367. super(PionSelectionne, self).clicDroit(event)