feat(hud): integrate loadout-based cost tracking in HUD
- Added LoadoutSelectionDialog for choosing loadout when starting session - Added set_cost_tracker() method to HUDOverlay for SessionCostTracker integration - Added new display row for loadout metrics: $/shot, $/hit, $/heal, hits, heals - Added mindforce cost support - Updated start_session() to accept loadout_id and per-action costs - Updated _refresh_display() to show new cost metrics
This commit is contained in:
parent
af624b26e0
commit
1b176b96a8
|
|
@ -279,6 +279,9 @@ class HUDOverlay(QWidget):
|
||||||
# Armor decay tracker (imported here to avoid circular imports)
|
# Armor decay tracker (imported here to avoid circular imports)
|
||||||
self._armor_tracker = None
|
self._armor_tracker = None
|
||||||
|
|
||||||
|
# Session cost tracker for loadout-based tracking
|
||||||
|
self._cost_tracker = None
|
||||||
|
|
||||||
# Drag state
|
# Drag state
|
||||||
self._dragging = False
|
self._dragging = False
|
||||||
self._drag_offset = QPoint()
|
self._drag_offset = QPoint()
|
||||||
|
|
@ -607,6 +610,71 @@ class HUDOverlay(QWidget):
|
||||||
|
|
||||||
layout.addLayout(row3)
|
layout.addLayout(row3)
|
||||||
|
|
||||||
|
# === LOADOUT COST METRICS ROW ===
|
||||||
|
row4 = QHBoxLayout()
|
||||||
|
|
||||||
|
# Cost per shot
|
||||||
|
cps_layout = QVBoxLayout()
|
||||||
|
cps_label = QLabel("$/SHOT")
|
||||||
|
cps_label.setStyleSheet("font-size: 8px; color: #888888;")
|
||||||
|
cps_layout.addWidget(cps_label)
|
||||||
|
|
||||||
|
self.cps_value_label = QLabel("0.00")
|
||||||
|
self.cps_value_label.setStyleSheet("font-size: 10px; color: #FFAAAA;")
|
||||||
|
cps_layout.addWidget(self.cps_value_label)
|
||||||
|
|
||||||
|
row4.addLayout(cps_layout)
|
||||||
|
|
||||||
|
# Cost per hit
|
||||||
|
cph_layout = QVBoxLayout()
|
||||||
|
cph_label = QLabel("$/HIT")
|
||||||
|
cph_label.setStyleSheet("font-size: 8px; color: #888888;")
|
||||||
|
cph_layout.addWidget(cph_label)
|
||||||
|
|
||||||
|
self.cph_value_label = QLabel("0.00")
|
||||||
|
self.cph_value_label.setStyleSheet("font-size: 10px; color: #FFAAAA;")
|
||||||
|
cph_layout.addWidget(self.cph_value_label)
|
||||||
|
|
||||||
|
row4.addLayout(cph_layout)
|
||||||
|
|
||||||
|
# Cost per heal
|
||||||
|
cphl_layout = QVBoxLayout()
|
||||||
|
cphl_label = QLabel("$/HEAL")
|
||||||
|
cphl_label.setStyleSheet("font-size: 8px; color: #888888;")
|
||||||
|
cphl_layout.addWidget(cphl_label)
|
||||||
|
|
||||||
|
self.cphl_value_label = QLabel("0.00")
|
||||||
|
self.cphl_value_label.setStyleSheet("font-size: 10px; color: #FFAAAA;")
|
||||||
|
cphl_layout.addWidget(self.cphl_value_label)
|
||||||
|
|
||||||
|
row4.addLayout(cphl_layout)
|
||||||
|
|
||||||
|
# Hits taken
|
||||||
|
hits_layout = QVBoxLayout()
|
||||||
|
hits_label = QLabel("HITS")
|
||||||
|
hits_label.setStyleSheet("font-size: 8px; color: #888888;")
|
||||||
|
hits_layout.addWidget(hits_label)
|
||||||
|
|
||||||
|
self.hits_value_label = QLabel("0")
|
||||||
|
self.hits_value_label.setStyleSheet("font-size: 10px; color: #FFD700;")
|
||||||
|
hits_layout.addWidget(self.hits_value_label)
|
||||||
|
|
||||||
|
row4.addLayout(hits_layout)
|
||||||
|
|
||||||
|
# Heals used
|
||||||
|
heals_layout = QVBoxLayout()
|
||||||
|
heals_label = QLabel("HEALS")
|
||||||
|
heals_label.setStyleSheet("font-size: 8px; color: #888888;")
|
||||||
|
heals_layout.addWidget(heals_label)
|
||||||
|
|
||||||
|
self.heals_value_label = QLabel("0")
|
||||||
|
self.heals_value_label.setStyleSheet("font-size: 10px; color: #FFD700;")
|
||||||
|
heals_layout.addWidget(self.heals_value_label)
|
||||||
|
|
||||||
|
row4.addLayout(heals_layout)
|
||||||
|
|
||||||
|
layout.addLayout(row4)
|
||||||
|
|
||||||
# === EQUIPMENT INFO ===
|
# === EQUIPMENT INFO ===
|
||||||
equip_separator = QFrame()
|
equip_separator = QFrame()
|
||||||
equip_separator.setFrameShape(QFrame.Shape.HLine)
|
equip_separator.setFrameShape(QFrame.Shape.HLine)
|
||||||
|
|
@ -794,9 +862,13 @@ class HUDOverlay(QWidget):
|
||||||
weapon_cost_per_hour: Decimal = Decimal('0.0'),
|
weapon_cost_per_hour: Decimal = Decimal('0.0'),
|
||||||
armor: str = "None",
|
armor: str = "None",
|
||||||
armor_durability: int = 2000,
|
armor_durability: int = 2000,
|
||||||
fap: str = "None") -> None:
|
fap: str = "None",
|
||||||
|
loadout_id: Optional[int] = None,
|
||||||
|
cost_per_shot: Decimal = Decimal('0.0'),
|
||||||
|
cost_per_hit: Decimal = Decimal('0.0'),
|
||||||
|
cost_per_heal: Decimal = Decimal('0.0')) -> None:
|
||||||
"""
|
"""
|
||||||
Start a new hunting session.
|
Start a new hunting session with loadout-based cost tracking.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
weapon: Name of the current weapon
|
weapon: Name of the current weapon
|
||||||
|
|
@ -806,16 +878,24 @@ class HUDOverlay(QWidget):
|
||||||
armor: Name of the equipped armor
|
armor: Name of the equipped armor
|
||||||
armor_durability: Armor durability rating
|
armor_durability: Armor durability rating
|
||||||
fap: Name of the equipped FAP
|
fap: Name of the equipped FAP
|
||||||
|
loadout_id: Database ID of the loadout configuration
|
||||||
|
cost_per_shot: Cost per weapon shot from loadout
|
||||||
|
cost_per_hit: Cost per armor hit from loadout
|
||||||
|
cost_per_heal: Cost per heal from loadout
|
||||||
"""
|
"""
|
||||||
self._session_start = datetime.now()
|
self._session_start = datetime.now()
|
||||||
self._stats = HUDStats()
|
self._stats = HUDStats()
|
||||||
self._stats.current_weapon = weapon
|
self._stats.current_weapon = weapon
|
||||||
self._stats.current_loadout = loadout
|
self._stats.current_loadout = loadout
|
||||||
|
self._stats.loadout_id = loadout_id
|
||||||
self._stats.current_armor = armor
|
self._stats.current_armor = armor
|
||||||
self._stats.current_fap = fap
|
self._stats.current_fap = fap
|
||||||
self._stats.weapon_dpp = weapon_dpp
|
self._stats.weapon_dpp = weapon_dpp
|
||||||
self._stats.weapon_cost_per_hour = weapon_cost_per_hour
|
self._stats.weapon_cost_per_hour = weapon_cost_per_hour
|
||||||
self._stats.armor_durability = armor_durability
|
self._stats.armor_durability = armor_durability
|
||||||
|
self._stats.cost_per_shot = cost_per_shot
|
||||||
|
self._stats.cost_per_hit = cost_per_hit
|
||||||
|
self._stats.cost_per_heal = cost_per_heal
|
||||||
self.session_active = True
|
self.session_active = True
|
||||||
|
|
||||||
# Initialize armor decay tracker
|
# Initialize armor decay tracker
|
||||||
|
|
@ -831,13 +911,42 @@ class HUDOverlay(QWidget):
|
||||||
self.status_label.setText("● Live - Recording")
|
self.status_label.setText("● Live - Recording")
|
||||||
self.status_label.setStyleSheet("font-size: 9px; color: #7FFF7F;")
|
self.status_label.setStyleSheet("font-size: 9px; color: #7FFF7F;")
|
||||||
|
|
||||||
|
def set_cost_tracker(self, cost_tracker: 'SessionCostTracker') -> None:
|
||||||
|
"""
|
||||||
|
Connect to a SessionCostTracker for real-time cost updates.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
cost_tracker: SessionCostTracker instance
|
||||||
|
"""
|
||||||
|
self._cost_tracker = cost_tracker
|
||||||
|
cost_tracker.register_callback(self._on_cost_update)
|
||||||
|
|
||||||
|
def _on_cost_update(self, state: 'SessionCostState') -> None:
|
||||||
|
"""Handle cost update from SessionCostTracker."""
|
||||||
|
if not self.session_active:
|
||||||
|
return
|
||||||
|
|
||||||
|
# Update stats from cost tracker state
|
||||||
|
self._stats.weapon_cost_total = state.weapon_cost
|
||||||
|
self._stats.armor_cost_total = state.armor_cost
|
||||||
|
self._stats.healing_cost_total = state.healing_cost
|
||||||
|
self._stats.enhancer_cost_total = state.enhancer_cost
|
||||||
|
self._stats.mindforce_cost_total = state.mindforce_cost
|
||||||
|
self._stats.shots_fired = state.shots_fired
|
||||||
|
self._stats.hits_taken = state.hits_taken
|
||||||
|
self._stats.heals_used = state.heals_used
|
||||||
|
|
||||||
|
self._stats.recalculate()
|
||||||
|
self._refresh_display()
|
||||||
|
self.stats_updated.emit(self._stats.to_dict())
|
||||||
|
|
||||||
def update_cost(self, cost_ped: Decimal, cost_type: str = 'weapon') -> None:
|
def update_cost(self, cost_ped: Decimal, cost_type: str = 'weapon') -> None:
|
||||||
"""
|
"""
|
||||||
Update total cost spent.
|
Update total cost spent.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
cost_ped: Cost in PED to add
|
cost_ped: Cost in PED to add
|
||||||
cost_type: Type of cost ('weapon', 'armor', 'healing', 'plates', 'enhancer')
|
cost_type: Type of cost ('weapon', 'armor', 'healing', 'plates', 'enhancer', 'mindforce')
|
||||||
"""
|
"""
|
||||||
if not self.session_active:
|
if not self.session_active:
|
||||||
return
|
return
|
||||||
|
|
@ -852,6 +961,8 @@ class HUDOverlay(QWidget):
|
||||||
self._stats.plates_cost_total += cost_ped
|
self._stats.plates_cost_total += cost_ped
|
||||||
elif cost_type == 'enhancer':
|
elif cost_type == 'enhancer':
|
||||||
self._stats.enhancer_cost_total += cost_ped
|
self._stats.enhancer_cost_total += cost_ped
|
||||||
|
elif cost_type == 'mindforce':
|
||||||
|
self._stats.mindforce_cost_total += cost_ped
|
||||||
|
|
||||||
self._stats.recalculate()
|
self._stats.recalculate()
|
||||||
self._refresh_display()
|
self._refresh_display()
|
||||||
|
|
@ -1167,6 +1278,13 @@ class HUDOverlay(QWidget):
|
||||||
self.heal_cost_value_label.setText(f"{self._stats.healing_cost_total:.2f}")
|
self.heal_cost_value_label.setText(f"{self._stats.healing_cost_total:.2f}")
|
||||||
self.cpk_value_label.setText(f"{self._stats.cost_per_kill:.2f}")
|
self.cpk_value_label.setText(f"{self._stats.cost_per_kill:.2f}")
|
||||||
|
|
||||||
|
# Loadout cost metrics
|
||||||
|
self.cps_value_label.setText(f"{self._stats.cost_per_shot:.3f}")
|
||||||
|
self.cph_value_label.setText(f"{self._stats.cost_per_hit:.3f}")
|
||||||
|
self.cphl_value_label.setText(f"{self._stats.cost_per_heal:.3f}")
|
||||||
|
self.hits_value_label.setText(str(self._stats.hits_taken))
|
||||||
|
self.heals_value_label.setText(str(self._stats.heals_used))
|
||||||
|
|
||||||
# Equipment info
|
# Equipment info
|
||||||
weapon_short = self._stats.current_weapon[:12] if len(self._stats.current_weapon) > 12 else self._stats.current_weapon
|
weapon_short = self._stats.current_weapon[:12] if len(self._stats.current_weapon) > 12 else self._stats.current_weapon
|
||||||
armor_short = self._stats.current_armor[:12] if len(self._stats.current_armor) > 12 else self._stats.current_armor
|
armor_short = self._stats.current_armor[:12] if len(self._stats.current_armor) > 12 else self._stats.current_armor
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,254 @@
|
||||||
|
# Description: Loadout selection dialog for hunting sessions
|
||||||
|
# Allows choosing a loadout when starting a new session
|
||||||
|
# Standards: Python 3.11+, PyQt6, type hints
|
||||||
|
|
||||||
|
from decimal import Decimal
|
||||||
|
from PyQt6.QtWidgets import (
|
||||||
|
QDialog, QVBoxLayout, QHBoxLayout, QLabel, QPushButton,
|
||||||
|
QListWidget, QListWidgetItem, QDialogButtonBox, QGroupBox,
|
||||||
|
QFormLayout, QMessageBox
|
||||||
|
)
|
||||||
|
from PyQt6.QtCore import Qt, pyqtSignal
|
||||||
|
from typing import Optional, Dict, Any, List
|
||||||
|
|
||||||
|
from core.loadout_db import LoadoutDatabase
|
||||||
|
from core.database import DatabaseManager
|
||||||
|
|
||||||
|
|
||||||
|
class LoadoutSelectionDialog(QDialog):
|
||||||
|
"""
|
||||||
|
Dialog for selecting a loadout when starting a hunting session.
|
||||||
|
|
||||||
|
Shows saved loadouts with their per-action cost metrics.
|
||||||
|
"""
|
||||||
|
|
||||||
|
loadout_selected = pyqtSignal(int, str) # loadout_id, loadout_name
|
||||||
|
|
||||||
|
def __init__(self, parent=None, db_manager: Optional[DatabaseManager] = None):
|
||||||
|
"""
|
||||||
|
Initialize loadout selection dialog.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
parent: Parent widget
|
||||||
|
db_manager: Optional database manager
|
||||||
|
"""
|
||||||
|
super().__init__(parent)
|
||||||
|
self.setWindowTitle("Select Loadout - Hunting Session")
|
||||||
|
self.setMinimumSize(500, 400)
|
||||||
|
|
||||||
|
self.db = db_manager or DatabaseManager()
|
||||||
|
self.loadout_db = LoadoutDatabase(self.db)
|
||||||
|
|
||||||
|
self.selected_loadout_id: Optional[int] = None
|
||||||
|
self.selected_loadout_name: Optional[str] = None
|
||||||
|
|
||||||
|
self._setup_ui()
|
||||||
|
self._load_loadouts()
|
||||||
|
|
||||||
|
def _setup_ui(self):
|
||||||
|
"""Setup the dialog UI."""
|
||||||
|
layout = QVBoxLayout(self)
|
||||||
|
layout.setSpacing(10)
|
||||||
|
|
||||||
|
# Header
|
||||||
|
header = QLabel("⚙️ Select Your Hunting Loadout")
|
||||||
|
header.setStyleSheet("font-size: 16px; font-weight: bold; color: #FFD700;")
|
||||||
|
layout.addWidget(header)
|
||||||
|
|
||||||
|
description = QLabel(
|
||||||
|
"Choose a loadout to track your costs accurately during this hunting session.\n"
|
||||||
|
"Costs will be calculated based on your configured gear."
|
||||||
|
)
|
||||||
|
description.setStyleSheet("color: #888888;")
|
||||||
|
description.setWordWrap(True)
|
||||||
|
layout.addWidget(description)
|
||||||
|
|
||||||
|
# Loadout list
|
||||||
|
self.loadout_list = QListWidget()
|
||||||
|
self.loadout_list.setAlternatingRowColors(True)
|
||||||
|
self.loadout_list.itemSelectionChanged.connect(self._on_selection_changed)
|
||||||
|
self.loadout_list.itemDoubleClicked.connect(self._on_double_click)
|
||||||
|
layout.addWidget(self.loadout_list)
|
||||||
|
|
||||||
|
# Preview panel
|
||||||
|
self.preview_group = QGroupBox("Loadout Details")
|
||||||
|
preview_layout = QFormLayout(self.preview_group)
|
||||||
|
|
||||||
|
self.preview_weapon = QLabel("-")
|
||||||
|
self.preview_armor = QLabel("-")
|
||||||
|
self.preview_healing = QLabel("-")
|
||||||
|
self.preview_cost_shot = QLabel("-")
|
||||||
|
self.preview_cost_hit = QLabel("-")
|
||||||
|
self.preview_cost_heal = QLabel("-")
|
||||||
|
|
||||||
|
preview_layout.addRow("🗡️ Weapon:", self.preview_weapon)
|
||||||
|
preview_layout.addRow("🛡️ Armor:", self.preview_armor)
|
||||||
|
preview_layout.addRow("💚 Healing:", self.preview_healing)
|
||||||
|
preview_layout.addRow("💰 Cost/Shot:", self.preview_cost_shot)
|
||||||
|
preview_layout.addRow("💰 Cost/Hit:", self.preview_cost_hit)
|
||||||
|
preview_layout.addRow("💰 Cost/Heal:", self.preview_cost_heal)
|
||||||
|
|
||||||
|
layout.addWidget(self.preview_group)
|
||||||
|
|
||||||
|
# Buttons
|
||||||
|
buttons = QDialogButtonBox(
|
||||||
|
QDialogButtonBox.StandardButton.Ok | QDialogButtonBox.StandardButton.Cancel
|
||||||
|
)
|
||||||
|
buttons.accepted.connect(self._on_accept)
|
||||||
|
buttons.rejected.connect(self.reject)
|
||||||
|
|
||||||
|
self.ok_button = buttons.button(QDialogButtonBox.StandardButton.Ok)
|
||||||
|
self.ok_button.setText("Start Session")
|
||||||
|
self.ok_button.setEnabled(False)
|
||||||
|
|
||||||
|
# Add "No Loadout" option button
|
||||||
|
no_loadout_btn = QPushButton("Skip (No Loadout)")
|
||||||
|
no_loadout_btn.setToolTip("Start session without cost tracking")
|
||||||
|
no_loadout_btn.clicked.connect(self._on_no_loadout)
|
||||||
|
|
||||||
|
btn_layout = QHBoxLayout()
|
||||||
|
btn_layout.addWidget(no_loadout_btn)
|
||||||
|
btn_layout.addStretch()
|
||||||
|
btn_layout.addWidget(buttons)
|
||||||
|
|
||||||
|
layout.addLayout(btn_layout)
|
||||||
|
|
||||||
|
def _load_loadouts(self):
|
||||||
|
"""Load saved loadouts from database."""
|
||||||
|
loadouts = self.loadout_db.list_loadouts()
|
||||||
|
|
||||||
|
if not loadouts:
|
||||||
|
# No loadouts saved
|
||||||
|
item = QListWidgetItem("No loadouts saved yet")
|
||||||
|
item.setFlags(item.flags() & ~Qt.ItemFlag.ItemIsSelectable)
|
||||||
|
item.setForeground(Qt.GlobalColor.gray)
|
||||||
|
self.loadout_list.addItem(item)
|
||||||
|
return
|
||||||
|
|
||||||
|
for loadout in loadouts:
|
||||||
|
item = QListWidgetItem()
|
||||||
|
item.setText(loadout['name'])
|
||||||
|
|
||||||
|
# Build tooltip with gear info
|
||||||
|
tooltip = f"Weapon: {loadout['weapon_name'] or 'None'}\n"
|
||||||
|
tooltip += f"Armor: {loadout['armor_name'] or 'None'}\n"
|
||||||
|
tooltip += f"Healing: {loadout['healing_tool_name'] or 'None'}\n"
|
||||||
|
tooltip += f"Cost/Shot: {loadout['cost_per_shot_ped']:.4f} PED\n"
|
||||||
|
tooltip += f"Cost/Hit: {loadout['cost_per_hit_ped']:.4f} PED\n"
|
||||||
|
tooltip += f"Cost/Heal: {loadout['cost_per_heal_ped']:.4f} PED"
|
||||||
|
item.setToolTip(tooltip)
|
||||||
|
|
||||||
|
# Store loadout ID
|
||||||
|
item.setData(Qt.ItemDataRole.UserRole, loadout['id'])
|
||||||
|
|
||||||
|
# Highlight active loadout
|
||||||
|
if loadout.get('is_active'):
|
||||||
|
item.setText(f"⭐ {loadout['name']} (Active)")
|
||||||
|
font = item.font()
|
||||||
|
font.setBold(True)
|
||||||
|
item.setFont(font)
|
||||||
|
|
||||||
|
self.loadout_list.addItem(item)
|
||||||
|
|
||||||
|
def _on_selection_changed(self):
|
||||||
|
"""Handle loadout selection change."""
|
||||||
|
items = self.loadout_list.selectedItems()
|
||||||
|
if not items:
|
||||||
|
self.ok_button.setEnabled(False)
|
||||||
|
self._clear_preview()
|
||||||
|
return
|
||||||
|
|
||||||
|
item = items[0]
|
||||||
|
loadout_id = item.data(Qt.ItemDataRole.UserRole)
|
||||||
|
|
||||||
|
if loadout_id is None:
|
||||||
|
self.ok_button.setEnabled(False)
|
||||||
|
return
|
||||||
|
|
||||||
|
self.selected_loadout_id = loadout_id
|
||||||
|
self.selected_loadout_name = item.text().replace("⭐ ", "").replace(" (Active)", "")
|
||||||
|
|
||||||
|
# Load and display preview
|
||||||
|
loadout = self.loadout_db.get_loadout(self.selected_loadout_name)
|
||||||
|
if loadout:
|
||||||
|
self._update_preview(loadout)
|
||||||
|
self.ok_button.setEnabled(True)
|
||||||
|
|
||||||
|
def _update_preview(self, loadout: Dict[str, Any]):
|
||||||
|
"""Update preview panel with loadout details."""
|
||||||
|
self.preview_weapon.setText(loadout.get('weapon_name') or "None")
|
||||||
|
self.preview_armor.setText(loadout.get('armor_name') or "None")
|
||||||
|
self.preview_healing.setText(loadout.get('healing_tool_name') or "None")
|
||||||
|
|
||||||
|
# Format costs
|
||||||
|
cost_shot = Decimal(str(loadout.get('cost_per_shot_ped', 0)))
|
||||||
|
cost_hit = Decimal(str(loadout.get('cost_per_hit_ped', 0)))
|
||||||
|
cost_heal = Decimal(str(loadout.get('cost_per_heal_ped', 0)))
|
||||||
|
|
||||||
|
self.preview_cost_shot.setText(f"{cost_shot:.4f} PED")
|
||||||
|
self.preview_cost_hit.setText(f"{cost_hit:.4f} PED")
|
||||||
|
self.preview_cost_heal.setText(f"{cost_heal:.4f} PED")
|
||||||
|
|
||||||
|
# Color code based on cost
|
||||||
|
if cost_shot > Decimal("0.5"):
|
||||||
|
self.preview_cost_shot.setStyleSheet("color: #FF7F7F;")
|
||||||
|
else:
|
||||||
|
self.preview_cost_shot.setStyleSheet("color: #7FFF7F;")
|
||||||
|
|
||||||
|
def _clear_preview(self):
|
||||||
|
"""Clear preview panel."""
|
||||||
|
self.preview_weapon.setText("-")
|
||||||
|
self.preview_armor.setText("-")
|
||||||
|
self.preview_healing.setText("-")
|
||||||
|
self.preview_cost_shot.setText("-")
|
||||||
|
self.preview_cost_hit.setText("-")
|
||||||
|
self.preview_cost_heal.setText("-")
|
||||||
|
|
||||||
|
def _on_double_click(self, item: QListWidgetItem):
|
||||||
|
"""Handle double click on loadout."""
|
||||||
|
if item.data(Qt.ItemDataRole.UserRole):
|
||||||
|
self._on_accept()
|
||||||
|
|
||||||
|
def _on_accept(self):
|
||||||
|
"""Handle OK button - start session with selected loadout."""
|
||||||
|
if self.selected_loadout_id:
|
||||||
|
self.loadout_selected.emit(self.selected_loadout_id, self.selected_loadout_name or "")
|
||||||
|
self.accept()
|
||||||
|
|
||||||
|
def _on_no_loadout(self):
|
||||||
|
"""Handle skip button - start session without loadout."""
|
||||||
|
reply = QMessageBox.question(
|
||||||
|
self,
|
||||||
|
"No Loadout Selected",
|
||||||
|
"Start session without cost tracking?\n\n"
|
||||||
|
"You won't be able to track accurate weapon/armor/healing costs.",
|
||||||
|
QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No
|
||||||
|
)
|
||||||
|
|
||||||
|
if reply == QMessageBox.StandardButton.Yes:
|
||||||
|
self.loadout_selected.emit(0, "No Loadout")
|
||||||
|
self.accept()
|
||||||
|
|
||||||
|
|
||||||
|
# Main entry for testing
|
||||||
|
if __name__ == "__main__":
|
||||||
|
import sys
|
||||||
|
import logging
|
||||||
|
from PyQt6.QtWidgets import QApplication
|
||||||
|
|
||||||
|
logging.basicConfig(level=logging.INFO)
|
||||||
|
|
||||||
|
app = QApplication(sys.argv)
|
||||||
|
app.setStyle('Fusion')
|
||||||
|
|
||||||
|
dialog = LoadoutSelectionDialog()
|
||||||
|
|
||||||
|
# Connect signal for testing
|
||||||
|
dialog.loadout_selected.connect(
|
||||||
|
lambda id, name: print(f"Selected loadout: {name} (ID: {id})")
|
||||||
|
)
|
||||||
|
|
||||||
|
if dialog.exec() == QDialog.DialogCode.Accepted:
|
||||||
|
print("Session starting!")
|
||||||
|
|
||||||
|
sys.exit(0)
|
||||||
Loading…
Reference in New Issue