| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423 |
- #from __future__ import unicode_literals
- # -*- coding: utf-8 -*-
- from __future__ import division
- from PyQt4.QtCore import QPointF, Qt, QSize, QString
- from PyQt4.QtGui import QGraphicsScene, QColor, QGraphicsPolygonItem, \
- QGraphicsItem, QPolygonF, QPen, QGraphicsPixmapItem, QApplication, \
- QGraphicsSimpleTextItem, QFont
- from Pion import ImgPion, EtiquettePion
- class VueEditionForme(QGraphicsScene):
- """vue graphique permettant d'afficher et de modifier la forme des creatures/decors"""
- def __init__(self, vue, parent=None):
- super(VueEditionForme, self).__init__()
- self.vue = vue
-
- self._vefImage = VefImage(self)
- self._vefEtiquette = VefEtiquette(self)
- self._couleur = QColor(190,190,190,255)
- self._cases = {}
- self._formeCases = "H"
- self._autoriseModifForme = False
-
- self._l0 = 0
- self._h0 = 0
- self._rotation = 0
- self.selection = None
- self.vue.setScene(self)
- self.vue.centerOn(self.vue.mapFromScene(QPointF(60,60))) #centre la vue sur la case 0,0
- self.vue.scale(0.22, 0.22)
- def setCursor(self, curseur):
- self.vue.setCursor(curseur)
- #acces aux donnees
- def chargerFormeDef(self, formeDef):
- self._formeDef = formeDef
- self._majFormeGraphique()
- def formeDef(self):
- """renvoie la definition de forme (selon la forme des cases actuelle)"""
- retour = []
- for coord in self._cases:
- if self._cases[coord].estSelectionnee() and coord != (0,0):
- retour.append(coord)
- return retour
- def chargerEtiquetteDef(self, etiquetteDef):
- self._vefEtiquette.charger(etiquetteDef)
- def etiquetteDef(self):
- return self._vefEtiquette.definition()
- def chargerImageDef(self, imgDef):
- self._vefImage.charger(imgDef)
- def nouvelleImageDef(self, rimage):
- imgDef = ImgPion()
- imgDef.rimage = rimage
- self._vefImage.charger(imgDef)
- def imageDef(self):
- return self._vefImage.definition()
-
- def majCouleur(self, couleur):
- """met a jour la couleur du pion"""
- self._couleur = couleur
- self._majCouleurGraphique()
- def couleur(self):
- return self._couleur
- def formeCases(self):
- return self._formeCases
- #creation, suppression, mises a jour...
- def creer(self, formeCases = "H"):
- self._formeCases = formeCases
-
- for x in range(-5,6):
- for y in range(-5,6):
- if not ((x%2)==1 and y == -5):
- c = VefCase(self)
- c.creer(x, y, self._couleur, self._formeCases)
- self._cases[(x,y)] = c
- def vider(self):
- for coord in self._cases:
- self.removeItem(self._cases[coord])
- self._cases = {}
- def _majFormeGraphique(self):
- """met a jour la forme affichee sur le graphique"""
- if self._formeDef:
- for coord in self._formeDef:
- if coord in self._cases:
- self._cases[coord].selectionner(True)
- self._cases[coord].setBrush(self._couleur)
- def _majCouleurGraphique(self):
- for coord in self._cases:
- if self._cases[coord].estSelectionnee():
- if coord == (0,0):
- c = self._couleur.darker(150)
- self._cases[coord].setBrush(c)
- else:
- self._cases[coord].setBrush(self._couleur)
- def majSelection(self, coord):
- """met a jour l'affichage des cases selectionnees pour l'affichage de la forme"""
- if self._autoriseModifForme:
- if self._cases[coord].estSelectionnee():
- valide = True
- for coordVerif in self._cases:
- #on parcourt les autres cases selectionnees
- if coordVerif != (0,0) and coordVerif != coord and self._cases[coordVerif].estSelectionnee():
- #on liste les cases connectees a cette case, de proche en proche
- connectees = [coordVerif]
- for coordVerif2 in connectees:
- for coordVoisin in self._cases[coordVerif2].voisins():
- if coordVoisin in self._cases and not coordVoisin in connectees:
- if self._cases[coordVoisin].estSelectionnee():
- connectees.append(coordVoisin)
- if not (0,0) in connectees:
- valide = False
- break
- if valide:
- self._cases[coord].selectionner(False)
- else:
- #on s'assure que la case est bien adjacente a une case selectionnee
- valide = False
- for coordVerif in self._cases[coord].voisins():
- if coordVerif in self._cases:
- if self._cases[coordVerif].estSelectionnee():
- valide = True
- break
- if valide:
- self._cases[coord].selectionner(True)
-
- self._majCouleurGraphique()
- def afficherMsg(self, msg):
- print msg
- def autoriserModifForme(self, actif):
- self._autoriseModifForme = actif
- class VefCase(QGraphicsPolygonItem):
- """case utilisee dans une VueEditionForme()"""
- def __init__(self, scene, parent=None):
- super(VefCase, self).__init__()
- self.scene = scene
- self._position = (0,0)
- self._estSelectionnee = False
- self._voisins = []
- self._couleur = None
-
- #interactions graphiques
- self.setFlag(QGraphicsItem.ItemIsFocusable)
- self.setAcceptHoverEvents(True)
- def estSelectionnee(self):
- return self._estSelectionnee
- def selectionner(self, actif):
- if actif:
- self.setBrush(self._couleur)
- else:
- self.setBrush(QColor(255,255,255,50))
- self._estSelectionnee = actif
- def voisins(self):
- return self._voisins
- def creer(self, x, y, couleur, formeCases="H"):
- """creation du polygone et enregistrement des donnees geometriques"""
- self._position = (x, y)
-
- polygone = QPolygonF()
-
- if formeCases == "H":
- my = 0
- if (x % 2) == 1: my = -0.5
- polygone << QPointF(((x*0.866)+0.2886)*120, (y+my)*120) \
- << QPointF(((x*0.866)+0.866)*120, (y+my)*120) \
- << QPointF(((x*0.866)+1.1547)*120, (y+my+0.5)*120) \
- << QPointF(((x*0.866)+0.866)*120, (y+my+1)*120) \
- << QPointF(((x*0.866)+0.2886)*120, (y+my+1)*120) \
- << QPointF( (x*0.866)*120, (y+my+0.5)*120)
- else:
- polygone << QPointF(x*120, y*120) \
- << QPointF((x+1)*120, y*120) \
- << QPointF((x+1)*120, (y+1)*120) \
- << QPointF(x*120, (y+1)*120)
- self.setPolygon(polygone)
- #enregistrement des cases voisines:
- if formeCases == "H":
- self._voisins = [(x, y-1), (x+1, y-1), (x+1, y), (x, y+1), (x-1, y), (x-1, y-1)]
- else:
- self._voisins.append((x, y-1))
- self._voisins.append((x, y+1))
- self._voisins.append((x-1, y))
- self._voisins.append((x+1, y))
- #pour afficher les coordonnees des cases:
- ## text = QGraphicsSimpleTextItem("{} {}".format(x, y), parent=self)
- ## police = QFont()
- ## police.setPointSize(20)
- ## text.setFont(police)
- ## k = 0
- ## if (x % 2) == 1: k = - 0.5
- ## text.setPos(QPointF(((x*0.866)+0.5773)*120, (y+0.5+k)*120))
- #couleur de fond par defaut
- if couleur.__class__.__name__ == "QColor":
- if couleur.isValid():
- self._couleur = couleur
- else:
- self._couleur = QColor("grey")
- else:
- self._couleur = QColor("grey")
-
- if self._position == (0, 0):
- couleur = self._couleur.darker(150)
- self.setBrush(couleur)
- self._estSelectionnee = True
- else:
- self.selectionner(False)
-
- #creation de l'objet graphique sur le plateau
- pinceau = QPen()
- pinceau.setWidth(2)
- pinceau.setColor(QColor(150,150,150,150))
- self.setPen(pinceau)
- self.scene.addItem(self)
- def mousePressEvent(self, event):
- """evenement lors du clic souris"""
- super(VefCase, self).mousePressEvent(event)
- if event.button() == 1: #sur clic gauche
- if self._position != (0, 0):
- self.scene.majSelection(self._position)
- class VefImage(QGraphicsPixmapItem):
- """etiquette utilisee dans une VueEditionForme()"""
- def __init__(self, scene, parent=None):
- super(VefImage, self).__init__()
- self.scene = scene
- self._def = ImgPion()
- self._pix = None
- self._l0 = 0
- self._h0 = 0
- self.setAcceptDrops(True)
- self.setAcceptHoverEvents(True)
- self.setFlags(QGraphicsItem.ItemIsMovable | QGraphicsItem.ItemIsSelectable | QGraphicsItem.ItemIsFocusable)
- self.scene.addItem(self)
- self.setZValue(10)
-
- def charger(self, definition):
- self._pix = None
- self._l0 = 0
- self._h0 = 0
- self._def = definition
- self._maj()
- def definition(self):
- return self._def
- def _maj(self):
- if self._def.rimage.estValide():
- if self._pix == None:
- self._pix = self._def.rimage.pix()
- if not self._pix.isNull():
- if self._pix.height() >= self._pix.width():
- self._pix = self._pix.scaledToHeight(120*0.9, Qt.SmoothTransformation)
- else:
- self._pix = self._pix.scaledToWidth(120*0.9, Qt.SmoothTransformation)
- self._l0 = self._pix.width()
- self._h0 = self._pix.height()
- else:
- self._pix = None
- else:
- self._pix = None
-
- if self._pix:
- taille = QSize((self._def.kx/10)*self._l0, (self._def.ky/10)*self._h0)
- self._pix = self._pix.scaled(taille, Qt.IgnoreAspectRatio, Qt.SmoothTransformation)
- k = 1
- if self.scene.formeCases() == "H": k = 1.1544
- deltaX = self._def.dx + 0.5*(120*k - self._pix.width())
- deltaY = self._def.dy + 0.5*(120 - self._pix.height())
-
- self.setPixmap(self._pix)
- self.setPos(QPointF(deltaX, deltaY))
- self.setRotation(self._def.rotation)
- def width(self):
- return self.boundingRect().width()
- def height(self):
- return self.boundingRect().height()
- def majPos(self, pos):
- k = 1
- if self.scene.formeCases() == "H": k = 1.1544
- self._def.dx = pos.x() - 0.5*(120*k - self._pix.width())
- self._def.dy = pos.y() - 0.5*(120 - self._pix.height())
- def mousePressEvent(self, event):
- self.prepareGeometryChange()
- self.scene.afficherMsg("Utilisez les touches Z, Q, S, D pour modifier la taille de l'image\n" \
- "Utilisez les touches W et X pour faire pivoter l'image")
- def mouseReleaseEvent(self, event):
- self.scene.afficherMsg("")
- super(VefImage, self).mouseReleaseEvent(event)
- QApplication.processEvents()
- self.majPos(self.scenePos())
- def keyPressEvent(self, event):
- if event.key() in [Qt.Key_Z, Qt.Key_Q, Qt.Key_S, Qt.Key_D, Qt.Key_W, Qt.Key_X]:
- if event.key() == Qt.Key_Z:
- self._def.ky += 2
- elif event.key() == Qt.Key_Q:
- self._def.kx -= 2
- elif event.key() == Qt.Key_S:
- self._def.ky -= 2
- elif event.key() == Qt.Key_D:
- self._def.kx += 2
- elif event.key() == Qt.Key_W:
- self._def.rotation -= 5
- elif event.key() == Qt.Key_X:
- self._def.rotation += 5
- self.majPos(self.scenePos())
- self._maj()
- class VefEtiquette(QGraphicsSimpleTextItem):
- """etiquette utilisee dans une VueEditionForme()"""
- def __init__(self, scene, parent=None):
- super(VefEtiquette, self).__init__()
- self.scene = scene
- self._def = EtiquettePion()
- self.setFlags(QGraphicsItem.ItemIsMovable | QGraphicsItem.ItemIsSelectable | QGraphicsItem.ItemIsFocusable)
- self.setAcceptDrops(True)
- self.setAcceptHoverEvents(True)
-
- self.scene.addItem(self)
- self.setZValue(10)
-
-
- def charger(self, definition):
- self._def = definition
- self._maj()
- def definition(self):
- return self._def
- def _maj(self):
- if len(self._def.txt) > 0:
- self.setText(QString.fromUtf8(self._def.txt))
- self.setPos(QPointF(self._def.dx - 0.112*120, self._def.dy - 0.5*120))
- police = QFont("Verdana", self._def.taille_police)
- police.setBold(self._def.gras)
- self.setFont(police)
- def majPos(self, pos):
- self._def.dx = pos.x() - 0.112*120
- self._def.dy = pos.y() - 0.5*120
- def mousePressEvent(self, event):
- self.prepareGeometryChange()
- self.scene.afficherMsg("Utilisez les touches HAUT et BAS pour modifier la taille de la police\n" \
- "Utilisez la touche G pour activer/desactiver l'écriture en gras")
- def mouseReleaseEvent(self, event):
- self.scene.afficherMsg("")
- super(VefEtiquette, self).mouseReleaseEvent(event)
- QApplication.processEvents()
- self.majPos(self.scenePos())
- def keyPressEvent(self, event):
- if event.key() == Qt.Key_Up:
- self._def.taille_police += 4
- self.majPos(self.scenePos())
- self._maj()
- elif event.key() == Qt.Key_Down:
- self._def.taille_police -= 4
- self.majPos(self.scenePos())
- self._maj()
- elif event.key() == Qt.Key_G:
- if not self._def.gras:
- self._def.gras = True
- else:
- self._def.gras = False
- self.majPos(self.scenePos())
- self._maj()
-
-
-
-
|