Procházet zdrojové kódy

Fonctionnement du plateau mis à jour
pour utiliser la nouvelle classe Pinceau

unknown před 10 roky
rodič
revize
9d7fabbb29
2 změnil soubory, kde provedl 82 přidání a 220 odebrání
  1. 72 73
      lib/Pinceau.py
  2. 10 147
      lib/Plateau.py

+ 72 - 73
lib/Pinceau.py

@@ -8,6 +8,7 @@ class Pinceau():
 
         self._forme = "simple"
         self._epaisseur = 1
+        self._formeVerrouillee = False
         
         self._origine = None
         self._point2 = None
@@ -22,9 +23,12 @@ class Pinceau():
 
     def majForme(self, forme):
         if forme in ["simple", "ligne", "frontiere", "pot", \
-                     "rectV", "rectP", "ellipseV", "ellipseP"]:
+                     "rectV", "rectP", "ellipseV", "ellipseP"] and not self._formeVerrouillee:
             self._forme = forme
 
+    def verrouillerForme(self, actif):
+        self._formeVerrouillee = True
+
     def majEpaisseur(self, val):
         if val in range(1, 5):
             self._epaisseur = val
@@ -42,6 +46,7 @@ class Pinceau():
 
     def demarrer(self, coord):
         """commence a peindre a partir de la case choisie comme origine"""
+        self._formeVerrouillee = False
         if self.plateau.coordonneesValides(coord):
             self._origine = self.plateau.cases[coord].centreGraphique
             self._point2 = self.plateau.cases[coord].centreGraphique
@@ -127,7 +132,7 @@ class Pinceau():
                     self._objetGraphique.setRect(rect)
 
                 #on liste les cases intersectant la forme
-                select = self.casesSousForme(self._objetGraphique, (self._forme[-1:] == "P"))
+                select = self.plateau.casesSousForme(self._objetGraphique, (self._forme[-1:] == "P"), self._epaisseur - 1)
                 
                 for coord in self._selection:
                     if not coord in select:
@@ -142,14 +147,8 @@ class Pinceau():
             for coord in enMoins:
                 self.afficherCase(coord, False)
                 self._selection.remove(coord)
-            
-    def annuler(self):
-        self.reinit()
-
-    def terminer(self):
-        return self._selection
 
-    def reinit(self):
+    def reinit(self): 
         for coord in self._selection:
             self.afficherCase(coord, False)
         if self._objetGraphique:
@@ -201,70 +200,70 @@ class Pinceau():
         return listeCases
 
 
