Modes.py 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476
  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. print self._param.franchissable
  150. self.plateau.cases[coord].majTerrain(self._param)
  151. elif self._param.__class__.__name__ == "QColor":
  152. if self._param.isValid():
  153. self.plateau.cases[coord].majTerrain(None)
  154. self.plateau.cases[coord].majCouleur(self._param)
  155. elif self._param.__class__.__name__ == "EffetCase":
  156. self.plateau.cases[coord].majEffet(self._param)
  157. self.plateau.pinceau.reinit()
  158. self.reinit()
  159. def toucheClavier(self, event):
  160. if event.key() == Qt.Key_Up:
  161. self.plateau.fenetre.ui.epaisseurPinceau.setValue(self.plateau.fenetre.ui.epaisseurPinceau.value()+1)
  162. elif event.key() == Qt.Key_Down:
  163. self.plateau.fenetre.ui.epaisseurPinceau.setValue(self.plateau.fenetre.ui.epaisseurPinceau.value()-1)
  164. class Pipette(ModeBaseCp):
  165. """mode pipette: on preleve la couleur ou le terrain d'une case"""
  166. def __init__(self, plateau):
  167. super(Pipette, self).__init__(plateau)
  168. self._sourceCurseur = "img\\curseurSeringue.png"
  169. def activerCurseur(self):
  170. super(Pipette, self).activerCurseur()
  171. def clic_case(self, coord):
  172. if len(self.plateau.cases[coord].terrain.nom) > 0:
  173. param = self.plateau.cases[coord].terrain
  174. else:
  175. param = self.plateau.cases[coord].couleur
  176. self.plateau.activerMode(MajCases, param)
  177. class ZonePlacement(ModeBaseCp):
  178. """mode de definition de la/les zones de placement des joueurs"""
  179. def __init__(self, plateau):
  180. super(ZonePlacement, self).__init__(plateau)
  181. self._sourceCurseur = "img\\curseurPinceau.png"
  182. self._focus = True
  183. def activerCurseur(self):
  184. super(ZonePlacement, self).activerCurseur()
  185. def activer(self, param = None):
  186. self.plateau.pinceau.majForme("rectP")
  187. self.plateau.pinceau.verrouillerForme(True)
  188. super(ZonePlacement, self).activer()
  189. def desactiver(self):
  190. self.plateau.pinceau.reinit()
  191. super(ZonePlacement, self).desactiver()
  192. def clic_case(self, coord):
  193. #demarre une operation de peinture des cases
  194. self.plateau.pinceau.demarrer(coord)
  195. def survolClic_case(self, coord):
  196. self.plateau.pinceau.maj(coord)
  197. def finClicGauche(self, coord):
  198. if self.plateau.pinceau.estActif():
  199. if len(self.plateau.pinceau.selection()) > 0:
  200. self.plateau.majZonePlacement(self.plateau.pinceau.selection())
  201. class EntreesSorties(ModeBaseCp):
  202. """mode de definition deentrees et sorties du plateau"""
  203. def __init__(self, plateau):
  204. super(EntreesSorties, self).__init__(plateau)
  205. self._sourceCurseur = "img\\curseurPinceau.png"
  206. self._focus = True
  207. def activerCurseur(self):
  208. super(EntreesSorties, self).activerCurseur()
  209. def activer(self, param):
  210. self.es = param
  211. self.es.creerForme()
  212. super(EntreesSorties, self).activer()
  213. def desactiver(self):
  214. if not self.es.estPositionne:
  215. self.es.prepareGeometryChange()
  216. self.es.plateau = None
  217. self.plateau.removeItem(self.es)
  218. super(EntreesSorties, self).desactiver()
  219. def mouvementSouris(self, event):
  220. if event.buttons() != Qt.LeftButton:
  221. if not self.es.estPositionne:
  222. self.es.majProjection(event.scenePos())
  223. def clicGauche(self, event):
  224. if not event.isAccepted():
  225. self.es.positionner()
  226. self.plateau.entreesSorties.append(self.es)
  227. self.desactiver()
  228. def toucheClavier(self, event):
  229. if event.key() == Qt.Key_Delete:
  230. #supprimer l'es
  231. self.desactiver()
  232. elif event.key() == Qt.Key_Right:
  233. self.es.nbRotations += 1
  234. self.es.majProjection()
  235. elif event.key() == Qt.Key_Left:
  236. self.es.nbRotations -= 1
  237. self.es.majProjection()
  238. class CreationPion(ModeBaseCp):
  239. """mode de creation de pions (combattant ou decor)"""
  240. def __init__(self, plateau):
  241. super(CreationPion, self).__init__(plateau)
  242. self._focus = True
  243. self._pion = None
  244. def activer(self, pion):
  245. self._pion = pion
  246. self.plateau.proj.creer(self._pion)
  247. super(CreationPion, self).activer()
  248. def desactiver(self):
  249. self.plateau.proj.desactiver()
  250. self._pion = None
  251. super(CreationPion, self).desactiver()
  252. def survol_case(self, coord):
  253. if self._pion:
  254. self.plateau.proj.majCoord(coord)
  255. def clic_case(self, coord):
  256. if self._pion:
  257. self.plateau.creerPion(self._pion)
  258. def toucheClavier(self, event):
  259. if self._pion:
  260. if event.key() == Qt.Key_Right:
  261. self.plateau.proj.majRotation(1)
  262. elif event.key() == Qt.Key_Left:
  263. self.plateau.proj.majRotation(-1)
  264. class SuppressionPion(ModeBaseCp):
  265. """mode de suppression de pions (combattant ou decor)"""
  266. def __init__(self, plateau):
  267. super(SuppressionPion, self).__init__(plateau)
  268. self._sourceCurseur = "img\\gomme.png"
  269. self._focus = True
  270. def clicGauche(self, event):
  271. """supprime le pion sous le clic. S'il y en a plusieurs,
  272. supprime le premier de la pile"""
  273. item = self.plateau.itemAt(event.scenePos())
  274. if item.parentItem().__class__.__name__ in ["Combattant", "Decor"]:
  275. self.plateau.pionSupprimer(item.parentItem().numero)
  276. class DeplacementPion(ModeBaseCp):
  277. """mode de deplacement de pions (combattant ou decor) en mode creation
  278. attention: different des actions de type deplacement qu'effectuent les pions en mode Combat"""
  279. def __init__(self, plateau):
  280. super(DeplacementPion, self).__init__(plateau)
  281. self._num = 0
  282. def activer(self, num):
  283. self._num = num
  284. if self._num < 10000:
  285. pion = self.plateau.combattants[self._num]
  286. else:
  287. pion = self.plateau.decors[self._num]
  288. self.plateau.proj.creer(pion)
  289. self.deplace = False
  290. super(DeplacementPion, self).activer()
  291. def desactiver(self):
  292. self.plateau.proj.desactiver()
  293. self._num = 0
  294. super(DeplacementPion, self).desactiver()
  295. def survol_case(self, coord):
  296. if self._num > 0:
  297. self.plateau.proj.majCoord(coord)
  298. self.deplace = True
  299. def clic_case(self, coord):
  300. if self._num > 0:
  301. if self.deplace:
  302. if self._num < 10000:
  303. pion = self.plateau.combattants[self._num]
  304. else:
  305. pion = self.plateau.decors[self._num]
  306. pion.majPosition(self.plateau.proj.coord(), self.plateau.proj.nbRotations())
  307. def toucheClavier(self, event):
  308. if self._num > 0:
  309. if event.key() == Qt.Key_Right:
  310. self.plateau.proj.majRotation(1)
  311. self.deplace = True
  312. elif event.key() == Qt.Key_Left:
  313. self.plateau.proj.majRotation(-1)
  314. self.deplace = True
  315. #-----------------------------------------------
  316. #-----------------------------------------------
  317. class StandardPi(ModeBasePi):
  318. """mode standard de la manipulation de pion en combat"""
  319. def __init__(self, plateau):
  320. super(StandardPi, self).__init__(plateau)
  321. self._focus = False
  322. self._activerDragMode = True
  323. def clic_combattant(self, num):
  324. self.plateau.activerMode(PionSelectionne, num)
  325. def nouvelleAction(self, action):
  326. pass
  327. class PionSelectionne(ModeBasePi):
  328. """mode active a la selection d'un pion combattant"""
  329. def __init__(self, plateau):
  330. super(PionSelectionne, self).__init__(plateau)
  331. self._focus = True
  332. self._num = None
  333. self._action = None
  334. def pion(self):
  335. """retourne la ref du pion actuellement selectionne"""
  336. retour = None
  337. if self._num in self.plateau.combattants:
  338. retour = self.plateau.combattants[self._num]
  339. return retour
  340. def activer(self, num):
  341. self._num = num
  342. #intensifie l'ombre du pion
  343. self.pion().afficheOmbreSelection(True)
  344. self.plateau.majPanneauPi()
  345. super(PionSelectionne, self).activer()
  346. def desactiver(self):
  347. if self._action:
  348. self._action.desactiver()
  349. self._action = None
  350. self.pion().afficheOmbreSelection(False)
  351. self._num = None
  352. self.plateau.majPanneauPi()
  353. super(PionSelectionne, self).desactiver()
  354. def nouvelleAction(self, action):
  355. self._action = action()
  356. self._action.activer(self.plateau, self._num)
  357. def survol_case(self, coord):
  358. if self._action:
  359. self._action.majCoordCible(coord)
  360. def clic_case(self, coord):
  361. if self._action:
  362. self._action.valider()
  363. def clicDroit(self, event):
  364. if self._action:
  365. self._action.desactiver()
  366. self._action = None
  367. else:
  368. super(PionSelectionne, self).clicDroit(event)
  369. def toucheClavier(self, event):
  370. if self._num > 0:
  371. if event.key() == Qt.Key_Right:
  372. self._action.pivoter(1)
  373. elif event.key() == Qt.Key_Left:
  374. self._action.pivoter(-1)