Add section toggles, simplify Customize, scope header to Match
- Customize menu: a "Sections" group to show/hide each Match panel (You, Match, Opponent, Turn stats, My deck, Preview, Opponent's cards); rows collapse when all their panels are hidden. Player panel details follow, then Arrange. The submenus duplicating Arrange are gone. - The top bar's match summary only shows on the Match tab. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
e82f8d1858
commit
5f3c7c13d0
4 files changed
+69
-23
No files matched your search
@@ -25,9 +25,10 @@ Two views, switched from the top bar (Ctrl+1 / Ctrl+2):
|
||||
filters. Click a game to open it in the Match view ("Back to live" returns). Games from the
|
||||
previous MTGA session (`Player-prev.log`) are imported on startup.
|
||||
|
||||
*⚙ Customize* shows or hides the match panels, turn stats, deck sections and the preview.
|
||||
*Customize → Arrange…* reorders (drag, or ↑/↓) and shows/hides the My deck and Opponent sections
|
||||
and the turn stats. Your choices are remembered.
|
||||
*⚙ Customize* shows or hides each panel of the Match page (You, Match, Opponent, Turn stats,
|
||||
My deck, Preview, Opponent's cards) and the details in the player panels. *Customize → Arrange…*
|
||||
reorders (drag, or ↑/↓) and shows/hides the My deck and Opponent sections and the turn stats.
|
||||
Your choices are remembered.
|
||||
|
||||
Card names, mana costs and types come from MTGA's own local card database, so they work offline.
|
||||
|
||||
|
||||
@@ -74,9 +74,11 @@ class DeckView(QWidget):
|
||||
self.preview.cleared.connect(self._clear_selection)
|
||||
|
||||
split = QSplitter(Qt.Orientation.Horizontal)
|
||||
split.addWidget(card_frame("My deck", self.mine))
|
||||
split.addWidget(card_frame("Preview", self.preview))
|
||||
split.addWidget(card_frame("Opponent", self.opp))
|
||||
self.my_frame = card_frame("My deck", self.mine)
|
||||
self.preview_frame = card_frame("Preview", self.preview)
|
||||
self.opp_frame = card_frame("Opponent", self.opp)
|
||||
for frame in (self.my_frame, self.preview_frame, self.opp_frame):
|
||||
split.addWidget(frame)
|
||||
split.setStretchFactor(0, 3)
|
||||
split.setStretchFactor(1, 2)
|
||||
split.setStretchFactor(2, 3)
|
||||
@@ -86,6 +88,12 @@ class DeckView(QWidget):
|
||||
lay.setContentsMargins(0, 0, 0, 0)
|
||||
lay.addWidget(split)
|
||||
|
||||
def show_panels(self, my_deck: bool, preview: bool, opp_deck: bool) -> None:
|
||||
self.my_frame.setVisible(my_deck)
|
||||
self.preview_frame.setVisible(preview)
|
||||
self.opp_frame.setVisible(opp_deck)
|
||||
self.setVisible(my_deck or preview or opp_deck)
|
||||
|
||||
def _clear_selection(self) -> None:
|
||||
for lst in (self.mine, self.opp):
|
||||
lst.setCurrentItem(None)
|
||||
|
||||
@@ -39,7 +39,16 @@ from .toggles import StayOpenMenu, Toggles
|
||||
from .turn_view import TURN_DEFAULTS_OFF, TURN_TOGGLES, TurnView
|
||||
|
||||
REFRESH_MS = 150
|
||||
DECK_TOGGLES = [("preview", "Card preview pane")]
|
||||
# Panels of the Match page that can be hidden (rows disappear when all their panels are hidden).
|
||||
SECTION_TOGGLES = [
|
||||
("you", "You"),
|
||||
("match", "Match"),
|
||||
("opponent", "Opponent"),
|
||||
("turns", "Turn stats"),
|
||||
("my_deck", "My deck"),
|
||||
("preview", "Preview"),
|
||||
("opp_deck", "Opponent's cards"),
|
||||
]
|
||||
VIEWS = ["Match", "History"]
|
||||
MATCH, HISTORY = 0, 1
|
||||
|
||||
@@ -91,7 +100,7 @@ class MainWindow(QMainWindow):
|
||||
self._settings = QSettings("mtga-assistant", "mtga-assistant")
|
||||
|
||||
self.toggles = [
|
||||
Toggles("deck", DECK_TOGGLES, parent=self),
|
||||
Toggles("sections", SECTION_TOGGLES, parent=self),
|
||||
Toggles("match", MATCH_TOGGLES, parent=self),
|
||||
Toggles("turn", TURN_TOGGLES, TURN_DEFAULTS_OFF, parent=self),
|
||||
]
|
||||
@@ -244,14 +253,22 @@ class MainWindow(QMainWindow):
|
||||
def _fill_customize(self) -> None:
|
||||
menu = self.customize_menu
|
||||
menu.clear()
|
||||
self.toggles[1].fill_menu(menu) # match panels
|
||||
for title, tg in (("Turn stats", self.toggles[2]), ("My deck sections", self.my_sections),
|
||||
("Opponent sections", self.opp_sections), ("Preview", self.toggles[0])):
|
||||
sub = StayOpenMenu(title, menu)
|
||||
tg.fill_menu(sub)
|
||||
menu.addMenu(sub)
|
||||
menu.addSeparator()
|
||||
menu.addAction("Arrange sections and stats…").triggered.connect(self._open_arrange)
|
||||
for heading, tg in (("Sections", self.toggles[0]), ("Player panel details", self.toggles[1])):
|
||||
title = menu.addAction(heading)
|
||||
title.setEnabled(False) # a heading, not an option
|
||||
font = title.font()
|
||||
font.setBold(True)
|
||||
title.setFont(font)
|
||||
tg.fill_menu(menu)
|
||||
menu.addSeparator()
|
||||
# Deck sections and turn stats (order and visibility) live in the Arrange dialog.
|
||||
menu.addAction("Arrange deck sections and turn stats…").triggered.connect(self._open_arrange)
|
||||
|
||||
def _apply_sections(self) -> None:
|
||||
on = self.toggles[0].on
|
||||
self.match_view.show_panels(you=on("you"), match=on("match"), opponent=on("opponent"),
|
||||
turns=on("turns"))
|
||||
self.deck_view.show_panels(my_deck=on("my_deck"), preview=on("preview"), opp_deck=on("opp_deck"))
|
||||
|
||||
def _open_arrange(self) -> None:
|
||||
ArrangeDialog(self._arrangeable(), "Arrange sections and stats", self).exec()
|
||||
@@ -380,16 +397,20 @@ class MainWindow(QMainWindow):
|
||||
if self._rendered.get(index) == key:
|
||||
return
|
||||
self._rendered[index] = key
|
||||
self._render_header(t)
|
||||
self.deck_view.preview.parentWidget().setVisible(self.toggles[0].on("preview"))
|
||||
self._render_header(t, show_match=index == MATCH)
|
||||
self._apply_sections()
|
||||
if index == MATCH:
|
||||
self.deck_view.render(t)
|
||||
self.match_view.render(t, self.now_ms())
|
||||
self.turn_view.render(t)
|
||||
|
||||
def _render_header(self, t: MatchTracker) -> None:
|
||||
def _render_header(self, t: MatchTracker, show_match: bool = True) -> None:
|
||||
g = t.game
|
||||
if g is None:
|
||||
if not show_match:
|
||||
# The match summary belongs to the Match tab only.
|
||||
self.header.setText("")
|
||||
self.header.setToolTip("")
|
||||
elif g is None:
|
||||
self.header.setText("<span style='color:#8b949c'>Waiting for a match…</span>")
|
||||
else:
|
||||
parts = [f"<b>vs {t.opponent_name or 'opponent'}</b>"]
|
||||
|
||||
@@ -214,7 +214,8 @@ class MatchView(QWidget):
|
||||
grid.addWidget(w, row, 0, Qt.AlignmentFlag.AlignHCenter)
|
||||
grid.setRowStretch(7, 1)
|
||||
|
||||
top = QWidget()
|
||||
self.turn_view = turn_view
|
||||
top = self.top = QWidget()
|
||||
top_lay = QHBoxLayout(top)
|
||||
top_lay.setContentsMargins(0, 0, 0, 0)
|
||||
top_lay.addWidget(self.me, 3)
|
||||
@@ -233,11 +234,26 @@ class MatchView(QWidget):
|
||||
lay = QVBoxLayout(self)
|
||||
lay.setContentsMargins(0, 0, 0, 0)
|
||||
lay.addWidget(self.split)
|
||||
self._panels = {"you": True, "match": True, "opponent": True}
|
||||
self._has_game = False
|
||||
|
||||
def show_panels(self, you: bool, match: bool, opponent: bool, turns: bool) -> None:
|
||||
"""Hide/show panels; a row with every panel hidden collapses out of the splitter."""
|
||||
self._panels = {"you": you, "match": match, "opponent": opponent}
|
||||
self.top.setVisible(you or match or opponent)
|
||||
self.turn_view.setVisible(turns)
|
||||
self._apply_panels()
|
||||
|
||||
def _apply_panels(self) -> None:
|
||||
# render() toggles these for "no game yet", so combine both conditions.
|
||||
self.me.setVisible(self._has_game and self._panels["you"])
|
||||
self.info.setVisible(self._has_game and self._panels["match"])
|
||||
self.opp.setVisible(self._has_game and self._panels["opponent"])
|
||||
|
||||
def render(self, t: MatchTracker, now_ms: int) -> None:
|
||||
g = t.game
|
||||
for w in (self.me, self.opp, self.info):
|
||||
w.setVisible(g is not None)
|
||||
self._has_game = g is not None
|
||||
self._apply_panels()
|
||||
if g is None:
|
||||
return
|
||||
self.me.render(g, g.my_seat, "You", now_ms)
|
||||
|
||||
Reference in new issue
Block a user