Modes.py 15 KB

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