Bläddra i källkod

Reprise des modes création, premiers tests concluants

unknown 10 år sedan
förälder
incheckning
2ceef29a83
4 ändrade filer med 285 tillägg och 230 borttagningar
  1. 0 0
      lib/EffetsCase.py
  2. 12 7
      lib/EntreeSortie.py
  3. 203 65
      lib/Modes.py
  4. 70 158
      lib/Plateau.py

+ 0 - 0
lib/EffetsCase.py


+ 12 - 7
lib/EntreeSortie.py

@@ -5,6 +5,7 @@ from __future__ import division
 from PyQt4.QtCore import *
 from PyQt4.QtGui import *
 
+import Modes
 
 
 class EntreeSortie(QGraphicsPolygonItem):
@@ -18,7 +19,6 @@ class EntreeSortie(QGraphicsPolygonItem):
         self.nbRotations = 0
         self.prepareGeometryChange()
         self.setFlag(QGraphicsItem.ItemIsFocusable)
-        
 
     def __getstate__(self):
         state = {key:value for key, value in self.__dict__.items() if key in ["entreeSortie", "position", "nbRotations"]}
@@ -47,6 +47,7 @@ class EntreeSortie(QGraphicsPolygonItem):
         self.setTransformOriginPoint(0,0)
         self.plateau.fenetre.ui.cbt_vue.fitInView(self.plateau.sceneRect(), Qt.KeepAspectRatio)
         self.plateau.addItem(self)
+        self.estPositionne = False
         
     def majProjection(self, position = None):
         """met a jour la projection de la position de l'objet"""
@@ -58,6 +59,7 @@ class EntreeSortie(QGraphicsPolygonItem):
     def positionner(self):
         """la projection est validee, le marqueur est laisse a cette position"""
         self.setOpacity(1)
+        self.estPositionne = True
 
     def recreer(self, plateau):
         """recreation et repositionnement dans le cadre d'un chargement du plateau"""
@@ -67,12 +69,15 @@ class EntreeSortie(QGraphicsPolygonItem):
         self.setPos(self.position)
         self.setRotation(self.nbRotations*90)
         self.setOpacity(1)
+        self.estPositionne = True
     
     def mousePressEvent(self, event):
         event.ignore()
-        if event.button() == 1:
-            if self.plateau.modeActif != "placementEntreeSortie":
-                self.setOpacity(0.5)
-                self.plateau.modeParam["entreeSortie"] = self
-                self.plateau.majMode("placementEntreeSortie")
-                event.accept()
+        #a revoir
+        
+##        if event.button() == 1:
+##            if self.plateau.modeActif != Modes.EntreesSorties:
+##                self.estPositionne = False
+##                self.setOpacity(0.5)
+##                self.plateau.activerMode(Modes.EntreesSorties, self)
+##                event.accept()

+ 203 - 65
lib/Modes.py

@@ -1,46 +1,14 @@
 """modes d'interaction avec le plateau"""
+from PyQt4.QtCore import *
+from PyQt4.QtGui import *
+from EntreeSortie import EntreeSortie
 
-class MajCases():
-    """mode de mise a jour des cases (terrain, couleur, effet special)"""
-    def __init__(self, plateau):
-        super(MajCases, self).__init__(plateau)
-        self.sourceCurseur = "img\\curseurPinceau.png"
-        self.focus = True
-        self._param = None   #parametre avec lequel on mettra a jour la case
-
-    def activer(self, param):
-        """active le mode"""
-        super(MajCases, self).activer()
-
-    def desactiver(self):
-        """desactive le mode"""
-        self.plateau.pinceau.reinit()
-        super(MajCases, self).desactiver()
-
-    def majParam(self, param):
-        self._param = param
-
-    def clic_case(self, event):
-        pass
-
-    def survolClic_case(self, event):
-        pass
-
-    def finClic_case(self, event):
-        pass
-
-    def toucheClavier(self, event):
-        pass
-
-
-
-
-### --------------------------------------- ####
-    
-class ModeBase():
+class ModeBase(object):
     """mode de base: tous les modes heritent de cette classe"""
     def __init__(self, plateau):
         self.plateau = plateau
+        #le mode est il active
+        self._actif = False
         #le dragmode est il active sur la QGraphicsView
         self._activerDragMode = 0
         #curseur de la QGraphicsView
@@ -48,18 +16,25 @@ class ModeBase():
         #met le focus sur la QGraphicsView a l'activation
         self._focus = False 
 
-    def activer(self):
+    def activer(self, param = None):
         """active le mode"""
         self.activerCurseur()
-        if self.focus:
+        if self._focus:
             self.plateau.fenetre.ui.cbt_vue.setFocus()
+        self._actif = True    
 
     def desactiver(self):
         """desactive le mode"""
         self.desactiverCurseur()
