dm.py 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542
  1. #from __future__ import unicode_literals
  2. # -*- coding: utf-8 -*-
  3. """ensemble des widgets surchargés"""
  4. import os
  5. from PyQt4.QtCore import QString, SIGNAL, QVariant, QSize, pyqtSignal, \
  6. QPersistentModelIndex, Qt, QEvent, QModelIndex
  7. from PyQt4.QtGui import QLabel, QPixmap, QTextEdit, QLineEdit, QGraphicsView, \
  8. QComboBox, QSpinBox, QTabWidget, QTableWidget, QTableWidgetItem, \
  9. QItemSelectionModel, QIcon, QColor, QBrush, QGroupBox, QFrame
  10. from lib.outilsSvg import afficheSvg
  11. try:
  12. import lib.regles as regles
  13. except:
  14. try:
  15. import regles as regles
  16. except:
  17. print "dm: impossible de charger regles"
  18. class Biblio():
  19. """cette classe fournit une liste spreciale"""
  20. def __init__(self):
  21. self.dico = {}
  22. self.ordre = []
  23. def trierPar(self, param):
  24. """trie en fonction du parametre des objets"""
  25. ordre = []
  26. return ordre
  27. def elt(self, index):
  28. return self.dict[index]
  29. class DmLabel(QLabel):
  30. """surcharge de QLabel"""
  31. def __init__(self, parent = None):
  32. super(DmLabel, self).__init__(parent)
  33. self._image = None
  34. def majTexte(self, txt):
  35. self.clear()
  36. self.setText(QString.fromUtf8(txt))
  37. def chargerImage(self, img = None):
  38. """prend une RImage en parametre"""
  39. self.clear()
  40. if img:
  41. self._image = img
  42. pix = img.pix(self.width(), self.height())
  43. else:
  44. pix = QPixmap()
  45. self.setPixmap(pix)
  46. def texte(self):
  47. return str(self.text().toUtf8())
  48. def image(self):
  49. return self._image
  50. def mousePressEvent(self, event):
  51. if event.button() == 1:
  52. self.emit(SIGNAL("clicked()"))
  53. def mouseDoubleClickEvent(self, event):
  54. if event.button() == 1:
  55. self.emit(SIGNAL("doubleClicked()"))
  56. class DmTextEdit(QTextEdit):
  57. def __init__(self, parent = None):
  58. super(DmTextEdit, self).__init__(parent)
  59. def majTexte(self, txt):
  60. self.clear()
  61. self.setText(QString.fromUtf8(str(txt)))
  62. def texte(self):
  63. return str(self.toPlainText().toUtf8())
  64. class DmLineEdit(QLineEdit):
  65. def __init__(self, parent = None):
  66. super(DmLineEdit, self).__init__(parent)
  67. def majTexte(self, txt):
  68. self.clear()
  69. self.setText(QString.fromUtf8(str(txt)))
  70. def texte(self):
  71. return str(self.text().toUtf8())
  72. class DmGraphicsView(QGraphicsView):
  73. """surcharge de QGraphicsView"""
  74. def __init__(self, parent = None):
  75. super(DmGraphicsView, self).__init__(parent)
  76. self.nbZoomActuel = 0
  77. def resizeEvent(self, event):
  78. super(DmGraphicsView, self).resizeEvent(event)
  79. self.emit(SIGNAL("resizeEvent()"))
  80. def wheelEvent(self, event):
  81. """zoom/dezoom avec la molette de la souris"""
  82. #on zoom/dezoom et on recentre sur la position du curseur
  83. zoom = 1.00
  84. if event.delta() > 0:
  85. if self.nbZoomActuel <= 10:
  86. self.nbZoomActuel += 1
  87. zoom = 1.25
  88. elif event.delta() < 0:
  89. if self.nbZoomActuel >= -10:
  90. zoom = 0.8
  91. self.nbZoomActuel -= 1
  92. if zoom != 0.00:
  93. self.scale(zoom, zoom)
  94. self.centerOn(self.mapToScene(event.pos()))
  95. self.emit(SIGNAL("zoomChange(int)"), self.nbZoomActuel)
  96. event.accept() #pour considerer l'evenement comme resolu, sans ca les barres de defilement reagissent aussi
  97. class DmComboBox(QComboBox):
  98. """surcharge de QComboBox"""
  99. def __init__(self, parent = None):
  100. super(DmComboBox, self).__init__(parent)
  101. def allerA(self, donnee):
  102. """cherche la donnee demandee et affiche la ligne"""
  103. index = self.findData(QVariant(donnee))
  104. self.setCurrentIndex(index)
  105. def valeurActuelle(self):
  106. """renvoie sous forme de QVariant la valeur en cours"""
  107. return self.itemData(self.currentIndex())
  108. class DmSpinBox(QSpinBox):
  109. """surcharge de QSpinBox"""
  110. def __init__(self, parent = None):
  111. super(DmSpinBox, self).__init__(parent)
  112. def focusInEvent(self, event):
  113. super(DmSpinBox, self).focusInEvent(event)
  114. self.selectAll()
  115. class DmTabInventaire(QTabWidget):
  116. """surcharge de QTabWidget stylisee et
  117. utilisee pour filtrer les types d'objets affiches"""
  118. def __init__(self, parent = None):
  119. super(DmTabInventaire, self).__init__(parent)
  120. self.setStyleSheet(QString.fromUtf8("""
  121. QTabWidget::pane { border-top: 2px solid #C2C7CB; }
  122. QTabWidget::tab-bar { alignment: right; }
  123. QTabBar::tab {
  124. background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
  125. stop: 0 #E1E1E1, stop: 0.4 #DDDDDD,
  126. stop: 0.5 #D8D8D8, stop: 1.0 #D3D3D3);
  127. border: 2px solid #C4C4C3;
  128. border-bottom-color: #C2C7CB; border-top-left-radius: 4px;
  129. border-top-right-radius: 8px;
  130. border-top-left-radius: 8px;
  131. padding-left: 15px; }
  132. QTabBar::tab:selected, QTabBar::tab:hover {
  133. background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
  134. stop: 0 #fafafa, stop: 0.4 #f4f4f4,
  135. stop: 0.5 #e7e7e7, stop: 1.0 #fafafa); }
  136. QTabBar::tab:selected { border-color: #9B9B9B;
  137. border-bottom-color: #C2C7CB; }
  138. """))
  139. class DmTableWidget(QTableWidget):
  140. """surcharge de QTableWidget"""
  141. def __init__(self, parent = None):
  142. super(DmTableWidget, self).__init__(parent)
  143. self.majEnCours = False
  144. def vider(self):
  145. """supprime toutes les lignes"""
  146. self.majEnCours = True
  147. while self.rowCount() > 0:
  148. self.removeRow(0)
  149. self.majEnCours = False
  150. def nouvelleLigneFin(self):
  151. """ajoute une ligne en derniere position"""
  152. pos = self.rowCount()
  153. self.insertRow(pos)
  154. return pos
  155. def lignes(self):
  156. """retourne la liste des index de lignes de la table"""
  157. return range(0, self.rowCount())
  158. def colonnes(self):
  159. """retourne la liste des index de lignes de la table"""
  160. return range(0, self.columnCount())
  161. def masquerColonneId(self):
  162. """masque la colonne en position 0 qui contient les identifiants"""
  163. self.setColumnWidth(0, 0)
  164. def majData(self, ligne, colonne, var):
  165. """met a jour la cellule avec une donnee de type QVariant"""
  166. var = QVariant(var)
  167. if not self.item(ligne, colonne):
  168. item = QTableWidgetItem()
  169. item.setData(0, var)
  170. self.setItem(ligne, colonne, item)
  171. else:
  172. self.item(ligne, colonne).setData(0, var)
  173. return True
  174. def majTexte(self, ligne, colonne, texte):
  175. """met a jour la cellule avec du texte"""
  176. if not self.item(ligne, colonne):
  177. self.setItem(ligne, colonne, QTableWidgetItem(QString.fromUtf8(str(texte))))
  178. else:
  179. self.item(ligne, colonne).setText(QString.fromUtf8(str(texte)))
  180. return True
  181. def majEnt(self, ligne, colonne, valeur):
  182. """met a jour la cellule avec une valeur numerique entiere
  183. si valeur ne peut etre converti en numerique, on retourne Faux"""
  184. retour = False
  185. try:
  186. entier = QVariant(long(valeur))
  187. self.item(ligne, colonne).setData(0, entier)
  188. retour = True
  189. except:
  190. pass
  191. return retour
  192. def chercherLigne(self, colonne, valeur):
  193. """cherche la valeur dans la colonne demandee
  194. renvoie la ligne correspondante """
  195. ligne = None
  196. for i in range(0, self.rowCount()):
  197. if str(self.item(i, colonne).text().toUtf8()) == str(valeur):
  198. ligne = i
  199. break
  200. return ligne
  201. def majLigne(self, ligne, dico, flags = []):
  202. """rempli la ligne avec les donnees trouvees dans le dictionnaire"""
  203. for colonne in range(0, self.columnCount()):
  204. nomChamp = ""
  205. item = self.horizontalHeaderItem(colonne)
  206. if item:
  207. nomChamp = str(item.text())
  208. if nomChamp in dico:
  209. item = QTableWidgetItem()
  210. for f in flags:
  211. item.setFlag(f)
  212. var = QVariant(dico[nomChamp])
  213. item.setData(0, var)
  214. self.setItem(ligne, colonne, item)
  215. def texte(self, ligne, colonne):
  216. return str(self.item(ligne, colonne).text().toUtf8())
  217. def data(self, ligne, colonne):
  218. retour = None
  219. item = self.item(ligne, colonne)
  220. if item:
  221. retour = item.data(0)
  222. return retour
  223. def ligneSelectionnee(self):
  224. """renvoie la ligne selectionnee (la premiere si plusieurs le sont)"""
  225. return self.currentRow()
  226. def selectionner(self, ligne, colonne):
  227. self.setCurrentCell(ligne, colonne, QItemSelectionModel.Select)
  228. class DmTableMat(DmTableWidget):
  229. """table utilisee pour afficher les bibliotheques d'objets:
  230. terrains, decors, creatures"""
  231. def __init__(self, parent = None):
  232. super(DmTableMat, self).__init__(parent)
  233. self._init = False
  234. def charger(self, listeMat):
  235. """remplit la table avec les donnees contenues dans les fichiers de materiel
  236. (filtre selon le prefixe)"""
  237. if not self._init:
  238. self.setIconSize(QSize(30,20))
  239. self.horizontalHeader().setStretchLastSection(True)
  240. self.masquerColonneId()
  241. self._init = True
  242. self.majEnCours = True
  243. self.setSortingEnabled(False)
  244. for mat in listeMat:
  245. ligne = self.nouvelleLigneFin()
  246. self.majTexte(ligne, 0, mat.idM())
  247. icon = QIcon() if not mat.icone() else QIcon(mat.icone().fichier())
  248. item = QTableWidgetItem(icon, QString.fromUtf8(mat.nom()))
  249. self.setItem(ligne, 1, item)
  250. self.sizeHintForColumn(1)
  251. self.sortItems(1)
  252. self.setSortingEnabled(True)
  253. self.majEnCours = False
  254. def maj(self):
  255. self.vider()
  256. self.remplir()
  257. def selection(self):
  258. """renvoie l'idM du materiel actuellement selectionne"""
  259. return self.texte(self.currentRow(), 0)
  260. # class DmTableAttributsPi(DmTableWidget):
  261. # """table utilisee pour afficher les attributs d'un pion dans le panneau Pi"""
  262. # def __init__(self, parent = None):
  263. # super(DmTableMat, self).__init__(parent)
  264. # self.masquerColonneId()
  265. #
  266. # def initAffichage(self):
  267. # """fait les differents reglages relatifs a l'apparence"""
  268. # self.setColumnWidth(0, 0)
  269. # self.setIconSize(QSize(30,20))
  270. # self.horizontalHeader().setStretchLastSection(True)
  271. #
  272. # def remplir(self, attributs):
  273. # """remplit la table avec les donnees du pion"""
  274. # self.majEnCours = True
  275. # self.setSortingEnabled(False)
  276. # index = 0
  277. # for elt in dico:
  278. # objet = dico[elt]
  279. # self.insertRow(int(index))
  280. #
  281. # #code de l'objet
  282. # self.setItem(int(index),0,QTableWidgetItem(QString.fromUtf8(elt)))
  283. # #icone et nom
  284. # icon = QIcon("img\\"+objet.icone())
  285. # item = QTableWidgetItem(icon,QString.fromUtf8(objet.nom))
  286. # self.setItem(int(index),1,item)
  287. #
  288. # index += 1
  289. # self.sizeHintForColumn(1)
  290. # self.setSortingEnabled(True)
  291. # self.sortItems(1)
  292. # self.majEnCours = False
  293. #
  294. # def maj(self):
  295. # self.vider()
  296. # self.remplir()
  297. # def actuel(self):
  298. # """renvoie l'objet actuellement selectionne"""
  299. # objet = None
  300. # index = self.item(self.currentRow(), 0)
  301. # if index > 0:
  302. # objet = charger(self.fichier, str(index.text().toUtf8()))
  303. # return objet
  304. class DmTableInventaire(DmTableWidget):
  305. """table utilisee pour afficher l'inventaire d'un combattant"""
  306. itemExited = pyqtSignal(QTableWidgetItem)
  307. def __init__(self, parent = None):
  308. super(DmTableInventaire, self).__init__(parent)
  309. self._inventaire = []
  310. #pour la gestion des survols
  311. self.setMouseTracking(True)
  312. self._last_index = QPersistentModelIndex()
  313. self.viewport().installEventFilter(self)
  314. self.connect(self, SIGNAL("itemEntered(QTableWidgetItem*)"), self.itemSurvole)
  315. self.connect(self, SIGNAL("itemExited(QTableWidgetItem*)"), self.itemSurvoleFin)
  316. self.connect(self, SIGNAL("itemClicked(QTableWidgetItem*)"), self.itemClique)
  317. def construire(self):
  318. self.setColumnWidth(0, 20);self.setColumnWidth(1, 70)
  319. self.setColumnWidth(2, 241);self.setColumnWidth(4, 60)
  320. self.setColumnWidth(6, 20)
  321. def ajouterObjet(self, objet):
  322. ligne = self.rowCount() - 1 #avant la ligne 'ajouter'
  323. self.insertRow(ligne)
  324. self.remplirLigne(ligne, objet)
  325. self._inventaire.append(objet)
  326. def charger(self, inventaire):
  327. """charge l'inventaire en parametre"""
  328. for objet in inventaire:
  329. self.ajouterObjet(objet)
  330. def majObjet(self, ancien, nouveau):
  331. """maj la ligne correspondant a l'objet"""
  332. index = self._inventaire.index(ancien)
  333. self._inventaire[index] = nouveau
  334. self.remplirLigne(index, nouveau)
  335. def supprimerObjet(self, objet):
  336. """ajoute la ligne correspondant a l'objet"""
  337. index = self._inventaire.index(objet)
  338. self._inventaire.remove(objet)
  339. self.removeRow(index)
  340. def remplirLigne(self, ligne, objet):
  341. """remplit les cellules de la ligne avec les donnees de l'objet"""
  342. imgType = ["pieces.png", "btn_ModeCombat.png", "chimie.png", "diamant.png", "boite_outils.png"]
  343. self.creerItem(ligne, 0, "", imgType[objet.typeObjet])
  344. self.creerItem(ligne, 1, objet.quantite)
  345. self.creerItem(ligne, 2, objet.nom)
  346. self.creerItem(ligne, 3, objet.poidsTotal())
  347. self.creerItem(ligne, 4, "")
  348. def inventaire(self):
  349. """cree un inventaire a partir des donnees de la table"""
  350. return self._inventaire
  351. def itemSurvole(self, item):
  352. ligne = item.row()
  353. self.majCouleurLigne(ligne, QColor(150, 50, 50, 150))
  354. def itemSurvoleFin(self, item):
  355. ligne = item.row()
  356. self.majCouleurLigne(ligne, QColor(248, 248, 248, 150))
  357. def itemClique(self, item):
  358. ligne = item.row()
  359. self.emit(SIGNAL("objetClique(int)"), ligne)
  360. def majCouleurLigne(self, ligne, couleur):
  361. """modifie la couleur de fond des items de la lignes"""
  362. for col in self.colonnes():
  363. item = self.item(ligne, col)
  364. if item:
  365. item.setBackground(QBrush(couleur))
  366. def creerItem(self, ligne, colonne, txt, img = None):
  367. item = QTableWidgetItem()
  368. item.setFlags(Qt.NoItemFlags)
  369. item.setText(QString().fromUtf8(" {}".format(txt)))
  370. if img:
  371. pix = QPixmap("img\\{}".format(img))
  372. item.setIcon(QIcon(pix))
  373. self.setItem(ligne, colonne, item)
  374. def filtrer(self, typeObjet):
  375. """filtre l'affichage des lignes par type d'objet"""
  376. for ligne in range(0, self.rowCount() - 1):
  377. self.setRowHidden(ligne, typeObjet >= 0 and typeObjet != self._inventaire[ligne].typeObjet )
  378. def eventFilter(self, widget, event):
  379. if widget is self.viewport():
  380. index = self._last_index
  381. if event.type() == QEvent.MouseMove:
  382. index = self.indexAt(event.pos())
  383. elif event.type() == QEvent.Leave:
  384. index = QModelIndex()
  385. if index != self._last_index:
  386. row = self._last_index.row()
  387. column = self._last_index.column()
  388. item = self.item(row, column)
  389. if item is not None:
  390. self.itemExited.emit(item)
  391. self._last_index = QPersistentModelIndex(index)
  392. return QTableWidget.eventFilter(self, widget, event)
  393. class DmTableInventaireCombat(DmTableInventaire):
  394. """inventaire affiche dans le panneau de combat"""
  395. def __init__(self, parent = None):
  396. super(DmTableInventaireCombat, self).__init__(parent)
  397. class DmTableMenu(QTableWidget):
  398. """table utilisee comme barre d'onglets verticale"""
  399. def __init__(self, parent = None):
  400. super(DmTableMenu, self).__init__(parent)
  401. def setItem(self, ligne, colonne, item):
  402. super(DmTableMenu, self).setItem(ligne, colonne, item)
  403. if ligne == 0:
  404. self.setItemSelected(item, True)
  405. class DmFrameInf_Combattant(QGroupBox):
  406. """frame d'information (combattant)"""
  407. def __init__(self, parent = None):
  408. super(DmFrameInf_Combattant, self).__init__(parent)
  409. def maj(self, combattant):
  410. self.setVisible((combattant != None))
  411. if combattant:
  412. self.findChild(DmLabel, "inf_pionNom").majTexte(combattant.nom())
  413. self.findChild(DmLabel, "inf_pionImage").chargerImage(combattant.img.rimage)
  414. self.findChild(DmLabel, "inf_pionEffet").setVisible(False)
  415. class DmFrameInf_Decor(QGroupBox):
  416. """frame d'information (decor)"""
  417. def __init__(self, parent = None):
  418. super(DmFrameInf_Decor, self).__init__(parent)
  419. def maj(self, decor):
  420. self.setVisible((decor != None))
  421. if decor:
  422. self.findChild(DmLabel, "inf_decorNom").majTexte(decor.nom())
  423. self.findChild(DmLabel, "inf_decorImage").chargerImage(decor.img.rimage)
  424. class DmFrameInf_Case(QGroupBox):
  425. """frame d'information (case)"""
  426. def __init__(self, parent = None):
  427. super(DmFrameInf_Case, self).__init__(parent)
  428. def maj(self, case):
  429. self.setVisible((case != None))
  430. if len(case.terrain.nom()) > 0:
  431. self.findChild(DmLabel, "inf_caseTerrain").majTexte(case.terrain.nom())
  432. else:
  433. self.findChild(DmLabel, "inf_caseTerrain").majTexte("Case")
  434. self.findChild(DmLabel, "inf_caseCoord").majTexte("X: {} Y: {}".format(case.x, case.y))
  435. self.findChild(DmLabel, "inf_caseAltitude").majTexte("Altitude: {}".format(case.altitude))
  436. if case.effetActif not in ["", "aucun"]:
  437. imgEffet = {"brule": "feu_16.png", "eau": "eau_16.png","glace": "glace_16.png","poison": "poison_16.png"}
  438. pix = QPixmap(":/interface/16/ressource/{}".format(imgEffet[case.effetActif]))
  439. self.findChild(DmLabel, "inf_caseEffet").setPixmap(pix)
  440. else:
  441. self.findChild(DmLabel, "inf_caseEffet").clear()
  442. class DmFrame(QFrame):
  443. """surcharge de QFrame"""
  444. def __init__(self, parent = None):
  445. super(DmFrame, self).__init__(parent)