diff options
author | amartin <olpc@xo-00-CE-12.localdomain> | 2007-06-28 21:25:38 (GMT) |
---|---|---|
committer | amartin <olpc@xo-00-CE-12.localdomain> | 2007-06-28 21:25:38 (GMT) |
commit | 146f6eefdb76494a1d8d9b033c64b3a686227225 (patch) | |
tree | 89485e3b794411f62e04a8739e312a6f0209f802 /Edit | |
parent | 1a360aa3235c5b661f8eff0f9b57de4816e73d68 (diff) |
network
Diffstat (limited to 'Edit')
-rw-r--r-- | Edit/HitInterface.py | 6 | ||||
-rw-r--r-- | Edit/MainWindow.py | 156 | ||||
-rw-r--r-- | Edit/NoteInterface.py | 13 | ||||
-rw-r--r-- | Edit/Properties.py | 153 | ||||
-rw-r--r-- | Edit/TrackInterface.py | 51 | ||||
-rw-r--r-- | Edit/TuneInterface.py | 31 |
6 files changed, 271 insertions, 139 deletions
diff --git a/Edit/HitInterface.py b/Edit/HitInterface.py index e3692b7..6e77908 100644 --- a/Edit/HitInterface.py +++ b/Edit/HitInterface.py @@ -27,11 +27,13 @@ class HitInterface( NoteInterface ): else: dirty = False - if self.note.cs.onset != self.oldOnset: - self.x = self.owner.ticksToPixels( self.noteDB.getPage(self.note.page).beats, self.note.cs.onset ) + beats = self.noteDB.getPage( self.note.page ).beats + if self.note.cs.onset != self.oldOnset or beats != self.oldBeats: + self.x = self.owner.ticksToPixels( beats, self.note.cs.onset ) self.x += self.origin[0] self.imgX = self.x - Config.NOTE_IMAGE_PADDING self.oldOnset = self.note.cs.onset + self.oldBeats = beats if self.note.cs.pitch != self.oldPitch: self.y = self.owner.pitchToPixelsDrum( self.note.cs.pitch ) + self.origin[1] self.imgY = self.y - Config.NOTE_IMAGE_PADDING diff --git a/Edit/MainWindow.py b/Edit/MainWindow.py index a546a5f..5fce403 100644 --- a/Edit/MainWindow.py +++ b/Edit/MainWindow.py @@ -442,13 +442,13 @@ class MainWindow( SubActivity ): self.GUI["9generationPopup"].connect("button-release-event", lambda w,e:self.doneGenerationPopup() ) self.GUI["9generationPopup"].add( self.generationPanel ) # + properties window - TP.ProfileBegin("init_GUI::propertiesPanel") - self.propertiesPanel = Properties( self.noteDB, self.donePropertiesPopup ) - TP.ProfileEnd("init_GUI::propertiesPanel") self.GUI["9propertiesPopup"] = gtk.Window(gtk.WINDOW_POPUP) self.GUI["9propertiesPopup"].set_modal(True) self.GUI["9propertiesPopup"].add_events( gtk.gdk.BUTTON_PRESS_MASK ) self.GUI["9propertiesPopup"].connect("button-release-event", lambda w,e:self.donePropertiesPopup() ) + TP.ProfileBegin("init_GUI::propertiesPanel") + self.propertiesPanel = Properties( self.noteDB, self.donePropertiesPopup, self.GUI["9propertiesPopup"] ) + TP.ProfileEnd("init_GUI::propertiesPanel") self.GUI["9propertiesPopup"].add( self.propertiesPanel ) # + playback scope self.GUI["9loopPopup"] = gtk.Window(gtk.WINDOW_POPUP) @@ -484,7 +484,6 @@ class MainWindow( SubActivity ): self.playingTuneIdx = 0 # timers - self.predrawTimeout = False self.playbackTimeout = False # FPS stuff @@ -594,9 +593,19 @@ class MainWindow( SubActivity ): if w.get_active(): self.GUI["9loopPopup"].show_all() else: self.GUI["9loopPopup"].hide() - #----------------------------------- + #----------------------------------- # playback functions #----------------------------------- + + def updatePageSelection( self, selectedIds ): + if not self.playing: + return + + if self.playScope == "All": + return + + self._playPages( selectedIds, self.displayedPage, self.trackInterface.getPlayhead() ) + def updatePagesPlaying( self ): self.csnd.loopDeactivate() @@ -612,6 +621,12 @@ class MainWindow( SubActivity ): for track in trackset: notes += self.noteDB.getNotesByTrack( page, track ) + numticks = 0 + self.page_onset = {} + for pid in self.pages_playing: + self.page_onset[pid] = numticks + numticks += self.noteDB.getPage(pid).ticks + #print self.pages_playing for n in notes: self.csnd.loopUpdate(n, NoteDB.PARAMETER.DURATION, n.cs.duration , 1) @@ -654,48 +669,49 @@ class MainWindow( SubActivity ): else: toPlay = self.tuneInterface.getSelectedIds() - if True : #self.pages_playing != toPlay: # rebuild note loop - self.pages_playing = toPlay[:] + self._playPages( toPlay, self.displayedPage, self.trackInterface.getPlayhead() ) - trackset = set( [ i for i in range(Config.NUMBER_OF_TRACKS) if self.trackActive[i] ] ) + self.playing = True - numticks = 0 - self.page_onset = {} - for pid in self.pages_playing: - self.page_onset[pid] = numticks - numticks += self.noteDB.getPage(pid).ticks + def _playPages( self, pages, startPage, startTick ): - notes = [] - for page in self.pages_playing: - for track in trackset: - notes += self.noteDB.getNotesByTrack( page, track ) + self.pages_playing = pages[:] + + trackset = set( [ i for i in range(Config.NUMBER_OF_TRACKS) if self.trackActive[i] ] ) + + numticks = 0 + self.page_onset = {} + for pid in self.pages_playing: + self.page_onset[pid] = numticks + numticks += self.noteDB.getPage(pid).ticks - if (Config.DEBUG > 3): - print 'rebuild note loop' - print 'pages : ', self.pages_playing - print 'trackset : ', trackset - print 'numticks : ', numticks - print 'notes : ', len(notes), 'notes' - self.csnd.loopClear() - for n in notes: - self.csnd.loopPlay(n, 1) - self.csnd.loopUpdate(n, NoteDB.PARAMETER.ONSET, n.cs.onset + self.page_onset[n.page] , 1) - self.csnd.loopSetNumTicks( numticks ) - - if (Config.DEBUG > 3): print "displayed page", self.displayedPage, self.tuneInterface.getDisplayedIndex() - if self.playScope == "All": startTick = 0 - else: startTick = self.tuneInterface.getDisplayedIndex()*(4*Config.TICKS_PER_BEAT) # TODO change this to handle varying beats per page - startTick += self.trackInterface.getPlayhead() - self.csnd.loopSetTick( startTick ) + notes = [] + for page in self.pages_playing: + for track in trackset: + notes += self.noteDB.getNotesByTrack( page, track ) + + if (Config.DEBUG > 3): + print 'rebuild note loop' + print 'pages : ', self.pages_playing + print 'trackset : ', trackset + print 'numticks : ', numticks + print 'notes : ', len(notes), 'notes' + self.csnd.loopClear() + for n in notes: + self.csnd.loopPlay(n, 1) + self.csnd.loopUpdate(n, NoteDB.PARAMETER.ONSET, n.cs.onset + self.page_onset[n.page] , 1) + + self.csnd.loopSetNumTicks( numticks ) + + self.csnd.loopSetTick( self.page_onset[startPage] + startTick ) self.csnd.loopSetTempo(self._data['tempo']) if (Config.DEBUG > 3): print "starting from tick", startTick, 'at tempo', self._data['tempo'] self.csnd.loopStart() - self.playing = True - if self.predrawTimeout: - gobject.source_remove( self.predrawTimeout ) - self.predrawTimeout = False - self.playbackTimeout = gobject.timeout_add( 50, self.onTimeout ) + if not self.playbackTimeout: + self.playbackTimeout = gobject.timeout_add( 50, self.onTimeout ) + + def handleStop( self, widget, rewind = True ): @@ -747,25 +763,34 @@ class MainWindow( SubActivity ): self.updateFPS() curTick = self.csnd.loopGetTick() - curIdx = curTick / ( 4 * Config.TICKS_PER_BEAT) #TODO handle each pages_playing length - - self.trackInterface.setPlayhead( curTick - curIdx*(4*Config.TICKS_PER_BEAT) ) - if self.pages_playing[curIdx] != self.displayedPage: - if curIdx + 1 < len(self.pages_playing): predraw = self.pages_playing[curIdx+1] + pageTick = self.page_onset[self.displayedPage] + if curTick < pageTick: + pageTick = 0 + ind = 0 + else: + ind = self.pages_playing.index(self.displayedPage) + + localTick = curTick - pageTick + pageLength = self.noteDB.getPage(self.pages_playing[ind]).ticks + max = len(self.pages_playing) + while localTick > pageLength: + ind += 1 + if ind == max: ind = 0 + localTick -= pageLength + pageLength = self.noteDB.getPage(self.pages_playing[ind]).ticks + + self.trackInterface.setPlayhead( localTick ) + + if self.pages_playing[ind] != self.displayedPage: + if ind + 1 < max: predraw = self.pages_playing[ind+1] else: predraw = self.pages_playing[0] - self.displayPage( self.pages_playing[curIdx], predraw ) + self.displayPage( self.pages_playing[ind], predraw ) else: - self.trackInterface.predrawPage( time.time() + 0.020 ) # 10 ms time limit + self.trackInterface.predrawPage() return True - def onPredrawTimeout( self ): - if self.trackInterface.predrawPage( time.time() + 0.020 ): # 20 ms time limit - self.predrawTimeout = False - return False - return True - def onMuteTrack( self, widget, trackId ): self._data['track_mute'][trackId] = not self._data['track_mute'][trackId] #if self._data['track_mute'][trackId]: @@ -1036,7 +1061,7 @@ class MainWindow( SubActivity ): winLoc = self.parent.window.get_position() balloc = self.GUI["2contextBox"].get_allocation() walloc = self.GUI["9propertiesPopup"].get_allocation() - if walloc.height != 1: # hack to make deal with showing the window before first allocation T_T + if walloc.height != 1: # hack to deal with showing the window before first allocation T_T self.GUI["9propertiesPopup"].move( balloc.x + winLoc[0], balloc.y - walloc.height + winLoc[1] ) else: self.GUI["9propertiesPopup"].move(0, 2048) # off the screen @@ -1128,15 +1153,11 @@ class MainWindow( SubActivity ): if not trackSelected: self.setContextState( CONTEXT.TRACK, False ) - self.updatePagesPlaying() - def setTrack( self, trackN, state ): if self.trackSelected[trackN] != state: self.trackSelected[trackN] = state self.trackInterface.trackToggled( trackN ) - self.updatePagesPlaying() - def clearTracks( self ): for i in range(Config.NUMBER_OF_TRACKS): if self.trackSelected[i]: @@ -1146,8 +1167,6 @@ class MainWindow( SubActivity ): self.setContextState( CONTEXT.TRACK, False ) - self.updatePagesPlaying() - def getTrackSelected( self, trackN ): return self.trackSelected[trackN] @@ -1239,14 +1258,10 @@ class MainWindow( SubActivity ): def predrawPage( self, pageId ): if self.playbackTimeout: return # we're playing, predrawing is already handled if self.trackInterface.setPredrawPage( pageId ): # page needs to be drawn - if self.predrawTimeout: - gobject.source_remove( self.predrawTimeout ) - self.predrawTimeout = gobject.timeout_add( 50, self.onPredrawTimeout ) + self.trackInterface.predrawPage() def abortPredrawPage( self ): - if self.predrawTimeout: - gobject.source_remove( self.predrawTimeout ) - self.predrawTimeout = False + self.trackInterface.abortPredrawPage() def pageGenerate( self, widget ): if widget.get_active(): @@ -1297,13 +1312,15 @@ class MainWindow( SubActivity ): self.displayPage( new[self.displayedPage] ) self.tuneInterface.selectPages( new.values() ) - def pageAdd( self, after = -1, beats = False ): + def pageAdd( self, after = -1, beats = False, color = False ): if after == -1: after = self.tuneInterface.getLastSelected() - if not beats: beats = self.noteDB.getPage( self.displayedPage ).beats + page = self.noteDB.getPage( self.displayedPage ) + if not beats: beats = page.beats + if not color: color = page.color # TODO think about network mode here... - self.displayPage( self.noteDB.addPage( -1, NoteDB.Page(beats), after ) ) + self.displayPage( self.noteDB.addPage( -1, NoteDB.Page(beats,color), after ) ) def pageBeats( self, pageIds = -1 ): @@ -1327,6 +1344,9 @@ class MainWindow( SubActivity ): def notifyPageMove( self, which, low, high ): return + def notifyPageUpdate( self, page, parameter, value ): + pass + def notifyNoteAdd( self, page, track, id ): if (Config.DEBUG > 3) : print 'INFO: adding note to loop', page, track, id n = self.noteDB.getNote(page, track, id) diff --git a/Edit/NoteInterface.py b/Edit/NoteInterface.py index 3a90c9f..a51fe2c 100644 --- a/Edit/NoteInterface.py +++ b/Edit/NoteInterface.py @@ -32,6 +32,7 @@ class NoteInterface: self.oldEnd = -1 self.oldPitch = -1 self.oldAmplitude = -1 + self.oldBeats = -1 self.lastDragO = 0 self.lastDragP = 0 self.lastDragD = 0 @@ -83,19 +84,21 @@ class NoteInterface: else: dirty = False - if self.note.cs.onset != self.oldOnset: - self.x = self.owner.ticksToPixels( self.noteDB.getPage( self.note.page).beats, self.note.cs.onset ) + beats = self.noteDB.getPage( self.note.page ).beats + if self.note.cs.onset != self.oldOnset or beats != self.oldBeats: + self.x = self.owner.ticksToPixels( beats, self.note.cs.onset ) self.x += self.origin[0] self.imgX = self.x - Config.NOTE_IMAGE_PADDING self.oldOnset = self.note.cs.onset - if self.end != self.oldEnd or self.note.cs.onset != self.oldOnset: - self.width = self.owner.ticksToPixels( self.noteDB.getPage( self.note.page).beats, self.end ) - self.x + self.origin[0] + if self.end != self.oldEnd or self.note.cs.onset != self.oldOnset or beats != self.oldBeats: + self.width = self.owner.ticksToPixels( beats, self.end ) - self.x + self.origin[0] self.imgWidth = self.width + Config.NOTE_IMAGE_PADDING_MUL2 self.oldEnd = self.end if self.note.cs.pitch != self.oldPitch: self.y = self.owner.pitchToPixels( self.note.cs.pitch ) + self.origin[1] self.imgY = self.y - Config.NOTE_IMAGE_PADDING self.oldPitch = self.note.cs.pitch + self.oldBeats = beats if dirty: if self.firstTransform: @@ -209,7 +212,7 @@ class NoteInterface: return True def noteDragOnset( self, do, stream ): - self. potentialDeselect = False + self.potentialDeselect = False if do != self.lastDragO: self.lastDragO = do stream += [ self.note.id, self.baseOnset + do ] diff --git a/Edit/Properties.py b/Edit/Properties.py index 6a4e515..0913966 100644 --- a/Edit/Properties.py +++ b/Edit/Properties.py @@ -12,11 +12,13 @@ import Config Tooltips = Config.Tooltips() class Properties( gtk.VBox ): - def __init__( self, noteDB, doneHandler ): + def __init__( self, noteDB, doneHandler, popup ): gtk.VBox.__init__( self ) self.tooltips = gtk.Tooltips() self.noteDB = noteDB self.doneHandler = doneHandler + self.popup = popup + self.popup.resize( 545, 378 ) self.context = "page" self.notes = {} # notes indexed by page and track @@ -30,21 +32,63 @@ class Properties( gtk.VBox ): self.algoTypes = [self.line, self.drunk, self.droneAndJump, self.repeter, self.loopseg] self.algorithm = self.algoTypes[0] + #self.set_size_request( 300, 200 ) + self.filterType = 0 self.minValue = 0. self.maxValue = 100. self.paraValue = 20. self.activeWidget = None + + self.pageIds = [] self.GUI = {} self.parametersBox = RoundHBox(fillcolor=Config.INST_BCK_COLOR, bordercolor=Config.PANEL_BCK_COLOR) - self.parametersBox.set_border_width(1) + #self.parametersBox.set_border_width(1) self.parametersBox.set_radius(10) self.pack_start(self.parametersBox) + self.fixed = gtk.Fixed() + self.parametersBox.pack_start( self.fixed ) - controlsBox = gtk.HBox() + self.controlsBox = gtk.HBox() + #-- Page Properties ------------------------------------------------ + self.pageBox = RoundHBox(fillcolor=Config.PANEL_COLOR, bordercolor=Config.INST_BCK_COLOR) + self.pageBox.set_size_request( 125, -1 ) + self.pageBox.set_border_width(3) + self.pageBox.set_radius(10) + beatBox = gtk.VBox() + self.beatAdjust = gtk.Adjustment( 4, 2, 12, 1, 1, 0) + self.GUI['beatSlider'] = ImageVScale( Config.TAM_TAM_ROOT + "/Resources/Images/sliderEditVolume.png", self.beatAdjust, 7 ) + self.beatAdjust.connect("value-changed", self.handleBeat) + self.GUI['beatSlider'].set_snap( 1 ) + self.GUI['beatSlider'].set_inverted(True) + self.GUI['beatSlider'].set_size_request(50, 200) + beatBox.pack_start( self.GUI['beatSlider'] ) + self.beatLabel = gtk.Image() + self.beatLabel.set_from_file(Config.IMAGE_ROOT + 'volume3.png') + self.handleBeat( self.beatAdjust ) + beatBox.pack_start( self.beatLabel ) + self.pageBox.pack_start( beatBox ) + colorBox = gtk.VBox() + self.GUI["color0Button"] = ImageRadioButton( None, Config.IMAGE_ROOT+"pageThumbnailBut0.png", Config.IMAGE_ROOT+"pageThumbnailBut0Down.png", backgroundFill = Config.PANEL_COLOR ) + self.GUI["color0Button"].connect( "clicked", self.handleColor, 0 ) + colorBox.pack_start( self.GUI["color0Button"] ) + self.GUI["color1Button"] = ImageRadioButton( self.GUI["color0Button"], Config.IMAGE_ROOT+"pageThumbnailBut1.png", Config.IMAGE_ROOT+"pageThumbnailBut1Down.png", backgroundFill = Config.PANEL_COLOR ) + self.GUI["color1Button"].connect( "clicked", self.handleColor, 1 ) + colorBox.pack_start( self.GUI["color1Button"] ) + self.GUI["color2Button"] = ImageRadioButton( self.GUI["color0Button"], Config.IMAGE_ROOT+"pageThumbnailBut2.png", Config.IMAGE_ROOT+"pageThumbnailBut2Down.png", backgroundFill = Config.PANEL_COLOR ) + self.GUI["color2Button"].connect( "clicked", self.handleColor, 2 ) + colorBox.pack_start( self.GUI["color2Button"] ) + self.GUI["color3Button"] = ImageRadioButton( self.GUI["color0Button"], Config.IMAGE_ROOT+"pageThumbnailBut3.png", Config.IMAGE_ROOT+"pageThumbnailBut3Down.png", backgroundFill = Config.PANEL_COLOR ) + self.GUI["color3Button"].connect( "clicked", self.handleColor, 3 ) + colorBox.pack_start( self.GUI["color3Button"] ) + self.pageBox.pack_start( colorBox ) + self.pageBox.show_all() + #self.controlsBox.pack_start(self.pageBox) + + #-- Note Properties ------------------------------------------------ pitchBox = RoundVBox(fillcolor=Config.PANEL_COLOR, bordercolor=Config.INST_BCK_COLOR) pitchBox.set_border_width(3) pitchBox.set_radius(10) @@ -60,7 +104,7 @@ class Properties( gtk.VBox ): self.GUI['pitchDown'] = ImageButton( Config.IMAGE_ROOT+"arrowEditDown.png", Config.IMAGE_ROOT+"arrowEditDownDown.png", Config.IMAGE_ROOT+"arrowEditDownOver.png", backgroundFill = Config.PANEL_COLOR ) self.GUI['pitchDown'].connect( "clicked", lambda w:self.stepPitch( -1 ) ) pitchBox.pack_start( self.GUI['pitchDown'] ) - controlsBox.pack_start(pitchBox) + self.controlsBox.pack_start(pitchBox) volumeBox = RoundVBox(fillcolor=Config.PANEL_COLOR, bordercolor=Config.INST_BCK_COLOR) volumeBox.set_border_width(3) @@ -77,7 +121,7 @@ class Properties( gtk.VBox ): self.GUI['volumeDown'] = ImageButton( Config.IMAGE_ROOT+"arrowEditDown.png", Config.IMAGE_ROOT+"arrowEditDownDown.png", Config.IMAGE_ROOT+"arrowEditDownOver.png", backgroundFill = Config.PANEL_COLOR ) self.GUI['volumeDown'].connect( "clicked", lambda w:self.stepVolume( -0.1 ) ) volumeBox.pack_start( self.GUI['volumeDown'] ) - controlsBox.pack_start(volumeBox) + self.controlsBox.pack_start(volumeBox) panBox = RoundVBox(fillcolor=Config.PANEL_COLOR, bordercolor=Config.INST_BCK_COLOR) panBox.set_border_width(3) @@ -95,7 +139,7 @@ class Properties( gtk.VBox ): panBox.pack_start(self.GUI['panGen'], True, True, 5) panBox.pack_start(self.GUI['panSlider'], True, True, 5) panBox.pack_start(self.panLabel, False, padding=10) - controlsBox.pack_start(panBox) + self.controlsBox.pack_start(panBox) reverbBox = RoundVBox(fillcolor=Config.PANEL_COLOR, bordercolor=Config.INST_BCK_COLOR) reverbBox.set_border_width(3) @@ -113,7 +157,7 @@ class Properties( gtk.VBox ): reverbBox.pack_start(self.GUI['reverbGen'], True, True, 5) reverbBox.pack_start(self.GUI['reverbSlider'], True, True, 5) reverbBox.pack_start(self.reverbLabel, False, padding=10) - controlsBox.pack_start(reverbBox) + self.controlsBox.pack_start(reverbBox) attackBox = RoundVBox(fillcolor=Config.PANEL_COLOR, bordercolor=Config.INST_BCK_COLOR) attackBox.set_border_width(3) @@ -131,7 +175,7 @@ class Properties( gtk.VBox ): attackBox.pack_start(self.GUI['attackGen'], True, True, 5) attackBox.pack_start(self.GUI['attackSlider'], True, True, 5) attackBox.pack_start(self.attackLabel, False, padding=10) - controlsBox.pack_start(attackBox) + self.controlsBox.pack_start(attackBox) decayBox = RoundVBox(fillcolor=Config.PANEL_COLOR, bordercolor=Config.INST_BCK_COLOR) decayBox.set_border_width(3) @@ -149,7 +193,7 @@ class Properties( gtk.VBox ): decayBox.pack_start(self.GUI['decayGen'], True, True, 5) decayBox.pack_start(self.GUI['decaySlider'], True, True, 5) decayBox.pack_start(self.decayLabel, False, padding=10) - controlsBox.pack_start(decayBox) + self.controlsBox.pack_start(decayBox) filterBox = RoundHBox(fillcolor=Config.PANEL_COLOR, bordercolor=Config.INST_BCK_COLOR) filterBox.set_border_width(3) @@ -186,9 +230,10 @@ class Properties( gtk.VBox ): filterBox.pack_start(self.filterSliderBox) - controlsBox.pack_start(filterBox) + self.controlsBox.pack_start(filterBox) self.algoBox = RoundVBox(fillcolor=Config.PANEL_COLOR, bordercolor=Config.INST_BCK_COLOR) + self.algoBox.set_size_request( -1, 378 ) self.algoBox.set_border_width(3) self.algoBox.set_radius(10) #self.algoBox = gtk.VBox() @@ -275,8 +320,8 @@ class Properties( gtk.VBox ): transButtonBox.pack_end(self.GUI["cancelButton"], False, False) self.algoBox.pack_start(transButtonBox) - self.parametersBox.pack_start(controlsBox) - self.parametersBox.pack_start(self.algoBox) + self.fixed.put( self.controlsBox, 0, 0 ) + self.algoBox.show_all() # set tooltips for key in self.GUI: @@ -292,30 +337,22 @@ class Properties( gtk.VBox ): self.property = data if self.activeWidget: self.activeWidget.set_active(False) - self.GUI['line'].show() - self.GUI['drunk'].show() - self.GUI['droneJump'].show() - self.GUI['repeater'].show() - self.GUI['loopseg'].show() - self.GUI['minSlider'].show() - self.GUI['maxSlider'].show() - self.GUI['paraSlider'].show() - self.GUI['checkButton'].show() - self.GUI['cancelButton'].show() self.activeWidget = widget + if self.context == "page": + if self.algoBox.parent == None: self.fixed.put( self.algoBox, 671, 0 ) + else: self.fixed.move( self.algoBox, 671, 0 ) + self.popup.resize( 927, 378 ) + else: + self.popup.resize( 801, 378 ) + if self.algoBox.parent == None: self.fixed.put( self.algoBox, 545, 0 ) + else: self.fixed.move( self.algoBox, 545, 0 ) else: self.property = None - self.GUI['line'].hide() - self.GUI['drunk'].hide() - self.GUI['droneJump'].hide() - self.GUI['repeater'].hide() - self.GUI['loopseg'].hide() - self.GUI['minSlider'].hide() - self.GUI['maxSlider'].hide() - self.GUI['paraSlider'].hide() - self.GUI['checkButton'].hide() - self.GUI['cancelButton'].hide() self.activeWidget = None + if self.algoBox.parent != None: + if self.context == "page": self.popup.resize( 671, 378 ) + else: self.popup.resize( 545, 378 ) + self.fixed.remove( self.algoBox ) def setContext( self, context, scale, pageIds = None, trackIds = None, notes = {} ): self.context = context @@ -330,18 +367,32 @@ class Properties( gtk.VBox ): except: self.activeWidget = None + print self.pageBox.parent if context == "page": + if self.pageBox.parent == None: + self.controlsBox.pack_start( self.pageBox ) + self.controlsBox.reorder_child( self.pageBox, 0 ) + self.controlsBox.set_size_request( 671, 378 ) + self.popup.resize( 671, 378 ) self.trackIds = [0,1,2,3,4] for p in pageIds: self.notes[p] = {} for t in range(Config.NUMBER_OF_TRACKS): self.notes[p][t] = self.noteDB.getNotesByTrack( p, t ) elif context == "track": + if self.pageBox.parent != None: + self.controlsBox.remove( self.pageBox ) + self.controlsBox.set_size_request( 545, 378 ) + self.popup.resize( 545, 378 ) for p in pageIds: self.notes[p] = {} for t in trackIds: self.notes[p][t] = self.noteDB.getNotesByTrack( p, t ) else: + if self.pageBox.parent != None: + self.controlsBox.remove( self.pageBox ) + self.controlsBox.set_size_request( 545, 378 ) + self.popup.resize( 545, 378 ) self.notes = notes self.pageIds = self.notes.keys() self.trackIds = self.notes[self.pageIds[0]].keys() @@ -375,19 +426,27 @@ class Properties( gtk.VBox ): self.GUI['cutoffGen'].show() self.filterType = n.cs.filterType self.cutoffAdjust.set_value( n.cs.filterCutoff ) - self.GUI['line'].hide() - self.GUI['drunk'].hide() - self.GUI['droneJump'].hide() - self.GUI['repeater'].hide() - self.GUI['loopseg'].hide() - self.GUI['minSlider'].hide() - self.GUI['maxSlider'].hide() - self.GUI['paraSlider'].hide() - self.GUI['checkButton'].hide() - self.GUI['cancelButton'].hide() self.setup = False return + def handleColor( self, widget, index ): + stream = [] + for page in self.pageIds: + stream += [ page, index ] + if len(stream): + self.noteDB.updatePages( [ PARAMETER.PAGE_COLOR, len(stream)//2 ] + stream ) + + def handleBeat( self, adjust ): + beats = int(adjust.value) + self.beatLabel.set_from_file(Config.IMAGE_ROOT + 'propBeats' + str(beats) + '.png') + if not self.setup: + stream = [] + for page in self.pageIds: + stream += [ page, beats ] + if len(stream): + self.noteDB.updatePages( [ PARAMETER.PAGE_BEATS, len(stream)//2 ] + stream ) + + def stepPitch( self, step ): stream = [] for p in self.notes: @@ -729,16 +788,6 @@ class Properties( gtk.VBox ): self.cancel(self.activeWidget) def cancel( self, widget, data=None ): - self.GUI['line'].hide() - self.GUI['drunk'].hide() - self.GUI['droneJump'].hide() - self.GUI['repeater'].hide() - self.GUI['loopseg'].hide() - self.GUI['minSlider'].hide() - self.GUI['maxSlider'].hide() - self.GUI['paraSlider'].hide() - self.GUI['checkButton'].hide() - self.GUI['cancelButton'].hide() self.activeWidget.set_active(False) def updateFilterLabel( self ): diff --git a/Edit/TrackInterface.py b/Edit/TrackInterface.py index 5db645d..f517b1d 100644 --- a/Edit/TrackInterface.py +++ b/Edit/TrackInterface.py @@ -2,6 +2,8 @@ import pygtk pygtk.require( '2.0' ) import gtk +import gobject + from math import floor import time @@ -157,11 +159,13 @@ class TrackInterface( gtk.EventBox ): self.pitchPerPixelDrum = float(Config.NUMBER_OF_POSSIBLE_PITCHES_DRUM-1)*Config.PITCH_STEP_DRUM / (self.trackHeightDrum - Config.HIT_HEIGHT) self.pixelsPerPitchDrum = float(self.trackHeightDrum-Config.HIT_HEIGHT)/(Config.MAXIMUM_PITCH_DRUM - Config.MINIMUM_PITCH_DRUM ) - self.pixelsPerTick = [0] + [ self.trackWidth//(i*Config.TICKS_PER_BEAT) for i in range(1,Config.MAXIMUM_BEATS+1) ] + self.pixelsPerTick = [0] + [ self.trackWidth/float(i*Config.TICKS_PER_BEAT) for i in range(1,Config.MAXIMUM_BEATS+1) ] self.ticksPerPixel = [0] + [ 1.0/self.pixelsPerTick[i] for i in range(1,Config.MAXIMUM_BEATS+1) ] - self.beatSpacing = [0] + [ self.pixelsPerTick[i]*Config.TICKS_PER_BEAT for i in range(1,Config.MAXIMUM_BEATS+1) ] + self.beatSpacing = [[0]] + for i in range(1,Config.MAXIMUM_BEATS+1): + self.beatSpacing.append( [ self.ticksToPixels( i, Config.TICKS_PER_BEAT*j ) for j in range(i) ] ) # screen buffers self.screenBuf = [ gtk.gdk.Pixmap( win, self.width, self.height ), \ @@ -173,6 +177,7 @@ class TrackInterface( gtk.EventBox ): self.screenBufResume = [ [0,0], [0,0] ] # allows for stopping and restarting in the middle of a draw self.curScreen = 0 self.preScreen = 1 + self.predrawTimeout = False #-- private -------------------------------------------- @@ -200,6 +205,25 @@ class TrackInterface( gtk.EventBox ): def notifyPageMove( self, which, low, high ): return + def notifyPageUpdate( self, page, parameter, value ): + if parameter == PARAMETER.PAGE_BEATS: + notes = self.noteDB.getNotesByPage( page, self ) + for note in notes: + note.updateTransform() + + if page == self.screenBufPage[self.curScreen]: + self.screenBufBeats[self.curScreen] = value + self.curBeats = value + if self.playheadT > value*Config.TICKS_PER_BEAT: + self.playheadT = value*Config.TICKS_PER_BEAT + self.playheadX = self.ticksToPixels( self.curBeats, self.playheadT ) + Config.TRACK_SPACING_DIV2 + self.invalidate_rect( 0, 0, self.width, self.height, page ) + if page == self.screenBufPage[self.preScreen]: + self.screenBufBeats[self.preScreen] = value + self.invalidate_rect( 0, 0, self.width, self.height, page ) + self.predrawPage() + + #======================================================= # Module Interface @@ -220,9 +244,23 @@ class TrackInterface( gtk.EventBox ): return True return False - def predrawPage( self, timeout ): + def predrawPage( self ): if self.screenBufPage[self.preScreen] == -1: return True # no page to predraw - return self.draw( self.preScreen, False, timeout ) + if not self.predrawTimeout: + self.predrawTimeout = gobject.timeout_add( 50, self._predrawTimeout ) + + def abortPredrawPage( self ): + if self.predrawTimeout: + gobject.source_remove( self.predrawTimeout ) + self.predrawTimeout = False + + def _predrawTimeout( self ): + if self.draw( self.preScreen, False, time.time() + 0.020 ): # 20 ms time limit + self.predrawTimeout = False + return False + return True + + def displayPage( self, page, predraw = -1 ): if page == self.curPage: @@ -988,7 +1026,6 @@ class TrackInterface( gtk.EventBox ): beatStart = Config.TRACK_SPACING_DIV2 beats = self.screenBufBeats[buf] - beatSpacing = self.beatSpacing[beats] pixmap = self.screenBuf[buf] @@ -1012,7 +1049,7 @@ class TrackInterface( gtk.EventBox ): # draw beat lines self.gc.foreground = self.beatColor for j in range(1,self.screenBufBeats[buf]): - x = beatStart + j*beatSpacing + x = beatStart + self.beatSpacing[beats][j] pixmap.draw_line( self.gc, x, self.trackRect[i].y, x, self.trackRect[i].y+self.trackRect[i].height ) resume[1] = 1 # background drawn @@ -1048,7 +1085,7 @@ class TrackInterface( gtk.EventBox ): # draw beat lines self.gc.foreground = self.beatColor for j in range(1,self.screenBufBeats[buf]): - x = beatStart + j*beatSpacing + x = beatStart + self.beatSpacing[beats][j] pixmap.draw_line( self.gc, x, self.trackRect[self.drumIndex].y, x, self.trackRect[self.drumIndex].y+self.trackRect[self.drumIndex].height ) resume[1] = 1 # background drawn diff --git a/Edit/TuneInterface.py b/Edit/TuneInterface.py index 938b361..9934700 100644 --- a/Edit/TuneInterface.py +++ b/Edit/TuneInterface.py @@ -115,11 +115,13 @@ class TuneInterface( gtk.EventBox ): self.selectedColor = colormap.alloc_color( Config.THUMBNAIL_SELECTED_COLOR, True, True ) # prepare thumbnail - pix = gtk.gdk.pixbuf_new_from_file( Config.IMAGE_ROOT+"pageThumbnailBG.png" ) - self.thumbnailBG = gtk.gdk.Pixmap( self.defaultwin, Config.PAGE_THUMBNAIL_WIDTH, Config.PAGE_THUMBNAIL_HEIGHT ) + self.thumbnailBG = [] self.gc.foreground = self.bgColor - self.thumbnailBG.draw_rectangle( self.gc, True, 0, 0, Config.PAGE_THUMBNAIL_WIDTH, Config.PAGE_THUMBNAIL_HEIGHT ) - self.thumbnailBG.draw_pixbuf( self.gc, pix, 0, 0, 0, 0, Config.PAGE_THUMBNAIL_WIDTH, Config.PAGE_THUMBNAIL_HEIGHT, gtk.gdk.RGB_DITHER_NONE ) + for i in range(4): + pix = gtk.gdk.pixbuf_new_from_file( Config.IMAGE_ROOT+"pageThumbnailBG%d.png"%i ) + self.thumbnailBG.append( gtk.gdk.Pixmap( self.defaultwin, Config.PAGE_THUMBNAIL_WIDTH, Config.PAGE_THUMBNAIL_HEIGHT ) ) + self.thumbnailBG[i].draw_rectangle( self.gc, True, 0, 0, Config.PAGE_THUMBNAIL_WIDTH, Config.PAGE_THUMBNAIL_HEIGHT ) + self.thumbnailBG[i].draw_pixbuf( self.gc, pix, 0, 0, 0, 0, Config.PAGE_THUMBNAIL_WIDTH, Config.PAGE_THUMBNAIL_HEIGHT, gtk.gdk.RGB_DITHER_NONE ) # load clipmask pix = gtk.gdk.pixbuf_new_from_file(Config.IMAGE_ROOT+'pageThumbnailMask.png') @@ -405,6 +407,8 @@ class TuneInterface( gtk.EventBox ): self.invalidate_rect( self.pageOffset + ind*Config.PAGE_THUMBNAIL_WIDTH, 0, Config.PAGE_THUMBNAIL_WIDTH, self.height ) + self.owner.updatePageSelection( self.selectedIds ) + return True # page added to selection def deselectPage( self, id, force = False, skip_redraw = False ): @@ -423,20 +427,28 @@ class TuneInterface( gtk.EventBox ): ind = self.noteDB.getPageIndex( id ) self.invalidate_rect( self.pageOffset + ind*Config.PAGE_THUMBNAIL_WIDTH, 0, Config.PAGE_THUMBNAIL_WIDTH, self.height ) + self.owner.updatePageSelection( self.selectedIds ) + return True # page removed from the selection def selectPages( self, which ): self.clearSelection() self.selectedIds += which + self.owner.updatePageSelection( self.selectedIds ) + def selectAll( self ): self.selectedIds = self.noteDB.getTune()[:] self.invalidate_rect( self.visibleX, 0, self.baseWidth, self.height ) + self.owner.updatePageSelection( self.selectedIds ) + def clearSelection( self ): self.selectedIds = [] self.invalidate_rect( self.visibleX, 0, self.baseWidth, self.height ) + self.owner.updatePageSelection( self.selectedIds ) + def getSelectedIds( self ): return self.selectedIds @@ -482,6 +494,15 @@ class TuneInterface( gtk.EventBox ): def notifyPageMove( self, which, low, high ): self.invalidate_rect( self.visibleX, 0, self.baseWidth, self.height ) + def notifyPageUpdate( self, page, parameter, value ): + if parameter == PARAMETER.PAGE_BEATS: + notes = self.noteDB.getNotesByPage( page, self ) + for note in notes: + note.updateParameter( -1, -1 ) # force update transform + + elif parameter == PARAMETER.PAGE_COLOR: + self.invalidate_thumbnail( page, 0, 0, Config.PAGE_THUMBNAIL_WIDTH, Config.PAGE_THUMBNAIL_HEIGHT ) + #======================================================= # Drawing @@ -492,7 +513,7 @@ class TuneInterface( gtk.EventBox ): stopY = rect.y + rect.height # draw background - pixmap.draw_drawable( self.gc, self.thumbnailBG, startX, startY, startX, startY, rect.width, rect.height+1 ) + pixmap.draw_drawable( self.gc, self.thumbnailBG[self.noteDB.getPage(id).color], startX, startY, startX, startY, rect.width, rect.height+1 ) # draw regular tracks self.gc.foreground = self.lineColor |