#from __future__ import unicode_literals # -*- coding: utf-8 -*- from __future__ import division import os from PyQt4.QtCore import * from PyQt4.QtGui import * from Pion import ImgPion, EtiquettePion class VueEditionForme(QGraphicsScene): """vue graphique permettant d'afficher et de modifier la forme des creatures/decors""" def __init__(self, fenetre, parent=None): super(VueEditionForme, self).__init__() self.fenetre = fenetre self._vefImage = VefImage(self) self._vefEtiquette = VefEtiquette(self) self._couleur = QColor("grey") self._cases = {} self._formeCases = "H" self._l0 = 0 self._h0 = 0 self._rotation = 0 self.fenetre.ui.edc_vueForme.setScene(self) self.fenetre.ui.edc_vueForme.centerOn(self.fenetre.ui.edc_vueForme.mapFromScene(QPointF(60,60))) #centre la vue sur la case 0,0 self.fenetre.ui.edc_vueForme.scale(0.25, 0.25) #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, cheminFichier): imgDef = ImgPion() imgDef.nomFichier = cheminFichier 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,5): if self._formeCases == "H": if 1 == (x % 2): y += 0.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 majSelection(self, coord): """met a jour l'affichage des cases selectionnees pour l'affichage de la forme""" if self._cases[coord].estSelectionnee(): #on deselectionne la case ## self._cases[coord].selectionner(False) 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) def afficherMsg(self, msg): print msg 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": polygone << QPointF(((x*0.866)+0.2886)*120, y*120) \ << QPointF(((x*0.866)+0.866)*120, y*120) \ << QPointF(((x*0.866)+1.1547)*120, (y+0.5)*120) \ << QPointF(((x*0.866)+0.866)*120, (y+1)*120) \ << QPointF(((x*0.866)+0.2886)*120, (y+1)*120) \ << QPointF( (x*0.866)*120, (y+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.append((x, y+1)) self._voisins.append((x, y-1)) self._voisins.append((x-1, y+0.5)) self._voisins.append((x-1, y-0.5)) self._voisins.append((x+1, y+0.5)) self._voisins.append((x+1, y-0.5)) 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) #text.setPos(QPointF(((x*0.866)+0.2886)*120, y*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.setFlags(QGraphicsItem.ItemIsMovable | QGraphicsItem.ItemIsSelectable | \ QGraphicsItem.ItemSendsGeometryChanges | 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 len(self._def.nomFichier) > 0: if self._pix == None: self._pix = QPixmap(QString.fromUtf8(self._def.nomFichier)) 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: self._pix.scaled((self._def.kx/10)*self._l0, (self._def.ky/10)*self._h0, \ 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 mousePressEvent(self, event): self.prepareGeometryChange() self.scene.afficherMsg("Utilisez les touches HAUT et BAS pour modifier la taille de l'image\n" \ "Utilisez les touches GAUCHE et DROITE pour faire pivoter l'image\n" \ "Utilisez la touche G pour activer/desactiver l'écriture en gras") def mouseReleaseEvent(self, event): self.scene.afficherMsg("") nouvellePos = self.scenePos() self._def.dx = nouvellePos.x()# - 0.5*(120*k - self._pix.width()) self._def.dy = nouvellePos.y()# - 0.5*(120 - self._pix.height()) def keyPressEvent(self, event): pass ## if event.key() == Qt.Key_Up: ## self._def.taille_police += 4 ## self._maj() ## elif event.key() == Qt.Key_Down: ## self._def.taille_police -= 4 ## self._maj() ## elif event.key() == Qt.Key_G: ## if not self._def.gras: ## self._def.gras = True ## else: ## self._def.gras = False ## 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.setFlags(QGraphicsItem.ItemIsMovable | QGraphicsItem.ItemIsSelectable | \ ## QGraphicsItem.ItemSendsGeometryChanges | QGraphicsItem.ItemIsFocusable) ## self.setFlags(QGraphicsItem.ItemIsSelectable | \ ## QGraphicsItem.ItemSendsGeometryChanges | QGraphicsItem.ItemIsFocusable) self.setAcceptDrops(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 itemChange(self, changement, nouvelleValeur): ## """reimplementation de la fonction de QGraphicsItem""" ## if changement == QGraphicsItem.ItemPositionChange: ## nouvellePos = nouvelleValeur.toPointF() ## #maj de dx et dy (par rapport a la position initiale ## self._def.dx = nouvellePos.x() - 0.112*120 ## self._def.dy = nouvellePos.y() - 0.5*120 ## return super(VefEtiquette, self).itemChange(changement, nouvelleValeur) 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("") nouvellePos = self.scenePos() self._def.dx = nouvellePos.x() - 0.112*120 self._def.dy = nouvellePos.y() - 0.5*120 def keyPressEvent(self, event): if event.key() == Qt.Key_Up: self._def.taille_police += 4 self._maj() elif event.key() == Qt.Key_Down: self._def.taille_police -= 4 self._maj() elif event.key() == Qt.Key_G: if not self._def.gras: self._def.gras = True else: self._def.gras = False self._maj()