def OnKeyDown(self, event: wx.Event): """Left/right/up/down key for move and rotate, space for drop, d for one line down, p for pause, all other ignore (pass on to next handler) """ if not self.board.started or self.board.this_piece.shape == Tetrominoes.NoShape: logging.debug("not started - ignore input") event.Skip() return keycode = event.GetKeyCode() logging.debug("OnKeyDown: keycode=%d", keycode) if keycode in [ord("P"), ord("p")]: self.pause() return if self.board.paused: return if keycode == wx.WXK_LEFT: self.try_move(self.board.this_piece, -1) elif keycode == wx.WXK_RIGHT: self.try_move(self.board.this_piece, +1) elif keycode == wx.WXK_DOWN: self.try_move(self.board.this_piece.rotate_ccw(), 0) elif keycode == wx.WXK_UP: self.try_move(self.board.this_piece.rotate_cw(), 0) elif keycode == wx.WXK_SPACE: self.drop_down() elif keycode == ord("D") or keycode == ord("d"): self.move_down() else: event.Skip()
def on_load_result(self, event: wx.Event): self.frame.elapsed_time = event.elapsed_time # タブ移動可 self.frame.release_tab() # フォーム有効化 self.frame.enable() # ワーカー終了 self.frame.load_worker = None # プログレス非表示 self.frame.file_panel_ctrl.gauge_ctrl.SetValue(0) if not event.result: # 終了音を鳴らす self.frame.sound_finish() event.Skip() return False result = self.frame.is_loaded_valid() if not result: # タブ移動可 self.frame.release_tab() # フォーム有効化 self.frame.enable() event.Skip() return False logger.info("ファイルデータ読み込みが完了しました", decoration=MLogger.DECORATION_BOX, title="OK") # フォーム無効化 self.frame.file_panel_ctrl.disable() # タブ固定 self.frame.file_panel_ctrl.fix_tab() if self.frame.worker: logger.error("まだ処理が実行中です。終了してから再度実行してください。", decoration=MLogger.DECORATION_BOX) else: # 停止ボタンに切り替え self.frame.file_panel_ctrl.exec_btn_ctrl.SetLabel("VMDサイジング停止") self.frame.file_panel_ctrl.exec_btn_ctrl.Enable() # 別スレッドで実行 self.frame.worker = SizingWorkerThread(self.frame, BulkSizingThreadEvent, event.target_idx, self.frame.is_saving, self.frame.is_out_log) self.frame.worker.start()
def on_button(self, event: wx.Event): event_obj = event.GetEventObject() if event_obj == self.btn_clear_1: self.set_defaults() elif event_obj == self.btn_clear_2: event.Skip() elif event_obj == self.btn_preview: event.Skip() elif event_obj == self.btn_save: event.Skip() else: event.Skip()
def on_rise_time(self, event: wx.Event): try: val = float(self.rise_time_text.GetValue()) except ValueError: self.rise_time_text.SetValue(str(self.rise_time)) event.Skip() return val = (0 if val < .05 else .1 if val < .3 else .5 if val < .75 else 1 if val < 1.5 else 2) if self.rise_time != val: self.rise_time = val self.modify_callback() self.rise_time_text.SetValue(str(self.rise_time)) event.Skip()
def on_amp(self, event: wx.Event): try: val = float(self.amp_text.GetValue()) except ValueError: self.amp_text.SetValue(str(self.amp)) event.Skip() return word = round(val / 20000 * 65536) word = 0 if word < 0 else 327 if word > 327 else word val = word / 65536 * 20000 if self.amp != val: self.amp = val self.modify_callback() self.amp_text.SetValue('%.1f' % self.amp) event.Skip()
def on_check(self, event: wx.Event): # 出力先をファイルパネルのコンソールに変更 sys.stdout = self.console_ctrl if self.check_btn_ctrl.GetLabel( ) == "読み込み処理停止" and self.frame.load_worker: # フォーム無効化 self.disable() # 停止状態でボタン押下時、停止 self.frame.load_worker.stop() # タブ移動可 self.frame.release_tab() # フォーム有効化 self.frame.enable() # ワーカー終了 self.frame.load_worker = None # プログレス非表示 self.gauge_ctrl.SetValue(0) self.timer.Stop() logger.warning("読み込み処理を中断します。", decoration=MLogger.DECORATION_BOX) event.Skip(False) elif not self.frame.load_worker: # フォーム無効化 self.disable() # タブ固定 self.fix_tab() # コンソールクリア self.console_ctrl.Clear() # 履歴保持 self.save() self.timer.Stop() # 一旦読み込み(そのままチェック) self.frame.load(event, target_idx=0) event.Skip() else: self.timer.Stop() logger.error("まだ処理が実行中です。終了してから再度実行してください。", decoration=MLogger.DECORATION_BOX) event.Skip(False)
def on_convert_blend_result(self, event: wx.Event): self.elapsed_time = event.elapsed_time # 終了音 self.frame.sound_finish() # タブ移動可 self.release_tab() # フォーム有効化 self.enable() # ワーカー終了 self.blend_worker = None # プログレス非表示 self.gauge_ctrl.SetValue(0) if not event.result: logger.error("モーフブレンド処理に失敗しました。", decoration=MLogger.DECORATION_BOX) event.Skip() return False logger.info("モーフブレンドが完了しました", decoration=MLogger.DECORATION_BOX, title="OK") # 出力先をデフォルトに戻す sys.stdout = self.frame.file_panel_ctrl.console_ctrl
def on_tab_change(self, event: wx.Event): if self.parent_panel_ctrl.is_fix_tab: self.note_ctrl.ChangeSelection(self.parent_panel_ctrl.tab_idx) event.Skip() return elif self.smooth_panel_ctrl.is_fix_tab: self.note_ctrl.ChangeSelection(self.smooth_panel_ctrl.tab_idx) event.Skip() return elif self.blend_panel_ctrl.is_fix_tab: self.note_ctrl.ChangeSelection(self.blend_panel_ctrl.tab_idx) event.Skip() return
def on_exec(self, event: wx.Event): if self.timer: self.timer.Stop() self.Unbind(wx.EVT_TIMER, id=TIMER_ID) # 出力先をファイルパネルのコンソールに変更 sys.stdout = self.console_ctrl if self.exec_btn_ctrl.GetLabel() == "VMDサイジング停止" and self.frame.worker: # フォーム無効化 self.disable() # 停止状態でボタン押下時、停止 self.frame.worker.stop() # タブ移動可 self.frame.release_tab() # フォーム有効化 self.frame.enable() # ワーカー終了 self.frame.worker = None # プログレス非表示 self.gauge_ctrl.SetValue(0) logger.warning("VMDサイジングを中断します。", decoration=MLogger.DECORATION_BOX) event.Skip(False) elif not self.frame.worker: # フォーム無効化 self.disable() # タブ固定 self.fix_tab() # コンソールクリア self.console_ctrl.Clear() # 履歴保持 self.save() # サイジング可否チェックの後に実行 self.frame.load(event, is_exec=True, target_idx=0) event.Skip() else: logger.error("まだ処理が実行中です。終了してから再度実行してください。", decoration=MLogger.DECORATION_BOX) event.Skip(False)
def on_text(self, event: wx.Event): event_obj = event.EventObject if event_obj == self.search_bar: value = event_obj.GetValue() self.in_grid.filter(value) if ':' not in value else None else: print('other text events') event.Skip()
def on_move(self, event: wx.Event): rc = self.GetRect() # print("window rect = (%d, %d, %d, %d)" % (rc.GetX(), rc.GetY(), rc.GetWidth(), rc.GetHeight())) if not self.IsIconized() and not self.IsMaximized(): self.window_rect = (rc.GetX(), rc.GetY(), rc.GetWidth(), rc.GetHeight()) event.Skip()
def on_pulse_width(self, event: wx.Event): try: val = float(self.pw_text.GetValue()) except ValueError: self.pw_text.SetValue(str(self.pulse_width)) event.Skip() return if val > self.period: val = self.period word = round(val / .017152) word = 0 if word < 0 else 0xfffff if word > 0xfffff else word val = word * .017152 if self.pulse_width != val: self.pulse_width = val self.modify_callback() self.pw_text.SetValue('%.3f' % self.pulse_width) event.Skip()
def show_process_dialog(self, event: wx.Event): if self.process_dialog: # 既にある場合、一旦破棄 self.process_dialog.Destroy() self.process_dialog = ProcessDialog(self.frame, self) self.process_dialog.Show() event.Skip()
def on_exec_result(self, event: wx.Event): # 実行ボタンに切り替え self.frame.file_panel_ctrl.exec_btn_ctrl.SetLabel("VMDサイジング実行") self.frame.file_panel_ctrl.exec_btn_ctrl.Enable() if not event.result: # 終了音を鳴らす self.frame.sound_finish() event.Skip() return False self.frame.elapsed_time += event.elapsed_time worked_time = "\n処理時間: {0}".format(self.frame.show_worked_time()) logger.info(worked_time) if self.frame.is_out_log and event.output_log_path and os.path.exists( event.output_log_path): # ログ出力対象である場合、追記 with open(event.output_log_path, mode='a', encoding='utf-8') as f: f.write(worked_time) # ワーカー終了 self.frame.worker = None if event.target_idx >= 0: # 次のターゲットがある場合、次を処理 logger.info("\n----------------------------------") return self.load(event, event.target_idx) # ファイルタブのコンソール sys.stdout = self.frame.file_panel_ctrl.console_ctrl # 終了音を鳴らす self.frame.sound_finish() # ファイルタブのコンソール if sys.stdout != self.frame.file_panel_ctrl.console_ctrl: sys.stdout = self.frame.file_panel_ctrl.console_ctrl # Bulk用データ消去 self.frame.morph_panel_ctrl.bulk_morph_set_dict = {} self.frame.arm_panel_ctrl.bulk_avoidance_set_dict = {} self.frame.camera_panel_ctrl.bulk_camera_set_dict = {} # タブ移動可 self.frame.release_tab() # フォーム有効化 self.frame.enable() # プログレス非表示 self.frame.file_panel_ctrl.gauge_ctrl.SetValue(0) logger.info("全てのサイジング処理が終了しました", decoration=MLogger.DECORATION_BOX, title="一括処理")
def on_check_arm_process_avoidance(self, event: wx.Event): # ラジオボタンかチェックボックスイベントがTrueの場合、切り替え if isinstance(event.GetEventObject(), wx.StaticText): if self.arm_process_flg_avoidance.GetValue() == 0: self.arm_process_flg_avoidance.SetValue(1) else: self.arm_process_flg_avoidance.SetValue(0) # パス再生成 self.set_output_vmd_path(event) event.Skip()
def check(self, event: wx.Event): if event.GetEventObject().GetLabel() == self.correct: self.correct_questions += 1 self.current_question += 1 if self.current_question < len(self.questions): self.update_question() self.Update() else: self.m_resultText.SetLabelText( "Your result: {}/{}!".format(self.correct_questions, self.current_question)) self.m_simplebook1.ChangeSelection(2) event.Skip()
def on_button(self, event: wx.Event): event_obj = event.GetEventObject() if event_obj == self.btn_reload: self.reload_ui() elif event_obj == self.info_panel.btn_clear_2: self.out_grid.clear() elif event_obj == self.info_panel.btn_preview: self.preview() elif event_obj == self.info_panel.btn_save: self.save() else: print(event_obj) event.Skip()
def increment_index(self, evt: wx.Event = None, increment: int = None): """Increment the ListCtrl selection with an event or fixed increment Parameters ---------- evt : wx.Event An event with a ``GetKeyCode`` method increment : int If no event is passed, use a fixed index increment """ if self.has_data: if hasattr(evt, "GetKeyCode"): keycode = evt.GetKeyCode() if keycode == wx.WXK_UP: evt.Skip() increment = -1 elif keycode == wx.WXK_DOWN: evt.Skip() increment = 1 else: return if increment is None: increment = 1 current_index = self.selected_row_index if len(current_index): new_index = current_index[0] + increment if new_index > self.row_count - 1: new_index = 0 else: new_index = -1 + increment if increment > 0 else -increment self.layout.Select(new_index)
def on_convert_smooth(self, event: wx.Event): # フォーム無効化 self.disable() # タブ固定 self.fix_tab() # コンソールクリア self.console_ctrl.Clear() # 出力先をスムージングパネルのコンソールに変更 sys.stdout = self.console_ctrl wx.GetApp().Yield() self.smooth_vmd_file_ctrl.save() self.smooth_model_file_ctrl.save() # JSON出力 MFileUtils.save_history(self.frame.mydir_path, self.frame.file_hitories) self.elapsed_time = 0 result = True result = self.smooth_vmd_file_ctrl.is_valid( ) and self.smooth_model_file_ctrl.is_valid() and result if not result: # 終了音 self.frame.sound_finish() # タブ移動可 self.release_tab() # フォーム有効化 self.enable() # 出力先をデフォルトに戻す sys.stdout = self.frame.file_panel_ctrl.console_ctrl return result # スムージング変換開始 if self.convert_smooth_worker: logger.error("まだ処理が実行中です。終了してから再度実行してください。", decoration=MLogger.DECORATION_BOX) else: # 別スレッドで実行 self.convert_smooth_worker = SmoothWorkerThread( self.frame, SmoothThreadEvent, self.frame.is_saving) self.convert_smooth_worker.start() return result event.Skip()
def on_close(self, event: wx.Event): if self.app.book.is_modified(): dialog = wx.MessageDialog( self.app.frame, _("Changes not saved! Do you want to exit without saving?"), _("Permanent Action"), wx.OK | wx.CANCEL | wx.CANCEL_DEFAULT | wx.ICON_WARNING) try: if dialog.ShowModal() == wx.ID_OK: event.Skip() self.app.settings_controls.save_settings_on_exit(event) finally: dialog.Destroy() else: self.app.settings_controls.save_settings_on_exit(event)
def on_add_set(self, event: wx.Event): self.file_set_list.append( SizingFileSet(self.frame, self.scrolled_window, self.file_hitories, len(self.file_set_list) + 2)) self.set_base_sizer.Add(self.file_set_list[-1].set_sizer, 0, wx.ALL, 5) self.set_base_sizer.Layout() # スクロールバーの表示のためにサイズ調整 self.sizer.Layout() # self.sizer.FitInside(self.scrolled_window) if self.frame.arm_panel_ctrl.arm_alignment_finger_flg_ctrl.GetValue( ) and len(self.file_set_list) > 0: self.frame.on_popup_finger_warning(event) event.Skip()
def on_button(self, e: wx.Event): e_obj = e.GetEventObject() if e_obj == self.btn1: fdlg = wx.FileDialog(self, 'Export to PDF', PDFS_DIR.as_posix(), style=wx.FD_SAVE, wildcard='PDF files (*.pdf)|*.pdf') if fdlg.ShowModal() == wx.ID_OK: fp = Path(fdlg.GetPath()).resolve() self.report(fp) else: return else: e.Skip()
def on_exec(self, event: wx.Event): self.timer.Stop() if not self.worker: # コンソールクリア self.console_ctrl.Clear() # 実行ボタン無効化 self.exec_btn_ctrl.Disable() # 中断ボタン有効化 self.kill_btn_ctrl.Enable() # 別スレッドで実行【Point.09】 self.worker = LongLogicWorker(self, LongThreadEvent, self.loop_cnt_ctrl.GetValue(), self.multi_process_ctrl.GetValue()) self.worker.start() event.Skip(False)
def on_exec_result(self, event: wx.Event): # 【Point.12】ロジック終了が明示的に分かるようにする self.sound_finish() # 実行ボタン有効化 self.exec_btn_ctrl.Enable() # 中断ボタン無効化 self.kill_btn_ctrl.Disable() if not event.result: event.Skip(False) return False self.elapsed_time += event.elapsed_time logger.info("\n処理時間: %s", self.show_worked_time()) # ワーカー終了 self.worker = None # プログレス非表示 self.gauge_ctrl.SetValue(0)
def on_convert_vmd(self, event: wx.Event): # フォーム無効化 self.disable() # タブ固定 self.fix_tab() # コンソールクリア self.console_ctrl.Clear() # 出力先をVMDパネルのコンソールに変更 sys.stdout = self.console_ctrl wx.GetApp().Yield() self.elapsed_time = 0 result = True result = self.bone_csv_file_ctrl.is_valid() and result if not result: # 終了音 self.frame.sound_finish() # タブ移動可 self.release_tab() # フォーム有効化 self.enable() # 出力先をデフォルトに戻す if sys.stdout != self.frame.file_panel_ctrl.console_ctrl: sys.stdout = self.frame.file_panel_ctrl.console_ctrl return result # VMD変換開始 if self.convert_vmd_worker: logger.error("まだ処理が実行中です。終了してから再度実行してください。", decoration=MLogger.DECORATION_BOX) else: # 別スレッドで実行 self.convert_vmd_worker = VmdWorkerThread(self.frame, VmdThreadEvent) self.convert_vmd_worker.start() return result event.Skip()
def on_check_arm_process_alignment(self, event: wx.Event): # ラジオボタンかチェックボックスイベントがTrueの場合、切り替え if isinstance(event.GetEventObject(), wx.StaticText): if self.arm_process_flg_alignment.GetValue() == 0: self.arm_process_flg_alignment.SetValue(1) else: self.arm_process_flg_alignment.SetValue(0) else: if self.arm_alignment_finger_flg_ctrl.GetValue( ) == 1 or self.arm_alignment_floor_flg_ctrl.GetValue() == 1: self.arm_process_flg_alignment.SetValue(1) if self.arm_alignment_finger_flg_ctrl.GetValue() and len( self.frame.multi_panel_ctrl.file_set_list) > 0: self.frame.on_popup_finger_warning(event) # パス再生成 self.set_output_vmd_path(event) event.Skip()
def on_kill(self, event: wx.Event): self.timer.Stop() if self.worker: # 停止状態でボタン押下時、停止 self.worker.stop() logger.warning("長いロジック処理を中断します。", decoration=MLogger.DECORATION_BOX) # ワーカー終了 self.worker = None # 実行ボタン有効化 self.exec_btn_ctrl.Enable() # 中断ボタン無効化 self.kill_btn_ctrl.Disable() # プログレス非表示 self.gauge_ctrl.SetValue(0) event.Skip(False)
def OnTimer(self, event: wx.Event): """Timer fire: normally move one line down (like D key event), otherwise produce new shape """ if event.GetId() != self.ID_TIMER: event.Skip() # we don"t process this event elif self.board.neednewpiece: # first timer after full row is removed, generate new piece instead of moving down if self.board.make_new_piece(): logging.debug("This: %s; next: %s", self.board.this_piece.shape, self.board.next_piece.shape) else: # cannot even place the shape at top middle of the board, finish the game self.timer.Stop() self.dashboard.message.SetLabel("Game over") self.dashboard.SetBackgroundColour((225, 225, 225)) logging.debug("game over") else: # normal: move the current piece down for one row logging.debug("moving piece down, curr_y = %d", self.board.cur_y) self.move_down() self.Refresh() self.dashboard.Refresh()
def on_change_file(self, event: wx.Event): # フォーム無効化 self.disable() # 出力先をCSVパネルのコンソールに変更 sys.stdout = self.console_ctrl # ファイルコントロール自身のパス確定処理 # 先頭と末尾の改行は除去 target_path = self.pmx_file_ctrl.file_ctrl.GetPath().strip() logger.test("target_path strip: %s", target_path) # 先頭と末尾のダブルクォーテーションは除去 target_path = re.sub(r'^\\+\"(\w)\\', r'\1:\\', target_path) target_path = target_path.strip("\"") logger.test("target_path strip: %s", target_path) # 再設定 self.pmx_file_ctrl.file_ctrl.SetPath(target_path) # ファイル読み込み処理 if self.pmx_file_ctrl.is_valid() and self.pmx_file_ctrl.load( is_check=False): # モーフ展開処理 morph_names = {"目": [], "眉": [], "口": [], "他": []} for mk, mv in self.pmx_file_ctrl.data.morphs.items(): if mv.display: morph_names[mv.get_panel_name()].append(mk) self.morph_eye_list.SetItems(morph_names["目"]) self.morph_eyebrow_list.SetItems(morph_names["眉"]) self.morph_lip_list.SetItems(morph_names["口"]) self.morph_other_list.SetItems(morph_names["他"]) # フォーム有効化 self.enable() event.Skip()
def on_exec_result(self, event: wx.Event): # 実行ボタンに切り替え self.file_panel_ctrl.exec_btn_ctrl.SetLabel("VMDサイジング実行") self.file_panel_ctrl.exec_btn_ctrl.Enable() if not event.result: # 終了音を鳴らす self.sound_finish() event.Skip() return False self.elapsed_time += event.elapsed_time logger.info("\n処理時間: %s", self.show_worked_time()) # ワーカー終了 self.worker = None if self.file_panel_ctrl.file_set.motion_vmd_file_ctrl.astr_path and self.get_target_vmd_path( event.target_idx + 1): # アスタリスク付きパスの場合、次の存在チェック logger.info("\n----------------------------------") return self.load(event, event.target_idx + 1, is_exec=True) # ファイルタブのコンソール sys.stdout = self.file_panel_ctrl.console_ctrl # 終了音を鳴らす self.sound_finish() # タブ移動可 self.release_tab() # フォーム有効化 self.enable() # プログレス非表示 self.file_panel_ctrl.gauge_ctrl.SetValue(0)