Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/Edit
diff options
context:
space:
mode:
authorNat <natcl@hotmail.com>2007-08-17 17:18:16 (GMT)
committer Nat <natcl@hotmail.com>2007-08-17 17:18:16 (GMT)
commit6e89806275673d7785aab0e0a44355eee678aea2 (patch)
treebdffc4d1d45ac5fe6d501ce30accaeddf6444bb9 /Edit
parentabc2fe2a2eb9cff483111756f994ae1f92daa883 (diff)
parent0c7820662df4a6b0ff2bd8a07018e44e6c3df765 (diff)
Merge branch 'master' of git+ssh://natcl@dev.laptop.org/git/projects/tamtam
Diffstat (limited to 'Edit')
-rw-r--r--Edit/EditToolbars.py182
-rw-r--r--Edit/MainWindow.py47
-rw-r--r--Edit/NoteInterface.py2
-rw-r--r--Edit/TuneInterface.py14
4 files changed, 210 insertions, 35 deletions
diff --git a/Edit/EditToolbars.py b/Edit/EditToolbars.py
index 1f02c5f..24b0ab2 100644
--- a/Edit/EditToolbars.py
+++ b/Edit/EditToolbars.py
@@ -1,6 +1,7 @@
#!/usr/bin/env python
import gtk
+
import Config
from sugar.graphics.toolbutton import ToolButton
from sugar.graphics.toggletoolbutton import ToggleToolButton
@@ -11,6 +12,7 @@ from Util.ThemeWidgets import *
from gettext import gettext as _
#Generation palette
+import gobject
from Generation.Generator import GenerationParameters
#Generation palette and Properties palette
from Generation.GenerationConstants import GenerationConstants
@@ -372,6 +374,13 @@ class generationPalette(Palette):
self.slidersBox.pack_start(self.XYSlider2, False, False, padding = 5)
self.slidersBox.pack_start(self.XYSlider3, False, False, padding = 5)
+ self.previewBox = gtk.HBox()
+ self.previewDA = gtk.DrawingArea()
+ self.previewDA.set_size_request( -1, 100 )
+ self.previewDA.connect( "size-allocate", self.handlePreviewAlloc )
+ self.previewDA.connect( "expose-event", self.handlePreviewExpose )
+ self.previewBox.pack_start( self.previewDA, True, True, padding = 5 )
+
self.scaleBoxHBox = gtk.HBox()
self.scaleBoxLabel = gtk.Label(_('Scale: '))
self.scaleBox = BigComboBox()
@@ -408,29 +417,87 @@ class generationPalette(Palette):
self.decisionBox.pack_start(self.previewButton, False, False, padding = 5)
self.mainBox.pack_start(self.slidersBox, False, False, padding = 5)
+ self.mainBox.pack_start( self.previewBox, False, False, padding = 5 )
self.mainBox.pack_start(self.scaleModeBox, False, False, padding = 5)
self.mainBox.pack_start(self.decisionBox, False, False, padding = 5)
self.mainBox.show_all()
self.set_content(self.mainBox)
+ #-- preview drawing -----------------------------------
+ win = gtk.gdk.get_default_root_window()
+ self.gc = gtk.gdk.GC( win )
+ self.parametersDirty = False
+ self.drawingPreview = False
+ self.predrawTarget = 0
+ self.predrawIdleAbort = False
+ # self.predrawBuffer is initialized in handlePreviewAlloc
+ pix = gtk.gdk.pixbuf_new_from_file( Config.IMAGE_ROOT+"sampleBG.png" )
+ self.sampleBg = gtk.gdk.Pixmap( win, pix.get_width(), pix.get_height() )
+ self.sampleBg.draw_pixbuf( self.gc, pix, 0, 0, 0, 0, pix.get_width(), pix.get_height(), gtk.gdk.RGB_DITHER_NONE )
+ self.sampleBg.endOffset = pix.get_width()-5
+ self.sampleNoteHeight = 7
+ if True: # load clipmask
+ pix = gtk.gdk.pixbuf_new_from_file(Config.IMAGE_ROOT+'sampleNoteMask.png')
+ pixels = pix.get_pixels()
+ stride = pix.get_rowstride()
+ channels = pix.get_n_channels()
+ bitmap = ""
+ byte = 0
+ shift = 0
+ for j in range(pix.get_height()):
+ offset = stride*j
+ for i in range(pix.get_width()):
+ r = pixels[i*channels+offset]
+ if r != "\0": byte += 1 << shift
+ shift += 1
+ if shift > 7:
+ bitmap += "%c" % byte
+ byte = 0
+ shift = 0
+ if shift > 0:
+ bitmap += "%c" % byte
+ byte = 0
+ shift = 0
+ self.sampleNoteMask = gtk.gdk.bitmap_create_from_data( None, bitmap, pix.get_width(), pix.get_height() )
+ self.sampleNoteMask.endOffset = pix.get_width()-3
+
+ colormap = self.previewDA.get_colormap()
+ self.colors = { "Beat_Line": colormap.alloc_color( "#959595", True, True ),
+ "Note_Border": colormap.alloc_color( Config.BG_COLOR, True, True ),
+ "Note_Fill": colormap.alloc_color( Config.FG_COLOR, True, True ) }
+
def handleXAdjustment1( self, data ):
self.rythmDensity = self.XAdjustment1.value * .01
+ self.parametersChanged()
def handleYAdjustment1( self, data ):
self.rythmRegularity = self.YAdjustment1.value * .01
+ self.parametersChanged()
def handleXAdjustment2( self, data ):
self.pitchRegularity = self.XAdjustment2.value * .01
+ self.parametersChanged()
def handleYAdjustment2( self, data ):
self.pitchStep = self.YAdjustment2.value * .01
+ self.parametersChanged()
def handleXAdjustment3( self, data ):
self.duration = self.XAdjustment3.value * .01
+ self.parametersChanged()
def handleYAdjustment3( self, data ):
self.silence = self.YAdjustment3.value * .01
+ self.parametersChanged()
+
+ def handleScale(self, widget, data = None):
+ self.scale = widget.props.value
+ self.parametersChanged()
+
+ def handleMode( self, widget, data = None ):
+ self.pattern = widget.props.value
+ self.parametersChanged()
def getGenerationParameters( self ):
return GenerationParameters( self.rythmDensity,
@@ -444,12 +511,6 @@ class generationPalette(Palette):
self.pattern,
self.scale )
- def handleScale(self, widget, data = None):
- self.scale = widget.props.value
-
- def handleMode( self, widget, data = None ):
- self.pattern = widget.props.value
-
def cancel(self, widget, data = None):
self.popdown(True)
@@ -487,7 +548,8 @@ class generationPalette(Palette):
for i in range(len(rythmSequence)):
if random() > parameters.silence:
trackNotes.append([rythmSequence[i], pitchSequence[i], gainSequence[i], durationSequence[i]])
- print trackNotes
+ #print "-------------------------------------------------------",trackNotes
+ return ( trackNotes, beat )
def makeGainSequence( self, onsetList ):
gainSequence = []
@@ -513,6 +575,112 @@ class generationPalette(Palette):
elif len( onsetList ) == 1:
durationSequence.append( ( barLength - onsetList[0] ) * Utils.prob2( table_duration ))
return durationSequence
+
+ def parametersChanged( self ):
+ if not self.drawingPreview:
+ self.drawPreview()
+ else:
+ self.parametersDirty = True
+
+ def drawPreview( self, force = False ):
+ if self.drawingPreview and not force:
+ return # should never happen
+
+ notes, beats = self.previewGenerator( self.getGenerationParameters() )
+ self.parametersDirty = False
+
+ if force:
+ if self.drawingPreview:
+ self.predrawIdleAbort = True
+ self._idleDraw( notes, beats, True, True )
+ else:
+ self.drawingPreview = True
+ gobject.idle_add( self._idleDraw, notes, beats, True, False )
+
+ def _idleDraw( self, notes, beats, fresh, force ):
+ if self.predrawIdleAbort and not force:
+ self.predrawIdleAbort = False
+ return False
+
+ pixmap = self.predrawBuffer[self.predrawTarget]
+
+ if fresh:
+ # draw bg
+ pixmap.draw_drawable( self.gc, self.sampleBg, 0, 0, 0, 0, self.previewDA.width-5, self.previewDA.height )
+ pixmap.draw_drawable( self.gc, self.sampleBg, self.sampleBg.endOffset, 0, self.previewDA.width-5, 0, 5, self.previewDA.height )
+ # draw beat lines
+ self.gc.set_line_attributes( Config.BEAT_LINE_SIZE, gtk.gdk.LINE_ON_OFF_DASH, gtk.gdk.CAP_BUTT, gtk.gdk.JOIN_MITER )
+ self.gc.foreground = self.colors["Beat_Line"]
+ for i in range(1,beats):
+ x = self.beatSpacing[beats][i]
+ pixmap.draw_line( self.gc, x, 1, x, self.previewDA.height-1 )
+
+ if not force:
+ gobject.idle_add( self._idleDraw, notes, beats, False, False )
+ return False
+
+ if force: N = len(notes)
+ else: N = min( 3, len( notes ) ) # adjust this value to get a reasonable response
+
+ self.gc.set_clip_mask( self.sampleNoteMask )
+ for i in range( N ): # draw N notes
+ note = notes.pop()
+ x = self.ticksToPixels( beats, note[0] )
+ endX = self.ticksToPixels( beats, note[0] + note[3] ) - 3 # include end cap offset
+ width = endX - x
+ y = self.pitchToPixels( note[1] )
+ # draw fill
+ self.gc.foreground = self.colors["Note_Fill"]
+ self.gc.set_clip_origin( x, y-self.sampleNoteHeight )
+ pixmap.draw_rectangle( self.gc, True, x+1, y+1, width+1, self.sampleNoteHeight-2 )
+ # draw border
+ self.gc.foreground = self.colors["Note_Border"]
+ self.gc.set_clip_origin( x, y )
+ pixmap.draw_rectangle( self.gc, True, x, y, width, self.sampleNoteHeight )
+ self.gc.set_clip_origin( endX-self.sampleNoteMask.endOffset, y )
+ pixmap.draw_rectangle( self.gc, True, endX, y, 3, self.sampleNoteHeight )
+ self.gc.set_clip_rectangle( self.clearClipMask )
+
+ if not len(notes):
+ self.predrawTarget = not self.predrawTarget
+ self.previewDA.queue_draw()
+
+ self.drawingPreview = False
+
+ if self.parametersDirty:
+ self.drawPreview()
+
+ return False
+
+ return True
+
+ def handlePreviewAlloc( self, widget, allocation ):
+ win = gtk.gdk.get_default_root_window()
+ self.previewDA.width = allocation.width
+ self.previewDA.height = allocation.height
+ self.predrawBuffer = [ gtk.gdk.Pixmap( win, allocation.width, allocation.height ),
+ gtk.gdk.Pixmap( win, allocation.width, allocation.height ) ]
+ self.clearClipMask = gtk.gdk.Rectangle( 0, 0, allocation.width, allocation.height )
+
+ self.pitchPerPixel = float(Config.NUMBER_OF_POSSIBLE_PITCHES-1) / (self.previewDA.height - self.sampleNoteHeight)
+ self.pixelsPerPitch = float(self.previewDA.height - self.sampleNoteHeight)/(Config.MAXIMUM_PITCH - Config.MINIMUM_PITCH)
+ self.pixelsPerTick = [0] + [ self.previewDA.width/float(i*Config.TICKS_PER_BEAT) for i in range(1,Config.MAXIMUM_BEATS+1) ]
+ self.ticksPerPixel = [0] + [ 1.0/self.pixelsPerTick[i] for i in range(1,Config.MAXIMUM_BEATS+1) ]
+
+ self.beatSpacing = [[0]]
+ for i in range(1,Config.MAXIMUM_BEATS+1):
+ self.beatSpacing.append( [ self.ticksToPixels( i, Config.TICKS_PER_BEAT*j ) for j in range(i) ] )
+
+ self.drawPreview( True )
+
+ def handlePreviewExpose( self, widget, event ):
+ widget.window.draw_drawable( self.gc, self.predrawBuffer[not self.predrawTarget], event.area.x, event.area.y, event.area.x, event.area.y, event.area.width, event.area.height )
+
+ def ticksToPixels( self, beats, ticks ):
+ return int(round( ticks * self.pixelsPerTick[beats] ))
+ def pitchToPixels( self, pitch ):
+ return int(round( ( Config.MAXIMUM_PITCH - pitch ) * self.pixelsPerPitch ))
+
class propertiesPalette(Palette):
def __init__(self, label, edit):
diff --git a/Edit/MainWindow.py b/Edit/MainWindow.py
index 770d4b9..eedc3ff 100644
--- a/Edit/MainWindow.py
+++ b/Edit/MainWindow.py
@@ -52,7 +52,7 @@ class MainWindow( SubActivity ):
for i in [6,7,8,9,10]:
self.csnd.setTrackVolume(100, i)
self.trackCount = 6
-
+
def init_data( ):
TP.ProfileBegin("init_data")
self._data = {}
@@ -116,7 +116,7 @@ class MainWindow( SubActivity ):
#------------------------------------------------------------------------
- # page
+ # page
self.GUI["2page"] = gtk.HBox()
self.GUI["2main"].pack_start( self.GUI["2page"], False )
if 1: # + instrument panel
@@ -213,7 +213,7 @@ class MainWindow( SubActivity ):
self.GUI["2instrumentPanel"].pack_start( self.GUI["2instrument4Box"] )
# + + drum box
self.GUI["2drumBox"] = formatRoundBox( RoundHBox(), Config.BG_COLOR )
- self.GUI["2drumBox"].set_size_request( -1, 165 )
+ self.GUI["2drumBox"].set_size_request( -1, 165 )
self.GUI["2drumVolBox"] = gtk.VBox()
self.GUI["2drumvolumeAdjustment"] = gtk.Adjustment( self._data["track_volume"][4], 0, 100, 1, 1, 0 )
#self.GUI["2drumvolumeAdjustment"].connect( "value_changed", self.onTrackVolumeChanged, 4 )
@@ -241,7 +241,7 @@ class MainWindow( SubActivity ):
self.GUI["2page"].pack_start( self.trackInterface, False, False )
#------------------------------------------------------------------------
- # tune interface
+ # tune interface
if 1: # + tune interface
self.GUI["2tuneHBox"] = RoundHBox( fillcolor = Config.TOOLBAR_BCK_COLOR, bordercolor = Config.TOOLBAR_BCK_COLOR, radius = 0 )
self.GUI["2tuneScrollLeftButton"] = ImageButton( Config.IMAGE_ROOT+"arrowEditLeft.png", Config.IMAGE_ROOT+"arrowEditLeftDown.png", Config.IMAGE_ROOT+"arrowEditLeftOver.png", backgroundFill = Config.TOOLBAR_BCK_COLOR )
@@ -377,7 +377,7 @@ class MainWindow( SubActivity ):
first = self.noteDB.addPage( -1, NoteDB.Page(4, instruments = instrumentsIds) )
self.displayPage( first )
-
+
self.createNewTune( None )
# Toolbar
@@ -386,7 +386,7 @@ class MainWindow( SubActivity ):
self.activity.toolbox.add_toolbar(_('Compose'), self._mainToolbar)
self.activity.toolbox.set_current_toolbar(1)
self._mainToolbar.show()
-
+
self.show_all() #gtk command
self.setContext( CONTEXT.PAGE )
@@ -892,6 +892,8 @@ class MainWindow( SubActivity ):
else:
self.handleInstrumentChanged( ( id, None ), False )
btn.setSecondary( None )
+ pages = self.tuneInterface.getSelectedIds()
+ self.noteDB.setInstrument2( pages, id, -1 )
# data is tuple ( trackId, instrumentName )
def handleInstrumentChanged( self, data, primary = True ):
@@ -1336,11 +1338,11 @@ class MainWindow( SubActivity ):
for i in range(Config.NUMBER_OF_TRACKS):
if self.trackInstrument[i].instrumentId != page.instruments[i]:
self.trackInstrument[i] = Config.INSTRUMENTSID[page.instruments[i]]
- if i == Config.NUMBER_OF_TRACKS-1:
+ if i == Config.NUMBER_OF_TRACKS-1:
btn = self.GUI["2drumButton"]
btn.setImage( "main", self.GUI["2instrumentIcons"][self.trackInstrument[i].name] )
btn.setImage( "alt", self.GUI["2instrumentIcons"][self.trackInstrument[i].name] )
- else:
+ else:
btn = self.GUI["2instrument%dButton"%(i+1)]
btn.setPrimary( self.GUI["2instrumentIcons"][self.trackInstrument[i].name] )
if self.trackInstrument2[i] != None:
@@ -1394,7 +1396,7 @@ class MainWindow( SubActivity ):
self.GUI["9propertiesPopup"].move( balloc.x + winLoc[0] - 100, balloc.y - walloc.height + winLoc[1] )
else:
self.GUI["9propertiesPopup"].hide()
-
+
def pageDelete( self, pageIds = -1, instruments = False ):
if pageIds == -1:
@@ -1920,7 +1922,7 @@ class MainWindow( SubActivity ):
class InstrumentButton( gtk.DrawingArea ):
-
+
def __init__( self, owner, index, backgroundFill ):
gtk.DrawingArea.__init__( self )
@@ -1929,13 +1931,13 @@ class InstrumentButton( gtk.DrawingArea ):
self.win = gtk.gdk.get_default_root_window()
self.gc = gtk.gdk.GC( self.win )
-
+
colormap = self.get_colormap()
self.color = { "background": colormap.alloc_color( backgroundFill, True, True ),
"divider": colormap.alloc_color( "#000", True, True ),
- "+/-": colormap.alloc_color( "#818286", True, True ),
+ "+/-": colormap.alloc_color( Config.FG_COLOR, True, True ),
"+/-Highlight": colormap.alloc_color( "#FFF", True, True ) }
-
+
self.pixmap = None
self.primary = None
self.primaryWidth = self.primaryHeight = 1
@@ -1975,15 +1977,15 @@ class InstrumentButton( gtk.DrawingArea ):
def button_press( self, widget, event ):
- self.clicked = "PRIMARY"
+ self.clicked = "PRIMARY"
self.hover = None
-
+
if event.x >= self.hotspots[0][0] and event.x <= self.hotspots[0][2] \
and event.y >= self.hotspots[0][1] and event.y <= self.hotspots[0][3]:
self.clicked = "HOTSPOT_0"
elif self.secondary != None:
-
+
if event.x >= self.hotspots[1][0] and event.x <= self.hotspots[1][2] \
and event.y >= self.hotspots[1][1] and event.y <= self.hotspots[1][3]:
self.clicked = "HOTSPOT_1"
@@ -2022,7 +2024,7 @@ class InstrumentButton( gtk.DrawingArea ):
if self.hover != "HOTSPOT_0":
self.hover = "HOTSPOT_0"
self.queue_draw()
-
+
elif self.secondary != None \
and event.x >= self.hotspots[1][0] and event.x <= self.hotspots[1][2] \
@@ -2037,7 +2039,7 @@ class InstrumentButton( gtk.DrawingArea ):
def leave_notify( self, widget, event ):
if event.mode != gtk.gdk.CROSSING_NORMAL:
- return
+ return
if self.hover != None:
self.hover = None
if self.clicked == None:
@@ -2057,10 +2059,10 @@ class InstrumentButton( gtk.DrawingArea ):
if img != None:
self.secondaryWidth = img.get_width()
self.secondaryHeight = img.get_height()
- self.secondaryOffset = self.secondaryHeight//2
+ self.secondaryOffset = self.secondaryHeight//2
if self.pixmap:
self.secondaryX = (self.alloc.width - self.secondaryWidth) // 2
- self.secondaryY = self.alloc.height//2
+ self.secondaryY = self.alloc.height//2
if self.pixmap:
self._updatePixmap()
@@ -2076,7 +2078,7 @@ class InstrumentButton( gtk.DrawingArea ):
else:
self.pixmap.draw_pixbuf( self.gc, self.primary, 0, 0, self.primaryX, self.primaryY, self.primaryWidth, self.primaryHeight, gtk.gdk.RGB_DITHER_NONE )
self.queue_draw()
-
+
def expose( self, widget, event ):
self.window.draw_drawable( self.gc, self.pixmap, 0, 0, 0, 0, self.alloc.width, self.alloc.height )
self.gc.set_line_attributes( 4, gtk.gdk.LINE_SOLID, gtk.gdk.CAP_ROUND, gtk.gdk.JOIN_MITER )
@@ -2092,10 +2094,9 @@ class InstrumentButton( gtk.DrawingArea ):
self.gc.foreground = self.color["+/-"]
self.window.draw_line( self.gc, self.hotspots[1][0], self.hotspots[1][5], self.hotspots[1][2], self.hotspots[1][5] )
else:
- if self.clicked == "HOTSPOT_0" or self.hover == "HOTSPOT_0":
+ if self.clicked == "HOTSPOT_0" or self.hover == "HOTSPOT_0":
self.gc.foreground = self.color["+/-Highlight"]
else:
self.gc.foreground = self.color["+/-"]
self.window.draw_line( self.gc, self.hotspots[0][0], self.hotspots[0][5], self.hotspots[0][2], self.hotspots[0][5] )
self.window.draw_line( self.gc, self.hotspots[0][4], self.hotspots[0][1], self.hotspots[0][4], self.hotspots[0][3] )
-
diff --git a/Edit/NoteInterface.py b/Edit/NoteInterface.py
index a51fe2c..a5035dd 100644
--- a/Edit/NoteInterface.py
+++ b/Edit/NoteInterface.py
@@ -54,7 +54,7 @@ class NoteInterface:
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.color = self.colormap.alloc_color( r, g, b, True, True ) # TODO potential memory leak?
self.oldAmplitude = self.note.cs.amplitude
self.updateTransform()
diff --git a/Edit/TuneInterface.py b/Edit/TuneInterface.py
index 54095e6..63141a3 100644
--- a/Edit/TuneInterface.py
+++ b/Edit/TuneInterface.py
@@ -184,6 +184,7 @@ class TuneInterface( gtk.EventBox ):
self.baseWidth = allocation.width
self.visibleEndX = self.baseWidth
self.baseHeight = allocation.height
+ self.updateSize()
self.alloced = True
self.width = allocation.width
self.height = allocation.height
@@ -205,11 +206,16 @@ class TuneInterface( gtk.EventBox ):
self.visibleEndX = self.visibleX + self.baseWidth
def updateSize( self ):
- if not self.alloced: return
- width = self.pageOffset + self.noteDB.getPageCount()*Config.PAGE_THUMBNAIL_WIDTH
+ width = self.noteDB.getPageCount()*Config.PAGE_THUMBNAIL_WIDTH + 5 # add extra 5 for the first page
self.waitingForAlloc = True
- self.set_size_request( max( self.baseWidth, width), -1 )
- self.invalidate_rect( self.visibleX, 0, self.baseWidth, self.height )
+ if width < self.baseWidth:
+ self.pageOffset = ( self.baseWidth - width ) // 2 + 5
+ else:
+ self.pageOffset = 5
+
+ if self.alloced:
+ self.set_size_request( max( self.baseWidth, width), -1 )
+ self.invalidate_rect( self.visibleX, 0, self.baseWidth, self.height )
def handleButtonPress( self, widget, event ):
if event.button != 1: