From 4bc692539d595dec783e6576f1568fbcaa0fef69 Mon Sep 17 00:00:00 2001 From: emkael Date: Fri, 21 Jun 2019 18:21:04 +0200 Subject: Phase mathes GUI --- jfr_playoff/gui/__init__.py | 9 ++ jfr_playoff/gui/frames/match.py | 239 +++++++++++++++++++++++++++++++++++++++- jfr_playoff/gui/tabs.py | 8 ++ 3 files changed, 255 insertions(+), 1 deletion(-) (limited to 'jfr_playoff') diff --git a/jfr_playoff/gui/__init__.py b/jfr_playoff/gui/__init__.py index 1ac43b1..df437d2 100644 --- a/jfr_playoff/gui/__init__.py +++ b/jfr_playoff/gui/__init__.py @@ -26,3 +26,12 @@ class PlayoffGUI(tk.Tk): def getDBs(self): return self.tabs['NetworkTab'].getDBList() + + def getMatches(self): + return self.tabs['MatchesTab'].getMatches() + + def getNewMatchID(self, match): + matches = self.tabs['MatchesTab'].getMatches() + if len(matches) > 0: + return max([m.getMatchID() for m in matches]) + 1 + return 1 diff --git a/jfr_playoff/gui/frames/match.py b/jfr_playoff/gui/frames/match.py index 3eea9e7..14d8ae8 100644 --- a/jfr_playoff/gui/frames/match.py +++ b/jfr_playoff/gui/frames/match.py @@ -140,7 +140,6 @@ class SwissesFrame(ScrollableFrame): self.swisses = WidgetRepeater(container, SwissSettingsFrame) self.swisses.pack(side=tk.TOP, fill=tk.BOTH, expand=True) -__all__ = ['SwissesFrame'] class MatchSelectionButton(SelectionButton): @property @@ -169,3 +168,241 @@ class MatchSelectionFrame(SelectionFrame): )).grid(row=idx+1, column=1, sticky=tk.W) +class BracketMatchSettingsFrame(GuiFrame): + SOURCE_TEAM=0 + SOURCE_BRACKET=1 + + def _enablePanels(self, *args): + for widget in self.teamWidgets: + widget.configure( + state=tk.NORMAL if self.source.get() == self.SOURCE_TEAM + else tk.DISABLED) + for widget in self.bracketWidgets: + widget.configure( + state=tk.NORMAL if self.source.get() == self.SOURCE_BRACKET + else tk.DISABLED) + + def _setPositions(self, positions): + self.positions = positions + + def _setLosers(self, matches): + self.losers = matches + + def _setWinners(self, matches): + self.winners = matches + + def renderContent(self): + self.source = tk.IntVar() + self.team = tk.StringVar() + self.positions = [] + self.winners = [] + self.losers = [] + + buttons = [ + ttk.Radiobutton( + self, variable=self.source, value=self.SOURCE_TEAM, + text='Konkretny team'), + ttk.Radiobutton( + self, variable=self.source, value=self.SOURCE_BRACKET, + text='Z drabinki')] + self.teamWidgets = [ + TeamList(self, self.team, self.team.get())] + self.bracketWidgets = [ + ttk.Label(self, text='Pozycje początkowe:'), + TeamSelectionButton( + self, prompt='Wybierz pozycje początkowe:', + dialogclass=PositionsSelectionFrame, + callback=self._setPositions), + ttk.Label(self, text='Zwycięzcy meczów:'), + MatchSelectionButton( + self, prompt='Wybierz mecze:', + dialogclass=MatchSelectionFrame, + callback=self._setWinners), + ttk.Label(self, text='Przegrani meczów:'), + MatchSelectionButton( + self, prompt='Wybierz mecze:', + dialogclass=MatchSelectionFrame, + callback=self._setLosers)] + + for idx, button in enumerate(buttons): + button.grid(row=idx, column=0, sticky=tk.W) + self.teamWidgets[0].grid(row=0, column=1, sticky=tk.W) + for idx, widget in enumerate(self.bracketWidgets): + widget.grid(row=1+idx/2, column=1+idx%2) + + self.source.trace('w', self._enablePanels) + self.source.set(self.SOURCE_TEAM) + +class MatchSettingsFrame(RepeatableFrame): + SCORE_SOURCE_DB = 0 + SCORE_SOURCE_LINK = 1 + SCORE_SOURCE_CUSTOM = 2 + + def _enablePanels(self, *args): + for val, fields in self.scoreWidgets.iteritems(): + for field in fields: + field.configure( + state=tk.NORMAL if self.source.get() == val + else tk.DISABLED) + if not self.scoreNotFinished.get(): + self.scoreWidgets[self.SCORE_SOURCE_CUSTOM][-2].configure( + state=tk.DISABLED) + + def renderContent(self): + self.matchID = self.winfo_toplevel().getNewMatchID(self) + (ttk.Label(self, text='Mecz #%d' % (self.matchID))).grid( + row=0, column=0, sticky=tk.W) + (ttk.Label(self, text='Link:')).grid(row=0, column=1, sticky=tk.E) + self.link = tk.StringVar() + (ttk.Entry(self, textvariable=self.link)).grid( + row=0, column=2, sticky=tk.W) + + bracketGroup = ttk.LabelFrame(self, text='Dane drabinki') + bracketGroup.grid(row=1, column=0, columnspan=3, sticky=tk.W+tk.E) + + homeTeam = ttk.LabelFrame(bracketGroup, text='Team gospodarzy') + homeTeam.grid(row=0, column=0, sticky=tk.W+tk.E) + awayTeam = ttk.LabelFrame(bracketGroup, text='Team gości') + awayTeam.grid(row=0, column=1, sticky=tk.W+tk.E) + + teamFrames = [homeTeam, awayTeam] + self.bracketSettings = [] + for frame in teamFrames: + bracket = BracketMatchSettingsFrame(frame) + bracket.grid(row=0, column=0, sticky=tk.N+tk.S+tk.W+tk.E) + self.bracketSettings.append(bracket) + + self.source = tk.IntVar() + self.source.trace('w', self._enablePanels) + + self.scoreDB = tk.StringVar() + self.scoreRound = tk.IntVar() + self.scoreTable = tk.IntVar() + self.scoreCustom = [tk.StringVar(), tk.StringVar()] + self.scoreNotFinished = tk.IntVar() + self.scoreNotFinished.trace('w', self._enablePanels) + self.scoreBoards = tk.IntVar() + + scoreGroup = ttk.LabelFrame(self, text='Dane wyniku meczu') + scoreGroup.grid(row=4, column=0, columnspan=3, sticky=tk.W+tk.E) + self.scoreWidgets = { + self.SCORE_SOURCE_DB: [ + DBSelectionField(scoreGroup, self.scoreDB, self.scoreDB.get()), + ttk.Label(scoreGroup, text='Runda:'), + tk.Spinbox( + scoreGroup, width=3, + textvariable=self.scoreRound, from_=1, to=999), + ttk.Label(scoreGroup, text='Stół:'), + tk.Spinbox( + scoreGroup, width=3, + textvariable=self.scoreTable, from_=1, to=999) + ], + self.SCORE_SOURCE_LINK: [ + ttk.Entry(scoreGroup, textvariable=self.link), + # TODO: TC support (Round/Session) + #ttk.Label(scoreGroup, text='Sesja:'), + #tk.Spinbox( + # scoreGroup, + #textvariable=self.scoreSession, from_=1, to=999), + #ttk.Label(scoreGroup, text='Runda:'), + #tk.Spinbox( + # scoreGroup, + #textvariable=self.scoreRound, from_=1, to=999), + ttk.Label(scoreGroup, text='Stół:'), + tk.Spinbox( + scoreGroup, width=3, + textvariable=self.scoreTable, from_=1, to=999) + ], + self.SCORE_SOURCE_CUSTOM: [ + ttk.Entry( + scoreGroup, textvariable=self.scoreCustom[0], width=3), + ttk.Label(scoreGroup, text=':'), + ttk.Entry( + scoreGroup, textvariable=self.scoreCustom[1], width=3), + ttk.Checkbutton( + scoreGroup, variable=self.scoreNotFinished, + text='mecz nie został zakończony, rozegrano:'), + tk.Spinbox( + scoreGroup, width=3, + textvariable=self.scoreBoards, from_=0, to=999), + ttk.Label(scoreGroup, text='rozdań') + ] + } + + (ttk.Radiobutton( + scoreGroup, variable=self.source, value=self.SCORE_SOURCE_DB, + text='Baza danych')).grid(row=0, column=0, sticky=tk.W) + self.scoreWidgets[self.SCORE_SOURCE_DB][0].grid( + row=0, column=1, columnspan=3) + for idx in range(1, 5): + self.scoreWidgets[self.SCORE_SOURCE_DB][idx].grid( + row=0, column=idx+3) + (ttk.Radiobutton( + scoreGroup, variable=self.source, value=self.SCORE_SOURCE_LINK, + text='Strona z wynikami')).grid(row=1, column=0, sticky=tk.W) + self.scoreWidgets[self.SCORE_SOURCE_LINK][0].grid( + row=1, column=1, columnspan=3) + self.scoreWidgets[self.SCORE_SOURCE_LINK][1].grid( + row=1, column=4) + self.scoreWidgets[self.SCORE_SOURCE_LINK][2].grid( + row=1, column=5) + (ttk.Radiobutton( + scoreGroup, variable=self.source, value=self.SCORE_SOURCE_CUSTOM, + text='Ustaw ręcznie')).grid(row=2, column=0, sticky=tk.W) + for idx in range(0, 3): + self.scoreWidgets[self.SCORE_SOURCE_CUSTOM][idx].grid( + row=2, column=idx+1) + self.scoreWidgets[self.SCORE_SOURCE_CUSTOM][3].grid( + row=2, column=4, columnspan=4) + for idx in range(4, 6): + self.scoreWidgets[self.SCORE_SOURCE_CUSTOM][idx].grid( + row=2, column=idx+5) + + self.source.set(self.SCORE_SOURCE_CUSTOM) + + + @classmethod + def info(cls): + return 'Nowy mecz' + + def getMatchID(self): + return self.matchID + +class MatchSeparator(RepeatableFrame): + def renderContent(self): + (ttk.Separator(self, orient=tk.HORIZONTAL)).pack( + side=tk.TOP, fill=tk.X, expand=True) + + @classmethod + def info(cls): + return 'Odstęp między meczami' + + +class MatchPhaseFrame(ScrollableFrame): + def _updateLinks(self, *args): + for match in self.matches.widgets: + if isinstance(match, MatchSettingsFrame): + match_link = match.link.get() + if not len(match_link) or match_link == self.previousLink: + match.link.set(self.link.get()) + self.previousLink = self.link.get() + + def renderContent(self, container): + self.previousLink = '' + headerFrame = tk.Frame(container) + headerFrame.pack(side=tk.TOP, fill=tk.X, expand=True) + (ttk.Label(headerFrame, text='Nazwa:')).pack(side=tk.LEFT) + self.name = tk.StringVar() + (ttk.Entry(headerFrame, textvariable=self.name)).pack(side=tk.LEFT) + (ttk.Label(headerFrame, text='Link:')).pack(side=tk.LEFT) + self.link = tk.StringVar() + (ttk.Entry(headerFrame, textvariable=self.link)).pack(side=tk.LEFT) + + self.matches = WidgetRepeater( + container, [MatchSettingsFrame, MatchSeparator]) + self.matches.pack(side=tk.TOP, fill=tk.BOTH, expand=True) + + self.link.trace('w', self._updateLinks) + + +__all__ = ['SwissesFrame', 'MatchPhaseFrame', 'MatchSettingsFrame'] diff --git a/jfr_playoff/gui/tabs.py b/jfr_playoff/gui/tabs.py index 3bace44..e72b3c3 100644 --- a/jfr_playoff/gui/tabs.py +++ b/jfr_playoff/gui/tabs.py @@ -164,6 +164,14 @@ class MatchesTab(PlayoffTab): def title(self): return 'Mecze' + def renderContent(self, container): + self.phase = MatchPhaseFrame(container, vertical=True) + self.phase.pack(side=tk.TOP, fill=tk.BOTH, expand=True) + + def getMatches(self): + return [w for w in self.phase.matches.widgets + if isinstance(w, MatchSettingsFrame)] + class SwissesTab(PlayoffTab): @property def title(self): -- cgit v1.2.3