GUI.py 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. # Based on "Digital Watch GUI" OCT 2008 by Reehan Shaikh reehan.shaikh@cs.mcgill.ca
  2. import tkinter
  3. from tkinter.constants import BOTH, NO
  4. import audio
  5. CANVAS_W = 520
  6. CANVAS_H = 348
  7. TIME_X0 = 412
  8. TIME_Y0 = 90
  9. TIME_X1 = 472
  10. TIME_Y1 = 106
  11. BUTTON_HEIGHT = 18
  12. BUTTON_X0 = 412
  13. BUTTON_X1 = 472
  14. START_X0 = BUTTON_X0
  15. START_Y0 = 234
  16. START_X1 = BUTTON_X1
  17. START_Y1 = START_Y0 + BUTTON_HEIGHT
  18. STOP_X0 = BUTTON_X0
  19. STOP_Y0 = 211
  20. STOP_X1 = BUTTON_X1
  21. STOP_Y1 = STOP_Y0 + BUTTON_HEIGHT
  22. INCTIME_X0 = BUTTON_X0
  23. INCTIME_Y0 = 188
  24. INCTIME_X1 = BUTTON_X1
  25. INCTIME_Y1 = INCTIME_Y0 + BUTTON_HEIGHT
  26. DOOR_X0 = 26
  27. DOOR_Y0 = 68
  28. DOOR_X1 = 379
  29. DOOR_Y1 = 285
  30. FONT_TIME = ("terminal", 14)
  31. class GUI(tkinter.Frame):
  32. def __init__(self, parent):
  33. super().__init__(parent)
  34. self.imgClosedOff = tkinter.PhotoImage(file="./small_closed_off.png")
  35. self.imgClosedOn = tkinter.PhotoImage(file="./small_closed_on.png")
  36. self.imgOpenedOff = tkinter.PhotoImage(file="./small_opened_off.png")
  37. self.imgOpenedOn = tkinter.PhotoImage(file="./small_opened_on.png")
  38. # state
  39. self.doorOpened = False
  40. self.running = False
  41. self.lastPressed = ""
  42. self.pack()
  43. self.canvas = tkinter.Canvas(master=self,
  44. takefocus=1,
  45. width=CANVAS_W, height=CANVAS_H,
  46. background="black")
  47. self.canvas.pack(fill=BOTH, expand=1)
  48. self.canvas.focus_set()
  49. self.background = self.canvas.create_image(0, 0, image=self.imgClosedOff, anchor="nw")
  50. self.rects = [
  51. (START_X0, START_X1, START_Y0, START_Y1, "START"),
  52. (STOP_X0, STOP_X1, STOP_Y0, STOP_Y1, "STOP"),
  53. (INCTIME_X0, INCTIME_X1, INCTIME_Y0, INCTIME_Y1, "INCTIME"),
  54. (DOOR_X0, DOOR_X1, DOOR_Y0, DOOR_Y1, "DOOR"),
  55. ]
  56. self.timeTag = self.canvas.create_text(
  57. TIME_X1-16, TIME_Y0+7,
  58. font=FONT_TIME, justify="center", fill="#0f0", text="0")
  59. self.canvas.bind("<ButtonPress-1>", self.mouse1Click)
  60. self.canvas.bind("<ButtonRelease-1>", self.mouse1Release)
  61. parent.protocol("WM_DELETE_WINDOW", self.window_close)
  62. def mouse1Click(self, event):
  63. def handle(what):
  64. if what == "START":
  65. self.send_event("start")
  66. self.lastPressed = "start"
  67. elif what == "STOP":
  68. self.send_event("stop")
  69. self.lastPressed = "stop"
  70. elif what == "INCTIME":
  71. self.send_event("increase_time")
  72. self.lastPressed = "increase_time"
  73. elif what == "DOOR":
  74. self.doorOpened = not self.doorOpened
  75. if self.doorOpened:
  76. self.send_event("door_opened")
  77. else:
  78. self.send_event("door_closed")
  79. self.refresh_background()
  80. self.lastPressed = ""
  81. else:
  82. self.lastPressed = ""
  83. X = self.canvas.canvasx(event.x)
  84. Y = self.canvas.canvasy(event.y)
  85. for X0, X1, Y0, Y1, what in self.rects:
  86. if X >= X0 and X <= X1 and Y >= Y0 and Y <= Y1:
  87. handle(what)
  88. break
  89. def mouse1Release(self, event):
  90. if self.lastPressed == "start":
  91. # self.send_event("releasedStart")
  92. pass
  93. elif self.lastPressed == "stop":
  94. # self.send_event("releasedStop")
  95. pass
  96. elif self.lastPressed == "increase_time":
  97. # self.send_event("releasedIncTime")
  98. pass
  99. self.lastPressed = ""
  100. def refresh_background(self):
  101. if self.doorOpened:
  102. if self.running:
  103. self.canvas.itemconfig(self.background, image=self.imgOpenedOn)
  104. else:
  105. self.canvas.itemconfig(self.background, image=self.imgOpenedOff)
  106. else:
  107. if self.running:
  108. self.canvas.itemconfig(self.background, image=self.imgClosedOn)
  109. else:
  110. self.canvas.itemconfig(self.background, image=self.imgClosedOff)
  111. # play or stop sound
  112. if self.running:
  113. audio.play_running()
  114. else:
  115. audio.stop_running()
  116. def handle_event(self, event):
  117. if event.name == "micro_on":
  118. self.running = True
  119. self.refresh_background()
  120. elif event.name == "micro_off":
  121. self.running = False
  122. self.refresh_background()
  123. elif event.name == "set_time":
  124. self.setTime(event.params[0])
  125. elif event.name == "bell":
  126. audio.play_bell()
  127. def setTime(self, time: int):
  128. self.canvas.itemconfig(self.timeTag, text=str(time))
  129. def window_close(self):
  130. import sys
  131. sys.exit(0)
  132. self.send_event('GUIQuit')
  133. tk = tkinter.Tk()
  134. tk.withdraw()
  135. topLevel = tkinter.Toplevel(tk)
  136. topLevel.resizable(width=NO, height=NO)
  137. topLevel.title("Microwave oven simulator")
  138. gui = GUI(topLevel)
  139. from sccd.action_lang.static.types import *
  140. SCCD_EXPORTS = {
  141. "display_time": (gui.setTime, SCCDFunction([SCCDInt])),
  142. }