+        self.plateau.fenetre.ui.cbt_vue.setDragMode(1)
+        self._actif = False
+
+    def reinit(self):
+        """remet les variables a 0 et reactive le mode"""
+        pass
 
     def activerCurseur(self):
-        self.fenetre.ui.cbt_vue.setDragMode(self._activerDragMode)
+        self.plateau.fenetre.ui.cbt_vue.setDragMode(self._activerDragMode)
         curseurPix = QPixmap(self._sourceCurseur)
         curseurPinceau = QCursor(curseurPix, 0, curseurPix.height())
         self.plateau.fenetre.ui.cbt_vue.setCursor(curseurPinceau)
@@ -69,53 +44,43 @@ class ModeBase():
 
     ### gestion des evenements souris
     # clic gauche
-    def clic_combattant(self, event):
+    def clic_combattant(self, num):
         pass
 
-    def clic_decor(self, event):
+    def clic_decor(self, num):
         pass
 
-    def clic_case(self, event):
+    def clic_case(self, coord):
         pass
 
     #double clic gauche
-    def doubleClic_combattant(self, event):
-        pass
-
-    def doubleClic_decor(self, event):
+    def doubleClic_combattant(self, num):
         pass
 
-    def doubleClic_case(self, event):
+    def doubleClic_decor(self, num):
         pass
 
-    # clic gauche relache
-    def finClic_combattant(self, event):
-        pass
-
-    def finClic_decor(self, event):
-        pass
-
-    def finClic_case(self, event):
+    def doubleClic_case(self, coord):
         pass
 
     #survol de la souris (entree)   
-    def survol_combattant(self, event):
+    def survol_combattant(self, num):
         pass
 
-    def survol_decor(self, event):
+    def survol_decor(self, num):
         pass
 
-    def survol_case(self, event):
+    def survol_case(self, coord):
         pass
 
     #survol de la souris (sortie)  
-    def finSurvol_combattant(self, event):
+    def finSurvol_combattant(self, num):
         pass
 
-    def finSurvol_decor(self, event):
+    def finSurvol_decor(self, num):
         pass
 
-    def finSurvol_case(self, event):
+    def finSurvol_case(self, coord):
         pass
 
     #survol de la souris avec clic gauche enfonce (entree)   
@@ -125,10 +90,183 @@ class ModeBase():
     def survolClic_decor(self, event):
         pass
 
-    def survolClic_case(self, event):
+    def survolClic_case(self, coord):
+        pass
+
+    #autre
+    def clicGauche(self, event):
         pass
 
-    #clavier
+    def finClicGauche(self, event):
+        pass
+    
+    def mouvementSouris(self, event):
+        pass
+    
     def toucheClavier(self, event):
         pass
   
