qt: better icons and bg thread
authorNiki Roo <niki@nikiroo.be>
Sun, 30 Mar 2025 10:35:53 +0000 (12:35 +0200)
committerNiki Roo <niki@nikiroo.be>
Sun, 30 Mar 2025 10:35:53 +0000 (12:35 +0200)
gamiki-qt.py
gamiki/qt/tiles.py

index 4d4991a78cdda221ea7a38b2c0a7af83f783afe4..e186280e0e75ac68a5345704b473bf27beeeac1d 100755 (executable)
@@ -9,12 +9,29 @@ from gamiki          import Builder, Library
 from gamiki.qt.utils import start
 from gamiki.qt.tiles import Grid, List
 
+mode = "list"
+
 class MainWindow(QWidget):
-    def __init__(self, centre: QWidget):
+    games = None
+    
+    def __init__(self):
         super().__init__()
-        self.initUi(centre)
+        self.initUi()
+        start(self)
+    
+    def run(self):
+        self.games = Builder().games
+        QTimer.singleShot(0, self._gamesLoaded)
+    
+    def _gamesLoaded(self):
+        if (mode == "list"):
+            centre = List(self.games)
+        else:
+            centre = Grid(self.games)
+        centre.onClick.connect(start)
+        self.layout.addWidget(centre)
     
-    def initUi(self, centre: QWidget):
+    def initUi(self):
         # Title/Icon
         self.setWindowTitle("Testy window")
         self.setWindowIcon(QIcon('gamiki.png'))
@@ -30,8 +47,8 @@ class MainWindow(QWidget):
         #self.setCentralWidget(centre)
         layout = QHBoxLayout()
         layout.setContentsMargins(0, 0, 0, 0)
-        layout.addWidget(centre)
         self.setLayout(layout)
+        self.layout = layout
 
         # Size and visibility
         self.resize(800, 600)
@@ -42,10 +59,8 @@ if __name__ == '__main__':
     
     app = QApplication(argv)
     
-    #centre = List(Builder().games)
-    centre = Grid(Builder().games)
-    centre.onClick.connect(start)
-    window = MainWindow(centre)
+    mode = "grid"
+    window = MainWindow()
     window.show()
     
     exit(app.exec_())
index 3c2fcab0c776c71bc08ea2b9701a829d60bf9cda..a61497edd9915463b84e97c450dc7f19c2b2bf7e 100755 (executable)
@@ -1,6 +1,7 @@
 #!/usr/bin/env python3
 
 # TODO: disable start() when one is running
+# TODO: default image
 
 from sys     import argv, exit
 from enum    import IntFlag
@@ -8,26 +9,60 @@ from pathlib import PurePath
 
 from gamiki                import Game
 from gamiki.qt.imports     import *
-from gamiki.qt.utils       import makeMouseAware
+from gamiki.qt.utils       import makeMouseAware, start
 from gamiki.qt.flow_layout import FlowLayout
 
 class ListItem(QWidget):
     onClick = pyqtSignal(Game)
 
-    def __init__(self, game: Game, coverSize: int = 0):
+    def __init__(self, game: Game, coverSize: int = 0, cover: str = None):
         super().__init__()
         
+        if (coverSize <= 0):
+            coverSize = 48
+        if (not cover):
+            cover = "icon"
+        
         self.game = game
-        self.coverSize = coverSize if (coverSize > 0) else 48  
+        self.coverSize = coverSize
         
         if (self.game.icon):
-            self.pixmap = QPixmap(self.game.get_icon("icon").as_posix())
+            self.imagePath = self.game.get_icon(cover).as_posix()
         else:
-            self.pixmap = QPixmap("")
-       
+            self.imagePath = ""
+        
         self.initUI()
         makeMouseAware(self, [self, self.cover])
     