-    def casesSousForme(self, forme, plein = True):
-        """renvoie la liste des cases en collision avec un QGraphicsItem en parametre
-            plein = False: pas le contenu de la forme
-            epaisseur = renvoie aussi les cases voisines jusqu'a la distance demandee"""
-        tmp = []
-        listeCases = []
-        point1 = None
-        point2 = None
-        #point 1 et 2
-        if forme.__class__.__name__ == "QGraphicsLineItem":
-            point1 = forme.line().p1()
-            point2 = forme.line().p2()
-        elif forme.__class__.__name__ == "QGraphicsRectItem" or forme.__class__.__name__ == "QGraphicsEllipseItem":
-            point1 = forme.rect().topLeft()
-            point2 = forme.rect().bottomRight()
-        else:
-            point1 = forme.boundingRect().topLeft()
-            point2 = forme.boundingRect().bottomRight()            
- 
-        #preselection des cases (meilleures perf)
-        preSelection = []
-        if point1 != None and point2 != None and point1 != point2:
-            coord1 = self.plateau.coordonneesAuPoint(point1)  
-            coord2 = self.plateau.coordonneesAuPoint(point2)
-            if coord1 != None and coord2 != None:
-                minX = min(coord1[0], coord2[0]) - 1
-                maxX = max(coord1[0], coord2[0]) + 1
-                minY = min(coord1[1], coord2[1]) - 1
-                maxY = max(coord1[1], coord2[1]) + 1
-                for coord in self.plateau.cases:
-                    if coord[0] >= minX and coord[0] <= maxX and coord[1] >= minY and coord[1] <= maxY :
-                        preSelection.append(coord)
-            else:
-                preSelection = self.cases       
-        else:
-            for coord in self.plateau.cases:
-                preSelection.append(coord)
-       
-        #on liste les cases en collision avec la forme 
-        for coord in preSelection:
-            if self.plateau.cases[coord].collidesWithItem(forme, Qt.IntersectsItemShape):
-                if plein:
-                    tmp.append(coord) 
-                else:
-                    contenu = True
-                    for i in range(0,len(self.plateau.cases[coord].polygon())):
-                        if not forme.contains(self.plateau.cases[coord].polygon().at(i)):
-                            contenu = False
-                            break
-                    if contenu == False:
-                         tmp.append(coord)    
-        #on applique l'epaisseur du pinceau (lignes ou formes vides seulement) si necessaire
-        if not plein and self._epaisseur > 0:
-            for coord in tmp:
-                zone = self.plateau.zone(coord, self._epaisseur - 1)
-                for coord2 in zone:
-                    if not coord2 in listeCases:
-                        listeCases.append(coord2)
-        else:
-            listeCases = tmp
-        #si la liste est vide, on ajoute l'origine de la forme
-        if len(listeCases) == 0:
-            listeCases = [self.plateau.coordonneesAuPoint(point1)]    
-        return listeCases                
+##    def casesSousForme(self, forme, plein = True):
+##        """renvoie la liste des cases en collision avec un QGraphicsItem en parametre
+##            plein = False: pas le contenu de la forme
+##            epaisseur = renvoie aussi les cases voisines jusqu'a la distance demandee"""
+##        tmp = []
+##        listeCases = []
+##        point1 = None
+##        point2 = None
+##        #point 1 et 2
+##        if forme.__class__.__name__ == "QGraphicsLineItem":
+##            point1 = forme.line().p1()
+##            point2 = forme.line().p2()
+##        elif forme.__class__.__name__ == "QGraphicsRectItem" or forme.__class__.__name__ == "QGraphicsEllipseItem":
+##            point1 = forme.rect().topLeft()
+##            point2 = forme.rect().bottomRight()
+##        else:
+##            point1 = forme.boundingRect().topLeft()
+##            point2 = forme.boundingRect().bottomRight()            
+## 
+##        #preselection des cases (meilleures perf)
+##        preSelection = []
+##        if point1 != None and point2 != None and point1 != point2:
+##            coord1 = self.plateau.coordonneesAuPoint(point1)  
+##            coord2 = self.plateau.coordonneesAuPoint(point2)
+##            if coord1 != None and coord2 != None:
+##                minX = min(coord1[0], coord2[0]) - 1
+##                maxX = max(coord1[0], coord2[0]) + 1
+##                minY = min(coord1[1], coord2[1]) - 1
+##                maxY = max(coord1[1], coord2[1]) + 1
+##                for coord in self.plateau.cases:
+##                    if coord[0] >= minX and coord[0] <= maxX and coord[1] >= minY and coord[1] <= maxY :
+##                        preSelection.append(coord)
+##            else:
+##                preSelection = self.cases       
+##        else:
+##            for coord in self.plateau.cases:
+##                preSelection.append(coord)
+##       
+##        #on liste les cases en collision avec la forme 
+##        for coord in preSelection:
+##            if self.plateau.cases[coord].collidesWithItem(forme, Qt.IntersectsItemShape):
+##                if plein:
+##                    tmp.append(coord) 
+##                else:
+##                    contenu = True
+##                    for i in range(0,len(self.plateau.cases[coord].polygon())):
+##                        if not forme.contains(self.plateau.cases[coord].polygon().at(i)):
+##                            contenu = False
+##                            break
+##                    if contenu == False:
+##                         tmp.append(coord)    
+##        #on applique l'epaisseur du pinceau (lignes ou formes vides seulement) si necessaire
+##        if not plein and self._epaisseur > 0:
+##            for coord in tmp:
+##                zone = self.plateau.zone(coord, self._epaisseur - 1)
+##                for coord2 in zone:
+##                    if not coord2 in listeCases:
+##                        listeCases.append(coord2)
+##        else:
+##            listeCases = tmp
+##        #si la liste est vide, on ajoute l'origine de la forme
+##        if len(listeCases) == 0:
+##            listeCases = [self.plateau.coordonneesAuPoint(point1)]    
+##        return listeCases                
 
 
 