+
+### --------------------------------------- ####
+
+
+class Standard(ModeBase):
+    """mode standard"""
+    def __init__(self, plateau):
+        super(Standard, self).__init__(plateau)
+        self._sourceCurseur = ""
+        self._focus = False
+        self.activerDragMode = True
+
+    def clic_pion(self, num):
+        pass
+        #doit selectionner le pion
+
+class MajCases(ModeBase):
+    """mode de mise a jour des cases (terrain, couleur, effet special)"""
+    def __init__(self, plateau):
+        super(MajCases, self).__init__(plateau)
+        self._sourceCurseur = "img\\curseurPinceau.png"
+        self._focus = True
+        self._param = None   #parametre avec lequel on mettra a jour la case
+
+    def activer(self, param):
+        """active le mode"""
+        self.majParam(param)
+        super(MajCases, self).activer()
+
+    def desactiver(self):
+        """desactive le mode"""
+        self.plateau.pinceau.reinit()
+        super(MajCases, self).desactiver()
+
+    def majParam(self, param):
+        self._param = param
+
+    def param(self):
+        return self._param
+
+    def clic_case(self, coord):
+        #demarre une operation de peinture des cases
+        self.plateau.pinceau.demarrer(coord)
+
+    def survolClic_case(self, coord):
+        self.plateau.pinceau.maj(coord)
+
+    def finClicGauche(self, event):
+        if self.plateau.pinceau.estActif():
+            for coord in self.plateau.pinceau.selection():
+                if self._param.__class__.__name__ == "Terrain":
+                    self.plateau.cases[coord].majTerrain(self._param)
+                elif self._param.__class__.__name__ == "QColor":
+                    if self._param.isValid():
+                         self.plateau.cases[coord].majTerrain(None)
+                         self.plateau.cases[coord].majCouleur(self._param)
+                elif self._param.__class__.__name__ == "EffetCase":
+                    self.plateau.cases[coord].majEffet(self._param)
+                self.plateau.pinceau.reinit()
+            self.reinit()
+
+    def toucheClavier(self, event):
+        if event.key() == Qt.Key_Up:
+            self.plateau.fenetre.ui.epaisseurPinceau.setValue(self.plateau.fenetre.ui.epaisseurPinceau.value()+1)
+        elif event.key() == Qt.Key_Down:
+            self.plateau.fenetre.ui.epaisseurPinceau.setValue(self.plateau.fenetre.ui.epaisseurPinceau.value()-1)
+
+class Pipette(ModeBase):
+    """mode pipette: on preleve la couleur ou le terrain d'une case"""
+    def __init__(self, plateau):
+        super(ZonePlacement, self).__init__(plateau)
+        self._sourceCurseur = "img\\curseurSeringue.png"
+
+    def activerCurseur(self):
+        super(Pipette, self).activerCurseur()
+        
+    def clic_case(self, coord):
+        if len(case.terrain.nom) > 0:
+             param = case.terrain
+        else:
+             param = case.couleur
+        self.plateau.activerMode(Modes.CaseMaj, param)     
+             
+
+class ZonePlacement(ModeBase):
+    """mode de definition de la/les zones de placement des joueurs"""
+    def __init__(self, plateau):
+        super(ZonePlacement, self).__init__(plateau)
+        self._sourceCurseur = "img\\curseurPinceau.png"
+        self._focus = True
+
+    def activerCurseur(self):
+        super(ZonePlacement, self).activerCurseur()
+
+    def activer(self, param = None):
+        self.plateau.pinceau.majForme("rectP")
+        self.plateau.pinceau.verrouillerForme(True)
+        super(ZonePlacement, self).activer()
+
+    def desactiver(self):
+        self.plateau.pinceau.reinit()
+        super(ZonePlacement, self).desactiver()
+
+    def clic_case(self, coord):
+        #demarre une operation de peinture des cases
+        self.plateau.pinceau.demarrer(coord)
+        
+    def survolClic_case(self, coord):
+        self.plateau.pinceau.maj(coord)
+    
+    def finClicGauche(self, coord):
+        if self.plateau.pinceau.estActif():
+            if len(self.plateau.pinceau.selection()) > 0:
+                self.plateau.majZonePlacement(self.plateau.pinceau.selection())
+                
+
+class EntreesSorties(ModeBase):
+    """mode de definition deentrees et sorties du plateau"""
+    def __init__(self, plateau):
+        super(EntreesSorties, self).__init__(plateau)
+        self._sourceCurseur = "img\\curseurPinceau.png"
+        self._focus = True
+
+    def activerCurseur(self):
+        super(EntreesSorties, self).activerCurseur()
+
+    def activer(self, param):
+        self.es = param
+        self.es.creerForme()
+        super(EntreesSorties, self).activer()
+
+    def desactiver(self):
+        if not self.es.estPositionne:
+            self.es.prepareGeometryChange()
+            self.es.plateau = None
+            self.plateau.removeItem(self.es)
+        super(EntreesSorties, self).desactiver()
+        
+    def mouvementSouris(self, event):
+        if event.buttons() != Qt.LeftButton:
+            if not self.es.estPositionne:
+                self.es.majProjection(event.scenePos())
+
+    def clicGauche(self, event):
+        if not event.isAccepted():
+            self.es.positionner()
+            self.plateau.entreesSorties.append(self.es)
+            self.desactiver()
+
+    def toucheClavier(self, event):
+        if event.key() == Qt.Key_Delete:
+            self.desactiver()
+        elif event.key() == Qt.Key_Right:
+            self.es.nbRotations += 1
+            self.es.majProjection()   
+        elif event.key() == Qt.Key_Left:
+            self.es.nbRotations -= 1
+            self.es.majProjection()    
+
+
+            
+
+
+    

+ 70 - 158
lib/Plateau.py

@@ -12,6 +12,7 @@ from PyQt4 import QtOpenGL
 
 ##from ui.ecran_editionAttaques import Ui_editionAttaques
 
+import Modes
 from Case import Case
 from Combattant import Combattant
 from Decor import Decor
@@ -64,7 +65,6 @@ class Plateau(QGraphicsScene):
         self.nbCasesY = 0
         self.hCase = 0
         self.modePrincipal = "creation"
-        self.modeActif = ""
         self.modeCombat = ""
         
         #interface
@@ -288,17 +288,13 @@ class Plateau(QGraphicsScene):
 
 
         #gestion du mode d'interaction avec le plateau
