""" Gear Selector Dialog for Lemontropia Suite Uses Entropia Nexus API to search and select real gear. """ from PyQt6.QtWidgets import ( QDialog, QVBoxLayout, QHBoxLayout, QLabel, QLineEdit, QPushButton, QComboBox, QTreeWidget, QTreeWidgetItem, QDialogButtonBox, QTabWidget, QGroupBox, QFormLayout, QMessageBox, QHeaderView ) from PyQt6.QtCore import Qt, pyqtSignal from decimal import Decimal import asyncio from typing import Optional, List class GearSelectorDialog(QDialog): """Dialog for selecting gear from Entropia Nexus.""" gear_selected = pyqtSignal(str, str, dict) # type, name, stats def __init__(self, gear_type: str = "weapon", parent=None): super().__init__(parent) self.gear_type = gear_type # weapon, armor, tool self.selected_gear = None self.setWindowTitle(f"Select {gear_type.title()} - Entropia Nexus") self.setMinimumSize(700, 500) self.setup_ui() # Load initial data self.load_mock_data() # Use mock data for now def setup_ui(self): layout = QVBoxLayout(self) layout.setSpacing(10) # Search box search_layout = QHBoxLayout() search_layout.addWidget(QLabel("Search:")) self.search_input = QLineEdit() self.search_input.setPlaceholderText(f"Search for {self.gear_type}...") self.search_input.returnPressed.connect(self.on_search) search_layout.addWidget(self.search_input) self.search_btn = QPushButton("Search") self.search_btn.clicked.connect(self.on_search) search_layout.addWidget(self.search_btn) layout.addLayout(search_layout) # Results list self.results_tree = QTreeWidget() self.results_tree.setHeaderLabels(["Name", "Damage/Protection", "DPP/Cost", "Range/Depth"]) self.results_tree.setAlternatingRowColors(True) self.results_tree.setSelectionMode(QTreeWidget.SelectionMode.SingleSelection) self.results_tree.itemSelectionChanged.connect(self.on_selection_changed) self.results_tree.itemDoubleClicked.connect(self.on_item_double_clicked) # Adjust columns header = self.results_tree.header() header.setSectionResizeMode(0, QHeaderView.ResizeMode.Stretch) header.setSectionResizeMode(1, QHeaderView.ResizeMode.Fixed) header.setSectionResizeMode(2, QHeaderView.ResizeMode.Fixed) header.setSectionResizeMode(3, QHeaderView.ResizeMode.Fixed) header.resizeSection(1, 120) header.resizeSection(2, 100) header.resizeSection(3, 100) layout.addWidget(self.results_tree) # Stats preview self.stats_group = QGroupBox("Stats Preview") self.stats_layout = QFormLayout(self.stats_group) self.stats_layout.addRow("Select an item to view stats", QLabel("")) layout.addWidget(self.stats_group) # Buttons button_box = QDialogButtonBox( QDialogButtonBox.StandardButton.Ok | QDialogButtonBox.StandardButton.Cancel ) button_box.accepted.connect(self.on_accept) button_box.rejected.connect(self.reject) self.ok_btn = button_box.button(QDialogButtonBox.StandardButton.Ok) self.ok_btn.setEnabled(False) self.ok_btn.setText("Select Gear") layout.addWidget(button_box) def load_mock_data(self): """Load mock gear data for testing.""" from core.nexus_api import MOCK_WEAPONS, MOCK_ARMORS, MOCK_TOOLS self.results_tree.clear() if self.gear_type == "weapon": for weapon_id, weapon in MOCK_WEAPONS.items(): item = QTreeWidgetItem([ weapon.name, f"{weapon.damage}", f"{weapon.dpp}", f"{weapon.range}m" ]) item.setData(0, Qt.ItemDataRole.UserRole, { 'id': weapon_id, 'type': 'weapon', 'data': weapon }) self.results_tree.addTopLevelItem(item) elif self.gear_type == "armor": for armor_id, armor in MOCK_ARMORS.items(): total_prot = armor.get_total_protection() item = QTreeWidgetItem([ armor.name, f"{total_prot}", f"{armor.decay_pec} PEC", "-" ]) item.setData(0, Qt.ItemDataRole.UserRole, { 'id': armor_id, 'type': 'armor', 'data': armor }) self.results_tree.addTopLevelItem(item) elif self.gear_type == "tool": for tool_id, tool in MOCK_TOOLS.items(): item = QTreeWidgetItem([ tool.name, f"{tool.depth}m", f"{tool.decay_pec} PEC", f"{tool.radius}m" ]) item.setData(0, Qt.ItemDataRole.UserRole, { 'id': tool_id, 'type': 'tool', 'data': tool }) self.results_tree.addTopLevelItem(item) def on_search(self): """Search for gear.""" query = self.search_input.text().strip().lower() if not query: self.load_mock_data() return # Filter results for i in range(self.results_tree.topLevelItemCount()): item = self.results_tree.topLevelItem(i) name = item.text(0).lower() item.setHidden(query not in name) def on_selection_changed(self): """Handle selection change.""" selected = self.results_tree.selectedItems() if selected: item_data = selected[0].data(0, Qt.ItemDataRole.UserRole) self.selected_gear = item_data self.ok_btn.setEnabled(True) self.update_stats_preview(item_data) else: self.selected_gear = None self.ok_btn.setEnabled(False) def update_stats_preview(self, item_data): """Update stats preview.""" # Clear previous while self.stats_layout.rowCount() > 0: self.stats_layout.removeRow(0) gear = item_data['data'] if item_data['type'] == 'weapon': self.stats_layout.addRow("Damage:", QLabel(f"{gear.damage}")) self.stats_layout.addRow("DPP:", QLabel(f"{gear.dpp}")) self.stats_layout.addRow("Decay:", QLabel(f"{gear.decay_pec} PEC")) self.stats_layout.addRow("Ammo:", QLabel(f"{gear.ammo_pec} PEC")) self.stats_layout.addRow("Range:", QLabel(f"{gear.range}m")) self.stats_layout.addRow("Attacks/min:", QLabel(f"{gear.attacks_per_min}")) self.stats_layout.addRow("Cost/hour:", QLabel(f"{gear.calculate_cost_per_hour():.2f} PED")) elif item_data['type'] == 'armor': self.stats_layout.addRow("Decay:", QLabel(f"{gear.decay_pec} PEC")) self.stats_layout.addRow("Total Protection:", QLabel(f"{gear.get_total_protection()}")) for dmg_type, value in gear.protection.items(): self.stats_layout.addRow(f" {dmg_type.title()}:", QLabel(f"{value}")) elif item_data['type'] == 'tool': self.stats_layout.addRow("Type:", QLabel(f"{gear.tool_type}")) self.stats_layout.addRow("Depth:", QLabel(f"{gear.depth}m")) self.stats_layout.addRow("Radius:", QLabel(f"{gear.radius}m")) self.stats_layout.addRow("Decay:", QLabel(f"{gear.decay_pec} PEC")) if gear.probe_cost: self.stats_layout.addRow("Cost/drop:", QLabel(f"{gear.calculate_cost_per_drop():.3f} PED")) def on_item_double_clicked(self, item, column): """Handle double click.""" self.on_accept() def on_accept(self): """Handle OK button.""" if self.selected_gear: gear = self.selected_gear['data'] self.gear_selected.emit( self.selected_gear['type'], gear.name, { 'id': self.selected_gear['id'], 'dpp': getattr(gear, 'dpp', None), 'cost_per_hour': getattr(gear, 'calculate_cost_per_hour', lambda: 0)() } ) self.accept() if __name__ == "__main__": import sys from PyQt6.QtWidgets import QApplication app = QApplication(sys.argv) dialog = GearSelectorDialog("weapon") if dialog.exec() == QDialog.DialogCode.Accepted: print("Selected gear:", dialog.selected_gear) sys.exit(0)