Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/Edit/NoteInterface.py
diff options
context:
space:
mode:
authorjaberg <james@localhost.localdomain>2007-01-07 21:24:04 (GMT)
committer jaberg <james@localhost.localdomain>2007-01-07 21:24:04 (GMT)
commit1becac24dfa6bd0cee4ae46f4c0b8630bfbb6269 (patch)
tree70d602342d546fd8c268143b54d46b8ca580a7ed /Edit/NoteInterface.py
parent2a940a71469b2b5964e8deab3ed6db0254424671 (diff)
unify_edit init
Diffstat (limited to 'Edit/NoteInterface.py')
-rw-r--r--Edit/NoteInterface.py279
1 files changed, 279 insertions, 0 deletions
diff --git a/Edit/NoteInterface.py b/Edit/NoteInterface.py
new file mode 100644
index 0000000..93ffed3
--- /dev/null
+++ b/Edit/NoteInterface.py
@@ -0,0 +1,279 @@
+import pygtk
+pygtk.require( '2.0' )
+import gtk
+
+from Framework.Constants import Constants
+from GUI.GUIConstants import GUIConstants
+
+class NoteInterface:
+
+ def __init__( self, parent, page, track, note, pitch, onset, duration, amplitude):
+ self.parent = parent
+ self.page = page
+ self.track = track
+ self.note = note # note id, not csnote!
+
+ self.x = 0
+ self.y = 0
+ self.width = 1
+ self.height = GUIConstants.NOTE_HEIGHT
+
+ self.updateParams( pitch, onset, duration, amplitude )
+
+ self.selected = False
+ self.potentialDeselect = False
+
+ self.lastDragO = 0
+ self.lastDragP = 0
+ self.lastDragD = 0
+
+ def destroy( self ):
+ # nothing to do?
+ return
+
+ def updateParams( self, pitch, onset, duration, amplitude):
+ self.pitch = pitch
+ self.onset = onset
+ self.duration = duration
+ self.end = onset + duration
+
+ self.amplitude = amplitude
+ self.bgColour = 1 - ( ( self.amplitude * 0.7 ) + 0.3 )
+
+ self.updateTransform( False )
+
+ 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, onlyX ):
+ if self.page == self.parent.curPage:
+ oldX = self.x
+ oldY = self.y
+ oldEndX = self.x + self.width
+
+ origin = self.parent.getTrackOrigin( self.track )
+ self.x = self.parent.ticksToPixels( self.onset )
+ self.width = self.parent.ticksToPixels( self.end ) - self.x
+ self.x += origin[0]
+ if not onlyX:
+ self.y = self.parent.pitchToPixels( self.pitch ) + origin[1]
+
+ if self.page == self.parent.curPage:
+ 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.parent.invalidate_rect( x, y, endx-x, endy-y )
+
+ def updateDragLimits( self, dragLimits, leftBound, rightBound, widthBound ):
+ left = leftBound - self.onset
+ right = rightBound - self.duration - self.onset
+ up = Constants.MAXIMUM_PITCH - self.pitch
+ down = Constants.MINIMUM_PITCH - self.pitch
+ short = Constants.MINIMUM_NOTE_DURATION - self.duration
+ long = widthBound - self.duration - self.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.onset
+ self.basePitch = self.pitch
+ self.baseDuration = self.duration
+
+ def updateSampleNote( self, pitch ):
+ return
+
+ def clearSampleNote( self ):
+ return
+
+ #=======================================================
+ # 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
+
+ if event.type == gtk.gdk._2BUTTON_PRESS: # select bar
+ self.potentialDeselect = False
+ start = 0
+ check = self.onset - Constants.TICKS_PER_BEAT
+ while start <= check: start += Constants.TICKS_PER_BEAT
+ stop = start + Constants.TICKS_PER_BEAT
+ check += self.duration
+ while stop < check: stop += Constants.TICKS_PER_BEAT
+ emitter.selectNotesByBar( self.track, start, stop )
+ elif event.type == gtk.gdk._3BUTTON_PRESS: # select track
+ self.potentialDeselect = False
+ emitter.selectNotesByTrack( self.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 )
+
+ 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 ] } )
+
+ self.clearSampleNote()
+
+ emitter.doneCurrentAction()
+
+ return True
+
+ def noteDrag( self, emitter, do, dp, dd ):
+ self.potentialDeselect = False
+
+ if do != self.lastDragO:
+ self.lastDragO = do
+ self.onset = self.baseOnset + do
+ self.end = self.onset + self.duration
+
+ if dp != self.lastDragP:
+ self.lastDragP = dp
+ newPitch = self.basePitch + dp
+ self.pitch = newPitch
+ self.updateSampleNote( newPitch )
+
+ if dd != self.lastDragD:
+ self.lastDragD = dd
+ self.duration = self.baseDuration + dd
+ self.end = self.onset + self.duration
+
+ self.updateTransform( False )
+
+ return (self.note, self.pitch, self.onset, self.duration)
+
+ def doneNoteDrag( self, emitter ):
+ self.baseOnset = self.onset
+ self.basePitch = self.pitch
+ self.baseDuration = self.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) ]
+ 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
+ if self.page == self.parent.curPage:
+ self.parent.invalidate_rect( self.x, self.y, self.width, self.height )
+ return True # state changed
+ return False # state is the same
+
+ def getSelected( self ):
+ return self.selected
+
+ #=======================================================
+ # Selection
+
+ def draw( self, context, 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
+
+
+ if False:
+ context.set_line_width( GUIConstants.NOTE_BORDER_SIZE )
+
+ context.move_to( self.x + GUIConstants.NOTE_BORDER_SIZE_DIV2, self.y + GUIConstants.NOTE_BORDER_SIZE_DIV2 )
+ context.rel_line_to( self.width - GUIConstants.NOTE_BORDER_SIZE, 0 )
+ context.rel_line_to( 0, self.height - GUIConstants.NOTE_BORDER_SIZE )
+ context.rel_line_to( -self.width + GUIConstants.NOTE_BORDER_SIZE, 0 )
+ context.close_path()
+
+ context.rectangle(self.x, self.y, self.width, self.height )
+
+ #background
+ context.set_source_rgb( self.bgColour, self.bgColour, self.bgColour )
+ #context.fill_preserve()
+ context.fill()
+ return True
+
+ #border
+ if self.selected: context.set_source_rgb( 1, 1, 1 )
+ else: context.set_source_rgb( 0, 0, 0 )
+ context.stroke()
+
+ return True # we drew something
+