def __init__(self): Window.__init__(self) self.create(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT, caption=True, resize=False) self._initTetris() # Button for 'Start' and 'Tetris.PAUSE' self._triggerButton = TextButton(self) self._triggerButton.rect = (0, 0, 50, 30) self._triggerButton.fontColor = color.red self._triggerButton.text = 'Start' self._triggerButton.background = r'Images\Button.jpg' self.autoRemove(self._triggerButton.bind('Click', self._onTrigger)) # Button for 'Restart' self._restartButton = TextButton(self) self._restartButton.rect = (60, 0, 50, 30) self._restartButton.fontColor = color.red self._restartButton.text = 'Restart' self._restartButton.background = r'Images\Button.jpg' self.autoRemove(self._restartButton.bind('Click', self._onRestart)) self._backgroundTexture = self.imageTextureManager.GetTexture(r'Images\Background.jpg') self._backgroundEffect = self.effectManager.GetEffect(r'backgroundEffects\Background.fx') self._fontEffect = self.effectManager.GetEffect(r'fontEffects\font.fx')
def __init__(self): Window.__init__(self) self.create(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT, caption=True, resize=False) self._initTetris() # Button for 'Start' and 'Tetris.PAUSE' self._triggerButton = TextButton(self) self._triggerButton.rect = (0, 0, 50, 30) self._triggerButton.fontColor = color.red self._triggerButton.text = 'Start' self._triggerButton.background = r'Images\Button.jpg' self.autoRemove(self._triggerButton.bind('Click', self._onTrigger)) # Button for 'Restart' self._restartButton = TextButton(self) self._restartButton.rect = (60, 0, 50, 30) self._restartButton.fontColor = color.red self._restartButton.text = 'Restart' self._restartButton.background = r'Images\Button.jpg' self.autoRemove(self._restartButton.bind('Click', self._onRestart)) self._backgroundTexture = self.imageTextureManager.GetTexture( r'Images\Background.jpg') self._backgroundEffect = self.effectManager.GetEffect( r'backgroundEffects\Background.fx') self._fontEffect = self.effectManager.GetEffect(r'fontEffects\font.fx')
def __init__(self): Window.__init__(self) self.create(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT, caption = True) self._plate_images = [] # Button for 'Start' and 'Pause' self._trigger_button = TextButton(self) self._trigger_button.rect = 0, 0, 50, 30 self._trigger_button.text = 'Start' self._trigger_button.background = r'Images\Root_button.png' self.autoRemove(self._trigger_button.bind('Click', self._on_trigger_button_click)) # Button for 'Restart' self._restart_button = TextButton(self) self._restart_button.rect = 60, 0, 50, 30 self._restart_button.text = 'Restart' self._restart_button.background = r'Images\Root_button.png' self.autoRemove(self._restart_button.bind('Click', self._on_restart_button_click)) # Button for 'Next' self._next_button = TextButton(self) self._next_button.rect = 120, 0, 50, 30 self._next_button.text = 'Next' self._next_button.background = r'Images\Root_button.png' self.autoRemove(self._next_button.bind('Click', self._on_next_button_click)) self._init_hanoi()
def __init__(self): Window.__init__(self) self.create(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT, caption=True) self._plate_images = [] # Button for 'Start' and 'Pause' self._trigger_button = TextButton(self) self._trigger_button.rect = 0, 0, 50, 30 self._trigger_button.text = 'Start' self._trigger_button.background = r'Images\Root_button.png' self.autoRemove( self._trigger_button.bind('Click', self._on_trigger_button_click)) # Button for 'Restart' self._restart_button = TextButton(self) self._restart_button.rect = 60, 0, 50, 30 self._restart_button.text = 'Restart' self._restart_button.background = r'Images\Root_button.png' self.autoRemove( self._restart_button.bind('Click', self._on_restart_button_click)) # Button for 'Next' self._next_button = TextButton(self) self._next_button.rect = 120, 0, 50, 30 self._next_button.text = 'Next' self._next_button.background = r'Images\Root_button.png' self.autoRemove( self._next_button.bind('Click', self._on_next_button_click)) self._init_hanoi()
def _init_hanoi(self): # Variables for the animation self._next_move = True self._move = 0 self._starting_left = 0 self._starting_top = 0 self._target_left = 0 self._target_top = 0 self._acceleration = 0 self._time_spent = 0 # Flags indicating the state of the program self._running_flag = False self._step_by_step_flag = False self._over_flag = False # Reset the trigger_button to 'Start' self._trigger_button.text = 'Start' # Hanoi algorithm object self._hanoi = Hanoi(input('Please enter the number of plates\n')) # Initialization of the plate images for each_plate in self._hanoi.get_plates(0): plate_image = TextButton(self) plate_image.rect = (70 + self._hanoi.get_total() * PLATE_BASE_WIDTH / 2) - each_plate.number * PLATE_BASE_WIDTH / 2, \ (WINDOW_HEIGHT - self._hanoi.get_total() * PLATE_HEIGHT) + each_plate.number * PLATE_HEIGHT, \ PLATE_BASE_WIDTH * (each_plate.number + 1), \ PLATE_HEIGHT plate_image.background = r'Images\Root_button.png' self._plate_images.insert(0, plate_image) # Start running the hanoi algorithm and animation self._steps = self._hanoi.move(self._hanoi.get_total(), 0, 2) self._animation = koan.anim.IntervalExecute(TIME_INTERVAL, self._onTimer)
class TetrisWindow(Window): def __init__(self): Window.__init__(self) self.create(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT, caption=True, resize=False) self._initTetris() # Button for 'Start' and 'Tetris.PAUSE' self._triggerButton = TextButton(self) self._triggerButton.rect = (0, 0, 50, 30) self._triggerButton.fontColor = color.red self._triggerButton.text = 'Start' self._triggerButton.background = r'Images\Button.jpg' self.autoRemove(self._triggerButton.bind('Click', self._onTrigger)) # Button for 'Restart' self._restartButton = TextButton(self) self._restartButton.rect = (60, 0, 50, 30) self._restartButton.fontColor = color.red self._restartButton.text = 'Restart' self._restartButton.background = r'Images\Button.jpg' self.autoRemove(self._restartButton.bind('Click', self._onRestart)) self._backgroundTexture = self.imageTextureManager.GetTexture(r'Images\Background.jpg') self._backgroundEffect = self.effectManager.GetEffect(r'backgroundEffects\Background.fx') self._fontEffect = self.effectManager.GetEffect(r'fontEffects\font.fx') # Initialization def _initTetris(self): self._gameState = Tetris.PAUSE self._tetrisP1 = Tetris.Tetris('P1') self._tetrisP1.setBricks() self._canvasP1 = TetrisCanvas(self, self._tetrisP1) self._canvasP1.rect = (WINDOW_WIDTH / 20, WINDOW_HEIGHT / 6, CANVAS_WIDTH, CANVAS_HEIGHT) # Create a new animation attribute for tetrisP1 self._tetrisP1.animation = None self._tetrisP2 = Tetris.Tetris('P2') self._tetrisP2.setBricks() self._canvasP2 = TetrisCanvas(self, self._tetrisP2) self._canvasP2.rect = (WINDOW_WIDTH / 2, WINDOW_HEIGHT / 6, CANVAS_WIDTH, CANVAS_HEIGHT) # Create a new animation attribute for tetrisP2 self._tetrisP2.animation = None # Callback function for key events def onKey(self, key): if self._gameState != Tetris.OVER and self._gameState != Tetris.PAUSE: self._controlP1(key) if not Tetris.SINGLE_MODE: self._controlP2(key) return super(TetrisWindow, self).onKey(key) # Key controls for player1 def _controlP1(self, key): if key == 'UP': self._tetrisP1.currentBrick.rotate(1) if self._tetrisP1.isOccupied('ROTATE') == True: self._tetrisP1.currentBrick.rotate(-1) elif key == 'DOWN': if self._tetrisP1.isOccupied('DOWN') == False: self._tetrisP1.currentBrick.top += 1 else: returnStatus = self._tetrisP1.checkElimination() self._gameState = returnStatus['GameState'] self._tetrisP2.levelChanged = returnStatus['LevelChanged'] elif key == 'LEFT': if self._tetrisP1.isOccupied('LEFT') == False: self._tetrisP1.currentBrick.left -= 1 elif key == 'RIGHT': if self._tetrisP1.isOccupied('RIGHT') == False: self._tetrisP1.currentBrick.left += 1 elif key == ' ': while self._tetrisP1.isOccupied('DOWN') == False: self._tetrisP1.currentBrick.top += 1 returnStatus = self._tetrisP1.checkElimination() self._gameState = returnStatus['GameState'] self._tetrisP2.levelChanged = returnStatus['LevelChanged'] self._canvasP1.setDirty() # Key controls for player2 def _controlP2(self, key): if key == 'w': self._tetrisP2.currentBrick.rotate(1) if self._tetrisP2.isOccupied('ROTATE') == True: self._tetrisP2.currentBrick.rotate(-1) elif key == 's': if self._tetrisP2.isOccupied('DOWN') == False: self._tetrisP2.currentBrick.top += 1 else: returnStatus = self._tetrisP2.checkElimination() self._gameState = returnStatus['GameState'] self._tetrisP1.levelChanged = returnStatus['LevelChanged'] elif key == 'a': if self._tetrisP2.isOccupied('LEFT') == False: self._tetrisP2.currentBrick.left -= 1 elif key == 'd': if self._tetrisP2.isOccupied('RIGHT') == False: self._tetrisP2.currentBrick.left += 1 elif key == '`': while self._tetrisP2.isOccupied('DOWN') == False: self._tetrisP2.currentBrick.top += 1 returnStatus = self._tetrisP2.checkElimination() self._gameState = returnStatus['GameState'] self._tetrisP1.levelChanged = returnStatus['LevelChanged'] self._canvasP2.setDirty() # Callback function for button 'Start' and 'Pause' def _onTrigger(self): if self._gameState == Tetris.PAUSE: self._gameState = Tetris.RUNNING self._triggerButton.text = 'PAUSE' self._restartButton.fontColor = color.black self._tetrisP1.animation = koan.anim.IntervalExecute(3.0 / (2 + self._tetrisP1.level), self._onTimer, self._tetrisP1, self._canvasP1) if not Tetris.SINGLE_MODE: self._tetrisP2.animation = koan.anim.IntervalExecute(3.0 / (2 + self._tetrisP2.level), self._onTimer, self._tetrisP2, self._canvasP2) elif self._gameState == Tetris.RUNNING: self._gameState = Tetris.PAUSE self._restartButton.fontColor = color.red self._triggerButton.text = 'Start' self._tetrisP1.animation.remove() if not Tetris.SINGLE_MODE: self._tetrisP2.animation.remove() # Callback function for button 'Restart' def _onRestart(self): if self._gameState == Tetris.PAUSE or self._gameState == Tetris.OVER: self._triggerButton.fontColor = color.red self._triggerButton.text = 'Start' if self._tetrisP1.animation: self._tetrisP1.animation.remove() if self._tetrisP2.animation: self._tetrisP2.animation.remove() self._initTetris() # Callback function for refreshing players' info and brick's location def _onTimer(self, tetris, canvas): # Level up, re-register the timer interval to change the speed of the brick if tetris.levelChanged: tetris.level += 1 tetris.levelChanged = False tetris.animation.remove() tetris.animation = koan.anim.IntervalExecute(3.0 / (2 + tetris.level), self._onTimer, tetris, canvas) # Check if the game is over if self._gameState == Tetris.OVER: self._restartButton.fontColor = color.red self._triggerButton.fontColor = color.black tetris.animation.remove() return # Check if the game is paused if self._gameState == Tetris.PAUSE: return if tetris.isOccupied('DOWN') == False: tetris.currentBrick.top += 1 else: returnStatus = tetris.checkElimination() self._gameState = returnStatus['GameState'] levelChanged = returnStatus['LevelChanged'] if tetris.name == 'P1': self._tetrisP2.levelChanged = levelChanged elif tetris.name == 'P2': self._tetrisP1.levelChanged = levelChanged tetris.time += 3.0 / (2 + tetris.level) self.setDirty() canvas.setDirty() def onDraw(self, render): render.Clear(*color.translucent) # Background color render.SetColor(*color.green) render.SetTexture(self._backgroundTexture) render.PushEffect(self._backgroundEffect) render.DrawRect(0, 0, self.right, self.bottom) render.PopEffect() self._drawGameState(render) self._drawPlayerInfo(render, self._tetrisP1, left=280) self._drawNextBrick(render, self._tetrisP1, left=300) self._drawNextBrick(render, self._tetrisP2, left=670) self._drawPlayerInfo(render, self._tetrisP2, left=650) def _drawGameState(self, render): render.SetColor(*color.white) render.PushEffect(self._fontEffect) if self._gameState == Tetris.OVER: if self._tetrisP1.gameOver and self._tetrisP2.gameOver: render.DrawText('Draw!!! Press "Restart" Button to restart', (200, 45), 20, color.white) elif self._tetrisP1.gameOver: render.DrawText('P2 Wins!!! Press "Restart" Button to restart', (200, 45), 20, color.white) elif self._tetrisP2.gameOver: render.DrawText('P1 Wins!!! Press "Restart" Button to restart', (200, 45), 20, color.white) elif self._gameState == Tetris.PAUSE: render.DrawText('Press "Start" Button to start', (200, 45), 20, color.white) else: render.DrawText('Time: ' + str(int(self._tetrisP1.time)), (330, 45), 20, color.white) render.PopEffect() def _drawPlayerInfo(self, render, tetris, left=280, top=80, size=20): render.SetColor(*color.white) render.PushEffect(self._fontEffect) render.DrawText('Level: ' + str(tetris.level), (left, top), size, color.white) render.DrawText('Lines: ' + str(tetris.lines), (left, top + 25), size, color.white) render.DrawText('Score: ' + str(tetris.score), (left, top + 50), size, color.white) render.DrawText('Next:', (left, top + 100), size, color.white) render.PopEffect() def _drawNextBrick(self, render, tetris, left=300, top=220): brickTexture = self.imageTextureManager.GetTexture(tetris.nextBrick.image) render.SetTexture(brickTexture) for i in range(4): for j in range(4): if tetris.nextBrick.imageMap[i][j] == 1: tempTop = top + i * GRID_LENGTH tempLeft = left + j * GRID_LENGTH render.DrawRect(tempLeft, tempTop, tempLeft + GRID_LENGTH, tempTop + GRID_LENGTH) def close(self): if self._tetrisP1.animation: self._tetrisP1.animation.remove() self._tetrisP1.animation = None if self._tetrisP2.animation: self._tetrisP2.animation.remove() self._tetrisP2.animation = None print '[TetrisWindow::close] Window closed' super(TetrisWindow, self).close()
class TetrisWindow(Window): def __init__(self): Window.__init__(self) self.create(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT, caption=True, resize=False) self._initTetris() # Button for 'Start' and 'Tetris.PAUSE' self._triggerButton = TextButton(self) self._triggerButton.rect = (0, 0, 50, 30) self._triggerButton.fontColor = color.red self._triggerButton.text = 'Start' self._triggerButton.background = r'Images\Button.jpg' self.autoRemove(self._triggerButton.bind('Click', self._onTrigger)) # Button for 'Restart' self._restartButton = TextButton(self) self._restartButton.rect = (60, 0, 50, 30) self._restartButton.fontColor = color.red self._restartButton.text = 'Restart' self._restartButton.background = r'Images\Button.jpg' self.autoRemove(self._restartButton.bind('Click', self._onRestart)) self._backgroundTexture = self.imageTextureManager.GetTexture( r'Images\Background.jpg') self._backgroundEffect = self.effectManager.GetEffect( r'backgroundEffects\Background.fx') self._fontEffect = self.effectManager.GetEffect(r'fontEffects\font.fx') # Initialization def _initTetris(self): self._gameState = Tetris.PAUSE self._tetrisP1 = Tetris.Tetris('P1') self._tetrisP1.setBricks() self._canvasP1 = TetrisCanvas(self, self._tetrisP1) self._canvasP1.rect = (WINDOW_WIDTH / 20, WINDOW_HEIGHT / 6, CANVAS_WIDTH, CANVAS_HEIGHT) # Create a new animation attribute for tetrisP1 self._tetrisP1.animation = None self._tetrisP2 = Tetris.Tetris('P2') self._tetrisP2.setBricks() self._canvasP2 = TetrisCanvas(self, self._tetrisP2) self._canvasP2.rect = (WINDOW_WIDTH / 2, WINDOW_HEIGHT / 6, CANVAS_WIDTH, CANVAS_HEIGHT) # Create a new animation attribute for tetrisP2 self._tetrisP2.animation = None # Callback function for key events def onKey(self, key): if self._gameState != Tetris.OVER and self._gameState != Tetris.PAUSE: self._controlP1(key) if not Tetris.SINGLE_MODE: self._controlP2(key) return super(TetrisWindow, self).onKey(key) # Key controls for player1 def _controlP1(self, key): if key == 'UP': self._tetrisP1.currentBrick.rotate(1) if self._tetrisP1.isOccupied('ROTATE') == True: self._tetrisP1.currentBrick.rotate(-1) elif key == 'DOWN': if self._tetrisP1.isOccupied('DOWN') == False: self._tetrisP1.currentBrick.top += 1 else: returnStatus = self._tetrisP1.checkElimination() self._gameState = returnStatus['GameState'] self._tetrisP2.levelChanged = returnStatus['LevelChanged'] elif key == 'LEFT': if self._tetrisP1.isOccupied('LEFT') == False: self._tetrisP1.currentBrick.left -= 1 elif key == 'RIGHT': if self._tetrisP1.isOccupied('RIGHT') == False: self._tetrisP1.currentBrick.left += 1 elif key == ' ': while self._tetrisP1.isOccupied('DOWN') == False: self._tetrisP1.currentBrick.top += 1 returnStatus = self._tetrisP1.checkElimination() self._gameState = returnStatus['GameState'] self._tetrisP2.levelChanged = returnStatus['LevelChanged'] self._canvasP1.setDirty() # Key controls for player2 def _controlP2(self, key): if key == 'w': self._tetrisP2.currentBrick.rotate(1) if self._tetrisP2.isOccupied('ROTATE') == True: self._tetrisP2.currentBrick.rotate(-1) elif key == 's': if self._tetrisP2.isOccupied('DOWN') == False: self._tetrisP2.currentBrick.top += 1 else: returnStatus = self._tetrisP2.checkElimination() self._gameState = returnStatus['GameState'] self._tetrisP1.levelChanged = returnStatus['LevelChanged'] elif key == 'a': if self._tetrisP2.isOccupied('LEFT') == False: self._tetrisP2.currentBrick.left -= 1 elif key == 'd': if self._tetrisP2.isOccupied('RIGHT') == False: self._tetrisP2.currentBrick.left += 1 elif key == '`': while self._tetrisP2.isOccupied('DOWN') == False: self._tetrisP2.currentBrick.top += 1 returnStatus = self._tetrisP2.checkElimination() self._gameState = returnStatus['GameState'] self._tetrisP1.levelChanged = returnStatus['LevelChanged'] self._canvasP2.setDirty() # Callback function for button 'Start' and 'Pause' def _onTrigger(self): if self._gameState == Tetris.PAUSE: self._gameState = Tetris.RUNNING self._triggerButton.text = 'PAUSE' self._restartButton.fontColor = color.black self._tetrisP1.animation = koan.anim.IntervalExecute( 3.0 / (2 + self._tetrisP1.level), self._onTimer, self._tetrisP1, self._canvasP1) if not Tetris.SINGLE_MODE: self._tetrisP2.animation = koan.anim.IntervalExecute( 3.0 / (2 + self._tetrisP2.level), self._onTimer, self._tetrisP2, self._canvasP2) elif self._gameState == Tetris.RUNNING: self._gameState = Tetris.PAUSE self._restartButton.fontColor = color.red self._triggerButton.text = 'Start' self._tetrisP1.animation.remove() if not Tetris.SINGLE_MODE: self._tetrisP2.animation.remove() # Callback function for button 'Restart' def _onRestart(self): if self._gameState == Tetris.PAUSE or self._gameState == Tetris.OVER: self._triggerButton.fontColor = color.red self._triggerButton.text = 'Start' if self._tetrisP1.animation: self._tetrisP1.animation.remove() if self._tetrisP2.animation: self._tetrisP2.animation.remove() self._initTetris() # Callback function for refreshing players' info and brick's location def _onTimer(self, tetris, canvas): # Level up, re-register the timer interval to change the speed of the brick if tetris.levelChanged: tetris.level += 1 tetris.levelChanged = False tetris.animation.remove() tetris.animation = koan.anim.IntervalExecute( 3.0 / (2 + tetris.level), self._onTimer, tetris, canvas) # Check if the game is over if self._gameState == Tetris.OVER: self._restartButton.fontColor = color.red self._triggerButton.fontColor = color.black tetris.animation.remove() return # Check if the game is paused if self._gameState == Tetris.PAUSE: return if tetris.isOccupied('DOWN') == False: tetris.currentBrick.top += 1 else: returnStatus = tetris.checkElimination() self._gameState = returnStatus['GameState'] levelChanged = returnStatus['LevelChanged'] if tetris.name == 'P1': self._tetrisP2.levelChanged = levelChanged elif tetris.name == 'P2': self._tetrisP1.levelChanged = levelChanged tetris.time += 3.0 / (2 + tetris.level) self.setDirty() canvas.setDirty() def onDraw(self, render): render.Clear(*color.translucent) # Background color render.SetColor(*color.green) render.SetTexture(self._backgroundTexture) render.PushEffect(self._backgroundEffect) render.DrawRect(0, 0, self.right, self.bottom) render.PopEffect() self._drawGameState(render) self._drawPlayerInfo(render, self._tetrisP1, left=280) self._drawNextBrick(render, self._tetrisP1, left=300) self._drawNextBrick(render, self._tetrisP2, left=670) self._drawPlayerInfo(render, self._tetrisP2, left=650) def _drawGameState(self, render): render.SetColor(*color.white) render.PushEffect(self._fontEffect) if self._gameState == Tetris.OVER: if self._tetrisP1.gameOver and self._tetrisP2.gameOver: render.DrawText('Draw!!! Press "Restart" Button to restart', (200, 45), 20, color.white) elif self._tetrisP1.gameOver: render.DrawText('P2 Wins!!! Press "Restart" Button to restart', (200, 45), 20, color.white) elif self._tetrisP2.gameOver: render.DrawText('P1 Wins!!! Press "Restart" Button to restart', (200, 45), 20, color.white) elif self._gameState == Tetris.PAUSE: render.DrawText('Press "Start" Button to start', (200, 45), 20, color.white) else: render.DrawText('Time: ' + str(int(self._tetrisP1.time)), (330, 45), 20, color.white) render.PopEffect() def _drawPlayerInfo(self, render, tetris, left=280, top=80, size=20): render.SetColor(*color.white) render.PushEffect(self._fontEffect) render.DrawText('Level: ' + str(tetris.level), (left, top), size, color.white) render.DrawText('Lines: ' + str(tetris.lines), (left, top + 25), size, color.white) render.DrawText('Score: ' + str(tetris.score), (left, top + 50), size, color.white) render.DrawText('Next:', (left, top + 100), size, color.white) render.PopEffect() def _drawNextBrick(self, render, tetris, left=300, top=220): brickTexture = self.imageTextureManager.GetTexture( tetris.nextBrick.image) render.SetTexture(brickTexture) for i in range(4): for j in range(4): if tetris.nextBrick.imageMap[i][j] == 1: tempTop = top + i * GRID_LENGTH tempLeft = left + j * GRID_LENGTH render.DrawRect(tempLeft, tempTop, tempLeft + GRID_LENGTH, tempTop + GRID_LENGTH) def close(self): if self._tetrisP1.animation: self._tetrisP1.animation.remove() self._tetrisP1.animation = None if self._tetrisP2.animation: self._tetrisP2.animation.remove() self._tetrisP2.animation = None print '[TetrisWindow::close] Window closed' super(TetrisWindow, self).close()
def __init__(self): Window.__init__(self) # Initialization of the C++ DirectShow Library self.audioFunctions = AudioFunctions() self.audioFunctions.InitDirectShow() # Media Information self.media = Media() # The main window self.create(100, 100, 700, 300, caption=True, resize=False) # Button for 'OpenFile' self._openFileButton = TextButton(self) self._openFileButton.rect = (0, 0, 50, 30) self._openFileButton.text = 'OpenFile' self._openFileButton.background = r'Images\Root_button.png' self.autoRemove(self._openFileButton.bind('Click', self._onOpenFile)) # Button for 'Play' and 'Pause' self._triggerButton = TextButton(self) self._triggerButton.rect = (60, 0, 50, 30) self._triggerButton.text = 'Play' self._triggerButton.background = r'Images\Root_button.png' self.autoRemove(self._triggerButton.bind('Click', self._onTrigger)) # Button for 'Stop' self._stopButton = TextButton(self) self._stopButton.rect = (120, 0, 50, 30) self._stopButton.text = 'Stop' self._stopButton.background = r'Images\Root_button.png' self.autoRemove(self._stopButton.bind('Click', self._onStop)) # Button for 'Remove' self._stopButton = TextButton(self) self._stopButton.rect = (450, 0, 50, 30) self._stopButton.text = 'Remove' self._stopButton.background = r'Images\Root_button.png' self.autoRemove(self._stopButton.bind('Click', self._onRemove)) # PlayTime self._playTimeText = Text(self) self._playTimeText.autosize = True self._playTimeText.text = 'PlayTime' self._playTimeText.fontSize = 15 self._playTimeText.xy = (30, 155) # Slider for 'playTime' self._playTimeSlider = Slider(self) self._playTimeSlider.bgColor = color.gray self._playTimeSlider.vertical = False self._playTimeSlider.rect = (100, 160, 255, 10) self._playTimeSlider.thumbMinSize = 10 self._playTimeSlider.thumbImage = r'Images\ScrollBarThumb.jpg' self.autoRemove( self._playTimeSlider.bind('Slide', self._onPlayTimeSlide)) self.autoRemove( self._playTimeSlider.bind('Slide Start', self._onPlayTimeSlideStart)) self.autoRemove( self._playTimeSlider.bind('Slide End', self._onPlayTimeSlideEnd)) # Slider for 'Volume' self._volumeSlider = Slider(self) self._volumeSlider.bgColor = color.gray self._volumeSlider.vertical = True self._volumeSlider.rect = (400, 50, 10, 100) self._volumeSlider.thumbMinSize = 10 self._volumeSlider.thumbImage = r'Images\ScrollBarThumb.jpg' self.autoRemove(self._volumeSlider.bind('Slide', self._onVolumeSlide)) # Volume self._volumeText = Text(self) self._volumeText.autosize = True self._volumeText.text = 'Volume' self._volumeText.fontSize = 15 self._volumeText.xy = (380, 155) # Media Information text self._mediaInfoText = Text(self) self._mediaInfoText.autosize = True self._mediaInfoText.fontSize = 15 self._mediaInfoText.xy = (20, 45) self._mediaInfoText.text = 'FileName: \n' \ 'Duration: 0 min 0 sec\n' # Media Position text self._mediaPositionText = Text(self) self._mediaPositionText.autosize = True self._mediaPositionText.fontSize = 15 self._mediaPositionText.xy = (20, 80) self._mediaPositionText.text = 'Position: 0 min 0 sec\n' # Playlist text self._playlistText = Text(self) self._playlistText.autosize = True self._playlistText.text = 'Playlist' self._playlistText.fontSize = 15 self._playlistText.fontColor = color.blue self._playlistText.xy = (450, 30) # Restore the playlist from disk self.playList = {} self.workingDir = os.getcwd() # Locate the current working directory try: playListFile = open(self.workingDir + r'\PlayList.pickle', 'rb') except IOError: print '[AudioBoxWindow::__init__] No Playlist File Found' else: print '[AudioBoxWindow::__init__] Load Playlist File' self.playList = pickle.load( playListFile) # Dictionary storing the playlist playListFile.close() # Radio button group self._platListGroup = Group(self) self._platListGroup.xy = (450, 50) self._platListGroup.size = (200, 500) self._platListGroup.autosize = True # Display the playlist self.mediaButtonList = [] self._refreshPlayList() # Flag indicating if the playTime slider is sliding self.playTimeSliding = False self.displayAnim = None self.displayAnimRunning = False
class AudioBoxWindow(Window): def __init__(self): Window.__init__(self) # Initialization of the C++ DirectShow Library self.audioFunctions = AudioFunctions() self.audioFunctions.InitDirectShow() # Media Information self.media = Media() # The main window self.create(100, 100, 700, 300, caption=True, resize=False) # Button for 'OpenFile' self._openFileButton = TextButton(self) self._openFileButton.rect = (0, 0, 50, 30) self._openFileButton.text = 'OpenFile' self._openFileButton.background = r'Images\Root_button.png' self.autoRemove(self._openFileButton.bind('Click', self._onOpenFile)) # Button for 'Play' and 'Pause' self._triggerButton = TextButton(self) self._triggerButton.rect = (60, 0, 50, 30) self._triggerButton.text = 'Play' self._triggerButton.background = r'Images\Root_button.png' self.autoRemove(self._triggerButton.bind('Click', self._onTrigger)) # Button for 'Stop' self._stopButton = TextButton(self) self._stopButton.rect = (120, 0, 50, 30) self._stopButton.text = 'Stop' self._stopButton.background = r'Images\Root_button.png' self.autoRemove(self._stopButton.bind('Click', self._onStop)) # Button for 'Remove' self._stopButton = TextButton(self) self._stopButton.rect = (450, 0, 50, 30) self._stopButton.text = 'Remove' self._stopButton.background = r'Images\Root_button.png' self.autoRemove(self._stopButton.bind('Click', self._onRemove)) # PlayTime self._playTimeText = Text(self) self._playTimeText.autosize = True self._playTimeText.text = 'PlayTime' self._playTimeText.fontSize = 15 self._playTimeText.xy = (30, 155) # Slider for 'playTime' self._playTimeSlider = Slider(self) self._playTimeSlider.bgColor = color.gray self._playTimeSlider.vertical = False self._playTimeSlider.rect = (100, 160, 255, 10) self._playTimeSlider.thumbMinSize = 10 self._playTimeSlider.thumbImage = r'Images\ScrollBarThumb.jpg' self.autoRemove( self._playTimeSlider.bind('Slide', self._onPlayTimeSlide)) self.autoRemove( self._playTimeSlider.bind('Slide Start', self._onPlayTimeSlideStart)) self.autoRemove( self._playTimeSlider.bind('Slide End', self._onPlayTimeSlideEnd)) # Slider for 'Volume' self._volumeSlider = Slider(self) self._volumeSlider.bgColor = color.gray self._volumeSlider.vertical = True self._volumeSlider.rect = (400, 50, 10, 100) self._volumeSlider.thumbMinSize = 10 self._volumeSlider.thumbImage = r'Images\ScrollBarThumb.jpg' self.autoRemove(self._volumeSlider.bind('Slide', self._onVolumeSlide)) # Volume self._volumeText = Text(self) self._volumeText.autosize = True self._volumeText.text = 'Volume' self._volumeText.fontSize = 15 self._volumeText.xy = (380, 155) # Media Information text self._mediaInfoText = Text(self) self._mediaInfoText.autosize = True self._mediaInfoText.fontSize = 15 self._mediaInfoText.xy = (20, 45) self._mediaInfoText.text = 'FileName: \n' \ 'Duration: 0 min 0 sec\n' # Media Position text self._mediaPositionText = Text(self) self._mediaPositionText.autosize = True self._mediaPositionText.fontSize = 15 self._mediaPositionText.xy = (20, 80) self._mediaPositionText.text = 'Position: 0 min 0 sec\n' # Playlist text self._playlistText = Text(self) self._playlistText.autosize = True self._playlistText.text = 'Playlist' self._playlistText.fontSize = 15 self._playlistText.fontColor = color.blue self._playlistText.xy = (450, 30) # Restore the playlist from disk self.playList = {} self.workingDir = os.getcwd() # Locate the current working directory try: playListFile = open(self.workingDir + r'\PlayList.pickle', 'rb') except IOError: print '[AudioBoxWindow::__init__] No Playlist File Found' else: print '[AudioBoxWindow::__init__] Load Playlist File' self.playList = pickle.load( playListFile) # Dictionary storing the playlist playListFile.close() # Radio button group self._platListGroup = Group(self) self._platListGroup.xy = (450, 50) self._platListGroup.size = (200, 500) self._platListGroup.autosize = True # Display the playlist self.mediaButtonList = [] self._refreshPlayList() # Flag indicating if the playTime slider is sliding self.playTimeSliding = False self.displayAnim = None self.displayAnimRunning = False def _refreshPlayList(self): # Delete all the the buttons for eachMedia in self.mediaButtonList: eachMedia.close() self.mediaButtonList = [] # Reinsert the items from the playlist for key in self.playList.keys(): self._addMediaButton(key) self.nowPlaying = -1 # Index of the media which is playing now, -1 means no one is playing # Insert the media button into the platListGroup def _addMediaButton(self, fileName): i = len(self.mediaButtonList) self.mediaButtonList.append(RadioTextButton(self._platListGroup)) self.mediaButtonList[-1].autosize = True self.mediaButtonList[-1].text = fileName self.mediaButtonList[-1].rect = (0, i * 20, 300, 20) self.autoRemove(self.mediaButtonList[-1].bind('Click', self._playListOnClicked, i)) self.mediaButtonList[-1].bindData('bgColor', self.mediaButtonList[-1], 'checked', dir='<-', converter=lambda x: color.lightgray if x else color.white) self.autoRemove(self.mediaButtonList[-1].changeEvent( 'checked', self._onMediaChanged, fileName, i)) self.mediaButtonList[-1].checked = False # Callback function for button 'Start' and 'Pause' def _onTrigger(self): currentState = self.audioFunctions.GetCurrentState() if currentState == STOP_STATE: if self.nowPlaying != -1: self.audioFunctions.PlayMedia() self._triggerButton.text = 'Pause' # Timer for refreshing the media information self.displayAnim = koan.anim.IntervalExecute(1, self._onTimer) self.displayAnimRunning = True elif currentState == PAUSE_STATE: if self.nowPlaying != -1: self.audioFunctions.PlayMedia() self._triggerButton.text = 'Pause' # Timer for refreshing the media information self.displayAnim = koan.anim.IntervalExecute(1, self._onTimer) self.displayAnimRunning = True elif currentState == PLAY_STATE: self.audioFunctions.PauseMedia() self._triggerButton.text = 'Play' self.displayAnim.remove() self.displayAnimRunning = False # Callback function for button 'Stop' def _onStop(self): if self.displayAnimRunning: self.displayAnim.remove() self.audioFunctions.StopMedia() self._triggerButton.text = 'Play' self._playTimeSlider.setValue(0) # Callback function for volume slider def _onVolumeSlide(self, value): self.audioFunctions.SetVolume(value) # Callback functions for playtime slider def _onPlayTimeSlide(self, value): if self.playTimeSliding: self.media.totalSec = int( (self.media.durationMin * 60 + self.media.durationSec) * value) if self._playTimeSlider.isMouseDown and self.nowPlaying != -1: self.audioFunctions.SetMediaPosition(self._playTimeSlider.value) self._displayMediaPosition() def _onPlayTimeSlideEnd(self): self.playTimeSliding = False if self.nowPlaying != -1: self.audioFunctions.SetMediaPosition(self._playTimeSlider.value) def _onPlayTimeSlideStart(self): self.playTimeSliding = True # Callback function for refreshing the media info def _onTimer(self): if self.playTimeSliding == False: self._displayMediaPosition() try: self._playTimeSlider.setValue( float(self.media.totalSec) / float(self.media.durationMin * 60 + self.media.durationSec)) except ZeroDivisionError: self._playTimeSlider.setValue(0) # It's the end of the media if self.media.currentPositionMin == self.media.durationMin and self.media.currentPositionSec == self.media.durationSec: self._onStop() def _displayMediaPosition(self): if self.playTimeSliding == False: self.media.totalSec = self.audioFunctions.GetMediaPosition() self.media.currentPositionSec = self.media.totalSec % 60 self.media.currentPositionMin = self.media.totalSec / 60 self._mediaPositionText.text = 'Position: ' + str( self.media.currentPositionMin) + ' min ' + str( self.media.currentPositionSec) + ' sec\n' def _displayMediaInfo(self): self._mediaInfoText.text = 'FileName: ' + self.media.fileName + '\n' \ 'Duration: ' + str(self.media.durationMin) + ' min ' + str(self.media.durationSec) + ' sec\n' # Callback function for button 'OpenFile' def _onOpenFile(self): fileName = self.audioFunctions.OpenFileDialog( ) # Call the MFC open file dialog if fileName != None: self.media.fileName = fileName self.media.totalSec = self.audioFunctions.GetMediaDuration() tempTotalSec = self.media.totalSec if ( tempTotalSec == 0 ): # Sometimes we can't open the file due to unknown file name or wrong file format self.media.fileName = 'File Not Supported' self.nowPlaying = -1 # Insert the newly opened file into playlist if fileName not in self.playList.keys() and tempTotalSec != 0: self.playList[fileName] = self.audioFunctions.GetFilePath() self._addMediaButton(self.media.fileName) self.mediaButtonList[ -1].checked = True # this step would have the _onMediaChanged get called else: # If it's already existed for eachMedia in self.mediaButtonList: if eachMedia.text == fileName: self._triggerButton.text = 'Play' eachMedia.checked = True # this step would have the _onMediaChanged get called # Callback function when user changes the media in the list or opens a file def _onMediaChanged(self, key, which): if self.mediaButtonList[ which].checked == True and which != self.nowPlaying: self._onStop() self.nowPlaying = which self.media.fileName = key self.audioFunctions.OpenMedia(self.playList[key]) self.audioFunctions.SetVolume(self._volumeSlider.getValue()) self.media.totalSec = self.audioFunctions.GetMediaDuration() tempTotalSec = self.media.totalSec self.media.durationMin = tempTotalSec / 60 self.media.durationSec = tempTotalSec % 60 self._triggerButton.text = 'Play' self._displayMediaInfo() # Callback function when user changes the media in the list, this function would have the _onMediaChanged get called def _playListOnClicked(self, i): self.mediaButtonList[i].checked = True # Callback function when user removes an item from the list def _onRemove(self): for eachMedia in self.mediaButtonList: # Search the one which is removed if eachMedia.checked: del self.playList[ eachMedia.text] # Remove it from the dictionary self.media.durationMin = 0 self.media.durationSec = 0 self.media.fileName = '' self._onStop() self.nowPlaying = -1 self._displayMediaInfo() self._refreshPlayList() def close(self): self.audioFunctions.FreeDirectShow() # Save the playlist to disk try: playListFile = open(self.workingDir + r'\PlayList.pickle', 'wb') except IOError: print '[AudioBoxWindow::close] Cannot write the playlist file' else: print '[AudioBoxWindow::close] Write playlist file' pickle.dump(self.playList, playListFile) playListFile.close() print '[AudioBoxWindow::close] Window closed' super(AudioBoxWindow, self).close() def onDraw(self, render): render.Clear(255, 255, 255, 255)
class HanoiWindow(Window): def __init__(self): Window.__init__(self) self.create(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT, caption = True) self._plate_images = [] # Button for 'Start' and 'Pause' self._trigger_button = TextButton(self) self._trigger_button.rect = 0, 0, 50, 30 self._trigger_button.text = 'Start' self._trigger_button.background = r'Images\Root_button.png' self.autoRemove(self._trigger_button.bind('Click', self._on_trigger_button_click)) # Button for 'Restart' self._restart_button = TextButton(self) self._restart_button.rect = 60, 0, 50, 30 self._restart_button.text = 'Restart' self._restart_button.background = r'Images\Root_button.png' self.autoRemove(self._restart_button.bind('Click', self._on_restart_button_click)) # Button for 'Next' self._next_button = TextButton(self) self._next_button.rect = 120, 0, 50, 30 self._next_button.text = 'Next' self._next_button.background = r'Images\Root_button.png' self.autoRemove(self._next_button.bind('Click', self._on_next_button_click)) self._init_hanoi() def _init_hanoi(self): # Variables for the animation self._next_move = True self._move = 0 self._starting_left = 0 self._starting_top = 0 self._target_left = 0 self._target_top = 0 self._acceleration = 0 self._time_spent = 0 # Flags indicating the state of the program self._running_flag = False self._step_by_step_flag = False self._over_flag = False # Reset the trigger_button to 'Start' self._trigger_button.text = 'Start' # Hanoi algorithm object self._hanoi = Hanoi(input('Please enter the number of plates\n')) # Initialization of the plate images for each_plate in self._hanoi.get_plates(0): plate_image = TextButton(self) plate_image.rect = (70 + self._hanoi.get_total() * PLATE_BASE_WIDTH / 2) - each_plate.number * PLATE_BASE_WIDTH / 2, \ (WINDOW_HEIGHT - self._hanoi.get_total() * PLATE_HEIGHT) + each_plate.number * PLATE_HEIGHT, \ PLATE_BASE_WIDTH * (each_plate.number + 1), \ PLATE_HEIGHT plate_image.background = r'Images\Root_button.png' self._plate_images.insert(0, plate_image) # Start running the hanoi algorithm and animation self._steps = self._hanoi.move(self._hanoi.get_total(), 0, 2) self._animation = koan.anim.IntervalExecute(TIME_INTERVAL, self._onTimer) def _on_trigger_button_click(self): if self._over_flag: return if self._trigger_button.text == 'Start': self._running_flag = True self._trigger_button.text = 'Pause' else: self._running_flag = False self._trigger_button.text = 'Start' def _on_restart_button_click(self): if self._running_flag: return # Remove the registered animation and images self._animation.remove() for each_plate_image in self._plate_images: each_plate_image.close() # Re-initialization of the program self._init_hanoi() def _on_next_button_click(self): if not self._running_flag: self._step_by_step_flag = True def _onTimer(self): # No update of the animation when it's in step by step state if not self._running_flag and not self._step_by_step_flag: return try: if self._next_move: self._next_move = False # Generating the next move self._move = self._steps.next() # Calculating the __starting point and __target point of the animation self._time_spent = 0 self._starting_left = self._plate_images[self._move.number].left self._starting_top = self._plate_images[self._move.number].top self._target_left = (70 + self._hanoi.get_total() * PLATE_BASE_WIDTH / 2) + self._move.to_location * (WINDOW_WIDTH / 3) - self._move.number * (PLATE_BASE_WIDTH / 2) self._target_top = WINDOW_HEIGHT - self._hanoi.get_total_in_location(self._move.to_location) * PLATE_HEIGHT # Calculating the total time and __acceleration needed from start to the __target total_time = abs((self._target_left - self._starting_left) / HORIZONTAL_SPEED) self._acceleration = 2 * (self._target_top - self._starting_top - VERTICAL_SPEED * total_time) / (total_time ** 2) # Indicating there's no move left except StopIteration: print '[HanoiWindow::_onTimer] Over!!!' self._running_flag = False self._over_flag = True return # The plate's moved to the __target point if self._plate_images[self._move.number].left == self._target_left: self._plate_images[self._move.number].top = self._target_top self._next_move = True if self._step_by_step_flag: self._step_by_step_flag = False return # Update the new location of the plate if self._target_left > self._plate_images[self._move.number].left: self._plate_images[self._move.number].left += HORIZONTAL_SPEED elif self._target_left < self._plate_images[self._move.number].left: self._plate_images[self._move.number].left -= HORIZONTAL_SPEED self._time_spent += 1 self._plate_images[self._move.number].top = self._starting_top + VERTICAL_SPEED * self._time_spent + self._acceleration * (self._time_spent ** 2) / 2 def close(self): # Remove the registered animation self._animation.remove() super(HanoiWindow, self).close() def onDraw(self, render): render.Clear(255, 0, 0, 0)
def __init__(self): Window.__init__(self) # Initialization of the C++ DirectShow Library self.audioFunctions = AudioFunctions() self.audioFunctions.InitDirectShow() # Media Information self.media = Media() # The main window self.create(100, 100, 700, 300, caption=True, resize=False) # Button for 'OpenFile' self._openFileButton = TextButton(self) self._openFileButton.rect = (0, 0, 50, 30) self._openFileButton.text = 'OpenFile' self._openFileButton.background = r'Images\Root_button.png' self.autoRemove(self._openFileButton.bind('Click', self._onOpenFile)) # Button for 'Play' and 'Pause' self._triggerButton = TextButton(self) self._triggerButton.rect = (60, 0, 50, 30) self._triggerButton.text = 'Play' self._triggerButton.background = r'Images\Root_button.png' self.autoRemove(self._triggerButton.bind('Click', self._onTrigger)) # Button for 'Stop' self._stopButton = TextButton(self) self._stopButton.rect = (120, 0, 50, 30) self._stopButton.text = 'Stop' self._stopButton.background = r'Images\Root_button.png' self.autoRemove(self._stopButton.bind('Click', self._onStop)) # Button for 'Remove' self._stopButton = TextButton(self) self._stopButton.rect = (450, 0, 50, 30) self._stopButton.text = 'Remove' self._stopButton.background = r'Images\Root_button.png' self.autoRemove(self._stopButton.bind('Click', self._onRemove)) # PlayTime self._playTimeText = Text(self) self._playTimeText.autosize = True self._playTimeText.text = 'PlayTime' self._playTimeText.fontSize = 15 self._playTimeText.xy = (30, 155) # Slider for 'playTime' self._playTimeSlider = Slider(self) self._playTimeSlider.bgColor = color.gray self._playTimeSlider.vertical = False self._playTimeSlider.rect = (100, 160, 255, 10) self._playTimeSlider.thumbMinSize = 10 self._playTimeSlider.thumbImage = r'Images\ScrollBarThumb.jpg' self.autoRemove(self._playTimeSlider.bind('Slide', self._onPlayTimeSlide)) self.autoRemove(self._playTimeSlider.bind('Slide Start', self._onPlayTimeSlideStart)) self.autoRemove(self._playTimeSlider.bind('Slide End', self._onPlayTimeSlideEnd)) # Slider for 'Volume' self._volumeSlider = Slider(self) self._volumeSlider.bgColor = color.gray self._volumeSlider.vertical = True self._volumeSlider.rect = (400, 50, 10, 100) self._volumeSlider.thumbMinSize = 10 self._volumeSlider.thumbImage = r'Images\ScrollBarThumb.jpg' self.autoRemove(self._volumeSlider.bind('Slide', self._onVolumeSlide)) # Volume self._volumeText = Text(self) self._volumeText.autosize = True self._volumeText.text = 'Volume' self._volumeText.fontSize = 15 self._volumeText.xy = (380, 155) # Media Information text self._mediaInfoText = Text(self) self._mediaInfoText.autosize = True self._mediaInfoText.fontSize = 15 self._mediaInfoText.xy = (20, 45) self._mediaInfoText.text = 'FileName: \n' \ 'Duration: 0 min 0 sec\n' # Media Position text self._mediaPositionText = Text(self) self._mediaPositionText.autosize = True self._mediaPositionText.fontSize = 15 self._mediaPositionText.xy = (20, 80) self._mediaPositionText.text = 'Position: 0 min 0 sec\n' # Playlist text self._playlistText = Text(self) self._playlistText.autosize = True self._playlistText.text = 'Playlist' self._playlistText.fontSize = 15 self._playlistText.fontColor = color.blue self._playlistText.xy = (450, 30) # Restore the playlist from disk self.playList = {} self.workingDir = os.getcwd() # Locate the current working directory try: playListFile = open(self.workingDir + r'\PlayList.pickle', 'rb') except IOError: print '[AudioBoxWindow::__init__] No Playlist File Found' else: print '[AudioBoxWindow::__init__] Load Playlist File' self.playList = pickle.load(playListFile) # Dictionary storing the playlist playListFile.close() # Radio button group self._platListGroup = Group(self) self._platListGroup.xy = (450, 50) self._platListGroup.size = (200, 500) self._platListGroup.autosize = True # Display the playlist self.mediaButtonList = [] self._refreshPlayList() # Flag indicating if the playTime slider is sliding self.playTimeSliding = False self.displayAnim = None self.displayAnimRunning = False
class AudioBoxWindow(Window): def __init__(self): Window.__init__(self) # Initialization of the C++ DirectShow Library self.audioFunctions = AudioFunctions() self.audioFunctions.InitDirectShow() # Media Information self.media = Media() # The main window self.create(100, 100, 700, 300, caption=True, resize=False) # Button for 'OpenFile' self._openFileButton = TextButton(self) self._openFileButton.rect = (0, 0, 50, 30) self._openFileButton.text = 'OpenFile' self._openFileButton.background = r'Images\Root_button.png' self.autoRemove(self._openFileButton.bind('Click', self._onOpenFile)) # Button for 'Play' and 'Pause' self._triggerButton = TextButton(self) self._triggerButton.rect = (60, 0, 50, 30) self._triggerButton.text = 'Play' self._triggerButton.background = r'Images\Root_button.png' self.autoRemove(self._triggerButton.bind('Click', self._onTrigger)) # Button for 'Stop' self._stopButton = TextButton(self) self._stopButton.rect = (120, 0, 50, 30) self._stopButton.text = 'Stop' self._stopButton.background = r'Images\Root_button.png' self.autoRemove(self._stopButton.bind('Click', self._onStop)) # Button for 'Remove' self._stopButton = TextButton(self) self._stopButton.rect = (450, 0, 50, 30) self._stopButton.text = 'Remove' self._stopButton.background = r'Images\Root_button.png' self.autoRemove(self._stopButton.bind('Click', self._onRemove)) # PlayTime self._playTimeText = Text(self) self._playTimeText.autosize = True self._playTimeText.text = 'PlayTime' self._playTimeText.fontSize = 15 self._playTimeText.xy = (30, 155) # Slider for 'playTime' self._playTimeSlider = Slider(self) self._playTimeSlider.bgColor = color.gray self._playTimeSlider.vertical = False self._playTimeSlider.rect = (100, 160, 255, 10) self._playTimeSlider.thumbMinSize = 10 self._playTimeSlider.thumbImage = r'Images\ScrollBarThumb.jpg' self.autoRemove(self._playTimeSlider.bind('Slide', self._onPlayTimeSlide)) self.autoRemove(self._playTimeSlider.bind('Slide Start', self._onPlayTimeSlideStart)) self.autoRemove(self._playTimeSlider.bind('Slide End', self._onPlayTimeSlideEnd)) # Slider for 'Volume' self._volumeSlider = Slider(self) self._volumeSlider.bgColor = color.gray self._volumeSlider.vertical = True self._volumeSlider.rect = (400, 50, 10, 100) self._volumeSlider.thumbMinSize = 10 self._volumeSlider.thumbImage = r'Images\ScrollBarThumb.jpg' self.autoRemove(self._volumeSlider.bind('Slide', self._onVolumeSlide)) # Volume self._volumeText = Text(self) self._volumeText.autosize = True self._volumeText.text = 'Volume' self._volumeText.fontSize = 15 self._volumeText.xy = (380, 155) # Media Information text self._mediaInfoText = Text(self) self._mediaInfoText.autosize = True self._mediaInfoText.fontSize = 15 self._mediaInfoText.xy = (20, 45) self._mediaInfoText.text = 'FileName: \n' \ 'Duration: 0 min 0 sec\n' # Media Position text self._mediaPositionText = Text(self) self._mediaPositionText.autosize = True self._mediaPositionText.fontSize = 15 self._mediaPositionText.xy = (20, 80) self._mediaPositionText.text = 'Position: 0 min 0 sec\n' # Playlist text self._playlistText = Text(self) self._playlistText.autosize = True self._playlistText.text = 'Playlist' self._playlistText.fontSize = 15 self._playlistText.fontColor = color.blue self._playlistText.xy = (450, 30) # Restore the playlist from disk self.playList = {} self.workingDir = os.getcwd() # Locate the current working directory try: playListFile = open(self.workingDir + r'\PlayList.pickle', 'rb') except IOError: print '[AudioBoxWindow::__init__] No Playlist File Found' else: print '[AudioBoxWindow::__init__] Load Playlist File' self.playList = pickle.load(playListFile) # Dictionary storing the playlist playListFile.close() # Radio button group self._platListGroup = Group(self) self._platListGroup.xy = (450, 50) self._platListGroup.size = (200, 500) self._platListGroup.autosize = True # Display the playlist self.mediaButtonList = [] self._refreshPlayList() # Flag indicating if the playTime slider is sliding self.playTimeSliding = False self.displayAnim = None self.displayAnimRunning = False def _refreshPlayList(self): # Delete all the the buttons for eachMedia in self.mediaButtonList: eachMedia.close() self.mediaButtonList = [] # Reinsert the items from the playlist for key in self.playList.keys(): self._addMediaButton(key) self.nowPlaying = -1 # Index of the media which is playing now, -1 means no one is playing # Insert the media button into the platListGroup def _addMediaButton(self, fileName): i = len(self.mediaButtonList) self.mediaButtonList.append(RadioTextButton(self._platListGroup)) self.mediaButtonList[-1].autosize = True self.mediaButtonList[-1].text = fileName self.mediaButtonList[-1].rect = (0, i * 20, 300, 20) self.autoRemove(self.mediaButtonList[-1].bind('Click', self._playListOnClicked, i)) self.mediaButtonList[-1].bindData('bgColor', self.mediaButtonList[-1], 'checked', dir='<-', converter=lambda x: color.lightgray if x else color.white) self.autoRemove(self.mediaButtonList[-1].changeEvent('checked', self._onMediaChanged, fileName, i)) self.mediaButtonList[-1].checked = False # Callback function for button 'Start' and 'Pause' def _onTrigger(self): currentState = self.audioFunctions.GetCurrentState() if currentState == STOP_STATE: if self.nowPlaying != -1: self.audioFunctions.PlayMedia() self._triggerButton.text = 'Pause' # Timer for refreshing the media information self.displayAnim = koan.anim.IntervalExecute(1, self._onTimer) self.displayAnimRunning = True elif currentState == PAUSE_STATE: if self.nowPlaying != -1: self.audioFunctions.PlayMedia() self._triggerButton.text = 'Pause' # Timer for refreshing the media information self.displayAnim = koan.anim.IntervalExecute(1, self._onTimer) self.displayAnimRunning = True elif currentState == PLAY_STATE: self.audioFunctions.PauseMedia() self._triggerButton.text = 'Play' self.displayAnim.remove() self.displayAnimRunning = False # Callback function for button 'Stop' def _onStop(self): if self.displayAnimRunning: self.displayAnim.remove() self.audioFunctions.StopMedia() self._triggerButton.text = 'Play' self._playTimeSlider.setValue(0) # Callback function for volume slider def _onVolumeSlide(self, value): self.audioFunctions.SetVolume(value) # Callback functions for playtime slider def _onPlayTimeSlide(self, value): if self.playTimeSliding: self.media.totalSec = int((self.media.durationMin * 60 + self.media.durationSec) * value) if self._playTimeSlider.isMouseDown and self.nowPlaying != -1: self.audioFunctions.SetMediaPosition(self._playTimeSlider.value) self._displayMediaPosition() def _onPlayTimeSlideEnd(self): self.playTimeSliding = False if self.nowPlaying != -1: self.audioFunctions.SetMediaPosition(self._playTimeSlider.value) def _onPlayTimeSlideStart(self): self.playTimeSliding = True # Callback function for refreshing the media info def _onTimer(self): if self.playTimeSliding == False: self._displayMediaPosition() try: self._playTimeSlider.setValue(float(self.media.totalSec) / float(self.media.durationMin * 60 + self.media.durationSec)) except ZeroDivisionError: self._playTimeSlider.setValue(0) # It's the end of the media if self.media.currentPositionMin == self.media.durationMin and self.media.currentPositionSec == self.media.durationSec: self._onStop() def _displayMediaPosition(self): if self.playTimeSliding == False: self.media.totalSec = self.audioFunctions.GetMediaPosition() self.media.currentPositionSec = self.media.totalSec % 60 self.media.currentPositionMin = self.media.totalSec / 60 self._mediaPositionText.text = 'Position: ' + str(self.media.currentPositionMin) + ' min ' + str(self.media.currentPositionSec) + ' sec\n' def _displayMediaInfo(self): self._mediaInfoText.text = 'FileName: ' + self.media.fileName + '\n' \ 'Duration: ' + str(self.media.durationMin) + ' min ' + str(self.media.durationSec) + ' sec\n' # Callback function for button 'OpenFile' def _onOpenFile(self): fileName = self.audioFunctions.OpenFileDialog() # Call the MFC open file dialog if fileName != None: self.media.fileName = fileName self.media.totalSec = self.audioFunctions.GetMediaDuration() tempTotalSec = self.media.totalSec if (tempTotalSec == 0): # Sometimes we can't open the file due to unknown file name or wrong file format self.media.fileName = 'File Not Supported' self.nowPlaying = -1 # Insert the newly opened file into playlist if fileName not in self.playList.keys() and tempTotalSec != 0: self.playList[fileName] = self.audioFunctions.GetFilePath() self._addMediaButton(self.media.fileName) self.mediaButtonList[-1].checked = True # this step would have the _onMediaChanged get called else: # If it's already existed for eachMedia in self.mediaButtonList: if eachMedia.text == fileName: self._triggerButton.text = 'Play' eachMedia.checked = True # this step would have the _onMediaChanged get called # Callback function when user changes the media in the list or opens a file def _onMediaChanged(self, key, which): if self.mediaButtonList[which].checked == True and which != self.nowPlaying: self._onStop() self.nowPlaying = which self.media.fileName = key self.audioFunctions.OpenMedia(self.playList[key]) self.audioFunctions.SetVolume(self._volumeSlider.getValue()) self.media.totalSec = self.audioFunctions.GetMediaDuration() tempTotalSec = self.media.totalSec self.media.durationMin = tempTotalSec / 60 self.media.durationSec = tempTotalSec % 60 self._triggerButton.text = 'Play' self._displayMediaInfo() # Callback function when user changes the media in the list, this function would have the _onMediaChanged get called def _playListOnClicked(self, i): self.mediaButtonList[i].checked = True # Callback function when user removes an item from the list def _onRemove(self): for eachMedia in self.mediaButtonList: # Search the one which is removed if eachMedia.checked: del self.playList[eachMedia.text] # Remove it from the dictionary self.media.durationMin = 0 self.media.durationSec = 0 self.media.fileName = '' self._onStop() self.nowPlaying = -1 self._displayMediaInfo() self._refreshPlayList() def close(self): self.audioFunctions.FreeDirectShow() # Save the playlist to disk try: playListFile = open(self.workingDir + r'\PlayList.pickle', 'wb') except IOError: print '[AudioBoxWindow::close] Cannot write the playlist file' else: print '[AudioBoxWindow::close] Write playlist file' pickle.dump(self.playList, playListFile) playListFile.close() print '[AudioBoxWindow::close] Window closed' super(AudioBoxWindow, self).close() def onDraw(self, render): render.Clear(255, 255, 255, 255)
class HanoiWindow(Window): def __init__(self): Window.__init__(self) self.create(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT, caption=True) self._plate_images = [] # Button for 'Start' and 'Pause' self._trigger_button = TextButton(self) self._trigger_button.rect = 0, 0, 50, 30 self._trigger_button.text = 'Start' self._trigger_button.background = r'Images\Root_button.png' self.autoRemove( self._trigger_button.bind('Click', self._on_trigger_button_click)) # Button for 'Restart' self._restart_button = TextButton(self) self._restart_button.rect = 60, 0, 50, 30 self._restart_button.text = 'Restart' self._restart_button.background = r'Images\Root_button.png' self.autoRemove( self._restart_button.bind('Click', self._on_restart_button_click)) # Button for 'Next' self._next_button = TextButton(self) self._next_button.rect = 120, 0, 50, 30 self._next_button.text = 'Next' self._next_button.background = r'Images\Root_button.png' self.autoRemove( self._next_button.bind('Click', self._on_next_button_click)) self._init_hanoi() def _init_hanoi(self): # Variables for the animation self._next_move = True self._move = 0 self._starting_left = 0 self._starting_top = 0 self._target_left = 0 self._target_top = 0 self._acceleration = 0 self._time_spent = 0 # Flags indicating the state of the program self._running_flag = False self._step_by_step_flag = False self._over_flag = False # Reset the trigger_button to 'Start' self._trigger_button.text = 'Start' # Hanoi algorithm object self._hanoi = Hanoi(input('Please enter the number of plates\n')) # Initialization of the plate images for each_plate in self._hanoi.get_plates(0): plate_image = TextButton(self) plate_image.rect = (70 + self._hanoi.get_total() * PLATE_BASE_WIDTH / 2) - each_plate.number * PLATE_BASE_WIDTH / 2, \ (WINDOW_HEIGHT - self._hanoi.get_total() * PLATE_HEIGHT) + each_plate.number * PLATE_HEIGHT, \ PLATE_BASE_WIDTH * (each_plate.number + 1), \ PLATE_HEIGHT plate_image.background = r'Images\Root_button.png' self._plate_images.insert(0, plate_image) # Start running the hanoi algorithm and animation self._steps = self._hanoi.move(self._hanoi.get_total(), 0, 2) self._animation = koan.anim.IntervalExecute(TIME_INTERVAL, self._onTimer) def _on_trigger_button_click(self): if self._over_flag: return if self._trigger_button.text == 'Start': self._running_flag = True self._trigger_button.text = 'Pause' else: self._running_flag = False self._trigger_button.text = 'Start' def _on_restart_button_click(self): if self._running_flag: return # Remove the registered animation and images self._animation.remove() for each_plate_image in self._plate_images: each_plate_image.close() # Re-initialization of the program self._init_hanoi() def _on_next_button_click(self): if not self._running_flag: self._step_by_step_flag = True def _onTimer(self): # No update of the animation when it's in step by step state if not self._running_flag and not self._step_by_step_flag: return try: if self._next_move: self._next_move = False # Generating the next move self._move = self._steps.next() # Calculating the __starting point and __target point of the animation self._time_spent = 0 self._starting_left = self._plate_images[ self._move.number].left self._starting_top = self._plate_images[self._move.number].top self._target_left = ( 70 + self._hanoi.get_total() * PLATE_BASE_WIDTH / 2) + self._move.to_location * (WINDOW_WIDTH / 3) - self._move.number * ( PLATE_BASE_WIDTH / 2) self._target_top = WINDOW_HEIGHT - self._hanoi.get_total_in_location( self._move.to_location) * PLATE_HEIGHT # Calculating the total time and __acceleration needed from start to the __target total_time = abs((self._target_left - self._starting_left) / HORIZONTAL_SPEED) self._acceleration = 2 * ( self._target_top - self._starting_top - VERTICAL_SPEED * total_time) / (total_time**2) # Indicating there's no move left except StopIteration: print '[HanoiWindow::_onTimer] Over!!!' self._running_flag = False self._over_flag = True return # The plate's moved to the __target point if self._plate_images[self._move.number].left == self._target_left: self._plate_images[self._move.number].top = self._target_top self._next_move = True if self._step_by_step_flag: self._step_by_step_flag = False return # Update the new location of the plate if self._target_left > self._plate_images[self._move.number].left: self._plate_images[self._move.number].left += HORIZONTAL_SPEED elif self._target_left < self._plate_images[self._move.number].left: self._plate_images[self._move.number].left -= HORIZONTAL_SPEED self._time_spent += 1 self._plate_images[ self._move. number].top = self._starting_top + VERTICAL_SPEED * self._time_spent + self._acceleration * ( self._time_spent**2) / 2 def close(self): # Remove the registered animation self._animation.remove() super(HanoiWindow, self).close() def onDraw(self, render): render.Clear(255, 0, 0, 0)