-        self.modeActif = "standard"
-        self.listMode = ["standard", "caseMajTerrain", "caseCopie", "caseMajEffet", "caseMajAltitude", "pionCreation", \
-                         "pionSelectionne", "pionDecorCreation", "pionDecorSelectionne", "pionSupprimer", "cachePlacer", \
-                         "combatDeplacement", "combatAttaqueCaC", "combatAttaqueDist", \
-                         "placementEntreeSortie", "majZonePlacement"]
-      
-        self.modeParam = {"terrain": None, "numPionSelectionne": 0, "pionNouveau": None, "creature": None, "decor": None, "effet":"", "couleurPion": QColor("grey"), \
+        self.modeActif = Modes.Standard(self)
+        self.modeActif_old = ""
+        self.modeParam = {"numPionSelectionne": 0, "pionNouveau": None, "creature": None, "decor": None, \
                           "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}
+                          "typeAttaqueZone": "", "formeAttaqueZone": None, "origineAttaqueZone": None, "point2AttaqueZone": None, \
+                          "listeCasesAttaqueZone": [], "ligneMireAttaqueZone": None}
   
         #mise a jour de l'interface de creation
         self.fenetre.majVisibilitePanneauxPlateau("creation")
@@ -388,7 +384,7 @@ class Plateau(QGraphicsScene):
     def majListeTerrains(self):
         """mise a jour de la liste des terrains depuis la sauvegarde"""
         self.fenetre.ui.cp_listeTerrains.maj()
-        self.majMode("standard")
+        self.activerMode(Modes.Standard)
 
     def terrainEdit(self):
         """ouvre la fenetre 'terrains' en mode edition"""
@@ -414,7 +410,7 @@ class Plateau(QGraphicsScene):
     def majListeCreatures(self):
         """mise a jour de la liste des creatures depuis la sauvegarde"""
         self.fenetre.ui.cp_listeCreatures.maj()
-        self.majMode("standard")
+        self.activerMode(Modes.Standard)
 
     def creatureEdit(self):
         """ouvre la fenetre 'creatures' en mode edition"""
@@ -441,7 +437,7 @@ class Plateau(QGraphicsScene):
     def majListeDecors(self):
         """mise a jour de la liste des decors depuis la sauvegarde"""
         self.fenetre.ui.cp_listeDecors.maj()
-        self.majMode("standard")
+        self.activerMode(Modes.Standard)
 
     def decorEdit(self):
         """ouvre la fenetre 'decors' en mode edition"""
@@ -454,31 +450,12 @@ class Plateau(QGraphicsScene):
     ###############
 
     ########### affichage des curseurs personnalises ########
-    def curseurSelection(self):
-        self.fenetre.ui.cbt_vue.setDragMode(0)
-        curseurPix = QPixmap("img\\curseurEpee.png")#.scaledToHeight(55, Qt.FastTransformation)
-        curseurPix.setMask(curseurPix.createHeuristicMask())
-        curseurPointe = QCursor(curseurPix, 0, 0)
-        self.fenetre.ui.cbt_vue.setCursor(curseurPointe)
-
-    def curseurPinceau(self):
-        self.fenetre.ui.cbt_vue.setDragMode(0)
-        curseurPix = QPixmap("img\\curseurPinceau.png")
-        curseurPinceau = QCursor(curseurPix, 0, curseurPix.height())
-        self.fenetre.ui.cbt_vue.setCursor(curseurPinceau)
-
     def curseurGomme(self):
         self.fenetre.ui.cbt_vue.setDragMode(0)
         curseurPix = QPixmap("img\\gomme.png")#.scaledToHeight(55, Qt.FastTransformation)
         curseurGomme = QCursor(curseurPix, 0, 0)
         self.fenetre.ui.cbt_vue.setCursor(curseurGomme)
 
-    def curseurSeringue(self):
-        self.fenetre.ui.cbt_vue.setDragMode(0)
-        curseurPix = QPixmap("img\\curseurSeringue.png")
-        curseurSeringue = QCursor(curseurPix, 0, 0)
-        self.fenetre.ui.cbt_vue.setCursor(curseurSeringue)
-
     def curseurEpee(self, valide = True):
         self.fenetre.ui.cbt_vue.setDragMode(0)
         if valide:
@@ -508,6 +485,12 @@ class Plateau(QGraphicsScene):
     def plateauModeCombat(self):
         self.fenetre.majVisibilitePanneauxPlateau("combat")
         self.modePrincipal = "combat"
+
+    def activerMode(self, mode, param = None):
+        """desactive le mode actif et active le nouveau a la place"""
+        self.modeActif.desactiver()
+        self.modeActif = mode(self)
+        self.modeActif.activer(param)
         
 ##    def majModeAffichage(self, index):
 ##        """met a jour le mode d'affichage"""
@@ -530,12 +513,11 @@ class Plateau(QGraphicsScene):
 
     def modePeintureCase(self):
         """enclenche le mode peinture de case a partir de la couleur selectionnee"""
-        self.majMode("standard")
         couleur = self.chercherCouleur()
         if couleur.isValid():
-            self.majMode("caseMajTerrain", couleur)
+            self.activerMode(Modes.MajCases, couleur)
         else:
-            self.majMode("standard")
+            self.activerMode(Modes.Standard)
 
     def modePeintureCase_perso(self):
         origine = self.sender().objectName()
@@ -544,17 +526,16 @@ class Plateau(QGraphicsScene):
         r, g, b = m_couleursRapides[index]
         couleur.setRgb(r, g, b)
         if couleur.isValid():
-            self.majMode("caseMajTerrain", couleur)
+            self.activerMode(Modes.MajCases, couleur)
         else:
-            self.majMode("standard")            
+            self.activerMode(Modes.Standard)            
 
     def modeCopieTerrain(self):
         """enclenche le mode copie de case"""
-        self.majMode("caseCopie") 
+        self.activerMode(Modes.Pipette)
 
     def modeCaseEffet(self):
         """enclenche le mode de mise a jour de l'ffet actif des cases"""
-        self.majMode("standard")
         origine = self.sender().objectName()
         if origine == "effFeu":
             effet = "brule"
@@ -566,9 +547,7 @@ class Plateau(QGraphicsScene):
             effet = "poison"   
         elif origine == "effEffacer":
             effet = "aucun"   
-            
-        self.majMode("caseMajEffet", effet)
-        self.fenetre.ui.cbt_vue.setFocus()
+        self.activerMode(ModesCaseMaj, effet)
 
     def modeCreationPion(self):
         """enclenche le mode de creation de pions simples"""
@@ -596,8 +575,10 @@ class Plateau(QGraphicsScene):
         """enclenche le mode permettant la mise a jour du terrain des cases"""
         index = self.fenetre.ui.cp_listeTerrains.item(ligne, 0)
         terrain = charger("lib\\biblio\\terrain", str(index.text().toUtf8()))
-        self.majMode("caseMajTerrain", terrain)
-        self.fenetre.ui.cbt_vue.setFocus()
+        if terrain:
+            self.activerMode(Modes.MajCases, terrain)
+        else:
+            print "terrain invalide"
 
     def majEpaisseurPinceau(self, epaisseur):
         """met a jour l'epaisseur du pinceau (en cases)"""
@@ -618,9 +599,6 @@ class Plateau(QGraphicsScene):
                   "cp_formeRectPlein": "rectP"}
         self.pinceau.majForme(formes[str(self.sender().objectName())])
 
