auto create & edit battles

This commit is contained in:
Maxime Réaux 2026-01-30 18:55:39 +01:00
parent 9f676f6b9d
commit 6bd3ee31dc
10 changed files with 442 additions and 55 deletions

View file

@ -6,7 +6,7 @@ from warchron.view.view import View
from warchron.constants import ItemType, RefreshScope from warchron.constants import ItemType, RefreshScope
from warchron.controller.dtos import ParticipantOption from warchron.controller.dtos import ParticipantOption
from warchron.view.view import PlayerDialog, WarDialog, CampaignDialog, ObjectiveDialog, WarParticipantDialog, CampaignParticipantDialog, SectorDialog, ChoicesDialog from warchron.view.view import PlayerDialog, WarDialog, CampaignDialog, ObjectiveDialog, WarParticipantDialog, CampaignParticipantDialog, SectorDialog, ChoicesDialog, BattlesDialog
class Controller: class Controller:
def __init__(self, model: Model, view: View): def __init__(self, model: Model, view: View):
@ -169,6 +169,7 @@ class Controller:
camp = self.model.get_campaign_by_round(round_id) camp = self.model.get_campaign_by_round(round_id)
self.view.show_round_details(index=camp.get_round_index(round_id)) self.view.show_round_details(index=camp.get_round_index(round_id))
participants = self.model.get_round_participants(round_id) participants = self.model.get_round_participants(round_id)
sectors = camp.get_all_sectors()
choices_for_display = [] choices_for_display = []
for part in participants: for part in participants:
choice = rnd.get_choice(part.id) choice = rnd.get_choice(part.id)
@ -183,6 +184,20 @@ class Controller:
choice.participant_id choice.participant_id
)) ))
self.view.display_round_choices(choices_for_display) self.view.display_round_choices(choices_for_display)
battles_for_display = []
for sect in sectors:
battle = rnd.get_battle(sect.id)
if not battle:
battle=self.model.create_battle(round_id=rnd.id, sector_id=sect.id)
player_1_name = self.model.get_player_name(battle.player_1_id) if battle.player_1_id else ""
player_2_name = self.model.get_player_name(battle.player_2_id) if battle.player_2_id else ""
battles_for_display.append((
camp.get_sector_name(battle.sector_id),
player_1_name,
player_2_name,
battle.sector_id
))
self.view.display_round_battles(battles_for_display)
def on_tree_selection_changed(self, selection): def on_tree_selection_changed(self, selection):
self.selected_war_id = None self.selected_war_id = None
@ -344,6 +359,9 @@ class Controller:
elif item_type == ItemType.CHOICE: elif item_type == ItemType.CHOICE:
self.edit_round_choice(item_id) self.edit_round_choice(item_id)
self.refresh(RefreshScope.ROUND_DETAILS) self.refresh(RefreshScope.ROUND_DETAILS)
elif item_type == ItemType.BATTLE:
self.edit_round_battle(item_id)
self.refresh(RefreshScope.ROUND_DETAILS)
def delete_item(self, item_type: str, item_id: str): def delete_item(self, item_type: str, item_id: str):
reply = QMessageBox.question( reply = QMessageBox.question(
@ -576,13 +594,16 @@ class Controller:
self.is_dirty = True self.is_dirty = True
self.refresh_and_select(RefreshScope.WARS_TREE, item_type=ItemType.ROUND, item_id=rnd.id) self.refresh_and_select(RefreshScope.WARS_TREE, item_type=ItemType.ROUND, item_id=rnd.id)
# Choices methods # Choice methods
def edit_round_choice(self, choice_id: str): def edit_round_choice(self, choice_id: str):
round_id = self.selected_round_id round_id = self.selected_round_id
if not round_id: if not round_id:
return return
camp, rnd, participants, sectors = self.model.get_round_choices_data(round_id) # camp, rnd, participants, sectors = self.model.get_round_choices_data(round_id)
camp = self.model.get_campaign_by_round(round_id)
rnd = camp.get_round(round_id)
sectors = camp.get_sectors_in_round(round_id)
choice = rnd.get_choice(choice_id) choice = rnd.get_choice(choice_id)
if not choice: if not choice:
return return
@ -596,12 +617,59 @@ class Controller:
sectors=sectors, sectors=sectors,
default_priority_id = choice.priority_sector_id, default_priority_id = choice.priority_sector_id,
default_secondary_id = choice.secondary_sector_id, default_secondary_id = choice.secondary_sector_id,
default_comment = choice.comment,
) )
if dialog.exec() != QDialog.DialogCode.Accepted: if dialog.exec() != QDialog.DialogCode.Accepted:
return return
rnd.set_choice( # TODO replace by update_choice through self.model...
rnd.update_choice(
participant_id = part.id, participant_id = part.id,
priority_sector_id = dialog.get_priority_id(), priority_sector_id = dialog.get_priority_id(),
secondary_sector_id = dialog.get_secondary_id(), secondary_sector_id = dialog.get_secondary_id(),
comment = dialog.get_comment()
)
# Battle methods
def edit_round_battle(self, battle_id: str):
round_id = self.selected_round_id
if not round_id:
return
camp = self.model.get_campaign_by_round(round_id)
rnd = camp.get_round(round_id)
participants = camp.get_all_campaign_participants()
battle = rnd.get_battle(battle_id)
if not battle:
return
sect = camp.sectors[battle.sector_id]
part_opts: list[ParticipantOption] = []
for part in participants:
player = self.model.get_player(part.id)
part_opts.append(
ParticipantOption(id=part.id, name=player.name)
)
dialog = BattlesDialog(
self.view,
sectors = [sect],
default_sector_id = sect.id,
players = part_opts,
default_player_1_id = battle.player_1_id,
default_player_2_id = battle.player_2_id,
default_winner_id = battle.winner_id,
default_score = battle.score,
default_victory_condition = battle.victory_condition,
default_comment = battle.comment,
)
if dialog.exec() != QDialog.DialogCode.Accepted:
return
# TODO replace by update_battle through self.model...
rnd.update_battle(
sector_id = sect.id,
player_1_id = dialog.get_player_1_id(),
player_2_id = dialog.get_player_2_id(),
winner_id = dialog.get_winner_id(),
score = dialog.get_score(),
victory_condition = dialog.get_victory_condition(),
comment = dialog.get_comment(),
) )

