Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoramartin <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)
commit146f6eefdb76494a1d8d9b033c64b3a686227225 (patch)
tree89485e3b794411f62e04a8739e312a6f0209f802
parent1a360aa3235c5b661f8eff0f9b57de4816e73d68 (diff)
network
-rw-r--r--Edit/HitInterface.py6
-rw-r--r--Edit/MainWindow.py156
-rw-r--r--Edit/NoteInterface.py13
-rw-r--r--Edit/Properties.py153
-rw-r--r--Edit/TrackInterface.py51
-rw-r--r--Edit/TuneInterface.py31
-rwxr-xr-xResources/Images/pageThumbnailBG0.pngbin0 -> 1147 bytes
-rwxr-xr-xResources/Images/pageThumbnailBG1.pngbin0 -> 1153 bytes
-rwxr-xr-xResources/Images/pageThumbnailBG2.pngbin0 -> 1149 bytes
-rwxr-xr-xResources/Images/pageThumbnailBG3.pngbin0 -> 1147 bytes
-rwxr-xr-xResources/Images/pageThumbnailBut0.pngbin0 -> 898 bytes
-rwxr-xr-xResources/Images/pageThumbnailBut0Down.pngbin0 -> 935 bytes
-rwxr-xr-xResources/Images/pageThumbnailBut1.pngbin0 -> 972 bytes
-rwxr-xr-xResources/Images/pageThumbnailBut1Down.pngbin0 -> 936 bytes
-rwxr-xr-xResources/Images/pageThumbnailBut2.pngbin0 -> 973 bytes
-rwxr-xr-xResources/Images/pageThumbnailBut2Down.pngbin0 -> 943 bytes
-rwxr-xr-xResources/Images/pageThumbnailBut3.pngbin0 -> 977 bytes
-rwxr-xr-xResources/Images/pageThumbnailBut3Down.pngbin0 -> 935 bytes
-rwxr-xr-xResources/Images/propBeats10.pngbin0 -> 1509 bytes
-rwxr-xr-xResources/Images/propBeats11.pngbin0 -> 1342 bytes
-rwxr-xr-xResources/Images/propBeats12.pngbin0 -> 1353 bytes
-rwxr-xr-xResources/Images/propBeats2.pngbin0 -> 1302 bytes
-rwxr-xr-xResources/Images/propBeats3.pngbin0 -> 1349 bytes
-rwxr-xr-xResources/Images/propBeats4.pngbin0 -> 1360 bytes
-rwxr-xr-xResources/Images/propBeats5.pngbin0 -> 1379 bytes
-rwxr-xr-xResources/Images/propBeats6.pngbin0 -> 1372 bytes
-rwxr-xr-xResources/Images/propBeats7.pngbin0 -> 1394 bytes
-rwxr-xr-xResources/Images/propBeats8.pngbin0 -> 1388 bytes
-rwxr-xr-xResources/Images/propBeats9.pngbin0 -> 1399 bytes
-rw-r--r--Util/NoteDB.py64
30 files changed, 331 insertions, 143 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
diff --git a/Resources/Images/pageThumbnailBG0.png b/Resources/Images/pageThumbnailBG0.png
new file mode 100755
index 0000000..5fb3652
--- /dev/null
+++ b/Resources/Images/pageThumbnailBG0.png
Binary files differ
diff --git a/Resources/Images/pageThumbnailBG1.png b/Resources/Images/pageThumbnailBG1.png
new file mode 100755
index 0000000..f60cae5
--- /dev/null
+++ b/Resources/Images/pageThumbnailBG1.png
Binary files differ
diff --git a/Resources/Images/pageThumbnailBG2.png b/Resources/Images/pageThumbnailBG2.png
new file mode 100755
index 0000000..7f2972c
--- /dev/null
+++ b/Resources/Images/pageThumbnailBG2.png
Binary files differ
diff --git a/Resources/Images/pageThumbnailBG3.png b/Resources/Images/pageThumbnailBG3.png
new file mode 100755
index 0000000..61151c5
--- /dev/null
+++ b/Resources/Images/pageThumbnailBG3.png
Binary files differ
diff --git a/Resources/Images/pageThumbnailBut0.png b/Resources/Images/pageThumbnailBut0.png
new file mode 100755
index 0000000..9a455fb
--- /dev/null
+++ b/Resources/Images/pageThumbnailBut0.png
Binary files differ
diff --git a/Resources/Images/pageThumbnailBut0Down.png b/Resources/Images/pageThumbnailBut0Down.png
new file mode 100755
index 0000000..cb376e6
--- /dev/null
+++ b/Resources/Images/pageThumbnailBut0Down.png
Binary files differ
diff --git a/Resources/Images/pageThumbnailBut1.png b/Resources/Images/pageThumbnailBut1.png
new file mode 100755
index 0000000..359830c
--- /dev/null
+++ b/Resources/Images/pageThumbnailBut1.png
Binary files differ
diff --git a/Resources/Images/pageThumbnailBut1Down.png b/Resources/Images/pageThumbnailBut1Down.png
new file mode 100755
index 0000000..81f0f34
--- /dev/null
+++ b/Resources/Images/pageThumbnailBut1Down.png
Binary files differ
diff --git a/Resources/Images/pageThumbnailBut2.png b/Resources/Images/pageThumbnailBut2.png
new file mode 100755
index 0000000..bc03b42
--- /dev/null
+++ b/Resources/Images/pageThumbnailBut2.png
Binary files differ
diff --git a/Resources/Images/pageThumbnailBut2Down.png b/Resources/Images/pageThumbnailBut2Down.png
new file mode 100755
index 0000000..809ebb5
--- /dev/null
+++ b/Resources/Images/pageThumbnailBut2Down.png
Binary files differ
diff --git a/Resources/Images/pageThumbnailBut3.png b/Resources/Images/pageThumbnailBut3.png
new file mode 100755
index 0000000..8eeac0f
--- /dev/null
+++ b/Resources/Images/pageThumbnailBut3.png
Binary files differ
diff --git a/Resources/Images/pageThumbnailBut3Down.png b/Resources/Images/pageThumbnailBut3Down.png
new file mode 100755
index 0000000..d192582
--- /dev/null
+++ b/Resources/Images/pageThumbnailBut3Down.png
Binary files differ
diff --git a/Resources/Images/propBeats10.png b/Resources/Images/propBeats10.png
new file mode 100755
index 0000000..27817c2
--- /dev/null
+++ b/Resources/Images/propBeats10.png
Binary files differ
diff --git a/Resources/Images/propBeats11.png b/Resources/Images/propBeats11.png
new file mode 100755
index 0000000..a36f41b
--- /dev/null
+++ b/Resources/Images/propBeats11.png
Binary files differ
diff --git a/Resources/Images/propBeats12.png b/Resources/Images/propBeats12.png
new file mode 100755
index 0000000..88d594f
--- /dev/null
+++ b/Resources/Images/propBeats12.png
Binary files differ
diff --git a/Resources/Images/propBeats2.png b/Resources/Images/propBeats2.png
new file mode 100755
index 0000000..50c26ba
--- /dev/null
+++ b/Resources/Images/propBeats2.png
Binary files differ
diff --git a/Resources/Images/propBeats3.png b/Resources/Images/propBeats3.png
new file mode 100755
index 0000000..b476d07
--- /dev/null
+++ b/Resources/Images/propBeats3.png
Binary files differ
diff --git a/Resources/Images/propBeats4.png b/Resources/Images/propBeats4.png
new file mode 100755
index 0000000..24210df
--- /dev/null
+++ b/Resources/Images/propBeats4.png
Binary files differ
diff --git a/Resources/Images/propBeats5.png b/Resources/Images/propBeats5.png
new file mode 100755
index 0000000..bb616c4
--- /dev/null
+++ b/Resources/Images/propBeats5.png
Binary files differ
diff --git a/Resources/Images/propBeats6.png b/Resources/Images/propBeats6.png
new file mode 100755
index 0000000..f46184f
--- /dev/null
+++ b/Resources/Images/propBeats6.png
Binary files differ
diff --git a/Resources/Images/propBeats7.png b/Resources/Images/propBeats7.png
new file mode 100755
index 0000000..58ac12c
--- /dev/null
+++ b/Resources/Images/propBeats7.png
Binary files differ
diff --git a/Resources/Images/propBeats8.png b/Resources/Images/propBeats8.png
new file mode 100755
index 0000000..62ce54d
--- /dev/null
+++ b/Resources/Images/propBeats8.png
Binary files differ
diff --git a/Resources/Images/propBeats9.png b/Resources/Images/propBeats9.png
new file mode 100755
index 0000000..1517771
--- /dev/null
+++ b/Resources/Images/propBeats9.png
Binary files differ
diff --git a/Util/NoteDB.py b/Util/NoteDB.py
index 2293cdc..7f3266d 100644
--- a/Util/NoteDB.py
+++ b/Util/NoteDB.py
@@ -2,6 +2,8 @@
import Config
class PARAMETER:
+ PAGE_BEATS, \
+ PAGE_COLOR, \
ONSET, \
PITCH, \
AMPLITUDE, \
@@ -13,7 +15,7 @@ class PARAMETER:
DECAY, \
FILTERTYPE, \
FILTERCUTOFF \
- = range(11) #python-stye enum
+ = range(13) #python-stye enum
class Note:
def __init__( self, page, track, id, cs ):
@@ -23,8 +25,9 @@ class Note:
self.cs = cs
class Page:
- def __init__( self, beats ): # , tempo, insruments, color = 0 ):
+ def __init__( self, beats, color = 0 ): # , tempo, insruments, color = 0 ):
self.beats = beats
+ self.color = color
self.ticks = beats*Config.TICKS_PER_BEAT
self.nextNoteId = 0 # first note will be 1
@@ -48,6 +51,9 @@ class PageListener:
def notifyPageMove( self, which, low, high ):
pass
+ def notifyPageUpdate( self, which, parameter, value ):
+ pass
+
class NoteListener:
def notifyNoteAdd( self, page, track, id ):
pass
@@ -69,6 +75,8 @@ class NoteDB:
self.tune = [] # list of pageIds ordered by tune
+ #self.beatsBefore = {} # count of beats on previous pages indexed by page id
+
self.listeners = [] # complete list of listeners
self.pageListeners = [] # list of listeners who want page notifications
self.noteListeners = [] # list of listeners who want note notifications
@@ -106,6 +114,8 @@ class NoteDB:
pid = self._newPage( pid, page )
at = self._insertPage( pid, after )
+ #self._updateBeatsBefore( at )
+
for l in self.pageListeners:
l.notifyPageAdd( pid, at )
@@ -124,6 +134,8 @@ class NoteDB:
for n in self.noteD[id][t].keys():
self.deleteNote( id, t, n )
+ #del self.beatsBefore[id]
+
del self.noteD[id]
del self.noteS[id]
del self.parasiteD[id]
@@ -136,8 +148,10 @@ class NoteDB:
if not len(self.tune):
self.addPage( -1, Page(beats) ) # always have at least one page
safe = self.tune[0]
+ #self._updateBeatsBefore(0)
else:
safe = self.tune[max(ind-1,0)]
+ #self._updateBeatsBefore(low)
for l in self.pageListeners:
l.notifyPageDelete( which, safe )
@@ -156,11 +170,13 @@ class NoteDB:
new = {}
for cp in sorted:
- id = self._newPage( -1, Page(self.pages[cp].beats) )
+ id = self._newPage( -1, Page(self.pages[cp].beats,self.pages[cp].color) )
self._insertPage( id, after )
after = id
new[cp] = id
+ #self._updateBeatsBefore( first )
+
for l in self.pageListeners:
l.notifyPageDuplicate( new, first )
@@ -190,11 +206,39 @@ class NoteDB:
i += 1
self.tune = self.tune[:at] + sorted + self.tune[at:]
+
+ #self._updateBeatsBefore( low )
for l in self.pageListeners:
l.notifyPageMove( sorted, low, high )
- #-- private --------------------------------------------
+ def updatePage( self, page, parameter, value ):
+ if parameter == PARAMETER.PAGE_BEATS:
+ self.pages[page].beats = value
+ self.pages[page].ticks = value*Config.TICKS_PER_BEAT
+ #self._updateBeatsBefore(self.tune.index(page))
+ elif parameter == PARAMETER.PAGE_COLOR:
+ self.pages[page].color = value
+
+ for l in self.pageListeners:
+ l.notifyPageUpdate( page, parameter, value )
+
+ # stream format:
+ # parameter id
+ # number of following pages (N)
+ # page id
+ # value
+ def updatePages( self, stream ):
+ i = [-1]
+ parameter = self._readstream(stream,i)
+ N = self._readstream(stream,i)
+ for j in range(N):
+ page = self._readstream(stream,i)
+ val = self._readstream(stream,i)
+ self.updatePage( page, parameter, val )
+
+
+ #-- private --------------------------------------------
def _newPage( self, pid, page ):
if pid == -1 : pid = self._genId()
self.pages[pid] = page
@@ -215,6 +259,14 @@ class NoteDB:
return at
+ #def _updateBeatsBefore( self, ind ):
+ # if ind == 0: beats = 0
+ # else: beats = self.beatsBefore[self.tune[ind-1]] + self.pages[self.tune[ind-1]].beats
+ # for i in range(ind, len(self.tune)):
+ # self.beatsBefore[self.tune[ind]] = beats
+ # beats += self.pages[self.tune[ind]].beats
+
+
#=======================================================
# Track Functions
@@ -645,6 +697,10 @@ class NoteDB:
def getPageIndex( self, page ):
return self.tune.index(page)
+ # Not sure if this is useful!
+ #def getBeatsBeforePage( self, page ):
+ # return self.beatsBefore[page]
+
def getNote( self, page, track, id, listener = None ):
if listener:
return self.parasiteD[page][track][listener][id]