Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/Edit
diff options
context:
space:
mode:
authoramartin <olpc@localhost.localdomain>2007-01-31 06:28:53 (GMT)
committer amartin <olpc@localhost.localdomain>2007-01-31 06:28:53 (GMT)
commit46d07b755b7a53610f6b88a98a2e170410668ba3 (patch)
treefe81b1f416db3e1312f4a4d7f63d468c80d2e96e /Edit
parent8f6117e6876047931a035d3058a5b725a720c318 (diff)
NoteDB
Diffstat (limited to 'Edit')
-rw-r--r--[-rwxr-xr-x]Edit/HitInterface.py117
-rw-r--r--Edit/MainWindow.py1074
-rw-r--r--[-rwxr-xr-x]Edit/NoteInterface.py184
-rw-r--r--Edit/TrackInterface.py499
-rw-r--r--Edit/TuneInterface.py248
5 files changed, 808 insertions, 1314 deletions
diff --git a/Edit/HitInterface.py b/Edit/HitInterface.py
index 3eac69f..1301a33 100755..100644
--- a/Edit/HitInterface.py
+++ b/Edit/HitInterface.py
@@ -2,87 +2,62 @@ import pygtk
pygtk.require( '2.0' )
import gtk
+from Util.NoteDB import PARAMETER
from Edit.NoteInterface import NoteInterface
import Config
class HitInterface( NoteInterface ):
- def __init__( self, parent, page, track, note, pitch, onset, duration, amplitude, image, imageSelected, colors ):
- NoteInterface.__init__( self, parent, page, track, note, pitch, onset, duration, amplitude, image, imageSelected, colors )
+ def __init__( self, noteDB, owner, note ):
+ NoteInterface.__init__( self, noteDB, owner, note )
- self.width = self.height = Config.HIT_HEIGHT
+ self.width = self.height = Config.HIT_HEIGHT
self.imgWidth = self.imgHeight = Config.HIT_HEIGHT + Config.HIT_IMAGE_PADDING_MUL2
self.firstTransform = True
self.updateTransform()
- def updateParams( self, pitch, onset, duration, amplitude):
- self.pitch = pitch
- self.onset = onset
- self.duration = duration
- self.end = onset + duration
-
- self.amplitude = amplitude
- r = self.baseColors[0][0] + int(self.baseColors[1][0]*amplitude)
- g = self.baseColors[0][1] + int(self.baseColors[1][1]*amplitude)
- b = self.baseColors[0][2] + int(self.baseColors[1][2]*amplitude)
- self.color = self.parent.drawingArea.get_colormap().alloc_color( r, g, b, True, True )
-
- self.updateTransform()
-
- def getId( self ):
- return self.note
-
- def getStartTick( self ):
- return self.onset
-
- def getEndTick( self ):
- return self.end
-
- def testOnset( self, start, stop ):
- return self.onset >= start and self.onset < stop
-
def updateTransform( self ):
- if self.page == self.parent.curPage and not self.firstTransform:
+ if self.note.page == self.owner.curPage and not self.firstTransform:
oldX = self.imgX
oldY = self.imgY
oldEndX = self.imgX + self.imgWidth
- if self.onset != self.oldOnset:
- self.x = self.parent.ticksToPixels( self.onset )
+ if self.note.cs.onset != self.oldOnset:
+ self.x = self.owner.ticksToPixels( self.noteDB.getPage(self.note.page).beats, self.note.cs.onset )
self.x += self.origin[0]
self.imgX = self.x - Config.NOTE_IMAGE_PADDING
- self.oldOnset = self.onset
- if self.pitch != self.oldPitch:
- self.y = self.parent.pitchToPixelsDrum( self.pitch ) + self.origin[1]
+ self.oldOnset = self.note.cs.onset
+ 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
- self.oldPitch = self.pitch
-
- if self.page == self.parent.curPage:
+ self.oldPitch = self.note.cs.pitch
+
+ if self.note.page == self.owner.curPage:
if self.firstTransform:
- self.parent.invalidate_rect( self.imgX, self.imgY, self.imgWidth, self.imgHeight, self.page )
+ self.owner.invalidate_rect( self.imgX, self.imgY, self.imgWidth, self.imgHeight, self.note.page )
self.firstTransform = False
else:
x = min( self.imgX, oldX )
y = min( self.imgY, oldY )
endx = max( self.imgX + self.imgWidth, oldEndX )
endy = max( self.imgY, oldY ) + self.imgHeight
- self.parent.invalidate_rect( x, y, endx-x, endy-y, self.page )
+ self.owner.invalidate_rect( x, y, endx-x, endy-y, self.note.page )
def updateDragLimits( self, dragLimits, leftBound, rightBound, widthBound, maxRightBound ):
- left = 0 - self.onset
- right = maxRightBound - self.duration - self.onset
- up = Config.MAXIMUM_PITCH_DRUM - self.pitch
- down = Config.MINIMUM_PITCH_DRUM - self.pitch
-
+ left = 0 - self.note.cs.onset
+ right = maxRightBound - self.note.cs.duration - self.note.cs.onset
+ up = Config.MAXIMUM_PITCH_DRUM - self.note.cs.pitch
+ down = Config.MINIMUM_PITCH_DRUM - self.note.cs.pitch
+
if dragLimits[0][0] < left: dragLimits[0][0] = left
if dragLimits[0][1] > right: dragLimits[0][1] = right
if dragLimits[1][0] < down: dragLimits[1][0] = down
if dragLimits[1][1] > up: dragLimits[1][1] = up
-
+
# store the current loc as a reference point
- self.baseOnset = self.onset
- self.basePitch = self.pitch
+ self.baseOnset = self.note.cs.onset
+ self.basePitch = self.note.cs.pitch
#=======================================================
# Events
@@ -97,62 +72,54 @@ class HitInterface( NoteInterface ):
return -1 # event occurs before us, no point in checking further
if eX > self.width:
return 0 # no X overlap
-
+
eY = event.y - self.y
if eY < 0 or eY > self.height:
return 0 # not a hit
-
+
if event.button == 3:
- print "Show some note parameters!?!"
- #self.noteParameters = NoteParametersWindow( self.note, self.getNoteParameters )
+ print "Show some note parameters!?!"
+ #self.noteParameters = NoteParametersWindow( self.note, self.getNoteParameters )
return 1 # handled
if event.type == gtk.gdk._2BUTTON_PRESS: # select bar
self.potentialDeselect = False
start = 0
- check = self.onset - Config.TICKS_PER_BEAT
+ check = self.note.cs.onset - Config.TICKS_PER_BEAT
while start <= check: start += Config.TICKS_PER_BEAT
stop = start + Config.TICKS_PER_BEAT
- check += self.duration
+ check += 1
while stop < check: stop += Config.TICKS_PER_BEAT
- emitter.selectNotesByBar( self.track, start, stop )
+ emitter.selectNotesByBar( self.note.track, start, stop )
elif event.type == gtk.gdk._3BUTTON_PRESS: # select track
self.potentialDeselect = False
- emitter.selectNotesByTrack( self.track )
+ emitter.selectNotesByTrack( self.note.track )
else:
if self.getSelected(): # we already selected, might want to delected
self.potentialDeselect = True
else:
- emitter.selectNotes( { self.track: [ self ] } )
- self.updateSampleNote( self.pitch )
-
+ emitter.selectNotes( { self.note.track: [ self ] } )
+ self.updateSampleNote( self.note.cs.pitch )
+
percent = eX/self.width
if percent < 0.5: emitter.setCurrentAction( "note-drag-onset", self )
else: emitter.setCurrentAction( "note-drag-pitch-drum", self )
-
+
return 1
def noteDrag( self, emitter, do, dp, dd ):
self.potentialDeselect = False
- changed = False
if do != self.lastDragO:
self.lastDragO = do
- self.onset = self.baseOnset + do
- self.end = self.onset + self.duration
- changed = True
+ self.noteDB.updateNote( self.note.page, self.note.track, self.note.id, PARAMETER.ONSET, self.baseOnset + do )
+ self.end = self.note.cs.onset + self.note.cs.duration
if dp != self.lastDragP and not dp%2:
self.lastDragP = dp
newPitch = self.basePitch + dp
- self.pitch = newPitch
+ self.noteDB.updateNote( self.note.page, self.note.track, self.note.id, PARAMETER.PITCH, newPitch )
self.updateSampleNote( newPitch )
- changed = True
-
- self.updateTransform()
-
- if changed: return (self.note, self.pitch, self.onset, self.duration )
- else: return False
# updateTooltip returns:
# -1, event occurs before us so don't bother checking any later notes
@@ -164,15 +131,15 @@ class HitInterface( NoteInterface ):
return -1 # event occurs before us, no point in checking further
if eX > self.width:
return 0 # no X overlap
-
+
eY = event.y - self.y
if eY < 0 or eY > self.height:
return 0 # not a hit
-
+
percent = eX/self.width
if percent < 0.5: emitter.setCursor("drag-onset")
else: emitter.setCursor("drag-pitch")
-
+
return 1 # we handled it
#=======================================================
@@ -190,4 +157,4 @@ class HitInterface( NoteInterface ):
win.draw_pixbuf( gc, img, 0, 0, self.imgX, self.imgY, self.imgWidth, self.imgHeight, gtk.gdk.RGB_DITHER_NONE )
return True # we drew something
-
+
diff --git a/Edit/MainWindow.py b/Edit/MainWindow.py
index 504fecf..f99e62e 100644
--- a/Edit/MainWindow.py
+++ b/Edit/MainWindow.py
@@ -1,6 +1,6 @@
import pygtk
pygtk.require( '2.0' )
-import gtk
+import gtk
import gobject
from Util.ThemeWidgets import *
@@ -17,8 +17,9 @@ import Config
from Edit.MixerWindow import MixerWindow
from Generation.GenerationConstants import GenerationConstants
from Generation.GenerationParametersWindow import GenerationParametersWindow
-from Edit.TrackInterface import TrackInterface
-from Edit.TuneInterface import TuneInterface
+from Util.NoteDB import NoteDB
+from Edit.TrackInterface import TrackInterface, TrackInterfaceParasite
+from Edit.TuneInterface import TuneInterface, TuneInterfaceParasite
from Util.Profiler import TP
@@ -28,9 +29,40 @@ from Generation.Generator import generator1, variate
# The main TamTam window
#-----------------------------------
class MainWindow( gtk.EventBox ):
-
+
def __init__( self, CSoundClient ):
self.csnd = CSoundClient
+
+ def init_data( ):
+ self._data = {}
+
+ #[ volume, ... ]
+ self._data['track_volume'] = [ Config.DEFAULT_VOLUME ] * Config.NUMBER_OF_TRACKS
+ self._data['track_mute'] = [ 1.0 ] * Config.NUMBER_OF_TRACKS
+
+ #[ instrument index, ... ]
+ track_inst = [
+ Config.FLUTE,
+ Config.KOTO,
+ Config.GAM,
+ Config.GUIT,
+ Config.DRUM1KIT ]
+ if len(track_inst) != Config.NUMBER_OF_TRACKS: raise 'error'
+
+ self._data['track_inst'] = track_inst + [Config.FLUTE] * (Config.NUMBER_OF_TRACKS - len( track_inst) )
+ #{ pageId: { [track 0 = note list], [track 2 = note list], ... ] }
+ npages = 40
+ nbeats = 4
+
+ self._data['volume'] = Config.DEFAULT_VOLUME
+ self._data['page_beats'] = [nbeats for p in range(npages)]
+ self._data['tempo'] = Config.PLAYER_TEMPO
+
+ self.trackSelected = [ 0 for i in range(Config.NUMBER_OF_TRACKS) ]
+
+ self.noteDB = NoteDB()
+ self.noteDB.addListener( self, page=True ) # register for page notifications
+
def formatRoundBox( box, fillcolor ):
box.set_radius( 7 )
box.set_border_width( 1 )
@@ -41,426 +73,232 @@ class MainWindow( gtk.EventBox ):
def init_GUI():
self.GUI = {}
self.GUI["2main"] = gtk.HBox()
-
+
def track_menu(trackId, lbl):
instrumentMenuItem = gtk.MenuItem( lbl )
instrumentMenu = gtk.Menu()
instrumentMenuItem.set_submenu( instrumentMenu )
-
+
instrumentNames = [ k for k in Config.INSTRUMENTS.keys() if k[0:4] != 'drum' ] + ['drum1kit']
instrumentNames.sort()
for i in instrumentNames:
menuItem = gtk.MenuItem( i )
menuItem.connect_object( "activate", self.handleInstrumentChanged, ( trackId, i ) )
instrumentMenu.append( menuItem )
-
+
instrumentMenuBar = gtk.MenuBar()
instrumentMenuBar.append( instrumentMenuItem )
return instrumentMenuBar
-
+
#-------------------------------------------------------------------------
# left panel
self.GUI["2leftPanel"] = gtk.VBox()
self.GUI["2leftPanel"].set_size_request( 137, -1 )
- # + instrument panel
- self.GUI["2instrumentPanel"] = gtk.VBox()
- # + + instrument 1 box
- self.GUI["2instrument1Box"] = formatRoundBox( RoundHBox(), "#6C9790" )
- self.GUI["2instrument1Box"].set_size_request( -1, 137 )
- self.GUI["2instrument1volumeAdjustment"] = gtk.Adjustment( self._data["track_volume"][1], 0, 100, 1, 1, 0 )
- self.GUI["2instrument1volumeAdjustment"].connect( "value_changed", self.onTrackVolumeChanged, 0 )
- self.GUI["2instrument1volumeSlider"] = ImageVScale( Config.IMAGE_ROOT+"sliderInst1.png", self.GUI["2instrument1volumeAdjustment"], 6 )
- self.GUI["2instrument1volumeSlider"].set_inverted(True)
- self.GUI["2instrument1volumeSlider"].set_size_request( 30, -1 )
- self.GUI["2instrument1volumeAdjustment"].connect( "value-changed", self.handleTrackVolume, 0 )
- self.GUI["2instrument1Box"].pack_start( self.GUI["2instrument1volumeSlider"], False, False, 0 )
- #self.GUI["2instrument1Button"] = gtk.Button("Inst 1")
- #self.GUI["2instrument1Box"].pack_start( self.GUI["2instrument1Button"] )
- self.GUI["2instrument1Box"].pack_start( track_menu(0,'?') )
- self.GUI["2instrumentPanel"].pack_start( self.GUI["2instrument1Box"] )
- # + + instrument 2 box
- self.GUI["2instrument2Box"] = formatRoundBox( RoundHBox(), "#6C9790" )
- self.GUI["2instrument2Box"].set_size_request( -1, 137 )
- self.GUI["2instrument2volumeAdjustment"] = gtk.Adjustment( self._data["track_volume"][1], 0, 100, 1, 1, 0 )
- self.GUI["2instrument2volumeAdjustment"].connect( "value_changed", self.onTrackVolumeChanged, 1 )
- self.GUI["2instrument2volumeSlider"] = ImageVScale( Config.IMAGE_ROOT+"sliderInst2.png", self.GUI["2instrument2volumeAdjustment"], 6 )
- self.GUI["2instrument2volumeSlider"].set_inverted(True)
- self.GUI["2instrument2volumeSlider"].set_size_request( 30, -1 )
- self.GUI["2instrument2volumeAdjustment"].connect( "value-changed", self.handleTrackVolume, 1 )
- self.GUI["2instrument2Box"].pack_start( self.GUI["2instrument2volumeSlider"], False, False, 0 )
- #self.GUI["2instrument2Button"] = gtk.Button("Inst 2")
- #self.GUI["2instrument2Box"].pack_start( self.GUI["2instrument2Button"] )
- self.GUI["2instrument2Box"].pack_start( track_menu(1,'?') )
- self.GUI["2instrumentPanel"].pack_start( self.GUI["2instrument2Box"] )
- # + + instrument 3 box
- self.GUI["2instrument3Box"] = formatRoundBox( RoundHBox(), "#6C9790" )
- self.GUI["2instrument3Box"].set_size_request( -1, 137 )
- self.GUI["2instrument3volumeAdjustment"] = gtk.Adjustment( self._data["track_volume"][2], 0, 100, 1, 1, 0 )
- self.GUI["2instrument3volumeAdjustment"].connect( "value_changed", self.onTrackVolumeChanged, 2 )
- self.GUI["2instrument3volumeSlider"] = ImageVScale( Config.IMAGE_ROOT+"sliderInst3.png", self.GUI["2instrument3volumeAdjustment"], 6 )
- self.GUI["2instrument3volumeSlider"].set_inverted(True)
- self.GUI["2instrument3volumeSlider"].set_size_request( 30, -1 )
- self.GUI["2instrument3volumeAdjustment"].connect( "value-changed", self.handleTrackVolume, 2 )
- self.GUI["2instrument3Box"].pack_start( self.GUI["2instrument3volumeSlider"], False, False, 0 )
- #self.GUI["2instrument3Button"] = gtk.Button("Inst 3")
- #self.GUI["2instrument3Box"].pack_start( self.GUI["2instrument3Button"] )
- self.GUI["2instrument3Box"].pack_start( track_menu(2,'?') )
- self.GUI["2instrumentPanel"].pack_start( self.GUI["2instrument3Box"] )
- # + + instrument 4 box
- self.GUI["2instrument4Box"] = formatRoundBox( RoundHBox(), "#6C9790" )
- self.GUI["2instrument4Box"].set_size_request( -1, 137 )
- self.GUI["2instrument4volumeAdjustment"] = gtk.Adjustment( self._data["track_volume"][3], 0, 100, 1, 1, 0 )
- self.GUI["2instrument4volumeAdjustment"].connect( "value_changed", self.onTrackVolumeChanged, 3 )
- self.GUI["2instrument4volumeSlider"] = ImageVScale( Config.IMAGE_ROOT+"sliderInst4.png", self.GUI["2instrument4volumeAdjustment"], 6 )
- self.GUI["2instrument4volumeSlider"].set_inverted(True)
- self.GUI["2instrument4volumeSlider"].set_size_request( 30, -1 )
- self.GUI["2instrument4volumeAdjustment"].connect( "value-changed", self.handleTrackVolume, 3 )
- self.GUI["2instrument4Box"].pack_start( self.GUI["2instrument4volumeSlider"], False, False, 0 )
- #self.GUI["2instrument4Button"] = gtk.Button("Inst 4")
- #self.GUI["2instrument4Box"].pack_start( self.GUI["2instrument4Button"] )
- self.GUI["2instrument4Box"].pack_start( track_menu(3,'?') )
- self.GUI["2instrumentPanel"].pack_start( self.GUI["2instrument4Box"] )
- # + + drum box
- self.GUI["2drumBox"] = formatRoundBox( RoundHBox(), "#6C9790" )
- self.GUI["2drumBox"].set_size_request( -1, 165 )
- self.GUI["2drumvolumeAdjustment"] = gtk.Adjustment( self._data["track_volume"][4], 0, 100, 1, 1, 0 )
- self.GUI["2drumvolumeAdjustment"].connect( "value_changed", self.onTrackVolumeChanged, 4 )
- self.GUI["2drumvolumeSlider"] = ImageVScale( Config.IMAGE_ROOT+"sliderDrum.png", self.GUI["2drumvolumeAdjustment"], 6 )
- self.GUI["2drumvolumeSlider"].set_inverted(True)
- self.GUI["2drumvolumeSlider"].set_size_request( 30, -1 )
- self.GUI["2drumvolumeAdjustment"].connect( "value-changed", self.handleTrackVolume, 4 )
- self.GUI["2drumBox"].pack_start( self.GUI["2drumvolumeSlider"], False, False, 0 )
- self.GUI["2drumButton"] = gtk.Button("?")
- self.GUI["2drumBox"].pack_start( self.GUI["2drumButton"] )
- #self.GUI["2instrument1Box"].pack_start( track_menu(4,'?') )
- self.GUI["2instrumentPanel"].pack_start( self.GUI["2drumBox"] )
- self.GUI["2leftPanel"].pack_start( self.GUI["2instrumentPanel"], False )
- # + volume panel
- self.GUI["2volumePanel"] = formatRoundBox( RoundHBox(), "#6C9790" )
- # + + volume box
- self.GUI["2volumeBox"] = gtk.VBox()
- self.GUI["2volumeImage"] = gtk.Image()
- self.GUI["2volumeImage"].set_from_file( Config.IMAGE_ROOT+"volume2.png" )
- self.GUI["2volumeBox"].pack_start( self.GUI["2volumeImage"], False )
- self.GUI["2volumeAdjustment"] = gtk.Adjustment( self._data["volume"], 0, 100, 1, 1, 0 )
- self.GUI["2volumeSlider"] = ImageVScale( Config.IMAGE_ROOT+"sliderEditVolume.png", self.GUI["2volumeAdjustment"], 6 )
- self.GUI["2volumeSlider"].set_inverted(True)
- self.GUI["2volumeAdjustment"].connect( "value-changed", self.handleVolume )
- self.GUI["2volumeBox"].pack_start( self.GUI["2volumeSlider"] )
- self.GUI["2volumePanel"].pack_start( self.GUI["2volumeBox"] )
- # + + tempo box
- self.GUI["2tempoBox"] = gtk.VBox()
- self.GUI["2tempoImage"] = gtk.Image()
- self.GUI["2tempoImage"].set_from_file( Config.IMAGE_ROOT+"tempo3.png" )
- self.GUI["2tempoBox"].pack_start( self.GUI["2tempoImage"], False )
- self.GUI["2tempoAdjustment"] = gtk.Adjustment( self._data["tempo"], 40, 240, 1, 1, 0 )
- self.GUI["2tempoSlider"] = ImageVScale( Config.IMAGE_ROOT+"sliderEditTempo.png", self.GUI["2tempoAdjustment"], 6 )
- self.GUI["2tempoSlider"].set_inverted(True)
- self.GUI["2tempoAdjustment"].connect( "value-changed", self.handleTempo )
- self.GUI["2tempoBox"].pack_start( self.GUI["2tempoSlider"] )
- self.GUI["2volumePanel"].pack_start( self.GUI["2tempoBox"] )
- self.GUI["2leftPanel"].pack_start( self.GUI["2volumePanel"] )
- self.GUI["2main"].pack_start( self.GUI["2leftPanel"], False )
-
+ if 1: # + instrument panel
+ self.GUI["2instrumentPanel"] = gtk.VBox()
+ # + + instrument 1 box
+ self.GUI["2instrument1Box"] = formatRoundBox( RoundHBox(), "#6C9790" )
+ self.GUI["2instrument1Box"].set_size_request( -1, 137 )
+ self.GUI["2instrument1volumeAdjustment"] = gtk.Adjustment( self._data["track_volume"][1], 0, 100, 1, 1, 0 )
+ self.GUI["2instrument1volumeAdjustment"].connect( "value_changed", self.onTrackVolumeChanged, 0 )
+ self.GUI["2instrument1volumeSlider"] = ImageVScale( Config.IMAGE_ROOT+"sliderInst1.png", self.GUI["2instrument1volumeAdjustment"], 6 )
+ self.GUI["2instrument1volumeSlider"].set_inverted(True)
+ self.GUI["2instrument1volumeSlider"].set_size_request( 30, -1 )
+ self.GUI["2instrument1volumeAdjustment"].connect( "value-changed", self.handleTrackVolume, 0 )
+ self.GUI["2instrument1Box"].pack_start( self.GUI["2instrument1volumeSlider"], False, False, 0 )
+ #self.GUI["2instrument1Button"] = gtk.Button("Inst 1")
+ #self.GUI["2instrument1Box"].pack_start( self.GUI["2instrument1Button"] )
+ self.GUI["2instrument1Box"].pack_start( track_menu(0,'?') )
+ self.GUI["2instrumentPanel"].pack_start( self.GUI["2instrument1Box"] )
+ # + + instrument 2 box
+ self.GUI["2instrument2Box"] = formatRoundBox( RoundHBox(), "#6C9790" )
+ self.GUI["2instrument2Box"].set_size_request( -1, 137 )
+ self.GUI["2instrument2volumeAdjustment"] = gtk.Adjustment( self._data["track_volume"][1], 0, 100, 1, 1, 0 )
+ self.GUI["2instrument2volumeAdjustment"].connect( "value_changed", self.onTrackVolumeChanged, 1 )
+ self.GUI["2instrument2volumeSlider"] = ImageVScale( Config.IMAGE_ROOT+"sliderInst2.png", self.GUI["2instrument2volumeAdjustment"], 6 )
+ self.GUI["2instrument2volumeSlider"].set_inverted(True)
+ self.GUI["2instrument2volumeSlider"].set_size_request( 30, -1 )
+ self.GUI["2instrument2volumeAdjustment"].connect( "value-changed", self.handleTrackVolume, 1 )
+ self.GUI["2instrument2Box"].pack_start( self.GUI["2instrument2volumeSlider"], False, False, 0 )
+ #self.GUI["2instrument2Button"] = gtk.Button("Inst 2")
+ #self.GUI["2instrument2Box"].pack_start( self.GUI["2instrument2Button"] )
+ self.GUI["2instrument2Box"].pack_start( track_menu(1,'?') )
+ self.GUI["2instrumentPanel"].pack_start( self.GUI["2instrument2Box"] )
+ # + + instrument 3 box
+ self.GUI["2instrument3Box"] = formatRoundBox( RoundHBox(), "#6C9790" )
+ self.GUI["2instrument3Box"].set_size_request( -1, 137 )
+ self.GUI["2instrument3volumeAdjustment"] = gtk.Adjustment( self._data["track_volume"][2], 0, 100, 1, 1, 0 )
+ self.GUI["2instrument3volumeAdjustment"].connect( "value_changed", self.onTrackVolumeChanged, 2 )
+ self.GUI["2instrument3volumeSlider"] = ImageVScale( Config.IMAGE_ROOT+"sliderInst3.png", self.GUI["2instrument3volumeAdjustment"], 6 )
+ self.GUI["2instrument3volumeSlider"].set_inverted(True)
+ self.GUI["2instrument3volumeSlider"].set_size_request( 30, -1 )
+ self.GUI["2instrument3volumeAdjustment"].connect( "value-changed", self.handleTrackVolume, 2 )
+ self.GUI["2instrument3Box"].pack_start( self.GUI["2instrument3volumeSlider"], False, False, 0 )
+ #self.GUI["2instrument3Button"] = gtk.Button("Inst 3")
+ #self.GUI["2instrument3Box"].pack_start( self.GUI["2instrument3Button"] )
+ self.GUI["2instrument3Box"].pack_start( track_menu(2,'?') )
+ self.GUI["2instrumentPanel"].pack_start( self.GUI["2instrument3Box"] )
+ # + + instrument 4 box
+ self.GUI["2instrument4Box"] = formatRoundBox( RoundHBox(), "#6C9790" )
+ self.GUI["2instrument4Box"].set_size_request( -1, 137 )
+ self.GUI["2instrument4volumeAdjustment"] = gtk.Adjustment( self._data["track_volume"][3], 0, 100, 1, 1, 0 )
+ self.GUI["2instrument4volumeAdjustment"].connect( "value_changed", self.onTrackVolumeChanged, 3 )
+ self.GUI["2instrument4volumeSlider"] = ImageVScale( Config.IMAGE_ROOT+"sliderInst4.png", self.GUI["2instrument4volumeAdjustment"], 6 )
+ self.GUI["2instrument4volumeSlider"].set_inverted(True)
+ self.GUI["2instrument4volumeSlider"].set_size_request( 30, -1 )
+ self.GUI["2instrument4volumeAdjustment"].connect( "value-changed", self.handleTrackVolume, 3 )
+ self.GUI["2instrument4Box"].pack_start( self.GUI["2instrument4volumeSlider"], False, False, 0 )
+ #self.GUI["2instrument4Button"] = gtk.Button("Inst 4")
+ #self.GUI["2instrument4Box"].pack_start( self.GUI["2instrument4Button"] )
+ self.GUI["2instrument4Box"].pack_start( track_menu(3,'?') )
+ self.GUI["2instrumentPanel"].pack_start( self.GUI["2instrument4Box"] )
+ # + + drum box
+ self.GUI["2drumBox"] = formatRoundBox( RoundHBox(), "#6C9790" )
+ self.GUI["2drumBox"].set_size_request( -1, 165 )
+ self.GUI["2drumvolumeAdjustment"] = gtk.Adjustment( self._data["track_volume"][4], 0, 100, 1, 1, 0 )
+ self.GUI["2drumvolumeAdjustment"].connect( "value_changed", self.onTrackVolumeChanged, 4 )
+ self.GUI["2drumvolumeSlider"] = ImageVScale( Config.IMAGE_ROOT+"sliderDrum.png", self.GUI["2drumvolumeAdjustment"], 6 )
+ self.GUI["2drumvolumeSlider"].set_inverted(True)
+ self.GUI["2drumvolumeSlider"].set_size_request( 30, -1 )
+ self.GUI["2drumvolumeAdjustment"].connect( "value-changed", self.handleTrackVolume, 4 )
+ self.GUI["2drumBox"].pack_start( self.GUI["2drumvolumeSlider"], False, False, 0 )
+ self.GUI["2drumButton"] = gtk.Button("?")
+ self.GUI["2drumBox"].pack_start( self.GUI["2drumButton"] )
+ #self.GUI["2instrument1Box"].pack_start( track_menu(4,'?') )
+ self.GUI["2instrumentPanel"].pack_start( self.GUI["2drumBox"] )
+ self.GUI["2leftPanel"].pack_start( self.GUI["2instrumentPanel"], False )
+ # + volume panel
+ self.GUI["2volumePanel"] = formatRoundBox( RoundHBox(), "#6C9790" )
+ # + + volume box
+ self.GUI["2volumeBox"] = gtk.VBox()
+ self.GUI["2volumeImage"] = gtk.Image()
+ self.GUI["2volumeImage"].set_from_file( Config.IMAGE_ROOT+"volume2.png" )
+ self.GUI["2volumeBox"].pack_start( self.GUI["2volumeImage"], False )
+ self.GUI["2volumeAdjustment"] = gtk.Adjustment( self._data["volume"], 0, 100, 1, 1, 0 )
+ self.GUI["2volumeSlider"] = ImageVScale( Config.IMAGE_ROOT+"sliderEditVolume.png", self.GUI["2volumeAdjustment"], 6 )
+ self.GUI["2volumeSlider"].set_inverted(True)
+ self.GUI["2volumeAdjustment"].connect( "value-changed", self.handleVolume )
+ self.GUI["2volumeBox"].pack_start( self.GUI["2volumeSlider"] )
+ self.GUI["2volumePanel"].pack_start( self.GUI["2volumeBox"] )
+ # + + tempo box
+ self.GUI["2tempoBox"] = gtk.VBox()
+ self.GUI["2tempoImage"] = gtk.Image()
+ self.GUI["2tempoImage"].set_from_file( Config.IMAGE_ROOT+"tempo3.png" )
+ self.GUI["2tempoBox"].pack_start( self.GUI["2tempoImage"], False )
+ self.GUI["2tempoAdjustment"] = gtk.Adjustment( self._data["tempo"], 40, 240, 1, 1, 0 )
+ self.GUI["2tempoSlider"] = ImageVScale( Config.IMAGE_ROOT+"sliderEditTempo.png", self.GUI["2tempoAdjustment"], 6 )
+ self.GUI["2tempoSlider"].set_inverted(True)
+ self.GUI["2tempoAdjustment"].connect( "value-changed", self.handleTempo )
+ self.GUI["2tempoBox"].pack_start( self.GUI["2tempoSlider"] )
+ self.GUI["2volumePanel"].pack_start( self.GUI["2tempoBox"] )
+ self.GUI["2leftPanel"].pack_start( self.GUI["2volumePanel"] )
+ self.GUI["2main"].pack_start( self.GUI["2leftPanel"], False )
+
#------------------------------------------------------------------------
# right panel
self.GUI["2rightPanel"] = gtk.VBox()
- # + track interface
- self.trackInterface = TrackInterface( self )
- self.trackInterface.set_size_request( -1, 713 )
- self.GUI["2rightPanel"].pack_start( self.trackInterface, False, False, 0 )
- # + tool panel
- self.GUI["2toolPanel"] = gtk.HBox()
- self.GUI["2toolPanel"].set_size_request( -1, 75 )
- # + + tool box
- self.GUI["2toolBox"] = formatRoundBox( RoundHBox(), "#6C9790" )
- self.GUI["2toolBox"].set_size_request( 146, -1 )
- self.GUI["2toolPointerButton"] = ImageRadioButton( None, Config.IMAGE_ROOT+"pointer.png", Config.IMAGE_ROOT+"pointerDown.png", backgroundFill = "#6C9790" )
- self.GUI["2toolPointerButton"].connect( "clicked", self.handleToolClick , "Default" )
- self.GUI["2toolBox"].pack_start( self.GUI["2toolPointerButton"] )
- self.GUI["2toolPencilButton"] = ImageRadioButton( self.GUI["2toolPointerButton"], Config.IMAGE_ROOT+"pencil.png", Config.IMAGE_ROOT+"pencilDown.png", backgroundFill = "#6C9790" )
- self.GUI["2toolPencilButton"].connect( "clicked", self.handleToolClick , "Draw" )
- self.GUI["2toolBox"].pack_start( self.GUI["2toolPencilButton"] )
- self.GUI["2toolPanel"].pack_start( self.GUI["2toolBox"], False, False )
- self.GUI["2rightPanel"].pack_start( self.GUI["2toolPanel"], False )
- # + + context box (for context sensitive buttons, nothing to do with CAIRO)
- contextWidth = 592
- self.GUI["2contextBox"] = formatRoundBox( RoundFixed(), "#6C9790" )
- self.GUI["2contextBox"].set_size_request( contextWidth, -1 )
- self.GUI["2contextPrevButton"] = gtk.Button("<")
- self.GUI["2contextPrevButton"].connect( "clicked", lambda a1:self.prevContext() )
- self.GUI["2contextBox"].put( self.GUI["2contextPrevButton"], 0, 0 )
- self.GUI["2contextNextButton"] = gtk.Button(">")
- self.GUI["2contextNextButton"].connect( "clicked", lambda a1:self.nextContext() )
- self.GUI["2contextBox"].put( self.GUI["2contextNextButton"], contextWidth-25, 0 )
- # + + + page box
- self.GUI["2pageBox"] = gtk.HBox()
- self.GUI["2pageBox"].set_size_request( contextWidth-50, -1 )
- self.GUI["2pageDeleteButton"] = gtk.Button("Delete")
- self.GUI["2pageDeleteButton"].connect( "clicked", lambda a1:self.removePages() )
- self.GUI["2pageBox"].pack_start( self.GUI["2pageDeleteButton"] )
- self.GUI["2pageNewButton"] = gtk.Button("New")
- self.GUI["2pageNewButton"].connect( "clicked", lambda a1:self.addPage() )
- self.GUI["2pageBox"].pack_start( self.GUI["2pageNewButton"] )
- self.GUI["2pageDuplicateButton"] = gtk.Button("Duplicate")
- self.GUI["2pageDuplicateButton"].connect( "clicked", lambda a1:self.duplicatePages() )
- self.GUI["2pageBox"].pack_start( self.GUI["2pageDuplicateButton"] )
- self.GUI["2contextBox"].put( self.GUI["2pageBox"], 25, 0 )
- # + + + track box
- self.GUI["2trackBox"] = gtk.HBox()
- self.GUI["2trackBox"].set_size_request( contextWidth-50, -1 )
- self.GUI["2trackDeleteButton"] = gtk.Button("tDelete")
- self.GUI["2trackDeleteButton"].connect( "clicked", lambda a1:self.removePages() )
- self.GUI["2trackBox"].pack_start( self.GUI["2trackDeleteButton"] )
- self.GUI["2trackNewButton"] = gtk.Button("tNew")
- self.GUI["2trackNewButton"].connect( "clicked", lambda a1:self.addPage() )
- self.GUI["2trackBox"].pack_start( self.GUI["2trackNewButton"] )
- self.GUI["2trackDuplicateButton"] = gtk.Button("tDuplicate")
- self.GUI["2trackDuplicateButton"].connect( "clicked", lambda a1:self.duplicatePages() )
- self.GUI["2trackBox"].pack_start( self.GUI["2trackDuplicateButton"] )
- self.GUI["2contextBox"].put( self.GUI["2trackBox"], 25, 0 )
- # + + + note box
- self.GUI["2noteBox"] = gtk.HBox()
- self.GUI["2noteBox"].set_size_request( contextWidth-50, -1 )
- self.GUI["2noteDeleteButton"] = gtk.Button("nDelete")
- self.GUI["2noteDeleteButton"].connect( "clicked", lambda a1:self.removePages() )
- self.GUI["2noteBox"].pack_start( self.GUI["2noteDeleteButton"] )
- self.GUI["2noteNewButton"] = gtk.Button("nNew")
- self.GUI["2noteNewButton"].connect( "clicked", lambda a1:self.addPage() )
- self.GUI["2noteBox"].pack_start( self.GUI["2noteNewButton"] )
- self.GUI["2noteDuplicateButton"] = gtk.Button("nDuplicate")
- self.GUI["2noteDuplicateButton"].connect( "clicked", lambda a1:self.duplicatePages() )
- self.GUI["2noteBox"].pack_start( self.GUI["2noteDuplicateButton"] )
- self.GUI["2contextBox"].put( self.GUI["2noteBox"], 25, 0 )
- self.GUI["2toolPanel"].pack_start( self.GUI["2contextBox"], False )
- # + + transport box
- self.GUI["2transportBox"] = formatRoundBox( RoundHBox(), "#6C9790" )
- self.GUI["2generateButton"] = gtk.Button("G")
- self.GUI["2generateButton"].connect( "clicked", self.handleGenerate, None )
- self.GUI["2transportBox"].pack_start( self.GUI["2generateButton"] )
- self.GUI["2recordButton"] = gtk.Button("R")
- self.GUI["2transportBox"].pack_start( self.GUI["2recordButton"] )
- self.GUI["2playButton"] = gtk.ToggleButton("P")
- self.GUI["2playButton"].connect( "toggled", self.handlePlay, "Page Play" )
- self.GUI["2transportBox"].pack_start( self.GUI["2playButton"] )
- self.GUI["2loopButton"] = gtk.Button("L")
- self.GUI["2transportBox"].pack_start( self.GUI["2loopButton"] )
- self.GUI["2toolPanel"].pack_start( self.GUI["2transportBox"] )
- # + tune box
- self.GUI["2tuneBox"] = formatRoundBox( RoundVBox(), "#6C9790" )
- self.GUI["2tuneScrolledWindow"] = gtk.ScrolledWindow()
- self.GUI["2tuneScrolledWindow"].set_policy( gtk.POLICY_ALWAYS, gtk.POLICY_NEVER )
- self.GUI["2tuneScrolledWindow"].set_shadow_type(gtk.SHADOW_NONE)
- self.tuneInterface = TuneInterface( self )
- self.GUI["2tuneScrolledWindow"].add_with_viewport( self.tuneInterface )
- self.GUI["2tuneBox"].pack_start( self.GUI["2tuneScrolledWindow"] )
- self.GUI["2rightPanel"].pack_start( self.GUI["2tuneBox"] )
- self.GUI["2main"].pack_start( self.GUI["2rightPanel"] )
-
+ if 1: # + track interface
+ self.trackInterface = TrackInterface( self.noteDB, self )
+ self.noteDB.addListener( self.trackInterface, TrackInterfaceParasite )
+ self.trackInterface.set_size_request( -1, 713 )
+ self.GUI["2rightPanel"].pack_start( self.trackInterface, False, False, 0 )
+ # + tool panel
+ self.GUI["2toolPanel"] = gtk.HBox()
+ self.GUI["2toolPanel"].set_size_request( -1, 75 )
+ # + + tool box
+ self.GUI["2toolBox"] = formatRoundBox( RoundHBox(), "#6C9790" )
+ self.GUI["2toolBox"].set_size_request( 146, -1 )
+ self.GUI["2toolPointerButton"] = ImageRadioButton( None, Config.IMAGE_ROOT+"pointer.png", Config.IMAGE_ROOT+"pointerDown.png", backgroundFill = "#6C9790" )
+ self.GUI["2toolPointerButton"].connect( "clicked", self.handleToolClick , "Default" )
+ self.GUI["2toolBox"].pack_start( self.GUI["2toolPointerButton"] )
+ self.GUI["2toolPencilButton"] = ImageRadioButton( self.GUI["2toolPointerButton"], Config.IMAGE_ROOT+"pencil.png", Config.IMAGE_ROOT+"pencilDown.png", backgroundFill = "#6C9790" )
+ self.GUI["2toolPencilButton"].connect( "clicked", self.handleToolClick , "Draw" )
+ self.GUI["2toolBox"].pack_start( self.GUI["2toolPencilButton"] )
+ self.GUI["2toolPanel"].pack_start( self.GUI["2toolBox"], False, False )
+ self.GUI["2rightPanel"].pack_start( self.GUI["2toolPanel"], False )
+ # + + context box (for context sensitive buttons, nothing to do with CAIRO)
+ contextWidth = 592
+ self.GUI["2contextBox"] = formatRoundBox( RoundFixed(), "#6C9790" )
+ self.GUI["2contextBox"].set_size_request( contextWidth, -1 )
+ self.GUI["2contextPrevButton"] = gtk.Button("<")
+ self.GUI["2contextPrevButton"].connect( "clicked", lambda a1:self.prevContext() )
+ self.GUI["2contextBox"].put( self.GUI["2contextPrevButton"], 0, 0 )
+ self.GUI["2contextNextButton"] = gtk.Button(">")
+ self.GUI["2contextNextButton"].connect( "clicked", lambda a1:self.nextContext() )
+ self.GUI["2contextBox"].put( self.GUI["2contextNextButton"], contextWidth-25, 0 )
+ # + + + page box
+ self.GUI["2pageBox"] = gtk.HBox()
+ self.GUI["2pageBox"].set_size_request( contextWidth-50, -1 )
+ self.GUI["2pageDeleteButton"] = gtk.Button("Delete")
+ self.GUI["2pageDeleteButton"].connect( "clicked", lambda a1:self.removePages() )
+ self.GUI["2pageBox"].pack_start( self.GUI["2pageDeleteButton"] )
+ self.GUI["2pageNewButton"] = gtk.Button("New")
+ self.GUI["2pageNewButton"].connect( "clicked", lambda a1:self.addPage() )
+ self.GUI["2pageBox"].pack_start( self.GUI["2pageNewButton"] )
+ self.GUI["2pageDuplicateButton"] = gtk.Button("Duplicate")
+ self.GUI["2pageDuplicateButton"].connect( "clicked", lambda a1:self.duplicatePages() )
+ self.GUI["2pageBox"].pack_start( self.GUI["2pageDuplicateButton"] )
+ self.GUI["2contextBox"].put( self.GUI["2pageBox"], 25, 0 )
+ # + + + track box
+ self.GUI["2trackBox"] = gtk.HBox()
+ self.GUI["2trackBox"].set_size_request( contextWidth-50, -1 )
+ self.GUI["2trackDeleteButton"] = gtk.Button("tDelete")
+ self.GUI["2trackDeleteButton"].connect( "clicked", lambda a1:self.removePages() )
+ self.GUI["2trackBox"].pack_start( self.GUI["2trackDeleteButton"] )
+ self.GUI["2trackNewButton"] = gtk.Button("tNew")
+ self.GUI["2trackNewButton"].connect( "clicked", lambda a1:self.addPage() )
+ self.GUI["2trackBox"].pack_start( self.GUI["2trackNewButton"] )
+ self.GUI["2trackDuplicateButton"] = gtk.Button("tDuplicate")
+ self.GUI["2trackDuplicateButton"].connect( "clicked", lambda a1:self.duplicatePages() )
+ self.GUI["2trackBox"].pack_start( self.GUI["2trackDuplicateButton"] )
+ self.GUI["2contextBox"].put( self.GUI["2trackBox"], 25, 0 )
+ # + + + note box
+ self.GUI["2noteBox"] = gtk.HBox()
+ self.GUI["2noteBox"].set_size_request( contextWidth-50, -1 )
+ self.GUI["2noteDeleteButton"] = gtk.Button("nDelete")
+ self.GUI["2noteDeleteButton"].connect( "clicked", lambda a1:self.removePages() )
+ self.GUI["2noteBox"].pack_start( self.GUI["2noteDeleteButton"] )
+ self.GUI["2noteNewButton"] = gtk.Button("nNew")
+ self.GUI["2noteNewButton"].connect( "clicked", lambda a1:self.addPage() )
+ self.GUI["2noteBox"].pack_start( self.GUI["2noteNewButton"] )
+ self.GUI["2noteDuplicateButton"] = gtk.Button("nDuplicate")
+ self.GUI["2noteDuplicateButton"].connect( "clicked", lambda a1:self.duplicatePages() )
+ self.GUI["2noteBox"].pack_start( self.GUI["2noteDuplicateButton"] )
+ self.GUI["2contextBox"].put( self.GUI["2noteBox"], 25, 0 )
+ self.GUI["2toolPanel"].pack_start( self.GUI["2contextBox"], False )
+ # + + transport box
+ self.GUI["2transportBox"] = formatRoundBox( RoundHBox(), "#6C9790" )
+ self.GUI["2generateButton"] = gtk.Button("G")
+ self.GUI["2generateButton"].connect( "clicked", self.handleGenerate, None )
+ self.GUI["2transportBox"].pack_start( self.GUI["2generateButton"] )
+ self.GUI["2recordButton"] = gtk.ToggleButton("R")
+ self.GUI["2transportBox"].pack_start( self.GUI["2recordButton"] )
+ self.GUI["2playButton"] = gtk.ToggleButton("P")
+ self.GUI["2playButton"].connect( "toggled", self.handlePlay, "Page Play" )
+ self.GUI["2transportBox"].pack_start( self.GUI["2playButton"] )
+ self.GUI["2loopButton"] = gtk.Button("L")
+ self.GUI["2transportBox"].pack_start( self.GUI["2loopButton"] )
+ self.GUI["2toolPanel"].pack_start( self.GUI["2transportBox"] )
+ # + tune box
+ self.GUI["2tuneBox"] = formatRoundBox( RoundVBox(), "#6C9790" )
+ self.GUI["2tuneScrolledWindow"] = gtk.ScrolledWindow()
+ self.GUI["2tuneScrolledWindow"].set_policy( gtk.POLICY_ALWAYS, gtk.POLICY_NEVER )
+ self.GUI["2tuneScrolledWindow"].set_shadow_type(gtk.SHADOW_NONE)
+ self.tuneInterface = TuneInterface( self.noteDB, self )
+ self.noteDB.addListener( self.tuneInterface, TuneInterfaceParasite, True )
+ self.GUI["2tuneScrolledWindow"].add_with_viewport( self.tuneInterface )
+ self.GUI["2tuneBox"].pack_start( self.GUI["2tuneScrolledWindow"] )
+ self.GUI["2rightPanel"].pack_start( self.GUI["2tuneBox"] )
+ self.GUI["2main"].pack_start( self.GUI["2rightPanel"] )
+
self.add( self.GUI["2main"] )
-
- self.addPage( 0, 4 ) # yeah! a page!
-
-
- def init_data( ):
- self._data = {}
- #[ volume, ... ]
- self._data['track_volume'] = [ Config.DEFAULT_VOLUME ] * Config.NUMBER_OF_TRACKS
- self._data['track_mute'] = [ 1.0 ] * Config.NUMBER_OF_TRACKS
+ self.generationParametersWindow = GenerationParametersWindow( self.generate, self.variate, self.handleCloseGenerationParametersWindow )
- #[ instrument index, ... ]
- track_inst = [
- Config.FLUTE,
- Config.KOTO,
- Config.GAM,
- Config.GUIT,
- Config.DRUM1KIT ]
- if len(track_inst) != Config.NUMBER_OF_TRACKS: raise 'error'
-
- self._data['track_inst'] = track_inst + [Config.FLUTE] * (Config.NUMBER_OF_TRACKS - len( track_inst) )
- #{ pageId: { [track 0 = note list], [track 2 = note list], ... ] }
- npages = 40
- nbeats = 4
-
- self._data['volume'] = Config.DEFAULT_VOLUME
- self._data['page_beats'] = [nbeats for p in range(npages)]
- self._data['tempo'] = Config.PLAYER_TEMPO
- self._data['tune'] = []
- self._data['notebin'] = []
- self._noteId = {}
- self._noteIdBase = 0
-
- self._data["pages"] = []
- self._pageIdBase = 0
-
- # these helper functions do not
- # run in any particular order....
- # TODO: give these functions better names, put them in execution order, cut hierarchy
-
- def setupGUI( ):
-
- self.volumeFunctions = {}
-
- self.generateParametersWindow = GenerationParametersWindow( self.generate, self.variate, self.handleCloseGenerateWindow )
-
- setupGlobalControls()
- setupPageControls()
- setupTrackControls()
- #setupMainView()
-
- #self.tuneView = TuneView( self.onTuneViewSelect )
- #self.pageBankView = PageBankView( self.onPageBankSelect, self.onPageBankDrop )
-
- self.mainWindowBox = gtk.HBox( False, 5 )
-
- self.globalControlsBox = gtk.VBox( False )
-
- self.fpsText = gtk.Label( "" )
- self.globalControlsBox.pack_start( self.fpsText, False )
- self.globalControlsBox.pack_start( self.globalControlsFrame, True )
-
- self.mainWindowBox.pack_start( self.globalControlsBox, False )
-
-
- controlsBox = gtk.VBox( False, 5 )
- controlsBox.pack_start( self.trackControlsBox, False )
- #TODO: this Label is temporary!!
- controlsBox.pack_start( gtk.Label( "" ), True )
- controlsBox.pack_start( self.pageControlsBox, False )
- self.mainWindowBox.pack_start( controlsBox, False )
-
- self.trackPagesBox = gtk.VBox( False )
- #self.trackPagesBox.pack_start( self.mainView, True )
- #self.trackPagesBox.pack_start( self.tuneView, False )
- #self.trackPagesBox.pack_start( self.pageBankView, False, True, 5 )
-
- self.mainWindowBox.pack_start( self.trackPagesBox )
-
- #self.add( self.mainWindowBox )
-
- # contains TAM-TAM and OLPC labels, as well as the volume and tempo sliders
- def setupGlobalControls( ):
- self.globalControlsFrame = gtk.Frame()
- self.globalControlsFrame.set_shadow_type( gtk.SHADOW_ETCHED_OUT )
-
- self.globalControlsBox = gtk.VBox()
-
- self.tamTamLabel = gtk.Label( " TAM - TAM " )
- self.globalControlsBox.pack_start( self.tamTamLabel )
-
-
- self.beatsPerPageAdjustment = gtk.Adjustment( 4, 1, 8, 1, 1, 0 )
- self.beatsPerPageAdjustment.connect( "value_changed", self.updateNumberOfBars, None )
- self.barsSlider = gtk.VScale( self.beatsPerPageAdjustment )
- self.barsSlider.set_draw_value( False )
- self.barsSlider.set_digits( 0 )
- self.barsSlider.set_inverted( True )
- self.barsSlider.set_increments( 1, 1 )
- self.barsSlider.set_update_policy( gtk.UPDATE_DELAYED )
- #self.mainSlidersBox.pack_start( self.barsSlider )
-
- #self.globalControlsBox.pack_start( self.mainSlidersBox )
-
- self.olpcLabel = gtk.Label( "OLPC" )
- self.globalControlsBox.pack_start( self.olpcLabel )
-
- self.saveButton = gtk.Button("Save")
- self.loadButton = gtk.Button("Open")
-
- fileBox = gtk.HBox()
- fileBox.pack_start( self.saveButton, True )
- fileBox.pack_start( self.loadButton, True )
- self.globalControlsBox.pack_start( fileBox, False )
- self.saveButton.connect("clicked", self.handleSave, None )
- self.loadButton.connect("clicked", self.handleLoad, None )
- self.globalControlsFrame.add( self.globalControlsBox )
-
- def setupPageControls( ):
- self.pageControlsBox = gtk.VBox( False )
-
- self.generateButton = gtk.ToggleButton( "Generate" )
- self.playButton = gtk.ToggleButton( "Play" )
- self.keyboardButton = gtk.ToggleButton( "K" )
- self.keyboardRecordButton = gtk.ToggleButton( "Record" )
-
- self.pageControlsBox.pack_start( self.generateButton, False )
- self.pageControlsBox.pack_start( self.playButton, False )
-
- keyboardBox = gtk.HBox()
- keyboardBox.pack_start( self.keyboardButton, False )
- keyboardBox.pack_start( self.keyboardRecordButton )
- self.pageControlsBox.pack_start( keyboardBox, False )
-
- self.generateButton.connect( "toggled", self.handleGenerate, None )
- self.playButton.connect( "toggled", self.handlePlay, "Page Play" )
- self.keyboardButton.connect( "toggled", self.onKeyboardButton, None )
- self.keyboardRecordButton.connect( "toggled", self.onKeyboardRecordButton, None )
-
- def setupTrackControls( ):
- self.trackControlsBox = gtk.VBox()
- self.instrumentRecordButtons = {}
- for trackId in range( Config.NUMBER_OF_TRACKS):
- trackControlsBox = gtk.HBox()
-
- #setup instrument controls
- instrumentControlsBox = gtk.VBox()
-
- instrumentMenu = gtk.Menu()
- instrumentMenuItem = gtk.MenuItem( "Instrument" )
- instrumentMenuItem.set_submenu( instrumentMenu )
-
- instrumentNames = []
- instrumentFolderNames = Config.INSTRUMENTS.keys()
- for instrumentName in instrumentFolderNames:
- if not instrumentName[0: 4] == 'drum':
- instrumentNames.append( instrumentName )
-
- instrumentNames.append( 'drum1kit' )
- instrumentNames.sort()
- for instrumentName in instrumentNames:
- menuItem = gtk.MenuItem( instrumentName )
- menuItem.connect_object( "activate", self.handleInstrumentChanged, ( trackId, instrumentName ) )
- instrumentMenu.append( menuItem )
-
- instrumentMenuBar = gtk.MenuBar()
- instrumentMenuBar.append( instrumentMenuItem )
- instrumentControlsBox.pack_start( instrumentMenuBar )
-
- recordButton = gtk.Button()
- recordButton.set_size_request( 15, 15 )
- self.instrumentRecordButtons[ trackId ] = recordButton
- instrumentControlsBox.pack_start( recordButton, False )
-
- trackControlsBox.pack_start( instrumentControlsBox )
-
- #setup playback controls
- playbackControlsBox = gtk.VBox()
-
- muteButton = gtk.ToggleButton()
- muteButton.set_size_request( 15, 15 )
- playbackControlsBox.pack_start( muteButton, False )
-
- volumeAdjustment = gtk.Adjustment( 0.8, 0, 1, 0.01, 0.01, 0 )
- volumeAdjustment.connect( "value_changed", self.onTrackVolumeChanged, trackId )
- self.volumeFunctions[ trackId ] = volumeAdjustment.get_value
- volumeSlider = gtk.VScale( volumeAdjustment )
- volumeSlider.set_update_policy( 0 )
- volumeSlider.set_digits( 2 )
- volumeSlider.set_draw_value( False )
- volumeSlider.set_digits( 0 )
- volumeSlider.set_inverted( True )
- playbackControlsBox.pack_start( volumeSlider, True )
-
- trackControlsBox.pack_start( playbackControlsBox )
-
- trackName = "Track %i" % trackId
- muteButton.connect( "toggled", self.onMuteTrack, trackId )
-
- self.trackControlsBox.pack_start( trackControlsBox )
-
+ #===================================================
+ # begin initialization
gtk.EventBox.__init__( self )
-
+
# keyboard variables
self.kb_active = False
self.kb_record = False
@@ -478,27 +316,24 @@ class MainWindow( gtk.EventBox ):
self.fpsFrameCount = 0
self.fpsN = 100 # how many frames to average FPS over
self.fpsLastTime = time.time() # fps will be borked for the first few frames but who cares?
-
+
self.context = -1 # invalidate
self.contextTrackActive = False
self.contextNoteActive = False
init_data() #above
- setupGUI() #above #TEMP
init_GUI() #above
self.csnd.setMasterVolume( self.getVolume() )
-
- #for pageId in range( GUIConfig.NUMBER_OF_PAGE_BANK_ROWS * GUIConfig.NUMBER_OF_PAGE_BANK_COLUMNS ):
- # self.pageBankView.addPage( pageId, False )
-
+
for tid in range(Config.NUMBER_OF_TRACKS):
self.handleInstrumentChanged( ( tid, self._data['track_inst'][tid] ) )
- #self.handleConfigureEvent( None, None ) # needs to come after pages have been added in initialize()
-
+ first = self.noteDB.addPage( 4 )
+ self.displayPage( first )
+
self.show_all() #gtk command
-
+
#self.GUI["2pageBox"].hide()
self.GUI["2trackBox"].hide()
self.GUI["2noteBox"].hide()
@@ -528,15 +363,29 @@ class MainWindow( gtk.EventBox ):
#TODO: check for track activation, to not take all
self.pages_playing = self.tuneInterface.getSelectedIds()
- trackset = set(range(Config.NUMBER_OF_TRACKS))
- pageset = set(self.pages_playing)
- notes = [n for n in self._data['notebin'] if n.pageId in pageset and n.trackId in trackset]
+
+ trackset = set( [ i for i in range(Config.NUMBER_OF_TRACKS) if self.trackSelected[i] ] )
+
+ notes = []
+ if len(trackset) == 0 or len(trackset) == Config.NUMBER_OF_TRACKS:
+ for page in self.pages_playing:
+ notes += self.noteDB.getCSNotesByPage( page )
+ else:
+ for page in self.pages_playing:
+ for track in trackset:
+ notes += self.noteDB.getCSNotesByTrack( page, track )
+
self.playing = True
self.playbackTimeout = gobject.timeout_add( 100, self.onTimeout )
- numticks = sum([self._data["pages"][id]["beats"] for id in self.pages_playing ] ) * Config.TICKS_PER_BEAT
+ if len(self.pages_playing) > 1:
+ self.displayPage( self.pages_playing[0], self.pages_playing[1] )
+ else:
+ self.displayPage( self.pages_playing[0] )
+
+ numticks = sum([self.noteDB.getPage(id).ticks for id in self.pages_playing ] )
print 'play!'
- print 'pageset : ', pageset
+ print 'pages : ', self.pages_playing
print 'trackset : ', trackset
print 'numticks : ', numticks
print 'notes : ', len(notes), 'notes'
@@ -561,20 +410,21 @@ class MainWindow( gtk.EventBox ):
self.playing = False
- self.kb_record = self.playButton.get_active() and self.keyboardRecordButton.get_active() and self.keyboardButton.get_active()
+ self.kb_record = self.GUI["2playButton"].get_active() and self.GUI["2recordButton"].get_active()
def onTimeout(self):
self.updateFPS()
curtick = self.csnd.loopGetTick()
curIdx = curtick / ( 4 * Config.TICKS_PER_BEAT) #TODO handle each pages_playing length
- self.tuneInterface.displayPage( self.pages_playing[curIdx], 0 )
- self.trackInterface.displayPage(self.pages_playing[curIdx], 4 ) #TODO: use page_beats
+ if curIdx + 1 < len(self.pages_playing): predraw = self.pages_playing[curIdx+1]
+ else: predraw = self.pages_playing[0]
+ self.displayPage( self.pages_playing[curIdx], predraw )
return True
def onMuteTrack( self, widget, trackId ):
- self._data['track_mute'][trackId] = not self._data['track_mute'][trackId]
+ self._data['track_mute'][trackId] = not self._data['track_mute'][trackId]
#if self._data['track_mute'][trackId]:
#self.noteLooper.setMute( trackId, 0.0 )
#else:
@@ -584,7 +434,7 @@ class MainWindow( gtk.EventBox ):
v = widget.get_value() / 100.0
self._data['track_volume'][trackId] = v
#self.noteLooper.setVolume( trackId, v )
-
+
# data is tuple ( trackId, instrumentName )
def handleInstrumentChanged( self, data ):
(id, instrumentName) = data
@@ -592,117 +442,69 @@ class MainWindow( gtk.EventBox ):
print id, instrumentName
#self.noteLooper.setInstrument(id, instrumentName)
- recordButton = self.instrumentRecordButtons[ id ]
- if instrumentName in Config.RECORDABLE_INSTRUMENTS:
- recordButton.show()
- recordButton.connect( "clicked",
- self.handleMicRecord,
- Config.RECORDABLE_INSTRUMENT_CSOUND_IDS[ instrumentName ] )
- else:
- recordButton.hide()
+ #recordButton = self.instrumentRecordButtons[ id ]
+ #if instrumentName in Config.RECORDABLE_INSTRUMENTS:
+ # recordButton.show()
+ # recordButton.connect( "clicked",
+ # self.handleMicRecord,
+ # Config.RECORDABLE_INSTRUMENT_CSOUND_IDS[ instrumentName ] )
+ #else:
+ # recordButton.hide()
def handleVolume( self, widget ):
self._data["volume"] = round( widget.get_value() )
self.csnd.setMasterVolume(self._data["volume"])
img = min(3,int(4*self._data["volume"]/100)) # volume 0-3
self.GUI["2volumeImage"].set_from_file( Config.IMAGE_ROOT+"volume"+str(img)+".png" )
-
+
def handleTrackVolume( self, widget, track ):
self._data["track_volume"][track] = round( widget.get_value() )
-
+
def handleTempo( self, widget ):
self._data['tempo'] = round( widget.get_value() )
img = min(7,int(8*(self._data["tempo"]-widget.lower)/(widget.upper-widget.lower)))+1# tempo 1-8
self.GUI["2tempoImage"].set_from_file( Config.IMAGE_ROOT+"tempo"+str(img)+".png" )
-
-
+
+
def handleToolClick( self, widget, mode ):
if widget.get_active(): self.trackInterface.setInterfaceMode( mode )
def onKeyboardButton( self, widget, data ):
self.kb_active = widget.get_active()
-
+
def onKeyboardRecordButton( self, widget, data ):
- if not self.kb_active:
- self.keyboardButton.set_active( True )
-
- self.kb_record = self.playButton.get_active() and self.keyboardRecordButton.get_active()
- def onScoreChange( self, action, noteList ):
- pass
-
- def onNoteDrag( self, dragList ):
- for (id, pitch, onset, duration) in dragList:
- print "ERROR: ignoring note drag"
- return
+ self.kb_record = self.GUI["playButton"].get_active() and self.GUI["2recordButton"].get_active()
#-----------------------------------
# generation functions
#-----------------------------------
def handleGenerate( self, widget, data ):
#if widget.get_active():
- self.generateParametersWindow.show_all()
+ self.generationParametersWindow.show_all()
#else:
- # self.handleCloseGenerateWindow()
-
- def handleCloseGenerateWindow( self, widget = None, data = None ):
- self.generateParametersWindow.hide_all()
+ # self.handleCloseGeneratonParametersWindow()
+
+ def handleCloseGenerationParametersWindow( self, widget = None, data = None ):
+ self.generationParametersWindow.hide_all()
#self.generateButton.set_active( False )
-
- def addNotesToTrackInterface( self, notes ):
- pageList = []
- trackList = []
- noteList = []
- csnoteList = []
- beatList = []
-
- for n in notes:
- pageList.append( n.pageId )
- trackList.append( n.trackId )
- noteList.append( n.noteId )
- csnoteList.append( n )
- beatList.append( p["beats"] for p in self._data["pages"] if p["pageId"] == n.pageId )
-
- self.trackInterface.addNotes(
- { "page":pageList,
- "track":trackList,
- "note":noteList,
- "csnote":csnoteList,
- "beatCount":beatList},
- len(notes) )
-
- def removeNotesFromTrackInterface( self, notes ):
- pageList = []
- trackList = []
- noteList = []
-
- for n in notes:
- pageList.append( n.pageId )
- trackList.append( n.trackId )
- noteList.append( n.noteId )
-
- self.trackInterface.deleteNotes(
- { "page":pageList,
- "track":trackList,
- "note":noteList },
- len(notes) )
-
+
def recompose( self, algo, params):
- def none_to_all(tracks):
- print 'tracks = ',tracks
- if tracks == []: return set(range(0,Config.NUMBER_OF_TRACKS))
- else: return set(tracks)
+ # this seems excessive!?
dict = {}
for t in range(Config.NUMBER_OF_TRACKS):
dict[t] = {}
for p in range(Config.NUMBER_OF_PAGES):
dict[t][p] = []
- newtracks = none_to_all( self.trackInterface.getSelectedTracks())
+ if self.trackSelected == [ 0 for i in range(Config.NUMBER_OF_TRACKS) ]:
+ newtracks = set(range(Config.NUMBER_OF_TRACKS))
+ else:
+ newtracks = set( [ i for i in range(Config.NUMBER_OF_TRACKS) if self.trackSelected[i] ] )
newpages = self.tuneInterface.getSelectedIds()
- algo(
+ algo(
params,
self._data['track_volume'][:],
self._data['track_inst'][:],
@@ -721,166 +523,107 @@ class MainWindow( gtk.EventBox ):
note.pageId = page
note.trackId = track
- #add notes to self._data
+ # add the new notes
newnotes = []
for tid in dict:
for pid in dict[tid]:
newnotes += dict[tid][pid]
- #delete the old pages & tracks!
- togo = [n for n in self._data['notebin'] if (n.trackId in newtracks and n.pageId in newpages) ]
- self.trackInterface.deleteNotes(
- { "page": [n.pageId for n in togo],
- "track":[n.trackId for n in togo] ,
- "note": [n.noteId for n in togo]},
- len(togo))
- self.addNotesToTrackInterface( newnotes )
-
- self._data['notebin'] = [n for n in self._data['notebin'] if not (n.noteId in togo)] + newnotes
+ # delete the notes and add the new
+ stream = []
+ for page in newpages:
+ for track in newtracks:
+ self.noteDB.deleteNotesByTrack( page, track )
+ stream += [ page, track, len(dict[track][page]) ]
+ stream += dict[track][page]
+ stream += [-1]
+ self.noteDB.addNotes( stream )
- self.handleCloseGenerateWindow( None, None )
- #self.handleConfigureEvent( None, None )
+ self.handleCloseGenerationParametersWindow( None, None )
def generate( self, params ):
self.recompose( generator1, params)
def variate( self, params ):
self.recompose( variate, params)
-
+
+ #=======================================================
+ # Track Functions
+
+ def toggleTrack( self, trackN, exclusive ):
+ if exclusive:
+ for i in range(Config.NUMBER_OF_TRACKS):
+ self.trackSelected[i] = False
+ self.trackSelected[trackN] = True
+ self.trackInterface.trackToggled() # invalidate whole page
+ self.setContextState( CONTEXT.TRACK, True )
+ self.setContext( CONTEXT.TRACK )
+ else:
+ self.trackSelected[trackN] = not self.trackSelected[trackN]
+ self.trackInterface.trackToggled( trackN )
+ for i in range(Config.NUMBER_OF_TRACKS):
+ if self.trackSelected[i]:
+ self.setContextState( CONTEXT.TRACK, True )
+ self.setContext( CONTEXT.TRACK )
+ return
+ self.setContextState( CONTEXT.TRACK, False )
+
+ def getTrackSelected( self, trackN ):
+ return self.trackSelected[trackN]
+
+ #=======================================================
+ # NoteDB notifications
+
+ def notifyPageAdd( self, id, at ):
+ self.displayPage( id )
+
+ def notifyPageDelete( self, which, safe ):
+ if self.displayedPage in which:
+ self.displayPage( safe )
+
+ def notifyPageDuplicate( self, new, at ):
+ self.displayPage( new[self.displayedPage] )
+
+ def notifyPageMove( self, which, low, high ):
+ return
+
#-----------------------------------
# tune functions
- #-----------------------------------
-
+ #-----------------------------------
+
def scrollTune( self, scroll ):
adj = self.GUI["2tuneScrolledWindow"].get_hadjustment()
adj.set_value( scroll )
-
- def displayPage( self, pageId, beats = -1 ):
-
- if beats == -1:
- for page in self._data["pages"]:
- if pageId == page["pageId"]: break
- beats = page["beats"]
-
+
+ def displayPage( self, pageId, nextId = -1 ):
+
self.displayedPage = pageId
- self.displayedBeats = beats
-
+
adj = self.GUI["2tuneScrolledWindow"].get_hadjustment()
scroll = self.tuneInterface.displayPage( pageId, adj.get_value() )
if scroll >= 0: adj.set_value(scroll)
-
- self.trackInterface.displayPage( pageId, beats )
-
- def addPage( self, insert = -1, beats = -1 ):
-
- if insert == -1: insert = self.tuneInterface.getLastSelected() + 1
- if beats == -1: beats = self.displayedBeats
-
- pageId = self._pageIdBase
- self._pageIdBase += 1
- while pageId in [ x["pageId"] for x in self._data["pages"] ]:
- pageId = self._pageIdBase
- self._pageIdBase += 1
-
- newpage = { "pageId": pageId, "beats": beats }
- self._data["pages"].insert( insert, newpage )
-
- self.tuneInterface.clearSelection()
- self.tuneInterface.insertPage( pageId, insert )
-
- self.displayPage( pageId, beats )
-
- def duplicatePages( self, insert = -1, pageIds = -1 ):
-
- if insert == -1: insert = self.tuneInterface.getLastSelected() + 1
- if pageIds == -1: pageIds = self.tuneInterface.getSelectedIds()
-
- nextDisplay = -1
- nextBeats = -1
- newpages = []
- for id in pageIds:
- for page in self._data["pages"]:
- if id == page["pageId"]: break
-
- pageId = self._pageIdBase
- self._pageIdBase += 1
- while pageId in [ x["pageId"] for x in self._data["pages"] ]:
- pageId = self._pageIdBase
- self._pageIdBase += 1
-
- if self.displayedPage == id:
- nextDisplay = pageId
- nextBeats = page["beats"]
-
- newnotes = [ n.clone() for n in self._data["notebin"] if n.pageId == id ]
- for n in newnotes: n.pageId = pageId
-
- self._data["notebin"].extend( newnotes )
- self.addNotesToTrackInterface( newnotes )
-
- newpages.append( { "pageId": pageId, "beats": page["beats"] } )
-
- self.tuneInterface.insertPages( [ p["pageId"] for p in newpages ], insert, True, True )
-
- for page in newpages:
- self._data["pages"].insert( insert, page )
- insert += 1
-
- self.displayPage( nextDisplay, nextBeats )
-
+
+ self.trackInterface.displayPage( pageId, nextId )
+
+ def addPage( self, after = -1, beats = False ):
+
+ if after == -1: after = self.tuneInterface.getLastSelected()
+ if not beats: beats = self.noteDB.getPage( self.displayedPage ).beats
+
+ self.noteDB.addPage( beats, after )
+
+ def duplicatePages( self, after = -1, pageIds = False ):
+
+ if after == -1: after = self.tuneInterface.getLastSelected()
+ if not pageIds: pageIds = self.tuneInterface.getSelectedIds()
+
+ self.noteDB.duplicatePages( pageIds, after )
+
def removePages( self, pageIds = -1 ):
-
- if pageIds == -1: pageIds = self.tuneInterface.getSelectedIds()
-
- next = self.tuneInterface.getLastSelected() + 1
- if next == len(self._data["pages"]):
- next -= 2
- while next >= 0 and self._data["pages"][next]["pageId"] in pageIds:
- next -= 1
-
- if next == -1:
- self.addPage()
- else:
- self.tuneInterface.selectPage( self._data["pages"][next]["pageId"], True ) # exclusive select
- self.displayPage( self._data["pages"][next]["pageId"], self._data["pages"][next]["beats"] )
-
- self.tuneInterface.removePages( pageIds )
- self.tuneInterface.selectPage( self._data["pages"][next]["pageId"] )
-
- for id in pageIds:
- for page in self._data["pages"]:
- if id == page["pageId"]: break
-
- self._data["pages"].remove(page)
-
- notes = [ n for n in self._data["notebin"] if n.pageId == id ]
- self.removeNotesFromTrackInterface( notes )
- self._data["notebin"] = [ n for n in self._data["notebin"] if n.pageId != id ]
-
- def movePages( self, insert = -1, pageIds = -1 ):
-
+
if pageIds == -1: pageIds = self.tuneInterface.getSelectedIds()
- if insert == -1: insert = self.tuneInterface.getLastSelected() + 1 - len(pageIds)
-
- for id in pageIds:
- remove = 0
- for page in self._data["pages"]:
- if id == page["pageId"]: break
- remove += 1
-
- self.tuneInterface.movePage( remove, insert )
-
- if remove == insert:
- insert += 1
- continue
- elif remove < insert:
- if remove == insert-1: continue
- insert -= 1
-
- self._data["pages"].pop(remove)
- self._data["pages"].insert( insert, page )
-
- insert += 1
+
+ self.noteDB.deletePages( pageIds )
#-----------------------------------
# load and save functions
@@ -891,12 +634,12 @@ class MainWindow( gtk.EventBox ):
chooser = gtk.FileChooserDialog(title=None,action=gtk.FILE_CHOOSER_ACTION_SAVE, buttons=(gtk.STOCK_CANCEL,gtk.RESPONSE_CANCEL,gtk.STOCK_SAVE,gtk.RESPONSE_OK))
if chooser.run() == gtk.RESPONSE_OK:
- try:
+ try:
print 'INFO: serialize to file %s' % chooser.get_filename()
f = open( chooser.get_filename(), 'w')
pickle.dump( self._data, f )
f.close()
- except IOError:
+ except IOError:
print 'ERROR: failed to serialize to file %s' % chooser.get_filename()
chooser.destroy()
@@ -905,11 +648,11 @@ class MainWindow( gtk.EventBox ):
chooser = gtk.FileChooserDialog(title=None,action=gtk.FILE_CHOOSER_ACTION_OPEN, buttons=(gtk.STOCK_CANCEL,gtk.RESPONSE_CANCEL,gtk.STOCK_OPEN,gtk.RESPONSE_OK))
if chooser.run() == gtk.RESPONSE_OK:
- try:
+ try:
print 'INFO: unserialize from file %s' % chooser.get_filename()
f = open( chooser.get_filename(), 'r')
self._data = pickle.load( f )
- except IOError:
+ except IOError:
print 'ERROR: failed to unserialize from file %s' % chooser.get_filename()
chooser.destroy()
@@ -928,11 +671,11 @@ class MainWindow( gtk.EventBox ):
# callback functions
#-----------------------------------
def onKeyPress(self,widget,event):
-
+
Config.ModKeys.keyPress( event.hardware_keycode )
- key = event.hardware_keycode
-
+ key = event.hardware_keycode
+
if key == 53 and Config.ModKeys.ctrlDown: # q == 53
self.destroy( self )
@@ -940,11 +683,11 @@ class MainWindow( gtk.EventBox ):
return
if self.kb_record:
self.kb_mono = False
-
+
# If the key is already in the dictionnary, exit function (to avoir key repeats)
if self.kb_keydict.has_key(key):
return
- # Assign on which track the note will be created according to the number of keys pressed
+ # Assign on which track the note will be created according to the number of keys pressed
track = len(self.kb_keydict)+10
if self.kb_mono:
track = 10
@@ -958,7 +701,7 @@ class MainWindow( gtk.EventBox ):
# get instrument from top selected track if a track is selected
if self.getSelectedtrackIds():
instrument = self._data['track_inst'][min(self.getSelectedtrackIds())]
-
+
if instrument == 'drum1kit':
if GenerationConfig.DRUMPITCH.has_key( pitch ):
instrument = Config.DRUM1INSTRUMENTS[ GenerationConfig.DRUMPITCH[ pitch ] ]
@@ -966,10 +709,10 @@ class MainWindow( gtk.EventBox ):
instrument = Config.DRUM1INSTRUMENTS[ pitch ]
pitch = 36
duration = 100
-
+
if Config.INSTRUMENTS[instrument].csoundInstrumentID == 102:
duration = 100
-
+
# Create and play the note
self.kb_keydict[key] = CSoundNote(onset = 0,
pitch = pitch,
@@ -981,15 +724,15 @@ class MainWindow( gtk.EventBox ):
instrument = instrument,
instrumentFlag = instrument)
self.kb_keydict[key].playNow()
-
+
def onKeyRelease(self,widget,event):
Config.ModKeys.keyRelease( event.hardware_keycode )
if not self.kb_active:
return
- key = event.hardware_keycode
-
+ key = event.hardware_keycode
+
if KEY_MAP.has_key(key):
self.kb_keydict[key].duration = 0
self.kb_keydict[key].amplitude = 0
@@ -1013,30 +756,7 @@ class MainWindow( gtk.EventBox ):
print TP.PrintAll()
gtk.main_quit()
-
- def updateNumberOfBars( self, widget = None, data = None ):
- self.trackInterface.updateBeatCount( int(round( self.beatsPerPageAdjustment.value)) )
-
- def updateSelection( self ):
- print 'WARNING: wtf is this?'
-
- def updatePage( self ):
- TP.ProfileBegin( "updatePage" )
-
- if self.playingTune:
- self.tuneView.selectPage( self.currentpageId, False )
- self.pageBankView.selectPage(self.pageBankView.NO_PAGE,False)
- else:
- self.tuneView.deselectAll()
- self.tuneView.selectPage(self.tuneView.NO_PAGE,False)
- # temp
- self.trackInterface.displayPage(0,int(round( self.beatsPerPageAdjustment.value)))
-
- self.handleConfigureEvent( None, None )
-
- print TP.ProfileEndAndPrint( "updatePage" )
-
def updateContextNavButtons( self ):
if self.context == CONTEXT.PAGE:
self.GUI["2contextPrevButton"].hide()
@@ -1104,24 +824,6 @@ class MainWindow( gtk.EventBox ):
else:
self.setContext( CONTEXT.NOTE )
-
- # handle resize (TODO: this could probably be done more efficiently)
- #def handleConfigureEvent( self, widget, event ):
- # mainBoxRect = self.trackPagesBox.get_allocation()
-
- #self.tuneView.set_size_request( mainBoxRect.width, GUIConfig.PAGE_HEIGHT +
- # self.tuneView.get_hscrollbar().get_allocation().height + 10 )
- #self.tuneView.show_all()
-
- #self.pageBankView.set_size_request( mainBoxRect.width, GUIConfig.PAGE_HEIGHT * GUIConfig.NUMBER_OF_PAGE_BANK_ROWS )
- #self.pageBankView.show_all()
-
- #mainViewRect = self.mainView.get_allocation()
-
- #self.trackInterface.set_size_request( mainViewRect.width, mainViewRect.height )
-
- #self.trackControlsBox.set_size_request( 100, mainViewRect.height )
-
#-----------------------------------
# access functions (not sure if this is the best way to go about doing this)
#-----------------------------------
diff --git a/Edit/NoteInterface.py b/Edit/NoteInterface.py
index e927444..9dc9e43 100755..100644
--- a/Edit/NoteInterface.py
+++ b/Edit/NoteInterface.py
@@ -4,15 +4,16 @@ import gtk
import Config
+from Util.NoteDB import PARAMETER
+
class NoteInterface:
- def __init__( self, parent, page, track, note, pitch, onset, duration, amplitude, image, imageSelected, colors ):
- self.parent = parent
- self.page = page
- self.track = track
- self.note = note # note id, not csnote!
+ def __init__( self, noteDB, owner, note ):
+ self.noteDB = noteDB
+ self.owner = owner
+ self.note = note
- self.origin = self.parent.getTrackOrigin( self.track )
+ self.origin = self.owner.getTrackOrigin( note.track )
self.firstTransform = True
self.x = 0
self.y = 0
@@ -25,89 +26,86 @@ class NoteInterface:
self.selected = False
self.potentialDeselect = False
-
+
self.oldOnset = -1
self.oldEnd = -1
self.oldPitch = -1
+ self.oldAmplitude = -1
self.lastDragO = 0
self.lastDragP = 0
self.lastDragD = 0
-
- self.image = image
- self.imageSelected = imageSelected
- self.baseColors = colors
- self.updateParams( pitch, onset, duration, amplitude )
+ self.image, self.imageSelected, self.colormap, self.baseColors = self.owner.getDrawingPackage( note.track )
+
+ self.updateParameter( None, None )
def destroy( self ):
- self.parent.invalidate_rect( self.imgX, self.imgY, self.imgWidth, self.imgHeight, self.page, True )
-
- def updateParams( self, pitch, onset, duration, amplitude):
- self.pitch = pitch
- self.onset = onset
- self.duration = duration
- self.end = onset + duration
-
- self.amplitude = amplitude
- r = self.baseColors[0][0] + int(self.baseColors[1][0]*amplitude)
- g = self.baseColors[0][1] + int(self.baseColors[1][1]*amplitude)
- b = self.baseColors[0][2] + int(self.baseColors[1][2]*amplitude)
- self.color = self.parent.drawingArea.get_colormap().alloc_color( r, g, b, True, True )
-
- self.updateTransform()
-
+ self.owner.invalidate_rect( self.imgX, self.imgY, self.imgWidth, self.imgHeight, self.note.page, True )
+
+ def updateParameter( self, parameter, value ):
+ self.end = self.note.cs.onset + self.note.cs.duration
+
+ if self.oldAmplitude != self.note.cs.amplitude:
+ r = self.baseColors[0][0] + int(self.baseColors[1][0]*self.note.cs.amplitude)
+ g = self.baseColors[0][1] + int(self.baseColors[1][1]*self.note.cs.amplitude)
+ b = self.baseColors[0][2] + int(self.baseColors[1][2]*self.note.cs.amplitude)
+ self.color = self.colormap.alloc_color( r, g, b, True, True )
+ self.oldAmplitude = self.note.cs.amplitude
+
+ self.updateTransform()
+
def getId( self ):
- return self.note
+ return self.note.id
def getStartTick( self ):
- return self.onset
+ return self.note.cs.onset
def getEndTick( self ):
- return self.end
+ return self.end
def testOnset( self, start, stop ):
- return self.onset >= start and self.onset < stop
-
+ return self.note.cs.onset >= start and self.note.cs.onset < stop
+
def getPitch( self ):
- return self.pitch
+ return self.note.cs.pitch
def updateTransform( self ):
- if self.page == self.parent.curPage and not self.firstTransform:
+ if self.note.page == self.owner.curPage and not self.firstTransform:
oldX = self.imgX
oldY = self.imgY
oldEndX = self.imgX + self.imgWidth
-
- if self.onset != self.oldOnset:
- self.x = self.parent.ticksToPixels( self.onset )
+
+ if self.note.cs.onset != self.oldOnset:
+ self.x = self.owner.ticksToPixels( self.noteDB.getPage( self.note.page).beats, self.note.cs.onset )
self.x += self.origin[0]
self.imgX = self.x - Config.NOTE_IMAGE_PADDING
- self.oldOnset = self.onset
- if self.end != self.oldEnd or self.onset != self.oldOnset:
- self.width = self.parent.ticksToPixels( self.end ) - self.x - self.origin[0]
+ 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]
self.imgWidth = self.width + Config.NOTE_IMAGE_PADDING_MUL2
self.oldEnd = self.end
- if self.pitch != self.oldPitch:
- self.y = self.parent.pitchToPixels( self.pitch ) + self.origin[1]
+ 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.pitch
-
+ self.oldPitch = self.note.cs.pitch
+
if self.firstTransform:
- self.parent.invalidate_rect( self.imgX, self.imgY, self.imgWidth, self.imgHeight, self.page, True )
+ self.owner.invalidate_rect( self.imgX, self.imgY, self.imgWidth, self.imgHeight, self.note.page, True )
self.firstTransform = False
else:
x = min( self.imgX, oldX )
y = min( self.imgY, oldY )
endx = max( self.imgX + self.imgWidth, oldEndX )
endy = max( self.imgY, oldY ) + self.imgHeight
- self.parent.invalidate_rect( x, y, endx-x, endy-y, self.page, True )
+ self.owner.invalidate_rect( x, y, endx-x, endy-y, self.note.page, True )
def updateDragLimits( self, dragLimits, leftBound, rightBound, widthBound, maxRightBound ):
- left = leftBound - self.onset
- right = rightBound - self.duration - self.onset
- up = Config.MAXIMUM_PITCH - self.pitch
- down = Config.MINIMUM_PITCH - self.pitch
- short = Config.MINIMUM_NOTE_DURATION - self.duration
- long = widthBound - self.duration - self.onset
+ left = leftBound - self.note.cs.onset
+ right = rightBound - self.note.cs.duration - self.note.cs.onset
+ up = Config.MAXIMUM_PITCH - self.note.cs.pitch
+ down = Config.MINIMUM_PITCH - self.note.cs.pitch
+ short = Config.MINIMUM_NOTE_DURATION - self.note.cs.duration
+ long = widthBound - self.note.cs.duration - self.note.cs.onset
if dragLimits[0][0] < left: dragLimits[0][0] = left
if dragLimits[0][1] > right: dragLimits[0][1] = right
@@ -117,9 +115,9 @@ class NoteInterface:
if dragLimits[2][1] > long: dragLimits[2][1] = long
# store the current loc as a reference point
- self.baseOnset = self.onset
- self.basePitch = self.pitch
- self.baseDuration = self.duration
+ self.baseOnset = self.note.cs.onset
+ self.basePitch = self.note.cs.pitch
+ self.baseDuration = self.note.cs.duration
def updateSampleNote( self, pitch ):
return
@@ -141,93 +139,83 @@ class NoteInterface:
return -1 # event occurs before us, no point in checking further
if eX > self.width:
return 0 # no X overlap
-
+
eY = event.y - self.y
if eY < 0 or eY > self.height:
return -2 # not a hit, but it was in our X range
-
+
if event.button == 3:
- print "Show some note parameters!?!"
- #self.noteParameters = NoteParametersWindow( self.note, self.getNoteParameters )
+ print "Show some note parameters!?!"
+ #self.noteParameters = NoteParametersWindow( self.note, self.getNoteParameters )
return 1 # handled
if event.type == gtk.gdk._2BUTTON_PRESS: # select bar
self.potentialDeselect = False
start = 0
- check = self.onset - Config.TICKS_PER_BEAT
+ check = self.note.cs.onset - Config.TICKS_PER_BEAT
while start <= check: start += Config.TICKS_PER_BEAT
stop = start + Config.TICKS_PER_BEAT
- check += self.duration
+ check += self.note.cs.duration
while stop < check: stop += Config.TICKS_PER_BEAT
- emitter.selectNotesByBar( self.track, start, stop )
+ emitter.selectNotesByBar( self.note.track, start, stop )
elif event.type == gtk.gdk._3BUTTON_PRESS: # select track
self.potentialDeselect = False
- emitter.selectNotesByTrack( self.track )
+ emitter.selectNotesByTrack( self.note.track )
else:
- if self.getSelected(): # we already selected, might want to delected
+ if self.selected: # we already selected, might want to delected
self.potentialDeselect = True
else:
- emitter.selectNotes( { self.track: [ self ] } )
- self.updateSampleNote( self.pitch )
-
+ emitter.selectNotes( { self.note.track: [ self ] } )
+ self.updateSampleNote( self.note.cs.pitch )
+
percent = eX/self.width
if percent < 0.3: emitter.setCurrentAction( "note-drag-onset", self )
elif percent > 0.7: emitter.setCurrentAction( "note-drag-duration", self )
else: emitter.setCurrentAction( "note-drag-pitch", self )
-
+
return 1
def handleButtonRelease( self, emitter, event, buttonPressCount ):
if self.potentialDeselect:
self.potentialDeselect = False
- emitter.deselectNotes( { self.track: [ self ] } )
+ emitter.deselectNotes( { self.note.track: [ self ] } )
self.clearSampleNote()
-
+
emitter.doneCurrentAction()
return True
def noteDrag( self, emitter, do, dp, dd ):
self.potentialDeselect = False
- changed = False
if do != self.lastDragO:
self.lastDragO = do
- self.onset = self.baseOnset + do
- self.end = self.onset + self.duration
- changed = True
+ self.noteDB.updateNote( self.note.page, self.note.track, self.note.id, PARAMETER.ONSET, self.baseOnset + do )
+ self.end = self.note.cs.onset + self.note.cs.duration
if dp != self.lastDragP:
self.lastDragP = dp
newPitch = self.basePitch + dp
- self.pitch = newPitch
+ self.noteDB.updateNote( self.note.page, self.note.track, self.note.id, PARAMETER.PITCH, newPitch )
self.updateSampleNote( newPitch )
- changed = True
if dd != self.lastDragD:
self.lastDragD = dd
- self.duration = self.baseDuration + dd
- self.end = self.onset + self.duration
- changed = True
-
- self.updateTransform()
-
- if changed: return (self.note, self.pitch, self.onset, self.duration )
- else: return False
+ self.noteDB.updateNote( self.note.page, self.note.track, self.note.id, PARAMETER.DURATION, self.baseDuration + dd )
+ self.end = self.note.cs.onset + self.note.cs.duration
def doneNoteDrag( self, emitter ):
- self.baseOnset = self.onset
- self.basePitch = self.pitch
- self.baseDuration = self.duration
-
+ self.baseOnset = self.note.cs.onset
+ self.basePitch = self.note.cs.pitch
+ self.baseDuration = self.note.cs.duration
+
self.lastDragO = 0
self.lastDragP = 0
self.lastDragD = 0
self.clearSampleNote()
-
def handleMarqueeSelect( self, emitter, start, stop ):
intersectionY = [ max(start[1],self.y), min(stop[1],self.y+self.height) ]
@@ -239,7 +227,7 @@ class NoteInterface:
return False
return True
-
+
# updateTooltip returns:
# -2, not a hit but there was X overlap
# -1, event occurs before us so don't bother checking any later notes
@@ -251,26 +239,26 @@ class NoteInterface:
return -1 # event occurs before us, no point in checking further
if eX > self.width:
return 0 # no X overlap
-
+
eY = event.y - self.y
if eY < 0 or eY > self.height:
return -2 # not a hit, but it was in our X range
-
+
percent = eX/self.width
if percent < 0.3: emitter.setCursor("drag-onset")
elif percent > 0.7: emitter.setCursor("drag-duration")
else: emitter.setCursor("drag-pitch")
-
+
return 1 # we handled it
#=======================================================
# Selection
-
+
def setSelected( self, state ):
if self.selected != state:
self.selected = state
- if self.page == self.parent.curPage:
- self.parent.invalidate_rect( self.imgX, self.imgY, self.imgWidth, self.imgHeight, self.page )
+ if self.note.page == self.owner.curPage:
+ self.owner.invalidate_rect( self.imgX, self.imgY, self.imgWidth, self.imgHeight, self.note.page )
return True # state changed
return False # state is the same
@@ -293,4 +281,4 @@ class NoteInterface:
win.draw_pixbuf( gc, img, Config.NOTE_IMAGE_TAIL, 0, self.imgX+self.imgWidth-Config.NOTE_IMAGE_ENDLENGTH, self.imgY, Config.NOTE_IMAGE_ENDLENGTH, self.imgHeight, gtk.gdk.RGB_DITHER_NONE )
return True # we drew something
-
+
diff --git a/Edit/TrackInterface.py b/Edit/TrackInterface.py
index da205f4..a3b3986 100644
--- a/Edit/TrackInterface.py
+++ b/Edit/TrackInterface.py
@@ -8,7 +8,6 @@ import Config
from Edit.NoteInterface import NoteInterface
from Edit.HitInterface import HitInterface
from Edit.MainWindow import CONTEXT
-#from GUI.Core.NoteParametersWindow import NoteParametersWindow
from Util.Profiler import TP
@@ -25,37 +24,39 @@ class INTERFACEMODE:
DRAW = 1
PASTE = 2
+class TrackInterfaceParasite:
+ def __init__( self, noteDB, owner, note ):
+ if note.track == Config.NUMBER_OF_TRACKS-1: # drum track
+ self.parasite = HitInterface( noteDB, owner, note )
+ else:
+ self.parasite = NoteInterface( noteDB, owner, note )
+
+ def attach( self ):
+ return self.parasite
+
class TrackInterface( gtk.EventBox ):
-
- def __init__( self, owner ):
+
+ def __init__( self, noteDB, owner ):
gtk.EventBox.__init__( self )
+ self.noteDB = noteDB
self.owner = owner
self.drawingArea = gtk.DrawingArea()
self.drawingAreaDirty = False # are we waiting to draw?
self.add( self.drawingArea )
self.dirtyRectToAdd = gtk.gdk.Rectangle() # used by the invalidate_rect function
-
+
self.fullWidth = 1 # store the maximum allowed width
self.width = 1
self.height = 1
self.interfaceMode = INTERFACEMODE.DEFAULT
-
- self.note = {} # list of pages, tracks, and notes: self.note[pageId][trackId][noteId]
- self.pageBeatCount = {} # keep track of the beat count for each page
- self.pageNoteCount = {} # keep track of how many notes are on a page (so we can get rid of them when they're empty)
- self.noteMap = {} # maps note ids to self.note[p][t][i]s
self.curPage = -1 # this isn't a real page at all!
- self.beatCount = 4
+ self.curBeats = 4
- self.trackSelected = []
- self.selectedNotes = []
- for i in range(0,Config.NUMBER_OF_TRACKS):
- self.trackSelected.insert( 0, False )
- self.selectedNotes.insert( 0, [] )
+ self.selectedNotes = [ [] for i in range(Config.NUMBER_OF_TRACKS) ]
self.curAction = False # stores the current mouse action
self.curActionObject = False # stores the object that in handling the action
@@ -64,7 +65,7 @@ class TrackInterface( gtk.EventBox ):
self.clickLoc = [0,0] # location of the last click
self.marqueeLoc = False # current drag location of the marquee
self.marqueeRect = [[0,0],[0,0]]
-
+
self.playheadX = Config.TRACK_SPACING_DIV2
self.cursor = { \
@@ -79,7 +80,7 @@ class TrackInterface( gtk.EventBox ):
self.add_events(gtk.gdk.POINTER_MOTION_MASK|gtk.gdk.POINTER_MOTION_HINT_MASK)
self.connect( "size-allocate", self.size_allocate )
-
+
self.drawingArea.connect( "expose-event", self.expose )
self.connect( "button-press-event", self.handleButtonPress )
self.connect( "button-release-event", self.handleButtonRelease )
@@ -87,18 +88,18 @@ class TrackInterface( gtk.EventBox ):
# prepare drawing stuff
hexToInt = { "0":0, "1":1, "2":2, "3":3, "4":4, "5":5, "6":6, "7":7, "8":8, "9":9, "A":10, "B":11, "C":12, "D":13, "E":14, "F":15, "a":10, "b":11, "c":12, "d":13, "e":14, "f":15 }
- self.trackColors = []
+ self.trackColors = []
for i in Config.TRACK_COLORS:
low = ( 256*(hexToInt[i[0][1]]*16+hexToInt[i[0][2]]), 256*(hexToInt[i[0][3]]*16+hexToInt[i[0][4]]), 256*(hexToInt[i[0][5]]*16+hexToInt[i[0][6]]) )
high = ( 256*(hexToInt[i[1][1]]*16+hexToInt[i[1][2]]), 256*(hexToInt[i[1][3]]*16+hexToInt[i[1][4]]), 256*(hexToInt[i[1][5]]*16+hexToInt[i[1][6]]) )
delta = ( high[0]-low[0], high[1]-low[1], high[2]-low[2] )
self.trackColors.append( (low, delta) )
-
+
colormap = self.drawingArea.get_colormap()
self.beatColor = colormap.alloc_color( Config.BEAT_COLOR, True, True )
self.playheadColor = colormap.alloc_color( Config.PLAYHEAD_COLOR, True, True )
self.marqueeColor = colormap.alloc_color( Config.MARQUEE_COLOR, True, True )
-
+
self.image = {}
img = gtk.Image()
win = gtk.gdk.get_default_root_window()
@@ -113,7 +114,7 @@ class TrackInterface( gtk.EventBox ):
newimg = gtk.Image()
newimg.set_from_file( Config.IMAGE_ROOT+name+".png" )
self.image[name] = newimg.get_pixbuf()
-
+
prepareDrawable( "trackBG" )
prepareDrawable( "trackBGSelected" )
prepareDrawable( "trackBGDrum" )
@@ -146,112 +147,47 @@ 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.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) ]
+
# screen buffers
self.screenBuf = [ gtk.gdk.Pixmap( win, self.width, self.height ), \
gtk.gdk.Pixmap( win, self.width, self.height ) ]
self.screenBufPage = [ -1, -1 ]
+ self.screenBufBeats = [ -1, -1 ]
self.screenBufDirtyRect = [ gtk.gdk.Rectangle(), gtk.gdk.Rectangle() ]
self.screenBufDirty = [ False, False ]
self.screenBufResume = [ [0,0], [0,0] ] # allows for stopping and restarting in the middle of a draw
self.curScreen = 0
self.preScreen = 1
-
#=======================================================
# Module Interface
- # noteParams: { "page":pagelist, "track":tracklist, "note":noteIDlist }
- def addNotes( self, noteParams, noteCount ):
- at = {}
-
- for i in range(noteCount):
- p = noteParams["page"][i]
- t = noteParams["track"][i]
- if p not in at:
- at[p] = [0] * Config.NUMBER_OF_TRACKS
- if p not in self.note:
- self.note[p] = map(lambda x:[], range(Config.NUMBER_OF_TRACKS))
- self.pageBeatCount[p] = noteParams["beatCount"][i]
- self.pageNoteCount[p] = 0
- csnote = noteParams["csnote"][i]
- if noteParams["track"][i] == self.drumIndex:
- note = HitInterface( self, p, noteParams["track"][i], noteParams["note"][i], \
- csnote.pitch, csnote.onset, csnote.duration, csnote.amplitude, \
- self.image["hit"], self.image["hitSelected"], self.trackColors[noteParams["track"][i]] )
- else:
- note = NoteInterface( self, p, noteParams["track"][i], noteParams["note"][i], \
- csnote.pitch, csnote.onset, csnote.duration, csnote.amplitude, \
- self.image["note"], self.image["noteSelected"], self.trackColors[noteParams["track"][i]] )
- while at[p][t] > 0:
- startT = self.note[p][t][at[p][t]-1].getStartTick()
- if startT <= csnote.onset:
- if startT < csnote.onset: break
- elif self.note[p][t][at[p][t]-1].getPitch <= csnote.pitch: break
- at[p][t] -= 1
- last = len(self.note[p][t])
- while at[p][t] < last:
- startT = self.note[p][t][at[p][t]].getStartTick()
- if startT >= csnote.onset:
- if startT > csnote.onset: break
- elif self.note[p][t][at[p][t]].getPitch >= csnote.pitch: break
- at[p][t] += 1
- self.note[p][t].insert( at[p][t], note )
- self.pageNoteCount[p] += 1
- at[p][t] += 1 # assume the next note will fall after this one
-
- for page in at:
- self.updateNoteMap( page )
-
- # noteParams: { "page":pagelist, "track":tracklist, "note":noteIDlist }
- def updateNotes( self, noteParams, noteCount ):
- for i in range(noteCount):
- p = noteParams["page"][i]
- t = noteParams["track"][i]
- id = noteParams["note"]
- csnote = noteParams["csnote"]
- self.resortNote( p, t, id, csnote.pitch, csnote.onset )
- self.note[p][t][self.noteMap[p][id]].updateParams( csnote.pitch, csnote.onset, csnote.duration, csnote.amplitude )
-
- # noteParams: { "page":pagelist, "track":tracklist, "note":noteIDlist }
- def deleteNotes( self, noteParams, noteCount ):
- modified = {}
- for i in range(noteCount):
- p = noteParams["page"][i]
- t = noteParams["track"][i]
- id = noteParams["note"][i]
- if not p in modified: modified[p] = True
- if p == self.curPage and self.note[p][t][self.noteMap[p][id]].getSelected():
- self.deselectNotes( { t: [ self.note[p][t][self.noteMap[p][id]] ] } )
- self.note[p][t][self.noteMap[p][id]].destroy()
- self.note[p][t][self.noteMap[p][id]] = None # flag for removal
- self.pageNoteCount[p] -= 1
- if self.pageNoteCount[p] == 0:
- del self.note[p]
- del self.pageNoteCount[p]
- del self.noteMap[p]
- del modified[p]
-
- for page in modified:
- for i in range(Config.NUMBER_OF_TRACKS):
- j = len(self.note[page][i])-1
- while j >= 0:
- if self.note[page][i][j] == None: del self.note[page][i][j]
- j -= 1
- self.updateNoteMap( page )
+ def getDrawingPackage( self, track ):
+ if track == self.drumIndex:
+ return ( self.image["hit"], self.image["hitSelected"], self.drawingArea.get_colormap(), self.trackColors[track] )
+ else:
+ return ( self.image["note"], self.image["noteSelected"], self.drawingArea.get_colormap(), self.trackColors[track] )
def predrawPage( self, page ):
if self.screenBufPage[self.preScreen] != page:
self.screenBufPage[self.preScreen] = page
+ self.screenBufBeats[self.preScreen] = self.noteDB.getPage(page).beats
self.invalidate_rect( 0, 0, self.width, self.height, page )
-
- def displayPage( self, page, beatCount, predraw = -1 ):
- if page == self.curPage and self.beatCount == beatCount: return
-
+
+ def displayPage( self, page, predraw = -1 ):
+ if page == self.curPage: return
+
if self.curPage >= 0 and self.curPage != page: clearNotes = True
else: clearNotes = False
-
+
self.curPage = page
-
+ self.curBeats = self.noteDB.getPage(page).beats
+
if self.screenBufPage[self.preScreen] == self.curPage: # we predrew this page, so smart!
t = self.preScreen
self.preScreen = self.curScreen
@@ -259,51 +195,22 @@ class TrackInterface( gtk.EventBox ):
self.invalidate_rect( 0, 0, self.width, self.height, self.curPage, False )
else: # we need to draw this page from scratch
self.screenBufPage[self.curScreen] = self.curPage
+ self.screenBufBeats[self.curScreen] = self.curBeats
self.invalidate_rect( 0, 0, self.width, self.height, self.curPage )
-
+
if predraw >= 0 and self.screenBufPage[self.preScreen] != predraw:
self.screenBufPage[self.preScreen] = predraw
+ self.screenBufBeats[self.preScreen] = self.noteDB.getPage(predraw).beats
self.invalidate_rect( 0, 0, self.width, self.height, predraw )
-
+
if clearNotes: # clear the notes now that we've sorted out the screen buffers
- self.clearSelectedNotes()
-
- if page not in self.note: # create a blank page if the page doesn't already exist
- self.note[page] = []
- for i in range(Config.NUMBER_OF_TRACKS):
- self.note[page].append( [] )
- self.pageBeatCount[page] = beatCount
- self.pageNoteCount[page] = 0
-
- self.updateBeatCount( beatCount )
-
- def updateBeatCount( self, beatCount ):
- self.beatCount = beatCount
-
- self.pixelsPerTick = self.trackWidth//(self.beatCount*Config.TICKS_PER_BEAT)
- self.ticksPerPixel = 1.0/self.pixelsPerTick
- self.beatSpacing = self.pixelsPerTick*Config.TICKS_PER_BEAT
-
- if self.pageBeatCount[self.curPage] != beatCount:
- self.pageBeatCount[self.curPage] = beatCount
- for i in range(Config.NUMBER_OF_TRACKS):
- track = self.note[self.curPage][i]
- map( lambda note:note.updateTransform( True ), track )
-
- if self.window != None:
- self.invalidate_rect( 0, 0, self.fullWidth, self.height, self.curPage )
-
+ self.clearSelectedNotes()
+
def setPlayhead( self, ticks ):
self.invalidate_rect( self.playheadX-Config.PLAYHEAD_SIZE/2, 0, Config.PLAYHEAD_SIZE, self.height, self.curPage, False )
- self.playheadX = self.ticksToPixels( ticks ) + Config.TRACK_SPACING_DIV2
+ self.playheadX = self.ticksToPixels( ticks, self.screenBufBeats[self.curScreen] ) + Config.TRACK_SPACING_DIV2
self.invalidate_rect( self.playheadX-Config.PLAYHEAD_SIZE/2, 0, Config.PLAYHEAD_SIZE, self.height, self.curPage, False )
- def getSelectedTracks( self ):
- r = []
- for i in range( len(self.trackSelected) ):
- if self.trackSelected[i]: r.append( i )
- return r
-
def setInterfaceMode( self, mode ):
if mode == "Draw":
self.interfaceMode = INTERFACEMODE.DRAW
@@ -311,39 +218,6 @@ class TrackInterface( gtk.EventBox ):
self.interfaceMode = INTERFACEMODE.PASTE
else:
self.interfaceMode = INTERFACEMODE.DEFAULT
-
- # private
- def updateNoteMap( self, page ):
- self.noteMap[page] = {}
- for i in range(Config.NUMBER_OF_TRACKS):
- for j in range(len(self.note[page][i])):
- self.noteMap[page][self.note[page][i][j].getId()] = j
-
- def resortNote( self, p, t, id, pitch, onset ):
- ins = out = self.noteMap[p][id]
- while ins > 0: # check backward
- startT = self.note[p][t][ins-1].getStartTick()
- if startT >= onset:
- if startT > onset or self.note[p][t][ins-1].getPitch() < pitch: ins -= 1
- else: break
- else: break
- if ins == out: # check forward
- while ins < len(self.note[p][t])-1:
- startT = self.note[p][t][ins+1].getStartTick()
- if startT <= onset:
- if startT < onset or self.note[p][t][ins+1].getPitch() >= pitch: ins += 1
- else: break
- else: break
- if ins != out: # resort
- if ins > out:
- for j in range( out+1, ins+1 ):
- self.noteMap[p][self.note[p][t][j].getId()] -= 1
- else:
- for j in range( ins, out ):
- self.noteMap[p][self.note[p][t][j].getId()] += 1
- self.noteMap[p][id] = ins
- n = self.note[p][t].pop( out )
- self.note[p][t].insert( ins, n )
#=======================================================
# Event Callbacks
@@ -354,7 +228,7 @@ class TrackInterface( gtk.EventBox ):
height = allocation.height
self.drawingArea.set_size_request( width, height )
-
+
if self.window != None:
self.invalidate_rect( 0, 0, width, height, self.curPage, False )
@@ -367,19 +241,19 @@ class TrackInterface( gtk.EventBox ):
else: self.buttonPressCount = 1
self.clickLoc = [ int(event.x), int(event.y) ]
-
+
# check if we clicked on the playhead
if event.x >= self.playheadX and event.x <= self.playheadX + Config.PLAYHEAD_SIZE:
self.setCurrentAction( "playhead-drag", self )
TP.ProfileEnd( "TI::handleButtonPress" )
- return
+ return
for i in range(Config.NUMBER_OF_TRACKS):
if self.trackLimits[i][0] > event.y: break
if self.trackLimits[i][1] < event.y: continue
-
+
handled = 0
- notes = self.note[self.curPage][i]
+ notes = self.noteDB.getNotesByTrack( self.curPage, i, self )
last = len(notes)-1
for n in range(last+1):
if i == self.drumIndex and n < last: # check to see if the next hit overlaps this one
@@ -394,7 +268,7 @@ class TrackInterface( gtk.EventBox ):
return
else: # all other options mean we can stop looking
break
-
+
if self.interfaceMode == INTERFACEMODE.DRAW:
if handled == -1: # event occured before this note and didn't overlap with the previous note, so we can draw
print "draw a note"
@@ -413,12 +287,12 @@ class TrackInterface( gtk.EventBox ):
if not self.curAction: #do track selection stuff here so that we can also handle marquee selection
for i in range(Config.NUMBER_OF_TRACKS):
if self.trackLimits[i][0] > event.y: break
- if self.trackLimits[i][1] < event.y: continue
+ if self.trackLimits[i][1] < event.y: continue
if event.button == 1:
- if self.buttonPressCount == 1: self.toggleTrack( i, False )
- else: self.toggleTrack( i, True )
+ if self.buttonPressCount == 1: self.owner.toggleTrack( i, False )
+ else: self.owner.toggleTrack( i, True )
break
-
+
TP.ProfileEnd( "TI::handleButtonRelease" )
return
@@ -451,37 +325,37 @@ class TrackInterface( gtk.EventBox ):
event.state = state
TP.ProfileEnd( "TI::handleMotion::Common" )
-
+
if event.state & gtk.gdk.BUTTON1_MASK:
TP.ProfileBegin( "TI::handleMotion::Drag" )
-
+
if not self.curAction: # no action is in progress yet we're dragging, start a marquee
self.setCurrentAction( "marquee", self )
- if self.curAction == "note-drag-onset":
+ if self.curAction == "note-drag-onset":
self.noteDragOnset( event )
- elif self.curAction == "note-drag-duration":
+ elif self.curAction == "note-drag-duration":
self.noteDragDuration( event )
- elif self.curAction == "note-drag-pitch":
+ elif self.curAction == "note-drag-pitch":
self.noteDragPitch( event )
-
+
elif self.curAction == "note-drag-pitch-drum":
self.noteDragPitch( event, True )
- elif self.curAction == "marquee":
+ elif self.curAction == "marquee":
self.updateMarquee( event )
-
+
elif self.curAction == "playhead-drag":
self.updatePlayhead( event )
-
+
TP.ProfileEnd( "TI::handleMotion::Drag" )
else:
TP.ProfileBegin( "TI::handleMotion::Hover" )
self.updateTooltip( event )
TP.ProfileEnd( "TI::handleMotion::Hover" )
-
+
return
#=======================================================
@@ -508,23 +382,9 @@ class TrackInterface( gtk.EventBox ):
self.curAction = False
self.curActionObject = False
- def toggleTrack( self, trackN, exclusive ):
- if exclusive:
- for i in range(Config.NUMBER_OF_TRACKS):
- self.trackSelected[i] = False
- self.trackSelected[trackN] = True
- self.invalidate_rect( 0, 0, self.width, self.height, self.curPage )
- self.owner.setContextState( CONTEXT.TRACK, True )
- self.owner.setContext( CONTEXT.TRACK )
- else:
- self.trackSelected[trackN] = not self.trackSelected[trackN]
- self.invalidate_rect( 0, self.trackLimits[trackN][0], self.width, self.trackLimits[trackN][1]-self.trackLimits[trackN][0], self.curPage )
- for i in range(Config.NUMBER_OF_TRACKS):
- if self.trackSelected[i]:
- self.owner.setContextState( CONTEXT.TRACK, True )
- self.owner.setContext( CONTEXT.TRACK )
- return
- self.owner.setContextState( CONTEXT.TRACK, False )
+ def trackToggled( self, trackN = -1 ):
+ if trackN == -1: self.invalidate_rect( 0, 0, self.width, self.height, self.curPage )
+ else: self.invalidate_rect( 0, self.trackLimits[trackN][0], self.width, self.trackLimits[trackN][1]-self.trackLimits[trackN][0], self.curPage )
def selectionChanged( self ):
if self.curAction == "note-drag-onset": self.updateDragLimits()
@@ -538,24 +398,22 @@ class TrackInterface( gtk.EventBox ):
return
self.owner.setContextState( CONTEXT.NOTE, False )
-
def applyNoteSelection( self, mode, trackN, which ):
if mode == SELECTNOTES.ALL:
- track = self.note[self.curPage][trackN]
+ track = self.noteDB.getNotesByTrack( self.curPage, trackN, self )
map( lambda note:note.setSelected( True ), track )
self.selectedNotes[trackN] = []
map( lambda note:self.selectedNotes[trackN].append(note), track )
elif mode == SELECTNOTES.NONE:
- if self.note.has_key(self.curPage):
- track = self.note[self.curPage][trackN]
- map( lambda note:note.setSelected( False ), track )
+ track = self.noteDB.getNotesByTrack( self.curPage, trackN, self )
+ map( lambda note:note.setSelected( False ), track )
self.selectedNotes[trackN] = []
elif mode == SELECTNOTES.ADD:
- for note in which:
- if note.setSelected( True ):
+ for note in which:
+ if note.setSelected( True ):
self.selectedNotes[trackN].append( note )
elif mode == SELECTNOTES.REMOVE:
- for note in which:
+ for note in which:
if note.setSelected( False ):
self.selectedNotes[trackN].remove( note )
elif mode == SELECTNOTES.FLIP:
@@ -567,28 +425,28 @@ class TrackInterface( gtk.EventBox ):
note.setSelected( True )
self.selectedNotes[trackN].append( note )
elif mode == SELECTNOTES.EXCLUSIVE:
- notes = self.note[self.curPage][trackN]
+ notes = self.noteDB.getNotesByTrack( self.curPage, trackN, self )
for n in range(len(notes)):
- if notes[n] in which:
+ if notes[n] in which:
if notes[n].setSelected( True ):
self.selectedNotes[trackN].append( notes[n] )
- else:
+ else:
if notes[n].setSelected( False ):
self.selectedNotes[trackN].remove( notes[n] )
def selectNotesByBar( self, trackN, start, stop ):
for i in range(Config.NUMBER_OF_TRACKS):
- if i == trackN:
+ if i == trackN:
notes = []
- track = self.note[self.curPage][trackN]
+ track = self.noteDB.getNotesByTrack( self.curPage, trackN, self )
for n in range(len(track)):
if track[n].testOnset( start, stop ): notes.append(track[n])
if not Config.ModKeys.ctrlDown: self.applyNoteSelection( SELECTNOTES.EXCLUSIVE, trackN, notes )
- else: self.applyNoteSelection( SELECTNOTES.ADD, trackN, notes )
+ else: self.applyNoteSelection( SELECTNOTES.ADD, trackN, notes )
else:
if not Config.ModKeys.ctrlDown: self.applyNoteSelection( SELECTNOTES.NONE, i, [] )
self.selectionChanged()
-
+
def selectNotesByTrack( self, trackN ):
if Config.ModKeys.ctrlDown:
self.applyNoteSelection( SELECTNOTES.ALL, trackN, [] )
@@ -609,7 +467,7 @@ class TrackInterface( gtk.EventBox ):
self.selectionChanged()
def deselectNotes( self, noteDic ):
- for i in noteDic:
+ for i in noteDic:
self.applyNoteSelection( SELECTNOTES.REMOVE, i, noteDic[i] )
self.selectionChanged()
@@ -620,12 +478,12 @@ class TrackInterface( gtk.EventBox ):
def updateDragLimits( self ):
self.dragLimits = [ [-9999,9999], [-9999,9999], [-9999,9999] ] # initialize to big numbers!
- maxRightBound = self.beatCount * Config.TICKS_PER_BEAT
-
+ maxRightBound = self.curBeats * Config.TICKS_PER_BEAT
+
for i in range(Config.NUMBER_OF_TRACKS):
if not len(self.selectedNotes[i]): continue # no selected notes here
- track = self.note[self.curPage][i]
+ track = self.noteDB.getNotesByTrack( self.curPage, i, self )
leftBound = 0
skip = True # skip the first note
for n in range(len(track)):
@@ -634,10 +492,10 @@ class TrackInterface( gtk.EventBox ):
thisNote = track[n]
continue
nextNote = track[n]
- if not thisNote.getSelected():
+ if not thisNote.getSelected():
leftBound = thisNote.getEndTick()
else:
- if not nextNote.getSelected():
+ if not nextNote.getSelected():
rightBound = min( nextNote.getStartTick(), maxRightBound )
widthBound = rightBound
else:
@@ -646,37 +504,29 @@ class TrackInterface( gtk.EventBox ):
thisNote.updateDragLimits( self.dragLimits, leftBound, rightBound, widthBound, maxRightBound )
thisNote = nextNote
# do the last note
- if thisNote.getSelected():
+ if thisNote.getSelected():
thisNote.updateDragLimits( self.dragLimits, leftBound, maxRightBound, maxRightBound, maxRightBound )
def noteDragOnset( self, event ):
- do = self.pixelsToTicks( event.x - self.clickLoc[0] )
+ do = self.pixelsToTicks( self.curBeats, event.x - self.clickLoc[0] )
do = min( self.dragLimits[0][1], max( self.dragLimits[0][0], do ) )
dp = 0
dd = 0
-
+
for i in range(Config.NUMBER_OF_TRACKS):
- changed = []
for note in self.selectedNotes[i]:
- ret = note.noteDrag(self, do, dp, dd)
- if ret:
- if i == self.drumIndex: self.resortNote( self.curPage, i, ret[0], ret[1], ret[2] )
- changed += [ret]
- if len(changed): self.owner.onNoteDrag( changed )
+ note.noteDrag(self, do, dp, dd)
def noteDragDuration( self, event ):
do = 0
dp = 0
- dd = self.pixelsToTicks( event.x - self.clickLoc[0] )
+ dd = self.pixelsToTicks( self.curBeats, event.x - self.clickLoc[0] )
dd = min( self.dragLimits[2][1], max( self.dragLimits[2][0], dd ) )
for i in range(Config.NUMBER_OF_TRACKS):
- changed = []
for note in self.selectedNotes[i]:
- ret = note.noteDrag(self, do, dp, dd)
- if ret: changed += [ret]
- self.owner.onNoteDrag( changed )
-
+ note.noteDrag(self, do, dp, dd)
+
def noteDragPitch( self, event, drum = False ):
do = 0
if not drum: dp = self.pixelsToPitch( event.y - self.clickLoc[1] )
@@ -685,13 +535,8 @@ class TrackInterface( gtk.EventBox ):
dd = 0
for i in range(Config.NUMBER_OF_TRACKS):
- changed = []
for note in self.selectedNotes[i]:
- ret = note.noteDrag(self, do, dp, dd)
- if ret:
- if i == self.drumIndex: self.resortNote( self.curPage, i, ret[0], ret[1], ret[2] )
- changed += [ret]
- self.owner.onNoteDrag( changed )
+ note.noteDrag(self, do, dp, dd)
def doneNoteDrag( self ):
for i in range(Config.NUMBER_OF_TRACKS):
@@ -708,7 +553,7 @@ class TrackInterface( gtk.EventBox ):
oldX = oldEndX = self.clickLoc[0]
oldY = oldEndY = self.clickLoc[1]
- self.marqueeLoc = [ int(event.x), int(event.y) ]
+ self.marqueeLoc = [ int(event.x), int(event.y) ]
if self.marqueeLoc[0] < 0: self.marqueeLoc[0] = 0
elif self.marqueeLoc[0] > self.width: self.marqueeLoc[0] = self.width
if self.marqueeLoc[1] < 0: self.marqueeLoc[1] = 0
@@ -726,90 +571,89 @@ class TrackInterface( gtk.EventBox ):
else:
self.marqueeRect[0][1] = self.marqueeLoc[1]
self.marqueeRect[1][1] = self.clickLoc[1] - self.marqueeLoc[1]
-
+
x = min( self.marqueeRect[0][0], oldX )
width = max( self.marqueeRect[0][0] + self.marqueeRect[1][0], oldEndX ) - x
y = min( self.marqueeRect[0][1], oldY )
height = max( self.marqueeRect[0][1] + self.marqueeRect[1][1], oldEndY ) - y
self.invalidate_rect( x-1, y-1, width+2, height+2, self.curPage, False )
- def doneMarquee( self, event ):
+ def doneMarquee( self, event ):
if self.marqueeLoc:
stop = [ self.marqueeRect[0][0] + self.marqueeRect[1][0], self.marqueeRect[0][1] + self.marqueeRect[1][1] ]
select = {}
-
+
for i in range(Config.NUMBER_OF_TRACKS):
intersectionY = [ max(self.marqueeRect[0][1],self.trackLimits[i][0]), min(stop[1],self.trackLimits[i][1]) ]
if intersectionY[0] > intersectionY[1]:
continue
-
+
notes = []
- track = self.note[self.curPage][i]
+ track = self.noteDB.getNotesByTrack( self.curPage, i, self )
for n in range(len(track)):
- hit = track[n].handleMarqueeSelect( self,
+ hit = track[n].handleMarqueeSelect( self,
[ self.marqueeRect[0][0], intersectionY[0] ], \
- [ stop[0], intersectionY[1] ] )
+ [ stop[0], intersectionY[1] ] )
if hit: notes.append(track[n])
if len(notes): select[i] = notes
-
+
self.selectNotes( select )
- self.marqueeLoc = False
+ self.marqueeLoc = False
self.doneCurrentAction()
-
+
self.invalidate_rect( self.marqueeRect[0][0]-1, self.marqueeRect[0][1]-1, self.marqueeRect[1][0]+2, self.marqueeRect[1][1]+2, self.curPage, False )
-
+
def updatePlayhead( self, event ):
- x = min( self.trackWidth - self.pixelsPerTick, max( Config.TRACK_SPACING_DIV2, event.x ) )
- self.setPlayhead( self.pixelsToTicks( x ) )
-
-
+ x = min( self.trackWidth - self.pixelsPerTick[self.curBeats], max( Config.TRACK_SPACING_DIV2, event.x ) )
+ self.setPlayhead( self.pixelsToTicks( self.curBeats, x ) )
+
def donePlayhead( self, event ):
- x = min( self.trackWidth - self.pixelsPerTick, max( Config.TRACK_SPACING_DIV2, event.x ) )
- ticks = self.pixelsToTicks( x )
- print "set playhead to %d ticks" % (ticks)
+ x = min( self.trackWidth - self.pixelsPerTick[self.curBeats], max( Config.TRACK_SPACING_DIV2, event.x ) )
+ ticks = self.pixelsToTicks( self.curBeats, x )
+ print "set playhead to %d ticks" % (ticks)
self.doneCurrentAction()
-
+
def updateTooltip( self, event ):
-
+
# check clicked the playhead
if event.x >= self.playheadX and event.x <= self.playheadX + Config.PLAYHEAD_SIZE:
self.setCursor("drag-playhead")
- return
-
+ return
+
for i in range(Config.NUMBER_OF_TRACKS):
if self.trackLimits[i][0] > event.y: break
if self.trackLimits[i][1] < event.y: continue
-
- notes = self.note[self.curPage][i]
+
+ notes = self.noteDB.getNotesByTrack( self.curPage, i, self )
handled = 0
for n in range(len(notes)):
handled = notes[n].updateTooltip( self, event )
if handled == 0: continue
elif handled == 1: return # event was handled
else: break
-
+
# note wasn't handled, could potentially draw a note
if self.interfaceMode == INTERFACEMODE.DRAW:
if handled == -2: # event X overlapped with a note
self.setCursor("default")
return
-
+
self.setCursor("pencil")
return
-
+
break
-
+
self.setCursor("default")
-
+
def setCursor( self, cursor ):
self.window.set_cursor(self.cursor[cursor])
-
+
#=======================================================
# Drawing
-
+
def predraw( self, buf, noescape = True ):
TP.ProfileBegin( "TrackInterface::predraw" )
@@ -818,12 +662,16 @@ class TrackInterface( gtk.EventBox ):
stopX = self.screenBufDirtyRect[buf].x + self.screenBufDirtyRect[buf].width
stopY = self.screenBufDirtyRect[buf].y + self.screenBufDirtyRect[buf].height
+ beatStart = Config.TRACK_SPACING_DIV2
+ beats = self.screenBufBeats[buf]
+ beatSpacing = self.beatSpacing[beats]
+
pixmap = self.screenBuf[buf]
resume = self.screenBufResume[buf]
self.gc.set_clip_rectangle( self.screenBufDirtyRect[buf] )
-
+
self.gc.set_line_attributes( Config.BEAT_LINE_SIZE, gtk.gdk.LINE_ON_OFF_DASH, gtk.gdk.CAP_BUTT, gtk.gdk.JOIN_MITER )
# regular tracks
for i in range( resume[0], self.drumIndex ):
@@ -832,21 +680,20 @@ class TrackInterface( gtk.EventBox ):
if stopY < self.trackLimits[i][0]: break
# draw background
- if self.trackSelected[i]:
+ if self.owner.getTrackSelected( i ):
pixmap.draw_drawable( self.gc, self.image["trackBGSelected"], 0, 0, 0, self.trackLimits[i][0], self.trackFullWidth, self.trackFullHeight )
else:
pixmap.draw_drawable( self.gc, self.image["trackBG"], 0, 0, 0, self.trackLimits[i][0], self.trackFullWidth, self.trackFullHeight )
-
+
# draw beat lines
self.gc.foreground = self.beatColor
- beatStart = Config.TRACK_SPACING_DIV2
- for j in range(1,self.beatCount):
- x = beatStart + j*self.beatSpacing
+ for j in range(1,self.screenBufBeats[buf]):
+ x = beatStart + j*beatSpacing
pixmap.draw_line( self.gc, x, self.trackRect[i].y, x, self.trackRect[i].y+self.trackRect[i].height )
-
+
# draw notes
TP.ProfileBegin("TI::draw notes")
- notes = self.note[self.curPage][i]
+ notes = self.noteDB.getNotesByTrack( self.curPage, i, self )
for n in range( resume[1], len(notes) ):
# check escape
if 0:
@@ -854,33 +701,32 @@ class TrackInterface( gtk.EventBox ):
resume[1] = n
TP.ProfilePause( "TrackInterface::predraw" )
return False
-
+
if not notes[n].draw( pixmap, self.gc, startX, stopX ): break
TP.ProfileEnd("TI::draw notes")
# finished a track, reset the resume values for the next one
resume[0] = 0
- resume[1] = 0
-
+ resume[1] = 0
+
# drum track
if stopY > self.trackLimits[self.drumIndex][0]:
-
- if resume[0] == 0:
+
+ if resume[0] == 0:
# draw background
- if self.trackSelected[self.drumIndex]:
+ if self.owner.getTrackSelected( self.drumIndex ):
pixmap.draw_drawable( self.gc, self.image["trackBGDrumSelected"], 0, 0, 0, self.trackLimits[self.drumIndex][0], self.trackFullWidth, self.trackFullHeightDrum )
else:
pixmap.draw_drawable( self.gc, self.image["trackBGDrum"], 0, 0, 0, self.trackLimits[self.drumIndex][0], self.trackFullWidth, self.trackFullHeightDrum )
-
+
# draw beat lines
self.gc.foreground = self.beatColor
- beatStart = Config.TRACK_SPACING_DIV2
- for j in range(1,self.beatCount):
- x = beatStart + j*self.beatSpacing
+ for j in range(1,self.screenBufBeats[buf]):
+ x = beatStart + j*beatSpacing
pixmap.draw_line( self.gc, x, self.trackRect[self.drumIndex].y, x, self.trackRect[self.drumIndex].y+self.trackRect[self.drumIndex].height )
-
+
# draw notes
- notes = self.note[self.curPage][self.drumIndex]
+ notes = self.noteDB.getNotesByTrack( self.curPage, self.drumIndex, self )
for n in range( resume[1], len(notes) ):
# check escape
if 0:
@@ -889,27 +735,27 @@ class TrackInterface( gtk.EventBox ):
TP.ProfilePause( "TrackInterface::predraw" )
return False
if not notes[n].draw( pixmap, self.gc, startX, stopX ): break
-
+
self.screenBufDirty[buf] = False
-
+
TP.ProfileEnd( "TrackInterface::predraw" )
-
+
return True
- def expose( self, DA, event ):
-
+ def expose( self, DA, event ):
+
if self.screenBufDirty[self.curScreen]:
self.predraw( self.curScreen )
-
+
TP.ProfileBegin( "TrackInterface::expose" )
-
+
startX = event.area.x
startY = event.area.y
stopX = event.area.x + event.area.width
stopY = event.area.y + event.area.height
-
+
#print "%d %d %d %d" % (startX,startY,stopX,stopY)
-
+
self.gc.set_clip_rectangle( event.area )
# draw base
@@ -919,22 +765,23 @@ class TrackInterface( gtk.EventBox ):
self.gc.set_line_attributes( Config.PLAYHEAD_SIZE, gtk.gdk.LINE_SOLID, gtk.gdk.CAP_BUTT, gtk.gdk.JOIN_MITER )
self.gc.foreground = self.playheadColor
DA.window.draw_line( self.gc, self.playheadX, startY, self.playheadX, stopY )
-
+
if self.marqueeLoc: # draw the selection rect
self.gc.set_line_attributes( Config.MARQUEE_SIZE, gtk.gdk.LINE_ON_OFF_DASH, gtk.gdk.CAP_BUTT, gtk.gdk.JOIN_MITER )
self.gc.foreground = self.marqueeColor
DA.window.draw_rectangle( self.gc, False, self.marqueeRect[0][0], self.marqueeRect[0][1], self.marqueeRect[1][0], self.marqueeRect[1][1] )
-
+
self.drawingAreaDirty = False
- TP.ProfileEnd( "TrackInterface::expose" )
-
+ TP.ProfileEnd( "TrackInterface::expose" )
+
def invalidate_rect( self, x, y, width, height, page, base = True ):
+ #print "%d %d %d %d Page %d CurPage %d" % (x,y,width,height,page,self.curPage)
self.dirtyRectToAdd.x = x
self.dirtyRectToAdd.y = y
self.dirtyRectToAdd.width = width
self.dirtyRectToAdd.height = height
-
+
#print "dirty %d %d %d %d %d %d" % (x, y, width, height, x+width, y+height)
if page == self.curPage:
if base: # the base image has been dirtied
@@ -950,7 +797,7 @@ class TrackInterface( gtk.EventBox ):
if self.drawingArea.window != None:
self.drawingArea.window.invalidate_rect( self.dirtyRectToAdd, True )
self.drawingAreaDirty = True
-
+
elif page == self.screenBufPage[self.preScreen]:
if not self.screenBufDirty[self.preScreen]:
self.screenBufDirtyRect[self.preScreen].x = x
@@ -961,16 +808,16 @@ class TrackInterface( gtk.EventBox ):
self.screenBufDirtyRect[self.preScreen] = self.screenBufDirtyRect[self.preScreen].union( self.dirtyRectToAdd )
self.screenBufResume[self.preScreen] = [0,0]
self.screenBufDirty[self.preScreen] = True
-
+
#self.queue_draw()
def getTrackOrigin( self, track ):
return ( self.trackRect[track].x, self.trackRect[track].y )
- def ticksToPixels( self, ticks ):
- return int(round( ticks * self.pixelsPerTick ))
- def pixelsToTicks( self, pixels ):
- return int(round( pixels * self.ticksPerPixel ))
+ def ticksToPixels( self, beats, ticks ):
+ return int(round( ticks * self.pixelsPerTick[beats] ))
+ def pixelsToTicks( self, beats, pixels ):
+ return int(round( pixels * self.ticksPerPixel[beats] ))
def pitchToPixels( self, pitch ):
return int(round( ( Config.MAXIMUM_PITCH - pitch ) * self.pixelsPerPitch ))
def pixelsToPitch( self, pixels ):
diff --git a/Edit/TuneInterface.py b/Edit/TuneInterface.py
index fd9bc3a..e6790b9 100644
--- a/Edit/TuneInterface.py
+++ b/Edit/TuneInterface.py
@@ -7,45 +7,63 @@ import Config
from Util.Profiler import TP
from Edit.MainWindow import CONTEXT
+class TuneInterfaceParasite:
+
+ def __init__( self, noteDB, owner, note ):
+ self.parasite = self
+ self.noteDB = noteDB
+ self.owner = owner
+ self.note = note
+
+ def attach( self ):
+ return self
+
+ def destroy( self ):
+ return
+
+ def updateParameter( self, parameter, value ):
+ return
+
class TuneInterface( gtk.EventBox ):
-
+
+ DRAG_BLOCK = -1 # block other drag events
DRAG_SELECT = 1
DRAG_DESELECT = 2
DRAG_MOVE = 3
-
- def __init__( self, owner ):
+
+ def __init__( self, noteDB, owner ):
gtk.EventBox.__init__( self )
-
+
+ self.noteDB = noteDB
self.owner = owner
-
+
self.drawingArea = gtk.DrawingArea()
self.drawingAreaDirty = False # is the drawingArea waiting to draw?
self.add( self.drawingArea )
self.dirtyRectToAdd = gtk.gdk.Rectangle() # used by the invalidate_rect function
- self.pages = []
self.selectedIds = []
self.displayedPage = -1
-
+
self.alloced = False
self.width = self.baseWidth = self.height = -1
self.waitingForAlloc = True
self.scrollTo = -1
self.clickX = -1
-
+
self.set_size_request( self.width, self.height )
self.pageSpacing = Config.PAGE_THUMBNAIL_WIDTH + Config.PAGE_THUMBNAIL_PADDING_MUL2
self.pageOffset = Config.PAGE_THUMBNAIL_PADDING + Config.PAGE_THUMBNAIL_PADDING_DIV2
-
+
self.dragMode = None
self.dropAt = -1
-
+
self.connect( "size-allocate", self.size_allocated )
self.drawingArea.connect( "expose-event", self.draw )
self.connect( "button-press-event", self.handleButtonPress )
self.connect( "button-release-event", self.handleButtonRelease )
self.connect( "motion-notify-event", self.handleMotion )
-
+
def size_allocated( self, widget, allocation ):
if not self.alloced:
self.baseWidth = allocation.width
@@ -54,35 +72,37 @@ class TuneInterface( gtk.EventBox ):
self.width = allocation.width
self.height = allocation.height
self.drawingArea.set_size_request( self.width, self.height )
-
+
self.pageY = (self.height-Config.PAGE_THUMBNAIL_HEIGHT)//2
-
+
if self.scrollTo >= 0:
self.owner.scrollTune( self.scrollTo )
self.scrollTo = -1
-
+
self.waitingForAlloc = False
def updateSize( self ):
if not self.alloced: return
- width = len(self.pages)*(Config.PAGE_THUMBNAIL_WIDTH + Config.PAGE_THUMBNAIL_PADDING_MUL2) + Config.PAGE_THUMBNAIL_PADDING_MUL2
+ width = self.noteDB.getPageCount()*(Config.PAGE_THUMBNAIL_WIDTH + Config.PAGE_THUMBNAIL_PADDING_MUL2) + Config.PAGE_THUMBNAIL_PADDING_MUL2
self.waitingForAlloc = True
self.set_size_request( max( self.baseWidth, width), -1 )
def handleButtonPress( self, widget, event ):
ind = int(event.x-self.pageOffset)//self.pageSpacing
- if ind >= len(self.pages): return
+ if ind >= self.noteDB.getPageCount():
+ self.dragMode = self.DRAG_BLOCK
+ return
if ind < 0: ind = 0
self.clickX = event.x
- id = self.pages[ ind ]
+ id = self.noteDB.getPageByIndex( ind )
if event.type == gtk.gdk._2BUTTON_PRESS: # double click -> exclusive select
self.selectPage( id )
self.owner.displayPage( id )
else:
- if Config.ModKeys.ctrlDown:
+ if Config.ModKeys.ctrlDown:
if id in self.selectedIds: # ctrl click, selected page -> remove page from selection
if self.deselectPage( id ):
self.dragMode = self.DRAG_DESELECT
@@ -98,141 +118,101 @@ class TuneInterface( gtk.EventBox ):
self.owner.displayPage( id )
self.owner.setContext( CONTEXT.PAGE )
-
+
def handleButtonRelease( self, widget, event ):
-
+
if self.dragMode == self.DRAG_MOVE:
self.invalidate_rect( 0, 0, self.width, self.height ) # drop head
- self.owner.movePages( self.dropAt, self.selectedIds )
+
+ if self.dropAt > 0: after = self.noteDB.getPageByIndex( self.dropAt-1 )
+ else: after = False
+
+ self.noteDB.movePages( self.selectedIds, after )
self.dropAt = -1
-
+
self.dragMode = None
-
+
def handleMotion( self, widget, event ):
-
- if Config.ModKeys.ctrlDown and (self.dragMode == None or self.dragMode == self.DRAG_MOVE):
+
+ if Config.ModKeys.ctrlDown and (self.dragMode == None or self.dragMode == self.DRAG_MOVE):
self.dropAt = -1
self.dragMode = self.DRAG_SELECT
-
+
if self.dragMode == self.DRAG_SELECT: # select on drag
ind = int(event.x-self.pageOffset)//self.pageSpacing
- if ind < len(self.pages): self.selectPage( self.pages[ind], False )
- elif self.dragMode == self.DRAG_DESELECT: # deselect on drag
+ if ind < self.noteDB.getPageCount(): self.selectPage( self.noteDB.getPageByIndex(ind), False )
+ elif self.dragMode == self.DRAG_DESELECT: # deselect on drag
ind = int(event.x-self.pageOffset)//self.pageSpacing
- if ind < len(self.pages): self.deselectPage( self.pages[ind] )
+ if ind < self.noteDB.getPageCount(): self.deselectPage( self.noteDB.getPageByIndex(ind) )
elif self.dragMode == None and abs(self.clickX-event.x) > 20: # drag and drop
self.dragMode = self.DRAG_MOVE
-
+
if self.dragMode == self.DRAG_MOVE:
self.dropAt = int(event.x-self.pageOffset+Config.PAGE_THUMBNAIL_WIDTH_DIV2)//self.pageSpacing
- if self.dropAt > len(self.pages): self.dropAt = len(self.pages)
+ c = self.noteDB.getPageCount()
+ if self.dropAt > c: self.dropAt = c
self.invalidate_rect( 0, 0, self.width, self.height )
-
+
def displayPage( self, id, scroll ):
if self.displayedPage == id: return -1
-
+
self.displayedPage = id
+
+ if id not in self.selectedIds:
+ self.selectPage( id )
- for ind in range(len(self.pages)):
- if self.pages[ind] == id: break
+ ind = self.noteDB.getPageIndex( id )
startX = self.pageOffset + ind*self.pageSpacing
stopX = startX + self.pageSpacing
self.invalidate_rect( 0, 0, self.width, self.height )
-
+
if scroll > startX: scroll = startX
elif scroll + self.baseWidth < stopX:
- scroll = stopX - self.baseWidth
+ scroll = stopX - self.baseWidth
if self.waitingForAlloc:
- self.scrollTo = scroll
- return -1
+ self.scrollTo = scroll
+ return -1
else:
scroll = stopX - self.baseWidth
return scroll
-
- def insertPages( self, ids, insert, select = True, exclusive = True ):
- if exclusive:
- self.clearSelection()
- for id in ids:
- self.insertPage( id, insert, select, False, False )
- insert += 1
-
- self.updateSize()
-
- def insertPage( self, id, insert, select = True, exclusive = True, resize = True ):
- self.pages.insert( insert, id )
-
- if select: self.selectPage( id, exclusive )
- else: self.invalidate_rect( 0, 0, self.width, self.height )
-
- if resize: self.updateSize()
-
- def removePages( self, ids ):
- for id in ids:
- self.removePage( id, False )
-
- self.updateSize()
-
- def removePage( self, id, resize = True ):
-
- if id in self.selectedIds: self.selectedIds.remove(id)
-
- self.pages.remove(id)
-
- self.invalidate_rect( 0, 0, self.width, self.height )
-
- if resize: self.updateSize()
-
- def movePage( self, remove, insert ):
- if remove == insert: return
- elif remove < insert:
- insert -= 1
- if remove == insert: return
-
- id = self.pages[remove]
- self.pages.pop(remove)
- self.pages.insert( insert, id )
-
- self.invalidate_rect( 0, 0, self.width, self.height )
def selectPage( self, id, exclusive = True ):
if exclusive: self.selectedIds = []
-
+
if id in self.selectedIds: return False # no change
-
+
+ ind = self.noteDB.getPageIndex( id )
l = len(self.selectedIds)
- j = 0
- for i in range(len(self.pages)):
- if j == l: break
- if self.pages[i] == self.selectedIds[j]: j += 1
- elif id == self.pages[i]: break
-
- self.selectedIds.insert( j, id )
-
+ i = 0 # in case len(self.selectedIds) == 0
+ while i < l:
+ if self.noteDB.getPageIndex( self.selectedIds[i] ) > ind: break
+ i += 1
+
+ self.selectedIds.insert( i, id )
+
self.invalidate_rect( 0, 0, self.width, self.height )
-
+
return True # page added to selection
def deselectPage( self, id, force = False ):
if not id in self.selectedIds: return False # page isn't selected
-
+
if not force:
if len(self.selectedIds) <= 1: return False # don't deselect the last page
if self.displayedPage == id:
- for i in range(len(self.selectedIds)):
- if self.selectedIds[i] == id:
- if i == 0: self.owner.displayPage( self.selectedIds[1] )
- else: self.owner.displayPage( self.selectedIds[i-1] )
- break
-
- self.selectedIds.remove( id )
+ i = self.selectedIds.index(id)
+ if i == 0: self.owner.displayPage( self.selectedIds[1] )
+ else: self.owner.displayPage( self.selectedIds[i-1] )
+
+ self.selectedIds.remove( id )
self.invalidate_rect( 0, 0, self.width, self.height )
-
+
return True # page removed from the selection
-
+
def clearSelection( self ):
self.selectedIds = []
@@ -241,23 +221,34 @@ class TuneInterface( gtk.EventBox ):
def getSelectedIds( self ):
return self.selectedIds
- def getAllIds( self ):
- return self.pages
-
def getLastSelected( self ):
- if len(self.selectedIds):
- id = self.selectedIds[-1]
- i = 0
- for pageId in self.pages:
- if pageId == id: break
- i += 1
- return i
- else: return 0
-
+ return self.selectedIds[-1]
+
+ #=======================================================
+ # NoteDB notifications
+
+ def notifyPageAdd( self, id, at ):
+ self.selectPage( id )
+ self.updateSize()
+
+ def notifyPageDelete( self, which, safe ):
+ for id in self.selectedIds:
+ if id in which: self.deselectPage( id, True )
+ self.updateSize()
+
+ def notifyPageDuplicate( self, new, at ):
+ self.clearSelection()
+ for k in new.keys():
+ self.selectPage( new[k], False )
+ self.updateSize()
+
+ def notifyPageMove( self, which, low, high ):
+ self.invalidate_rect( 0, 0, self.width, self.height )
+
#=======================================================
# Drawing
- def draw( self, drawingArea, event ):
+ def draw( self, drawingArea, event ):
startX = event.area.x
startY = event.area.y
@@ -266,7 +257,7 @@ class TuneInterface( gtk.EventBox ):
context = drawingArea.window.cairo_create()
context.set_antialias(0) # I don't know what to set this to to turn it off, and it doesn't seem to work anyway!?
- context.set_line_width( 2 )
+ context.set_line_width( 2 )
context.move_to( 0, 0 )
context.rel_line_to( self.width, 0 )
@@ -276,13 +267,13 @@ class TuneInterface( gtk.EventBox ):
#draw background
context.set_source_rgb( 0.75, 0.05, 0.0 )
- context.fill_preserve()
-
+ context.fill_preserve()
+
# draw pages
x = Config.PAGE_THUMBNAIL_PADDING_MUL2 # double padding on first page!
l = len(self.selectedIds)
j = 0
- for pageId in self.pages:
+ for pageId in self.noteDB.getTune():
if pageId == self.displayedPage: # displayed page border
context.set_source_rgb( 1.0, 1.0, 1.0 )
if j<l and self.selectedIds[j] == pageId: j += 1
@@ -297,24 +288,23 @@ class TuneInterface( gtk.EventBox ):
context.rel_line_to( 0, Config.PAGE_THUMBNAIL_HEIGHT )
context.rel_line_to( -Config.PAGE_THUMBNAIL_WIDTH, 0 )
context.close_path()
- context.stroke()
-
+ context.stroke()
+
x += self.pageSpacing
-
+
# draw drop marker
if self.dropAt >= 0:
- context.set_line_width( Config.PAGE_THUMBNAIL_PADDING )
+ context.set_line_width( Config.PAGE_THUMBNAIL_PADDING )
context.set_source_rgb( 0.0, 0.0, 0.0 )
context.move_to( Config.PAGE_THUMBNAIL_PADDING + self.pageSpacing*self.dropAt, self.pageY - 4 )
context.rel_line_to( 0, Config.PAGE_THUMBNAIL_HEIGHT + 8 )
- context.stroke()
+ context.stroke()
def invalidate_rect( self, x, y, width, height ):
- if self.alloced == False: return
+ if self.alloced == False: return
self.dirtyRectToAdd.x = x
self.dirtyRectToAdd.y = y
self.dirtyRectToAdd.width = width
self.dirtyRectToAdd.height = height
self.drawingArea.window.invalidate_rect( self.dirtyRectToAdd, True )
self.drawingAreaDirty = True
- #self.queue_draw()