Case.py 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636
  1. #from __future__ import unicode_literals
  2. # -*- coding: utf-8 -*-
  3. from __future__ import division
  4. from PyQt4.QtCore import Qt, SIGNAL, QPointF, QString, QRectF
  5. from PyQt4.QtGui import QGraphicsPolygonItem, QColor, QGraphicsItem, \
  6. QGraphicsSimpleTextItem, QBrush, QPen, QRadialGradient, QFont, qRed, \
  7. qGreen, qBlue, QGraphicsEllipseItem, QGraphicsTextItem, QTextBlockFormat, \
  8. QTextCursor
  9. import Modes
  10. from Pion import Pion
  11. from Terrain import Terrain
  12. from lib.dmF import DmPile
  13. class Case(QGraphicsPolygonItem):
  14. """objet graphique representant une case du plateau"""
  15. def __init__(self, plateau, parent=None):
  16. super(Case, self).__init__(parent)
  17. #plateau
  18. self.plateau = plateau
  19. #attributs
  20. self.x = 0
  21. self.y = 0
  22. self.z0 = 0
  23. self.terrain = Terrain() #terrain par defaut
  24. self.bordure = QColor(85, 85, 85, 85) #couleur de la bordure par defaut
  25. self.centreGraphique = None
  26. # self._occ = {} #zA: num du pion
  27. self._occ = DmPile()
  28. self.caches = [] #liste des caches places par le MJ sur la case (cache le terrain, les decors, les pions aux joueurs...)
  29. #effet sur la case
  30. self.effetActif = ""
  31. #polygones d'affichage
  32. self.polygoneEffet = None
  33. self.polygoneAffichageSpecial = None
  34. self.etiquetteAltitude = None
  35. self.polygoneCache = None
  36. def __getstate__(self):
  37. """selectionne les attributs qui seront sauvegardes"""
  38. state = {key:value for key, value in self.__dict__.items() if key in ["x", "y", "z0","terrain","bordure","couleur", \
  39. "ombre", "effetActif", "caches"]}
  40. return (state)
  41. def __setstate__(self, state):
  42. """recupere les attributs sauvegardes"""
  43. self.__dict__ = state
  44. # if self.z0 == None: self.z0 = 0
  45. ######## fonctions de base : geometrie, aspect graphique ######
  46. def creer(self, x, y, couleur = QColor(0, 255, 0, 80)):
  47. """creation du polygone et enregistrement des donnees geometriques"""
  48. self.x = x
  49. self.y = y
  50. self.terrain.couleur = couleur
  51. #creation de l'objet graphique sur le plateau
  52. self.creerGraphique()
  53. def creerGraphique(self):
  54. """cree les objets graphiques representant la case"""
  55. #reinitialisation des variables
  56. self.couleurEffet = {"brule":QColor("orange"), "glace":QColor("white"), "poison":QColor("green"), "eau":QColor("blue")}
  57. self.imgEffet = {"brule":"effFeu.jpg", "glace":"effGlace.jpg", "poison":"effPoison.png", "eau":"effEau.png"}
  58. #enregistrement des cases voisines:
  59. self.voisins = self.lstVoisins(self.x, self.y)
  60. # self._occ = {}
  61. self._occ = DmPile()
  62. #enregistrement du centre
  63. if self.plateau.formeCases == "H": #refPlateau
  64. k = 0
  65. if 1 == (self.x % 2): k = 0.5
  66. self.centreGraphique = QPointF(((self.x*0.866)+0.5773)*self.plateau.hCase, (self.y+k+0.5)*self.plateau.hCase)
  67. else:
  68. self.centreGraphique = QPointF((self.x+0.5)*self.plateau.hCase, (self.y+0.5)*self.plateau.hCase)
  69. #cree le polygone de la case
  70. self.setPolygon(self.polygone())
  71. self.plateau.addItem(self) #refPlateau
  72. #interactions graphiques:
  73. self.setFlag(QGraphicsItem.ItemIsFocusable)
  74. self.setAcceptHoverEvents(True)
  75. self.setAcceptDrops(True)
  76. self.setZValue(0)
  77. self.setFiltersChildEvents(True)
  78. # #pour afficher les coordonnees des cases:
  79. self.etiquette = None
  80. self.afficherEtiquette("{}-{}".format(self.x,self.y))
  81. self.logoDep = LogoDep(self)
  82. self.logoDep.creer()
  83. #apparence initiale de la case
  84. self.majTerrain(self.terrain)
  85. #polygone utilise pour afficher la cible du curseur
  86. self.maille = Maille(self)
  87. self.maille.creer()
  88. # self.polygoneCible = QGraphicsPolygonItem(self.polygone(self.x, self.y), parent=self)
  89. # self.polygoneCible = QGraphicsPolygonItem(self.polygone(self.x, self.y))
  90. # self.polygoneCible.setVisible(False)
  91. # self.polygoneCible.setAcceptHoverEvents(False)
  92. # self.polygoneCible.setZValue(100)
  93. # self.plateau.addItem(self.polygoneCible)
  94. #cache
  95. self.polygoneCache = PolygoneCache(self)
  96. self.polygoneCache.creer()
  97. def recreer(self, plateau):
  98. ## self.plateau = plateau #refPlateau
  99. self.plateau = plateau
  100. super(Case, self).__init__()
  101. #polygones d'affichage
  102. self.polygoneEffet = None
  103. self.polygoneAffichageSpecial = None
  104. self.polygoneCache = None
  105. self.etiquetteAltitude = None
  106. self.creerGraphique()
  107. self.majTerrain(self.terrain)
  108. self.majEffet(self.effetActif)
  109. def polygone(self):
  110. return self.plateau.polygone(self.x, self.y)
  111. # def polygone(self, x, y):
  112. # """renvoie l'objet graphique hexagone de la case"""
  113. # polygone = QPolygonF()
  114. # if self.plateau.formeCases == "H":
  115. # #si x est impair sur un plateau a cases hexagonales, le y est augmente de 0.5
  116. # if 1 == (x % 2):
  117. # y += 0.5
  118. # polygone << QPointF(((x*0.866)+0.2886)*self.plateau.hCase, y*self.plateau.hCase) \
  119. # << QPointF(((x*0.866)+0.866)*self.plateau.hCase, y*self.plateau.hCase) \
  120. # << QPointF(((x*0.866)+1.1547)*self.plateau.hCase, (y+0.5)*self.plateau.hCase) \
  121. # << QPointF(((x*0.866)+0.866)*self.plateau.hCase, (y+1)*self.plateau.hCase) \
  122. # << QPointF(((x*0.866)+0.2886)*self.plateau.hCase, (y+1)*self.plateau.hCase) \
  123. # << QPointF( (x*0.866)*self.plateau.hCase, (y+0.5)*self.plateau.hCase)
  124. # else:
  125. # polygone << QPointF(x*self.plateau.hCase, y*self.plateau.hCase) \
  126. # << QPointF((x+1)*self.plateau.hCase, y*self.plateau.hCase) \
  127. # << QPointF((x+1)*self.plateau.hCase, (y+1)*self.plateau.hCase) \
  128. # << QPointF(x*self.plateau.hCase, (y+1)*self.plateau.hCase)
  129. # return polygone
  130. def lstVoisins(self, x, y):
  131. """renvoie la liste des cases voisines
  132. seulement cases existantes sur le plateau / seulement cases adjacentes (cas des cases carrees)"""
  133. voisins = []
  134. if self.plateau.formeCases == "H":
  135. if 1 == (x % 2):
  136. lst = [(x, y-1), (x+1, y), (x+1, y+1), (x, y+1), (x-1, y+1), (x-1, y)]
  137. else:
  138. lst = [(x, y-1), (x+1, y-1), (x+1, y), (x, y+1), (x-1, y), (x-1, y-1)]
  139. else:
  140. lst = [(x, y-1), (x+1, y-1), (x+1, y), (x+1, y+1), (x, y+1), (x-1, y+1), (x-1, y), (x-1, y-1)]
  141. for coord in lst:
  142. if (coord[0] >= 0 and coord[1] >= 0 and coord[0] < self.plateau.nbCasesX and coord[1] < self.plateau.nbCasesY):
  143. voisins.append(coord)
  144. return voisins
  145. def afficherEtiquette(self, txt):
  146. """affiche l'etiquette avec le texte demande"""
  147. if self.etiquette == None:
  148. self.etiquette = QGraphicsSimpleTextItem(QString().fromUtf8(str(txt)), parent=self)
  149. k = 0
  150. if 1 == (self.x % 2): k = 0.5
  151. if self.plateau.formeCases == "H":
  152. self.etiquette.setPos(QPointF(((self.x*0.866)+0.2886)*self.plateau.hCase, (self.y+k+0.5)*self.plateau.hCase))
  153. else:
  154. self.etiquette.setPos(QPointF(self.x*self.plateau.hCase, self.y*self.plateau.hCase))
  155. else:
  156. self.etiquette.setText(QString().fromUtf8(str(txt)))
  157. ########################
  158. ### occupation
  159. def z0(self):
  160. """altitude du terrain nu """
  161. if self.terrain.hPlafond: return None
  162. return self.z0
  163. def zP(self):
  164. return self.plateau.zP if self.plateau.zP != None else 100
  165. def z1(self):
  166. """premiere altitude ABSOLUE disponible
  167. altitude z0 de la case, augmentee de la hauteur des decors empiles dessus;
  168. None si aucune altitude disponible"""
  169. if self.terrain.hPlafond: return None
  170. z1 = (self.z0 + self._occ.hauteur())
  171. if z1 >= self.zP(): return None
  172. return z1
  173. def occuper(self, num, h):
  174. """un pion vient occuper la case a l'altitude relative zR"""
  175. if h == 100: h = self.zP() - self.z0
  176. self._occ.ajouter(num, h)
  177. def liberer(self, num):
  178. """aucun pion n'occupe plus la case a l'altitude relative zR"""
  179. self._occ.retirer(num)
  180. def occupants(self):
  181. """renvoie la liste des occupants de la case"""
  182. return self._occ.pile()
  183. def occupant(self, zA = None):
  184. """renvoie l'occupant de la case a l'altitude ABSOLUE zA:
  185. - le numero du pion s'il y en a un
  186. - 0 si sous le sol ou au dessus du plafond
  187. - sinon None"""
  188. #1 - si pas d'altitude, on renvoie l'occupant du dessus s'il existe
  189. if not zA: return self._occ.premier()
  190. #2 - si au dessous du sol ou au dessus du plafond:
  191. if zA < self.z0 or zA >= self.zP(): return 0
  192. #3 - on renvoie l'objet de la pile s'il existe
  193. # (!!! attention, la pile fonctionne avec des altitudes relatives)
  194. return self._occ[(zA - self.z0)]
  195. def estOccupee(self, zA):
  196. """renvoie vrai si la case est occupee a l'altitude absolue zA"""
  197. return (self.occupant(zA) != None)
  198. def occupation(self):
  199. return self._occ
  200. def zA(self, num):
  201. """renvoie l'altitude absolue de l'occupant s'il existe, None sinon"""
  202. if not num in self.occupants(): return None
  203. return self.z0 + self._occ.zR(num)
  204. def hOcc(self, num):
  205. """renvoie la liste des altitudes absolues occupees poar le pion s'il existe,
  206. une liste vide sinon"""
  207. zA = self.zA(num)
  208. if not zA != None: return []
  209. return range(zA, (zA + self._occ.hDe(num)))
  210. ########## fonctions de maj ###########
  211. def majTerrain(self, terrain = Terrain()):
  212. """met a jour le terrain de la case"""
  213. self.terrain = terrain
  214. if self.terrain.couleur.isValid():
  215. self.setBrush(QBrush(self.terrain.couleur))
  216. pinceau = QPen()
  217. pinceau.setColor(self.couleurBordure())
  218. pinceau.setWidth(1)
  219. self.setPen(pinceau)
  220. def majAltitude(self, z0):
  221. """met a jour l'altitude de la case"""
  222. if z0 > self.zP(): z0 = self.zP()
  223. self.z0 = z0
  224. def majAffichageDeplacement(self, cout, valide = True, dz = 0):
  225. """lorsque cette case est sur le chemin d'un pion,
  226. un disque blanc ou rouge apparait indiquant le
  227. cout du deplacement jusqua cette case
  228. un cout de 0 fait disparaitre ce symbole"""
  229. self.logoDep.afficher(cout, valide, dz)
  230. def majEstCibleCurseur(self, actif, valide=True):
  231. """affiche la case comme etant la cible du curseur (lors d'une creation de pion, d'un deplacement...)"""
  232. self.maille.afficher(actif, valide)
  233. # if actif:
  234. # pinceau = QPen()
  235. # pinceau.setWidth(5)
  236. # brush = QBrush()
  237. # brush.setStyle(13)
  238. # pinceau.setColor(self.couleurProj(valide))
  239. # brush.setColor(self.couleurProj(valide))
  240. # self.polygoneCible.setPen(pinceau)
  241. # self.polygoneCible.setBrush(brush)
  242. # self.polygoneCible.setVisible(actif)
  243. def majEffet(self, effet):
  244. """met a jour l'effet actif sur la case"""
  245. if self.polygoneEffet == None:
  246. #on cree le polygone utilise pour afficher les effets
  247. self.polygoneEffet = QGraphicsPolygonItem(self.polygone(), parent=self)
  248. pinceau = QPen()
  249. pinceau.setColor(self.bordure)
  250. pinceau.setWidth(1)
  251. self.polygoneEffet.setPen(pinceau)
  252. self.polygoneEffet.setVisible(False)
  253. if len(effet) > 0 and effet != "aucun":
  254. #gradient de couleur
  255. gradient = QRadialGradient(self.centreGraphique, 0.5*self.plateau.hCase)
  256. couleur0 = QColor(0,0,0,0)
  257. couleur20 = self.couleurEffet[effet]
  258. couleur20.setAlpha(70)
  259. couleur10 = self.couleurEffet[effet]
  260. couleur10.setAlpha(255)
  261. gradient.setColorAt(0, couleur0)
  262. gradient.setColorAt(0.8, couleur0)
  263. gradient.setColorAt(0.95, couleur10)
  264. gradient.setColorAt(0.98, couleur20)
  265. gradient.setColorAt(1, couleur10)
  266. self.polygoneEffet.setBrush(gradient)
  267. self.polygoneEffet.setVisible(True)
  268. self.effetActif = effet
  269. else:
  270. self.effetActif = ""
  271. self.polygoneEffet.setVisible(False)
  272. #caches
  273. def ajouterCache(self, idCache):
  274. if not idCache in self.caches: self.caches.append(idCache)
  275. self.majCache()
  276. def retirerCache(self, idCache):
  277. if idCache in self.caches: self.caches.remove(idCache)
  278. self.majCache()
  279. def majCache(self):
  280. """met a jour l'aspect de la case selon la situation"""
  281. self.polygoneCache.afficher((len(self.caches) > 0))
  282. self.polygoneCache.majTransparence()
  283. def estCachee(self):
  284. """une case cachee ne recoit plus aucun evenement souris ou clavier"""
  285. return (len(self.caches) > 0)
  286. #fonctions secondaires
  287. def couleurDep(self):
  288. """renvoie une couleur secondaire utilisee pour les champs de deplacements"""
  289. luminositeActuelle = self.couleurEffective().lightness()
  290. if luminositeActuelle < 150:
  291. retour = QColor(210,255,255,100)
  292. else:
  293. retour = QColor(210,255,255,100)
  294. return retour
  295. def couleurProj(self, valide):
  296. """renvoie une couleur secondaire utilisee pour les projections de deplacement"""
  297. luminositeActuelle = self.couleurEffective().lightness()
  298. if valide:
  299. retour = QColor("white")
  300. else:
  301. retour = QColor("red")
  302. if luminositeActuelle > 220:
  303. retour = retour.darker(120)
  304. return retour
  305. def couleurBordure(self):
  306. """renvoie la couleur utilisee pour les bordures de la case"""
  307. luminositeActuelle = self.couleurEffective().lightness()
  308. if luminositeActuelle > 150:
  309. retour = QColor(85, 85, 85, 130)
  310. elif luminositeActuelle > 100 and luminositeActuelle <= 150:
  311. retour = QColor(10, 10, 10, 130)
  312. else:
  313. retour = QColor(255, 255, 255, 180)
  314. return retour
  315. def couleurEffective(self):
  316. """renvoie la couleur effective de la case (utile quand la texture est une image)"""
  317. texture = self.brush()
  318. if texture.textureImage().isNull():
  319. couleurFond = texture.color()
  320. else:
  321. couleurFond = self.couleurDominante(texture.textureImage())
  322. return couleurFond
  323. def couleurDominante(self, img):
  324. """retourne la couleur dominante d'une QImage"""
  325. r = 0
  326. v = 0
  327. b = 0
  328. for i in range(0, img.width()):
  329. for j in range(0, img.height()):
  330. pixel = img.pixel(i,j)
  331. r += qRed(pixel)
  332. v += qGreen(pixel)
  333. b += qBlue(pixel)
  334. nb_pix = img.width() * img.height()
  335. r_moy = int(r / nb_pix)
  336. v_moy = int(v / nb_pix)
  337. b_moy = int(b / nb_pix)
  338. return QColor(r_moy, v_moy, b_moy)
  339. ######### evenements souris et clavier #################
  340. #recuperes depuis la maille
  341. #la case recoit d'abord l'evenement
  342. #si elle ne l'a pas accepte, les pions le recoivent par ordre d'empilement,
  343. def _mousePressEvent(self, event):
  344. """evenement lors du clic souris"""
  345. # super(Case, self).mousePressEvent(event)
  346. if event.button() == 1:
  347. if self.plateau.clic_case((self.x, self.y)): return True
  348. for num in self.occupants():
  349. if self.plateau.clic_pion(num): return True
  350. return False
  351. def _hoverEnterEvent(self, event):
  352. """met a jour l'affichage de la case au survol de la souris, si un pion est selectionne"""
  353. # super(Case, self).hoverEnterEvent(event)
  354. if not self.estCachee() or issubclass(self.plateau.modeActif.__class__, Modes.ModeBaseCp):
  355. if self.plateau.survol_case((self.x, self.y)): return True
  356. for num in self.occupants():
  357. if self.plateau.survol_pion(num): return True
  358. return False
  359. def _hoverLeaveEvent(self, event):
  360. """met a jour l'affichage de la case au survol de la souris, si un pion est selectionne"""
  361. # super(Case, self).hoverLeaveEvent(event)
  362. if not self.estCachee() or issubclass(self.plateau.modeActif.__class__, Modes.ModeBaseCp):
  363. if self.plateau.finSurvol_case((self.x, self.y)): return True
  364. for num in self.occupants():
  365. if self.plateau.finSurvol_pion(num): return True
  366. return False
  367. def _mouseDoubleClickEvent(self, event):
  368. """evenement lors du double-clic souris"""
  369. super(Pion, self).mouseDoubleClickEvent(event)
  370. if event.button() == 1: #sur clic gauche
  371. if self.plateau.doubleClic_pion(self.numero): return True
  372. return False
  373. ########################
  374. class Maille(QGraphicsPolygonItem):
  375. """clone de la case place au dessus des autres items,
  376. et permettant aux cases de recevoir prioritairement certains signaux,
  377. meme lorsqu'elles sont cachees sous des pions, caches...Etc"""
  378. def __init__(self, case, parent = None):
  379. super(Maille, self).__init__()
  380. self._case = case
  381. self._actif = False
  382. def coord(self):
  383. return (self._case.x, self._case.y)
  384. def paint(self, *args):
  385. if not self._actif: return
  386. return super(Maille, self).paint(*args)
  387. def creer(self):
  388. self.setPolygon(self._case.polygone())
  389. # self.setVisible(False)
  390. self.setAcceptHoverEvents(True)
  391. self.setZValue(100)
  392. self._case.plateau.addItem(self)
  393. self.afficher(False)
  394. def afficher(self, actif, valide = True):
  395. self._actif = actif
  396. pinceau = QPen()
  397. brush = QBrush()
  398. if actif:
  399. pinceau.setWidth(5)
  400. pinceau.setColor(self._case.couleurProj(valide))
  401. brush.setStyle(13)
  402. brush.setColor(self._case.couleurProj(valide))
  403. self.setPen(pinceau)
  404. self.setBrush(brush)
  405. def mousePressEvent(self, event):
  406. """evenement lors du clic souris"""
  407. accepte = self._case._mousePressEvent(event)
  408. if accepte:
  409. event.accept()
  410. else:
  411. event.ignore()
  412. super(Maille, self).mousePressEvent(event)
  413. def hoverEnterEvent(self, event):
  414. """met a jour l'affichage de la case au survol de la souris, si un pion est selectionne"""
  415. accepte = self._case._hoverEnterEvent(event)
  416. if accepte:
  417. event.accept()
  418. else:
  419. event.ignore()
  420. super(Maille, self).hoverEnterEvent(event)
  421. def hoverLeaveEvent(self, event):
  422. """met a jour l'affichage de la case au survol de la souris, si un pion est selectionne"""
  423. accepte = self._case._hoverLeaveEvent(event)
  424. if accepte:
  425. event.accept()
  426. else:
  427. event.ignore()
  428. super(Maille, self).hoverLeaveEvent(event)
  429. class LogoDep(QGraphicsEllipseItem):
  430. """logo utilise pour afficher le chemin que va suivre le pion lors d'un deplacement"""
  431. def __init__(self, parent = None):
  432. super(LogoDep, self).__init__()
  433. self.parent = parent
  434. self.couleur = None
  435. self.txt = None
  436. def creer(self):
  437. hC = self.parent.plateau.hCase
  438. rect = QRectF()
  439. rayon = 0.4*hC
  440. rect.setTopLeft(QPointF(self.parent.centreGraphique.x() - rayon, self.parent.centreGraphique.y() - rayon))
  441. rect.setBottomRight(QPointF(self.parent.centreGraphique.x() + rayon, self.parent.centreGraphique.y() + rayon))
  442. self.setRect(rect)
  443. self.txt = QGraphicsTextItem(self)
  444. police = QFont("Georgia", 24)
  445. police.setBold(True)
  446. self.txt.setFont(police)
  447. self.txt.setParentItem(self)
  448. self.txt.setPos(QPointF(self.parent.centreGraphique.x() - rayon, self.parent.centreGraphique.y() - 0.6*rayon))
  449. self.txt.setTextWidth(2*rayon)
  450. self.txt.setPlainText(QString.fromUtf8(""))
  451. self.centrerTexte()
  452. self.setVisible(False)
  453. self.setZValue(100)
  454. self.setAcceptHoverEvents(False)
  455. self.parent.plateau.addItem(self)
  456. def afficher(self, valeur, valide, dz = 0):
  457. """lorsque cette case est sur le chemin d'un pion,
  458. un disque blanc ou rouge apparait indiquant le
  459. mode de deplacement (icone: 'dep_simple', 'nage', 'escalade', 'vol')
  460. un cout de 0 fait disparaitre ce symbole"""
  461. if valeur > 0:
  462. #couleur
  463. if valide:
  464. couleur = QColor(255, 255, 220, 200)
  465. else:
  466. couleur = QColor(240, 60, 20, 200)
  467. self.setBrush(couleur)
  468. self.setPen(QPen(couleur))
  469. #txt
  470. escalade = "" if dz == 0 else (chr(30) if dz > 0 else chr(31))
  471. txt = "{}{}".format(valeur, escalade)
  472. self.txt.setPlainText(QString.fromUtf8(txt))
  473. self.centrerTexte()
  474. self.setVisible(True)
  475. else:
  476. self.setVisible(False)
  477. def centrerTexte(self):
  478. f = QTextBlockFormat()
  479. f.setAlignment(Qt.AlignCenter)
  480. cursor = self.txt.textCursor()
  481. cursor.select(QTextCursor.Document)
  482. cursor.mergeBlockFormat(f)
  483. cursor.clearSelection()
  484. self.txt.setTextCursor(cursor)
  485. class PolygoneCache(QGraphicsPolygonItem):
  486. def __init__(self, case, parent=None):
  487. """initialisation de la fenetre"""
  488. super(PolygoneCache, self).__init__(parent)
  489. self.case = case
  490. self.case.plateau.fenetre.connect(self.case.plateau.fenetre.ui.cbt_vue, SIGNAL("zoomChange(int)"), self.zoomChange)
  491. def creer(self):
  492. polygone = self.case.polygone()
  493. self.setPolygon(polygone)
  494. self.majTransparence()
  495. self.setTransformOriginPoint(self.case.centreGraphique)
  496. self.setZValue(98)
  497. self.setVisible(False)
  498. self.setScale(1.05)
  499. # self.setAcceptHoverEvents(True)
  500. # self.setAcceptDrops(True)
  501. self.case.plateau.addItem(self)
  502. def afficher(self, actif = True):
  503. self.setVisible(actif)
  504. def majTransparence(self):
  505. self.setBrush(QColor(0,0,0,self.transparence()))
  506. pinceau = QPen()
  507. pinceau.setBrush(QColor(0,0,0,self.transparence()))
  508. pinceau.setWidth(1)
  509. self.setPen(pinceau)
  510. def transparence(self):
  511. if issubclass(self.case.plateau.modeActif.__class__, Modes.ModeBaseCp):
  512. retour = 100
  513. else:
  514. retour = 255
  515. return retour
  516. def activerSurbrillance(self, actif):
  517. if actif:
  518. couleur = QColor(150,150,150,100)
  519. else:
  520. couleur = QColor(0,0,0,100)
  521. self.setBrush(couleur)
  522. def zoomChange(self, nbZoom):
  523. """le zoom sur la dmGraphicsView a change, on met a jour le scale de l'objet,
  524. on cherche a eviter un phenomene qui fait que lorsque le zoom est lointain,
  525. on devine les couleurs entre les polygones du cache, le rendant a moitie inutile"""
  526. s = (1 + 0.01*(10-nbZoom))
  527. self.setScale(s)
  528. def sceneEvent(self, event):
  529. """filtre les evenements souris et clavier
  530. si faux: l'evenement est bloque"""
  531. autorise = not self.case.estCachee() or issubclass(self.case.plateau.modeActif.__class__, Modes.ModeBaseCp)
  532. if not autorise:
  533. event.accept()
  534. else:
  535. event.ignore()
  536. return autorise