Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/Jam
diff options
context:
space:
mode:
authorJames <olpc@xo-05-28-3A.localdomain>2007-08-26 23:07:14 (GMT)
committer James <olpc@xo-05-28-3A.localdomain>2007-08-26 23:07:14 (GMT)
commitc18b73bd20f2e5ad7a76ac3f69feefcac634e50f (patch)
treee78ae7367264a55a29e4f9a8bec9bca7c9fb16ed /Jam
parent593acd0a9c2258765784c599347931c6ac2df749 (diff)
parent42ca65d2e583639cdbb0a6af921ddf2dae75af54 (diff)
Merge branch 'master' of git+ssh://jaberg@dev.laptop.org/git/projects/tamtam
Diffstat (limited to 'Jam')
-rw-r--r--Jam/Block.py63
-rw-r--r--Jam/Desktop.py45
-rw-r--r--Jam/JamMain.py196
-rw-r--r--Jam/Picker.py180
-rw-r--r--Jam/Toolbars.py13
5 files changed, 368 insertions, 129 deletions
diff --git a/Jam/Block.py b/Jam/Block.py
index d8bc099..5eaf53e 100644
--- a/Jam/Block.py
+++ b/Jam/Block.py
@@ -16,6 +16,8 @@ class Block():
WIDTH = 100
HEIGHT = 100
+ SNAP = 15
+
def __init__( self, owner, graphics_context, data ):
self.owner = owner
self.gc = graphics_context
@@ -89,22 +91,12 @@ class Block():
def snapToParentLoc( self, loc ):
self.setLoc( loc[0] - self.parentOffset, loc[1] )
- def testSubstitute( self, block ):
-
- if not self.canSubstitute:
- return False
-
- if self.type != block.type:
- return False
-
- if abs( self.x - block.x ) < 10 and abs( self.y - block.y ) < 10:
- return self
-
- return False
-
def substitute( self, block ):
pass # override in subclasses
+ def testSubstitute( self, block ):
+ return False
+
def testChild( self, loc ):
if not self.canParent:
@@ -112,7 +104,7 @@ class Block():
if self.child:
return self.child.testChild( loc )
- elif abs( self.endX - loc[0] ) < 10 and abs( self.y - loc[1] ) < 10:
+ elif abs( self.endX - loc[0] ) < Block.SNAP and abs( self.y - loc[1] ) < Block.SNAP:
return self
return False
@@ -246,10 +238,24 @@ class Instrument(Block):
if not "volume" in self.data.keys():
self.data["volume"] = 0.5
+ self.img = [ self.owner.getInstrumentImage( self.data["id"], False ),
+ self.owner.getInstrumentImage( self.data["id"], True ) ]
+
def substitute( self, block ):
self.data["id"] = block.data["id"]
+ self.img = [ self.owner.getInstrumentImage( self.data["id"], False ),
+ self.owner.getInstrumentImage( self.data["id"], True ) ]
self.invalidate_rect( True )
+ def testSubstitute( self, block ):
+ if self.type == Loop:
+ return False
+
+ if abs( self.x - block.x ) < Block.SNAP and abs( self.y - block.y ) < Block.SNAP:
+ return self
+
+ return False
+
def _doButtonPress( self, event ): # we were hit with a button press
pass
@@ -273,10 +279,8 @@ class Instrument(Block):
pixmap.draw_rectangle( self.gc, True, x, y, width, height )
# draw block
- if self.active: self.gc.foreground = self.owner.colors["Bg_Active"]
- else: self.gc.foreground = self.owner.colors["Bg_Inactive"]
self.gc.set_clip_origin( self.x-Instrument.MASK_START, self.y-self.height )
- pixmap.draw_rectangle( self.gc, True, x, y, width, height )
+ pixmap.draw_drawable( self.gc, self.img[self.active], x-self.x, y-self.y, x, y, width, height )
def drawHighlight( self, startX, startY, stopX, stopY, pixmap ):
self.gc.foreground = self.owner.colors["Border_Highlight"]
@@ -307,13 +311,33 @@ class Drum(Block):
if not "seed" in self.data.keys():
self.data["seed"] = random.random()
+ self.img = [ self.owner.getInstrumentImage( self.data["id"], False ),
+ self.owner.getInstrumentImage( self.data["id"], True ) ]
+
+
def substitute( self, block ):
self.data["id"] = block.data["id"]
+
+ self.img = [ self.owner.getInstrumentImage( self.data["id"], False ),
+ self.owner.getInstrumentImage( self.data["id"], True ) ]
+
self.invalidate_rect( True )
if self.active:
self.owner.updateDrum()
+ def testSubstitute( self, block ):
+ if self.type == Loop:
+ return False
+
+ if Config.INSTRUMENTSID[block.data["id"]].kit == None:
+ return False
+
+ if abs( self.x - block.x ) < Block.SNAP and abs( self.y - block.y ) < Block.SNAP:
+ return self
+
+ return False
+
def _doButtonPress( self, event ): # we were hit with a button press
pass
@@ -340,10 +364,9 @@ class Drum(Block):
pixmap.draw_rectangle( self.gc, True, x, y, width, height )
# draw block
- if self.active: self.gc.foreground = self.owner.colors["Bg_Active"]
- else: self.gc.foreground = self.owner.colors["Bg_Inactive"]
self.gc.set_clip_origin( self.x-Drum.MASK_START, self.y-self.height )
- pixmap.draw_rectangle( self.gc, True, x, y, width, height )
+ pixmap.draw_drawable( self.gc, self.img[self.active], x-self.x, y-self.y, x, y, width, height )
+
def drawHighlight( self, startX, startY, stopX, stopY, pixmap ):
self.gc.foreground = self.owner.colors["Border_Highlight"]
diff --git a/Jam/Desktop.py b/Jam/Desktop.py
index c5eb4ab..b4b4bda 100644
--- a/Jam/Desktop.py
+++ b/Jam/Desktop.py
@@ -17,45 +17,10 @@ class Desktop( gtk.EventBox ):
self.drawingArea = gtk.DrawingArea()
self.add( self.drawingArea )
- win = gtk.gdk.get_default_root_window()
- self.gc = gtk.gdk.GC( win )
- colormap = self.drawingArea.get_colormap()
- self.colors = { "bg": colormap.alloc_color( Config.PANEL_BCK_COLOR, True, True ), \
- "Border_Active": colormap.alloc_color( "#FF6000", True, True ), \
- "Border_Inactive": colormap.alloc_color( "#5D5D5D", True, True ), \
- "Border_Highlight": colormap.alloc_color( "#FFFFFF", True, True ), \
- "Bg_Active": colormap.alloc_color( "#9400BE", True, True ), \
- "Bg_Inactive": colormap.alloc_color( "#DBDBDB", True, True ), \
- "tempWhite": colormap.alloc_color( "#FFFFFF", True, True ), \
- "tempBlock1": colormap.alloc_color( "#227733", True, True ), \
- "tempBlock2": colormap.alloc_color( "#837399", True, True ), \
- "tempBlock3": colormap.alloc_color( "#111177", True, True ), \
- "tempBlock4": colormap.alloc_color( "#99AA22", True, True ), \
- "tempBlock5": colormap.alloc_color( "#449977", True, True ) }
-
- if True: # load clipmask
- pix = gtk.gdk.pixbuf_new_from_file(Config.IMAGE_ROOT+'jam-blockMask.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.clipMask = gtk.gdk.bitmap_create_from_data( None, bitmap, pix.get_width(), pix.get_height() )
+ # take drawing setup from owner
+ self.gc = owner.gc
+ self.colors = owner.colors
+ self.clipMask = owner.clipMask
self.dirtyRectToAdd = gtk.gdk.Rectangle() # used by the invalidate_rect function
self.screenBuf = None
@@ -149,6 +114,8 @@ class Desktop( gtk.EventBox ):
block.destroy()
+ def getInstrumentImage( self, id, active = False ):
+ return self.owner.getInstrumentImage( id, active )
#==========================================================
# State
diff --git a/Jam/JamMain.py b/Jam/JamMain.py
index 1fe4c0f..67b832e 100644
--- a/Jam/JamMain.py
+++ b/Jam/JamMain.py
@@ -6,14 +6,21 @@ import gtk
from SubActivity import SubActivity
import Config
+from gettext import gettext as _
+import sugar.graphics.style as style
from Jam.Desktop import Desktop
import Jam.Picker as Picker
+import Jam.Block as Block
+from Jam.Toolbars import DesktopToolbar
+
from Util.CSoundNote import CSoundNote
from Util.CSoundClient import new_csound_client
+import Util.InstrumentDB as InstrumentDB
from Fillin import Fillin
from RythmGenerator import generator
+from Generation.GenerationConstants import GenerationConstants
from Util.NoteDB import Note
from math import sqrt
@@ -25,6 +32,8 @@ class JamMain(SubActivity):
self.activity = activity
+ self.instrumentDB = InstrumentDB.getRef()
+
#-- initial settings ----------------------------------
self.tempo = Config.PLAYER_TEMPO
self.volume = 50
@@ -36,10 +45,83 @@ class JamMain(SubActivity):
self.csnd.setMasterVolume( self.volume )
self.csnd.setTempo( self.tempo )
- #======================================================
- # GUI
+ #-- Drawing -------------------------------------------
+ win = gtk.gdk.get_default_root_window()
+ self.gc = gtk.gdk.GC( win )
+ colormap = gtk.gdk.colormap_get_system()
+ self.colors = { "bg": colormap.alloc_color( Config.PANEL_BCK_COLOR ),
+ "Picker_Bg": colormap.alloc_color( "#404040" ),
+ "Picker_Bg_Inactive": colormap.alloc_color( "#808080" ),
+ #"Picker_Bg": colormap.alloc_color( style.COLOR_TOOLBAR_GREY.get_html() ),
+ #"Picker_Bg_Inactive": colormap.alloc_color( style.COLOR_BUTTON_GREY.get_html() ),
+ "Picker_Fg": colormap.alloc_color( style.COLOR_WHITE.get_html() ),
+ "Border_Active": colormap.alloc_color( "#FF6000" ),
+ "Border_Inactive": colormap.alloc_color( "#8D8D8D" ),
+ "Border_Highlight": colormap.alloc_color( "#FFFFFF" ),
+ "Bg_Active": colormap.alloc_color( "#9400BE" ),
+ "Bg_Inactive": colormap.alloc_color( "#DBDBDB" ) }
+
+ if True: # load clipmask
+ pix = gtk.gdk.pixbuf_new_from_file(Config.IMAGE_ROOT+'jam-blockMask.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.clipMask = gtk.gdk.bitmap_create_from_data( None, bitmap, pix.get_width(), pix.get_height() )
+
+ #-- Instrument Images ---------------------------------
+ self.instrumentImage = {}
+ self.instrumentImageActive = {}
+ for inst in self.instrumentDB.getSet( "all" ):
+ try:
+ pix = gtk.gdk.pixbuf_new_from_file(inst.img)
+ x = (Block.Block.WIDTH-pix.get_width())//2
+ y = (Block.Block.HEIGHT-pix.get_height())//2
+ img = gtk.gdk.Pixmap( win, Block.Block.WIDTH, Block.Block.HEIGHT )
+ self.gc.foreground = self.colors["Bg_Inactive"]
+ img.draw_rectangle( self.gc, True, 0, 0, Block.Block.WIDTH, Block.Block.HEIGHT )
+ img.draw_pixbuf( self.gc, pix, 0, 0, x, y, pix.get_width(), pix.get_height(), gtk.gdk.RGB_DITHER_NONE )
+ self.instrumentImage[inst.id] = img
+ img = gtk.gdk.Pixmap( win, Block.Block.WIDTH, Block.Block.HEIGHT )
+ self.gc.foreground = self.colors["Bg_Active"]
+ img.draw_rectangle( self.gc, True, 0, 0, Block.Block.WIDTH, Block.Block.HEIGHT )
+ img.draw_pixbuf( self.gc, pix, 0, 0, x, y, pix.get_width(), pix.get_height(), gtk.gdk.RGB_DITHER_NONE )
+ self.instrumentImageActive[inst.id] = img
+ except:
+ if Config.DEBUG >= 5: print "JamMain:: file does not exist: " + inst.img
+ img = gtk.gdk.Pixmap( win, Block.Block.WIDTH, Block.Block.HEIGHT )
+ self.gc.foreground = self.colors["Bg_Inactive"]
+ img.draw_rectangle( self.gc, True, 0, 0, Block.Block.WIDTH, Block.Block.HEIGHT )
+ self.instrumentImage[inst.id] = img
+ img = gtk.gdk.Pixmap( win, Block.Block.WIDTH, Block.Block.HEIGHT )
+ self.gc.foreground = self.colors["Bg_Active"]
+ img.draw_rectangle( self.gc, True, 0, 0, Block.Block.WIDTH, Block.Block.HEIGHT )
+ self.instrumentImageActive[inst.id] = img
+
+ #-- Toolbars ------------------------------------------
+ self.desktopToolbar = DesktopToolbar( self )
+ self.activity.toolbox.add_toolbar( _("Desktop"), self.desktopToolbar )
+ #-- GUI -----------------------------------------------
if True: # GUI
+ self.modify_bg( gtk.STATE_NORMAL, self.colors["bg"] ) # window bg
+
self.GUI = {}
self.GUI["mainVBox"] = gtk.VBox()
self.add( self.GUI["mainVBox"] )
@@ -49,38 +131,44 @@ class JamMain(SubActivity):
self.GUI["mainVBox"].pack_start( self.GUI["desktop"] )
#-- Bank ----------------------------------------------
- self.GUI["bankVBox"] = gtk.VBox()
- self.GUI["mainVBox"].pack_start( self.GUI["bankVBox"], False, False )
- if True: # Tabs
- self.GUI["bankTabs"] = gtk.HBox()
- self.GUI["bankTabs"].set_size_request( -1, 38 )
- self.GUI["bankVBox"].pack_start( self.GUI["bankTabs"], False, False )
-
- self.GUI["bankInstrumentsTab"] = gtk.RadioButton( None, "Instruments" )
- self.GUI["bankInstrumentsTab"].connect( "clicked", lambda w: self.setPicker( Picker.Instrument, None ) )
- self.GUI["bankTabs"].pack_start( self.GUI["bankInstrumentsTab"] )
- self.GUI["bankDrumsTab"] = gtk.RadioButton( self.GUI["bankInstrumentsTab"], "Drums" )
- self.GUI["bankDrumsTab"].connect( "clicked", lambda w: self.setPicker( Picker.Drum ) )
- self.GUI["bankTabs"].pack_start( self.GUI["bankDrumsTab"] )
- self.GUI["bankLoopsTab"] = gtk.RadioButton( self.GUI["bankInstrumentsTab"], "Loops" )
- self.GUI["bankLoopsTab"].connect( "clicked", lambda w: self.setPicker( Picker.Loop ) )
- self.GUI["bankTabs"].pack_start( self.GUI["bankLoopsTab"] )
-
- if True: # Picker
- self.GUI["bankPicker"] = gtk.HBox()
- self.GUI["bankPicker"].set_size_request( -1, 149 )
- self.GUI["bankVBox"].pack_start( self.GUI["bankPicker"], False, False )
-
- self.pickers = {}
- self.pickerScroll = {}
- for type in [ Picker.Instrument, Picker.Drum, Picker.Loop ]:
- self.pickers[type] = type( self )
+ separator = gtk.Label( " " )
+ separator.set_size_request( -1, style.TOOLBOX_SEPARATOR_HEIGHT )
+ self.GUI["mainVBox"].pack_start( separator, False )
+ self.GUI["notebook"] = gtk.Notebook()
+ self.GUI["notebook"].set_scrollable( True )
+ self.GUI["notebook"].modify_bg( gtk.STATE_NORMAL, self.colors["Picker_Bg"] ) # active tab
+ self.GUI["notebook"].modify_bg( gtk.STATE_ACTIVE, self.colors["Picker_Bg_Inactive"] ) # inactive tab
+ self.GUI["notebook"].props.tab_vborder = style.TOOLBOX_TAB_VBORDER
+ self.GUI["notebook"].props.tab_hborder = style.TOOLBOX_TAB_HBORDER
+ self.GUI["notebook"].set_size_request( -1, 160 )
+ self.GUI["notebook"].connect( "switch-page", self.setPicker )
+ self.GUI["mainVBox"].pack_start( self.GUI["notebook"], False, False )
+ self.pickers = {}
+ self.pickerScroll = {}
+ for type in [ Picker.Instrument, Picker.Drum, Picker.Loop ]:
+ self.pickers[type] = type( self )
+
+ def prepareLabel( name ):
+ label = gtk.Label( _(name) )
+ label.set_alignment( 0.0, 0.5 )
+ label.modify_fg( gtk.STATE_NORMAL, self.colors["Picker_Fg"] )
+ label.modify_fg( gtk.STATE_ACTIVE, self.colors["Picker_Fg"] )
+ return label
+
+ self.GUI["notebook"].append_page( self.pickers[Picker.Drum], prepareLabel("Drum Kits") )
+ self.GUI["notebook"].append_page( self.pickers[Picker.Loop], prepareLabel("Loops") )
+
+ sets = self.instrumentDB.getLabels()[:]
+ sets.sort()
+ for set in sets:
+ page = gtk.HBox()
+ page.set = set
+ self.GUI["notebook"].append_page( page, prepareLabel( set ) )
self.show_all()
- self.curPicker = None
- self.setPicker( Picker.Instrument )
-
+ self.GUI["notebook"].set_current_page( 0 )
+
#-- Keyboard ------------------------------------------
self.key_dict = {}
self.nextTrack = 1
@@ -92,6 +180,9 @@ class JamMain(SubActivity):
# use dummy values for now
self.drumFillin = Fillin( 2, 100, Config.INSTRUMENTS["drum1kit"].instrumentId, self.reverb, 1 )
+ #==========================================================
+ # SubActivity Handlers
+
def onActivate( self, arg ):
pass
@@ -101,20 +192,8 @@ class JamMain(SubActivity):
def onDestroy( self ):
pass
- def getDesktop( self ):
- return self.desktop
-
- def setPicker( self, type, filter = None ):
- if self.curPicker == type:
- if self.pickers[self.curPicker].getFilter() == filter:
- return
- self.pickers[self.curPicker].setFilter( filter )
- else:
- if self.curPicker != None:
- self.GUI["bankPicker"].remove( self.pickers[self.curPicker] )
-
- self.GUI["bankPicker"].pack_start( self.pickers[type] )
- self.curPicker = type
+ #==========================================================
+ # Playback
def onKeyPress( self, widget, event ):
key = event.hardware_keycode
@@ -129,12 +208,13 @@ class JamMain(SubActivity):
if inst.kit: # drum kit
if pitch in GenerationConstants.DRUMPITCH:
pitch = GenerationConstants.DRUMPITCH[pitch]
+ print inst.kit
self._playNote( key,
36,
self.instrument["amplitude"],
self.instrument["pan"],
100,
- inst.kit[pitch],
+ inst.kit[pitch].instrumentId,
self.instrument["reverb"] )
else:
if event.state == gtk.gdk.MOD1_MASK:
@@ -225,3 +305,27 @@ class JamMain(SubActivity):
self.drumFillin.stop()
self.csnd.loopPause()
+ #==========================================================
+ # Get/Set
+
+ def getDesktop( self ):
+ return self.desktop
+
+ def getInstrumentImage( self, id, active = False ):
+ if active: return self.instrumentImageActive[id]
+ else: return self.instrumentImage[id]
+
+ def setPicker( self, widget, pagePointer, page_num ):
+ page = self.GUI["notebook"].get_nth_page( page_num )
+ if page == self.pickers[Picker.Drum]:
+ pass
+ elif page == self.pickers[Picker.Loop]:
+ pass
+ else:
+ self.pickers[Picker.Instrument].setFilter( ( page.set ) )
+ parent = self.pickers[Picker.Instrument].get_parent()
+ if parent != page:
+ if parent != None:
+ parent.remove( self.pickers[Picker.Instrument] )
+ page.add( self.pickers[Picker.Instrument] )
+
diff --git a/Jam/Picker.py b/Jam/Picker.py
index eb3103b..2364d94 100644
--- a/Jam/Picker.py
+++ b/Jam/Picker.py
@@ -7,8 +7,12 @@ import random #TEMP
import sets
import Config
+from gettext import gettext as _
+
+from sugar.graphics.palette import Palette, WidgetInvoker
import Util.ControlStream
+import Util.InstrumentDB as InstrumentDB
import Jam.Block as Block
@@ -18,24 +22,39 @@ class Picker( gtk.HBox ):
gtk.HBox.__init__( self )
self.owner = owner
+
+ # take drawing setup from owner
+ self.gc = owner.gc
+ self.colors = owner.colors
+ self.clipMask = owner.clipMask
self.filter = filter
self.desktop = owner.getDesktop()
self.scrollLeft = gtk.Button( "<" )
+ self.scrollLeft.connect( "clicked", self.doScroll, "left" )
self.pack_start( self.scrollLeft, False, False )
self.scrolledWindow = gtk.ScrolledWindow()
+ #self.scrolledWindow.modify_bg( gtk.STATE_NORMAL, self.colors["Bg_Active"] )
self.scrolledWindow.set_policy( gtk.POLICY_ALWAYS, gtk.POLICY_NEVER )
self.pack_start( self.scrolledWindow )
self.hadjustment = self.scrolledWindow.get_hadjustment()
+ self.hadjustment.connect( "changed", self.scrollChanged )
+ self.hadjustment.connect( "value-changed", self.scrollChanged )
self.scrollRight = gtk.Button( ">" )
+ self.scrollRight.connect( "clicked", self.doScroll, "right" )
self.pack_start( self.scrollRight, False, False )
self.pickerBox = gtk.HBox()
self.scrolledWindow.add_with_viewport( self.pickerBox )
+ self.pickerBox.get_parent().modify_bg( gtk.STATE_NORMAL, self.colors["Picker_Bg"] )
+
+ # spacers
+ self.pickerBox.pack_start( gtk.Label(" "), True, True )
+ self.pickerBox.pack_end( gtk.Label(" "), True, True )
self.show_all()
@@ -44,9 +63,21 @@ class Picker( gtk.HBox ):
self.blocks = []
- def addBlock( self, data, name = "TEMPORARY ARG" ):
- block = gtk.Button(name)
- block.add_events(gtk.gdk.BUTTON_MOTION_MASK)
+ def addBlock( self, data, name, block = None ):
+ if block == None:
+ block = gtk.Button( name )
+
+ # tooltip
+ block._palette = Palette( name )
+ block._palette.props.invoker = WidgetInvoker(block)
+ block._palette.set_property( "position", Palette.AT_CURSOR )
+
+ block.add_events( gtk.gdk.BUTTON_PRESS_MASK
+ | gtk.gdk.BUTTON_RELEASE_MASK
+ | gtk.gdk.ENTER_NOTIFY_MASK
+ | gtk.gdk.LEAVE_NOTIFY_MASK
+ | gtk.gdk.POINTER_MOTION_MASK
+ | gtk.gdk.POINTER_MOTION_HINT_MASK )
block.connect( "button-press-event", self.button_press )
block.connect( "button-release-event", self.button_release )
block.connect( "motion-notify-event", self.motion_notify )
@@ -54,9 +85,10 @@ class Picker( gtk.HBox ):
self.blocks.append( block )
- # TODO test against filter
- self.pickerBox.pack_start( block, False, False )
- block.show()
+ if self._testAgainstFilter( block ):
+ self.pickerBox.pack_start( block, False, False, 3 )
+
+ block.show_all()
return block
@@ -64,17 +96,48 @@ class Picker( gtk.HBox ):
return filter
def setFilter( self, filter ):
- # TODO apply filter
+ if filter == self.filter:
+ return
self.scroll[self.filter] = self.hadjustment.get_value()
+ self.filter = filter
+
+ for block in self.pickerBox.get_children()[1:-1]: # outside children are spacers
+ self.pickerBox.remove( block )
+
+ for block in self.blocks:
+ if self._testAgainstFilter( block ):
+ self.pickerBox.pack_start( block, False, False, 3 )
+
if self.scroll.has_key( filter ):
self.hadjustment.set_value( self.scroll[filter] )
else:
self.hadjustment.set_value( 0 )
self.scroll[filter] = 0
- self.filter = filter
+ def _testAgainstFilter( self, block ):
+ return True
+
+ def doScroll( self, widget, data ):
+ if data == "left":
+ val = max( self.hadjustment.get_property("lower"), self.hadjustment.get_value() - self.hadjustment.get_property("page_increment") )
+ else:
+ val = min( self.hadjustment.get_property("upper") - self.hadjustment.get_property("page_size"), self.hadjustment.get_value() + self.hadjustment.get_property("page_increment") )
+
+ self.hadjustment.set_value( val )
+
+ def scrollChanged( self, widget ):
+ val = self.hadjustment.get_value()
+ if val == 0:
+ self.scrollLeft.set_sensitive( False )
+ else:
+ self.scrollLeft.set_sensitive( True )
+
+ if val >= self.hadjustment.get_property( "upper" ) - self.hadjustment.get_property("page_size"):
+ self.scrollRight.set_sensitive( False )
+ else:
+ self.scrollRight.set_sensitive( True )
def button_press( self, widget, event ):
pass
@@ -88,20 +151,62 @@ class Picker( gtk.HBox ):
class Instrument( Picker ):
- def __init__( self, owner, filter = None ):
+ def __init__( self, owner, filter = ( "all" ) ):
Picker.__init__( self, owner, filter )
self.type = Instrument
- # TEMP
- self.addBlock( Config.INSTRUMENTS["kalimba"].instrumentId )
- self.addBlock( Config.INSTRUMENTS["flute"].instrumentId )
+ self.instrumentDB = InstrumentDB.getRef()
+
+ for inst in self.instrumentDB.getSet( "all" ):
+ self.addBlock( inst.id )
def addBlock( self, id ):
# match data structure of Block.Instrument
- data = { "name": Config.INSTRUMENTSID[id].name,
+ data = { "name": _(Config.INSTRUMENTSID[id].name),
"id": id }
- Picker.addBlock( self, data, Config.INSTRUMENTSID[id].name )
+
+ win = gtk.gdk.get_default_root_window()
+ width = Block.Instrument.WIDTH
+ height = Block.Instrument.HEIGHT
+ pixmap = gtk.gdk.Pixmap( win, width, height )
+
+ self.gc.set_clip_rectangle( gtk.gdk.Rectangle( 0, 0, width, height ) )
+
+ # draw bg
+ self.gc.foreground = self.colors["Picker_Bg"]
+ pixmap.draw_rectangle( self.gc, True, 0, 0, width, height )
+
+ self.gc.set_clip_mask( self.clipMask )
+
+ # draw border
+ self.gc.foreground = self.colors["Border_Inactive"]
+ self.gc.set_clip_origin( -Block.Instrument.MASK_START, 0 )
+ pixmap.draw_rectangle( self.gc, True, 0, 0, width, height )
+
+ # draw block
+ inst = self.owner.getInstrumentImage( data["id"] )
+ self.gc.set_clip_origin( -Block.Instrument.MASK_START, -height )
+ pixmap.draw_drawable( self.gc, inst, 0, 0, 0, 0, width, height )
+
+ image = gtk.Image()
+ image.set_from_pixmap( pixmap, None )
+
+ block = gtk.EventBox()
+ block.modify_bg( gtk.STATE_NORMAL, self.colors["Picker_Bg"] )
+ block.add( image )
+
+ Picker.addBlock( self, data, data["name"], block )
+
+ def _testAgainstFilter( self, block ):
+ if "all" in self.filter:
+ return True
+
+ for label in self.instrumentDB.getInstrument( block.data["id"] ).labels:
+ if label in self.filter:
+ return True
+
+ return False
def button_press( self, widget, event ):
walloc = widget.get_allocation()
@@ -117,17 +222,47 @@ class Drum( Picker ):
self.type = Drum
- # TEMP
- self.addBlock( Config.INSTRUMENTS["drum1kit"].instrumentId )
- self.addBlock( Config.INSTRUMENTS["drum2kit"].instrumentId )
- self.addBlock( Config.INSTRUMENTS["drum3kit"].instrumentId )
- self.addBlock( Config.INSTRUMENTS["drum4kit"].instrumentId )
+ self.instrumentDB = InstrumentDB.getRef()
+
+ for inst in self.instrumentDB.getSet( "kit" ):
+ self.addBlock( inst.id )
def addBlock( self, id ):
# match data structure of Block.Drum
- data = { "name": Config.INSTRUMENTSID[id].name,
+ data = { "name": _(Config.INSTRUMENTSID[id].name),
"id": id }
- Picker.addBlock( self, data, Config.INSTRUMENTSID[id].name )
+
+ win = gtk.gdk.get_default_root_window()
+ width = Block.Drum.WIDTH
+ height = Block.Drum.HEIGHT
+ pixmap = gtk.gdk.Pixmap( win, width, height )
+
+ self.gc.set_clip_rectangle( gtk.gdk.Rectangle( 0, 0, width, height ) )
+
+ # draw bg
+ self.gc.foreground = self.colors["Picker_Bg"]
+ pixmap.draw_rectangle( self.gc, True, 0, 0, width, height )
+
+ self.gc.set_clip_mask( self.clipMask )
+
+ # draw border
+ self.gc.foreground = self.colors["Border_Inactive"]
+ self.gc.set_clip_origin( -Block.Drum.MASK_START, 0 )
+ pixmap.draw_rectangle( self.gc, True, 0, 0, width, height )
+
+ # draw block
+ inst = self.owner.getInstrumentImage( data["id"] )
+ self.gc.set_clip_origin( -Block.Drum.MASK_START, -height )
+ pixmap.draw_drawable( self.gc, inst, 0, 0, 0, 0, width, height )
+
+ image = gtk.Image()
+ image.set_from_pixmap( pixmap, None )
+
+ block = gtk.EventBox()
+ block.modify_bg( gtk.STATE_NORMAL, self.colors["Picker_Bg"] )
+ block.add( image )
+
+ Picker.addBlock( self, data, data["name"], block )
def button_press( self, widget, event ):
walloc = widget.get_allocation()
@@ -166,9 +301,6 @@ class Loop( Picker ):
except OSError,e:
print 'ERROR: failed to open file %s for reading\n' % ofilename
-
-
-
def _scanDirectory( self, path ):
pass
diff --git a/Jam/Toolbars.py b/Jam/Toolbars.py
new file mode 100644
index 0000000..ecb710b
--- /dev/null
+++ b/Jam/Toolbars.py
@@ -0,0 +1,13 @@
+
+import pygtk
+pygtk.require( '2.0' )
+import gtk
+
+class DesktopToolbar( gtk.Toolbar ):
+
+ def __init__( self, owner ):
+ gtk.Toolbar.__init__( self )
+
+ self.owner = owner
+
+