View file

@ -108,6 +108,13 @@ class Campaign:
# TODO manage battles referring to it # TODO manage battles referring to it
del self.sectors[sector_id] del self.sectors[sector_id]
def get_sectors_in_round(self, round_id: str) -> list[Sector]:
sectors = [
s for s in self.sectors.values()
if s.round_id == round_id
]
return sectors
# Round methods # Round methods
def has_round(self, round_id: str) -> bool: def has_round(self, round_id: str) -> bool:
@ -158,6 +165,16 @@ class Campaign:
rnd = self.get_round(round_id) rnd = self.get_round(round_id)
rnd.remove_choice(participant_id) rnd.remove_choice(participant_id)
# Battle methods
def create_battle(self, round_id: str, sector_id: str) -> Battle:
rnd = self.get_round(round_id)
return rnd.create_battle(sector_id)
def remove_battle(self, round_id: str, sector_id: str) -> Battle:
rnd = self.get_round(round_id)
rnd.remove_battle(sector_id)
class CampaignParticipant: class CampaignParticipant:
def __init__(self, player_id: str, leader: str, theme: str): def __init__(self, player_id: str, leader: str, theme: str):
self.id: str = player_id # ref to War.participants self.id: str = player_id # ref to War.participants
@ -181,6 +198,8 @@ class Sector:
self.major_objective_id: str | None = major_id # ref to War.objectives self.major_objective_id: str | None = major_id # ref to War.objectives
self.minor_objective_id: str | None = minor_id # ref to War.objectives self.minor_objective_id: str | None = minor_id # ref to War.objectives
self.influence_objective_id: str | None = influence_id # ref to War.objectives self.influence_objective_id: str | None = influence_id # ref to War.objectives
self.mission: str | None = None
self.description: str | None = None
def set_id(self, new_id: str): def set_id(self, new_id: str):
self.id = new_id self.id = new_id

View file

@ -318,7 +318,7 @@ class Model:
war = self.get_war_by_round(round_id) war = self.get_war_by_round(round_id)
war.remove_round(round_id) war.remove_round(round_id)
# Choices methods # Choice methods
def create_choice(self, round_id: str, participant_id: str) -> Choice: def create_choice(self, round_id: str, participant_id: str) -> Choice:
war = self.get_war_by_round(round_id) war = self.get_war_by_round(round_id)
@ -337,3 +337,14 @@ class Model:
if s.round_id == round_id if s.round_id == round_id
] ]
return camp, rnd, participants, sectors return camp, rnd, participants, sectors
# Battle methods
def create_battle(self, round_id: str, sector_id: str) -> Battle:
war = self.get_war_by_round(round_id)
return war.create_battle(round_id, sector_id)
def remove_battle(self, round_id: str, sector_id: str):
war = self.get_war_by_round(round_id)
war.remove_battle(round_id, sector_id)

View file

@ -14,9 +14,6 @@ class Round:
def set_state(self, new_state: bool): def set_state(self, new_state: bool):
self.is_over = new_state self.is_over = new_state
def set_choice(self, participant_id: str, priority_sector_id: str | None, secondary_sector_id: str | None):
self.choices[participant_id] = Choice(participant_id, priority_sector_id, secondary_sector_id)
def toDict(self): def toDict(self):
return { return {
"id": self.id, "id": self.id,
@ -36,7 +33,7 @@ class Round:
rnd.set_state(data.get("is_over", False)) rnd.set_state(data.get("is_over", False))
return rnd return rnd
# Choices methods # Choice methods
def get_choice(self, participant_id: str) -> Choice | None: def get_choice(self, participant_id: str) -> Choice | None:
return self.choices.get(participant_id) return self.choices.get(participant_id)
@ -51,17 +48,88 @@ class Round:
self.choices[participant_id] = choice self.choices[participant_id] = choice
return self.choices[participant_id] return self.choices[participant_id]
def update_choice(self, participant_id: str, priority_sector_id: str | None, secondary_sector_id: str | None, comment: str | None):
choice = self.get_choice(participant_id)
choice.set_priority(priority_sector_id)
choice.set_secondary(secondary_sector_id)
choice.set_comment(comment)
def remove_choice(self,participant_id: str): def remove_choice(self,participant_id: str):
del self.choices[participant_id] del self.choices[participant_id]
# Battle methods
def get_battle(self, sector_id: str) -> Battle | None:
return self.battles.get(sector_id)
def create_battle(self, sector_id: str) -> Battle:
if sector_id not in self.battles:
battle = Battle(
sector_id = sector_id,
player_1_id = None,
player_2_id = None
)
self.battles[sector_id] = battle
return self.battles[sector_id]
def update_battle(self, sector_id: str, player_1_id: str | None, player_2_id: str | None, winner_id: str | None, score: str | None, victory_condition: str | None, comment: str | None):
bat = self.get_battle(sector_id)
bat.set_player_1(player_1_id)
bat.set_player_2(player_2_id)
bat.set_winner(winner_id)
bat.set_score(score)
bat.set_victory_condition(victory_condition)
bat.set_comment(comment)
def remove_battle(self,sector_id: str):
del self.battles[sector_id]
class Choice: class Choice:
def __init__(self, participant_id: str, priority_sector_id: str | None = None, secondary_sector_id: str | None = None): def __init__(self, participant_id: str, priority_sector_id: str | None = None, secondary_sector_id: str | None = None):
self.participant_id: str = participant_id # ref to Campaign.participants self.participant_id: str = participant_id # ref to Campaign.participants
self.priority_sector_id: str | None = priority_sector_id # ref to Campaign.sectors self.priority_sector_id: str | None = priority_sector_id # ref to Campaign.sectors
self.secondary_sector_id: str | None = secondary_sector_id # ref to Campaign.sectors self.secondary_sector_id: str | None = secondary_sector_id # ref to Campaign.sectors
self.comment: str | None = None
def set_id(self, new_id: str):
self.participant_id = new_id
def set_priority(self, new_priority_id: str):
self.priority_sector_id = new_priority_id
def set_secondary(self, new_secondary_id: str):
self.secondary_sector_id = new_secondary_id
def set_comment(self, new_comment: str):
self.comment = new_comment
class Battle: class Battle:
def __init__(self, sector_id: str, player_1_id: str | None = None, player_2_id: str | None = None): def __init__(self, sector_id: str, player_1_id: str | None = None, player_2_id: str | None = None):
self.sector_id: str = sector_id # ref to Campaign.sector self.sector_id: str = sector_id # ref to Campaign.sector
self.player_1_id: str | None = player_1_id # ref to Campaign.participants self.player_1_id: str | None = player_1_id # ref to Campaign.participants
self.player_2_id: str | None = player_2_id # ref to Campaign.participants self.player_2_id: str | None = player_2_id # ref to Campaign.participants
self.winner_id: str | None = None
self.score: str | None = None
self.victory_condition: str | None = None
self.comment: str | None = None
def set_id(self, new_id: str):
self.sector_id = new_id
def set_player_1(self, new_player_id: str):
self.player_1_id = new_player_id
def set_player_2(self, new_player_id: str):
self.player_2_id = new_player_id
def set_winner(self, new_player_id: str):
self.winner_id = new_player_id
def set_score(self, new_score: str):
self.score = new_score
def set_victory_condition(self, new_victory_condition: str):
self.victory_condition = new_victory_condition
def set_comment(self, new_comment: str):
self.comment = new_comment

View file

@ -227,6 +227,16 @@ class War:
camp = self.get_campaign_by_round(round_id) camp = self.get_campaign_by_round(round_id)
camp.remove_choice(round_id, participant_id) camp.remove_choice(round_id, participant_id)
# Battle methods
def create_battle(self, round_id: str, sector_id: str) -> Battle:
camp = self.get_campaign_by_round(round_id)
return camp.create_battle(round_id, sector_id)
def remove_battle(self, round_id: str, sector_id: str):
camp = self.get_campaign_by_round(round_id)
camp.remove_battle(round_id, sector_id)
class Objective: class Objective:
def __init__(self, name: str, description: str): def __init__(self, name: str, description: str):
self.id: str = str(uuid4()) self.id: str = str(uuid4())

View file

@ -13,15 +13,50 @@ class Ui_battleResultDialog(object):
def setupUi(self, battleResultDialog): def setupUi(self, battleResultDialog):
battleResultDialog.setObjectName("battleResultDialog") battleResultDialog.setObjectName("battleResultDialog")
battleResultDialog.setWindowModality(QtCore.Qt.WindowModality.ApplicationModal) battleResultDialog.setWindowModality(QtCore.Qt.WindowModality.ApplicationModal)
battleResultDialog.resize(561, 246) battleResultDialog.resize(668, 317)
icon = QtGui.QIcon() icon = QtGui.QIcon()
icon.addPixmap(QtGui.QPixmap(".\\src\\warchron\\view\\ui\\../resources/warchron_logo.png"), QtGui.QIcon.Mode.Normal, QtGui.QIcon.State.Off) icon.addPixmap(QtGui.QPixmap(".\\src\\warchron\\view\\ui\\../resources/warchron_logo.png"), QtGui.QIcon.Mode.Normal, QtGui.QIcon.State.Off)
battleResultDialog.setWindowIcon(icon) battleResultDialog.setWindowIcon(icon)
self.formLayout = QtWidgets.QFormLayout(battleResultDialog) self.gridLayout = QtWidgets.QGridLayout(battleResultDialog)
self.formLayout.setObjectName("formLayout") self.gridLayout.setObjectName("gridLayout")
self.label_7 = QtWidgets.QLabel(parent=battleResultDialog)
self.label_7.setObjectName("label_7")
self.gridLayout.addWidget(self.label_7, 0, 0, 1, 1)
self.sectorComboBox = QtWidgets.QComboBox(parent=battleResultDialog)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.sectorComboBox.sizePolicy().hasHeightForWidth())
self.sectorComboBox.setSizePolicy(sizePolicy)
self.sectorComboBox.setObjectName("sectorComboBox")
self.gridLayout.addWidget(self.sectorComboBox, 0, 1, 1, 1)
self.label_5 = QtWidgets.QLabel(parent=battleResultDialog)
self.label_5.setObjectName("label_5")
self.gridLayout.addWidget(self.label_5, 0, 2, 1, 1)
self.player1ComboBox = QtWidgets.QComboBox(parent=battleResultDialog)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.player1ComboBox.sizePolicy().hasHeightForWidth())
self.player1ComboBox.setSizePolicy(sizePolicy)
self.player1ComboBox.setObjectName("player1ComboBox")
self.gridLayout.addWidget(self.player1ComboBox, 0, 3, 1, 1)
self.label_6 = QtWidgets.QLabel(parent=battleResultDialog)
self.label_6.setObjectName("label_6")
self.gridLayout.addWidget(self.label_6, 0, 4, 1, 1)
self.player2ComboBox = QtWidgets.QComboBox(parent=battleResultDialog)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.player2ComboBox.sizePolicy().hasHeightForWidth())
self.player2ComboBox.setSizePolicy(sizePolicy)
self.player2ComboBox.setObjectName("player2ComboBox")
self.gridLayout.addWidget(self.player2ComboBox, 0, 5, 1, 1)
spacerItem = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.Expanding)
self.gridLayout.addItem(spacerItem, 1, 1, 1, 1)
self.label = QtWidgets.QLabel(parent=battleResultDialog) self.label = QtWidgets.QLabel(parent=battleResultDialog)
self.label.setObjectName("label") self.label.setObjectName("label")
self.formLayout.setWidget(0, QtWidgets.QFormLayout.ItemRole.LabelRole, self.label) self.gridLayout.addWidget(self.label, 2, 0, 1, 1)
self.winnerComboBox = QtWidgets.QComboBox(parent=battleResultDialog) self.winnerComboBox = QtWidgets.QComboBox(parent=battleResultDialog)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Fixed) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Fixed)
sizePolicy.setHorizontalStretch(0) sizePolicy.setHorizontalStretch(0)
@ -29,30 +64,30 @@ class Ui_battleResultDialog(object):
sizePolicy.setHeightForWidth(self.winnerComboBox.sizePolicy().hasHeightForWidth()) sizePolicy.setHeightForWidth(self.winnerComboBox.sizePolicy().hasHeightForWidth())
self.winnerComboBox.setSizePolicy(sizePolicy) self.winnerComboBox.setSizePolicy(sizePolicy)
self.winnerComboBox.setObjectName("winnerComboBox") self.winnerComboBox.setObjectName("winnerComboBox")
self.formLayout.setWidget(0, QtWidgets.QFormLayout.ItemRole.FieldRole, self.winnerComboBox) self.gridLayout.addWidget(self.winnerComboBox, 2, 1, 1, 1)
self.label_2 = QtWidgets.QLabel(parent=battleResultDialog) self.label_2 = QtWidgets.QLabel(parent=battleResultDialog)
self.label_2.setObjectName("label_2") self.label_2.setObjectName("label_2")
self.formLayout.setWidget(1, QtWidgets.QFormLayout.ItemRole.LabelRole, self.label_2) self.gridLayout.addWidget(self.label_2, 3, 0, 1, 1)
self.score = QtWidgets.QLineEdit(parent=battleResultDialog) self.score = QtWidgets.QLineEdit(parent=battleResultDialog)
self.score.setObjectName("score") self.score.setObjectName("score")
self.formLayout.setWidget(1, QtWidgets.QFormLayout.ItemRole.FieldRole, self.score) self.gridLayout.addWidget(self.score, 3, 1, 1, 2)
self.label_3 = QtWidgets.QLabel(parent=battleResultDialog) self.label_3 = QtWidgets.QLabel(parent=battleResultDialog)
self.label_3.setObjectName("label_3") self.label_3.setObjectName("label_3")
self.formLayout.setWidget(2, QtWidgets.QFormLayout.ItemRole.LabelRole, self.label_3) self.gridLayout.addWidget(self.label_3, 3, 3, 1, 1)
self.victoryCondition = QtWidgets.QLineEdit(parent=battleResultDialog) self.victoryCondition = QtWidgets.QLineEdit(parent=battleResultDialog)
self.victoryCondition.setObjectName("victoryCondition") self.victoryCondition.setObjectName("victoryCondition")
self.formLayout.setWidget(2, QtWidgets.QFormLayout.ItemRole.FieldRole, self.victoryCondition) self.gridLayout.addWidget(self.victoryCondition, 3, 4, 1, 2)
self.label_4 = QtWidgets.QLabel(parent=battleResultDialog) self.label_4 = QtWidgets.QLabel(parent=battleResultDialog)
self.label_4.setObjectName("label_4") self.label_4.setObjectName("label_4")
self.formLayout.setWidget(3, QtWidgets.QFormLayout.ItemRole.LabelRole, self.label_4) self.gridLayout.addWidget(self.label_4, 4, 0, 1, 1)
self.battleComment = QtWidgets.QPlainTextEdit(parent=battleResultDialog) self.battleComment = QtWidgets.QPlainTextEdit(parent=battleResultDialog)
self.battleComment.setObjectName("battleComment") self.battleComment.setObjectName("battleComment")
self.formLayout.setWidget(3, QtWidgets.QFormLayout.ItemRole.FieldRole, self.battleComment) self.gridLayout.addWidget(self.battleComment, 4, 1, 1, 5)
self.buttonBox = QtWidgets.QDialogButtonBox(parent=battleResultDialog) self.buttonBox = QtWidgets.QDialogButtonBox(parent=battleResultDialog)
self.buttonBox.setOrientation(QtCore.Qt.Orientation.Horizontal) self.buttonBox.setOrientation(QtCore.Qt.Orientation.Horizontal)
self.buttonBox.setStandardButtons(QtWidgets.QDialogButtonBox.StandardButton.Cancel|QtWidgets.QDialogButtonBox.StandardButton.Ok) self.buttonBox.setStandardButtons(QtWidgets.QDialogButtonBox.StandardButton.Cancel|QtWidgets.QDialogButtonBox.StandardButton.Ok)
self.buttonBox.setObjectName("buttonBox") self.buttonBox.setObjectName("buttonBox")
self.formLayout.setWidget(4, QtWidgets.QFormLayout.ItemRole.SpanningRole, self.buttonBox) self.gridLayout.addWidget(self.buttonBox, 5, 4, 1, 2)
self.retranslateUi(battleResultDialog) self.retranslateUi(battleResultDialog)
self.buttonBox.accepted.connect(battleResultDialog.accept) # type: ignore self.buttonBox.accepted.connect(battleResultDialog.accept) # type: ignore
@ -62,6 +97,9 @@ class Ui_battleResultDialog(object):
def retranslateUi(self, battleResultDialog): def retranslateUi(self, battleResultDialog):
_translate = QtCore.QCoreApplication.translate _translate = QtCore.QCoreApplication.translate
battleResultDialog.setWindowTitle(_translate("battleResultDialog", "Battle result")) battleResultDialog.setWindowTitle(_translate("battleResultDialog", "Battle result"))
self.label_7.setText(_translate("battleResultDialog", "Sector"))
self.label_5.setText(_translate("battleResultDialog", "Player 1"))
self.label_6.setText(_translate("battleResultDialog", "Player 2"))
self.label.setText(_translate("battleResultDialog", "Winner")) self.label.setText(_translate("battleResultDialog", "Winner"))
self.label_2.setText(_translate("battleResultDialog", "Score")) self.label_2.setText(_translate("battleResultDialog", "Score"))
self.label_3.setText(_translate("battleResultDialog", "Victory condition")) self.label_3.setText(_translate("battleResultDialog", "Victory condition"))