+ 10 - 147
lib/Plateau.py

@@ -72,6 +72,7 @@ class Plateau(QGraphicsScene):
         self.epaisseurpinceau = 0
 
         #objets
+        self.pinceau = Pinceau(self)
         self.cases = {}   #dict des cases du plateau   (coordonnées: case)
         self.combattants = {}   #liste de combattants positionnes sur le plateau
         self.decors = {}  #liste des decors places sur le plateau
@@ -85,8 +86,6 @@ class Plateau(QGraphicsScene):
         self.polygoneZonePlacement = None
         self.entreesSorties = []
 
-        self.pinceau = Pinceau(self)
-            
         #infos combat
         self.numCombattantEnCours = 0
         self.ordreJeu = {}  #numero du pion: ordre de jeu
@@ -101,7 +100,7 @@ class Plateau(QGraphicsScene):
                                                                                   "modeParam", "nbZoomActuel", "epaisseurPinceau", \
                                                                                   "editionTerrain", "editionCreature", "editionDecor", \
                                                                                   "polygoneZonePlacement", "gestionCombat", "polygonesCaches", \
-                                                                                  "editionAttaques"]}
+                                                                                  "editionAttaques", "pinceau"]}
         return (state)
 
     def __setstate__(self, state):
@@ -134,6 +133,7 @@ class Plateau(QGraphicsScene):
     def recreer(self, fenetre):
         self.fenetre = fenetre
         self.gestionCombat = None
+        self.pinceau = Pinceau(self)
         super(Plateau, self).__init__()
         self.connexions()
 
@@ -169,6 +169,7 @@ class Plateau(QGraphicsScene):
     def fermer(self):
         """ferme le plateau 'proprement'"""
         self.miniature()
+        self.pinceau = None
         for item in self.items():
             item.prepareGeometryChange()
             self.removeItem(item)
@@ -294,9 +295,7 @@ class Plateau(QGraphicsScene):
                          "placementEntreeSortie", "majZonePlacement"]
       
         self.modeParam = {"terrain": None, "numPionSelectionne": 0, "pionNouveau": None, "creature": None, "decor": None, "effet":"", "couleurPion": QColor("grey"), \
-                          "coordProjectionPosition": (0,0), "formeProjectionPosition": None, "nbRotations": 0, \
-                          "typeFormeDessin": "simple", "formeDessin": None, "origineFormeDessin": None, "point2FormeDessin": None, "listeCasesFormeDessin": [], \
-                          "projectionFormeDessin": [], "formeCoordEnCours": (0,0), \
+                          "coordProjectionPosition": (0,0), "formeProjectionPosition": None, "nbRotations": 0, "formeCoordEnCours": (0,0), \
                           "zoneAttaqueCaC": [], "cibleAttaqueCaC": None, "cibleAttaqueDist": None, "pionCibleAttaqueDist": None, "ligneAttaqueDist": None, \
                           "typeAttaqueZone": "", "formeAttaqueZone": None, "origineAttaqueZone": None, "point2AttaqueZone": None, "listeCasesAttaqueZone": [], "ligneMireAttaqueZone": None, \
                           "entreeSortie": None}
