Pinceau.py 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. """pinceau utilise pour la selection et la mise a jour des cases du plateau"""
  2. from PyQt4.QtCore import *
  3. from PyQt4.QtGui import *
  4. class Pinceau():
  5. def __init__(self, plateau):
  6. self.plateau = plateau
  7. self._forme = "simple"
  8. self._epaisseur = 1
  9. self._formeVerrouillee = False
  10. self._origine = None
  11. self._point2 = None
  12. self._selection = []
  13. self._objetGraphique = None
  14. self._actif = False
  15. def estActif(self):
  16. return self._actif
  17. def majForme(self, forme):
  18. if forme in ["simple", "ligne", "frontiere", "pot", \
  19. "rectV", "rectP", "ellipseV", "ellipseP"] and not self._formeVerrouillee:
  20. self._forme = forme
  21. def verrouillerForme(self, actif):
  22. self._formeVerrouillee = True
  23. def majEpaisseur(self, val):
  24. if val in range(1, 5):
  25. self._epaisseur = val
  26. def defOrigine(self, coord):
  27. if self.plateau.coordonneesValides(coord):
  28. self._origine = self.plateau.cases[coord].centreGraphique
  29. def defPoint2(self, coord):
  30. if self.plateau.coordonneesValides(coord):
  31. self._point2 = self.plateau.cases[coord].centreGraphique
  32. def selection(self):
  33. return self._selection
  34. def demarrer(self, coord):
  35. """commence a peindre a partir de la case choisie comme origine"""
  36. self._formeVerrouillee = False
  37. if self.plateau.coordonneesValides(coord):
  38. self._origine = self.plateau.cases[coord].centreGraphique
  39. self._point2 = self.plateau.cases[coord].centreGraphique
  40. self._actif = True
  41. def maj(self, coord):
  42. """on met a jour la selection en fonction de la case qui vient d'etre ajoutee"""
  43. if self._actif:
  44. enPlus = [] #cases a ajouter a la selection
  45. enMoins = [] #cases a retirer de la selection
  46. if self._origine == None: self._origine = self.plateau.cases[coord].centreGraphique
  47. if self._forme == "simple":
  48. #pas de forme: on ajoute les cases survolees a la liste des cases
  49. zone = self.plateau.zone(coord, self._epaisseur - 1)
  50. for coord in zone:
  51. if not coord in self._selection:
  52. enPlus.append(coord)
  53. elif self._forme == "frontiere":
  54. #droite qui selectionne toutes les cases situees au dessus d'elle
  55. if self._objetGraphique == None:
  56. pinceau = QPen()
  57. pinceau.setColor(QColor("black"))
  58. self._objetGraphique = QGraphicsLineItem()
  59. self._objetGraphique.setPen(pinceau)
  60. self.plateau.addItem(self._objetGraphique)
  61. self._point2 = self.plateau.cases[coord].centreGraphique
  62. ligne = QLineF(self._origine, self._point2)
  63. orientation = int((1+int(ligne.angle()/22.5))/2)
  64. ligne.setAngle(orientation*45)
  65. self._objetGraphique.setLine(ligne)
  66. select = self.selectionFrontiere()
  67. #on met compare avec l'ancienne selection pour minimiser le nombre de cases a maj
  68. for coord in self._selection:
  69. if not coord in select:
  70. enMoins.append(coord)
  71. else:
  72. select.remove(coord)
  73. enPlus = select #toutes les coord qui restent dans select sont a ajouter
  74. else:
  75. if self._forme == "ligne":
  76. #segment simple
  77. if self._objetGraphique == None:
  78. pinceau = QPen()
  79. pinceau.setColor(QColor("black"))
  80. self._objetGraphique = QGraphicsLineItem()
  81. self._objetGraphique.setPen(pinceau)
  82. self._objetGraphique.prepareGeometryChange()
  83. self.plateau.addItem(self._objetGraphique)
  84. self._point2 = self.plateau.cases[coord].centreGraphique
  85. ligne = QLineF(self._origine, self._point2)
  86. self._objetGraphique.setLine(ligne)
  87. elif self._forme == "rectV" or self._forme == "rectP":
  88. #rectangle
  89. if self._objetGraphique == None:
  90. pinceau = QPen()
  91. pinceau.setColor(QColor("black"))
  92. self._objetGraphique = QGraphicsRectItem()
  93. self._objetGraphique.prepareGeometryChange()
  94. self._objetGraphique.setPen(pinceau)
  95. self.plateau.addItem(self._objetGraphique)
  96. self._point2 = self.plateau.cases[coord].centreGraphique
  97. rect = QRectF(QPointF(min(self._origine.x(), self._point2.x()), min(self._origine.y(), self._point2.y())), \
  98. QPointF(max(self._origine.x(), self._point2.x()), max(self._origine.y(), self._point2.y())) )
  99. self._objetGraphique.setRect(rect)
  100. elif self._forme == "ellipseV" or self._forme == "ellipseP":
  101. #ellipse
  102. if self._objetGraphique == None:
  103. pinceau = QPen()
  104. pinceau.setColor(QColor("black"))
  105. self._objetGraphique = QGraphicsEllipseItem()
  106. self._objetGraphique.prepareGeometryChange()
  107. self._objetGraphique.setPen(pinceau)
  108. self.plateau.addItem(self._objetGraphique)
  109. self._point2 = self.plateau.cases[coord].centreGraphique
  110. rect = QRectF(QPointF(min(self._origine.x(), self._point2.x()), min(self._origine.y(), self._point2.y())), \
  111. QPointF(max(self._origine.x(), self._point2.x()), max(self._origine.y(), self._point2.y())) )
  112. self._objetGraphique.setRect(rect)
  113. #on liste les cases intersectant la forme
  114. select = self.plateau.casesSousForme(self._objetGraphique, (self._forme[-1:] == "P"), self._epaisseur - 1)
  115. for coord in self._selection:
  116. if not coord in select:
  117. enMoins.append(coord)
  118. else:
  119. select.remove(coord)
  120. enPlus = select
  121. for coord in enPlus:
  122. self.afficherCase(coord, True)
  123. self._selection.append(coord)
  124. for coord in enMoins:
  125. self.afficherCase(coord, False)
  126. self._selection.remove(coord)
  127. def reinit(self):
  128. for coord in self._selection:
  129. self.afficherCase(coord, False)
  130. if self._objetGraphique:
  131. self.plateau.removeItem(self._objetGraphique)
  132. self._objetGraphique = None
  133. self._origine = None
  134. self._point2 = None
  135. self._selection = []
  136. self._actif = False
  137. def afficherCase(self, coord, actif):
  138. self.plateau.cases[coord].majEstCibleCurseur(actif)
  139. def selectionFrontiere(self):
  140. """retourne les cases selectionnees lors de l'utilisation de la forme 'frontiere'"""
  141. listeCases = []
  142. if self._objetGraphique != None:
  143. ligne = self._objetGraphique.line()
  144. normale = ligne.normalVector()
  145. normale = normale.unitVector()
  146. coordOrigine = self.plateau.coordonneesAuPoint(self._origine)
  147. dx = normale.p2().x() - normale.p1().x()
  148. dy = normale.p2().y() - normale.p1().y()
  149. for coord in self.plateau.cases:
  150. if dx < 0 and dy == 0: #normale pointe vers la gauche
  151. if (coord[0] - coordOrigine[0]) <= 0:
  152. listeCases.append(coord)
  153. if dx > 0 and dy == 0: #normale pointe vers la droite
  154. if (coord[0] - coordOrigine[0]) >= 0:
  155. listeCases.append(coord)
  156. if dx == 0 and dy < 0: #pointe vers le haut (rappel: axe y vers le bas)
  157. if (coord[1] - coordOrigine[1]) <= 0:
  158. listeCases.append(coord)
  159. elif dx == 0 and dy > 0: #pointe vers le bas
  160. if (coord[1] - coordOrigine[1]) >= 0:
  161. listeCases.append(coord)
  162. if dx > 0 and dy < 0: #pointe vers le haut droite
  163. if (coord[0] - coordOrigine[0]) + -1*(coord[1] - coordOrigine[1]) >= 0:
  164. listeCases.append(coord)
  165. elif dx > 0 and dy > 0: #pointe vers le bas droite
  166. if -1*(coord[0] - coordOrigine[0]) + -1*(coord[1] - coordOrigine[1]) <= 0:
  167. listeCases.append(coord)
  168. if dx < 0 and dy < 0: #pointe vers le haut gauche
  169. if (coord[0] - coordOrigine[0]) + (coord[1] - coordOrigine[1]) <= 0:
  170. listeCases.append(coord)
  171. elif dx < 0 and dy > 0: #pointe vers le bas gauche
  172. if -1*(coord[0] - coordOrigine[0]) + (coord[1] - coordOrigine[1]) >= 0:
  173. listeCases.append(coord)
  174. return listeCases