View file

@ -9,8 +9,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>561</width> <width>668</width>
<height>246</height> <height>317</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
@ -20,15 +20,79 @@
<iconset> <iconset>
<normaloff>../resources/warchron_logo.png</normaloff>../resources/warchron_logo.png</iconset> <normaloff>../resources/warchron_logo.png</normaloff>../resources/warchron_logo.png</iconset>
</property> </property>
<layout class="QFormLayout" name="formLayout"> <layout class="QGridLayout" name="gridLayout">
<item row="0" column="0"> <item row="0" column="0">
<widget class="QLabel" name="label_7">
<property name="text">
<string>Sector</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="sectorComboBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Player 1</string>
</property>
</widget>
</item>
<item row="0" column="3">
<widget class="QComboBox" name="player1ComboBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item row="0" column="4">
<widget class="QLabel" name="label_6">
<property name="text">
<string>Player 2</string>
</property>
</widget>
</item>
<item row="0" column="5">
<widget class="QComboBox" name="player2ComboBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item row="1" column="1">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label"> <widget class="QLabel" name="label">
<property name="text"> <property name="text">
<string>Winner</string> <string>Winner</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="0" column="1"> <item row="2" column="1">
<widget class="QComboBox" name="winnerComboBox"> <widget class="QComboBox" name="winnerComboBox">
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed"> <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
@ -38,37 +102,37 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="1" column="0"> <item row="3" column="0">
<widget class="QLabel" name="label_2"> <widget class="QLabel" name="label_2">
<property name="text"> <property name="text">
<string>Score</string> <string>Score</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="1" column="1"> <item row="3" column="1" colspan="2">
<widget class="QLineEdit" name="score"/> <widget class="QLineEdit" name="score"/>
</item> </item>
<item row="2" column="0"> <item row="3" column="3">
<widget class="QLabel" name="label_3"> <widget class="QLabel" name="label_3">
<property name="text"> <property name="text">
<string>Victory condition</string> <string>Victory condition</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="2" column="1"> <item row="3" column="4" colspan="2">
<widget class="QLineEdit" name="victoryCondition"/> <widget class="QLineEdit" name="victoryCondition"/>
</item> </item>
<item row="3" column="0"> <item row="4" column="0">
<widget class="QLabel" name="label_4"> <widget class="QLabel" name="label_4">
<property name="text"> <property name="text">
<string>Comment</string> <string>Comment</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="3" column="1"> <item row="4" column="1" colspan="5">
<widget class="QPlainTextEdit" name="battleComment"/> <widget class="QPlainTextEdit" name="battleComment"/>
</item> </item>
<item row="4" column="0" colspan="2"> <item row="5" column="4" colspan="2">
<widget class="QDialogButtonBox" name="buttonBox"> <widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation"> <property name="orientation">
<enum>Qt::Horizontal</enum> <enum>Qt::Horizontal</enum>

