124 lines
4.4 KiB
Python
124 lines
4.4 KiB
Python
"""Fila de la lista: icono, nombre, descripción y botones Download/Run."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from pathlib import Path
|
|
|
|
from PySide6.QtCore import Qt, Signal
|
|
from PySide6.QtGui import QPixmap
|
|
from PySide6.QtWidgets import (
|
|
QFrame,
|
|
QHBoxLayout,
|
|
QLabel,
|
|
QPushButton,
|
|
QSizePolicy,
|
|
QVBoxLayout,
|
|
)
|
|
|
|
from ..config import Game
|
|
from ..metadata import GameMeta, icon_path, load_meta
|
|
from ..paths import repo_dir
|
|
|
|
ICON_SIZE = 64
|
|
|
|
|
|
class GameRow(QFrame):
|
|
"""Widget de una fila. Emite señales cuando se pulsan los botones."""
|
|
|
|
download_requested = Signal(object) # Game
|
|
run_requested = Signal(object) # Game
|
|
|
|
def __init__(self, game: Game, root: Path, parent=None) -> None:
|
|
super().__init__(parent)
|
|
self.game = game
|
|
self.root = root
|
|
self.setObjectName("gameRow")
|
|
self.setFrameShape(QFrame.StyledPanel)
|
|
|
|
layout = QHBoxLayout(self)
|
|
layout.setContentsMargins(10, 8, 10, 8)
|
|
layout.setSpacing(12)
|
|
|
|
# --- Icono ---
|
|
self.icon_label = QLabel()
|
|
self.icon_label.setFixedSize(ICON_SIZE, ICON_SIZE)
|
|
self.icon_label.setAlignment(Qt.AlignCenter)
|
|
layout.addWidget(self.icon_label)
|
|
|
|
# --- Texto (nombre + descripción + estado) ---
|
|
text_box = QVBoxLayout()
|
|
text_box.setSpacing(2)
|
|
self.name_label = QLabel(game.name)
|
|
self.name_label.setStyleSheet("font-weight: bold; font-size: 14px;")
|
|
self.desc_label = QLabel("")
|
|
self.desc_label.setWordWrap(True)
|
|
self.desc_label.setStyleSheet("color: #aaaaaa;")
|
|
self.status_label = QLabel("")
|
|
self.status_label.setStyleSheet("color: #6fae6f; font-size: 11px;")
|
|
text_box.addWidget(self.name_label)
|
|
text_box.addWidget(self.desc_label)
|
|
text_box.addWidget(self.status_label)
|
|
text_box.addStretch(1)
|
|
layout.addLayout(text_box, stretch=1)
|
|
|
|
# --- Botones ---
|
|
self.download_btn = QPushButton("Download")
|
|
self.run_btn = QPushButton("Run")
|
|
for btn in (self.download_btn, self.run_btn):
|
|
btn.setMinimumWidth(96)
|
|
btn.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
|
|
self.download_btn.clicked.connect(lambda: self.download_requested.emit(self.game))
|
|
self.run_btn.clicked.connect(lambda: self.run_requested.emit(self.game))
|
|
btn_box = QVBoxLayout()
|
|
btn_box.addWidget(self.download_btn)
|
|
btn_box.addWidget(self.run_btn)
|
|
layout.addLayout(btn_box)
|
|
|
|
self.refresh()
|
|
|
|
# ----------------------------------------------------------------- estado
|
|
|
|
def refresh(self) -> None:
|
|
"""Recarga icono, descripción y estado desde la cache local."""
|
|
meta = load_meta(self.root, self.game.id)
|
|
self._set_icon()
|
|
self.desc_label.setText(meta.description or "(sin descripción todavía)")
|
|
self._set_status(meta)
|
|
|
|
def _set_icon(self) -> None:
|
|
path = icon_path(self.root, self.game.id)
|
|
pixmap = QPixmap(str(path)) if path.exists() else QPixmap()
|
|
if pixmap.isNull():
|
|
self.icon_label.setText("🎮")
|
|
self.icon_label.setStyleSheet("font-size: 32px;")
|
|
else:
|
|
self.icon_label.setStyleSheet("")
|
|
self.icon_label.setPixmap(
|
|
pixmap.scaled(
|
|
ICON_SIZE,
|
|
ICON_SIZE,
|
|
Qt.KeepAspectRatio,
|
|
Qt.SmoothTransformation,
|
|
)
|
|
)
|
|
|
|
def _set_status(self, meta: GameMeta) -> None:
|
|
installed = (repo_dir(self.root, self.game.id) / ".git").exists()
|
|
if not installed:
|
|
self.status_label.setText("No instalado")
|
|
self.status_label.setStyleSheet("color: #cc8855; font-size: 11px;")
|
|
self.run_btn.setEnabled(True) # se permite, avisará si no está
|
|
else:
|
|
ver = f" {meta.version}" if meta.version else ""
|
|
self.status_label.setText(f"Instalado{ver}")
|
|
self.status_label.setStyleSheet("color: #6fae6f; font-size: 11px;")
|
|
|
|
# --------------------------------------------------------------- busy UI
|
|
|
|
def set_busy(self, busy: bool, message: str = "") -> None:
|
|
self.download_btn.setEnabled(not busy)
|
|
self.run_btn.setEnabled(not busy)
|
|
if busy and message:
|
|
self.status_label.setText(message)
|
|
self.status_label.setStyleSheet("color: #d0d060; font-size: 11px;")
|