Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/Jam
diff options
context:
space:
mode:
authoramartin <olpc@xo-05-28-21.localdomain>2007-08-31 05:25:21 (GMT)
committer amartin <olpc@xo-05-28-21.localdomain>2007-08-31 05:25:21 (GMT)
commitc72c8119c18fca5f277cb3efd61acead578cd4d0 (patch)
tree58d69c906cd51ca1385db14608b36c01a43fe8f5 /Jam
parent0696bd1e480debac4a9a134954767e2086e33241 (diff)
jam popups
Diffstat (limited to 'Jam')
-rw-r--r--Jam/Block.py21
-rw-r--r--Jam/Desktop.py25
-rw-r--r--Jam/JamMain.py31
-rw-r--r--Jam/Picker.py24
-rw-r--r--Jam/Popup.py142
-rw-r--r--Jam/Toolbars.py7
6 files changed, 209 insertions, 41 deletions
diff --git a/Jam/Block.py b/Jam/Block.py
index 424b257..9857715 100644
--- a/Jam/Block.py
+++ b/Jam/Block.py
@@ -150,6 +150,12 @@ class Block():
self.active = state
self.invalidate_rect( not self.dragging )
+ def getData( self, key ):
+ return self.data[ key ]
+
+ def setData( self, key, value ):
+ self.data[ key ] = value
+
def button_press( self, event ):
if event.y < self.y or event.y > self.endY:
@@ -244,7 +250,7 @@ class Instrument(Block):
MASK_START = 0
#::: data format:
- # { "name": name, "id": instrumentId [, "volume": 0-1 ] }
+ # { "name": name, "id": instrumentId [, "volume": 0-1, "pan": 0-1, "reverb": 0-1 ] }
#:::
def __init__( self, owner, data ):
Block.__init__( self, owner, data )
@@ -256,10 +262,19 @@ class Instrument(Block):
if not "volume" in self.data.keys():
self.data["volume"] = 0.5
+ if not "pan" in self.data.keys():
+ self.data["pan"] = 0.5
+ if not "reverb" in self.data.keys():
+ self.data["reverb"] = 0
self.img = [ self.owner.getInstrumentImage( self.data["id"], False ),
self.owner.getInstrumentImage( self.data["id"], True ) ]
+ def setData( self, key, value ):
+ self.data[ key ] = value
+ if self.active:
+ self.owner.updateInstrument( self )
+
def substitute( self, block ):
self.data["id"] = block.data["id"]
self.img = [ self.owner.getInstrumentImage( self.data["id"], False ),
@@ -319,7 +334,7 @@ class Drum(Block):
MASK_START = 100
#::: data format:
- # { "name": name, "id": instrumentId [, "volume": 0-1, "beats": 2-12, "regularity": 0-1, "seed": 0-1 ] }
+ # { "name": name, "id": instrumentId [, "volume": 0-1, "reverb": 0-1, "beats": 2-12, "regularity": 0-1, "seed": 0-1 ] }
#:::
def __init__( self, owner, data ):
Block.__init__( self, owner, data )
@@ -330,6 +345,8 @@ class Drum(Block):
if not "volume" in self.data.keys():
self.data["volume"] = 0.5
+ if not "reverb" in self.data.keys():
+ self.data["reverb"] = 0.5
if not "beats" in self.data.keys():
self.data["beats"] = random.randint(2, 12)
if not "regularity" in self.data.keys():
diff --git a/Jam/Desktop.py b/Jam/Desktop.py
index 9ad134c..568695d 100644
--- a/Jam/Desktop.py
+++ b/Jam/Desktop.py
@@ -6,9 +6,9 @@ import gtk
import Config
from gettext import gettext as _
-from sugar.graphics.palette import Palette, WidgetInvoker
-import Jam.Block as Block
+from Jam import Block
+from Jam import Popup
class Desktop( gtk.EventBox ):
@@ -54,7 +54,10 @@ class Desktop( gtk.EventBox ):
#-- Popups --------------------------------------------
self.rightClicked = False
- # TODO
+
+ self.popup = {}
+ self.popup[Popup.Shortcut] = Popup.Shortcut( _("Assign Key"), self.owner )
+ self.popup[Popup.Instrument] = Popup.Instrument( _("Instrument Properties"), self.owner )
def dumpToStream( self, ostream ):
for b in self.blocks:
@@ -152,8 +155,12 @@ class Desktop( gtk.EventBox ):
block.setActive( True )
self.activeInstrument = block
+
+ self.updateInstrument( block )
+
+ def updateInstrument( self, block ):
data = block.data
- self.owner._updateInstrument( data["id"], data["volume"] )
+ self.owner._updateInstrument( data["id"], data["volume"], data["pan"], data["reverb"] )
def activateDrum( self, block ):
if self.activeDrum:
@@ -175,7 +182,7 @@ class Desktop( gtk.EventBox ):
def updateDrum( self ):
data = self.activeDrum.data
- self.owner._playDrum( data["id"], data["volume"], data["beats"], data["regularity"], data["seed"] )
+ self.owner._playDrum( data["id"], data["volume"], data["reverb"], data["beats"], data["regularity"], data["seed"] )
def activateLoop( self, block ):
block.setActive( True )
@@ -225,8 +232,13 @@ class Desktop( gtk.EventBox ):
def on_button_release( self, widget, event ):
if event.button == 3: # Right Click
+ if self.clickedBlock:
+ if self.clickedBlock.type == Block.Instrument:
+ self.popup[Popup.Instrument].setBlock( self.clickedBlock )
+ self.popup[Popup.Instrument].popup()
+
+ self.clickedBlock = None
self.rightClicked = False
- self.clickedBlock = None
return
if self.possibleDelete:
@@ -399,4 +411,3 @@ class Desktop( gtk.EventBox ):
self.drawingArea.window.invalidate_rect( self.dirtyRectToAdd, True )
self.drawingAreaDirty = True
-
diff --git a/Jam/JamMain.py b/Jam/JamMain.py
index d3c8826..dd21be8 100644
--- a/Jam/JamMain.py
+++ b/Jam/JamMain.py
@@ -43,13 +43,12 @@ class JamMain(SubActivity):
#-- initial settings ----------------------------------
self.tempo = Config.PLAYER_TEMPO
- self.volume = 50
- self.reverb = 0
+ self.volume = 0.5
self.csnd = new_csound_client()
for i in range(0,9):
self.csnd.setTrackVolume( 100, i )
- self.csnd.setMasterVolume( self.volume )
+ self.csnd.setMasterVolume( self.volume*100 ) # csnd expects a range 0-100 for now
self.csnd.setTempo( self.tempo )
#-- Drawing -------------------------------------------
@@ -70,6 +69,7 @@ class JamMain(SubActivity):
self.gc = gtk.gdk.GC( win )
colormap = gtk.gdk.colormap_get_system()
self.colors = { "bg": colormap.alloc_color( Config.PANEL_BCK_COLOR ),
+ "black": colormap.alloc_color( style.COLOR_BLACK.get_html() ),
"Picker_Bg": colormap.alloc_color( "#404040" ),
"Picker_Bg_Inactive": colormap.alloc_color( "#808080" ),
#"Picker_Bg": colormap.alloc_color( style.COLOR_TOOLBAR_GREY.get_html() ),
@@ -223,7 +223,7 @@ class JamMain(SubActivity):
#-- Drums ---------------------------------------------
self.drumLoopId = None
# use dummy values for now
- self.drumFillin = Fillin( 2, 100, Config.INSTRUMENTS["drum1kit"].instrumentId, self.reverb, 1 )
+ self.drumFillin = Fillin( 2, 100, Config.INSTRUMENTS["drum1kit"].instrumentId, 0, 1 )
#-- Desktops ------------------------------------------
self.curDesktop = None
@@ -270,7 +270,7 @@ class JamMain(SubActivity):
if Config.KEY_MAP_PIANO.has_key( key ):
pitch = Config.KEY_MAP_PIANO[key]
- inst = Config.INSTRUMENTS[self.instrument["name"]]
+ inst = Config.INSTRUMENTSID[self.instrument["id"]]
if inst.kit: # drum kit
if pitch in GenerationConstants.DRUMPITCH:
@@ -331,14 +331,13 @@ class JamMain(SubActivity):
self.csnd.play(csnote, 0.3)
del self.key_dict[key]
- def _updateInstrument( self, id, volume ):
- self.instrument = { "name": Config.INSTRUMENTSID[id].name,
- "id": id,
- "amplitude": sqrt( self.volume*volume*0.1 ),
- "pan": 0.5,
- "reverb": self.reverb }
-
- def _playDrum( self, id, volume, beats, regularity, seed ):
+ def _updateInstrument( self, id, volume, pan = 0, reverb = 0 ):
+ self.instrument = { "id": id,
+ "amplitude": volume,
+ "pan": pan,
+ "reverb": reverb }
+
+ def _playDrum( self, id, volume, reverb, beats, regularity, seed ):
def flatten(ll):
rval = []
for l in ll:
@@ -353,7 +352,7 @@ class JamMain(SubActivity):
noteOnsets = []
notePitchs = []
i = 0
- for x in flatten( generator( Config.INSTRUMENTSID[id].name, beats, 0.8, regularity, self.reverb) ):
+ for x in flatten( generator( Config.INSTRUMENTSID[id].name, beats, 0.8, regularity, reverb) ):
x.amplitude = x.amplitude * volume
noteOnsets.append(x.onset)
notePitchs.append(x.pitch)
@@ -363,7 +362,7 @@ class JamMain(SubActivity):
self.csnd.loopSetNumTicks( beats * Config.TICKS_PER_BEAT, self.drumLoopId )
self.drumFillin.setLoopId( self.drumLoopId )
- self.drumFillin.setProperties( self.tempo, Config.INSTRUMENTSID[id].name, volume, beats, self.reverb )
+ self.drumFillin.setProperties( self.tempo, Config.INSTRUMENTSID[id].name, volume, beats, reverb )
self.drumFillin.unavailable( noteOnsets, notePitchs )
self.drumFillin.play()
@@ -427,7 +426,7 @@ class JamMain(SubActivity):
def _setVolume( self, volume ):
self.volume = volume
- self.csnd.setMasterVolume( self.volume )
+ self.csnd.setMasterVolume( self.volume*100 ) # csnd expects a range 0-100 for now
def getTempo( self ):
return self.tempo
diff --git a/Jam/Picker.py b/Jam/Picker.py
index f41f1b2..ad136da 100644
--- a/Jam/Picker.py
+++ b/Jam/Picker.py
@@ -39,7 +39,6 @@ class Picker( gtk.HBox ):
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()
@@ -80,9 +79,9 @@ class Picker( gtk.HBox ):
| 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 )
+ block.connect( "button-press-event", self.on_button_press )
+ block.connect( "button-release-event", self.on_button_release )
+ block.connect( "motion-notify-event", self.on_motion_notify )
block.data = data
self.blocks.append( block )
@@ -141,14 +140,14 @@ class Picker( gtk.HBox ):
else:
self.scrollRight.set_sensitive( True )
- def button_press( self, widget, event ):
+ def on_button_press( self, widget, event ):
pass
- def button_release( self, widget, event ):
- self.desktop.button_release( widget, event )
+ def on_button_release( self, widget, event ):
+ self.desktop.on_button_release( widget, event )
- def motion_notify( self, widget, event ):
- self.desktop.motion_notify( widget, event )
+ def on_motion_notify( self, widget, event ):
+ self.desktop.on_motion_notify( widget, event )
class Instrument( Picker ):
@@ -210,7 +209,7 @@ class Instrument( Picker ):
return False
- def button_press( self, widget, event ):
+ def on_button_press( self, widget, event ):
walloc = widget.get_allocation()
salloc = self.scrolledWindow.get_allocation()
loc = ( walloc.x + salloc.x + event.x - self.hadjustment.get_value(), -1 )
@@ -268,7 +267,7 @@ class Drum( Picker ):
Picker.addBlock( self, data, data["name"], block )
- def button_press( self, widget, event ):
+ def on_button_press( self, widget, event ):
walloc = widget.get_allocation()
salloc = self.scrolledWindow.get_allocation()
loc = ( walloc.x + salloc.x + event.x - self.hadjustment.get_value(), -1 )
@@ -405,8 +404,7 @@ class Loop( Picker ):
Picker.addBlock( self, data, data["name"], block )
-
- def button_press( self, widget, event ):
+ def on_button_press( self, widget, event ):
walloc = widget.get_allocation()
salloc = self.scrolledWindow.get_allocation()
loc = ( walloc.x + salloc.x + event.x - self.hadjustment.get_value(), -1 )
diff --git a/Jam/Popup.py b/Jam/Popup.py
new file mode 100644
index 0000000..1e4f326
--- /dev/null
+++ b/Jam/Popup.py
@@ -0,0 +1,142 @@
+
+import pygtk
+pygtk.require( '2.0' )
+import gtk
+
+import Config
+
+from gettext import gettext as _
+from sugar.graphics import style
+from sugar.graphics.palette import Palette, WidgetInvoker
+
+
+class Popup( Palette ):
+
+ def __init__( self, label, owner ):
+ Palette.__init__( self, label )
+
+ self.owner = owner
+
+ self.props.invoker = WidgetInvoker( gtk.HBox() ) # garbage invoker
+ self.set_property( "position", Palette.AT_CURSOR )
+ self.set_group_id( "TamTamPopup" )
+
+ self.connect( "key-press-event", self.owner.onKeyPress )
+ self.connect( "key-release-event", self.owner.onKeyRelease )
+
+ self.connect( "focus_out_event", self.closePopup )
+
+ def _leave_notify_event_cb( self, widget, event ):
+ pass # don't popdown()
+
+ def popup( self, immediate = False ):
+ self.owner.activity.handler_block(self.owner.activity.focusOutHandler)
+ self.owner.activity.handler_block(self.owner.activity.focusInHandler)
+
+ Palette.popup( self, immediate )
+
+ def popdown( self, immediate = False ):
+ Palette.popdown( self, immediate )
+
+ self.owner.activity.handler_unblock(self.owner.activity.focusOutHandler)
+ self.owner.activity.handler_unblock(self.owner.activity.focusInHandler)
+
+ def closePopup( self, widget, event ):
+ self.popdown()
+
+
+class Instrument( Popup ):
+
+ def __init__( self, label, owner ):
+ Popup.__init__( self, label, owner )
+
+ self.GUI = {}
+
+ self.GUI["mainBox"] = gtk.VBox()
+ self.set_content( self.GUI["mainBox"] )
+
+ #-- Volume --------------------------------------------
+ self.GUI["volumeBox"] = gtk.HBox()
+ self.GUI["mainBox"].pack_start( self.GUI["volumeBox"], padding = style.DEFAULT_PADDING )
+ self.GUI["volumeLabel"] = gtk.Label( _("Volume:") )
+ self.GUI["volumeLabel"].set_size_request( 100, -1 )
+ self.GUI["volumeLabel"].set_alignment( 0.0, 0.5 )
+ self.GUI["volumeBox"].pack_start( self.GUI["volumeLabel"], False, padding = style.DEFAULT_PADDING )
+ self.GUI["volumeAdjustment"] = gtk.Adjustment( 0.5, 0.0, 1.0, 0.1, 0.1, 0 )
+ self.GUI["volumeAdjustment"].connect( 'value-changed', self.handleVolume )
+ self.GUI["volumeSlider"] = gtk.HScale( adjustment = self.GUI["volumeAdjustment"] )
+ self.GUI["volumeSlider"].set_size_request( 250, -1 )
+ self.GUI["volumeSlider"].set_draw_value( False )
+ self.GUI["volumeBox"].pack_start( self.GUI["volumeSlider"], False, padding = style.DEFAULT_PADDING )
+ self.GUI["volumeImage"] = gtk.Image()
+ self.GUI["volumeBox"].pack_start( self.GUI["volumeImage"], False, padding = style.DEFAULT_PADDING )
+
+ #-- Pan -----------------------------------------------
+ self.GUI["panBox"] = gtk.HBox()
+ self.GUI["mainBox"].pack_start( self.GUI["panBox"], padding = style.DEFAULT_PADDING )
+ self.GUI["panLabel"] = gtk.Label( _("Pan:") )
+ self.GUI["panLabel"].set_size_request( 100, -1 )
+ self.GUI["panLabel"].set_alignment( 0.0, 0.5 )
+ self.GUI["panBox"].pack_start( self.GUI["panLabel"], False, padding = style.DEFAULT_PADDING )
+ self.GUI["panAdjustment"] = gtk.Adjustment( 0.5, 0, 1.0, 0.1, 0.1, 0 )
+ self.GUI["panAdjustment"].connect( 'value-changed', self.handlePan )
+ self.GUI["panSlider"] = gtk.HScale( adjustment = self.GUI["panAdjustment"] )
+ self.GUI["panSlider"].set_size_request( 250, -1 )
+ self.GUI["panSlider"].set_draw_value( False )
+ self.GUI["panBox"].pack_start( self.GUI["panSlider"], False, padding = style.DEFAULT_PADDING )
+ self.GUI["panImage"] = gtk.Image()
+ self.GUI["panBox"].pack_start( self.GUI["panImage"], False, padding = style.DEFAULT_PADDING )
+
+ #-- Reverb --------------------------------------------
+ self.GUI["reverbBox"] = gtk.HBox()
+ self.GUI["mainBox"].pack_start( self.GUI["reverbBox"], padding = style.DEFAULT_PADDING )
+ self.GUI["reverbLabel"] = gtk.Label( _("Reverb:") )
+ self.GUI["reverbLabel"].set_size_request( 100, -1 )
+ self.GUI["reverbLabel"].set_alignment( 0.0, 0.5 )
+ self.GUI["reverbBox"].pack_start( self.GUI["reverbLabel"], False, padding = style.DEFAULT_PADDING )
+ self.GUI["reverbAdjustment"] = gtk.Adjustment( 0.5, 0, 1.0, 0.1, 0.1, 0 )
+ self.GUI["reverbAdjustment"].connect( 'value-changed', self.handleReverb )
+ self.GUI["reverbSlider"] = gtk.HScale( adjustment = self.GUI["reverbAdjustment"] )
+ self.GUI["reverbSlider"].set_size_request( 250, -1 )
+ self.GUI["reverbSlider"].set_draw_value( False )
+ self.GUI["reverbBox"].pack_start( self.GUI["reverbSlider"], False, padding = style.DEFAULT_PADDING )
+ self.GUI["reverbImage"] = gtk.Image()
+ self.GUI["reverbBox"].pack_start( self.GUI["reverbImage"], False, padding = style.DEFAULT_PADDING )
+
+ self.GUI["separator"] = gtk.HSeparator()
+ self.GUI["mainBox"].pack_start( self.GUI["separator"], padding = style.DEFAULT_PADDING )
+
+ #-- Export --------------------------------------------
+ self.GUI["exportBox"] = gtk.HBox()
+ self.GUI["mainBox"].pack_start( self.GUI["exportBox"], padding = style.DEFAULT_PADDING )
+ self.GUI["exportEntry"] = gtk.Entry()
+ self.GUI["exportEntry"].modify_fg( gtk.STATE_NORMAL, self.owner.colors["black"] )
+ self.GUI["exportEntry"].modify_fg( gtk.STATE_ACTIVE, self.owner.colors["black"] )
+ self.GUI["exportBox"].pack_start( self.GUI["exportEntry"], padding = style.DEFAULT_PADDING )
+ self.GUI["exportButton"] = gtk.Button( "Export" )
+ self.GUI["exportBox"].pack_start( self.GUI["exportButton"], False, padding = style.DEFAULT_PADDING )
+
+ self.GUI["mainBox"].show_all()
+
+ def setBlock( self, block ):
+ self.block = block
+ self.GUI["volumeAdjustment"].set_value( block.getData( "volume" ) )
+ self.GUI["panAdjustment"].set_value( block.getData( "pan" ) )
+ self.GUI["reverbAdjustment"].set_value( block.getData( "reverb" ) )
+ self.GUI["exportEntry"].set_text( block.getData( "name" ) )
+
+ def handleVolume( self, widget ):
+ self.block.setData( "volume", widget.get_value() )
+
+ def handlePan( self, widget ):
+ self.block.setData( "pan", widget.get_value() )
+
+ def handleReverb( self, widget ):
+ self.block.setData( "reverb", widget.get_value() )
+
+class Shortcut( Popup ):
+
+ def __init__( self, label, owner ):
+ Popup.__init__( self, label, owner )
+
+
diff --git a/Jam/Toolbars.py b/Jam/Toolbars.py
index 3514708..29d034b 100644
--- a/Jam/Toolbars.py
+++ b/Jam/Toolbars.py
@@ -10,6 +10,7 @@ from sugar.graphics.radiotoolbutton import RadioToolButton
import Config
+
class JamToolbar( gtk.Toolbar ):
def __init__( self, owner ):
@@ -23,7 +24,7 @@ class JamToolbar( gtk.Toolbar ):
self.volumeImg.set_from_file( Config.IMAGE_ROOT + 'volume2.png' )
self._insert_widget( self.volumeImg, -1 )
- self.volumeAdjustment = gtk.Adjustment( 50, 0, 100+1, 10, 10, 1 )
+ self.volumeAdjustment = gtk.Adjustment( 0.5, 0, 1.0, 0.1, 0.1, 0 )
self.volumeAdjustment.connect( 'value-changed', self.handleVolume )
self.volumeSlider = gtk.HScale( adjustment = self.volumeAdjustment )
self.volumeSlider.set_size_request( 450, -1 )
@@ -37,7 +38,7 @@ class JamToolbar( gtk.Toolbar ):
self.tempoImg.set_from_file( Config.IMAGE_ROOT + 'tempo2.png' )
self._insert_widget( self.tempoImg, -1 )
- self.tempoAdjustment = gtk.Adjustment( Config.PLAYER_TEMPO, Config.PLAYER_TEMPO_LOWER, Config.PLAYER_TEMPO_UPPER+1, 10, 10, 1 )
+ self.tempoAdjustment = gtk.Adjustment( Config.PLAYER_TEMPO, Config.PLAYER_TEMPO_LOWER, Config.PLAYER_TEMPO_UPPER+1, 10, 10, 0 )
self.tempoAdjustment.connect( 'value-changed', self.handleTempo )
self.tempoSlider = gtk.HScale( adjustment = self.tempoAdjustment )
self.tempoSlider.set_size_request( 450, -1 )
@@ -100,7 +101,7 @@ class DesktopToolbar( gtk.Toolbar ):
btn.set_tooltip( _('Desktop 1') )
self.insert( btn, -1 )
self.desktop.append( btn )
-
+
for i in range(2,11):
btn = RadioToolButton( 'preset%d'%i, group = self.desktop[0] )
btn.connect( 'toggled', self.setDesktop, i-1 )