View file

@ -206,7 +206,7 @@ class Ui_MainWindow(object):
self.horizontalLayout_13.setObjectName("horizontalLayout_13") self.horizontalLayout_13.setObjectName("horizontalLayout_13")
self.sectorsTable = QtWidgets.QTableWidget(parent=self.pageCampaign) self.sectorsTable = QtWidgets.QTableWidget(parent=self.pageCampaign)
self.sectorsTable.setObjectName("sectorsTable") self.sectorsTable.setObjectName("sectorsTable")
self.sectorsTable.setColumnCount(5) self.sectorsTable.setColumnCount(6)
self.sectorsTable.setRowCount(0) self.sectorsTable.setRowCount(0)
item = QtWidgets.QTableWidgetItem() item = QtWidgets.QTableWidgetItem()
self.sectorsTable.setHorizontalHeaderItem(0, item) self.sectorsTable.setHorizontalHeaderItem(0, item)
@ -218,6 +218,8 @@ class Ui_MainWindow(object):
self.sectorsTable.setHorizontalHeaderItem(3, item) self.sectorsTable.setHorizontalHeaderItem(3, item)
item = QtWidgets.QTableWidgetItem() item = QtWidgets.QTableWidgetItem()
self.sectorsTable.setHorizontalHeaderItem(4, item) self.sectorsTable.setHorizontalHeaderItem(4, item)
item = QtWidgets.QTableWidgetItem()
self.sectorsTable.setHorizontalHeaderItem(5, item)
self.horizontalLayout_13.addWidget(self.sectorsTable) self.horizontalLayout_13.addWidget(self.sectorsTable)
self.addSectorBtn = QtWidgets.QPushButton(parent=self.pageCampaign) self.addSectorBtn = QtWidgets.QPushButton(parent=self.pageCampaign)
self.addSectorBtn.setEnabled(True) self.addSectorBtn.setEnabled(True)
@ -269,10 +271,10 @@ class Ui_MainWindow(object):
item = QtWidgets.QTableWidgetItem() item = QtWidgets.QTableWidgetItem()
self.battlesTable.setHorizontalHeaderItem(2, item) self.battlesTable.setHorizontalHeaderItem(2, item)
self.horizontalLayout_15.addWidget(self.battlesTable) self.horizontalLayout_15.addWidget(self.battlesTable)
self.enterResultBtn = QtWidgets.QPushButton(parent=self.pageRound) self.countResultBtn = QtWidgets.QPushButton(parent=self.pageRound)
self.enterResultBtn.setEnabled(True) self.countResultBtn.setEnabled(False)
self.enterResultBtn.setObjectName("enterResultBtn") self.countResultBtn.setObjectName("countResultBtn")
self.horizontalLayout_15.addWidget(self.enterResultBtn) self.horizontalLayout_15.addWidget(self.countResultBtn)
self.gridLayout_5.addLayout(self.horizontalLayout_15, 4, 0, 1, 3) self.gridLayout_5.addLayout(self.horizontalLayout_15, 4, 0, 1, 3)
self.horizontalLayout_16 = QtWidgets.QHBoxLayout() self.horizontalLayout_16 = QtWidgets.QHBoxLayout()
self.horizontalLayout_16.setObjectName("horizontalLayout_16") self.horizontalLayout_16.setObjectName("horizontalLayout_16")
@ -385,7 +387,7 @@ class Ui_MainWindow(object):
self.retranslateUi(MainWindow) self.retranslateUi(MainWindow)
self.tabWidget.setCurrentIndex(1) self.tabWidget.setCurrentIndex(1)
self.selectedDetailsStack.setCurrentIndex(2) self.selectedDetailsStack.setCurrentIndex(3)
QtCore.QMetaObject.connectSlotsByName(MainWindow) QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow): def retranslateUi(self, MainWindow):
@ -450,6 +452,8 @@ class Ui_MainWindow(object):
item.setText(_translate("MainWindow", "Minor opp.")) item.setText(_translate("MainWindow", "Minor opp."))
item = self.sectorsTable.horizontalHeaderItem(4) item = self.sectorsTable.horizontalHeaderItem(4)
item.setText(_translate("MainWindow", "Influence imp.")) item.setText(_translate("MainWindow", "Influence imp."))
item = self.sectorsTable.horizontalHeaderItem(5)
item.setText(_translate("MainWindow", "Description"))
self.addSectorBtn.setText(_translate("MainWindow", "Add Sector")) self.addSectorBtn.setText(_translate("MainWindow", "Add Sector"))
self.campaignName.setText(_translate("MainWindow", "campaignName")) self.campaignName.setText(_translate("MainWindow", "campaignName"))
self.campaignMonth.setText(_translate("MainWindow", "campaignMonth")) self.campaignMonth.setText(_translate("MainWindow", "campaignMonth"))
@ -462,7 +466,7 @@ class Ui_MainWindow(object):
item.setText(_translate("MainWindow", "Player 1")) item.setText(_translate("MainWindow", "Player 1"))
item = self.battlesTable.horizontalHeaderItem(2) item = self.battlesTable.horizontalHeaderItem(2)
item.setText(_translate("MainWindow", "Player 2")) item.setText(_translate("MainWindow", "Player 2"))
self.enterResultBtn.setText(_translate("MainWindow", "Enter results")) self.countResultBtn.setText(_translate("MainWindow", "Count results"))
item = self.choicesTable.horizontalHeaderItem(0) item = self.choicesTable.horizontalHeaderItem(0)
item.setText(_translate("MainWindow", "Player")) item.setText(_translate("MainWindow", "Player"))
item = self.choicesTable.horizontalHeaderItem(1) item = self.choicesTable.horizontalHeaderItem(1)

