gui.py 6.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. # coding: utf-8
  2. import os
  3. import typing
  4. from tkinter import Tk
  5. from tkinter import Button
  6. from tkinter import YES
  7. from tkinter import StringVar
  8. from tkinter import OptionMenu
  9. from tkinter import W
  10. from tkinter import E
  11. from tkinter import messagebox
  12. from tkinter.ttk import Combobox
  13. from tkinter.ttk import Treeview
  14. import time
  15. from synergine2.config import Config
  16. from opencombat.gui import Gui
  17. from opencombat.strategy.manager import TroopManager
  18. from opencombat.strategy.team.stash import TeamStash
  19. class SelectTroopsGui(Gui):
  20. def __init__(
  21. self,
  22. config: Config,
  23. master: Tk,
  24. team_stash: TeamStash,
  25. troop_manager: TroopManager,
  26. countries: typing.List[str],
  27. troops_dir_path: str = '.',
  28. ) -> None:
  29. super().__init__(config, master)
  30. self._master.title('Troops selection')
  31. self._countries = countries
  32. self._team_stash = team_stash
  33. self._troop_manager = troop_manager
  34. self._troops_dir_path = troops_dir_path
  35. self._countries_troops = {} # type: typing.Dict[str, typing.List[TeamModel]] # nopep8
  36. # Widgets
  37. self._selected_country_var = StringVar(self._master)
  38. self._selected_country_var.set(countries[0])
  39. self._selected_country_var.trace('w', self._country_changed)
  40. self._select_country_menu = OptionMenu(
  41. self._master,
  42. self._selected_country_var,
  43. *countries,
  44. )
  45. self._teams_var = StringVar(self._master)
  46. self._teams_list = Combobox(
  47. self._master,
  48. height=10,
  49. state='readonly',
  50. textvariable=self._teams_var,
  51. )
  52. self._add_troop_var = StringVar(self._master)
  53. self._add_troop_button = Button(
  54. self._master,
  55. textvariable=self._add_troop_var,
  56. command=self._add_troop,
  57. )
  58. self._add_troop_var.set('Add troop')
  59. self._remove_troop_var = StringVar(self._master)
  60. self._remove_troop_button = Button(
  61. self._master,
  62. textvariable=self._remove_troop_var,
  63. command=self._remove_troop,
  64. )
  65. self._remove_troop_var.set('Remove troop')
  66. self._troops_view = Treeview(
  67. self._master,
  68. columns=('Soldiers',),
  69. height=10,
  70. )
  71. self._troops_view.heading('#0', text='Team')
  72. self._troops_view.heading('#1', text='Soldiers')
  73. self._troops_view.column('#0', stretch=YES)
  74. self._troops_view.column('#1', stretch=YES)
  75. self._generate_troops_var = StringVar(self._master)
  76. self._generate_troops_button = Button(
  77. self._master,
  78. textvariable=self._generate_troops_var,
  79. command=self._generate_troops,
  80. )
  81. self._generate_troops_var.set('Generate troops')
  82. # Layout
  83. self._select_country_menu.grid(row=0, column=0, sticky=W)
  84. self._teams_list.grid(row=1, column=0, sticky=W)
  85. self._add_troop_button.grid(row=2, column=0, sticky=W)
  86. self._troops_view.grid(row=3, column=0, sticky=W)
  87. self._remove_troop_button.grid(row=4, column=0, sticky=W)
  88. self._generate_troops_button.grid(row=4, column=0, sticky=E)
  89. # Default behaviours
  90. self._selected_country_var.set(countries[0])
  91. self._country_changed()
  92. def _country_changed(self, *args, **kwargs) -> None:
  93. country = self._selected_country_var.get()
  94. self._logger.info('Change country to "{}"'.format(
  95. country,
  96. ))
  97. country_team_names = [
  98. t.name for
  99. t in self._team_stash.get_team_by_country(
  100. self._selected_country_var.get(),
  101. )
  102. ]
  103. self._logger.debug('Change teams for: "{}"'.format(country_team_names))
  104. self._teams_list['values'] = country_team_names
  105. self._teams_var.set(country_team_names[0])
  106. self._update_troops_view(country)
  107. def _add_troop(self, *args, **kwargs) -> None:
  108. if self._teams_var.get():
  109. country = self._selected_country_var.get()
  110. team_name = self._teams_var.get()
  111. self._logger.info('Add troop "{}" to country "{}" troops'.format(
  112. team_name,
  113. team_name,
  114. ))
  115. team_model = self._team_stash.get_team_by_name(
  116. team_name=team_name,
  117. team_country=country,
  118. )
  119. self._countries_troops.setdefault(country, []).append(
  120. team_model,
  121. )
  122. self._update_troops_view(country)
  123. def _remove_troop(self, *args, **kwargs) -> None:
  124. selecteds = self._troops_view.selection()
  125. for selected in selecteds:
  126. team_name = self._troops_view.item(selected)['text']
  127. country = self._selected_country_var.get()
  128. self._logger.info('Remove team "{}" from country "{}"'.format(
  129. team_name,
  130. country,
  131. ))
  132. team_model = self._team_stash.get_team_by_name(
  133. team_name=team_name,
  134. team_country=country,
  135. )
  136. self._countries_troops[country].remove(team_model)
  137. if selecteds:
  138. self._update_troops_view(country)
  139. def _update_troops_view(self, country: str) -> None:
  140. teams = self._countries_troops.get(country, [])
  141. self._troops_view.delete(*self._troops_view.get_children())
  142. for team in teams:
  143. self._troops_view.insert(
  144. '',
  145. 'end',
  146. text=team.name,
  147. values=('o' * len(team.units,))
  148. )
  149. def _generate_troops(self, *args, **kwargs) -> None:
  150. # Must have team(s) in all countries
  151. if len(self._countries_troops.keys()) == len(self._countries) \
  152. and all(self._countries_troops.values()):
  153. troops_file_path = os.path.join(
  154. self._troops_dir_path,
  155. 'troops_{}.xml'.format(str(time.time())),
  156. )
  157. self._logger.info('Generate troops into file "{}"'.format(
  158. troops_file_path,
  159. ))
  160. troops_xml = self._troop_manager.get_troop_dump(
  161. self._countries_troops,
  162. )
  163. with open(troops_file_path, 'w+') as file:
  164. file.write(troops_xml)
  165. else:
  166. messagebox.showinfo(
  167. 'Missing information',
  168. 'All countries must have teams',
  169. )