Bladeren bron

Ouverture d'une branche pour la ceartion de la classe pinceau

unknown 10 jaren geleden
bovenliggende
commit
8d93dc29bf
8 gewijzigde bestanden met toevoegingen van 316 en 101 verwijderingen
  1. 0 7
      PJ.txt
  2. 0 2
      combat_commandes manquantes.txt
  3. 0 40
      creation.txt
  4. 63 0
      lib/ModesInteraction.py
  5. 249 0
      lib/Pinceau.py
  6. 4 7
      lib/Plateau.py
  7. 0 15
      lib/a faire - plateau.txt
  8. 0 30
      modes.txt

+ 0 - 7
PJ.txt

@@ -1,7 +0,0 @@
-PJ:
-
-Combattant()
-
-estPJ = True
-
-

+ 0 - 2
combat_commandes manquantes.txt

@@ -1,2 +0,0 @@
-Ajouter les PJ
-Editer/Nouveau/Importer terrains, décors, créatures

+ 0 - 40
creation.txt

@@ -1,40 +0,0 @@
-3 types d'objets: terrains, décors, créatures
-
-3 origines (4?): Commun, Perso, Ce plateau seulement (, règles?)
-
-Général:
-  Id
-  Nom
-  Logo
-  notes
-
-Pion:
-  hauteur
-  Forme
-  couleur
-  image et format image
-  texte et format texte
-
-Terrain:
-  couleur
-  texture
-  franchissable
-  franchissableNage
-  franchissableEscalade
-  modDeplacement  
-  visibilite
-
-Décor:
-  escalade
-  franchissable
-  brule
-
-Créature:
-  Deplacement
-  Deplacement (nage)
-  Deplacement (vol)
-  Attaques
-  Inventaire
-  Attributs
-
-

+ 63 - 0
lib/ModesInteraction.py

@@ -0,0 +1,63 @@
+"""les modes d'interaction permettent l'interaction
+entre l'interface (l'utilisateur) et le plateau de combat.
+Un seul mode ne peut etre actif a la fois
+Cette classe doit permettre de recevoir les commandes de l'utilisateur
+de maniere a produire un resultat unique (cases peintes, pion deplace...)
+Les modes sont repartis en deux categories:
+cp -> creation du plateau
+pi -> manipulation des pions"""
+
+class ModesInteraction():
+    def __init__(self, plateau):
+        self._actif = ""
+
+    def activer(self, mode, param = None):
+        """active le mode demande (avec si necessaire un parametre supplementaire)"""
+        #desactiver le mode actif
+        #activer le nouveau mode
+        #enregistrer ce mode comme etant le nouveau mode
+        pass
+
+    def resultat(self):
+        """renvoie le resultat de la derniere interaction"""
+        pass
+
+    def actif(self):
+        """renvoie le mode actif"""
+        return self._actif
+    
+
+class Mode():
+    def __init__(self):
+        self.nom = ""
+        self.curseur = ""
+        self.dragMode = False
+        self.param = {}
+        
+        
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+ 249 - 0
lib/Pinceau.py