View file

@ -150,7 +150,7 @@
<item> <item>
<widget class="QStackedWidget" name="selectedDetailsStack"> <widget class="QStackedWidget" name="selectedDetailsStack">
<property name="currentIndex"> <property name="currentIndex">
<number>2</number> <number>3</number>
</property> </property>
<widget class="QWidget" name="pageEmpty"> <widget class="QWidget" name="pageEmpty">
<layout class="QVBoxLayout" name="verticalLayout_4"> <layout class="QVBoxLayout" name="verticalLayout_4">
@ -446,6 +446,11 @@
<string>Influence imp.</string> <string>Influence imp.</string>
</property> </property>
</column> </column>
<column>
<property name="text">
<string>Description</string>
</property>
</column>
</widget> </widget>
</item> </item>
<item> <item>
@ -551,12 +556,12 @@
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QPushButton" name="enterResultBtn"> <widget class="QPushButton" name="countResultBtn">
<property name="enabled"> <property name="enabled">
<bool>true</bool> <bool>false</bool>
</property> </property>
<property name="text"> <property name="text">
<string>Enter results</string> <string>Count results</string>
</property> </property>
</widget> </widget>
</item> </item>

View file

@ -17,6 +17,7 @@ from warchron.view.ui.ui_war_participant_dialog import Ui_warParticipantDialog
from warchron.view.ui.ui_campaign_participant_dialog import Ui_campaignParticipantDialog from warchron.view.ui.ui_campaign_participant_dialog import Ui_campaignParticipantDialog
from warchron.view.ui.ui_sector_dialog import Ui_sectorDialog from warchron.view.ui.ui_sector_dialog import Ui_sectorDialog
from warchron.view.ui.ui_choices_dialog import Ui_choicesDialog from warchron.view.ui.ui_choices_dialog import Ui_choicesDialog
from warchron.view.ui.ui_battle_result_dialog import Ui_battleResultDialog
# utils... # utils...
@ -66,6 +67,8 @@ class View(QtWidgets.QMainWindow, Ui_MainWindow):
self.sectorsTable.customContextMenuRequested.connect(self._on_sectors_table_context_menu) self.sectorsTable.customContextMenuRequested.connect(self._on_sectors_table_context_menu)
self.choicesTable.setContextMenuPolicy(Qt.ContextMenuPolicy.CustomContextMenu) self.choicesTable.setContextMenuPolicy(Qt.ContextMenuPolicy.CustomContextMenu)
self.choicesTable.customContextMenuRequested.connect(self._on_choices_table_context_menu) self.choicesTable.customContextMenuRequested.connect(self._on_choices_table_context_menu)
self.battlesTable.setContextMenuPolicy(Qt.ContextMenuPolicy.CustomContextMenu)
self.battlesTable.customContextMenuRequested.connect(self._on_battles_table_context_menu)
def _emit_selection_changed(self, current, previous): def _emit_selection_changed(self, current, previous):
if not self.on_tree_selection_changed: if not self.on_tree_selection_changed:
@ -395,6 +398,23 @@ class View(QtWidgets.QMainWindow, Ui_MainWindow):
if action == edit_action and self.on_edit_item: if action == edit_action and self.on_edit_item:
self.on_edit_item(ItemType.CHOICE, choice_id) self.on_edit_item(ItemType.CHOICE, choice_id)
def _on_battles_table_context_menu(self, pos):
item = self.battlesTable.itemAt(pos)
if not item:
return
row = item.row()
name_item = self.battlesTable.item(row, 0)
if not name_item:
return
battle_id = name_item.data(Qt.ItemDataRole.UserRole)
if battle_id is None:
return
menu = QMenu(self)
edit_action = menu.addAction("Edit")
action = menu.exec(self.battlesTable.viewport().mapToGlobal(pos))
if action == edit_action and self.on_edit_item:
self.on_edit_item(ItemType.BATTLE, battle_id)
def show_round_details(self, *, index: int): def show_round_details(self, *, index: int):
self.roundNb.setText(f"Round {index}") self.roundNb.setText(f"Round {index}")
@ -412,6 +432,20 @@ class View(QtWidgets.QMainWindow, Ui_MainWindow):
table.setItem(row, 2, secondary_item) table.setItem(row, 2, secondary_item)
table.resizeColumnsToContents() table.resizeColumnsToContents()
def display_round_battles(self, sectors: list[tuple[str, str, str, str]]):
table = self.battlesTable
table.clearContents()
table.setRowCount(len(sectors))
for row, (sector, player_1, player_2, battle_id) in enumerate(sectors):
sector_item = QtWidgets.QTableWidgetItem(sector)
player_1_item = QtWidgets.QTableWidgetItem(player_1)
player_2_item = QtWidgets.QTableWidgetItem(player_2)
sector_item.setData(Qt.ItemDataRole.UserRole, battle_id)
table.setItem(row, 0, sector_item)
table.setItem(row, 1, player_1_item)
table.setItem(row, 2, player_2_item)
table.resizeColumnsToContents()
class PlayerDialog(QDialog): class PlayerDialog(QDialog):
def __init__(self, parent=None, *, default_name: str = ""): def __init__(self, parent=None, *, default_name: str = ""):
super().__init__(parent) super().__init__(parent)
@ -540,7 +574,13 @@ class SectorDialog(QDialog):
return self.ui.influenceComboBox.currentData() return self.ui.influenceComboBox.currentData()
class ChoicesDialog(QDialog): class ChoicesDialog(QDialog):
def __init__(self, parent=None, *, participants: list, default_participant_id=None, sectors: list, default_priority_id=None, default_secondary_id=None): def __init__(self, parent = None, *,
participants: list,
default_participant_id = None,
sectors: list,
default_priority_id = None,
default_secondary_id = None,
default_comment = None):
super().__init__(parent) super().__init__(parent)
self.ui = Ui_choicesDialog() self.ui = Ui_choicesDialog()
self.ui.setupUi(self) self.ui.setupUi(self)
@ -555,6 +595,7 @@ class ChoicesDialog(QDialog):
self.ui.secondaryComboBox.addItem(sect.name, sect.id) self.ui.secondaryComboBox.addItem(sect.name, sect.id)
select_if_exists(self.ui.priorityComboBox, default_priority_id) select_if_exists(self.ui.priorityComboBox, default_priority_id)
select_if_exists(self.ui.secondaryComboBox, default_secondary_id) select_if_exists(self.ui.secondaryComboBox, default_secondary_id)
self.ui.choiceComment.setPlainText(default_comment)
def get_participant_id(self) -> str: def get_participant_id(self) -> str:
return self.ui.playerComboBox.currentData() return self.ui.playerComboBox.currentData()
@ -564,3 +605,62 @@ class ChoicesDialog(QDialog):
def get_secondary_id(self) -> str: def get_secondary_id(self) -> str:
return self.ui.secondaryComboBox.currentData() return self.ui.secondaryComboBox.currentData()
def get_comment(self) -> str:
return self.ui.choiceComment.toPlainText().strip()
class BattlesDialog(QDialog):
def __init__(self, parent = None, *,
sectors: list,
default_sector_id = None,
players: list,
default_player_1_id = None,
default_player_2_id = None,
default_winner_id = None,
default_score = None,
default_victory_condition = None,
default_comment = None):
super().__init__(parent)
self.ui = Ui_battleResultDialog()
self.ui.setupUi(self)
for sect in sectors:
self.ui.sectorComboBox.addItem(sect.name, sect.id)
select_if_exists(self.ui.sectorComboBox, default_sector_id)
self.ui.sectorComboBox.setEnabled(False)
self.ui.player1ComboBox.addItem("(none)", None)
self.ui.player2ComboBox.addItem("(none)", None)
for play in players:
self.ui.player1ComboBox.addItem(play.name, play.id)
self.ui.player2ComboBox.addItem(play.name, play.id)
select_if_exists(self.ui.player1ComboBox, default_player_1_id)
select_if_exists(self.ui.player2ComboBox, default_player_2_id)
self.ui.winnerComboBox.addItem("(none)", None)
for play in players:
if play.id in (default_player_1_id, default_player_2_id):
self.ui.winnerComboBox.addItem(play.name, play.id)
select_if_exists(self.ui.winnerComboBox, default_winner_id)
self.ui.score.setText(default_score)
self.ui.victoryCondition.setText(default_victory_condition)
self.ui.battleComment.setPlainText(default_comment)
def get_sector_id(self) -> str:
return self.ui.sectorComboBox.currentData()
def get_player_1_id(self) -> str:
return self.ui.player1ComboBox.currentData()
def get_player_2_id(self) -> str:
return self.ui.player2ComboBox.currentData()
def get_winner_id(self) -> str:
return self.ui.winnerComboBox.currentData()
def get_score(self) -> str:
return self.ui.score.text().strip()
def get_victory_condition(self) -> str:
return self.ui.victoryCondition.text().strip()
def get_comment(self) -> str:
return self.ui.battleComment.toPlainText().strip()