diff --git a/SerialController/Commands/CommandBase.py b/SerialController/Commands/CommandBase.py index f8a6f76..665e4d4 100644 --- a/SerialController/Commands/CommandBase.py +++ b/SerialController/Commands/CommandBase.py @@ -17,3 +17,17 @@ def start(self, ser, postProcess=None): @abstractclassmethod def end(self, ser): pass + + def startWithOption(self, root, ser, postProcess=None): + if self.openOptionDialog(root): + self.apply() + self.start(ser, postProcess) + return True + else: + return False + + def openOptionDialog(self, root): + return True + + def apply(self): + pass \ No newline at end of file diff --git a/SerialController/Commands/PythonCommands/AutoRelease.py b/SerialController/Commands/PythonCommands/AutoRelease.py index e086463..f773cf1 100644 --- a/SerialController/Commands/PythonCommands/AutoRelease.py +++ b/SerialController/Commands/PythonCommands/AutoRelease.py @@ -3,6 +3,7 @@ from Commands.PythonCommandBase import PythonCommand, ImageProcPythonCommand from Commands.Keys import KeyPress, Button, Direction, Stick +import GuiAssets # auto releaseing pokemons class AutoRelease(ImageProcPythonCommand): @@ -19,7 +20,7 @@ def do(self): for i in range(0, self.row): for j in range(0, self.col): - if not self.cam.isOpened(): + if not self.is_use_ir: self.Release() else: # if shiny, then skip @@ -47,4 +48,34 @@ def Release(self): self.press(Button.A, wait=1) self.press(Direction.UP, wait=0.2) self.press(Button.A, wait=1.5) - self.press(Button.A, wait=0.3) \ No newline at end of file + self.press(Button.A, wait=0.3) + + def openOptionDialog(self, root): + self.option = Dialog(root, self.NAME, self.cam).option + return self.option != None + + def apply(self): + self.is_use_ir = self.option['is_use_ir'] + +class Dialog(GuiAssets.Dialog): + def __init__(self, parent, title, cam): + self.cam = cam + super().__init__(parent, title) + + def body(self, master): + frame = None + if self.cam.isOpened(): + frame, self.var = self.setSelectRadioButton(master, "画像認識", {1:"使用する", 0:"使用しない"}, init_var=1) + else: + frame, self.var = self.setSelectRadioButton(master, "画像認識", {0:"使用しない"}) + frame.grid(row=0) + + def validate(self): + try: + self.option = { + 'is_use_ir': self.var.get() & self.cam.isOpened() + } + return 1 + except ValueError: + tk.messagebox.showwarning("Input Value Error", "不正な入力値です.\nPlease try again.") + return 0 diff --git a/SerialController/Commands/PythonCommands/Hoge.py b/SerialController/Commands/PythonCommands/Hoge.py new file mode 100644 index 0000000..302df7b --- /dev/null +++ b/SerialController/Commands/PythonCommands/Hoge.py @@ -0,0 +1,48 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +from Commands.PythonCommandBase import PythonCommand, ImageProcPythonCommand +from Commands.Keys import KeyPress, Button, Direction, Stick +import GuiAssets +import tkinter as tk + +class Hoge(PythonCommand): + NAME = 'hoge' + + def __init__(self): + super().__init__() + + def do(self): + while True: + self.wait(0.5) + self.press(Button.A) + + def openOptionDialog(self, root): + d = MyDialog(root, self.NAME) + return d.option != None + + def apply(self): + self.count = 0 + +class MyDialog(GuiAssets.Dialog): + def __init__(self, parent, title = None): + super().__init__(parent, title) + + def body(self, master): + frame1, self.e1 = self.setLabelWithEntry(master, "First:") + frame2, self.e2 = self.setLabelWithEntry(master, "Second:") + frame1.grid(row=0) + frame2.grid(row=1) + + def validate(self): + try: + first = int(self.e1.get()) + second = int(self.e2.get()) + self.option = first, second + return 1 + except ValueError: + tk.messagebox.showwarning("Input Value Error", "不正な入力値です.\nPlease try again.") + return 0 + + def apply(self): + pass \ No newline at end of file diff --git a/SerialController/GuiAssets.py b/SerialController/GuiAssets.py index fbe5fdf..68b4489 100644 --- a/SerialController/GuiAssets.py +++ b/SerialController/GuiAssets.py @@ -2,6 +2,7 @@ # -*- coding: utf-8 -*- import tkinter as tk +import tkinter.messagebox from tkinter import ttk from tkinter.scrolledtext import ScrolledText import cv2 @@ -60,6 +61,100 @@ def capture(self): def saveCapture(self): self.camera.saveCapture() +# The modal dialog +# based from here: http://effbot.org/tkinterbook/tkinter-dialog-windows.htm +class Dialog(tk.Toplevel): + def __init__(self, parent, title = None): + tk.Toplevel.__init__(self, parent) + self.transient(parent) + self.option = None + + if title: + self.title(title) + + self.parent = parent + self.result = None + + body = tk.Frame(self) + self.initial_focus = self.body(body) + body.pack(padx=5, pady=5) + + self.setButtonbox() + + if not self.initial_focus: + self.initial_focus = self + + self.protocol("WM_DELETE_WINDOW", self.cancel) + + self.geometry("+%d+%d" % (parent.winfo_rootx(), + parent.winfo_rooty())) + + self.initial_focus.focus_set() + self.wait_window(self) + + # Create dialog body that returns widget that should have initial focus. + # This method should be overridden. + def body(self, master): + pass + + # Add standard button box. Override if you don't want the standard buttons. + def setButtonbox(self): + box = tk.Frame(self) + + w = tk.Button(box, text="OK", width=10, command=self.ok, default=tk.ACTIVE) + w.pack(side=tk.LEFT, padx=5, pady=5) + w = tk.Button(box, text="Cancel", width=10, command=self.cancel) + w.pack(side=tk.LEFT, padx=5, pady=5) + + self.bind("", self.ok) + self.bind("", self.cancel) + + box.pack() + + def ok(self, event=None): + if not self.validate(): + self.initial_focus.focus_set() # put focus back + return + + self.withdraw() + self.update_idletasks() + + self.apply() + self.cancel() + + def cancel(self, event=None): + # put focus back to the parent window + self.parent.focus_set() + self.destroy() + + def validate(self): + return 1 # override + + def apply(self): + pass # override + + ## -- Set syntax-sugars + def setLabel(self, master, text): + return tk.Label(master, text=text) + + def setLabelWithEntry(self, master, text): + frame = tk.Frame(master, relief='flat') + tk.Label(frame, text=text).grid(row=0, column=0) + entry = tk.Entry(frame) + entry.grid(row=0, column=1) + return frame, entry + + def setSelectRadioButton(self, master, text, radio_pairs, init_var=0): + frame = tk.Frame(master, relief='flat') + tk.Label(frame, text=text).grid(row=0, column=0) + + var = tk.IntVar(value=0) + for i, (k, text) in enumerate(radio_pairs.items()): + tk.Radiobutton(frame, value=k, variable=var, text=text).grid(row=1, column=i) + var.set(init_var) + + return frame, var + # GUI of switch controller simulator class ControllerGUI: def __init__(self, root, ser): diff --git a/SerialController/Window.py b/SerialController/Window.py index 3e327b4..a8f040b 100644 --- a/SerialController/Window.py +++ b/SerialController/Window.py @@ -196,12 +196,11 @@ def startPlay(self): # set and init selected command self.assignCommand() - print(self.startButton["text"] + ' ' + self.cur_command.NAME) - self.cur_command.start(self.ser, self.stopPlayPost) - - self.startButton["text"] = "Stop" - self.startButton["command"] = self.stopPlay - self.reloadCommandButton["state"] = "disabled" + if self.cur_command.startWithOption(self.lf, self.ser, self.stopPlayPost): + print(self.startButton["text"] + ' ' + self.cur_command.NAME) + self.startButton["text"] = "Stop" + self.startButton["command"] = self.stopPlay + self.reloadCommandButton["state"] = "disabled" def stopPlay(self): print(self.startButton["text"] + ' ' + self.cur_command.NAME)