@@ -603,7 +602,6 @@ class Plateau(QGraphicsScene):
     def majEpaisseurPinceau(self, epaisseur):
         """met a jour l'epaisseur du pinceau (en cases)"""
         self.fenetre.ui.cp_valeurEpaisseurPinceau.setText(QString.fromUtf8(str(epaisseur)))
-##        self.epaisseurPinceau = int(epaisseur)
         self.pinceau.majEpaisseur(int(epaisseur))
 
     def modeMajAltitudeCase(self):
@@ -618,7 +616,6 @@ class Plateau(QGraphicsScene):
                   "cp_formeEllipsePlein": "ellipseP", \
                   "cp_formeRectVide": "rectV", \
                   "cp_formeRectPlein": "rectP"}
-##        self.modeParam["typeFormeDessin"] = formes[str(self.sender().objectName())]
         self.pinceau.majForme(formes[str(self.sender().objectName())])
 
         if self.modeActif[0:7] != "caseMaj":    
@@ -681,15 +678,7 @@ class Plateau(QGraphicsScene):
             self.modeParam["nbRotations"] = 0
                 
         if self.modeActif[0:7] == "caseMaj" or self.modeActif == "cachePlacer" or self.modeActif == "majZonePlacement":
-##            if self.modeParam["formeDessin"] != None:
-##                self.modeParam["formeDessin"].prepareGeometryChange()
-##                self.removeItem(self.modeParam["formeDessin"])    
-##            self.modeParam["formeDessin"] = None
-##            self.modeParam["origineFormeDessin"] = None
-##            self.modeParam["point2FormeDessin"] = None
             self.pinceau.reinit()
-##            self.afficherListeCases(self.modeParam["listeCasesFormeDessin"], False)
-##            self.modeParam["listeCasesFormeDessin"] = []
 
         if self.modeActif == "placementEntreeSortie":            
             if self.modeParam["entreeSortie"] != None:
@@ -727,12 +716,14 @@ class Plateau(QGraphicsScene):
             elif mode == "cachePlacer":
                 self.curseurPinceau()
                 self.fenetre.ui.cbt_vue.setDragMode(0)
-                self.modeParam["typeFormeDessin"] = "rectP"
+                self.pinceau.majForme("rectP")
+                self.verrouillerForme(True)
 
             elif mode == "majZonePlacement":
                 self.curseurPinceau()
                 self.fenetre.ui.cbt_vue.setDragMode(0)
-                self.modeParam["typeFormeDessin"] = "rectP"
+                self.pinceau.majForme("rectP")
+                self.verrouillerForme(True)
 
             elif mode == "placementEntreeSortie":
                 self.fenetre.ui.cbt_vue.setDragMode(0)               
@@ -1318,78 +1309,6 @@ class Plateau(QGraphicsScene):
                         break       
         return coord            
 
