Lemontropia-Suite/ui/armor_selector.py

204 lines
6.8 KiB
Python

"""
Lemontropia Suite - Simple Armor Selector
Quick armor selection for cost configuration.
"""
import logging
from decimal import Decimal
from PyQt6.QtWidgets import (
QDialog, QVBoxLayout, QHBoxLayout, QLabel,
QPushButton, QLineEdit, QListWidget, QListWidgetItem,
QMessageBox, QFormLayout, QGroupBox
)
from PyQt6.QtCore import Qt, pyqtSignal
from core.nexus_full_api import get_nexus_api
logger = logging.getLogger(__name__)
class ArmorSelectorDialog(QDialog):
"""Simple dialog to select armor for cost tracking."""
def __init__(self, parent=None):
super().__init__(parent)
self.setWindowTitle("Select Armor")
self.setMinimumSize(500, 400)
self.selected_armor = None
self._armors = []
self._setup_ui()
self._load_armors()
def _setup_ui(self):
"""Setup simple UI."""
layout = QVBoxLayout(self)
layout.setSpacing(10)
# Search
search_layout = QHBoxLayout()
search_layout.addWidget(QLabel("Search:"))
self.search_edit = QLineEdit()
self.search_edit.setPlaceholderText("Type armor name...")
self.search_edit.textChanged.connect(self._on_search)
search_layout.addWidget(self.search_edit)
layout.addLayout(search_layout)
# Armor list
self.armor_list = QListWidget()
self.armor_list.itemClicked.connect(self._on_select)
self.armor_list.itemDoubleClicked.connect(self._on_double_click)
layout.addWidget(self.armor_list)
# Preview
preview_group = QGroupBox("Selected Armor")
preview_layout = QFormLayout(preview_group)
self.preview_name = QLabel("None")
preview_layout.addRow("Name:", self.preview_name)
self.preview_protection = QLabel("-")
preview_layout.addRow("Protection:", self.preview_protection)
self.preview_decay = QLabel("-")
preview_layout.addRow("Decay/Hit:", self.preview_decay)
self.preview_cost = QLabel("-")
self.preview_cost.setStyleSheet("font-weight: bold; color: #7FFF7F;")
preview_layout.addRow("Cost/Hit:", self.preview_cost)
layout.addWidget(preview_group)
# Buttons
button_layout = QHBoxLayout()
button_layout.addStretch()
self.ok_btn = QPushButton("Select")
self.ok_btn.clicked.connect(self.accept)
self.ok_btn.setEnabled(False)
self.ok_btn.setStyleSheet("""
QPushButton {
background-color: #2E7D32;
color: white;
padding: 8px 16px;
font-weight: bold;
}
QPushButton:disabled {
background-color: #333;
color: #666;
}
""")
button_layout.addWidget(self.ok_btn)
cancel_btn = QPushButton("Cancel")
cancel_btn.clicked.connect(self.reject)
button_layout.addWidget(cancel_btn)
layout.addLayout(button_layout)
def _load_armors(self):
"""Load armors from API."""
try:
nexus = get_nexus_api()
# Get armor sets from API
self._armors = nexus.get_all_armor_sets()
# Sort by name
self._armors.sort(key=lambda a: a.name.lower())
self._populate_list(self._armors)
except Exception as e:
logger.error(f"Failed to load armors: {e}")
QMessageBox.warning(self, "Error", f"Failed to load armors: {e}")
def _populate_list(self, armors):
"""Populate list with armors."""
self.armor_list.clear()
for armor in armors:
# Get decay from Defense field if available
decay_pec = Decimal("0")
if hasattr(armor, 'defense') and armor.defense:
# Estimate decay based on protection level
# Higher protection = higher decay
decay_pec = Decimal("15") # Default estimate
cost_per_hit = decay_pec / Decimal("100")
item = QListWidgetItem(f"{armor.name}")
item.setData(Qt.ItemDataRole.UserRole, armor)
# Tooltip with protection info
tooltip_parts = [f"Set ID: {armor.id}"]
if hasattr(armor, 'defense') and armor.defense:
tooltip_parts.append(f"Defense: {armor.defense}")
tooltip_parts.append(f"Est. Decay: {decay_pec} PEC")
tooltip_parts.append(f"Est. Cost/Hit: {cost_per_hit:.4f} PED")
item.setToolTip("\n".join(tooltip_parts))
self.armor_list.addItem(item)
def _on_search(self, text):
"""Filter armors by search text."""
if not text:
self._populate_list(self._armors)
return
text_lower = text.lower()
filtered = [a for a in self._armors if text_lower in a.name.lower()]
self._populate_list(filtered)
def _on_select(self, item):
"""Update preview when armor selected."""
armor = item.data(Qt.ItemDataRole.UserRole)
if not armor:
return
self.selected_armor = armor
# Estimate decay (we'll need to calculate this properly)
decay_pec = self._estimate_decay(armor)
cost_per_hit = decay_pec / Decimal("100")
# Update preview
self.preview_name.setText(armor.name)
protection_text = "See tooltip"
if hasattr(armor, 'defense') and armor.defense:
protection_text = str(armor.defense)[:50]
self.preview_protection.setText(protection_text)
self.preview_decay.setText(f"{decay_pec} PEC (estimated)")
self.preview_cost.setText(f"{cost_per_hit:.4f} PED")
self.ok_btn.setEnabled(True)
def _estimate_decay(self, armor):
"""Estimate decay based on armor protection."""
# This is a simplified estimate - real decay comes from API data
# For now, return a default value
# TODO: Get real decay from armor pieces or set data
return Decimal("15")
def _on_double_click(self, item):
"""Double-click to select immediately."""
self._on_select(item)
self.accept()
def get_selected_armor(self):
"""Get the selected armor as a dict for the simplified system."""
if not self.selected_armor:
return None
decay_pec = self._estimate_decay(self.selected_armor)
return {
'name': self.selected_armor.name,
'api_id': getattr(self.selected_armor, 'id', None),
'decay_pec': decay_pec,
'protection_summary': str(getattr(self.selected_armor, 'defense', 'Unknown')),
}