PanelOptimizer.py 41 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138
  1. """
  2. This file is part of RuneOptimizer.
  3. RuneOptimizer is free software: you can redistribute it and/or modify it
  4. under the terms of the GNU General Public License as published by the Free
  5. Software Foundation, either version 3 of the License, or (at your option)
  6. any later version.
  7. RuneOptimizer is distributed in the hope that it will be useful, but WITHOUT
  8. ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  9. FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  10. more details.
  11. You should have received a copy of the GNU General Public License along with
  12. RuneOptimizer. If not, see <https://www.gnu.org/licenses/>.
  13. """
  14. class PanelOptimizer(wx.Panel):
  15. """
  16. The optimizer form Panel.
  17. Parameters
  18. ----------
  19. unitId : string
  20. Currently selected unit ID (default None)
  21. unitStats : int[10]
  22. The current stats of the selected unit (HP, ATK, DEF, SPD, CRR, CRD,
  23. RES, ACC). (default is [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]).
  24. teamIds : string[]
  25. IDs of all teams, indexed by the order they appear in the team selector.
  26. unitIdSelectorIndex : int[]
  27. Array with the IDs of all units, in the same order as displayed in
  28. unitChoice, so an ID can be retrived knowing the choice
  29. selected index.
  30. optionsSizer : wx.BoxSizer
  31. Holds every widget that is hidden until a unit is selected.
  32. unitInfoBox : wx.StaticBox
  33. Box containig the non-editable elements with a unit info.
  34. unitChoice : wx.Choice
  35. Unit selecctor. Choosing a unit triggers selectUnit.
  36. statGrid : wx.Grid.grid
  37. Table with the unit base and current stats.
  38. runeLabelList : wx.StaticText[6]
  39. Labels with all the info about the currently equipped runes.
  40. minStatSlidList : wx.Slider[6]
  41. List of sliders for the minimum selectors for each stat.
  42. minStatTextList : wx.StaticText[6]
  43. List of text inputs for the minimum selectors for each stat.
  44. statCheckListList : wx.CheckListBox[2]
  45. Tho selctors to choose stats allowed in optimization.
  46. setChoiceList : wx.Choice[3]
  47. List of selector to pik rune sets.
  48. optSetCheckListList : wx.CheckListBox
  49. Selectors to choose optional rune sets.
  50. levelChoice : wx.Choice
  51. Selector to pick the level for the rune optimization.
  52. inventoryCheck : wx.Checkbox
  53. Checkbox to use only runes in the inventory.
  54. brokenCheck : wx.Checkbox
  55. Checkbox to enable broken sets.
  56. teamCheckList : wx.CheckboxList :
  57. List of selectable teams to exclude from the optimization.
  58. progressGauge : wx.Gauge
  59. A progress bar
  60. timer : wx.Timer
  61. Timer to check the update process for new output to display.
  62. process : wx.Process
  63. The update process.
  64. Methods
  65. -------
  66. selectAllTeams(event)
  67. Selects all teams in the list.
  68. deselectAllTeams(event)
  69. Deselects all teams in the list.
  70. selectUnit(event)
  71. Loads a unit info and enables optimizaton options.
  72. processResults(jsonData)
  73. Processes data obtained from RuneOptimizer.
  74. startOptimization(event)
  75. Prepares and runs a command optimization.
  76. checkProcess(event)
  77. Checks the process and update the progress bar.
  78. updateComplete(event)
  79. Called at process end, rediresct to the result view.
  80. minStatChangeBySlider(event)
  81. Changes text when a slider is changed.
  82. minStatChangeByText(event)
  83. Changes the slider when the text is changed.
  84. adaptStats(event)
  85. Sets all stats requeriments to the unit current values.
  86. resetsStats(event)
  87. Sets all stats requeriments to the unit base values.
  88. """
  89. unitId = None
  90. unitStats = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
  91. teamIds = []
  92. unidIdSelectorIndex = []
  93. optionsSizer = None
  94. unitInfoBox = None
  95. unitChoice = None
  96. statGrid = None
  97. runeLabelList = None
  98. minStatSlidList = None
  99. minStatTextList = None
  100. statCheckListList = None
  101. setChoiceList = None
  102. levelChoice = None
  103. inventoryCheck = None
  104. teamCheckList = None
  105. progressGauge = None
  106. timer = None
  107. process = None
  108. def __init__(self, parent, id=wx.ID_ANY):
  109. """Initializes the panel.
  110. Sets upt all the widgets.
  111. Parameters
  112. ----------
  113. parent : wx.*
  114. Panel parent.
  115. id : int, optional
  116. ID for the panel (default wx.ID_ANY).
  117. """
  118. # Parent constructor
  119. wx.Panel.__init__(self, parent=parent, id=id)
  120. # Prepare some fonts.
  121. monospaceFont = wx.Font(
  122. pointSize=8, family=wx.FONTFAMILY_TELETYPE,
  123. style=wx.FONTSTYLE_NORMAL, weight=wx.FONTWEIGHT_NORMAL
  124. )
  125. smallFont = wx.Font(
  126. pointSize=6, family=wx.FONTFAMILY_DEFAULT,
  127. style=wx.FONTSTYLE_NORMAL, weight=wx.FONTWEIGHT_NORMAL
  128. )
  129. # Sizer for all optimization options. Will be hidden until a unit is
  130. # selected.
  131. self.optionsSizer = wx.BoxSizer(wx.VERTICAL)
  132. # Unit info box
  133. self.unitInfoBox = wx.StaticBox(
  134. self, label="Select unit:", id=wx.ID_ANY, pos=(10, 0), size=(450, 300)
  135. )
  136. # Get data from all units and populate the unit selector
  137. cursor = conn.execute("SELECT id, name FROM units ORDER BY name")
  138. names = []
  139. for row in cursor:
  140. names.append(row[1])
  141. self.unidIdSelectorIndex.append(row[0])
  142. self.unitChoice =wx.Choice(
  143. parent=self.unitInfoBox, id=wx.ID_ANY, pos=(10, 0),
  144. size=(200, 30), choices=names
  145. )
  146. self.Bind(wx.EVT_CHOICE, self.selectUnit, self.unitChoice)
  147. # Stats table
  148. self.statGrid = wx.grid.Grid(
  149. parent=self.unitInfoBox, id=wx.ID_ANY, pos=(0, 30), size=(165, 220)
  150. )
  151. self.statGrid.CreateGrid(
  152. numRows=10, numCols=2
  153. )
  154. self.statGrid.EnableEditing(False)
  155. self.statGrid.SetDefaultCellAlignment(
  156. horiz=wx.ALIGN_RIGHT, vert=wx.ALIGN_CENTRE
  157. )
  158. self.statGrid.SetDefaultCellFont(monospaceFont)
  159. self.statGrid.SetColSize(col=0, width=50)
  160. self.statGrid.SetColLabelValue(col=0, value="Base")
  161. self.statGrid.SetColSize(col=0, width=50)
  162. self.statGrid.SetColLabelValue(col=1, value="Current")
  163. self.statGrid.SetRowLabelSize(width=35)
  164. self.statGrid.SetColLabelSize(height=20)
  165. self.statGrid.SetRowSize(row=0, height=20)
  166. self.statGrid.SetRowSize(row=1, height=20)
  167. self.statGrid.SetRowSize(row=2, height=20)
  168. self.statGrid.SetRowSize(row=3, height=20)
  169. self.statGrid.SetRowSize(row=4, height=20)
  170. self.statGrid.SetRowSize(row=5, height=20)
  171. self.statGrid.SetRowSize(row=6, height=20)
  172. self.statGrid.SetRowSize(row=7, height=20)
  173. self.statGrid.SetRowSize(row=8, height=20)
  174. self.statGrid.SetRowSize(row=9, height=20)
  175. self.statGrid.SetRowLabelValue(row=0, value=" HP")
  176. self.statGrid.SetRowLabelValue(row=1, value="ATK")
  177. self.statGrid.SetRowLabelValue(row=2, value="DEF")
  178. self.statGrid.SetRowLabelValue(row=3, value="SPD")
  179. self.statGrid.SetRowLabelValue(row=4, value="CRR")
  180. self.statGrid.SetRowLabelValue(row=5, value="CRD")
  181. self.statGrid.SetRowLabelValue(row=6, value="RES")
  182. self.statGrid.SetRowLabelValue(row=7, value="ACC")
  183. self.statGrid.SetRowLabelValue(row=8, value="EHP")
  184. self.statGrid.SetRowLabelValue(row=9, value="DMG")
  185. #self.unitContent.Add(self.statGrid)
  186. #Rune set list
  187. runeBoxList = [
  188. wx.StaticBox(
  189. parent=self.unitInfoBox, label="Slot1:", id=wx.ID_ANY,
  190. pos=(265, 30), size=(80, 115)
  191. ),
  192. wx.StaticBox(
  193. parent=self.unitInfoBox, label="Slot2:", id=wx.ID_ANY,
  194. pos=(350, 30), size=(80, 115)
  195. ),
  196. wx.StaticBox(
  197. parent=self.unitInfoBox, label="Slot3:", id=wx.ID_ANY,
  198. pos=(350, 150), size=(80, 115)
  199. ),
  200. wx.StaticBox(
  201. parent=self.unitInfoBox, label="Slot4:", id=wx.ID_ANY,
  202. pos=(265, 150), size=(80, 115)
  203. ),
  204. wx.StaticBox(
  205. parent=self.unitInfoBox, label="Slot5:", id=wx.ID_ANY,
  206. pos=(180, 150), size=(80, 115)
  207. ),
  208. wx.StaticBox(
  209. parent=self.unitInfoBox, label="Slot6:", id=wx.ID_ANY,
  210. pos=(180, 30), size=(80, 115)
  211. )
  212. ]
  213. self.runeLabelList = [
  214. wx.StaticText(
  215. parent=runeBoxList[0], id=wx.ID_ANY, label="",
  216. pos=(0, 0), size=(80, 115)
  217. ),
  218. wx.StaticText(
  219. parent=runeBoxList[1], id=wx.ID_ANY, label="",
  220. pos=(0, 0), size=(80, 115)
  221. ),
  222. wx.StaticText(
  223. parent=runeBoxList[2], id=wx.ID_ANY, label="",
  224. pos=(0, 0), size=(80, 115)
  225. ),
  226. wx.StaticText(
  227. parent=runeBoxList[3], id=wx.ID_ANY, label="",
  228. pos=(0, 0), size=(80, 115)
  229. ),
  230. wx.StaticText(
  231. parent=runeBoxList[4], id=wx.ID_ANY, label="",
  232. pos=(0, 0), size=(80, 115)
  233. ),
  234. wx.StaticText(
  235. parent=runeBoxList[5], id=wx.ID_ANY, label="",
  236. pos=(0, 0), size=(80, 115)
  237. )
  238. ]
  239. monospaceFont.PointSize -= 2
  240. for i in range(0, 6):
  241. runeBoxList[i].SetFont(monospaceFont)
  242. monospaceFont.PointSize += 2
  243. # Min stats
  244. minStatBox = wx.StaticBox(
  245. parent=self, label="Min. stats:", id=wx.ID_ANY,
  246. pos=(470, 0), size=(240, 300)
  247. )
  248. wx.StaticText(
  249. parent=minStatBox, label="HP", id=wx.ID_ANY, pos=(0, 0), size=(30, 25)
  250. )
  251. wx.StaticText(
  252. parent=minStatBox, label="ATK", id=wx.ID_ANY,
  253. pos=(0, 25), size=(30, 25)
  254. )
  255. wx.StaticText(
  256. parent=minStatBox, label="DEF", id=wx.ID_ANY,
  257. pos=(0, 50), size=(30, 25)
  258. )
  259. wx.StaticText(
  260. parent=minStatBox, label="SPD", id=wx.ID_ANY,
  261. pos=(0, 75), size=(30, 25)
  262. )
  263. wx.StaticText(
  264. parent=minStatBox, label="CRR", id=wx.ID_ANY,
  265. pos=(0, 100), size=(30, 25)
  266. )
  267. wx.StaticText(
  268. parent=minStatBox, label="CRD", id=wx.ID_ANY,
  269. pos=(0, 125), size=(30, 25)
  270. )
  271. wx.StaticText(
  272. parent=minStatBox, label="RES", id=wx.ID_ANY,
  273. pos=(0, 150), size=(30, 25)
  274. )
  275. wx.StaticText(
  276. parent=minStatBox, label="ACC", id=wx.ID_ANY,
  277. pos=(0, 175), size=(30, 25)
  278. )
  279. wx.StaticText(
  280. parent=minStatBox, label="EHP", id=wx.ID_ANY,
  281. pos=(0, 200), size=(30, 25)
  282. )
  283. wx.StaticText(
  284. parent=minStatBox, label="DMG", id=wx.ID_ANY,
  285. pos=(0, 225), size=(30, 25)
  286. )
  287. self.minStatSlidList = [
  288. wx.Slider(
  289. parent=minStatBox, id=wx.ID_ANY, pos=(30, 0),
  290. size=(120, 25), name="slid0"
  291. ),
  292. wx.Slider(
  293. parent=minStatBox, id=wx.ID_ANY, pos=(30, 25),
  294. size=(120, 25), name="slid1"
  295. ),
  296. wx.Slider(
  297. parent=minStatBox, id=wx.ID_ANY, pos=(30, 50),
  298. size=(120, 25), name="slid2"
  299. ),
  300. wx.Slider(
  301. parent=minStatBox, id=wx.ID_ANY, pos=(30, 75),
  302. size=(120, 25), name="slid3"
  303. ),
  304. wx.Slider(
  305. parent=minStatBox, id=wx.ID_ANY, pos=(30, 100),
  306. size=(120, 25), name="slid4"
  307. ),
  308. wx.Slider(
  309. parent=minStatBox, id=wx.ID_ANY, pos=(30, 125),
  310. size=(120, 25), name="slid5"
  311. ),
  312. wx.Slider(
  313. parent=minStatBox, id=wx.ID_ANY, pos=(30, 150),
  314. size=(120, 25), name="slid6"
  315. ),
  316. wx.Slider(
  317. parent=minStatBox, id=wx.ID_ANY, pos=(30, 175),
  318. size=(120, 25), name="slid7"
  319. ),
  320. wx.Slider(
  321. parent=minStatBox, id=wx.ID_ANY, pos=(30, 200),
  322. size=(120, 25), name="slid8"
  323. ),
  324. wx.Slider(
  325. parent=minStatBox, id=wx.ID_ANY, pos=(30, 225),
  326. size=(120, 25), name="slid9"
  327. )
  328. ]
  329. for i in range(0, 10):
  330. self.minStatSlidList[i].SetMin(0)
  331. self.minStatSlidList[i].SetMax(0)
  332. self.minStatSlidList[i].SetValue(0)
  333. self.Bind(
  334. wx.EVT_SCROLL, self.minStatChangeBySlider, self.minStatSlidList[i]
  335. )
  336. self.minStatTextList = [
  337. wx.TextCtrl(
  338. parent=minStatBox, id=wx.ID_ANY, value="",
  339. pos=(155, 0), size=(65, 25), name="tx0",
  340. style=wx.TE_RIGHT|wx.TE_PROCESS_ENTER|wx.TE_PROCESS_TAB
  341. ),
  342. wx.TextCtrl(
  343. parent=minStatBox, id=wx.ID_ANY, value="",
  344. pos=(155, 25), size=(65, 25), name="tx1",
  345. style=wx.TE_RIGHT|wx.TE_PROCESS_ENTER|wx.TE_PROCESS_TAB
  346. ),
  347. wx.TextCtrl(
  348. parent=minStatBox, id=wx.ID_ANY, value="",
  349. pos=(155, 50), size=(65, 25), name="tx2",
  350. style=wx.TE_RIGHT|wx.TE_PROCESS_ENTER|wx.TE_PROCESS_TAB
  351. ),
  352. wx.TextCtrl(
  353. parent=minStatBox, id=wx.ID_ANY, value="",
  354. pos=(155, 75), size=(65, 25), name="tx3",
  355. style=wx.TE_RIGHT|wx.TE_PROCESS_ENTER|wx.TE_PROCESS_TAB
  356. ),
  357. wx.TextCtrl(
  358. parent=minStatBox, id=wx.ID_ANY, value="",
  359. pos=(155, 100), size=(65, 25), name="tx4",
  360. style=wx.TE_RIGHT|wx.TE_PROCESS_ENTER|wx.TE_PROCESS_TAB
  361. ),
  362. wx.TextCtrl(
  363. parent=minStatBox, id=wx.ID_ANY, value="",
  364. pos=(155, 125), size=(65, 25), name="tx5",
  365. style=wx.TE_RIGHT|wx.TE_PROCESS_ENTER|wx.TE_PROCESS_TAB
  366. ),
  367. wx.TextCtrl(
  368. parent=minStatBox, id=wx.ID_ANY, value="",
  369. pos=(155, 150), size=(65, 25), name="tx6",
  370. style=wx.TE_RIGHT|wx.TE_PROCESS_ENTER|wx.TE_PROCESS_TAB
  371. ),
  372. wx.TextCtrl(
  373. parent=minStatBox, id=wx.ID_ANY, value="",
  374. pos=(155, 175), size=(65, 25), name="tx7",
  375. style=wx.TE_RIGHT|wx.TE_PROCESS_ENTER|wx.TE_PROCESS_TAB
  376. ),
  377. wx.TextCtrl(
  378. parent=minStatBox, id=wx.ID_ANY, value="",
  379. pos=(155, 200), size=(65, 25), name="tx8",
  380. style=wx.TE_RIGHT|wx.TE_PROCESS_ENTER|wx.TE_PROCESS_TAB
  381. ),
  382. wx.TextCtrl(
  383. parent=minStatBox, id=wx.ID_ANY, value="",
  384. pos=(155, 225), size=(65, 25), name="tx9",
  385. style=wx.TE_RIGHT|wx.TE_PROCESS_ENTER|wx.TE_PROCESS_TAB
  386. )
  387. ]
  388. for i in range(0, 9):
  389. self.Bind(
  390. wx.EVT_TEXT,
  391. self.minStatChangeByText, self.minStatTextList[i]
  392. )
  393. minStatsReset = wx.Button(
  394. parent=minStatBox, id=wx.ID_ANY, pos=(10, 250),
  395. size=(100, 20), style=wx.LC_REPORT, label="Reset all"
  396. )
  397. self.Bind(wx.EVT_BUTTON, self.resetStats, minStatsReset)
  398. minStatsAdapt = wx.Button(
  399. parent=minStatBox, id=wx.ID_ANY, pos=(120, 250),
  400. size=(100, 20), style=wx.LC_REPORT, label="Adapt all")
  401. self.Bind(wx.EVT_BUTTON, self.adaptStats, minStatsAdapt)
  402. self.optionsSizer.Add(minStatBox)
  403. # Allowed main stats for even slots
  404. names = [
  405. ["HP ", "HP% ", "ATK ", "ATK%", "DEF ", "DEF%"],
  406. ["SPD ", "CRR ", "CRD ", "RES ", "ACC "]
  407. ]
  408. statBox = wx.StaticBox(
  409. self, id=wx.ID_ANY, label="Main stats (2, 4, 6):",
  410. pos=(10, 300), size=(150, 190)
  411. )
  412. self.statCheckListList = [
  413. wx.CheckListBox(
  414. parent=statBox, id=wx.ID_ANY, pos=(5, 5),
  415. size=(70, 155), choices=names[0]
  416. ),
  417. wx.CheckListBox(
  418. parent=statBox, id=wx.ID_ANY, pos=(70, 5),
  419. size=(70, 155), choices=names[1]
  420. )
  421. ]
  422. self.optionsSizer.Add(statBox)
  423. # Rune sets
  424. names = [
  425. "", "ENERGY ", "GUARD ", "SWIFT ", "BLADE ", "RAGE ",
  426. "FOCUS ", "ENDURE ", "FATAL ", "DESPAIR", "VAMPIRE",
  427. "VIOLENT", "NEMESIS", "WILL ", "SHIELD ", "REVENGE", "DESTROY",
  428. "FIGHT ", "DETERMI", "ENHANCE", "ACCURAC", "TOLERAN"
  429. ]
  430. setBox = wx.StaticBox(
  431. self, label="Rune Sets:", id=wx.ID_ANY,
  432. pos=(170, 300), size=(115, 120)
  433. )
  434. self.setChoiceList = [
  435. wx.Choice(
  436. parent=setBox, id=wx.ID_ANY, pos=(5, 0),
  437. size=(100, 30), choices=names
  438. ),
  439. wx.Choice(
  440. parent=setBox, id=wx.ID_ANY, pos=(5, 30),
  441. size=(100, 30), choices=names
  442. ),
  443. wx.Choice(
  444. parent=setBox, id=wx.ID_ANY, pos=(5, 60),
  445. size=(100, 30), choices=names
  446. )
  447. ]
  448. self.optionsSizer.Add(setBox)
  449. # Rune level selector
  450. levelBox = wx.StaticBox(
  451. self, label="Rune Level:", id=wx.ID_ANY,
  452. pos=(170, 420), size=(115, 70)
  453. )
  454. self.levelChoice = wx.Choice(
  455. parent=levelBox, id=wx.ID_ANY, pos=(5, 0),
  456. choices=["Current", "+ 12", " + 15"]
  457. )
  458. self.optionsSizer.Add(levelBox)
  459. optSetBox = wx.StaticBox(
  460. self, label="Other Rune Sets:", id=wx.ID_ANY,
  461. pos=(290, 300), size=(110, 190)
  462. )
  463. self.optionsSizer.Add(optSetBox)
  464. self.optSetCheckList = wx.CheckListBox(
  465. parent=optSetBox, id=wx.ID_ANY, pos=(5, 5),
  466. size=(100, 160), choices=names[1:]
  467. )
  468. # Team list
  469. teams = []
  470. cursor = conn.execute("""
  471. SELECT
  472. id, name, priority
  473. FROM teams
  474. ORDER BY priority DESC;
  475. """)
  476. for row in cursor:
  477. self.teamIds.append(row[0])
  478. teams.append(str(row[1]) + " (" + str(row[2]) + ")")
  479. teamsBox = wx.StaticBox(
  480. parent=self, label="Exclude runes from units in teams",
  481. id=wx.ID_ANY, pos=(410, 300), size=(260, 170)
  482. )
  483. self.optionsSizer.Add(teamsBox)
  484. self.teamCheckList = wx.CheckListBox(
  485. parent=teamsBox, id=wx.ID_ANY,
  486. pos=(5, 5), size=(250, 110), choices=teams
  487. )
  488. btAllTeams = wx.Button(
  489. parent=teamsBox, id=wx.ID_ANY,
  490. pos=(5, 115), size=(120, 20), label="Select all"
  491. )
  492. btNoTeams = wx.Button(
  493. parent=teamsBox, id=wx.ID_ANY,
  494. pos=(130, 115), size=(120, 20), label="Deselect all"
  495. )
  496. self.Bind(wx.EVT_BUTTON, self.selectAllTeams, btAllTeams)
  497. self.Bind(wx.EVT_BUTTON, self.deselectAllTeams, btNoTeams)
  498. # Broken sets option
  499. self.brokenCheck = wx.CheckBox(
  500. parent=self, id=wx.ID_ANY, label="Allow broken sets",
  501. pos=(400, 470), size=(180, 20)
  502. )
  503. self.optionsSizer.Add(self.brokenCheck)
  504. # Inventory only option
  505. self.inventoryCheck = wx.CheckBox(
  506. parent=self, id=wx.ID_ANY, label="Only runes in storage",
  507. pos=(560, 470), size=(180, 20)
  508. )
  509. self.optionsSizer.Add(self.inventoryCheck)
  510. # Button to start
  511. btOptimize = wx.Button(
  512. parent=self, id=wx.ID_ANY, pos=(600, 500),
  513. size=(100, 40), style=wx.LC_REPORT, label="OPTIMIZE"
  514. )
  515. self.optionsSizer.Add(btOptimize)
  516. self.Bind(wx.EVT_BUTTON, self.startOptimization, btOptimize)
  517. # Progress bar
  518. self.progressGauge = wx.Gauge(
  519. parent=self, id=wx.ID_ANY, range=20,
  520. pos=(50, 485), size=(500, 40), style=wx.GA_HORIZONTAL
  521. )
  522. # By default, hide all optimization options
  523. self.optionsSizer.ShowItems(False)
  524. def selectAllTeams(self, event = None):
  525. """Selects all teams in the list.
  526. Parameters
  527. ----------
  528. event : wxEvent, optional
  529. The event that triggered the call (default is None).
  530. """
  531. for i in range(0, len(self.teamIds)):
  532. self.teamCheckList.Check(i, True)
  533. def deselectAllTeams(self, event = None):
  534. """Deselects all teams in the list.
  535. Parameters
  536. ----------
  537. event : wxEvent, optional
  538. The event that triggered the call (default is None).
  539. """
  540. for i in range(0, len(self.teamIds)):
  541. self.teamCheckList.Check(i, False)
  542. def selectUnit(self, event = None):
  543. """Loads a unit info and enables optimizaton options.
  544. Called when a unit is selected in unitChoice. If called from an
  545. an event, the unit selected in unitChoice gets priority. When
  546. manually called, it uses unitId, so it must be set beforehand.
  547. Parameters
  548. ----------
  549. event : wxEvent, optional
  550. The event that triggered the call (default is None).
  551. """
  552. # If its called from an event, it means a unit has been selected in this
  553. # panel selector.
  554. if event != None:
  555. self.unitId = \
  556. self.unidIdSelectorIndex[self.unitChoice.GetSelection()]
  557. # It it was not called from an event, it uses self.unitId and sets the
  558. # selected unit in the unit selector automatically.
  559. else:
  560. for i in range(0, len(self.unidIdSelectorIndex)):
  561. if self.unidIdSelectorIndex[i] == self.unitId:
  562. self.unitChoice.SetSelection(i)
  563. break
  564. # Get the unit details
  565. cursor = conn.execute("""
  566. SELECT
  567. base_hp,
  568. base_atk,
  569. base_def,
  570. base_spd,
  571. base_crr,
  572. base_crd,
  573. base_res,
  574. base_acc,
  575. current_hp,
  576. current_atk,
  577. current_def,
  578. current_spd,
  579. current_crr,
  580. current_crd,
  581. current_res,
  582. current_acc,
  583. id,
  584. name
  585. FROM units
  586. WHERE
  587. id = """ + self.unitId + """;
  588. """)
  589. row = cursor.fetchone()
  590. # First, set sliders max values
  591. self.minStatSlidList[0].SetMax(100000) #HP
  592. self.minStatSlidList[1].SetMax(5000) #ATK
  593. self.minStatSlidList[2].SetMax(5000) #DEF
  594. self.minStatSlidList[3].SetMax(500) #SPD
  595. self.minStatSlidList[4].SetMax(100) #CRR
  596. self.minStatSlidList[5].SetMax(500) #CRD
  597. self.minStatSlidList[6].SetMax(100) #RES
  598. self.minStatSlidList[7].SetMax(85) #ACC
  599. self.minStatSlidList[8].SetMax(500000) #EHP
  600. self.minStatSlidList[9].SetMax(8000) #DMG
  601. self.unitInfoBox.SetLabel(row[17] + " #" + row[16])
  602. for i in range(0, 8):
  603. value = str(row[i])
  604. self.minStatSlidList[i].SetMin(int(value))
  605. if i > 3:
  606. value = value + "%"
  607. else:
  608. value = value + " "
  609. self.statGrid.SetCellValue(row=i, col=0, s=value)
  610. for i in range(0, 8):
  611. value = str(row[8 + i])
  612. self.minStatSlidList[i].SetValue(int(value))
  613. self.minStatTextList[i].SetValue(value)
  614. self.unitStats[i] = int(value)
  615. if i > 3:
  616. value = value + "%"
  617. else:
  618. value = value + " "
  619. self.statGrid.SetCellValue(row=i, col=1, s=value)
  620. # Galculate EHP and DMG
  621. baseHp = int(self.statGrid.GetCellValue(row=0, col=0))
  622. baseDef = int(self.statGrid.GetCellValue(row=2, col=0).replace("%", ""))
  623. baseEhp = math.ceil((((baseDef * 3.5) + 1140) * baseHp) / 1000)
  624. self.statGrid.SetCellValue(row=8, col=0, s=str(baseEhp))
  625. self.minStatSlidList[8].SetMin(baseEhp)
  626. currentHp = int(self.statGrid.GetCellValue(row=0, col=1))
  627. currentDef = \
  628. int(self.statGrid.GetCellValue(row=2, col=1).replace("%", ""))
  629. currentEhp = math.ceil((((currentDef * 3.5) + 1140) * currentHp) / 1000)
  630. self.statGrid.SetCellValue(row=8, col=1, s=str(currentEhp))
  631. self.minStatSlidList[8].SetValue(currentEhp)
  632. self.minStatTextList[8].SetValue(str(currentEhp))
  633. baseAtk = int(self.statGrid.GetCellValue(row=1, col=0))
  634. baseCrr = int(self.statGrid.GetCellValue(row=4, col=0).replace("%", ""))
  635. baseCrd = int(self.statGrid.GetCellValue(row=5, col=0).replace("%", ""))
  636. if (baseCrr > 100):
  637. # Dont use crit rate over 100
  638. baseCrr = 100
  639. baseDmg = math.ceil(
  640. (baseAtk * (100 - baseCrr) / 100) +
  641. (baseAtk * ( baseCrr / 100) * baseCrd / 100)
  642. )
  643. self.statGrid.SetCellValue(row=9, col=0, s=str(baseDmg))
  644. self.minStatSlidList[9].SetMin(baseDmg)
  645. currentAtk = int(self.statGrid.GetCellValue(row=1, col=1))
  646. currentCrr = \
  647. int(self.statGrid.GetCellValue(row=4, col=1).replace("%", ""))
  648. currentCrd = \
  649. int(self.statGrid.GetCellValue(row=5, col=1).replace("%", ""))
  650. if (currentCrr > 100):
  651. # Dont use crit rate over 100
  652. currentCrr = 100
  653. currentDmg = math.ceil(
  654. (currentAtk * (100 - currentCrr) / 100) + # Non-crit
  655. (currentAtk * ( currentCrr / 100) * currentCrd / 100) # Crit
  656. )
  657. self.statGrid.SetCellValue(row=9, col=1, s=str(currentDmg))
  658. self.minStatSlidList[9].SetValue(currentDmg)
  659. self.minStatTextList[9].SetValue(str(currentDmg))
  660. # Populate the runes
  661. for i in range(0, 6):
  662. self.runeLabelList[i].SetLabel("")
  663. cursor = conn.execute("""
  664. SELECT
  665. id, slot, type
  666. FROM runes
  667. WHERE
  668. unit = """ + self.unitId + """
  669. ORDER BY slot;
  670. """)
  671. i = 0
  672. currEvenStats = [0, 0, 0]
  673. currSets = [0] * 23;
  674. for row in cursor:
  675. currSets[row[2]] += 1
  676. label = ""
  677. label = label + set_names[row[2]] + "\n"
  678. # Get all stats
  679. cursorStats = conn.execute("""
  680. SELECT
  681. slot, stat, value, grind, enchant
  682. FROM rune_stats
  683. WHERE
  684. rune = """ + row[0] + """
  685. ORDER BY slot;
  686. """)
  687. j = -1
  688. for rowStats in cursorStats:
  689. if (int(row[1]) == 2 and rowStats[0] == -1):
  690. currEvenStats[0] = rowStats[1]
  691. elif (int(row[1]) == 4 and rowStats[0] == -1):
  692. currEvenStats[1] = rowStats[1]
  693. elif (int(row[1]) == 6 and rowStats[0] == -1):
  694. currEvenStats[2] = rowStats[1]
  695. while (j != rowStats[0]):
  696. label = label + "\n"
  697. j = j + 1;
  698. label = label + \
  699. stat_names[rowStats[1]] + str(rowStats[2]).rjust(4) + ""
  700. if rowStats[3] > 0:
  701. label = label + " +" + str(rowStats[3])
  702. self.runeLabelList[i].SetLabel(label)
  703. i = i + 1
  704. # Try to infer data to set the default options, reset the rest
  705. # Except the team list, rune level and storage: never reset those.
  706. self.statCheckListList[0].SetCheckedItems(())
  707. self.statCheckListList[1].SetCheckedItems(())
  708. for i in range(0, 3):
  709. if currEvenStats[i] == 1: # HP
  710. self.statCheckListList[0].Check(0, True)
  711. elif currEvenStats[i] == 2: # HP%
  712. self.statCheckListList[0].Check(1, True)
  713. elif currEvenStats[i] == 3: # ATK
  714. self.statCheckListList[0].Check(2, True)
  715. elif currEvenStats[i] == 4: # ATK%
  716. self.statCheckListList[0].Check(3, True)
  717. elif currEvenStats[i] == 5: # DEF
  718. self.statCheckListList[0].Check(4, True)
  719. elif currEvenStats[i] == 6: # DEF%
  720. self.statCheckListList[0].Check(5, True)
  721. elif currEvenStats[i] == 8: # SPD
  722. self.statCheckListList[1].Check(0, True)
  723. elif currEvenStats[i] == 9: # CRR
  724. self.statCheckListList[1].Check(1, True)
  725. elif currEvenStats[i] == 10: # CRD
  726. self.statCheckListList[1].Check(2, True)
  727. elif currEvenStats[i] == 11: # RES
  728. self.statCheckListList[1].Check(3, True)
  729. elif currEvenStats[i] == 12: # ACC
  730. self.statCheckListList[1].Check(4, True)
  731. currSetList = [-1, -1, -1]
  732. j = 0
  733. for i in range(0, 23):
  734. if j < 3:
  735. # If a set of 2 has 4 or 2:
  736. if i in [1, 2, 4, 6, 7, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23]:
  737. if currSets[i] >= 4:
  738. currSetList[j] = i - 1
  739. currSetList[j + 1] = i - 1
  740. j += 2
  741. elif currSets[i] >= 2:
  742. currSetList[j] = i - 1
  743. j += 1
  744. # If a set of 4 has 4
  745. elif i in [3, 5, 8, 10, 11, 13]:
  746. if currSets[i] >= 4:
  747. currSetList[j] = i - 1
  748. j += 1
  749. # Rune set IDs 9 and 12 dont exist, so do a little trick with indexes.
  750. for i in range(0, 3):
  751. #if currSetList[i] != 0:
  752. actualId = currSetList[i] + 1
  753. if (actualId > 8):
  754. actualId -= 1
  755. if (actualId > 11):
  756. actualId -= 1
  757. self.setChoiceList[i].SetSelection(actualId)
  758. # Clear all optional sets
  759. self.optSetCheckList.SetCheckedItems(())
  760. self.optionsSizer.ShowItems(True)
  761. def startOptimization(self, event):
  762. """Prepares and runs a command optimization.
  763. Once is done, switches to the results view.
  764. Parameters
  765. ----------
  766. event : wxEvent, optional
  767. The event that triggered the call (default is None).
  768. """
  769. # Example call:
  770. # ../RuneOptimizer optimize 7223811472 -l 15
  771. #-e rage,blade --stats atk,crr,crd -h 10000 -f 10
  772. # TODO: Executable name for windows.
  773. command = "RuneOptimizer optimize "
  774. unitId = self.unitId
  775. command += unitId
  776. level = self.levelChoice.GetSelection()
  777. if level == 1:
  778. level = "12"
  779. elif level == 2:
  780. level = "15"
  781. else:
  782. level = "current"
  783. command += (" --level " + level)
  784. sets = ""
  785. for i in range (0, 3):
  786. selected = self.setChoiceList[i].GetString(
  787. self.setChoiceList[i].GetSelection()
  788. ).upper().replace(" ", "");
  789. for j in range(0, 22):
  790. name = set_names[j].upper()
  791. if len(name) > 7:
  792. name = name[0:7]
  793. if selected == name:
  794. sets += set_names[j].lower() + ","
  795. if len(sets) > 0:
  796. sets = sets[:-1]
  797. # TODO: ELSE ERROR
  798. command += (" --sets " + sets)
  799. stats = ""
  800. selected_stats = \
  801. self.statCheckListList[0].GetCheckedItems() + \
  802. self.statCheckListList[1].GetCheckedItems()
  803. for s in self.statCheckListList[0].GetCheckedItems():
  804. if s == 0:
  805. stats += "hpflat,"
  806. elif s == 1:
  807. stats += "hp,"
  808. elif s == 2:
  809. stats += "atkflat,"
  810. elif s == 3:
  811. stats += "atk,"
  812. elif s == 4:
  813. stats += "defflat,"
  814. elif s == 5:
  815. stats += "def,"
  816. for s in self.statCheckListList[1].GetCheckedItems():
  817. if s == 0:
  818. stats += "spd,"
  819. elif s == 1:
  820. stats += "crr,"
  821. elif s == 2:
  822. stats += "crd,"
  823. elif s == 3:
  824. stats += "res,"
  825. elif s == 4:
  826. stats += "acc,"
  827. if len(stats) > 0:
  828. stats = stats[:-1]
  829. # TODO: ELSE ERROR
  830. # Optional sets
  831. optSets = ""
  832. for s in self.optSetCheckList.GetCheckedItems():
  833. if s == 0:
  834. optSets += "energy,"
  835. elif s == 1:
  836. optSets += "guard,"
  837. elif s == 2:
  838. optSets += "swift,"
  839. elif s == 3:
  840. optSets += "blade,"
  841. elif s == 4:
  842. optSets += "rage,"
  843. elif s == 5:
  844. optSets += "focus,"
  845. elif s == 6:
  846. optSets += "endure,"
  847. elif s == 7:
  848. optSets += "fatal,"
  849. elif s == 8:
  850. optSets += "despair,"
  851. elif s == 9:
  852. optSets += "vampire,"
  853. elif s == 10:
  854. optSets += "violent,"
  855. elif s == 11:
  856. optSets += "nemesis,"
  857. elif s == 12:
  858. optSets += "will,"
  859. elif s == 13:
  860. optSets += "shield,"
  861. elif s == 14:
  862. optSets += "revenge,"
  863. elif s == 15:
  864. optSets += "destroy,"
  865. elif s == 16:
  866. optSets += "fight,"
  867. elif s == 17:
  868. optSets += "determination,"
  869. elif s == 18:
  870. optSets += "enhance,"
  871. elif s == 19:
  872. optSets += "accuracy,"
  873. elif s == 20:
  874. optSets += "tolerance,"
  875. if len(optSets) > 0:
  876. optSets = optSets[:-1]
  877. command += (" --opt-sets " + optSets)
  878. command += (" --stats " + stats)
  879. command += (" --min-hp " + str(self.minStatSlidList[0].GetValue()))
  880. command += (" --min-atk " + str(self.minStatSlidList[1].GetValue()))
  881. command += (" --min-def " + str(self.minStatSlidList[2].GetValue()))
  882. command += (" --min-spd " + str(self.minStatSlidList[3].GetValue()))
  883. command += (" --min-crr " + str(self.minStatSlidList[4].GetValue()))
  884. command += (" --min-crd " + str(self.minStatSlidList[5].GetValue()))
  885. command += (" --min-res " + str(self.minStatSlidList[6].GetValue()))
  886. command += (" --min-acc " + str(self.minStatSlidList[7].GetValue()))
  887. command += (" --min-ehp " + str(self.minStatSlidList[8].GetValue()))
  888. command += (" --min-dmg " + str(self.minStatSlidList[9].GetValue()))
  889. if self.inventoryCheck.GetValue():
  890. command += " --storage"
  891. if self.brokenCheck.GetValue():
  892. command += " --broken"
  893. if len(self.teamCheckList.GetCheckedItems()) > 0:
  894. command += " --no-teams "
  895. for team in self.teamCheckList.GetCheckedItems():
  896. command += str(self.teamIds[team]) + ","
  897. command = command[:-1]
  898. command += (" --gui ")
  899. print("Command: " + command)
  900. self.progressGauge.SetValue(0)
  901. # Timer ot periodically check on the process
  902. self.timer = wx.Timer(self)
  903. self.timer.Start(1000)
  904. self.Bind(wx.EVT_TIMER, self.checkProcess)
  905. # Create and execute the process
  906. self.Bind(wx.EVT_END_PROCESS, self.optimizationComplete)
  907. #print("Command: " + command)
  908. self.process = wx.Process(self)
  909. self.process.Redirect()
  910. wx.Execute(command, wx.EXEC_ASYNC, self.process)
  911. def checkProcess(self, event):
  912. """Checks the process output and updates progress bar.
  913. Parameters
  914. ----------
  915. event : wxEvent, optional
  916. The event that triggered the call.
  917. """
  918. if self.process is not None:
  919. stream = self.process.GetInputStream()
  920. if stream.CanRead():
  921. text = bytes.decode(stream.read())
  922. text = text[:-1] # Remove the last newline
  923. # Get only the last line
  924. if text.rfind("\n") != -1:
  925. text = text[text.rfind("\n") + 1:]
  926. # If the line is just a number, it's a progress indicator (1-20)
  927. if text.isnumeric() and int(text) <= 20:
  928. self.progressGauge.SetValue(int(text))
  929. else:
  930. self.timer.Stop()
  931. def optimizationComplete(self, event):
  932. """Called when the update process is complete.
  933. Hiddes the progress image, checks for errors in the output, prints a
  934. message annd sets self.updateDone and self.updateError.
  935. Parameters
  936. ----------
  937. event : wxEvent, optional
  938. The event that triggered the call.
  939. """
  940. self.timer.Stop()
  941. self.progressGauge.SetValue(20)
  942. stream = self.process.GetInputStream()
  943. jsonText = ""
  944. if stream.CanRead():
  945. text = bytes.decode(stream.read())
  946. text = text[:-1] # Remove the last newline
  947. # Get only the last line
  948. if text.rfind("\n") != -1:
  949. text = text[text.rfind("\n") + 1:]
  950. jsonText = text
  951. # DEBUG: Sample data.
  952. #self.unitId = "7223811472"
  953. #json = ""{"result_count":5000,"results":[
  954. # {"id":0,"rating":215,"hp":20461,"atk":2521,"dfc":845,"spd":137,"crr":63,"crd":167,"res":29,"acc":15,"ehp":83839,"dmg":5174,"runes":["22677809846","22920616295","21755980400","25633344349","26207902579","28512560500"]},
  955. # {"id":1,"rating":195,"hp":18876,"atk":2521,"dfc":853,"spd":137,"crr":60,"crd":174,"res":37,"acc":8,"ehp":77873,"dmg":5153,"runes":["22677809846","22920616295","27654723287","25633344349","26207902579","28512560500"]},
  956. # {"id":2,"rating":185,"hp":17730,"atk":2521,"dfc":862,"spd":147,"crr":60,"crd":164,"res":28,"acc":15,"ehp":73704,"dmg":5002,"runes":["21564691276","22920616295","27654723287","25633344349","26207902579","22348038576"]},
  957. # {"id":3,"rating":179,"hp":15810,"atk":2431,"dfc":1011,"spd":137,"crr":61,"crd":160,"res":27,"acc":15,"ehp":73968,"dmg":4804,"runes":["21564691276","22920616295","27444728625","22750814840","26670411873","22348038576"]},
  958. # {"id":4,"rating":176,"hp":15319,"atk":2530,"dfc":909,"spd":142,"crr":60,"crd":165,"res":28,"acc":15,"ehp":66202,"dmg":5035,"runes":["21564691276","16759622995","27654723287","22750814840","26207902579","22348038576"]}]}
  959. #
  960. print ("---- RESULT OUTPUT -------------------------------------------")
  961. print(jsonText)
  962. print ("--------------------------------------------------------------")
  963. if jsonText != "":
  964. data = json.loads(
  965. jsonText,
  966. object_hook=lambda d: SimpleNamespace(**d)
  967. )
  968. if data.result_count == 0:
  969. wx.MessageBox(
  970. parent=self,
  971. message="No results found for the current settings.",
  972. caption="No results found"
  973. )
  974. else:
  975. self.GetParent().frameResults.processResults(
  976. self.unitId, jsonText
  977. )
  978. self.GetParent().ChangeSelection(3)
  979. else:
  980. wx.MessageBox(
  981. parent=self,
  982. message="No data received from RuneOptimizer.",
  983. caption="Error"
  984. )
  985. def minStatChangeBySlider(self, event=None):
  986. """Changes text when a slider is changed.
  987. Doesn't do validation.
  988. Parameters
  989. ----------
  990. event : wxEvent, optional
  991. The event that triggered the call (default is None).
  992. """
  993. slidId = int(event.GetEventObject().GetName().replace("slid", ""))
  994. self.minStatTextList[slidId].SetValue(
  995. str(event.GetEventObject().GetValue())
  996. )
  997. def minStatChangeByText(self, event=None):
  998. """Changes the slider when the text is changed.
  999. Validates the text value.
  1000. Parameters
  1001. ----------
  1002. event : wxEvent, optional
  1003. The event that triggered the call (default is None).
  1004. """
  1005. textId = int(event.GetEventObject().GetName().replace("tx", ""))
  1006. if event.GetEventObject().GetValue().isdigit() == False and \
  1007. event.GetEventObject().GetValue() != "":
  1008. event.GetEventObject().SetValue(
  1009. str(self.minStatSlidList[textId].GetValue())
  1010. )
  1011. minValue = self.minStatSlidList[textId].GetMin()
  1012. maxValue = self.minStatSlidList[textId].GetMax()
  1013. if event.GetEventObject().GetValue().isdigit():
  1014. value = int(event.GetEventObject().GetValue())
  1015. else:
  1016. value = minValue
  1017. # Unbind scroll event of the slider, set value and rebind.
  1018. self.Unbind(wx.EVT_SCROLL, self.minStatSlidList[textId])
  1019. self.minStatSlidList[textId].SetValue(value)
  1020. self.Bind(
  1021. wx.EVT_SCROLL,
  1022. self.minStatChangeBySlider, self.minStatSlidList[textId]
  1023. )
  1024. def adaptStats(self, event=None):
  1025. """Sets all stats requeriments to the unit current values.
  1026. Parameters
  1027. ----------
  1028. event : wxEvent, optional
  1029. The event that triggered the call (default is None).
  1030. """
  1031. for i in range(0, 10):
  1032. self.minStatSlidList[i].SetValue(self.unitStats[i])
  1033. self.minStatTextList[i].SetValue(str(self.unitStats[i]))
  1034. def resetStats(self, event=None):
  1035. """Sets all stats requeriments to the unit base values.
  1036. Parameters
  1037. ----------
  1038. event : wxEvent, optional
  1039. The event that triggered the call (default is None).
  1040. """
  1041. for i in range(0, 10):
  1042. self.minStatSlidList[i].SetValue(self.minStatSlidList[i].GetMin())
  1043. self.minStatTextList[i].SetValue(
  1044. str(self.minStatSlidList[i].GetMin())
  1045. )