Handlers.py 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. #!/usr/bin/env python3
  2. # -*- coding: utf-8 -*-
  3. #
  4. # Handlers.py
  5. #
  6. # MIT License
  7. # Copyright 2022 Stephen Stengel <stephen.stengel@cwu.edu>
  8. #
  9. import gi
  10. gi.require_version("Gtk", "3.0")
  11. ##Gdk is needed to change background color, GLib is for setting a timer
  12. from gi.repository import Gtk, Gdk, GLib
  13. from os import kill
  14. import random
  15. import subprocess
  16. import signal
  17. import pygame.mixer as mixer
  18. #exitProcess global variable is used to make sure that the music process gets killed when the window is closed.
  19. #It is set to a value at the same time as self.myProcess.
  20. #It is only read when the exit window button is pressed and the Gtk.main_quit function is about to be called.
  21. #An alternate way would be to save the number to a file.
  22. exitProcess = None
  23. class Handlers():
  24. myProcess = None
  25. is_bright_phase = False
  26. flashCount = 0
  27. label1Angle = 0
  28. timeout_id = None
  29. playButtonPressCounter = 0
  30. whichJigglypuffGif = 0
  31. currentPath = ""
  32. jigglypuff = None
  33. stop_button = None
  34. label1 = None
  35. window = None
  36. is_deprecated_been_printed = False
  37. is_playing = False
  38. #Initialize some fields.
  39. def __init__(self, jigglypuff, stop_button, label1, window):
  40. mixer.init()
  41. mixer.music.load("james-brown-dead.ogg")
  42. self.whichJigglypuffGif = -1
  43. self.jigglypuff_increment()
  44. self.jigglypuff = jigglypuff
  45. self.stop_button = stop_button
  46. self.label1 = label1
  47. self.window = window
  48. #The event function for the play music button. It creates an ogg123
  49. #process and saves the ID. Also, it starts playing a jigglypuff gif.
  50. def button1_clicked(self, button):
  51. print("Start music button pressed!")
  52. if self.is_playing is False:
  53. mixer.music.play(loops = -1)
  54. self.renderJigglypuffFrame()
  55. self.jigglypuff_increment()
  56. self.is_playing = True
  57. self.changeBackgroundColor()
  58. #Increase spinny speed if pressed multiple times. Name change might be prudent.?
  59. if self.playButtonPressCounter == 0:
  60. self.start_timer()
  61. self.playButtonPressCounter += 1
  62. self.stop_button.set_sensitive(True)
  63. #The event function for the stop music button. It stops the music
  64. #and hides jigglypuff.
  65. def music_stop_clicked_cb(self, button):
  66. print("Stop button pressed!")
  67. mixer.music.stop()
  68. self.stop_timer()
  69. self.playButtonPressCounter = 0
  70. Gtk.Image.clear(self.jigglypuff)
  71. self.stop_button.set_sensitive(False)
  72. self.is_playing = False
  73. #This is used to stop the music from playing if the user closes the window during playback.
  74. def myDestroy(self):
  75. print("Exit window button pressed!")
  76. global exitProcess
  77. if exitProcess is not None:
  78. print("Killing this process: " + str(exitProcess.pid))
  79. kill(exitProcess.pid, signal.SIGKILL)
  80. #The rave button!!!!!!!1 WOOOOOOOOOO!!!1!+shift1!!!
  81. def rave_button_clicked_cb(self, button):
  82. print("Rave button clicked!")
  83. self.changeBackgroundColor()
  84. self.spinText()
  85. #The function that is called when the timer times out.
  86. #kwargs doesn't seem to do anything. I don't know why it is there.
  87. def on_timeout(self, *args, **kwargs):
  88. if self.timeout_id is not None:
  89. self.changeBackgroundColor()
  90. self.spinText()
  91. return True
  92. else:
  93. return False
  94. #Increments the jigglypuff gif that will be played.
  95. def jigglypuff_increment(self):
  96. self.whichJigglypuffGif += 1
  97. self.whichJigglypuffGif %= 5
  98. self.currentPath = "jigglypuff-gifs/" + str(self.whichJigglypuffGif + 1) + ".gif"
  99. #Play the current jigglypuff gif.
  100. def renderJigglypuffFrame(self):
  101. myPath = self.currentPath
  102. self.jigglypuff.set_from_file(myPath)
  103. #Starts the rave color changing timer. I used 114ms because it
  104. #matches up with the music.
  105. def start_timer(self):
  106. self.timeout_id = GLib.timeout_add(114, self.on_timeout, None)
  107. #Stops the rave timer. Called from music_stop_clicked_cb()
  108. def stop_timer(self):
  109. if self.timeout_id:
  110. GLib.source_remove(self.timeout_id)
  111. self.timeout_id = None
  112. #Changes the background color whenever you type on the keyboard.
  113. def myWindow_key_press_event(self, a, b):
  114. print("key-press-event has happened!")
  115. self.changeBackgroundColor()
  116. self.spinText()
  117. #This function picks a random background color to change to and
  118. #changes to it. I made sure to alternate between light and dark with
  119. #every call to give more strobe effect.
  120. def changeBackgroundColor(self):
  121. r, g, b = random.random(), random.random(), random.random()
  122. if self.is_bright_phase == False:
  123. #Set the color to be a little darker
  124. r = r - (r / 2)
  125. g = g - (g / 2)
  126. b = b - (b / 2)
  127. self.is_bright_phase = True
  128. else:
  129. #set the color to be a little brighter
  130. r = ((1 - r) / 2) + r
  131. g = ((1 - g) / 2) + g
  132. b = ((1 - b) / 2) + b
  133. self.is_bright_phase = False
  134. #depricated call
  135. if not self.is_deprecated_been_printed:
  136. print("\"override_background_color\" is depricated. "
  137. "Try to find the new way to do it.")
  138. self.is_deprecated_been_printed = True
  139. self.window.override_background_color(
  140. Gtk.StateFlags.NORMAL,
  141. Gdk.RGBA(r, g, b, 1)) #Opacity should never change.
  142. #This updates the angle of the spinning text.
  143. def spinText(self):
  144. adjustedCounter = None
  145. if self.playButtonPressCounter == 0:
  146. adjustedCounter = 1
  147. else:
  148. adjustedCounter = self.playButtonPressCounter
  149. angleIncrement = 6 * adjustedCounter
  150. self.label1Angle = (self.label1Angle - angleIncrement) % 360
  151. self.label1.set_angle(self.label1Angle)