PionDecor.py 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. #from __future__ import unicode_literals
  2. # -*- coding: utf-8 -*-
  3. from __future__ import division
  4. from PyQt4.QtCore import *
  5. from PyQt4.QtGui import *
  6. from Decor import Decor
  7. from Forme import Forme
  8. class PionDecor(QGraphicsItem):
  9. """pion du plateau de combat representant un decor"""
  10. def __init__(self, plateau, numero, parent=None):
  11. super(PionDecor, self).__init__(parent)
  12. #plateau
  13. self.plateau = plateau
  14. #attributs
  15. self.nom = "decor"
  16. self.numero = numero
  17. self.decor = Decor()
  18. self.position = (-1, -1)
  19. self.forme = Forme(self.plateau.formeCases)
  20. self.z = 0
  21. self.hauteur = 1 #hauteur de l'objet en cases
  22. self.pixGraphique = None
  23. self.largeurOriginale = 0
  24. self.hauteurOriginale = 0
  25. self.polygoneGraphique = None
  26. self.nbRotations = 0
  27. def __getstate__(self):
  28. state = {key:value for key, value in self.__dict__.items() if not key in ["plateau", "forme", "polygoneGraphique", "pixGraphique", "shadow"]}
  29. return (state)
  30. def __setstate__(self, state):
  31. self.__dict__ = state
  32. def paint(self, painter, option, widget = None):
  33. """reimplemente de QGraphicsItem"""
  34. pass
  35. def surbrillance(self, active):
  36. """active/desactive la surbrillance"""
  37. pass
  38. def txtId(self):
  39. return self.nom
  40. ########### fonctions graphiques et geometriques ##############
  41. def creer(self, posX, posY, decor, nbRotations):
  42. """place le pion decor sur le plateau"""
  43. self.decor = decor
  44. self.setFlag(QGraphicsItem.ItemHasNoContents) #inutile de peindre l'item
  45. self.setHandlesChildEvents(True)
  46. if len(self.decor.formeDef[self.plateau.formeCases]) > 0:
  47. self.forme.definirForme(self.decor.formeDef[self.plateau.formeCases])
  48. self.hauteur = self.decor.hauteur
  49. self.position = (posX, posY)
  50. self.majNbRotations(nbRotations)
  51. #aspect graphique
  52. self.majAspectGraphique()
  53. #ajout de l'objet graphique et placement
  54. self.plateau.addItem(self)
  55. def recreer(self, plateau):
  56. """recree l'objet graphique apres un chargement"""
  57. self.plateau = plateau
  58. super(PionDecor, self).__init__()
  59. self.setFlag(QGraphicsItem.ItemHasNoContents) #inutile de peindre l'item
  60. self.setHandlesChildEvents(True)
  61. self.polygoneGraphique = None
  62. self.pixGraphique = None
  63. self.forme = Forme(self.plateau.formeCases)
  64. if len(self.decor.formeDef[self.plateau.formeCases]) > 0:
  65. self.forme.definirForme(self.decor.formeDef[self.plateau.formeCases])
  66. #aspect graphique
  67. self.majAspectGraphique()
  68. #ajout de l'objet graphique et placement
  69. self.plateau.addItem(self)
  70. def majAspectGraphique(self):
  71. """met a jour l'aspect graphique du pion"""
  72. #creation de la forme
  73. if not self.polygoneGraphique:
  74. polygone = self.plateau.polygoneAgglo(self.forme.listeCases((0,0)))
  75. self.polygoneGraphique = QGraphicsPolygonItem()
  76. self.polygoneGraphique.setPolygon(polygone)
  77. self.polygoneGraphique.setAcceptHoverEvents(True)
  78. self.polygoneGraphique.setFlag(QGraphicsItem.ItemIsFocusable) #l'item peut recevoir des commandes souris/clavier
  79. self.polygoneGraphique.setParentItem(self)
  80. self.polygoneGraphique.setPos(QPointF(0,0))
  81. if self.plateau.formeCases == "H":
  82. self.polygoneGraphique.setTransformOriginPoint(QPointF(2*0.2886*self.plateau.hCase,0.5*self.plateau.hCase))
  83. else:
  84. self.polygoneGraphique.setTransformOriginPoint(QPointF(0.5*self.plateau.hCase,0.5*self.plateau.hCase))
  85. if self.plateau.formeCases == "H":
  86. angleRotation = 60
  87. positionGraphique = QPointF(self.position[0] * 0.866 * self.plateau.hCase, self.position[1] * self.plateau.hCase)
  88. else:
  89. angleRotation = 90
  90. positionGraphique = QPointF(self.position[0] * self.plateau.hCase, self.position[1] * self.plateau.hCase)
  91. self.polygoneGraphique.setRotation(self.nbRotations*angleRotation)
  92. self.setPos(positionGraphique)
  93. self.setZValue(10) #place au dessus des cases
  94. #interactions
  95. self.setFlag(QGraphicsItem.ItemIsFocusable)
  96. self.setAcceptHoverEvents(True) #accepte les evenements survol souris
  97. #bordure
  98. pinceau = QPen()
  99. #pinceau.setColor(self.decor.couleur.darker(130))
  100. pinceau.setColor(self.decor.couleur)
  101. pinceau.setWidth(10)
  102. self.polygoneGraphique.setPen(pinceau)
  103. #ombre
  104. self.shadow = QGraphicsDropShadowEffect()
  105. self.shadow.setColor(QColor(50, 50, 50))
  106. self.shadow.setXOffset(1)
  107. self.shadow.setYOffset(2)
  108. self.shadow.setBlurRadius(3)
  109. self.shadow.setEnabled(True)
  110. self.polygoneGraphique.setGraphicsEffect(self.shadow)
  111. #maj de l'image
  112. self.majImage()
  113. #fond
  114. if self.decor.couleur.isValid():
  115. self.polygoneGraphique.setBrush(self.decor.couleur)
  116. else:
  117. self.polygoneGraphique.setBrush(QColor(255, 0, 0, 100))
  118. #on met a jour l'occupation des cases
  119. for coord in self.forme.listeCases((self.position[0],self.position[1]), self.nbRotations):
  120. self.plateau.cases[coord].majOccupation(self, self.z)
  121. def majImage(self):
  122. """met a jour la taille, la position et l'orientation de l'image"""
  123. if len(self.decor.img["nom"]) > 0:
  124. pix = QPixmap(QString.fromUtf8("img\\"+self.decor.img["nom"]))
  125. if self.decor.img["masqueAuto"]:
  126. pix.setMask(pix.createHeuristicMask())
  127. if not pix.isNull():
  128. if not self.pixGraphique:
  129. self.pixGraphique = QGraphicsPixmapItem()
  130. self.pixGraphique.setZValue(10)
  131. if pix.height() >= pix.width():
  132. pix = pix.scaledToHeight(self.plateau.hCase*0.9, Qt.SmoothTransformation)
  133. else:
  134. pix = pix.scaledToWidth(self.plateau.hCase*0.9, Qt.SmoothTransformation)
  135. self.largeurOriginale = pix.width()
  136. self.hauteurOriginale = pix.height()
  137. pix = pix.scaled((self.decor.img["kx"]/10)*pix.width(), \
  138. (self.decor.img["ky"]/10)*pix.height(), \
  139. Qt.IgnoreAspectRatio, Qt.SmoothTransformation)
  140. self.pixGraphique.setPixmap(pix)
  141. deltaX = self.decor.img["dx"] + 0.5*(self.plateau.hCase*1.1544 - self.largeurOriginale)
  142. deltaY = self.decor.img["dy"] + 0.5*(self.plateau.hCase - self.hauteurOriginale)
  143. if self.decor.img["nom"] != self.decor.logo and self.decor.img["pivote"] == True:
  144. self.pixGraphique.setParentItem(self.polygoneGraphique)
  145. else:
  146. self.pixGraphique.setParentItem(self)
  147. self.pixGraphique.setRotation(self.decor.img["rotation"])
  148. self.pixGraphique.setPos(QPointF(deltaX, deltaY))
  149. def majNbRotations(self, nbRotations):
  150. self.nbRotations = nbRotations
  151. if self.plateau.formeCases == "H":
  152. rotationsTour = 6
  153. else:
  154. rotationsTour = 4
  155. if self.nbRotations >= 0:
  156. self.nbRotations = self.nbRotations % rotationsTour
  157. else:
  158. self.nbRotations = self.nbRotations % (-rotationsTour)
  159. def majPosition(self, position, nbRotations = 0):
  160. for coord in self.forme.listeCases((self.position[0],self.position[1]), self.nbRotations):
  161. self.plateau.cases[coord].majOccupation(self)
  162. self.position = position
  163. self.majNbRotations(nbRotations)
  164. self.majAspectGraphique()
  165. def afficheOmbreSelection(self, actif = False):
  166. if actif:
  167. self.shadow.setXOffset(3)
  168. self.shadow.setYOffset(3)
  169. else:
  170. self.shadow.setXOffset(1)
  171. self.shadow.setYOffset(2)
  172. def supprimer(self):
  173. """'deconnecte' les items enfants avant de supprimer du pion"""
  174. if self.pixGraphique != None:
  175. self.pixGraphique.prepareGeometryChange()
  176. self.pixGraphique.setParentItem(None)
  177. self.polygoneGraphique.prepareGeometryChange()
  178. self.polygoneGraphique.setParentItem(None)
  179. self.plateau.removeItem(self)
  180. self.plateau = None
  181. ##################
  182. ############### evenements clavier et souris ##############
  183. def boundingRect(self):
  184. return QRectF()
  185. def hoverEnterEvent(self, event):
  186. """evenement lors du survol de la souris (en entree)"""
  187. self.plateau.caseSurvol(self.plateau.cases[self.position])
  188. self.plateau.pionDecorSurvol(self.numero)
  189. def hoverLeaveEvent(self, event):
  190. """evenement lors du survol de la souris (en sortie)"""
  191. self.plateau.pionDecorSurvol(None)
  192. def mousePressEvent(self, event):
  193. """evenement lors du clic souris"""
  194. if event.button() == 1: #sur clic gauche
  195. #en mode creation, on peut selectionner le decor pour le deplacer ou le supprimer
  196. if self.plateau.modePrincipal == "creation":
  197. self.plateau.pionDecorSaisir(self.numero)
  198. event.accept()
  199. else:
  200. event.ignore()
  201. #######################