-        if self.modeActif[0:7] != "caseMaj":    
-            self.majMode("caseMajTerrain", self.modeParam["terrain"])
-
     def majModeCombatDeplacement(self):
         """active le mode de combat 'deplacement' (mode standard)"""
         self.majModeCombat("combatDeplacement")
@@ -645,17 +623,15 @@ class Plateau(QGraphicsScene):
 ##            self.majModeCombat("combatAttaqueZone")
 
     def majModeDefinirEntree(self):
-        self.modeParam["entreeSortie"] = EntreeSortie(self, "E")
-        self.modeParam["entreeSortie"].creerForme()
-        self.majMode("placementEntreeSortie")
+        entree = EntreeSortie(self, "E")
+        self.activerMode(Modes.EntreesSorties, entree)
 
     def majModeDefinirSortie(self):
-        self.modeParam["entreeSortie"] = EntreeSortie(self, "S")
-        self.modeParam["entreeSortie"].creerForme()
-        self.majMode("placementEntreeSortie")
+        sortie = EntreeSortie(self, "S")
+        self.activerMode(Modes.EntreesSorties, sortie)
 
     def majModeZonePlacement(self):
-        self.majMode("majZonePlacement")
+        self.activerMode(Modes.ZonePlacement)
     
     def majMode(self, mode = "standard", param = None):
         """modifie ou reinitialise le type d'interaction avec le plateau"""   
@@ -663,32 +639,32 @@ class Plateau(QGraphicsScene):
         ##on desactive le mode precedent
         if self.pionSelectionne() != None:
             self.pionSelectionne().afficheOmbreSelection(False)
-            if self.modeActif == "pionSelectionne":    
+            if self.modeActif_old == "pionSelectionne":    
                  self.majModeCombat("")   
             self.modeParam["numPionSelectionne"] = 0
         elif self.pionDecorSelectionne() != None:
             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_old == "pionSelectionne" or self.modeActif_old == "pionCreation" or \
+           self.modeActif_old == "pionDecorSelectionne" or self.modeActif_old == "pionDecorCreation":  
             self.majProjectionPosition(False)
             self.modeParam["formeProjectionPosition"] = None
             self.modeParam["coordProjectionPosition"] = None
             self.modeParam["nbRotations"] = 0
                 
-        if self.modeActif[0:7] == "caseMaj" or self.modeActif == "cachePlacer" or self.modeActif == "majZonePlacement":
+        if self.modeActif_old[0:7] == "caseMaj" or self.modeActif_old == "cachePlacer" or self.modeActif_old == "majZonePlacement":
             self.pinceau.reinit()
 
