class Editor(QWidget): def __init__(self, song): super().__init__() self.initUI(song) def initUI(self, song): self.songLenInBeats = 100 self.songBeatsPBar = 4 self.reverse = 1 self.pixPSec = 1000.0 self.disp8 = True self.disp12 = False self.disp16 = True self.disp24 = False self.disp32 = False self.disp48 = False self.disp64 = False self.spectrogramDisplay = True self.cursorExists = False self.framecount = 0 self.timeOutLength = 17 self.timer = QTimer() self.editorTheme = self.getTheme() self.boxw = self.editorTheme['BoxWidth'] self.topLayout = QVBoxLayout() self.topLayout.setContentsMargins(0, 0, 0, 0) self.song = song self.song.pos = 0 self.setLayout(self.topLayout) self.gs = QGraphicsScene() self.gv = QGraphicsView(self.gs) self.drawBG() self.song = song # self.drawArrowDemo() self.boxes = [] self.topLayout.addWidget(self.gv) def update(self, song, level): self.gs.clear() print(self.song.pos) self.song = song self.cursorExists = False self.song.pos = 0 self.play(0) self.pause() self.updatescreen() if self.spectrogramDisplay: self.spectrogramPixMap = QPixmap(spectrogram_dir + song.audioFile + '.png') width = self.spectrogramPixMap.width() height = self.spectrogramPixMap.height() self.spectrogramPixMap = self.gs.addPixmap(self.spectrogramPixMap) self.spectrogramPixMap.setRotation(90) self.spectrogramPixMap.setTransform(QTransform().scale( -1, (self.song.lengthInSeconds * self.pixPSec) / width)) self.drawGrid(self.song.levels[level]) self.drawArrowDemo(self.song.levels[level]) #self.play(0) def levelSelected(self, level): print("Selected ", level) if level in self.song.levels: print('switching') self.update(self.song, level) else: print('creating new level') def play(self, pos): self.timer.timeout.connect(self.updatescreen) self.timer.start(self.timeOutLength) self.song.playSong(pos) def pause(self): self.timer.stop() self.song.pauseSong() def keyPressEvent(self, event): key = event.key() shiftPressed = event.modifiers() == Qt.ShiftModifier ctrlPressed = event.modifiers() == Qt.ControlModifier altPressed = event.modifiers() == Qt.AltModifier restart = self.song.isPlaying if key == Qt.Key_Space: if self.song.isPlaying: self.pause() else: self.play(self.song.pos / 1000) elif key == Qt.Key_BracketRight: restart = self.song.isPlaying self.pause() if ctrlPressed: self.song.pos += 10000 elif shiftPressed: self.song.pos += 1000 elif altPressed: self.song.pos += 10 else: self.song.pos += 100 if not (self.song.pos > self.song.lengthInSeconds * 1000): if restart: self.play(self.song.pos / 1000) else: self.play(self.song.pos / 1000) self.pause() else: self.song.pos = self.song.lengthInSeconds * 1000 - 1 self.play(self.song.pos / 1000) self.pause() self.updatescreen() elif key == Qt.Key_BracketLeft: self.pause() if ctrlPressed: self.song.pos -= 10000 elif shiftPressed: self.song.pos -= 1000 elif altPressed: self.song.pos -= 10 else: self.song.pos -= 100 if self.song.pos < 0: self.song.pos = 0 if restart: self.play(self.song.pos / 1000) else: self.play(self.song.pos / 1000) self.pause() self.updatescreen() elif key == Qt.Key_BraceRight: restart = self.song.isPlaying self.pause() if ctrlPressed: self.song.pos += 10000 elif shiftPressed: self.song.pos += 1000 elif altPressed: self.song.pos += 10 else: self.song.pos += 200 if not (self.song.pos > self.song.lengthInSeconds * 1000): if restart: self.play(self.song.pos / 1000) else: self.play(self.song.pos / 1000) self.pause() else: self.song.pos = self.song.lengthInSeconds * 1000 - 1 self.play(self.song.pos / 1000) self.pause() self.updatescreen() elif key == Qt.Key_BraceLeft: self.pause() if ctrlPressed: self.song.pos -= 10000 elif shiftPressed: self.song.pos -= 1000 elif altPressed: self.song.pos += 10 else: self.song.pos -= 200 if self.song.pos < 0: self.song.pos = 0 if restart: self.play(self.song.pos / 1000) else: self.play(self.song.pos / 1000) self.pause() self.updatescreen() def updatescreen(self): self.song.updatePos() if self.song.isPlaying: self.framecount += 1 curTime = time.time() if (curTime - self.song.time > 1): print('FPS: ', self.framecount) self.framecount = 0 self.song.time = curTime if self.cursorExists: self.gs.removeItem(self.cursorLine) ypos = (self.song.pos / 1000.0 * self.pixPSec) self.gv.centerOn(0, ypos) self.cursorLine = self.gs.addLine(0, ypos, 1000, ypos, self.editorTheme['GridMeasure']) self.cursorExists = True self.cursor = True if self.song.pos < 0: self.song.pos = 0 self.gv.centerOn(0, 0) self.pause() def drawArrowDemo(self, level): boxRotation = [180, 0, 90, 270, 225, 135, 315, 45, 0] for beatBox in level.notes: if beatBox.type == 0: if beatBox.cutDirection == 8: notePixmap = QPixmap(graphics_dir + 'redcircle.png') else: notePixmap = QPixmap(graphics_dir + 'redarrow.png') elif beatBox.type == 1: if beatBox.cutDirection == 8: notePixmap = QPixmap(graphics_dir + 'bluecircle.png') else: notePixmap = QPixmap(graphics_dir + 'bluearrow.png') else: notePixmap = QPixmap(graphics_dir + 'mine.png') notePixmap = notePixmap.scaled(40, 40) noteBox = NoteBox() noteBox.setPixmap(notePixmap) noteBox.setBox(beatBox) box = self.gs.addItem(noteBox) print(type(noteBox)) noteBox.setTransformOriginPoint(20, 20) noteBox.setRotation(boxRotation[beatBox.cutDirection]) boxy = (level.beatToSec(beatBox.time) * self.pixPSec - (self.reverse * 20)) * self.reverse boxx = 40 * beatBox.lineIndex + 170 * beatBox.lineLayer noteBox.setPos(boxx, boxy) self.boxes.append(noteBox) def drawBG(self): self.gs.setBackgroundBrush(self.editorTheme['BG']) def drawGrid(self, level): #DEBUG need to through a clear grid in here self.drawGridConstantTime(level) def drawGridConstantBeat(self): pass def drawGridConstantTime(self, level): # DONT FORGET TO ADD REVERSE SCROLL # self.disp192 = True self.noteLayer1 = self.gs.createItemGroup([]) self.noteLayer2 = self.gs.createItemGroup([]) self.noteLayer3 = self.gs.createItemGroup([]) self.obstacleLayer = self.gs.createItemGroup([]) self.eventLayer = self.gs.createItemGroup([]) width = self.editorTheme['BoxWidth'] * 4 spacing = self.editorTheme['LaneSpacing'] self.noteLayer1Values = LayerValue(0, 0, width) self.noteLayer2Values = LayerValue((width + spacing), 0, width) self.noteLayer3Values = LayerValue((width + spacing) * 2, 0, width) self.obstacleLayerValues = LayerValue((width + spacing) * 3, 0, width) self.eventLayerValues = LayerValue((width + spacing) * 4, 0, width) self.drawGridLaneConstantTime(self.noteLayer1, self.noteLayer1Values, level) self.drawGridLaneConstantTime(self.noteLayer2, self.noteLayer2Values, level) self.drawGridLaneConstantTime(self.noteLayer3, self.noteLayer3Values, level) self.drawGridLaneConstantTime(self.obstacleLayer, self.obstacleLayerValues, level) self.drawGridLaneConstantTime(self.eventLayer, self.eventLayerValues, level) def drawGridLaneConstantTime(self, lane, values, level): #debug songlen not a int need to address leftover time for beat in range(int(self.song.lengthInBeats)): if beat % self.song.beatsPerBar == 0: lane.addToGroup( self.gs.addLine( values.x + self.editorTheme['GridLineWidth'], self.reverse * (self.song.offset + level.beatToSec(beat)) * self.pixPSec, values.x + values.w - self.editorTheme['GridLineWidth'] * 2, self.reverse * (self.song.offset + level.beatToSec(beat)) * self.pixPSec, self.editorTheme['GridMeasure'])) else: lane.addToGroup( self.gs.addLine( values.x + self.editorTheme['GridLineWidth'], self.reverse * (self.song.offset + level.beatToSec(beat)) * self.pixPSec, values.x + values.w - self.editorTheme['GridLineWidth'] * 2, self.reverse * (self.song.offset + level.beatToSec(beat)) * self.pixPSec, self.editorTheme['Grid4'])) if self.disp8: lane.addToGroup( self.gs.addLine( values.x + self.editorTheme['GridLineWidth'], self.reverse * (self.song.offset + level.beatToSec(beat + .5)) * self.pixPSec, values.x + values.w - self.editorTheme['GridLineWidth'] * 2, self.reverse * (self.song.offset + level.beatToSec(beat + .5)) * self.pixPSec, self.editorTheme['Grid8'])) if self.disp16: lane.addToGroup( self.gs.addLine( values.x + self.editorTheme['GridLineWidth'], self.reverse * (self.song.offset + level.beatToSec(beat + .25)) * self.pixPSec, values.x + values.w - self.editorTheme['GridLineWidth'] * 2, self.reverse * (self.song.offset + level.beatToSec(beat + .25)) * self.pixPSec, self.editorTheme['Grid16'])) lane.addToGroup( self.gs.addLine( values.x + self.editorTheme['GridLineWidth'], self.reverse * (self.song.offset + level.beatToSec(beat + .75)) * self.pixPSec, values.x + values.w - self.editorTheme['GridLineWidth'] * 2, self.reverse * (self.song.offset + level.beatToSec(beat + .75)) * self.pixPSec, self.editorTheme['Grid16'])) if self.disp32: lane.addToGroup( self.gs.addLine( values.x + self.editorTheme['GridLineWidth'], self.reverse * (self.song.offset + level.beatToSec(beat + .125)) * self.pixPSec, values.x + values.w - self.editorTheme['GridLineWidth'] * 2, self.reverse * (self.song.offset + level.beatToSec(beat + .125)) * self.pixPSec, self.editorTheme['Grid32'])) lane.addToGroup( self.gs.addLine( values.x + self.editorTheme['GridLineWidth'], self.reverse * (self.song.offset + level.beatToSec(beat + .375)) * self.pixPSec, values.x + values.w - self.editorTheme['GridLineWidth'] * 2, self.reverse * (self.song.offset + level.beatToSec(beat + .375)) * self.pixPSec, self.editorTheme['Grid32'])) lane.addToGroup( self.gs.addLine( values.x + self.editorTheme['GridLineWidth'], self.reverse * (self.song.offset + level.beatToSec(beat + .625)) * self.pixPSec, values.x + values.w - self.editorTheme['GridLineWidth'] * 2, self.reverse * (self.song.offset + level.beatToSec(beat + .625)) * self.pixPSec, self.editorTheme['Grid32'])) lane.addToGroup( self.gs.addLine( values.x + self.editorTheme['GridLineWidth'], self.reverse * (self.song.offset + level.beatToSec(beat + .875)) * self.pixPSec, values.x + values.w - self.editorTheme['GridLineWidth'] * 2, self.reverse * (self.song.offset + level.beatToSec(beat + .875)) * self.pixPSec, self.editorTheme['Grid32'])) if self.disp64: lane.addToGroup( self.gs.addLine( values.x + self.editorTheme['GridLineWidth'], self.reverse * (self.song.offset + level.beatToSec(beat + .0625)) * self.pixPSec, values.x + values.w - self.editorTheme['GridLineWidth'] * 2, self.reverse * (self.song.offset + level.beatToSec(beat + .0625)) * self.pixPSec, self.editorTheme['Grid64'])) lane.addToGroup( self.gs.addLine( values.x + self.editorTheme['GridLineWidth'], self.reverse * (self.song.offset + level.beatToSec(beat + .1875)) * self.pixPSec, values.x + values.w - self.editorTheme['GridLineWidth'] * 2, self.reverse * (self.song.offset + level.beatToSec(beat + .1875)) * self.pixPSec, self.editorTheme['Grid64'])) lane.addToGroup( self.gs.addLine( values.x + self.editorTheme['GridLineWidth'], self.reverse * (self.song.offset + level.beatToSec(beat + .3125)) * self.pixPSec, values.x + values.w - self.editorTheme['GridLineWidth'] * 2, self.reverse * (self.song.offset + level.beatToSec(beat + .3125)) * self.pixPSec, self.editorTheme['Grid64'])) lane.addToGroup( self.gs.addLine( values.x + self.editorTheme['GridLineWidth'], self.reverse * (self.song.offset + level.beatToSec(beat + .4375)) * self.pixPSec, values.x + values.w - self.editorTheme['GridLineWidth'] * 2, self.reverse * (self.song.offset + level.beatToSec(beat + .4375)) * self.pixPSec, self.editorTheme['Grid64'])) lane.addToGroup( self.gs.addLine( values.x + self.editorTheme['GridLineWidth'], self.reverse * (self.song.offset + level.beatToSec(beat + .5625)) * self.pixPSec, values.x + values.w - self.editorTheme['GridLineWidth'] * 2, self.reverse * (self.song.offset + level.beatToSec(beat + .5625)) * self.pixPSec, self.editorTheme['Grid64'])) lane.addToGroup( self.gs.addLine( values.x + self.editorTheme['GridLineWidth'], self.reverse * (self.song.offset + level.beatToSec(beat + .6875)) * self.pixPSec, values.x + values.w - self.editorTheme['GridLineWidth'] * 2, self.reverse * (self.song.offset + level.beatToSec(beat + .6875)) * self.pixPSec, self.editorTheme['Grid64'])) lane.addToGroup( self.gs.addLine( values.x + self.editorTheme['GridLineWidth'], self.reverse * (self.song.offset + level.beatToSec(beat + .8125)) * self.pixPSec, values.x + values.w - self.editorTheme['GridLineWidth'] * 2, self.reverse * (self.song.offset + level.beatToSec(beat + .8125)) * self.pixPSec, self.editorTheme['Grid64'])) lane.addToGroup( self.gs.addLine( values.x + self.editorTheme['GridLineWidth'], self.reverse * (self.song.offset + level.beatToSec(beat + .9375)) * self.pixPSec, values.x + values.w - self.editorTheme['GridLineWidth'] * 2, self.reverse * (self.song.offset + level.beatToSec(beat + .9375)) * self.pixPSec, self.editorTheme['Grid64'])) if self.disp12: lane.addToGroup( self.gs.addLine( values.x + self.editorTheme['GridLineWidth'], self.reverse * (self.song.offset + level.beatToSec(beat + 1 / 3)) * self.pixPSec, values.x + values.w - self.editorTheme['GridLineWidth'] * 2, self.reverse * (self.song.offset + level.beatToSec(beat + 1 / 3)) * self.pixPSec, self.editorTheme['Grid12'])) lane.addToGroup( self.gs.addLine( values.x + self.editorTheme['GridLineWidth'], self.reverse * (self.song.offset + level.beatToSec(beat + 2 / 3)) * self.pixPSec, values.x + values.w - self.editorTheme['GridLineWidth'] * 2, self.reverse * (self.song.offset + level.beatToSec(beat + 2 / 3)) * self.pixPSec, self.editorTheme['Grid12'])) if self.disp24: lane.addToGroup( self.gs.addLine( values.x + self.editorTheme['GridLineWidth'], self.reverse * (self.song.offset + level.beatToSec(beat + 1 / 6)) * self.pixPSec, values.x + values.w - self.editorTheme['GridLineWidth'] * 2, self.reverse * (self.song.offset + level.beatToSec(beat + 1 / 6)) * self.pixPSec, self.editorTheme['Grid24'])) lane.addToGroup( self.gs.addLine( values.x + self.editorTheme['GridLineWidth'], self.reverse * (self.song.offset + level.beatToSec(beat + .5)) * self.pixPSec, values.x + values.w - self.editorTheme['GridLineWidth'] * 2, self.reverse * (self.song.offset + level.beatToSec(beat + .5)) * self.pixPSec, self.editorTheme['Grid24'])) lane.addToGroup( self.gs.addLine( values.x + self.editorTheme['GridLineWidth'], self.reverse * (self.song.offset + level.beatToSec(beat + 5 / 6)) * self.pixPSec, values.x + values.w - self.editorTheme['GridLineWidth'] * 2, self.reverse * (self.song.offset + level.beatToSec(beat + 5 / 6)) * self.pixPSec, self.editorTheme['Grid24'])) if self.disp48: lane.addToGroup( self.gs.addLine( values.x + self.editorTheme['GridLineWidth'], self.reverse * (self.song.offset + level.beatToSec(beat + 1 / 12)) * self.pixPSec, values.x + values.w - self.editorTheme['GridLineWidth'] * 2, self.reverse * (self.song.offset + level.beatToSec(beat + 1 / 12)) * self.pixPSec, self.editorTheme['Grid48'])) lane.addToGroup( self.gs.addLine( values.x + self.editorTheme['GridLineWidth'], self.reverse * (self.song.offset + level.beatToSec(beat + .25)) * self.pixPSec, values.x + values.w - self.editorTheme['GridLineWidth'] * 2, self.reverse * (self.song.offset + level.beatToSec(beat + .25)) * self.pixPSec, self.editorTheme['Grid48'])) lane.addToGroup( self.gs.addLine( values.x + self.editorTheme['GridLineWidth'], self.reverse * (self.song.offset + level.beatToSec(beat + 5 / 12)) * self.pixPSec, values.x + values.w - self.editorTheme['GridLineWidth'] * 2, self.reverse * (self.song.offset + level.beatToSec(beat + 5 / 12)) * self.pixPSec, self.editorTheme['Grid48'])) lane.addToGroup( self.gs.addLine( values.x + self.editorTheme['GridLineWidth'], self.reverse * (self.song.offset + level.beatToSec(beat + 7 / 12)) * self.pixPSec, values.x + values.w - self.editorTheme['GridLineWidth'] * 2, self.reverse * (self.song.offset + level.beatToSec(beat + 7 / 12)) * self.pixPSec, self.editorTheme['Grid48'])) lane.addToGroup( self.gs.addLine( values.x + self.editorTheme['GridLineWidth'], self.reverse * (self.song.offset + level.beatToSec(beat + .75)) * self.pixPSec, values.x + values.w - self.editorTheme['GridLineWidth'] * 2, self.reverse * (self.song.offset + level.beatToSec(beat + .75)) * self.pixPSec, self.editorTheme['Grid48'])) lane.addToGroup( self.gs.addLine( values.x + self.editorTheme['GridLineWidth'], self.reverse * (self.song.offset + level.beatToSec(beat + 11 / 12)) * self.pixPSec, values.x + values.w - self.editorTheme['GridLineWidth'] * 2, self.reverse * (self.song.offset + level.beatToSec(beat + 11 / 12)) * self.pixPSec, self.editorTheme['Grid48'])) lane.addToGroup( self.gs.addLine( values.x, values.y, values.x, self.reverse * (self.song.offset + level.beatToSec(self.song.lengthInBeats)) * self.pixPSec, self.editorTheme['GridLayer1Vert'])) lane.addToGroup( self.gs.addLine( values.x + values.w * .25, values.y, values.x + values.w * .25, self.reverse * (self.song.offset + level.beatToSec(self.song.lengthInBeats)) * self.pixPSec, self.editorTheme['GridLayer1Vert'])) lane.addToGroup( self.gs.addLine( values.x + values.w * .5, values.y, values.x + values.w * .5, self.reverse * (self.song.offset + level.beatToSec(self.song.lengthInBeats)) * self.pixPSec, self.editorTheme['GridLayer1Vert'])) lane.addToGroup( self.gs.addLine( values.x + values.w * .75, values.y, values.x + values.w * .75, self.reverse * (self.song.offset + level.beatToSec(self.song.lengthInBeats)) * self.pixPSec, self.editorTheme['GridLayer1Vert'])) lane.addToGroup( self.gs.addLine( values.x + values.w, values.y, values.x + values.w, self.reverse * (self.song.offset + level.beatToSec(self.song.lengthInBeats)) * self.pixPSec, self.editorTheme['GridLayer1Vert'])) def getTheme(self): return { 'BoxWidth': 60, 'LaneSpacing': 20, 'BG': QBrush(QColor(0, 0, 0), Qt.SolidPattern), 'GridLayer1Vert': QPen(QBrush(QColor(255, 255, 255)), 1, Qt.SolidLine), 'GridLayer1BG': QBrush(Qt.black, Qt.SolidPattern), 'GridLayer2Vert': QPen(Qt.white, Qt.SolidLine), 'GridLayer2BG': QBrush(Qt.black, Qt.SolidPattern), 'GridLayer3Vert': QPen(Qt.white, Qt.SolidLine), 'GridLayer3BG': QBrush(Qt.black, Qt.SolidPattern), 'GridObs': QPen(Qt.blue, Qt.SolidLine), 'GridObsBG': QBrush(Qt.black, Qt.SolidPattern), 'GridEventVert': QPen(Qt.red, Qt.SolidLine), 'GridEventBG': QBrush(Qt.black, Qt.SolidPattern), 'GridMeasure': QPen(QBrush(QColor(255, 0, 0)), 2, Qt.SolidLine), 'Grid4': QPen(QBrush(QColor(255, 255, 255)), 2, Qt.DashLine), 'Grid8': QPen(QBrush(QColor(0, 150, 255)), 2, Qt.DotLine), 'Grid12': QPen(QBrush(QColor(100, 255, 50)), 2, Qt.DotLine), 'Grid16': QPen(QBrush(QColor(255, 255, 50)), 2, Qt.DotLine), 'Grid24': QPen(QBrush(QColor(150, 100, 255)), 2, Qt.DotLine), 'Grid32': QPen(QBrush(QColor(0, 255, 150)), 2, Qt.DotLine), 'Grid48': QPen(QBrush(QColor(255, 100, 150)), 2, Qt.DotLine), 'Grid64': QPen(QBrush(QColor(150, 200, 100)), 2, Qt.DotLine), # 'Grid192': QPen(Qt.red,Qt.SolidLine), 'GridLineWidth': 1 }