| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263 |
- """pinceau utilise pour la selection et la mise a jour des cases du plateau"""
- from PyQt4.QtCore import *
- from PyQt4.QtGui import *
- from Terrain import Terrain
- from dmF import *
- from bresenham import casesEntre
- class Pinceau():
- def __init__(self, plateau):
- self.plateau = plateau
- self._forme = "simple"
- self._epaisseur = 1
- self._formeVerrouillee = False
-
- self._coordOrigine = None
- self._origine = None
- self._point2 = None
- self._selection = []
- self._objetGraphique = None
- self._actif = False
- def estActif(self):
- return self._actif
- def majForme(self, forme):
- if forme in ["simple", "ligne", "frontiere", "pot", "rectV", "rectP"] and \
- not self._formeVerrouillee:
- self._forme = forme
- def verrouillerForme(self, actif = True):
- self._formeVerrouillee = actif
- def majEpaisseur(self, val):
- if val in range(1, 5):
- self._epaisseur = val
- def defOrigine(self, coord):
- if self.plateau.coordonneesValides(coord):
- self._coordOrigine = coord
- self._origine = self.plateau.cases[coord].centreGraphique
- def defPoint2(self, coord):
- if self.plateau.coordonneesValides(coord):
- self._point2 = self.plateau.cases[coord].centreGraphique
- def selection(self):
- return self._selection
- def demarrer(self, coord):
- """commence a peindre a partir de la case choisie comme origine"""
- self._formeVerrouillee = False
- if self.plateau.coordonneesValides(coord):
- self._coordOrigine = coord
- self._origine = self.plateau.cases[coord].centreGraphique
- self._point2 = self.plateau.cases[coord].centreGraphique
- self._actif = True
- self.maj(coord)
- def maj(self, coord):
- """on met a jour la selection en fonction de la case qui vient d'etre ajoutee"""
- if self._actif:
- enPlus = [] #cases a ajouter a la selection
- enMoins = [] #cases a retirer de la selection
- if self._origine == None: self._origine = self.plateau.cases[coord].centreGraphique
- if self._forme == "simple":
- #pas de forme: on ajoute les cases survolees a la liste des cases
- zone = self.plateau.zone(coord, self._epaisseur - 1)
- for coord in zone:
- if not coord in self._selection:
- enPlus.append(coord)
-
- elif self._forme == "pot":
- #pot de peinture: on ne met a jour que si aucune projection n'est affichee
- if not len(self._selection) > 0:
- enPlus = self.selectionPot(coord)
- elif self._forme == "frontiere":
- #droite qui selectionne toutes les cases situees au dessus d'elle
- if self._objetGraphique == None:
- pinceau = QPen()
- pinceau.setColor(QColor("black"))
- self._objetGraphique = QGraphicsLineItem()
- self._objetGraphique.setPen(pinceau)
- self.plateau.addItem(self._objetGraphique)
-
- self._point2 = self.plateau.cases[coord].centreGraphique
- ligne = QLineF(self._origine, self._point2)
- orientation = int((1+int(ligne.angle()/22.5))/2)
- ligne.setAngle(orientation*45)
- self._objetGraphique.setLine(ligne)
- select = self.selectionFrontiere()
- #on met compare avec l'ancienne selection pour minimiser le nombre de cases a maj
- for coord in self._selection:
- if not coord in select:
- enMoins.append(coord)
- else:
- select.remove(coord)
- enPlus = select #toutes les coord qui restent dans select sont a ajouter
- elif self._forme == "rectV" or self._forme == "rectP":
- #rectangle
- if self._objetGraphique == None:
- pinceau = QPen()
- pinceau.setColor(QColor("black"))
- self._objetGraphique = QGraphicsRectItem()
- self._objetGraphique.prepareGeometryChange()
- self._objetGraphique.setPen(pinceau)
- self.plateau.addItem(self._objetGraphique)
- self._point2 = self.plateau.cases[coord].centreGraphique
- rect = QRectF(QPointF(min(self._origine.x(), self._point2.x()), min(self._origine.y(), self._point2.y())), \
- QPointF(max(self._origine.x(), self._point2.x()), max(self._origine.y(), self._point2.y())) )
- self._objetGraphique.setRect(rect)
- select = self.selectionRectangle(self._coordOrigine, coord, (self._forme == "rectP"))
- #on met compare avec l'ancienne selection pour minimiser le nombre de cases a maj
- for coord in self._selection:
- if not coord in select:
- enMoins.append(coord)
- else:
- select.remove(coord)
- enPlus = select #toutes les coord qui restent dans select sont a ajouter
-
- elif self._forme == "ligne":
- #segment simple
- if self._objetGraphique == None:
- pinceau = QPen()
- pinceau.setColor(QColor("black"))
- self._objetGraphique = QGraphicsLineItem()
- self._objetGraphique.setPen(pinceau)
- self._objetGraphique.prepareGeometryChange()
- self.plateau.addItem(self._objetGraphique)
- self._point2 = self.plateau.cases[coord].centreGraphique
- ligne = QLineF(self._origine, self._point2)
- self._objetGraphique.setLine(ligne)
- #on liste les cases intersectant la forme
- # if self._objetGraphique:
- # select = self.plateau.casesSousForme(self._objetGraphique, (self._forme[-1:] == "P"), self._epaisseur - 1)
- # else:
- # select = [coord]
- select = self.selectionLigne(self._coordOrigine, coord)
- for coord in self._selection:
- if not coord in select:
- enMoins.append(coord)
- else:
- select.remove(coord)
- enPlus = select
- for coord in enPlus:
- self.afficherCase(coord, True)
- self._selection.append(coord)
- for coord in enMoins:
- self.afficherCase(coord, False)
- self._selection.remove(coord)
- def reinit(self):
- for coord in self._selection:
- self.afficherCase(coord, False)
- if self._objetGraphique:
- self.plateau.removeItem(self._objetGraphique)
- self._objetGraphique = None
- self._origine = None
- self._point2 = None
- self._selection = []
- self._actif = False
- def afficherCase(self, coord, actif):
- self.plateau.cases[coord].majEstCibleCurseur(actif)
- def selectionLigne(self, coord0, coord1):
- retour = casesEntre(coord0, coord1, self.plateau.formeCases)
- # retour = []
- return retour
- def selectionRectangle(self, coord0, coord1, plein = True):
- """retourne les cases selectionnees lors de l'utilisation de la forme 'rectP' ou 'rectV'"""
- retour = []
- #a: point en haut a gauche
- xa = mini(coord0[0], coord1[0]); ya = mini(coord0[1], coord1[1])
- #b: point en bas a droite
- xb = maxi(coord0[0], coord1[0]); yb = maxi(coord0[1], coord1[1])
-
- for coord in self.plateau.cases:
- x, y = coord
- if xa <= x <= xb and ya <= y <= yb:
- if plein:
- retour.append((x,y))
- else:
- if x == xa or x == xb or y == ya or y == yb:
- retour.append((x,y))
- return retour
- def selectionFrontiere(self):
- """retourne les cases selectionnees lors de l'utilisation de la forme 'frontiere'"""
- listeCases = []
- if self._objetGraphique != None:
- ligne = self._objetGraphique.line()
- normale = ligne.normalVector()
- normale = normale.unitVector()
- coordOrigine = self.plateau.coordonneesAuPoint(self._origine)
- dx = normale.p2().x() - normale.p1().x()
- dy = normale.p2().y() - normale.p1().y()
- for coord in self.plateau.cases:
- if dx < 0 and dy == 0: #normale pointe vers la gauche
- if (coord[0] - coordOrigine[0]) <= 0:
- listeCases.append(coord)
- if dx > 0 and dy == 0: #normale pointe vers la droite
- if (coord[0] - coordOrigine[0]) >= 0:
- listeCases.append(coord)
- if dx == 0 and dy < 0: #pointe vers le haut (rappel: axe y vers le bas)
- if (coord[1] - coordOrigine[1]) <= 0:
- listeCases.append(coord)
- elif dx == 0 and dy > 0: #pointe vers le bas
- if (coord[1] - coordOrigine[1]) >= 0:
- listeCases.append(coord)
- if dx > 0 and dy < 0: #pointe vers le haut droite
- if (coord[0] - coordOrigine[0]) + -1*(coord[1] - coordOrigine[1]) >= 0:
- listeCases.append(coord)
- elif dx > 0 and dy > 0: #pointe vers le bas droite
- if -1*(coord[0] - coordOrigine[0]) + -1*(coord[1] - coordOrigine[1]) <= 0:
- listeCases.append(coord)
- if dx < 0 and dy < 0: #pointe vers le haut gauche
- if (coord[0] - coordOrigine[0]) + (coord[1] - coordOrigine[1]) <= 0:
- listeCases.append(coord)
- elif dx < 0 and dy > 0: #pointe vers le bas gauche
- if -1*(coord[0] - coordOrigine[0]) + (coord[1] - coordOrigine[1]) >= 0:
- listeCases.append(coord)
- return listeCases
- def selectionPot(self, coord0):
- retour = [coord0]
- aVerifier = [coord0]
- while len(aVerifier) > 0:
- coord = aVerifier[0]
- for voisine in self.plateau.cases[coord].voisins:
- if not voisine in retour:
- if self.ontTerrainsSimilaires(voisine, coord):
- retour.append(voisine)
- aVerifier.append(voisine)
- aVerifier.remove(coord)
- return retour
- def ontTerrainsSimilaires(self, coord1, coord2):
- return (self.plateau.cases[coord1].terrain.nom == self.plateau.cases[coord2].terrain.nom and \
- self.plateau.cases[coord1].terrain.couleur.rgb() == self.plateau.cases[coord2].terrain.couleur.rgb() and \
- self.plateau.cases[coord1].terrain.imgTexture.definition() == self.plateau.cases[coord1].terrain.imgTexture.definition())
-
-
|