-        if self.modeActif == "placementEntreeSortie":            
+        if self.modeActif_old == "placementEntreeSortie":            
             if self.modeParam["entreeSortie"] != None:
                 self.modeParam["entreeSortie"].prepareGeometryChange()
                 self.removeItem(self.modeParam["entreeSortie"])
                 self.modeParam["entreeSortie"] = None
    
         ### definition du nouveau mode
-        if mode in self.listMode and mode != "standard":
-            self.modeActif = mode
+        if mode != "standard":
+            self.modeActif_old = mode
             reinit = False
             if mode == "caseMajTerrain":
                 #curseur pinceau, on ajoute des terrains au cases
@@ -717,13 +693,13 @@ class Plateau(QGraphicsScene):
                 self.curseurPinceau()
                 self.fenetre.ui.cbt_vue.setDragMode(0)
                 self.pinceau.majForme("rectP")
-                self.verrouillerForme(True)
+                self.pinceau.verrouillerForme(True)
 
             elif mode == "majZonePlacement":
                 self.curseurPinceau()
                 self.fenetre.ui.cbt_vue.setDragMode(0)
                 self.pinceau.majForme("rectP")
-                self.verrouillerForme(True)
+                self.pinceau.verrouillerForme(True)
 
             elif mode == "placementEntreeSortie":
                 self.fenetre.ui.cbt_vue.setDragMode(0)               
@@ -781,13 +757,11 @@ class Plateau(QGraphicsScene):
                     self.majListeAttaques()
                     self.majModeCombat("aucun")                  
 
-        elif not mode in self.listMode:
-            print("mode non reconnu")
 
         ##on reinitialise si necessaire    
         if reinit:
             #mode standard : pas d'interaction avec les cases, on deplace le plateau en le saisissant ou les pions en cliquant dessus
-            self.modeActif = "standard"
+            self.modeActif_old = "standard"
 
             self.majAffichagePionSelectionne()
             self.majInfosPion()
@@ -1610,7 +1584,7 @@ class Plateau(QGraphicsScene):
 
     def validerAttaqueZone(self):
         """l'attaque de zone est validee"""
-        if self.modeActif == "pionSelectionne" and self.modeCombat == "combatAttaqueZone":
+        if self.modeActif_old == "pionSelectionne" and self.modeCombat == "combatAttaqueZone":
             for numCombattant in self.pionsSurListeCase(self.modeParam["listeCasesAttaqueZone"]):
                 print("{} a lance une attaque de zone sur {}".format(self.pionSelectionne().nom, self.pionSelectionne().numero , \
                                                                      self.combattants[numCombattant].nom, self.combattants[numCombattant].numero))
@@ -1703,27 +1677,16 @@ class Plateau(QGraphicsScene):
     def caseCliquee(self, x, y):
         """on a clique sur la case (clic gauche)"""
         coord = (x, y)
+        self.modeActif.clic_case(coord)
         accepte = False
         if coord in self.cases:
             case = self.cases[coord]
-            if self.modeActif == "caseCopie":
-                if len(case.terrain.nom) > 0:
-                     self.majMode("caseMajTerrain", case.terrain)
-                     accepte = True
-                else:
-                     self.majMode("caseMajTerrain", case.couleur)
-                     accepte = True
-                 
-            elif self.modeActif[0:7] == "caseMaj" or self.modeActif == "cachePlacer" or self.modeActif == "majZonePlacement":
-                self.pinceau.demarrer((x, y))
-                accepte = True
-                
-            elif self.modeActif == "pionDecorSelectionne":
+            if self.modeActif_old == "pionDecorSelectionne":
                 if coord != self.pionDecorSelectionne().position:
                     self.pionDeposer(coord)
                     accepte = True
                     
-            elif self.modeActif == "pionSelectionne":
+            elif self.modeActif_old == "pionSelectionne":
                 if self.modeCombat == "combatDeplacement":
                     if self.pionSelectionne() != None:
                         if coord != self.pionSelectionne().position:
@@ -1745,41 +1708,33 @@ class Plateau(QGraphicsScene):
                     self.validerAttaqueZone()
                     accepte = True
                     
-            elif self.modeActif == "pionCreation":
+            elif self.modeActif_old == "pionCreation":
                 self.pionCreer(coord)
                 accepte = True
                 
-            elif self.modeActif == "pionDecorCreation":
+            elif self.modeActif_old == "pionDecorCreation":
                 self.pionDecorCreer(coord)
                 accepte = True    
         return accepte       
 
