1 # -*- coding: utf-8 -*-
3 # GUIのメインフレームにおけるお守り検索Notebookのview
4 # 2013/12/15 written by kei9
11 class NoteBookAmuletView():
12 u""" メインのフレームのお守り検索タブ """
13 def __init__(self, frame):
17 self.update_filter_radio()
18 self._last_search_type = None
24 self.button_search = xrc.XRCCTRL(self.frame, "ButtonAmuletSearchSearch")
25 self.button_clear = xrc.XRCCTRL(self.frame, "ButtonAmuletSearchClear")
26 self.button_simulate = xrc.XRCCTRL(self.frame, "ButtonAmuletToSimulator")
27 self.ID_BUTTON_SEARCH = xrc.XRCID("ButtonAmuletSearchSearch")
28 self.ID_BUTTON_CLEAR = xrc.XRCID("ButtonAmuletSearchClear")
29 self.ID_BUTTON_SIMULATE = xrc.XRCID("ButtonAmuletToSimulator")
32 self.radiobox_amulet = xrc.XRCCTRL(self.frame, "RadioBoxAmulet")
33 self.radiobox_search_type = xrc.XRCCTRL(self.frame, "RadioBoxSearchType")
34 self.radiobox_filter = xrc.XRCCTRL(self.frame, "RadioBoxFilter")
37 self.grid_seeds = xrc.XRCCTRL(self.frame, "GridAmuletSeeds")
38 self.grid_seeds.CreateGrid(1, constnumbers.NUM_AMULET_SEEDS_GRID_COL)
39 self.grid_seeds.SetColLabelValue(0, constnumbers.LABEL_FORMAT_AMULET_SEEDS_GRID_COL1)
40 self.grid_seeds.SetColLabelValue(1, constnumbers.LABEL_FORMAT_AMULET_SEEDS_GRID_COL2)
41 self.grid_seeds.DisableDragGridSize()
42 self.grid_seeds.EnableEditing(False)
43 self.grid_seeds.SetRowLabelSize(30)
44 self.grid_seeds.SetSelectionMode(wx.grid.Grid.wxGridSelectRows)
47 self.spin_ctrl_skill1_val = xrc.XRCCTRL(self.frame, "SpinCtrlAmuletSearchSkill1Value")
48 self.spin_ctrl_skill2_val = xrc.XRCCTRL(self.frame, "SpinCtrlAmuletSearchSkill2Value")
49 self.spin_ctrl_slot_num = xrc.XRCCTRL(self.frame, "SpinCtrlAmuletSearchSlotNumber")
50 self.ID_SPIN_CTRL_SKILL1_VAL = xrc.XRCID("SpinCtrlAmuletSearchSkill1Value")
51 self.ID_SPIN_CTRL_SKILL2_VAL = xrc.XRCID("SpinCtrlAmuletSearchSkill2Value")
54 self.combo_box_skill1 = xrc.XRCCTRL(self.frame, "ComboBoxAmuletSearchSkill1")
55 self.combo_box_skill2 = xrc.XRCCTRL(self.frame, "ComboBoxAmuletSearchSkill2")
56 self.ID_COMBO_BOX_SKILL1 = xrc.XRCID("ComboBoxAmuletSearchSkill1")
57 self.ID_COMBO_BOX_SKILL2 = xrc.XRCID("ComboBoxAmuletSearchSkill2")
60 self.text_ctrl_result = xrc.XRCCTRL(self.frame, "TextCtrlAmuletSearchResult")
61 self.text_ctrl_seed2 = xrc.XRCCTRL(self.frame, "TextCtrlFixedSeed2")
63 # set min & max of slot
64 self.set_slot_minmax(constnumbers.SLOT_MIN, constnumbers.SLOT_MAX)
66 def _init_event(self):
68 self.grid_seeds.Bind(wx.EVT_SIZE, self.OnSeedGridSizeChanged)
69 self.combo_box_skill1.Bind(wx.EVT_COMBOBOX, self.OnComboSkill1Changed)
70 self.combo_box_skill2.Bind(wx.EVT_COMBOBOX, self.OnComboSkill2Changed)
71 self.radiobox_amulet.Bind(wx.EVT_RADIOBOX, self.OnRadioAmuletChanged)
72 self.radiobox_search_type.Bind(wx.EVT_RADIOBOX, self.OnRadioSearchTypeChanged)
73 self.radiobox_filter.Bind(wx.EVT_RADIOBOX, self.OnRadioFilterChanged)
75 def OnSeedGridSizeChanged(self, event):
76 u""" SeedGridサイズの変更時 """
77 width, height = self.grid_seeds.GetParent().GetSize()
78 each_width = (width-40) / (constnumbers.NUM_AMULET_SEEDS_GRID_COL) # consider margin size
79 #self.grid_seeds.SetRowLabelValue(0, u"")
80 for col in range(constnumbers.NUM_AMULET_SEEDS_GRID_COL):
81 self.grid_seeds.SetColSize(col, each_width)
83 def OnComboSkill1Changed(self, event):
84 u""" スキル1のコンボボックスの変更時 """
85 self.update_skill_minmax(1)
87 def OnComboSkill2Changed(self, event):
88 u""" スキル2のコンボボックスの変更時 """
89 self.update_skill_minmax(2)
91 def OnRadioAmuletChanged(self, event):
92 u""" お守り選択のラジオボタン変更時 """
93 self.update_skill_names()
94 self.update_skill_minmax()
96 def OnRadioSearchTypeChanged(self, event):
97 u""" お守り選択のラジオボタン変更時 """
98 search_type = self.get_selected_search_type()
99 if search_type == constnumbers.SEARCH_TYPE_FIXED_SEED2:
100 self.text_ctrl_seed2.Enable()
102 self.text_ctrl_seed2.Disable()
104 def OnRadioFilterChanged(self, event):
105 u""" 結果表示のフィルターラジオボックスの変更時 """
106 if self._last_search_type == None:
108 elif self._last_search_type == constnumbers.SEARCH_TYPE_SEED2:
109 self._set_items_dict_only_seed2()
110 elif self._last_search_type == constnumbers.SEARCH_TYPE_FIXED_SEED2:
111 self._set_items_dict_fixed_seed2()
113 raise NotImplementedError("irregular radio button selected")
115 def bind_radiobox_search_type(self, event_func, evt=wx.EVT_RADIOBOX):
116 u""" 判定値の種類のラジオボタンが押された時のイベントをセットする """
117 self.radiobox_search_type.Bind(evt, event_func)
119 def bind_button_search(self, event_func, evt=wx.EVT_BUTTON):
120 u""" 検索ボタンが押された時のイベントをセットする """
121 self.button_search.Bind(evt, event_func)
123 def bind_button_clear(self, event_func, evt=wx.EVT_BUTTON):
124 u""" クリアボタンが押された時のイベントをセットする """
125 self.button_clear.Bind(evt, event_func)
127 def bind_button_simulate(self, event_func, evt=wx.EVT_BUTTON):
128 u""" シミュレーター移動ボタンが押された時のイベントをセットする """
129 self.button_simulate.Bind(evt, event_func)
131 def set_skillminmax_dict(self, skill_names, amulet_names, minmax_dict):
132 u"""スキル名のリスト、お守り名のリスト、
133 そのお守りに対応する第1,2スキルの最大最小の辞書をセットする
134 {amulet_name:({skill1_name:(min1,max1)}, {skill2_name:(min2,max2)})}
136 self._skill_names = skill_names
137 self._amulet_names = amulet_names
138 self._minmax_dict = minmax_dict
139 self.set_selected_amulet(constnumbers.NAME_AMULET1)
140 self.update_skill_names()
141 self.update_skill_minmax()
143 def set_skillnames_ordered(self, skillnames):
144 u""" 順番に並べられたスキル名のシーケンスをセットする """
145 self._skillnames = skillnames
147 def update_skill_names(self):
148 u""" 選択されたお守り名に応じてスキル名のリストを更新する """
149 amu_name = self.get_selected_amulet()
150 skill1_minmax, skill2_minmax = self._minmax_dict[amu_name]
151 self.combo_box_skill1.SetItems([x for x in self._skill_names if x in skill1_minmax])
152 self.combo_box_skill2.SetItems([constnumbers.VAL_NO_SKILL] +
153 [x for x in self._skill_names if x in skill2_minmax])
154 self.combo_box_skill1.SetSelection(0)
155 self.combo_box_skill2.SetSelection(0)
157 def update_skill_minmax(self, index=None):
158 u""" 選択されたスキル名に応じて値の範囲を設定する """
159 amu_name = self.get_selected_amulet()
160 skill1_minmax, skill2_minmax = self._minmax_dict[amu_name]
162 if index is None or index == 1:
163 skill1_name = self.combo_box_skill1.GetStringSelection()
164 if skill1_name in skill1_minmax:
165 min1, max1 = skill1_minmax[skill1_name]
166 self.spin_ctrl_skill1_val.SetRange(min1, max1)
168 self.spin_ctrl_skill1_val.SetRange(0, 0)
170 if index is None or index == 2:
171 skill2_name = self.combo_box_skill2.GetStringSelection()
172 if skill2_name in skill2_minmax:
173 min2, max2 = skill2_minmax[skill2_name]
174 self.spin_ctrl_skill2_val.SetRange(min2, max2)
176 self.spin_ctrl_skill2_val.SetRange(0, 0)
178 def update_filter_radio(self):
179 u""" 検索方式に応じて結果表示のフィルターを変える """
180 search_type = self.get_selected_search_type()
181 if search_type == constnumbers.SEARCH_TYPE_SEED2:
182 self.radiobox_filter.SetItemLabel(0, constnumbers.SEARCH_TYPE_SEED2_FILTER1)
183 self.radiobox_filter.SetItemLabel(1, constnumbers.SEARCH_TYPE_SEED2_FILTER2)
184 self.radiobox_filter.SetItemLabel(2, constnumbers.SEARCH_TYPE_SEED2_FILTER3)
185 self.grid_seeds.SetColLabelValue(0, constnumbers.SEARCH_TYPE_SEED2_COL1)
186 self.grid_seeds.SetColLabelValue(1, constnumbers.SEARCH_TYPE_SEED2_COL2)
187 elif search_type == constnumbers.SEARCH_TYPE_FIXED_SEED2:
188 self.radiobox_filter.SetItemLabel(0, constnumbers.SEARCH_TYPE_FIXED_SEED2_FILTER1)
189 self.radiobox_filter.SetItemLabel(1, constnumbers.SEARCH_TYPE_FIXED_SEED2_FILTER2)
190 self.radiobox_filter.SetItemLabel(2, constnumbers.SEARCH_TYPE_FIXED_SEED2_FILTER3)
191 self.grid_seeds.SetColLabelValue(0, constnumbers.SEARCH_TYPE_FIXED_SEED2_COL1)
192 self.grid_seeds.SetColLabelValue(1, constnumbers.SEARCH_TYPE_FIXED_SEED2_COL2)
194 raise NotImplementedError("irregular radio button selected")
196 def set_slot_minmax(self, slot_min, slot_max):
197 u""" スロットの最大値と最小値をセットする """
198 self.spin_ctrl_slot_num.SetRange(slot_min, slot_max)
200 def get_skill_values(self):
202 return (skill1_val, skill2_val)"""
203 skill1_val = self.spin_ctrl_skill1_val.GetValue()
204 skill2_val = self.spin_ctrl_skill2_val.GetValue()
205 return (skill1_val, skill2_val)
207 def get_slot_value(self):
209 return self.spin_ctrl_slot_num.GetValue()
211 def clear_input_values(self):
212 u""" 入力された値を初期化する """
213 self.combo_box_skill1.SetSelection(0)
214 self.combo_box_skill2.SetSelection(0)
215 self.spin_ctrl_skill1_val.SetValue(1)
216 self.spin_ctrl_skill2_val.SetValue(0)
217 self.spin_ctrl_slot_num.SetValue(1)
218 self.text_ctrl_seed2.SetValue(u"")
219 self.text_ctrl_result.SetValue(u"")
221 def get_fixed_seed2(self):
222 u""" seed2固定検索時のSeed2を返す """
223 seed2 = self.text_ctrl_seed2.GetValue()
229 def set_selected_amulet(self, value, amulet_name=constnumbers.NAME_AMULET1):
231 arg: (value, amulet_name)
233 if amulet_name == constnumbers.NAME_AMULET1:
235 elif amulet_name == constnumbers.NAME_AMULET2:
237 elif amulet_name == constnumbers.NAME_AMULET3:
239 self.radiobox_amulet.SetSelection(idx)
241 def get_selected_amulet(self):
243 return: (NAME_OF_AMULET)
245 idx = self.radiobox_amulet.GetSelection()
247 return constnumbers.NAME_AMULET1
249 return constnumbers.NAME_AMULET2
251 return constnumbers.NAME_AMULET3
253 raise NotImplementedError("irregular radio button selected")
255 def get_selected_search_type(self):
256 u""" 選択されているラジオボタンの検索種類IDを得る
257 return: (THRESHOLD_TYPE_ID)
259 idx = self.radiobox_search_type.GetSelection()
261 return constnumbers.SEARCH_TYPE_SEED2
263 return constnumbers.SEARCH_TYPE_FIXED_SEED2
265 return constnumbers.SEARCH_TYPE_SEED1_SEED2
267 raise NotImplementedError("irregular radio button selected")
269 def get_selected_tenun_type(self):
270 u""" 固定Seed2における天運の種類を返す。判別できない場合はNone """
271 if self._last_search_type == constnumbers.SEARCH_TYPE_FIXED_SEED2:
272 filter_str = self.radiobox_filter.GetStringSelection()
273 if filter_str == constnumbers.SEARCH_TYPE_FIXED_SEED2_FILTER1:
274 return constnumbers.KEY_TENUN888
275 elif filter_str == constnumbers.SEARCH_TYPE_FIXED_SEED2_FILTER2:
276 return constnumbers.KEY_TENUN555
277 elif filter_str == constnumbers.SEARCH_TYPE_FIXED_SEED2_FILTER3:
278 return constnumbers.KEY_TENUN888
282 def get_skill_names(self):
283 u""" skill1, skill2で選択されているスキル名を返す
284 return (skill1_name, skill2_name)"""
285 skill1_name = self.combo_box_skill1.GetStringSelection()
286 skill2_name = self.combo_box_skill2.GetStringSelection()
287 return (skill1_name, skill2_name)
289 def set_skill_names(self, skill1_names, skill2_names):
290 u""" スキル1、スキル2のコンボボックスの一覧をセットする """
291 self.combo_box_skill1.SetItems(skill1_names)
292 self.combo_box_skill2.SetItems(skill2_names)
294 def set_simualte_button_enable(self, value):
295 u""" 対応スキル検索ボタンの有効・無効の切り替え """
297 self.button_simulate.Enable()
299 self.button_simulate.Disable()
301 def set_result(self, value):
302 u""" 結果表示用のTextCtrlに値をセットする """
303 self.text_ctrl_result.SetValue(value)
305 def set_result_only_seed2(self, suff_val, threshold, th1_seed2s, th2_seed2s):
306 u""" Seed2のみからの検索結果表示用に値をセットする """
307 self.update_filter_radio()
308 seed2s = th1_seed2s | th2_seed2s
309 self.text_ctrl_result.SetValue(u"""※簡易検索のため、不正確な場合があります
310 充足値: {0}, 必要な判定値: {1}
311 {1}以上の判定値1を持つSeed2: {2}
312 {1}以上の判定値2を持つSeed2: {3}
313 {1}以上の判定値を持つSeed2: {4}""".format(
314 suff_val, threshold, len(th1_seed2s), len(th2_seed2s), len(seed2s)))
315 self._last_search_type = constnumbers.SEARCH_TYPE_SEED2
316 self._last_values = (suff_val, threshold, th1_seed2s, th2_seed2s)
317 self._set_items_dict_only_seed2()
319 def _set_items_dict_only_seed2(self):
320 u""" Seed2のみからの検索時結果をフィルターに応じて表示 """
321 if self._last_search_type == constnumbers.SEARCH_TYPE_SEED2:
322 filter_str = self.radiobox_filter.GetStringSelection()
323 if filter_str == constnumbers.SEARCH_TYPE_SEED2_FILTER1:
324 th1_include, th2_include = True, True
325 elif filter_str == constnumbers.SEARCH_TYPE_SEED2_FILTER2:
326 th1_include, th2_include = True, False
327 elif filter_str == constnumbers.SEARCH_TYPE_SEED2_FILTER3:
328 th1_include, th2_include = False, True
330 suff_val, threshold, th1_seed2s, th2_seed2s = self._last_values
331 seed2s = th1_seed2s | th2_seed2s
336 if seed2 in th1_seed2s:
337 texts.append(u"判定値1")
340 if seed2 in th2_seed2s:
341 texts.append(u"判定値2")
345 texts = u", ".join(texts)
346 texts = u"Seed2({0})".format(texts) if len(texts) > 0 else texts
347 items_dict[seed2] = texts
348 self.set_grid_seeds_items(items_dict)
350 def set_result_fixed_seed2(self, suff_val, threshold, seed2, seed1s_555, seed1s_888):
351 u""" 固定Seed2からの検索結果表示用に値をセットする """
352 self.update_filter_radio()
353 seed1s = seed1s_555 | seed1s_888
354 self.text_ctrl_result.SetValue(u"""Seed2:\t{0}
355 充足値: {1}, 必要な判定値: {2}
358 Seed1の合計:\t{5}""".format(seed2, suff_val, threshold, len(seed1s_555), len(seed1s_888), len(seed1s)))
360 self._last_search_type = constnumbers.SEARCH_TYPE_FIXED_SEED2
361 self._last_values = (suff_val, threshold, seed2, seed1s_555, seed1s_888)
362 self._set_items_dict_fixed_seed2()
364 def _set_items_dict_fixed_seed2(self):
365 u""" 固定Seed2からの検索時結果をフィルターに応じて表示 """
366 if self._last_search_type == constnumbers.SEARCH_TYPE_FIXED_SEED2:
367 filter_str = self.radiobox_filter.GetStringSelection()
368 if filter_str == constnumbers.SEARCH_TYPE_FIXED_SEED2_FILTER1:
369 include_555, include_888 = True, True
370 elif filter_str == constnumbers.SEARCH_TYPE_FIXED_SEED2_FILTER2:
371 include_555, include_888 = True, False
372 elif filter_str == constnumbers.SEARCH_TYPE_FIXED_SEED2_FILTER3:
373 include_555, include_888 = False, True
376 suff_val, threshold, seed2, seed1s_555, seed1s_888 = self._last_values
377 seed1s = seed1s_555 | seed1s_888
381 if seed1 in seed1s_555:
382 texts.append(u"天運555")
385 if seed1 in seed1s_888:
386 texts.append(u"天運888")
390 texts = u", ".join(texts)
391 texts = u"Seed1({0})".format(texts) if len(texts) > 0 else texts
392 items_dict[seed1] = texts
393 self.set_grid_seeds_items(items_dict)
395 def set_result_seeds(self, suff_val, result_dict):
397 Seed2から各天運のSeed1の集合の辞書を引数とする。
398 result_dict={seed2:(seed1s_555, seed1s_888)}"""
400 self.text_ctrl_result.SetValue(u"充足値: {0} Seed2の総数:\t{1}".format(suff_val, len(result_dict)))
402 for seed2, (seed1s_555, seed1s_888) in result_dict.items():
403 seed1s = seed1s_555 | seed1s_888
406 if seed1 in seed1s_555:
407 texts.append(u"天運555")
408 if seed1 in seed1s_888:
409 texts.append(u"天運888")
410 texts = u", ".join(texts)
411 texts = u"Seed1({0})".format(texts) if len(texts) > 0 else texts
412 items_dict[(seed1, seed2)] = texts
413 self.set_grid_seeds_items(items_dict)
415 raise NotImplementedError(u"give up to implement all search because of ttoo heavy and long calc")
417 def set_grid_seeds_items(self, items_dict):
418 u""" Seed一覧のGridに値をセットする。
419 引数はSeed -> 文字列の辞書とする。
420 Noneが与えられた時はClearする"""
421 if items_dict is not None and len(items_dict) > 0:
422 row_num = len(items_dict)
423 diff = row_num - self.grid_seeds.GetNumberRows()
425 self.grid_seeds.AppendRows(diff, False)
427 self.grid_seeds.DeleteRows(0, -diff, False)
429 for row, seed in enumerate(sorted(items_dict.keys())):
430 #self.grid_seeds.SetRowLabelValue(row, u"")
431 type_str = items_dict[seed]
432 self.grid_seeds.SetCellValue(row, 0, u"{0}".format(seed))
433 self.grid_seeds.SetCellValue(row, 1, type_str)
434 self.set_simualte_button_enable(True)
436 self.clear_grid_seeds()
437 self.set_simualte_button_enable(False)
439 def get_selected_seeds(self):
440 u""" Seed一覧のGridの選択された(Seed1,Seed2)の値を得る。"""
441 rows = [x for x in self.grid_seeds.GetSelectedRows()]
443 if self._last_search_type == constnumbers.SEARCH_TYPE_FIXED_SEED2:
444 seed1 = int(self.grid_seeds.GetCellValue(rows[0], 0))
445 seed2 = self._last_values[2]
447 elif self._last_search_type == constnumbers.SEARCH_TYPE_SEED2:
449 seed2 = int(self.grid_seeds.GetCellValue(rows[0], 0))
456 def set_grid_seeds_selected_idx(self, idx):
457 u""" Seed一覧のGridの選択された行を選択状態にする。"""
458 if idx >= 0 and idx < self.grid_seeds.GetNumberRows():
459 self.grid_seeds.MakeCellVisible(idx, 0)
460 self.grid_seeds.SelectRow(idx)
462 def clear_grid_seeds(self):
463 u""" Seed一覧のGridから値をClearする"""
464 for row in range(self.grid_seeds.GetNumberRows()):
465 self.grid_seeds.SetRowLabelValue(row, u"")
466 for col in range(self.grid_seeds.GetNumberCols()):
467 self.grid_seeds.SetCellValue(row, col, u"")
468 self.grid_seeds.ClearSelection()
469 self.set_simualte_button_enable(False)
470 self._last_search_type = None
471 self._last_valuse = None
473 def clear_grid(self):
475 self.clear_grid_seeds()