diff options
Diffstat (limited to 'Jam/Parasite.py')
-rw-r--r-- | Jam/Parasite.py | 349 |
1 files changed, 0 insertions, 349 deletions
diff --git a/Jam/Parasite.py b/Jam/Parasite.py deleted file mode 100644 index 084d092..0000000 --- a/Jam/Parasite.py +++ /dev/null @@ -1,349 +0,0 @@ -import pygtk -pygtk.require( '2.0' ) -import gtk - -import Config - -from Util.NoteDB import PARAMETER -from Util.CSoundClient import new_csound_client - -class LoopParasite: - - def __init__( self, noteDB, owner, note ): - self.noteDB = noteDB - self.owner = owner - self.note = note - - self.firstTransform = True - self.x = 0 - self.y = 0 - self.width = 1 - self.height = Config.NOTE_HEIGHT - - self.selected = False - self.potentialDeselect = False - - self.oldOnset = -1 - self.oldEnd = -1 - self.oldPitch = -1 - self.oldAmplitude = -1 - self.oldBeats = -1 - self.lastDragO = 0 - self.lastDragP = 0 - self.lastDragD = 0 - - self.gc = self.owner.gc - self.colors = self.owner.colors - - self.updateParameter( None, None ) - - def attach( self ): - return self - - def destroy( self ): - if self.selected: - self.owner.deselectNotes( { self.note.track: [self] } ) - else: # if we were deselected above the rect has already been invalidated - self.owner.invalidatePreview( self.x, self.y, self.width, self.height, self.note.page, True ) - - def updateParameter( self, parameter, value ): - self.end = self.note.cs.onset + self.note.cs.duration - - self.updateTransform() - - def getId( self ): - return self.note.id - - def getStartTick( self ): - return self.note.cs.onset - - def getEndTick( self ): - return self.end - - def testOnset( self, start, stop ): - return self.note.cs.onset >= start and self.note.cs.onset < stop - - def getPitch( self ): - return self.note.cs.pitch - - def updateTransform( self, force = False ): - if self.note.page == self.owner.getPage(): - if not self.firstTransform: - oldX = self.x - oldY = self.y - oldEndX = self.x + self.width - dirty = True - else: - dirty = False - - beats = self.noteDB.getPage( self.note.page ).beats - if force or self.note.cs.onset != self.oldOnset or beats != self.oldBeats: - self.x = self.owner.ticksToPixels( beats, self.note.cs.onset ) - self.oldOnset = self.note.cs.onset - if force or self.end != self.oldEnd or self.note.cs.onset != self.oldOnset or beats != self.oldBeats: - self.width = self.owner.ticksToPixels( beats, self.end ) - self.x - self.oldEnd = self.end - if force or self.note.cs.pitch != self.oldPitch: - self.y = self.owner.pitchToPixels( self.note.cs.pitch ) - self.oldPitch = self.note.cs.pitch - self.oldBeats = beats - - if dirty: - if self.firstTransform: - self.owner.invalidatePreview( self.x, self.y, self.width, self.height, self.note.page, True ) - else: - x = min( self.x, oldX ) - y = min( self.y, oldY ) - endx = max( self.x + self.width, oldEndX ) - endy = max( self.y, oldY ) + self.height - self.owner.invalidatePreview( x, y, endx-x, endy-y, self.note.page, True ) - - self.firstTransform = False - - def updateDragLimits( self, dragLimits, leftBound, rightBound, widthBound, maxRightBound ): - 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 - if dragLimits[1][0] < down: dragLimits[1][0] = down - if dragLimits[1][1] > up: dragLimits[1][1] = up - if dragLimits[2][0] < short: dragLimits[2][0] = short - if dragLimits[2][1] > long: dragLimits[2][1] = long - - # store the current loc as a reference point - self.baseOnset = self.note.cs.onset - self.basePitch = self.note.cs.pitch - self.baseDuration = self.note.cs.duration - - def playSampleNote( self, full=True ): - secs_per_tick = 0.025 - csnd = new_csound_client() - - if full: - onset = self.note.cs.onset - instrumentId = self.note.cs.instrumentId - self.note.cs.onset = 0 - self.note.cs.instrumentId = self.owner.instrument["id"] - csnd.play( self.note.cs, 0.024) - self.note.cs.onset = onset - self.note.cs.instrumentId = instrumentId - else: - onset = self.note.cs.onset - duration = self.note.cs.duration - instrumentId = self.note.cs.instrumentId - self.note.cs.onset = 0 - self.note.cs.duration = 10 - self.note.cs.instrumentId = self.owner.instrument["id"] - csnd.play( self.note.cs, 0.024) - self.note.cs.onset = onset - self.note.cs.duration = duration - self.note.cs.instrumentId = instrumentId - - #======================================================= - # Events - - # handleButtonPress returns: - # -2, not a hit but there was X overlap - # -1, event occurs before us so don't bother checking any later notes - # 0, event didn't hit - # 1, event was handled - def handleButtonPress( self, emitter, event ): - eX = event.x - self.x - if eX < 0: - 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 ) - return 1 # handled - - playSample = False - - if event.type == gtk.gdk._2BUTTON_PRESS: # select bar - self.potentialDeselect = False - start = 0 - 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.note.cs.duration - while stop < check: stop += Config.TICKS_PER_BEAT - emitter.selectNotesByBar( self.note.track, start, stop ) - elif event.type == gtk.gdk._3BUTTON_PRESS: # select track - self.potentialDeselect = False - emitter.selectNotesByTrack( self.note.track ) - else: - if self.selected: # we already selected, might want to delected - self.potentialDeselect = True - else: - emitter.selectNotes( { self.note.track: [ self ] } ) - playSample = True - - 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 ) - if playSample: self.playSampleNote() - - return 1 - - def handleButtonRelease( self, emitter, event, buttonPressCount ): - - if self.potentialDeselect: - self.potentialDeselect = False - emitter.deselectNotes( { self.note.track: [ self ] } ) - - emitter.doneCurrentAction() - - return True - - def noteDragOnset( self, do, stream ): - self.potentialDeselect = False - if do != self.lastDragO: - self.lastDragO = do - stream += [ self.note.id, self.baseOnset + do ] - - def noteDragPitch( self, dp, stream ): - self.potentialDeselect = False - if dp != self.lastDragP: - self.lastDragP = dp - stream += [ self.note.id, self.basePitch + dp ] - - def noteDragDuration( self, dd, stream ): - self.potentialDeselect = False - if dd != self.lastDragD: - self.lastDragD = dd - stream += [ self.note.id, self.baseDuration + dd ] - - def doneNoteDrag( self, emitter ): - 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 - - def noteDecOnset( self, step, leftBound, stream ): - if self.selected: - if leftBound < self.note.cs.onset: - onset = max( self.note.cs.onset+step, leftBound ) - stream += [ self.note.id, onset ] - return onset + self.note.cs.duration - return self.end - - def noteIncOnset( self, step, rightBound, stream ): - if self.selected: - if rightBound > self.end: - onset = min( self.end+step, rightBound ) - self.note.cs.duration - stream += [ self.note.id, onset ] - return onset - return self.note.cs.onset - - def noteDecPitch( self, step, stream ): - if self.note.cs.pitch > Config.MINIMUM_PITCH: - stream += [ self.note.id, max( self.note.cs.pitch+step, Config.MINIMUM_PITCH ) ] - - def noteIncPitch( self, step, stream ): - if self.note.cs.pitch < Config.MAXIMUM_PITCH: - stream += [ self.note.id, min( self.note.cs.pitch+step, Config.MAXIMUM_PITCH ) ] - - def noteDecDuration( self, step, stream ): - if self.note.cs.duration > Config.MINIMUM_NOTE_DURATION: - stream += [ self.note.id, max( self.note.cs.duration+step, Config.MINIMUM_NOTE_DURATION ) ] - - def noteIncDuration( self, step, rightBound, stream ): - if self.selected: - if self.end < rightBound: - stream += [ self.note.id, min( self.end+step, rightBound ) - self.note.cs.onset ] - - def noteDecVolume( self, step, stream ): - if self.note.cs.amplitude > 0: - stream += [ self.note.id, max( self.note.cs.amplitude+step, 0 ) ] - - def noteIncVolume( self, step, stream ): - if self.note.cs.amplitude < 1: - stream += [ self.note.id, min( self.note.cs.amplitude+step, 1 ) ] - - def handleMarqueeSelect( self, emitter, start, stop ): - intersectionY = [ max(start[1],self.y), min(stop[1],self.y+self.height) ] - if intersectionY[0] > intersectionY[1]: - return False - - intersectionX = [ max(start[0],self.x), min(stop[0],self.x+self.width) ] - if intersectionX[0] > intersectionX[1]: - 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 - # 0, event didn't hit - # 1, event was handled - def updateTooltip( self, emitter, event ): - eX = event.x - self.x - if eX < 0: - 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 - self.owner.invalidatePreview( self.x, self.y, self.width, self.height, self.note.page ) - return True # state changed - return False # state is the same - - def getSelected( self ): - return self.selected - - #======================================================= - # Draw - - def draw( self, win, gc, startX, stopX ): - if stopX < self.x: return False # we don't need to draw and no one after us will draw - if startX > self.x + self.width: return True # we don't need to draw, but maybe a later note does - - # draw fill - self.gc.foreground = self.colors["Preview_Note_Fill"] - self.gc.set_clip_origin( self.x, self.y-self.owner.sampleNoteHeight ) - self.owner.previewBuffer.draw_rectangle( self.gc, True, self.x+1, self.y+1, self.width-2, self.owner.sampleNoteHeight-2 ) - # draw border - if self.selected: - self.gc.foreground = self.colors["Preview_Note_Selected"] - else: - self.gc.foreground = self.colors["Preview_Note_Border"] - self.gc.set_clip_origin( self.x, self.y ) - endX = self.x + self.width - 3 - self.owner.previewBuffer.draw_rectangle( self.gc, True, self.x, self.y, self.width-3, self.owner.sampleNoteHeight ) - self.gc.set_clip_origin( endX-self.owner.sampleNoteMask.endOffset, self.y ) - self.owner.previewBuffer.draw_rectangle( self.gc, True, endX, self.y, 3, self.owner.sampleNoteHeight ) - - return True # we drew something - |