-    def caseSurvolClicEnfonce(self, coordCase):
+    def caseSurvolClicEnfonce(self, coord):
         """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)
-
-    def clicGaucheRelache(self):
-        """si une forme de selection etait affichee, elle est validee""" 
-        if self.pinceau.estActif():
-            if len(self.pinceau.selection()) > 0:
-                self.majListeCases(self.pinceau.selection())
-                self.pinceau.reinit()
-            #on reinit le mode
-            self.majMode(self.modeActif)
+        self.modeActif.survolClic_case(coord)
 
     def caseSurvol(self, x, y):
         """une case est survole par le curseur, on affiche ses informations dans la zone prevue"""
+        self.modeActif.survol_case((x,y))
+        
         case = self.cases[(x, y)]
         self.majInfosCase(case)
-        if (self.modeActif == "pionSelectionne" and self.modeCombat == "combatDeplacement") or self.modeActif == "pionCreation"\
-           or self.modeActif == "pionDecorSelectionne" or self.modeActif == "pionDecorCreation":
+        if (self.modeActif_old == "pionSelectionne" and self.modeCombat == "combatDeplacement") or self.modeActif_old == "pionCreation"\
+           or self.modeActif_old == "pionDecorSelectionne" or self.modeActif_old == "pionDecorCreation":
             self.majProjectionPosition(False)
             self.modeParam["coordProjectionPosition"] = (case.x, case.y)
             self.majProjectionPosition(True)
-        elif self.modeActif == "pionSelectionne" and self.modeCombat == "combatAttaqueDist" and self.modeParam["cibleAttaqueDist"] != (case.x, case.y):
+        elif self.modeActif_old == "pionSelectionne" and self.modeCombat == "combatAttaqueDist" and self.modeParam["cibleAttaqueDist"] != (case.x, case.y):
             self.majLigneMireAttaqueDist((case.x,case.y))
-        elif self.modeActif == "pionSelectionne" and self.pionSelectionne() != None and self.modeCombat == "combatAttaqueZone":
+        elif self.modeActif_old == "pionSelectionne" and self.pionSelectionne() != None and self.modeCombat == "combatAttaqueZone":
             if case.centreGraphique != self.modeParam["point2AttaqueZone"]:
                 self.cases[self.coordonneesAuPoint(self.modeParam["point2AttaqueZone"])].majEstCibleCurseur(False)
                 self.modeParam["point2AttaqueZone"] = case.centreGraphique
@@ -1790,35 +1745,6 @@ class Plateau(QGraphicsScene):
         for coord in listeCases:
             self.cases[coord].majEstCibleCurseur(actif)
         
-    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)
-        elif self.modeActif == "cachePlacer":
-            self.majAffichageCache(self.cacheEnCours, False)
-            self.caches[self.cacheEnCours]["listeCases"] = listeCases
-            self.majAffichageCache(self.cacheEnCours, True)
-        elif self.modeActif == "majZonePlacement":
-            self.majZonePlacement(listeCases)
-
-    def caseMaj(self, coordCase):
-        """met a jour la case selon le mode actif (et les cases adjacentes selon l'epaisseur du pinceau)"""
-        if self.modeActif == "caseMajTerrain":
-            if self.modeParam["terrain"] != None:
-                if self.modeParam["terrain"].__class__.__name__ == "Terrain":
-                     self.cases[coordCase].majTerrain(self.modeParam["terrain"])
-                elif self.modeParam["terrain"].__class__.__name__ == "QColor":
-                     if self.modeParam["terrain"].isValid():
-                         self.cases[coordCase].majTerrain(None)
-                         self.cases[coordCase].majCouleur(self.modeParam["terrain"])
-##                self.cases[coordCase].majAltitude(int(self.fenetre.ui.altitudeCase.value()))
-        elif self.modeActif == "caseMajEffet":
-            self.cases[coordCase].majEffet(self.modeParam["effet"])
-        elif self.modeActif == "caseMajAltitude":
-            self.cases[coordCase].majAltitude(int(self.fenetre.ui.altitudeCase.value()))
-        
     def majInfosCase(self, case=None):
         """met a jour les informations d'un pion dans la zone prevue"""
         if case != None:
@@ -1845,7 +1771,7 @@ class Plateau(QGraphicsScene):
             self.validerAttaqueDist()
             accepte = True
             
-        elif self.modeActif == "standard" and self.pionSelectionne() == None:
+        elif self.modeActif_old == "standard" and self.pionSelectionne() == None:
             self.pionSaisir(numCombattant)
             accepte = True
         return accepte    
@@ -2027,7 +1953,7 @@ class Plateau(QGraphicsScene):
                         self.cases[coord].majEstCibleCurseur(activer, True)
                              
                         #on affiche la distance correspondante en bulle-info
-                        if activer and self.modeActif == "pionSelectionne" and self.modePrincipal == "combat":
+                        if activer and self.modeActif_old == "pionSelectionne" and self.modePrincipal == "combat":
                              if coord in self.pionSelectionne().champDeplacement:
                                   msg = "Distance {}".format(self.pionSelectionne().champDeplacement[coord])
                                   QToolTip.showText(QCursor.pos(), msg, self.fenetre.ui.cbt_vue)
@@ -2037,7 +1963,7 @@ class Plateau(QGraphicsScene):
 
     def majProjectionAttaqueCaC(self, pionCible):
         """affiche ou non la cible de l'attaque au corps a corps, selon sa validite ou non"""
-        if self.modeActif == "pionSelectionne" and self.modeCombat == "combatAttaqueCaC":
+        if self.modeActif_old == "pionSelectionne" and self.modeCombat == "combatAttaqueCaC":
             if pionCible != self.pionSelectionne():
                 if pionCible != None:
                     conditionPossible = (pionCible.position in self.modeParam["zoneAttaqueCaC"])
@@ -2149,19 +2075,16 @@ class Plateau(QGraphicsScene):
             if coord != None:
                 self.caseSurvolClicEnfonce(coord)  
         else:
-            if self.modeActif == "placementEntreeSortie":
-                self.modeParam["entreeSortie"].majProjection(event.scenePos())
+            self.modeActif.mouvementSouris(event)
             event.ignore() 
 
     def mousePressEvent(self, event):
         super(Plateau, self).mousePressEvent(event)
+        if event.button() == 1:
+            self.modeActif.clicGauche(event)
+        
         if event.button() == 1 and self.fenetre.ui.cbt_vue.dragMode() != QGraphicsView.ScrollHandDrag:
-            if self.modeActif == "placementEntreeSortie" and not event.isAccepted():
-                self.modeParam["entreeSortie"].positionner()
-                self.entreesSorties.append(self.modeParam["entreeSortie"])
-                self.modeParam["entreeSortie"] = None
-                self.majMode("standard")
-            elif self.modeActif == "pionSupprimer":
+            if self.modeActif_old == "pionSupprimer":
                 for item in self.items(event.scenePos()):
                     if item.__class__.__name__ == "PionDecor":
                         self.pionDecorSupprimer(item.numero)
@@ -2179,17 +2102,20 @@ class Plateau(QGraphicsScene):
                 self.majModeCombat("aucun")
             else:    
                 self.majMode("standard")
+                self.activerMode(Modes.Standard)
             event.accept()
         #event.ignore()
 
     def mouseReleaseEvent(self, event):
         super(Plateau, self).mouseReleaseEvent(event)
-        self.clicGaucheRelache()
+        self.modeActif.finClicGauche(event)
 
     def keyPressEvent(self, event):
         """gestion des evenements clavier"""
         toucheClavier = event.key()
-        if self.modeActif == "pionCreation" or self.modeActif == "pionSelectionne" or self.modeActif == "pionDecorSelectionne" or self.modeActif == "pionDecorCreation":
+        self.modeActif.toucheClavier(event)
+        
+        if self.modeActif_old == "pionCreation" or self.modeActif_old == "pionSelectionne" or self.modeActif_old == "pionDecorSelectionne" or self.modeActif_old == "pionDecorCreation":
             #pivots de la projection du deplacement
             if toucheClavier == Qt.Key_Right:
                 self.majProjectionPosition(False)
@@ -2201,29 +2127,15 @@ class Plateau(QGraphicsScene):
                 self.modeParam["nbRotations"] -= 1
                 self.majProjectionPosition(True)
                 event.accept()
-        elif self.modeActif == "creerEntreeSortie":
-            if toucheClavier == Qt.Key_Right: self.modeParam["entreeSortie"].nbRotations += 1
-            if toucheClavier == Qt.Key_Left: self.modeParam["entreeSortie"].nbRotations -= 1
-            self.modeParam["entreeSortie"].majProjection()
-        if self.modeActif[0:7] == "caseMaj":             
-            if toucheClavier == Qt.Key_Up:
-                self.fenetre.ui.epaisseurPinceau.setValue(self.fenetre.ui.epaisseurPinceau.value()+1)
-            elif toucheClavier == Qt.Key_Down:
-                self.fenetre.ui.epaisseurPinceau.setValue(self.fenetre.ui.epaisseurPinceau.value()-1)
+
         if toucheClavier == Qt.Key_Delete:
             if self.pionSelectionne() != None:
                 num = self.pionSelectionne().numero
-                if self.modeActif == "pionSelectionne":
+                if self.modeActif_old == "pionSelectionne":
                     self.pionSupprimer(num)
-                elif self.modeActif == "pionDecorSelectionne":            
+                elif self.modeActif_old == "pionDecorSelectionne":            
                     self.pionDecorSupprimer(num)
                 self.majMode("standard")    
-            elif self.modeActif == "placementEntreeSortie":
-                self.modeParam["entreeSortie"].plateau = None
-                self.removeItem(self.modeParam["entreeSortie"])
-                self.entreesSorties.remove(self.modeParam["entreeSortie"])
-                self.modeParam["entreeSortie"] = None
-                self.majMode("standard")
             
     ################