-##    def creerOrigineFormeDessin(self, coord):
-##        """place le point d'origine de la forme de selection"""
-##        self.modeParam["listeCasesFormeDessin"] = []
-##        self.modeParam["origineFormeDessin"] = self.cases[coord].centreGraphique
-##        self.modeParam["point2FormeDessin"] = self.cases[coord].centreGraphique
-##        self.modeParam["listeCasesFormeDessin"] = [coord]
-##        self.afficherListeCases(self.modeParam["listeCasesFormeDessin"], True)
-##        
-##    def majFormeDessin(self):
-##        """cree/maj la forme utilisee pour selectionner les cases et met a jour la liste des cases selectionnes"""
-##        self.afficherListeCases(self.modeParam["listeCasesFormeDessin"], False)
-##        
-##        pinceau = QPen()
-##        pinceau.setColor(QColor("black"))
-##        point2 = self.modeParam["point2FormeDessin"]
-##        
-##        if self.modeParam["typeFormeDessin"] == "simple":
-##            #pas de forme: on ajoute les cases survolees a la liste des cases
-##            coordPoint2 = self.coordonneesAuPoint(point2)
-##            zone = self.zone(coordPoint2, self.epaisseurPinceau-1)
-##            for coord in zone:
-##                if not coord in self.modeParam["listeCasesFormeDessin"]:
-##                    self.modeParam["listeCasesFormeDessin"].append(coord)
-##
-##        elif self.modeParam["typeFormeDessin"] == "frontiere":
-##            #droite qui selectionne toutes les cases situees au dessus d'elle
-##            if self.modeParam["formeDessin"] == None:
-##                self.modeParam["formeDessin"] = QGraphicsLineItem()
-##                self.modeParam["formeDessin"].setPen(pinceau)
-##                self.addItem(self.modeParam["formeDessin"])    
-##            ligne = QLineF(self.modeParam["origineFormeDessin"], point2)
-##            orientation = int((1+int(ligne.angle()/22.5))/2)
-##            ligne.setAngle(orientation*45)
-##            self.modeParam["formeDessin"].setLine(ligne)
-##            self.modeParam["listeCasesFormeDessin"] = self.selectionFrontiere()
-##
-##        else:    
-##            if self.modeParam["typeFormeDessin"] == "ligne":
-##                #segment simple
-##                if self.modeParam["formeDessin"] == None:
-##                    self.modeParam["formeDessin"] = QGraphicsLineItem()
-##                    self.modeParam["formeDessin"].setPen(pinceau)
-##                    self.modeParam["formeDessin"].prepareGeometryChange()
-##                    self.addItem(self.modeParam["formeDessin"])
-##                ligne = QLineF(self.modeParam["origineFormeDessin"], point2)
-##                self.modeParam["formeDessin"].setLine(ligne)
-##            
-##            elif self.modeParam["typeFormeDessin"] == "rectV" or self.modeParam["typeFormeDessin"] == "rectP":
-##                #rectangle
-##                if self.modeParam["formeDessin"] == None:
-##                    self.modeParam["formeDessin"] = QGraphicsRectItem()
-##                    self.modeParam["formeDessin"].prepareGeometryChange()
-##                    self.modeParam["formeDessin"].setPen(pinceau)
-##                    self.addItem(self.modeParam["formeDessin"])
-##                rect = self.rectFormeDessin(self.modeParam["origineFormeDessin"], point2)
-##                self.modeParam["formeDessin"].setRect(rect)
-##            
-##            elif self.modeParam["typeFormeDessin"] == "ellipseV" or self.modeParam["typeFormeDessin"] == "ellipseP":
-##                #ellipse
-##                if self.modeParam["formeDessin"] == None:
-##                    self.modeParam["formeDessin"] = QGraphicsEllipseItem()
-##                    self.modeParam["formeDessin"].prepareGeometryChange()
-##                    self.modeParam["formeDessin"].setPen(pinceau)
-##                    self.addItem(self.modeParam["formeDessin"])
-##                rect = self.rectFormeDessin(self.modeParam["origineFormeDessin"], point2)
-##                self.modeParam["formeDessin"].setRect(rect)
-##
-##            #on liste les cases intersectant la forme
-##            plein = (self.modeParam["typeFormeDessin"][len(self.modeParam["typeFormeDessin"])-1:] == "P")
-##            self.modeParam["listeCasesFormeDessin"] = self.casesSousForme(self.modeParam["formeDessin"], plein, self.epaisseurPinceau - 1)
-##        self.afficherListeCases(self.modeParam["listeCasesFormeDessin"], True)
-
     def casesSousForme(self, forme, plein = True, epaisseur = 0):
         """renvoie la liste des cases en collision avec un QGraphicsItem en parametre
             plein = False: pas le contenu de la forme
@@ -1462,55 +1381,6 @@ class Plateau(QGraphicsScene):
             preSelection = self.cases
         return preSelection                         
 
-    def selectionFrontiere(self):
-        """retourne les cases selectionnees lors de l'utilisation de la forme 'frontiere'"""
-        listeCases = []
-        ligne = self.modeParam["formeDessin"].line()
-        normale = ligne.normalVector()
-        normale = normale.unitVector()
-        coordOrigine = self.coordonneesAuPoint(self.modeParam["origineFormeDessin"])
-        dx = normale.p2().x() - normale.p1().x()
-        dy = normale.p2().y() - normale.p1().y()
-        for coord in self.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 validerFormeDessin(self):
-##        """la projection des cases a peindre a ete acceptee, on peint ces cases"""
-##        if self.modeActif[0:7] == "caseMaj" or self.modeActif == "caseCopie" or self.modeActif == "cachePlacer" or self.modeActif == "majZonePlacement":
-##            self.majListeCases(self.modeParam["listeCasesFormeDessin"])
-##        self.majMode(self.modeActif)  
-            
-##    def rectFormeDessin(self, point1, point2):
-##        """retourne le rectangle repesentant la forme de selection
-##           determine pour ce faire les points A et B, cad le point haut-droit et le point bas-gauche"""
-##        pointA = QPointF(min(point1.x(), point2.x()), min(point1.y(), point2.y()))
-##        pointB = QPointF(max(point1.x(), point2.x()), max(point1.y(), point2.y()))             
-##        rect = QRectF(pointA, pointB)
-##        return rect
 
     def majLigneMireAttaqueDist(self, coordCible = None):
         """met a jour la ligne de mire representant l'attaque a distance"""