@@ -0,0 +1,249 @@
+"""pinceau utilise pour la selection et la mise a jour des cases du plateau"""
+
+class Pinceau():
+    def __init__(self, plateau):
+        self.plateau = plateau
+
+        self._forme = "simple"
+        self._epaisseur = 1
+        
+        self._origine = None
+        self._point2 = None
+        self._selection = []
+
+        self._objetGraphique = None
+
+        self._actif = False
+
+    def majForme(self, forme):
+        if forme in ["simple", "ligne", "frontiere", "pot", \
+                     "rectV", "rectP", "ecclipseV", "ecclipseP"]:
+            self._forme = forme
+
+    def majEpaisseur(self, val):
+        if val in range(1, 5):
+            self._epaisseur = val
+
+    def defOrigine(self, coord):
+        if self.plateau.coordonneesValides(coord):
+            self._origine = self.cases[coord].centreGraphique
+
+    def defPoint2(self, coord):
+        if self.plateau.coordonneesValides(coord):
+            self._point2 = self.cases[coord].centreGraphique
+
+    def selection(self):
+        return self._selection
+
+    def demarrer(self, coord):
+        """commence a peindre a partir de la case choisie comme origine"""
+        if self.plateau.coordonneesValides(coord):
+            self._origine = self.cases[coord].centreGraphique
+            self._point2 = self.cases[coord].centreGraphique
+            self._actif = True
+
+    def maj(self, coord):
+        """on met a jour la selection en fonction de la case qui vient d'etre ajoutee"""
+        enPlus  = []  #cases a ajouter a la selection
+        enMoins = []  #cases a retirer de la selection 
+
+        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 == "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)
+                select.remove(coord)
+            enPlus = select   #toutes les coord qui restent dans select sont a ajouter
+
+        else:    
+            if 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)                                   
+            
+            elif self._forme == "rectV" or self.modeParam["typeFormeDessin"] == "rectP":
+                #rectangle
+                if self.modeParam["formeDessin"] == None:
+                    pinceau = QPen()
+                    pinceau.setColor(QColor("black"))
+                    self._objetGraphique = QGraphicsRectItem()
+                    self._objetGraphique.prepareGeometryChange()
+                    self._objetGraphique.setPen(pinceau)
+                    self.plateau.addItem(self._objetGraphique)            
+                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)
+            
+            elif self._forme == "ellipseV" or self.modeParam["typeFormeDessin"] == "ellipseP":
+                #ellipse
+                if self._objetGraphique == None:
+                    pinceau = QPen()
+                    pinceau.setColor(QColor("black"))
+                    self._objetGraphique = QGraphicsEllipseItem()
+                    self._objetGraphique.prepareGeometryChange()
+                    self._objetGraphique.setPen(pinceau)
+                    self.plateau.addItem(self._objetGraphique)
+                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)
+
+            #on liste les cases intersectant la forme
+            select = self.casesSousForme(self._objetGraphique, (self._forme[-1:] == "P"), self._epaisseur - 1)
+            
+            for coord in self._selection:
+                if not coord in select:
+                    enMoins.append(coord)
+                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 annuler(self):
+        self.reinit()
+
+    def terminer(self):
+        return self._selection
+
+    def reinit(self):
+        for coord in self_selection:
+            self.afficherCase(coord, False)
+        self._origine = (-1, -1)
+        self._point2 = (-1, -1)
+        self._selection = []
+        self._actif = False
+
+    def afficherCase(self, coord, actif):
+        self.plateau.cases[coord].majEstCibleCurseur(actif)
+
+
+    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.coordonneesAuPoint(self.modeParam["origineFormeDessin"])
+            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 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
+            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)    
+        if point1 != None and point2 != None and point1 != point2:
+            preSelection = self.preSelectionCollision(point1, point2)
+        else:
+            preSelection = []
+            for coord in self.cases:
+                preSelection.append(coord)
+       
+        #on liste les cases en collision avec la forme 
+        for coord in preSelection:
+            if self.cases[coord].collidesWithItem(forme, Qt.IntersectsItemShape):
+                if plein:
+                    tmp.append(coord) 
+                else:
+                    contenu = True
+                    for i in range(0,len(self.cases[coord].polygon())):
+                        if not forme.contains(self.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 epaisseur > 0:
+            for coord in tmp:
+                zone = self.zone(coord, epaisseur)
+                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.coordonneesAuPoint(point1)]    
+        return listeCases                
+
+
+
+
+
+    

+ 4 - 7
lib/Plateau.py

@@ -299,7 +299,6 @@ class Plateau(QGraphicsScene):
                           "typeAttaqueZone": "", "formeAttaqueZone": None, "origineAttaqueZone": None, "point2AttaqueZone": None, "listeCasesAttaqueZone": [], "ligneMireAttaqueZone": None, \
                           "entreeSortie": None}
   
