# Based on "Digital Watch GUI" OCT 2008 by Reehan Shaikh reehan.shaikh@cs.mcgill.ca import tkinter from tkinter.constants import BOTH, NO import audio CANVAS_W = 520 CANVAS_H = 348 TIME_X0 = 412 TIME_Y0 = 90 TIME_X1 = 472 TIME_Y1 = 106 BUTTON_HEIGHT = 18 BUTTON_X0 = 412 BUTTON_X1 = 472 START_X0 = BUTTON_X0 START_Y0 = 234 START_X1 = BUTTON_X1 START_Y1 = START_Y0 + BUTTON_HEIGHT STOP_X0 = BUTTON_X0 STOP_Y0 = 211 STOP_X1 = BUTTON_X1 STOP_Y1 = STOP_Y0 + BUTTON_HEIGHT INCTIME_X0 = BUTTON_X0 INCTIME_Y0 = 188 INCTIME_X1 = BUTTON_X1 INCTIME_Y1 = INCTIME_Y0 + BUTTON_HEIGHT DOOR_X0 = 26 DOOR_Y0 = 68 DOOR_X1 = 379 DOOR_Y1 = 285 FONT_TIME = ("terminal", 14) class GUI(tkinter.Frame): def __init__(self, parent): super().__init__(parent) self.imgClosedOff = tkinter.PhotoImage(file="./small_closed_off.png") self.imgClosedOn = tkinter.PhotoImage(file="./small_closed_on.png") self.imgOpenedOff = tkinter.PhotoImage(file="./small_opened_off.png") self.imgOpenedOn = tkinter.PhotoImage(file="./small_opened_on.png") # state self.doorOpened = False self.running = False self.lastPressed = "" self.pack() self.canvas = tkinter.Canvas(master=self, takefocus=1, width=CANVAS_W, height=CANVAS_H, background="black") self.canvas.pack(fill=BOTH, expand=1) self.canvas.focus_set() self.background = self.canvas.create_image(0, 0, image=self.imgClosedOff, anchor="nw") self.rects = [ (START_X0, START_X1, START_Y0, START_Y1, "START"), (STOP_X0, STOP_X1, STOP_Y0, STOP_Y1, "STOP"), (INCTIME_X0, INCTIME_X1, INCTIME_Y0, INCTIME_Y1, "INCTIME"), (DOOR_X0, DOOR_X1, DOOR_Y0, DOOR_Y1, "DOOR"), ] self.timeTag = self.canvas.create_text( TIME_X1-16, TIME_Y0+7, font=FONT_TIME, justify="center", fill="#0f0", text="0") self.canvas.bind("", self.mouse1Click) self.canvas.bind("", self.mouse1Release) parent.protocol("WM_DELETE_WINDOW", self.window_close) def mouse1Click(self, event): def handle(what): if what == "START": self.send_event("start") self.lastPressed = "start" elif what == "STOP": self.send_event("stop") self.lastPressed = "stop" elif what == "INCTIME": self.send_event("increase_time") self.lastPressed = "increase_time" elif what == "DOOR": self.doorOpened = not self.doorOpened if self.doorOpened: self.send_event("door_opened") else: self.send_event("door_closed") self.refresh_background() self.lastPressed = "" else: self.lastPressed = "" X = self.canvas.canvasx(event.x) Y = self.canvas.canvasy(event.y) for X0, X1, Y0, Y1, what in self.rects: if X >= X0 and X <= X1 and Y >= Y0 and Y <= Y1: handle(what) break def mouse1Release(self, event): if self.lastPressed == "start": # self.send_event("releasedStart") pass elif self.lastPressed == "stop": # self.send_event("releasedStop") pass elif self.lastPressed == "increase_time": # self.send_event("releasedIncTime") pass self.lastPressed = "" def refresh_background(self): if self.doorOpened: if self.running: self.canvas.itemconfig(self.background, image=self.imgOpenedOn) else: self.canvas.itemconfig(self.background, image=self.imgOpenedOff) else: if self.running: self.canvas.itemconfig(self.background, image=self.imgClosedOn) else: self.canvas.itemconfig(self.background, image=self.imgClosedOff) # play or stop sound if self.running: audio.play_running() else: audio.stop_running() def handle_event(self, event): if event.name == "micro_on": self.running = True self.refresh_background() elif event.name == "micro_off": self.running = False self.refresh_background() elif event.name == "set_time": self.setTime(event.params[0]) elif event.name == "bell": audio.play_bell() def setTime(self, time: int): self.canvas.itemconfig(self.timeTag, text=str(time)) def window_close(self): import sys sys.exit(0) self.send_event('GUIQuit') tk = tkinter.Tk() tk.withdraw() topLevel = tkinter.Toplevel(tk) topLevel.resizable(width=NO, height=NO) topLevel.title("Microwave oven simulator") gui = GUI(topLevel) from sccd.action_lang.static.types import * SCCD_EXPORTS = { "display_time": (gui.setTime, SCCDFunction([SCCDInt])), }