@@ -1623,7 +1493,6 @@ class Plateau(QGraphicsScene):
         print(msg)
         self.majModeCombat("aucun")
 
-
     def rectEllipseCirculaire(self, centre, rayon):
         """renvoie le QRectF definissant une ellipse ayant le QPointF pour centre et le rayon en cases entres en param
            attention: l'ellipse n'est pas tout a fait circulaire, elle couvre horizontalement et
@@ -1847,7 +1716,6 @@ class Plateau(QGraphicsScene):
                  
             elif self.modeActif[0:7] == "caseMaj" or self.modeActif == "cachePlacer" or self.modeActif == "majZonePlacement":
                 self.pinceau.demarrer((x, y))
-##                self.creerOrigineFormeDessin(coord)
                 accepte = True
                 
             elif self.modeActif == "pionDecorSelectionne":
@@ -1890,10 +1758,6 @@ class Plateau(QGraphicsScene):
         """une case est survolee par le curseur (le clic gauche est enfonce)"""
         if self.modeActif[0:7] == "caseMaj" or self.modeActif == "cachePlacer" or self.modeActif == "majZonePlacement":
             self.pinceau.maj(coordCase)
-##            if self.cases[coordCase].centreGraphique != self.modeParam["point2FormeDessin"]:
-##                if self.modeParam["origineFormeDessin"] == None: self.modeParam["origineFormeDessin"] = self.cases[coordCase].centreGraphique
-##                self.modeParam["point2FormeDessin"] = self.cases[coordCase].centreGraphique
-##                self.majFormeDessin()
 
     def clicGaucheRelache(self):
         """si une forme de selection etait affichee, elle est validee""" 
@@ -2255,12 +2119,11 @@ class Plateau(QGraphicsScene):
         """met a jour l'affichage des cases selon les parametres enregistres pour le cache"""
         if self.polygonesCaches[numCache] == None:
             self.polygonesCaches[numCache] = Cache(self, numCache)
-        self.polygonesCaches[numCache].afficher(afficher, self.caches[numCache]["listeCases"])    
+        self.polygonesCaches[numCache].afficher(afficher, self.pinceau.selection())    
         
     ###############"
         
     ######### gestion des evenements souris et clavier ###############
-    #*ES 
     def wheelEvent(self, event):
         """zoom/dezoom avec la molette de la souris"""
         #on zoom/dezoom et on recentre sur la position du curseur