-
         #mise a jour de l'interface de creation
         self.fenetre.majVisibilitePanneauxPlateau("creation")
 ##        self.fenetre.ui.cbt_nomPlateau.setText(QString.fromUtf8(self.nom))
@@ -670,7 +669,8 @@ class Plateau(QGraphicsScene):
             self.pionDecorSelectionne().afficheOmbreSelection(False)
             self.modeParam["numPionSelectionne"] = 0
 
-        if self.modeActif == "pionSelectionne" or self.modeActif == "pionCreation" or self.modeActif == "pionDecorSelectionne" or self.modeActif == "pionDecorCreation":  
+        if self.modeActif == "pionSelectionne" or self.modeActif == "pionCreation" or \
+           self.modeActif == "pionDecorSelectionne" or self.modeActif == "pionDecorCreation":  
             self.majProjectionPosition(False)
             self.modeParam["formeProjectionPosition"] = None
             self.modeParam["coordProjectionPosition"] = None
@@ -840,7 +840,6 @@ class Plateau(QGraphicsScene):
             self.reinitAttaqueZone()
 ##            if mode != "combatAttaqueZone": self.fenetre.majVisibiliteBarreCombat("menu")
             self.modeParam["listeCasesAttaqueZone"] = []
-               
 
         ## definition du nouveau mode de combat
         if self.pionSelectionne() != None:
@@ -1068,7 +1067,6 @@ class Plateau(QGraphicsScene):
         self.fenetre.ui.pi_listeAttributsAttaqueEC.setColumnWidth(1, (0.5*self.fenetre.ui.pi_listeAttributsAttaqueEC.width()))
         
     def majListeAttaques(self):
-        #*eea
         """met a jour la liste des attaques du pion dans le panneau de combat"""
         #on vide la liste
         while self.fenetre.ui.pi_listeAttaques.rowCount() > 0:
@@ -1384,7 +1382,7 @@ class Plateau(QGraphicsScene):
 
             #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.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):
@@ -1920,7 +1918,6 @@ class Plateau(QGraphicsScene):
     def majListeCases(self, listeCases):
         """met a jour les cases dont les coordonnees sont dans la liste"""
         self.afficherListeCases(listeCases, False)    
-            
         if self.modeActif[0:7] == "caseMaj":
             for coord in listeCases:
                 self.caseMaj(coord)
@@ -2061,7 +2058,7 @@ class Plateau(QGraphicsScene):
                else:
                    valide = False
            if valide:        
-               positionPrecedente = pion.position 
+##               positionPrecedente = pion.position 
                #mise a jour de la position du pion selon le mode
                if self.modePrincipal == "combat":
 ##                   if coordCase in pion.champDeplacement:

+ 0 - 15
lib/a faire - plateau.txt

@@ -1,15 +0,0 @@
-creer une fonction générique pour les curseurs
-
-revoir les connect et les organiser par panneau
-
-renommer les fonctions par panneau (par mode)
-
-creer une fonction générique pour les fonctions de listes
-
-changer les modes combat et creation par cp et pi
-
-chercher un moyen de synthétiser les fonctions de "modes"
-
-réfléchir à la forme de majModeCombat
-
-creer une classe Combat()

+ 0 - 30
modes.txt

@@ -1,30 +0,0 @@
-"standard"
-
-**** cp
-caseMajTerrain
-caseCopie
-caseMajEffet
-caseMajAltitude
-pionCreation
-pionSelectionne
-pionDecorCreation
-pionDecorSelectionne
-pionSupprimer
-cachePlacer
-combatDeplacement
-combatAttaqueCaC
-combatAttaqueDist
-placementEntreeSortie
-majZonePlacement
-
-
-cp_cl   couleur
-cp_tr   terrain
-cp_ef   effet
-cp_nc   nouveau cache
-cp_ 
-
-
-
-
-*** pi