+    def loadCover(self):
+        if (not self.imagePath):
+            return
+        
+        self.pixmap = QPixmap(self.imagePath)
+        w = self.pixmap.width()
+        h = self.pixmap.height()
+        
+        if ("mode" == "zoom"): # if you want it, change the code
+            if (w > h):
+                icon = self.pixmap.copy((w - h) // 2, 0, min(w, h), min(w, h))
+            else:
+                icon = self.pixmap.copy(0, (h - w) // 2, min(w, h), min(w, h))
+        else: # add black (transparent) bars
+            icon = QPixmap(max(w, h), max(w, h))
+            icon.fill(QColor(0, 0, 0, 0))
+            painter = QPainter(icon)
+            if (w > h):
+                painter.drawPixmap(0, (w - h) // 2, self.pixmap)
+            else:
+                painter.drawPixmap((h - w) // 2, 0, self.pixmap)
+            painter.end()
+        
+        self.icon = icon
+        QTimer.singleShot(0, self._loadCover)
+       
+    def _loadCover(self): 
+        self.cover.setPixmap(self.icon)
+    
     def initUI(self):
         self.line1 = QLabel(self.game.name)
         self.line1.setStyleSheet("font-size: 20px; font-weight: bold;")
@@ -42,15 +77,6 @@ class ListItem(QWidget):
         self.cover.setMinimumSize(self.coverSize, self.coverSize)
         self.cover.setMaximumSize(self.coverSize, self.coverSize)
         
-        w = self.pixmap.width()
-        h = self.pixmap.height()
-        crop = self.pixmap.copy(
-            int((w - h) / 2) if w > h else 0, 
-            int((h - w) / 2) if h > w else 0, 
-            min(w, h), min(w, h)
-        )
-        self.cover.setPixmap(crop)
-        
         line1sub = QWidget()
         hlay = QHBoxLayout()
         hlay.setContentsMargins(0, 0, 0, 0)
@@ -76,24 +102,20 @@ class ListItem(QWidget):
         if event.button() == Qt.LeftButton:
             self.onClick.emit(self.game)
 
-class GridItem(QWidget):
-    onClick = pyqtSignal(Game)
-
-    def __init__(self, game: Game, coverSize: int = 0, fixed: bool = False):
-        super().__init__()
+class GridItem(ListItem):
+    def __init__(
+            self, game: Game, coverSize: int = 0, cover: str = None, 
+            fixed: bool = False
+    ):
+        
+        if (coverSize <= 0):
+            coverSize = 200
+        if (not cover):
+            cover = "square"
         
-        self.game = game
-        self.coverSize = coverSize if (coverSize > 0) else 200 
         self.fixed = fixed
+        super().__init__(game, coverSize, cover)
         
-        if (self.game.icon):
-            self.pixmap = QPixmap(self.game.get_icon("square").as_posix())
-        else:
-            self.pixmap = QPixmap("")
-       
-        self.initUI()
-        makeMouseAware(self, [self, self.cover])
-    
     def initUI(self):
         self.line1 = QLabel(self.game.name)
         self.line1.setStyleSheet("font-size: 20px; font-weight: bold;")
@@ -108,15 +130,6 @@ class GridItem(QWidget):
         self.cover.setMinimumSize(self.coverSize, self.coverSize)
         self.cover.setMaximumSize(self.coverSize, self.coverSize)
         
-        w = self.pixmap.width()
-        h = self.pixmap.height()
-        crop = self.pixmap.copy(
-            int((w - h) / 2) if w > h else 0, 
-            int((h - w) / 2) if h > w else 0, 
-            min(w, h), min(w, h)
-        )
-        self.cover.setPixmap(crop)
-        
         line1sub = QWidget()
         hlay = QHBoxLayout()
         hlay.setContentsMargins(0, 0, 0, 0)
@@ -156,10 +169,6 @@ class GridItem(QWidget):
         self.line2.setMinimumWidth(self.coverSize)
         super().resizeEvent(event)
 
-    def mouseReleaseEvent(self, event):
-        if event.button() == Qt.LeftButton:
-            self.onClick.emit(self.game)
-
 class List(QWidget):
     onClick = pyqtSignal(Game)
 
@@ -168,22 +177,34 @@ class List(QWidget):
         
         self.games = games
         self.icon_size = icon_size
+        self.covers = []
         
         self.initUI()
+        
+        start(self)
+    
+    def run(self):
+        for cover in self.covers:
+            cover.loadCover()
     
     def initUI(self):
         area = QWidget()
         layout = QVBoxLayout(area)
         layout.setContentsMargins(0, 0, 0, 0)
+        self.layout = layout
         
         for game in self.games:
             cover = ListItem(game, self.icon_size)
-            cover.onClick.connect(lambda game: self.onClick.emit(game))
-            layout.addWidget(cover)
+            self.addCover(cover)
         layout.addStretch()
         
         self._setScrollLayout(area)
     
+    def addCover(self, cover: ListItem):
+        self.covers.append(cover)
+        cover.onClick.connect(lambda game: self.onClick.emit(game))
+        self.layout.addWidget(cover)
+    
     def _setScrollLayout(self, area):
         layout = QVBoxLayout()
         layout.setContentsMargins(0, 0, 0, 0)
@@ -194,17 +215,17 @@ class List(QWidget):
     
         layout.addWidget(scroll)
     
-        self.setLayout(layout)    
+        self.setLayout(layout)
     
 class Grid(List):
     def initUI(self):
         area = QWidget()
         layout = FlowLayout(area)
+        self.layout = layout
         
         for game in self.games:
-            cover = GridItem(game, self.icon_size, True)
-            cover.onClick.connect(lambda game: self.onClick.emit(game))
-            layout.addWidget(cover)
+            cover = GridItem(game, self.icon_size, None, True)
+            self.addCover(cover)
         
         self._setScrollLayout(area)
 
@@ -220,10 +241,10 @@ if __name__ == '__main__':
      
     #game_widget1 = ListItem(game1) ; game_widget1.show()
     #game_widget2 = GridItem(game3) ; game_widget2.show()
-    list1 = List([ game1, game2, game3 ]) ; list1.show()
+    #list1 = List([ game1, game2, game3 ]) ; list1.show()
     grid = Grid([ game1, game2, game3 ]) ; grid.show()  
     
-    list1.onClick.connect(lambda game: print("LIST:", game.name))
+    #list1.onClick.connect(lambda game: print("LIST1:", game.name))
     grid.onClick.connect(lambda game: print("GRID:", game.name))
 
     exit(app.exec_())