Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/TamTamEdit.activity/Edit/MainWindow.py
diff options
context:
space:
mode:
authorNat <natcl@hotmail.com>2007-09-13 15:55:52 (GMT)
committer Nat <natcl@hotmail.com>2007-09-13 15:55:52 (GMT)
commite12dbff4dda5aafbaac98f75f0467ef00dc06c32 (patch)
tree52f74f5a699ca1a2827b333e76a7225b7d768256 /TamTamEdit.activity/Edit/MainWindow.py
parentb94ccdfd2329ed2d1128a4392e2f67b1e6b704da (diff)
Activity split
Diffstat (limited to 'TamTamEdit.activity/Edit/MainWindow.py')
-rw-r--r--TamTamEdit.activity/Edit/MainWindow.py2091
1 files changed, 2091 insertions, 0 deletions
diff --git a/TamTamEdit.activity/Edit/MainWindow.py b/TamTamEdit.activity/Edit/MainWindow.py
new file mode 100644
index 0000000..58f82f1
--- /dev/null
+++ b/TamTamEdit.activity/Edit/MainWindow.py
@@ -0,0 +1,2091 @@
+import pygtk
+pygtk.require( '2.0' )
+import gtk
+
+import gobject
+
+from Util.ThemeWidgets import *
+from Util.Profiler import TP
+from Util import NoteDB
+from Util.NoteDB import PARAMETER
+from Util import ControlStream
+from Util.CSoundClient import new_csound_client
+from Util.InstrumentPanel import InstrumentPanel
+from Util.InstrumentPanel import DrumPanel
+from Util.CSoundNote import CSoundNote
+from EditToolbars import mainToolbar
+from EditToolbars import generateToolbar
+from gettext import gettext as _
+from subprocess import Popen
+from sugar.graphics.palette import Palette, WidgetInvoker
+import time
+import os
+import commands
+import random
+
+class CONTEXT:
+ PAGE = 0
+ TRACK = 1
+ NOTE = 2
+
+import Config
+from SubActivity import SubActivity
+
+from Generation.GenerationConstants import GenerationConstants
+from Generation.GenerationParametersWindow import GenerationParametersWindow
+from Edit.Properties import Properties
+from Edit.TrackInterface import TrackInterface, TrackInterfaceParasite
+from Edit.TuneInterface import TuneInterface, TuneInterfaceParasite
+
+from Generation.Generator import generator1, GenerationParameters
+
+Tooltips = Config.Tooltips()
+KEY_MAP_PIANO = Config.KEY_MAP_PIANO
+
+#-----------------------------------
+# The main TamTam window
+#-----------------------------------
+class MainWindow( SubActivity ):
+
+ def __init__( self, activity, set_mode ):
+ self.csnd = new_csound_client()
+ self.tooltips = gtk.Tooltips()
+ self.activity = activity
+ for i in [6,7,8,9,10]:
+ self.csnd.setTrackVolume(100, i)
+ self.trackCount = 6
+
+ self.scale = GenerationConstants.DEFAULT_SCALE
+
+ # META ALGO: [section, variation or not, nPages] A B A C
+ # TODO: Different parameters sets for each tracks
+ self.tuneForm = [[0, False, 4], [1, False, 4], [0, True, 4], [2, False, 2]]
+
+ def init_data( ):
+ TP.ProfileBegin("init_data")
+ self._data = {}
+
+ #[ volume, ... ]
+ self._data['track_volume'] = [ Config.DEFAULT_VOLUME ] * Config.NUMBER_OF_TRACKS
+ self._data['track_mute'] = [ 1.0 ] * Config.NUMBER_OF_TRACKS
+
+ #[ instrument index, ... ]
+ self.trackInstrumentDefault = [
+ Config.INSTRUMENTS["kalimba"],
+ Config.INSTRUMENTS["kalimba"],
+ Config.INSTRUMENTS["kalimba"],
+ Config.INSTRUMENTS["kalimba"],
+ Config.INSTRUMENTS["drum2kit"] ]
+ self.trackInstrument = self.trackInstrumentDefault[:]
+ if len(self.trackInstrument) != Config.NUMBER_OF_TRACKS: raise 'error'
+ self.drumIndex = Config.NUMBER_OF_TRACKS - 1
+
+ #second instrument for melodic tracks
+ self.trackInstrument2Default = [ None, None, None, None]
+ self.trackInstrument2 = self.trackInstrument2Default[:]
+
+ self._data['volume'] = Config.DEFAULT_VOLUME
+ self._data['tempo'] = Config.PLAYER_TEMPO
+
+ self.playScope = "Selection"
+ self.displayedPage = -1
+ self.trackSelected = [ 0 for i in range(Config.NUMBER_OF_TRACKS) ]
+ self.trackActive = [ 1 for i in range(Config.NUMBER_OF_TRACKS) ]
+
+ self.pages_playing = []
+ self.journalCalled = True
+
+ self.noteDB = NoteDB.NoteDB()
+ TP.ProfileEnd("init_data")
+
+ def formatRoundBox( box, fillcolor ):
+ box.set_radius( 7 )
+ box.set_border_width( 1 )
+ box.set_fill_color( fillcolor )
+ box.set_border_color( Config.PANEL_BCK_COLOR )
+ return box
+
+ def init_GUI():
+
+ self.GUI = {}
+ self.GUI["2main"] = gtk.VBox()
+
+ def draw_inst_icons():
+ instrumentNames = [ k for k in Config.INSTRUMENTS.keys() if (k[0:4] != 'drum' and k[0:4] != 'guid') or Config.INSTRUMENTS[k].category == "kit" ]
+ self.GUI["2instrumentIcons"] = {}
+ for instrument in instrumentNames:
+ try:
+ self.GUI["2instrumentIcons"][instrument] = gtk.gdk.pixbuf_new_from_file(Config.IMAGE_ROOT + instrument + '.png')
+ except:
+ self.GUI["2instrumentIcons"][instrument] = gtk.gdk.pixbuf_new_from_file(Config.IMAGE_ROOT + 'generic.png')
+ TP.ProfileBegin("init_GUI::instrument icons")
+ draw_inst_icons()
+ TP.ProfileEnd("init_GUI::instrument icons")
+
+
+ #------------------------------------------------------------------------
+ # page
+ self.GUI["2page"] = gtk.HBox()
+ self.GUI["2main"].pack_start( self.GUI["2page"], False )
+ if 1: # + instrument panel
+ self.GUI["2instrumentPanel"] = gtk.VBox()
+ self.GUI["2instrumentPanel"].set_size_request( 132, -1 )
+ self.GUI["2page"].pack_start( self.GUI["2instrumentPanel"], False )
+ # + + instrument 1 box
+ self.GUI["2instrument1Box"] = formatRoundBox( RoundHBox(), Config.BG_COLOR )
+ self.GUI["2instrument1Box"].set_size_request( -1, 132 )
+ self.GUI["2instrument1volBox"] = gtk.VBox()
+ self.GUI["2instrument1volumeAdjustment"] = gtk.Adjustment( self._data["track_volume"][1], 0, 100, 1, 1, 0 )
+ #self.GUI["2instrument1volumeAdjustment"].connect( "value_changed", self.onTrackVolumeChanged, 0 )
+ self.GUI["2instrument1volumeSlider"] = gtk.VScale(self.GUI["2instrument1volumeAdjustment"])
+ self.GUI["2instrument1volumeSlider"].set_draw_value(False)
+ self.GUI["2instrument1volumeSlider"].set_inverted(True)
+ self.GUI["2instrument1volumeSlider"].set_size_request( 30, -1 )
+ self.GUI["2instrument1volumeAdjustment"].connect( "value-changed", self.handleTrackVolume, 0 )
+ self.GUI["2instrument1muteButton"] = ImageToggleButton(Config.IMAGE_ROOT+"checkOff.svg",Config.IMAGE_ROOT+"checkOn.svg")
+ self.GUI["2instrument1muteButton"].connect("toggled",self.handlemuteButton,0)
+ self.GUI["2instrument1muteButton"].connect("button-press-event",self.handlemuteButtonRightClick,0)
+ self.GUI["2instrument1muteButton"].set_active(True)
+ #self.GUI["2instrument1volBox"].pack_start( self.GUI["2instrument1volumeSlider"], True, True, 0 )
+ #self.GUI["2instrument1volBox"].pack_start( self.GUI["2instrument1muteButton"], False, False, 5 )
+ self.GUI["2instrument1Box"].pack_start( self.GUI["2instrument1volBox"], False, False, 0 )
+ self.GUI["2instrument1Button"] = InstrumentButton( self, 0, Config.BG_COLOR )
+ self.GUI["2instrument1Palette"] = instrumentPalette(_('Track 1 Volume'), 0, self)
+ self.GUI["2instrument1Button"].set_palette(self.GUI["2instrument1Palette"])
+ self.GUI["2instrument1Button"].setPrimary( self.GUI["2instrumentIcons"][self.trackInstrument[0].name] )
+ self.GUI["2instrument1Box"].pack_start( self.GUI["2instrument1Button"], padding = 3 )
+ self.GUI["2instrumentPanel"].pack_start( self.GUI["2instrument1Box"] )
+ # + + instrument 2 box
+ self.GUI["2instrument2Box"] = formatRoundBox( RoundHBox(), Config.BG_COLOR )
+ self.GUI["2instrument2Box"].set_size_request( -1, 132 )
+ self.GUI["2instrument2volBox"] = gtk.VBox()
+ self.GUI["2instrument2volumeAdjustment"] = gtk.Adjustment( self._data["track_volume"][1], 0, 100, 1, 1, 0 )
+ #self.GUI["2instrument2volumeAdjustment"].connect( "value_changed", self.onTrackVolumeChanged, 1 )
+ self.GUI["2instrument2volumeSlider"] = gtk.VScale(self.GUI["2instrument2volumeAdjustment"])
+ self.GUI["2instrument2volumeSlider"].set_draw_value(False)
+ self.GUI["2instrument2volumeSlider"].set_inverted(True)
+ self.GUI["2instrument2volumeSlider"].set_size_request( 30, -1 )
+ self.GUI["2instrument2volumeAdjustment"].connect( "value-changed", self.handleTrackVolume, 1 )
+ self.GUI["2instrument2muteButton"] = ImageToggleButton(Config.IMAGE_ROOT+"checkOff.svg",Config.IMAGE_ROOT+"checkOn.svg")
+ self.GUI["2instrument2muteButton"].connect("toggled",self.handlemuteButton,1)
+ self.GUI["2instrument2muteButton"].connect("button-press-event",self.handlemuteButtonRightClick,1)
+ self.GUI["2instrument2muteButton"].set_active(True)
+ #self.GUI["2instrument2volBox"].pack_start( self.GUI["2instrument2volumeSlider"], True, True, 0 )
+ #self.GUI["2instrument2volBox"].pack_start( self.GUI["2instrument2muteButton"], False, False, 5 )
+ self.GUI["2instrument2Box"].pack_start( self.GUI["2instrument2volBox"], False, False, 0 )
+ self.GUI["2instrument2Button"] = InstrumentButton( self, 1, Config.BG_COLOR )
+ self.GUI["2instrument2Palette"] = instrumentPalette(_('Track 2 Volume'), 1, self)
+ self.GUI["2instrument2Button"].set_palette(self.GUI["2instrument2Palette"])
+ self.GUI["2instrument2Button"].setPrimary( self.GUI["2instrumentIcons"][self.trackInstrument[1].name] )
+ self.GUI["2instrument2Box"].pack_start( self.GUI["2instrument2Button"], padding = 3 )
+ self.GUI["2instrumentPanel"].pack_start( self.GUI["2instrument2Box"] )
+ # + + instrument 3 box
+ self.GUI["2instrument3Box"] = formatRoundBox( RoundHBox(), Config.BG_COLOR )
+ self.GUI["2instrument3Box"].set_size_request( -1, 132 )
+ self.GUI["2instrument3volBox"] = gtk.VBox()
+ self.GUI["2instrument3volumeAdjustment"] = gtk.Adjustment( self._data["track_volume"][2], 0, 100, 1, 1, 0 )
+ #self.GUI["2instrument3volumeAdjustment"].connect( "value_changed", self.onTrackVolumeChanged, 2 )
+ self.GUI["2instrument3volumeSlider"] = gtk.VScale(self.GUI["2instrument3volumeAdjustment"])
+ self.GUI["2instrument3volumeSlider"].set_draw_value(False)
+ self.GUI["2instrument3volumeSlider"].set_inverted(True)
+ self.GUI["2instrument3volumeSlider"].set_size_request( 30, -1 )
+ self.GUI["2instrument3volumeAdjustment"].connect( "value-changed", self.handleTrackVolume, 2 )
+ self.GUI["2instrument3muteButton"] = ImageToggleButton(Config.IMAGE_ROOT+"checkOff.svg",Config.IMAGE_ROOT+"checkOn.svg")
+ self.GUI["2instrument3muteButton"].connect("toggled",self.handlemuteButton,2)
+ self.GUI["2instrument3muteButton"].connect("button-press-event",self.handlemuteButtonRightClick,2)
+ self.GUI["2instrument3muteButton"].set_active(True)
+ #self.GUI["2instrument3volBox"].pack_start( self.GUI["2instrument3volumeSlider"], True, True, 0 )
+ #self.GUI["2instrument3volBox"].pack_start( self.GUI["2instrument3muteButton"], False, False, 5 )
+ self.GUI["2instrument3Box"].pack_start( self.GUI["2instrument3volBox"], False, False, 0 )
+ self.GUI["2instrument3Button"] = InstrumentButton( self, 2, Config.BG_COLOR )
+ self.GUI["2instrument3Palette"] = instrumentPalette(_('Track 3 Volume'), 2, self)
+ self.GUI["2instrument3Button"].set_palette(self.GUI["2instrument3Palette"])
+ self.GUI["2instrument3Button"].setPrimary( self.GUI["2instrumentIcons"][self.trackInstrument[2].name] )
+ self.GUI["2instrument3Box"].pack_start( self.GUI["2instrument3Button"], padding = 3 )
+ self.GUI["2instrumentPanel"].pack_start( self.GUI["2instrument3Box"] )
+ # + + instrument 4 box
+ self.GUI["2instrument4Box"] = formatRoundBox( RoundHBox(), Config.BG_COLOR )
+ self.GUI["2instrument4Box"].set_size_request( -1, 132 )
+ self.GUI["2instrument4volBox"] = gtk.VBox()
+ self.GUI["2instrument4volumeAdjustment"] = gtk.Adjustment( self._data["track_volume"][3], 0, 100, 1, 1, 0 )
+ #self.GUI["2instrument4volumeAdjustment"].connect( "value_changed", self.onTrackVolumeChanged, 3 )
+ self.GUI["2instrument4volumeSlider"] = gtk.VScale(self.GUI["2instrument4volumeAdjustment"])
+ self.GUI["2instrument4volumeSlider"].set_draw_value(False)
+ self.GUI["2instrument4volumeSlider"].set_inverted(True)
+ self.GUI["2instrument4volumeSlider"].set_size_request( 30, -1 )
+ self.GUI["2instrument4volumeAdjustment"].connect( "value-changed", self.handleTrackVolume, 3 )
+ self.GUI["2instrument4muteButton"] = ImageToggleButton(Config.IMAGE_ROOT+"checkOff.svg",Config.IMAGE_ROOT+"checkOn.svg")
+ self.GUI["2instrument4muteButton"].connect("toggled",self.handlemuteButton,3)
+ self.GUI["2instrument4muteButton"].connect("button-press-event",self.handlemuteButtonRightClick,3)
+ self.GUI["2instrument4muteButton"].set_active(True)
+ #self.GUI["2instrument4volBox"].pack_start( self.GUI["2instrument4volumeSlider"], True, True, 0 )
+ #self.GUI["2instrument4volBox"].pack_start( self.GUI["2instrument4muteButton"], False, False, 5 )
+ self.GUI["2instrument4Box"].pack_start( self.GUI["2instrument4volBox"], False, False, 0 )
+ self.GUI["2instrument4Button"] = InstrumentButton( self, 3, Config.BG_COLOR )
+ self.GUI["2instrument4Palette"] = instrumentPalette(_('Track 4 Volume'), 3, self)
+ self.GUI["2instrument4Button"].set_palette(self.GUI["2instrument4Palette"])
+ self.GUI["2instrument4Button"].setPrimary( self.GUI["2instrumentIcons"][self.trackInstrument[3].name] )
+ self.GUI["2instrument4Box"].pack_start( self.GUI["2instrument4Button"], padding = 3 )
+ 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["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 )
+ self.GUI["2drumvolumeSlider"] = gtk.VScale(self.GUI["2drumvolumeAdjustment"])
+ self.GUI["2drumvolumeSlider"].set_draw_value(False)
+ self.GUI["2drumvolumeSlider"].set_inverted(True)
+ self.GUI["2drumvolumeSlider"].set_size_request( 30, -1 )
+ self.GUI["2drumvolumeAdjustment"].connect( "value-changed", self.handleTrackVolume, 4 )
+ self.GUI["2drumMuteButton"] = ImageToggleButton(Config.IMAGE_ROOT+"checkOff.svg",Config.IMAGE_ROOT+"checkOn.svg")
+ self.GUI["2drumMuteButton"].connect("toggled",self.handlemuteButton,4)
+ self.GUI["2drumMuteButton"].connect("button-press-event",self.handlemuteButtonRightClick,4)
+ self.GUI["2drumMuteButton"].set_active(True)
+ #self.GUI["2drumVolBox"].pack_start( self.GUI["2drumvolumeSlider"], True, True, 0 )
+ #self.GUI["2drumVolBox"].pack_start( self.GUI["2drumMuteButton"], False, False, 5 )
+ self.GUI["2drumBox"].pack_start( self.GUI["2drumVolBox"], False, False, 0 )
+ self.GUI["2drumButton"] = ImageToggleButton(Config.IMAGE_ROOT + self.trackInstrument[4].name + '.png', Config.IMAGE_ROOT + self.trackInstrument[4].name + '.png')
+ self.GUI["2drumPalette"] = instrumentPalette(_('Track 5 Volume'), 4, self)
+ self.GUI["2drumButton"].set_palette(self.GUI["2drumPalette"])
+ self.GUI["2drumButton"].connect("toggled", self.pickDrum)
+ self.GUI["2drumButton"].connect('enter-notify-event', self.blockFocus)
+ self.GUI["2drumButton"].connect('leave-notify-event', self.unblockFocus)
+ self.GUI["2drumBox"].pack_start( self.GUI["2drumButton"] )
+ self.GUI["2instrumentPanel"].pack_start( self.GUI["2drumBox"] )
+ self.GUI["2page"].pack_start( self.GUI["2instrumentPanel"], False )
+ # + track interface
+ self.trackInterface = TrackInterface( self.noteDB, self, self.getScale )
+ self.noteDB.addListener( self.trackInterface, TrackInterfaceParasite, True )
+ self.trackInterface.set_size_request( 1068, 693 )
+ self.GUI["2page"].pack_start( self.trackInterface, False, False )
+
+ #------------------------------------------------------------------------
+ # 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 )
+ self.GUI["2tuneScrollLeftButton"].set_size_request( 25, -1 )
+ self.GUI["2tuneScrollLeftButton"].connect( "clicked", lambda a1:self.scrollTune( -1 ) )
+ self.GUI["2tuneHBox"].pack_start( self.GUI["2tuneScrollLeftButton"], False, False )
+ self.GUI["2tuneVBox"] = gtk.VBox()
+ self.GUI["2tuneScrolledWindow"] = gtk.ScrolledWindow()
+ self.GUI["2tuneScrolledWindow"].set_policy( gtk.POLICY_NEVER, gtk.POLICY_NEVER )
+ self.tuneInterface = TuneInterface( self.noteDB, self, self.GUI["2tuneScrolledWindow"].get_hadjustment() )
+ self.noteDB.addListener( self.tuneInterface, TuneInterfaceParasite, True )
+ self.GUI["2tuneScrolledWindow"].add_with_viewport( self.tuneInterface )
+ self.tuneInterface.get_parent().set_shadow_type( gtk.SHADOW_NONE )
+ self.GUI["2tuneVBox"].pack_start( self.GUI["2tuneScrolledWindow"] )
+ self.GUI["2tuneSlider"] = gtk.HScrollbar( self.GUI["2tuneScrolledWindow"].get_hadjustment() ) #ImageHScale( Config.IMAGE_ROOT+"sliderEditTempo.png", self.GUI["2tuneScrolledWindow"].get_hadjustment(), 6 )
+ self.GUI["2tuneVBox"].pack_start( self.GUI["2tuneSlider"], False, False )
+ self.GUI["2tuneHBox"].pack_start( self.GUI["2tuneVBox"] )
+ self.GUI["2tuneScrollRightButton"] = ImageButton( Config.IMAGE_ROOT+"arrowEditRight.png", Config.IMAGE_ROOT+"arrowEditRightDown.png", Config.IMAGE_ROOT+"arrowEditRightOver.png", backgroundFill = Config.TOOLBAR_BCK_COLOR )
+ self.GUI["2tuneScrollRightButton"].set_size_request( 25, -1 )
+ self.GUI["2tuneScrollRightButton"].connect( "clicked", lambda a1:self.scrollTune( 1 ) )
+ self.GUI["2tuneHBox"].pack_start( self.GUI["2tuneScrollRightButton"], False, False )
+ self.GUI["2main"].pack_start( self.GUI["2tuneHBox"] )
+
+ # set tooltips
+ for key in self.GUI:
+ if Tooltips.Edit.has_key(key):
+ self.tooltips.set_tip(self.GUI[key],Tooltips.Edit[key])
+
+ self.add( self.GUI["2main"] )
+
+ self.skipCleanup = "" # used when jumping between duplicate note/track
+
+
+ # Popups
+ TP.ProfileBegin("init_GUI::popups")
+ # + instrument panel
+ self.GUI["9instrumentPopup"] = gtk.Window(gtk.WINDOW_POPUP)
+ self.GUI["9instrumentPopup"].move( 400, 100 )
+ self.GUI["9instrumentPopup"].resize( 800, 452 )
+ self.GUI["9instrumentPopup"].set_modal(True)
+ self.GUI["9instrumentPopup"].add_events( gtk.gdk.BUTTON_PRESS_MASK )
+ self.GUI["9instrumentPopup"].connect("button-release-event", lambda w,e:self.cancelInstrumentSelection() )
+ # + drum panel
+ TP.ProfileBegin("init_GUI::drumPanel")
+ self.drumPanel = DrumPanel( self.donePickDrum )
+ TP.ProfileEnd("init_GUI::drumPanel")
+ self.GUI["9drumPopup"] = gtk.Window(gtk.WINDOW_POPUP)
+ self.GUI["9drumPopup"].move( 400, 100 )
+ self.GUI["9drumPopup"].resize( 400, 100 )
+ self.GUI["9drumPopup"].set_modal(True)
+ self.GUI["9drumPopup"].add_events( gtk.gdk.BUTTON_PRESS_MASK )
+ self.GUI["9drumPopup"].connect("button-release-event", lambda w,e:self.cancelDrumSelection() )
+ self.GUI["9drumPopup"].add( self.drumPanel )
+ # + generation window
+ #TP.ProfileBegin("init_GUI::generationPanel")
+ #self.generationPanel = GenerationParametersWindow( self.generate, self.doneGenerationPopup )
+ #TP.ProfileEnd("init_GUI::generationPanel")
+ #self.GUI["9generationPopup"] = gtk.Window(gtk.WINDOW_POPUP)
+ #self.GUI["9generationPopup"].set_modal(True)
+ #self.GUI["9generationPopup"].add_events( gtk.gdk.BUTTON_PRESS_MASK )
+ #self.GUI["9generationPopup"].connect("button-release-event", lambda w,e:self.doneGenerationPopup() )
+ #self.GUI["9generationPopup"].add( self.generationPanel )
+ # + properties window
+ #self.GUI["9propertiesPopup"] = gtk.Window(gtk.WINDOW_POPUP)
+ #self.GUI["9propertiesPopup"].set_modal(True)
+ #self.GUI["9propertiesPopup"].add_events( gtk.gdk.BUTTON_PRESS_MASK )
+ #self.GUI["9propertiesPopup"].connect("button-release-event", lambda w,e:self.donePropertiesPopup() )
+ #TP.ProfileBegin("init_GUI::propertiesPanel")
+ #self.propertiesPanel = Properties( self.noteDB, self.donePropertiesPopup, self.GUI["9propertiesPopup"] )
+ #TP.ProfileEnd("init_GUI::propertiesPanel")
+ #self.GUI["9propertiesPopup"].add( self.propertiesPanel )
+ # + playback scope
+ self.GUI["9loopPopup"] = gtk.Window(gtk.WINDOW_POPUP)
+ self.GUI["9loopPopup"].move( 100, 100 )
+ self.GUI["9loopPopup"].resize( 300, 100 )
+ self.GUI["9loopPopup"].set_modal(True)
+ self.GUI["9loopPopup"].add_events( gtk.gdk.BUTTON_PRESS_MASK )
+ self.GUI["9loopPopup"].connect("button-release-event", lambda w,e:self.GUI["2loopButton"].set_active(False) )
+ self.GUI["9loopBox"] = formatRoundBox( RoundHBox(), Config.BG_COLOR )
+ self.GUI["9loopAllOnce"] = gtk.Button("AO")
+ self.GUI["9loopBox"].pack_start( self.GUI["9loopAllOnce"] )
+ self.GUI["9loopAllRepeat"] = gtk.Button("AR")
+ self.GUI["9loopBox"].pack_start( self.GUI["9loopAllRepeat"] )
+ self.GUI["9loopSelectedOnce"] = gtk.Button("SO")
+ self.GUI["9loopBox"].pack_start( self.GUI["9loopSelectedOnce"] )
+ self.GUI["9loopSelectedRepeat"] = gtk.Button("SR")
+ self.GUI["9loopBox"].pack_start( self.GUI["9loopSelectedRepeat"] )
+ self.GUI["9loopPopup"].add(self.GUI["9loopBox"])
+ TP.ProfileEnd("init_GUI::popups")
+
+ #===================================================
+ # begin initialization
+ SubActivity.__init__( self, set_mode )
+
+ # keyboard variables
+ self.kb_record = False
+ self.kb_keydict = {}
+
+ # playback params
+ self.playing = False
+ self.playSource = 'Page'
+ self.currentpageId = 0
+ self.playingTuneIdx = 0
+
+ # timers
+ self.playbackTimeout = False
+
+ # FPS stuff
+ self.fpsTotalTime = 0
+ self.fpsFrameCount = 0
+ self.fpsN = 100 # how many frames to average FPS over
+ self.fpsLastTime = time.time() # fps will be borked for the first few frames but who cares?
+
+ self.context = -1 # invalidate
+ self.contextTrackActive = False
+ self.contextNoteActive = False
+
+ init_data() #above
+ init_GUI() #above
+
+ # register for notification AFTER track and tune interfaces
+ self.noteDB.addListener( self, page=True, note=True )
+
+ self.csnd.setMasterVolume( self.getVolume() )
+ self.initTrackVolume()
+
+ for tid in range(Config.NUMBER_OF_TRACKS):
+ self.handleInstrumentChanged( ( tid, self.trackInstrument[tid] ) )
+
+ instrumentsIds = []
+ for inst in self.trackInstrument:
+ instrumentsIds.append(inst.instrumentId)
+
+ first = self.noteDB.addPage( -1, NoteDB.Page(4, instruments = instrumentsIds) )
+ self.displayPage( first )
+
+ self.createNewTune( None )
+
+ # Toolbar
+ self.activity.activity_toolbar.keep.show()
+ self._mainToolbar = mainToolbar(self.activity.toolbox, self)
+ self._generateToolbar = generateToolbar(self.activity.toolbox, self)
+ self.activity.toolbox.add_toolbar(_('Compose'), self._mainToolbar)
+ self.activity.toolbox.add_toolbar(_('Generate'), self._generateToolbar)
+ self.activity.toolbox.set_current_toolbar(1)
+ self._mainToolbar.show()
+ self._generateToolbar.show()
+
+ self.show_all() #gtk command
+
+ self.setContext( CONTEXT.PAGE )
+
+ self.audioRecordState = False
+
+ def createNewTune( self, widget, data=None ):
+ self.createNewTune3()
+
+ def createNewTune3( self ):
+
+ if self.playing == True:
+ self.handleStop()
+
+ self.tuneInterface.selectPages( self.noteDB.getTune() )
+
+ beats = random.randint(3,8)
+ stream = []
+ for page in self.noteDB.getTune():
+ stream += [ page, beats ]
+ if len(stream):
+ self.noteDB.updatePages( [ PARAMETER.PAGE_BEATS, len(stream)//2 ] + stream )
+
+ orch = self.newOrchestra()
+
+ instrumentsIds = []
+ for inst in orch:
+ instrumentsIds.append(inst.instrumentId)
+
+ self.pageDelete( -1, instruments = instrumentsIds )
+
+ initTempo = random.randint(60, 132)
+ self._data['tempo'] = initTempo
+
+ formsUsed = []
+ for section in self.tuneForm:
+ if section[0] not in formsUsed:
+ param = self.chooseGenParams()
+ self.tuneInterface.selectPages( self.noteDB.getTune() )
+ if not formsUsed:
+ for i in range(section[2]-1):
+ self.pageAdd(instruments = instrumentsIds)
+ else:
+ for i in range(section[2]):
+ self.pageAdd(instruments = instrumentsIds)
+ formsUsed.append(section[0])
+
+ self.tuneInterface.selectPages( self.noteDB.getTune()[-section[2]:] )
+ self.generateMode = 'page'
+ self.generate( GenerationParameters( density = param[0], rythmRegularity = param[1], step = param[2], pitchRegularity = param[3], articule = param[4], silence = param[5], pattern = param[6], scale = param[7]), section[2] )
+ else:
+ pageOffset = 0
+ pageIds = []
+ firstPos = [i[0] for i in self.tuneForm].index(section[0])
+ if firstPos == 0:
+ pageOffset = 0
+ else:
+ for i in range(firstPos):
+ pageOffset += self.tuneForm[i][2]
+ for i in range(section[2]):
+ pageIds.append(self.noteDB.getTune()[pageOffset + i])
+ after = self.noteDB.getTune()[-1]
+ self.displayPage( self.noteDB.getTune()[pageOffset] )
+ self.tuneInterface.selectPages(self.noteDB.getTune())
+ self.pageDuplicate(-1, pageIds)
+
+ self.tuneInterface.selectPages( self.noteDB.getTune() )
+ self.displayPage( self.noteDB.getTune()[0] )
+
+
+ def newOrchestra(self):
+ stringsPickup = []
+ windsPickup = []
+ keyboardPickup = []
+ fxPickup = []
+ drumsPickup = ["drum1kit", "drum2kit", "drum3kit", "drum4kit", "drum5kit"]
+ for name in Config.INSTRUMENTS.keys():
+ if Config.INSTRUMENTS[name].category == 'strings' and Config.INSTRUMENTS[name].name != 'violin':
+ stringsPickup.append(name)
+ elif Config.INSTRUMENTS[name].category == 'winds' and Config.INSTRUMENTS[name].name != 'didjeridu':
+ windsPickup.append(name)
+ elif Config.INSTRUMENTS[name].category == 'keyboard' or Config.INSTRUMENTS[name].category == 'percussions':
+ if Config.INSTRUMENTS[name].name != 'zap' and Config.INSTRUMENTS[name].name != 'cling':
+ keyboardPickup.append(name)
+ return [
+ Config.INSTRUMENTS[random.choice(stringsPickup)],
+ Config.INSTRUMENTS[random.choice(stringsPickup)],
+ Config.INSTRUMENTS[random.choice(windsPickup)],
+ Config.INSTRUMENTS[random.choice(keyboardPickup)],
+ Config.INSTRUMENTS[random.choice(drumsPickup)] ]
+
+ def chooseGenParams(self):
+ choose = random.randint(0,4)
+ density = GenerationConstants.RYTHM_DENSITY_BANK[choose]
+ rytReg = GenerationConstants.RYTHM_REGU_BANK[choose]
+ step = GenerationConstants.PITCH_STEP_BANK[choose]
+ pitReg = GenerationConstants.PITCH_REGU_BANK[choose]
+ dur = GenerationConstants.DURATION_BANK[choose]
+ silence = GenerationConstants.SILENCE_BANK[choose]
+ pattern = [random.choice([0,1,1,2,3,3]) for x in range(4)]
+ scale = random.randint(0,6)
+ return [density, rytReg, step, pitReg, dur, silence, pattern, scale]
+
+ def onActivate( self, arg ):
+ SubActivity.onActivate( self,arg )
+ # whatever needs to be done on initialization
+ self.csnd.loopPause()
+ self.csnd.loopClear()
+ for n in self.noteDB.getNotes( ):
+ self.csnd.loopPlay(n, 0) #adds all notes to c client in inactive state
+
+
+ def onDeactivate( self ):
+ SubActivity.onDeactivate( self )
+ # clean up things like popups etc
+ self.releaseInstrumentPanel()
+ self.csnd.loopPause()
+ self.csnd.loopClear()
+
+ def setInstrumentPanel( self, instrumentPanel ):
+ instrumentPanel.configure( self.donePickInstrument, self.playInstrumentNote, enterMode = True )
+ self.instrumentPanel = instrumentPanel
+ self.GUI["9instrumentPopup"].add( self.instrumentPanel )
+
+ def releaseInstrumentPanel( self ):
+ self.GUI["9instrumentPopup"].remove( self.instrumentPanel )
+
+
+ def updateFPS( self ):
+ t = time.time()
+ dt = t - self.fpsLastTime
+ self.fpsLastTime = t
+ self.fpsTotalTime += dt
+ self.fpsFrameCount += 1
+ if self.fpsFrameCount == self.fpsN:
+ fps = self.fpsN/self.fpsTotalTime
+ avgMS = 1000/fps
+ fps = "FPS %d ms %.2f" % (fps, avgMS)
+ #self.fpsText.set_text(fps )
+ if (Config.DEBUG > 2): print fps
+ self.fpsTotalTime = 0
+ self.fpsFrameCount = 0
+
+ #=========================================================
+ # Popup Windows
+
+ def doneGenerationPopup( self ):
+ if self.GUI["2pageGenerateButton"].get_active():
+ self.GUI["2pageGenerateButton"].set_active( False )
+ if self.GUI["2trackGenerateButton"].get_active():
+ self.GUI["2trackGenerateButton"].set_active( False )
+
+ def donePropertiesPopup( self ):
+ if self.GUI["2pagePropertiesButton"].get_active():
+ self.GUI["2pagePropertiesButton"].set_active( False )
+ if self.GUI["2trackPropertiesButton"].get_active():
+ self.GUI["2trackPropertiesButton"].set_active( False )
+ if self.GUI["2notePropertiesButton"].get_active():
+ self.GUI["2notePropertiesButton"].set_active( False )
+
+ def cancelPopup( self, w, event, popup ):
+ popup.hide()
+
+
+ def handleLoopButton( self, w ):
+ if w.get_active(): self.GUI["9loopPopup"].show_all()
+ else: self.GUI["9loopPopup"].hide()
+
+ #-----------------------------------
+ # playback functions
+ #-----------------------------------
+
+ def updatePageSelection( self, selectedIds ):
+ if not self.playing:
+ return
+
+ if self.playScope == "All":
+ return
+
+ if self.displayedPage in selectedIds:
+ startPage = self.displayedPage
+ else:
+ startPage = selectedIds[0]
+
+ self._playPages( selectedIds, startPage, self.trackInterface.getPlayhead() )
+
+ def updatePagesPlaying( self ):
+ if not self.playing:
+ return
+
+ curTick = self.csnd.loopGetTick()
+
+ pageTick = self.page_onset[self.displayedPage]
+ if curTick < pageTick:
+ pageTick = 0
+ ind = 0
+ else:
+ ind = self.pages_playing.index(self.displayedPage)
+
+ localTick = curTick - pageTick
+
+ self._playPages( self.tuneInterface.getSelectedIds(), ind, localTick )
+
+ def handleAudioRecord( self, widget, data=None ):
+ if widget.get_active() == True:
+ chooser = gtk.FileChooserDialog(
+ title='Save tune as Audio file',
+ action=gtk.FILE_CHOOSER_ACTION_SAVE,
+ buttons=(gtk.STOCK_CANCEL,gtk.RESPONSE_CANCEL,gtk.STOCK_SAVE,gtk.RESPONSE_OK))
+ filter = gtk.FileFilter()
+ filter.add_pattern('*.ogg')
+ chooser.set_filter(filter)
+ chooser.set_current_folder(Config.TUNE_DIR)
+
+ for f in chooser.list_shortcut_folder_uris():
+ chooser.remove_shortcut_folder_uri(f)
+
+ if chooser.run() == gtk.RESPONSE_OK:
+ if self.playing:
+ self.handleStop()
+ else:
+ self.handleRewind()
+
+ self.audioRecordState = True
+ self.audioFileName = chooser.get_filename()
+ if self.audioFileName[-4:] != '.ogg':
+ self.audioFileName += '.ogg'
+
+ self.audioRecordTimeout = gobject.timeout_add( 500, self._startAudioRecord )
+ self.audioRecordTick = -1
+ chooser.destroy()
+ else:
+ self.audioRecordState = False
+
+ def _startAudioRecord( self ):
+ if not self.playing:
+ self.handlePlay()
+ return False
+
+ def handlePlay( self, widget = None ):
+
+ if widget:
+ widget.event( gtk.gdk.Event( gtk.gdk.LEAVE_NOTIFY ) ) # fake the leave event
+
+ if self.audioRecordState:
+ self.csnd.inputMessage( "i5400 0 -1" )
+ time.sleep( 0.01 )
+
+ if self.playScope == "All":
+ toPlay = self.noteDB.getTune()
+ else:
+ toPlay = self.tuneInterface.getSelectedIds()
+
+ self._playPages( toPlay, self.displayedPage, self.trackInterface.getPlayhead() )
+
+ self.playing = True
+
+ def _playPages( self, pages, startPage, startTick ):
+
+ self.pages_playing = pages[:]
+
+ trackset = set( [ i for i in range(Config.NUMBER_OF_TRACKS) if self.trackActive[i] ] )
+
+ numticks = 0
+ self.page_onset = {}
+ for pid in self.pages_playing:
+ self.page_onset[pid] = numticks
+ numticks += self.noteDB.getPage(pid).ticks
+
+ # check for a second instrument on melodic tracks
+ stream = []
+ for page in self.pages_playing:
+ for track in trackset:
+ if track != self.drumIndex:
+ if self.trackInstrument2[track] != None:
+ if len(self.noteDB.getNotesByTrack(page, track)):
+ stream += [ page, track, NoteDB.PARAMETER.INSTRUMENT2, len(self.noteDB.getNotesByTrack(page, track)) ]
+ for n in self.noteDB.getNotesByTrack(page, track):
+ stream += [ n.id, self.trackInstrument2[track].instrumentId ]
+ if len(stream):
+ self.noteDB.updateNotes( stream + [-1] )
+
+ self.csnd.loopClear()
+ for page in self.pages_playing:
+ for track in trackset:
+ for n in self.noteDB.getNotesByTrack( page, track ):
+ self.csnd.loopPlay(n, 1)
+ self.csnd.loopUpdate(n, NoteDB.PARAMETER.ONSET, n.cs.onset + self.page_onset[n.page] , 1)
+
+ self.csnd.loopSetNumTicks( numticks )
+
+ self.csnd.loopSetTick( self.page_onset[startPage] + startTick )
+ self.csnd.setTempo(self._data['tempo'])
+ if (Config.DEBUG > 3): print "starting from tick", startTick, 'at tempo', self._data['tempo']
+ self.csnd.loopStart()
+
+ if not self.playbackTimeout:
+ self.playbackTimeout = gobject.timeout_add( 50, self.onTimeout )
+
+
+
+ def handleStop( self, widget = None, rewind = True ):
+
+ if widget:
+ widget.event( gtk.gdk.Event( gtk.gdk.LEAVE_NOTIFY ) ) # fake the leave event
+
+ if self.audioRecordState:
+ self.csnd.inputMessage( "i5401 4 1" )
+ time.sleep( 0.01 )
+
+ if self.playbackTimeout:
+ gobject.source_remove( self.playbackTimeout )
+ self.playbackTimeout = False
+
+ self.csnd.loopPause()
+ self.csnd.loopDeactivate()
+
+ if self.audioRecordState:
+ time.sleep(4)
+ self.csnd.__del__()
+ time.sleep(0.5)
+ self.audioRecordState = False
+ command = "gst-launch-0.10 filesrc location=" + Config.PREF_DIR + "/perf.wav ! wavparse ! audioconvert ! vorbisenc ! oggmux ! filesink location=" + self.audioFileName
+ command2 = "rm /home/olpc/.sugar/default/tamtam/perf.wav"
+ (status, output) = commands.getstatusoutput(command)
+ (status2, output2) = commands.getstatusoutput(command2)
+ self.csnd.__init__()
+ time.sleep(0.1)
+ self.csnd.connect(True)
+ time.sleep(0.1)
+ self.waitToSet()
+ self.csnd.load_instruments()
+ self.GUI["2recordButton"].set_active(False)
+ self.playing = False
+
+ if rewind: self.handleRewind()
+
+ def handleRewind( self, widget = None ):
+ if self.playScope == "All": id = self.noteDB.getPageByIndex(0)
+ else: id = self.tuneInterface.getFirstSelected()
+ self.trackInterface.setPlayhead( 0 )
+ self.displayPage( id )
+
+ def handleClose(self,widget):
+ self.activity.close()
+
+ def onTimeout(self):
+ self.updateFPS()
+
+ curTick = self.csnd.loopGetTick()
+
+ pageTick = self.page_onset[self.displayedPage]
+ if curTick < pageTick:
+ pageTick = 0
+ ind = 0
+ else:
+ ind = self.pages_playing.index(self.displayedPage)
+
+ localTick = curTick - pageTick
+ pageLength = self.noteDB.getPage(self.pages_playing[ind]).ticks
+ max = len(self.pages_playing)
+ while localTick > pageLength:
+ ind += 1
+ if ind == max: ind = 0
+ localTick -= pageLength
+ pageLength = self.noteDB.getPage(self.pages_playing[ind]).ticks
+
+ self.trackInterface.setPlayhead( localTick )
+
+ if self.pages_playing[ind] != self.displayedPage:
+ if ind + 1 < max: predraw = self.pages_playing[ind+1]
+ else: predraw = self.pages_playing[0]
+ self._displayPage( self.pages_playing[ind], predraw )
+ else:
+ self.trackInterface.predrawPage()
+
+ if self.audioRecordState:
+ if self.audioRecordTick > curTick: # we've looped around
+ self.handleStop()
+ else:
+ self.audioRecordTick = curTick
+
+
+ return True
+
+ def onMuteTrack( self, widget, trackId ):
+ self._data['track_mute'][trackId] = not self._data['track_mute'][trackId]
+ #if self._data['track_mute'][trackId]:
+ #self.noteLooper.setMute( trackId, 0.0 )
+ #else:
+ #self.noteLooper.setMute( trackId, 1.0 )
+
+ def onTrackVolumeChanged( self, widget, trackId ):
+ v = widget.get_value() / 100.0
+ self._data['track_volume'][trackId] = v
+ #self.noteLooper.setVolume( trackId, v )
+
+ def clearInstrument( self, id, primary = True ):
+ btn = self.GUI["2instrument%dButton" % (id+1)]
+ if primary:
+ if self.trackInstrument2[id] == None:
+ return
+ self.handleInstrumentChanged( ( id, self.trackInstrument2[id] ), True )
+ self.handleInstrumentChanged( ( id, None ), False )
+ btn.setPrimary( self.GUI["2instrumentIcons"][self.trackInstrument[id].name] )
+ btn.setSecondary( None )
+ 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 ):
+ (id, instrument) = data
+ if primary:
+ self.trackInstrument[id] = instrument
+ else:
+ self.trackInstrument2[id] = instrument
+
+
+ if primary: # TODO handle secondary instruments properly
+ if (Config.DEBUG > 3): print "handleInstrumentChanged", id, instrument.name, primary
+
+ pages = self.tuneInterface.getSelectedIds()
+ self.noteDB.setInstrument( pages, id, instrument.instrumentId )
+
+ def getScale(self):
+ return self.scale
+
+ def handleVolume( self, widget ):
+ self._data["volume"] = round( widget.get_value() )
+ self.csnd.setMasterVolume(self._data["volume"])
+ img = min(3,int(4*self._data["volume"]/100)) # volume 0-3
+ #self.GUI["2volumeImage"].set_from_file( Config.IMAGE_ROOT+"volume"+str(img)+".png" )
+
+ def initTrackVolume( self ):
+ for i in range(Config.NUMBER_OF_TRACKS):
+ self.csnd.setTrackVolume(self._data["track_volume"][i], i)
+
+ def handleTrackVolume( self, widget, track ):
+ self._data["track_volume"][track] = round( widget.get_value() )
+ self.csnd.setTrackVolume(self._data["track_volume"][track], track)
+
+ def getTrackInstrument( self, track ):
+ return self.trackInstrument[track]
+
+ def getTrackVolume( self, track ):
+ return self._data["track_volume"][track]
+
+ def handleTempo( self, widget ):
+ self._data['tempo'] = round( widget.get_value() )
+ img = min(7,int(8*(self._data["tempo"]-widget.lower)/(widget.upper-widget.lower)))+1# tempo 1-8
+ #self.GUI["2tempoImage"].set_from_file( Config.IMAGE_ROOT+"tempo"+str(img)+".png" )
+ if self.playing:
+ self.csnd.setTempo(self._data['tempo'])
+
+ def handleToolClick( self, widget, mode ):
+ if widget.get_active(): self.trackInterface.setInterfaceMode( mode )
+
+ def getTool( self ):
+ if self.GUI["2toolPointerButton"].get_active(): return "default"
+ else: return "draw"
+
+ def handleKeyboardRecordButton( self, widget, data=None ):
+ self.kb_record = widget.get_active()
+
+ def pickInstrument( self, widget, num, primary = True ):
+ self.last_clicked_instTrackID = num
+ self.last_clicked_instPrimary = primary
+ self.instrumentPanel.selectFirstCat()
+ if primary or self.trackInstrument2[num] == None:
+ self.instrumentPanel.set_activeInstrument( self.trackInstrument[num].name, True )
+ else:
+ self.instrumentPanel.set_activeInstrument( self.trackInstrument2[num].name, True )
+ winLoc = self.parent.window.get_position()
+ alloc = widget.parent.get_allocation()
+ x = alloc.x + alloc.width + winLoc[0]
+ y = alloc.y + winLoc[1]
+ self.GUI["9instrumentPopup"].move( x, y )
+ self.GUI["9instrumentPopup"].show()
+
+ def cancelInstrumentSelection( self ):
+ self.GUI["9instrumentPopup"].hide()
+
+ def donePickInstrument( self, instrumentName ):
+ self.handleInstrumentChanged( (self.last_clicked_instTrackID, Config.INSTRUMENTS[instrumentName]), self.last_clicked_instPrimary )
+ btn = self.GUI["2instrument%dButton" % (self.last_clicked_instTrackID+1)]
+ if self.last_clicked_instPrimary:
+ btn.setPrimary( self.GUI["2instrumentIcons"][instrumentName] )
+ else:
+ btn.setSecondary( self.GUI["2instrumentIcons"][instrumentName] )
+ self.GUI["9instrumentPopup"].hide()
+
+
+ def pickDrum( self, widget , data = None ):
+ if widget.get_active(): # show the panel
+ winLoc = self.parent.window.get_position()
+ alloc = widget.get_allocation()
+ x = alloc.x + alloc.width + winLoc[0]
+ y = alloc.y + winLoc[1]
+ self.drumPanel.set_activeInstrument( self.trackInstrument[Config.NUMBER_OF_TRACKS-1].name, True )
+ self.GUI["9drumPopup"].move( x, y )
+ self.GUI["9drumPopup"].show()
+ else: # hide the panel
+ self.GUI["9drumPopup"].hide()
+
+ def cancelDrumSelection( self ):
+ self.GUI["2drumButton"].set_active( False )
+
+ def donePickDrum( self, drumName ):
+ self.handleInstrumentChanged( ( self.drumIndex, Config.INSTRUMENTS[drumName] ) )
+ self.GUI["2drumButton"].setImage( "main", self.GUI["2instrumentIcons"][drumName] )
+ self.GUI["2drumButton"].setImage( "alt", self.GUI["2instrumentIcons"][drumName] )
+ self.GUI["2drumButton"].set_active( False )
+
+ def playInstrumentNote( self, instrumentName, secs_per_tick = 0.025):
+ self.csnd.play(
+ CSoundNote( onset = 0,
+ pitch = 36,
+ amplitude = 1,
+ pan = 0.5,
+ duration = 20,
+ trackId = 1,
+ instrumentId = Config.INSTRUMENTS[instrumentName].instrumentId,
+ reverbSend = 0),
+ secs_per_tick)
+
+ def handlemuteButton(self,widget,track):
+ if widget.get_active():
+ self.trackActive[track] = True
+ else:
+ self.trackActive[track] = False
+ self.updatePagesPlaying()
+
+ def handlemuteButtonRightClick(self,widget,event,track):
+ if event.button == 3:
+ widget.set_active(True)
+ #if the other tracks are inactive
+ if self.trackActive.count(False) == Config.NUMBER_OF_TRACKS - 1:
+ for i in range(Config.NUMBER_OF_TRACKS):
+ if i == 4:
+ #self.GUI["2drumMuteButton"].set_active(True)
+ self.GUI["2drumPalette"].muteButton.set_active(True)
+ else:
+ #self.GUI["2instrument" + str(i+1) + "muteButton"].set_active(True)
+ self.GUI["2instrument" + str(i+1) + "Palette"].muteButton.set_active(True)
+ else:
+ for i in range(Config.NUMBER_OF_TRACKS):
+ if i != track:
+ if i == 4:
+ #self.GUI["2drumMuteButton"].set_active(False)
+ self.GUI["2drumPalette"].muteButton.set_active(False)
+ else:
+ #self.GUI["2instrument" + str(i+1) + "muteButton"].set_active(False)
+ self.GUI["2instrument" + str(i+1) + "Palette"].muteButton.set_active(False)
+ self.updatePagesPlaying()
+
+ def blockFocus(self, widget = None, data = None):
+ self.activity.handler_block(self.activity.focusOutHandler)
+ self.activity.handler_block(self.activity.focusInHandler)
+
+ def unblockFocus(self, widget = None, data = None):
+ self.activity.handler_unblock(self.activity.focusOutHandler)
+ self.activity.handler_unblock(self.activity.focusInHandler)
+
+ #-----------------------------------
+ # generation functions
+ #-----------------------------------
+
+ def recompose( self, algo, params, nPagesCycle = 4):
+ if self.generateMode == "track":
+ if self.trackSelected == [ 0 for i in range(Config.NUMBER_OF_TRACKS) ]:
+ newtracks = set(range(Config.NUMBER_OF_TRACKS))
+ else:
+ newtracks = set( [ i for i in range(Config.NUMBER_OF_TRACKS) if self.trackSelected[i] ] )
+ newpages = self.tuneInterface.getSelectedIds()
+ else: # page mode
+ newtracks = set(range(Config.NUMBER_OF_TRACKS))
+ newpages = self.tuneInterface.getSelectedIds()
+
+ dict = {}
+ for t in newtracks:
+ dict[t] = {}
+ for p in newpages:
+ dict[t][p] = self.noteDB.getCSNotesByTrack( p, t )
+
+ beatsOfPages = {}
+ for pageId in newpages:
+ beatsOfPages[pageId] = self.noteDB.pages[pageId].beats
+
+ instruments = self.noteDB.getInstruments(newpages)
+
+ #[ i.name for i in self.trackInstrument ],
+ algo(
+ params,
+ self._data['track_volume'][:],
+ instruments,
+ self._data['tempo'],
+ beatsOfPages,
+ newtracks,
+ newpages,
+ dict, nPagesCycle)
+
+ # filter & fix input ...WTF!?
+ for track in dict:
+ for page in dict[track]:
+ for note in dict[track][page]:
+ intdur = int(note.duration)
+ note.duration = intdur
+ note.pageId = page
+ note.trackId = track
+
+ # prepare the new notes
+ newnotes = []
+ for tid in dict:
+ for pid in dict[tid]:
+ newnotes += dict[tid][pid]
+
+ # delete the notes and add the new
+ self.noteDB.deleteNotesByTrack( newpages, newtracks )
+
+ stream = []
+ for page in newpages:
+ for track in newtracks:
+ stream += [ page, track, len(dict[track][page]) ]
+ stream += dict[track][page]
+ stream += [-1]
+ self.noteDB.addNotes( stream )
+
+ def generate( self, params, nPagesCycle = 4 ):
+ self.recompose( generator1, params, nPagesCycle)
+
+ #=======================================================
+ # Clipboard Functions
+
+ def getClipboardArea( self, page = -1 ):
+ if page == -1: page = self.displayedPage
+ ids = self.tuneInterface.getSelectedIds()
+ return self.noteDB.getClipboardArea( ids.index(page) )
+
+ def pasteClipboard( self, offset, trackMap ):
+ pages = self.tuneInterface.getSelectedIds()
+ instrumentMap = {}
+ for t in trackMap:
+ if t != trackMap[t]: instrumentMap[t] = self.trackInstrument[t].instrumentId
+ return self.noteDB.pasteClipboard( pages, offset, trackMap, instrumentMap )
+
+ def cleanupClipboard( self ):
+ self.trackInterface.donePaste()
+
+
+ #=======================================================
+ # Note Functions
+
+ def noteProperties( self, widget ):
+ if widget.get_active():
+ ids = self.trackInterface.getSelectedNotes()
+ notes = { self.displayedPage: {} }
+ for t in range(Config.NUMBER_OF_TRACKS):
+ if len(ids[t]):
+ notes[self.displayedPage][t] = [ self.noteDB.getNote( self.displayedPage, t, id ) for id in ids[t] ]
+
+ self.propertiesPanel.setContext("note", self.generationPanel.scale, notes = notes )
+ winLoc = self.parent.window.get_position()
+ balloc = self.GUI["2contextBox"].get_allocation()
+ walloc = self.GUI["9propertiesPopup"].get_allocation()
+ if walloc.height != 1: # hack to deal with showing the window before first allocation T_T
+ self.GUI["9propertiesPopup"].move( balloc.x + winLoc[0] - 30, balloc.y - walloc.height + winLoc[1] )
+ else:
+ self.GUI["9propertiesPopup"].move(0, 2048) # off the screen
+ self.GUI["9propertiesPopup"].show()
+ if walloc.height == 1:
+ walloc = self.GUI["9propertiesPopup"].get_allocation()
+ self.GUI["9propertiesPopup"].move( balloc.x + winLoc[0] - 30, balloc.y - walloc.height + winLoc[1] )
+ else:
+ self.GUI["9propertiesPopup"].hide()
+
+ def noteDelete( self ):
+ ids = self.trackInterface.getSelectedNotes()
+ stream = []
+ for t in range(Config.NUMBER_OF_TRACKS):
+ N = len(ids[t])
+ if not N: continue
+ stream += [ self.displayedPage, t, N ] + ids[t]
+ if len(stream):
+ self.noteDB.deleteNotes( stream + [-1] )
+
+ def noteDuplicate( self ):
+ ids = self.trackInterface.getSelectedNotes()
+ stream = []
+ for t in range(Config.NUMBER_OF_TRACKS):
+ N = len(ids[t])
+ if not N: continue
+ stream += [ self.displayedPage, t, N ] + ids[t]
+ if len(stream):
+ self.skipCleanup = "note"
+ self.skipCleanup = ""
+ self.noteDB.notesToClipboard( stream + [-1] )
+ self.trackInterface.setInterfaceMode("paste_notes")
+ return True
+ return False
+
+ def noteDuplicateWidget( self, widget ):
+ if widget.get_active():
+ if self.noteDuplicate(): # duplicate succeeded
+ return
+ # cancel duplicate
+ widget.set_active(False)
+ self.trackInterface.setInterfaceMode("tool")
+ else:
+ self.trackInterface.setInterfaceMode("tool")
+
+ def noteOnset( self, step ):
+ self.trackInterface.noteStepOnset( step )
+
+ def notePitch( self, step ):
+ # TODO
+ return
+
+ def noteDuration( self, step ):
+ # TODO
+ return
+
+ def noteVolume( self, step ):
+ # TODO
+ return
+
+ #=======================================================
+ # Track Functions
+
+ def toggleTrack( self, trackN, exclusive ):
+ if exclusive:
+ for i in range(Config.NUMBER_OF_TRACKS):
+ if self.trackSelected[i]:
+ self.trackSelected[i] = False
+ self.trackInterface.trackToggled( i )
+ self.tuneInterface.trackToggled( i )
+ self.trackSelected[trackN] = True
+ self.trackInterface.trackToggled( trackN )
+ self.tuneInterface.trackToggled( trackN )
+ self.setContextState( CONTEXT.TRACK, True )
+ self.setContext( CONTEXT.TRACK )
+ else:
+ self.trackSelected[trackN] = not self.trackSelected[trackN]
+ self.trackInterface.trackToggled( trackN )
+ self.tuneInterface.trackToggled( trackN )
+ trackSelected = False
+ for i in range(Config.NUMBER_OF_TRACKS):
+ if self.trackSelected[i]:
+ self.setContextState( CONTEXT.TRACK, True )
+ self.setContext( CONTEXT.TRACK )
+ trackSelected = True
+ break
+ if not trackSelected:
+ self.setContextState( CONTEXT.TRACK, False )
+
+ def setTrack( self, trackN, state ):
+ if self.trackSelected[trackN] != state:
+ self.trackSelected[trackN] = state
+ self.trackInterface.trackToggled( trackN )
+
+ def clearTracks( self ):
+ for i in range(Config.NUMBER_OF_TRACKS):
+ if self.trackSelected[i]:
+ self.trackSelected[i]= False
+ self.trackInterface.trackToggled( i )
+ self.tuneInterface.trackToggled( i )
+
+ self.setContextState( CONTEXT.TRACK, False )
+
+ def getTrackSelected( self, trackN ):
+ return self.trackSelected[trackN]
+
+ def trackGenerate( self, widget ):
+ if widget.get_active():
+ self.generateMode = "track"
+ winLoc = self.parent.window.get_position()
+ balloc = self.GUI["2contextBox"].get_allocation()
+ walloc = self.GUI["9generationPopup"].get_allocation()
+ if walloc.height != 1: # hack to make deal with showing the window before first allocation T_T
+ self.GUI["9generationPopup"].move( balloc.x + winLoc[0], balloc.y - walloc.height + winLoc[1] )
+ else:
+ self.GUI["9generationPopup"].move(0, 2048) # off the screen
+ self.GUI["9generationPopup"].show()
+ if walloc.height == 1:
+ walloc = self.GUI["9generationPopup"].get_allocation()
+ self.GUI["9generationPopup"].move( balloc.x + winLoc[0], balloc.y - walloc.height + winLoc[1] )
+ else:
+ self.GUI["9generationPopup"].hide()
+
+
+ def trackProperties( self, widget ):
+ if widget.get_active():
+ self.propertiesPanel.setContext( "track", self.generationPanel.scale, self.tuneInterface.getSelectedIds(), [ i for i in range(Config.NUMBER_OF_TRACKS) if self.trackSelected[i] ] )
+ winLoc = self.parent.window.get_position()
+ balloc = self.GUI["2contextBox"].get_allocation()
+ walloc = self.GUI["9propertiesPopup"].get_allocation()
+ if walloc.height != 1: # hack to make deal with showing the window before first allocation T_T
+ self.GUI["9propertiesPopup"].move( balloc.x + winLoc[0] - 30, balloc.y - walloc.height + winLoc[1] )
+ else:
+ self.GUI["9propertiesPopup"].move(0, 2048) # off the screen
+ self.GUI["9propertiesPopup"].show()
+ if walloc.height == 1:
+ walloc = self.GUI["9propertiesPopup"].get_allocation()
+ self.GUI["9propertiesPopup"].move( balloc.x + winLoc[0] - 30, balloc.y - walloc.height + winLoc[1] )
+ else:
+ self.GUI["9propertiesPopup"].hide()
+
+ def trackDelete( self, pageIds = -1, trackIds = -1 ):
+
+ if pageIds == -1: pageIds = self.tuneInterface.getSelectedIds()
+ if trackIds == -1: trackIds = [ i for i in range(Config.NUMBER_OF_TRACKS) if self.trackSelected[i] ]
+
+ self.noteDB.deleteNotesByTrack( pageIds, trackIds )
+
+ def trackDuplicate( self, pageIds = -1, trackIds = -1 ):
+
+ if pageIds == -1: pageIds = self.tuneInterface.getSelectedIds()
+ if trackIds == -1: trackIds = [ i for i in range(Config.NUMBER_OF_TRACKS) if self.trackSelected[i] ]
+
+ if len(trackIds):
+ self.skipCleanup = "track"
+ self.skipCleanup = ""
+ self.noteDB.tracksToClipboard( pageIds, trackIds )
+ self.trackInterface.setInterfaceMode("paste_tracks")
+ return True
+ return False
+
+ def trackDuplicateWidget( self, widget ):
+ if widget.get_active():
+ if self.trackDuplicate(): # duplicate succeeded
+ return
+ # cancel duplicate
+ widget.set_active(False)
+ self.trackInterface.setInterfaceMode("tool")
+ else:
+ self.trackInterface.setInterfaceMode("tool")
+
+ #-----------------------------------
+ # tune/page functions
+ #-----------------------------------
+
+ def scrollTune( self, direction ):
+ adj = self.GUI["2tuneScrolledWindow"].get_hadjustment()
+ if direction > 0:
+ adj.set_value( min( adj.value + Config.PAGE_THUMBNAIL_WIDTH, adj.upper - adj.page_size ) )
+ else:
+ adj.set_value( max( adj.value - Config.PAGE_THUMBNAIL_WIDTH, 0) )
+
+ def displayPage( self, pageId, nextId = -1 ):
+ if self.playing:
+ if self.displayedPage != pageId and pageId in self.pages_playing:
+ self.csnd.loopSetTick( self.page_onset[pageId] )
+
+ self._displayPage( pageId, nextId )
+
+
+ # only called locally!
+ def _displayPage( self, pageId, nextId = -1 ):
+
+ self.displayedPage = pageId
+
+ page = self.noteDB.getPage(pageId)
+ 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:
+ 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:
+ btn = self.GUI["2instrument%dButton"%(i+1)]
+ btn.setPrimary( self.GUI["2instrumentIcons"][self.trackInstrument[i].name] )
+ if self.trackInstrument2[i] != None:
+ btn.setSecondary( self.GUI["2instrumentIcons"][self.trackInstrument2[i].name] )
+ else:
+ btn.setSecondary( None )
+ self.tuneInterface.displayPage( pageId )
+ self.trackInterface.displayPage( pageId, nextId )
+
+ def predrawPage( self, pageId ):
+ if self.playbackTimeout: return # we're playing, predrawing is already handled
+ if self.trackInterface.setPredrawPage( pageId ): # page needs to be drawn
+ self.trackInterface.predrawPage()
+
+ def abortPredrawPage( self ):
+ self.trackInterface.abortPredrawPage()
+
+ def pageGenerate( self, widget ):
+ if widget.get_active():
+ self.generateMode = "page"
+ winLoc = self.parent.window.get_position()
+ balloc = self.GUI["2contextBox"].get_allocation()
+ walloc = self.GUI["9generationPopup"].get_allocation()
+ if walloc.height != 1: # hack to make deal with showing the window before first allocation T_T
+ self.GUI["9generationPopup"].move( balloc.x + winLoc[0], balloc.y - walloc.height + winLoc[1] )
+ else:
+ self.GUI["9generationPopup"].move(0, 2048) # off the screen
+ self.GUI["9generationPopup"].show()
+ if walloc.height == 1:
+ walloc = self.GUI["9generationPopup"].get_allocation()
+ self.GUI["9generationPopup"].move( balloc.x + winLoc[0], balloc.y - walloc.height + winLoc[1] )
+ else:
+ self.GUI["9generationPopup"].hide()
+
+ def setPageGenerateMode(self, mode):
+ self.generateMode = mode
+
+ def pageProperties( self, widget ):
+ if widget.get_active():
+ self.propertiesPanel.setContext( "page", self.generationPanel.scale, self.tuneInterface.getSelectedIds() )
+ winLoc = self.parent.window.get_position()
+ balloc = self.GUI["2contextBox"].get_allocation()
+ walloc = self.GUI["9propertiesPopup"].get_allocation()
+ if walloc.height != 1: # hack to make deal with showing the window before first allocation T_T
+ self.GUI["9propertiesPopup"].move( balloc.x + winLoc[0] - 100, balloc.y - walloc.height + winLoc[1] )
+ else:
+ self.GUI["9propertiesPopup"].move(0, 2048) # off the screen
+ self.GUI["9propertiesPopup"].show()
+ if walloc.height == 1:
+ walloc = self.GUI["9propertiesPopup"].get_allocation()
+ 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:
+ pageIds = self.tuneInterface.getSelectedIds()
+
+ if instruments == False:
+ instruments = []
+ for inst in self.trackInstrument:
+ instruments.append(inst.instrumentId)
+
+ self.noteDB.deletePages( pageIds[:], instruments )
+
+ def pageDuplicate( self, after = -1, pageIds = False ):
+
+ if after == -1: after = self.tuneInterface.getLastSelected()
+ if not pageIds: pageIds = self.tuneInterface.getSelectedIds()
+
+ new = self.noteDB.duplicatePages( pageIds[:], after )
+ self.displayPage( new[self.displayedPage] )
+ self.tuneInterface.selectPages( new.values() )
+
+ def pageAdd( self, after = -1, beats = False, color = False, instruments = False ):
+
+ if after == -1: after = self.tuneInterface.getLastSelected()
+ page = self.noteDB.getPage( self.displayedPage )
+ if not beats: beats = page.beats
+ if not color: color = page.color
+ if not instruments: instruments = page.instruments
+
+ # TODO think about network mode here...
+ self.displayPage( self.noteDB.addPage( -1, NoteDB.Page(beats,color,instruments), after ) )
+
+ def pageBeats( self, pageIds = -1 ):
+
+ if pageIds == -1: pageIds = self.tuneInterface.getSelectedIds()
+
+ # TODO change the beats
+
+ #=======================================================
+ # NoteDB notifications
+
+ def notifyPageAdd( self, id, at ):
+ return
+
+ def notifyPageDelete( self, which, safe ):
+ if self.displayedPage in which:
+ self.displayPage( safe )
+
+ def notifyPageDuplicate( self, new, at ):
+ return
+
+ def notifyPageMove( self, which, low, high ):
+ return
+
+ def notifyPageUpdate( self, page, parameter, value ):
+ pass
+
+ def notifyNoteAdd( self, page, track, id ):
+ if (Config.DEBUG > 3) : print 'INFO: adding note to loop', page, track, id
+ n = self.noteDB.getNote(page, track, id)
+ self.csnd.loopPlay(n,0)
+ if self.playing and (n.page in self.page_onset ):
+ onset = n.cs.onset + self.page_onset[n.page]
+ self.csnd.loopUpdate(n, NoteDB.PARAMETER.ONSET, onset, 1) #set onset + activate
+
+ def notifyNoteDelete( self, page, track, id ):
+ if (Config.DEBUG > 3) : print 'INFO: deleting note from loop', page, track, id
+ self.csnd.loopDelete1(page,id)
+ def notifyNoteUpdate( self, page, track, id, parameter, value ):
+ if (Config.DEBUG > 3) : print 'INFO: updating note ', page, id, parameter, value
+ note = self.noteDB.getNote(page, track, id)
+ self.csnd.loopUpdate(note, parameter, value, -1)
+
+ #-----------------------------------
+ # load and save functions
+ #-----------------------------------
+
+ def waitToSet(self):
+ self.csnd.setMasterVolume(self._data['volume'])
+ self.csnd.setTempo(self._data['tempo'])
+ self.initTrackVolume()
+
+ def handleSave(self, widget):
+
+ chooser = gtk.FileChooserDialog(
+ title='Save Tune',
+ action=gtk.FILE_CHOOSER_ACTION_SAVE,
+ buttons=(gtk.STOCK_CANCEL,gtk.RESPONSE_CANCEL,gtk.STOCK_SAVE,gtk.RESPONSE_OK))
+ filter = gtk.FileFilter()
+ filter.add_pattern('*.tam')
+ chooser.set_filter(filter)
+ chooser.set_current_folder(Config.TUNE_DIR)
+
+ for f in chooser.list_shortcut_folder_uris():
+ chooser.remove_shortcut_folder_uri(f)
+
+ if chooser.run() == gtk.RESPONSE_OK:
+ ofilename = chooser.get_filename()
+ if ofilename[-4:] != '.tam':
+ ofilename += '.tam'
+ try:
+ ofile = open(ofilename, 'w')
+ ofilestream = ControlStream.TamTamOStream (ofile)
+ self.noteDB.dumpToStream(ofilestream)
+ ofilestream.track_vol(self._data['track_volume'])
+ ofilestream.master_vol(self._data['volume'])
+ ofilestream.tempo(self._data['tempo'])
+ ofile.close()
+ except OSError,e:
+ print 'ERROR: failed to open file %s for writing\n' % ofilename
+ chooser.destroy()
+
+ def handleJournalSave(self, file_path):
+ ofile = open(file_path, 'w')
+ ofilestream = ControlStream.TamTamOStream (ofile)
+ self.noteDB.dumpToStream(ofilestream)
+ ofilestream.track_vol(self._data['track_volume'])
+ ofilestream.master_vol(self._data['volume'])
+ ofilestream.tempo(self._data['tempo'])
+ ofile.close()
+
+ def _loadFile( self, path ):
+ try:
+ oldPages = self.noteDB.getTune()[:]
+
+ ifile = open(path, 'r')
+ ttt = ControlStream.TamTamTable ( self.noteDB )
+ ttt.parseFile(ifile)
+ self.trackInstrument = self.trackInstrumentDefault[:] # these will get set correctly in displayPage
+ self._data['track_volume'] = ttt.tracks_volume
+ self._data['volume'] = float(ttt.masterVolume)
+ self._data['tempo'] = float(ttt.tempo)
+ #self.GUI["2volumeAdjustment"].set_value(self._data['volume'])
+ #self.GUI["2tempoAdjustment"].set_value(self._data['tempo'])
+ for i in range(Config.NUMBER_OF_TRACKS):
+ if i == 4:
+ string = '2drumvolumeAdjustment'
+ else:
+ string = '2instrument' + str(i+1) + 'volumeAdjustment'
+ self.GUI[string].set_value(self._data['track_volume'][i])
+ ifile.close()
+
+ self.noteDB.deletePages( oldPages )
+
+ self.tuneInterface.selectPages( self.noteDB.getTune() )
+ except OSError,e:
+ print 'ERROR: failed to open file %s for reading\n' % ofilename
+
+ def handleLoad(self, widget):
+ chooser = gtk.FileChooserDialog(
+ title='Load Tune',
+ action=gtk.FILE_CHOOSER_ACTION_OPEN,
+ buttons=(gtk.STOCK_CANCEL,gtk.RESPONSE_CANCEL,gtk.STOCK_OPEN,gtk.RESPONSE_OK))
+
+ filter = gtk.FileFilter()
+ filter.add_pattern('*.tam')
+ chooser.set_filter(filter)
+ chooser.set_current_folder(Config.TUNE_DIR)
+
+ for f in chooser.list_shortcut_folder_uris():
+ chooser.remove_shortcut_folder_uri(f)
+
+ if chooser.run() == gtk.RESPONSE_OK:
+ print 'DEBUG: loading file: ', chooser.get_filename()
+ self._loadFile( chooser.get_filename() )
+
+ chooser.destroy()
+ self.delay = gobject.timeout_add(1000, self.waitToSet)
+
+ def handleJournalLoad(self,file_path):
+ self.journalCalled = True
+ self._loadFile( file_path )
+
+ #-----------------------------------
+ # Record functions
+ #-----------------------------------
+ def handleMicRecord( self, widget, data ):
+ self.csnd.micRecording( data )
+ def handleCloseMicRecordWindow( self, widget = None, data = None ):
+ self.micRecordWindow.destroy()
+ self.micRecordButton.set_active( False )
+
+ #-----------------------------------
+ # callback functions
+ #-----------------------------------
+ def handleKeyboardShortcuts(self,event):
+ keyval = event.keyval
+
+ # backspace and del keys
+ if keyval == gtk.keysyms.Delete or keyval == gtk.keysyms.BackSpace:
+ if self.context == CONTEXT.PAGE: self.pageDelete()
+ if self.context == CONTEXT.TRACK: self.trackDelete()
+ if self.context == CONTEXT.NOTE: self.noteDelete()
+ # plus key
+ if keyval == gtk.keysyms.equal:
+ self.pageAdd()
+ # duplicate ctrl-c
+ if event.state == gtk.gdk.CONTROL_MASK and keyval == gtk.keysyms.c:
+ if self.context == CONTEXT.PAGE: self.pageDuplicate()
+ if self.context == CONTEXT.TRACK: self.trackDuplicate()
+ if self.context == CONTEXT.NOTE: self.noteDuplicate()
+ #Arrows
+ if event.state == gtk.gdk.SHIFT_MASK:
+ # up/down arrows volume
+ if keyval == gtk.keysyms.Up: self.trackInterface.noteStepVolume(0.1)
+ if keyval == gtk.keysyms.Down: self.trackInterface.noteStepVolume(-0.1)
+ # left/right arrows onset
+ if keyval == gtk.keysyms.Left: self.trackInterface.noteStepDuration(-1)
+ if keyval == gtk.keysyms.Right: self.trackInterface.noteStepDuration(1)
+ else:
+ # up/down arrows pitch
+ if keyval == gtk.keysyms.Up: self.trackInterface.noteStepPitch(1)
+ if keyval == gtk.keysyms.Down: self.trackInterface.noteStepPitch(-1)
+ # left/right arrows duration
+ if keyval == gtk.keysyms.Left: self.trackInterface.noteStepOnset(-1)
+ if keyval == gtk.keysyms.Right: self.trackInterface.noteStepOnset(1)
+
+
+ def onKeyPress(self,widget,event):
+ self.handleKeyboardShortcuts(event)
+ Config.ModKeys.keyPress( event.hardware_keycode )
+ key = event.hardware_keycode
+
+ # If the key is already in the dictionnary, exit function (to avoir key repeats)
+ if self.kb_keydict.has_key(key):
+ return
+
+ # Assign on which track the note will be created according to the number of keys pressed
+ if self.trackCount >= 9:
+ self.trackCount = 6
+ fakeTrack = self.trackCount
+ self.trackCount += 1
+
+ # If the pressed key is in the keymap
+ if KEY_MAP_PIANO.has_key(key):
+ pitch = KEY_MAP_PIANO[key]
+ duration = -1
+
+ # get instrument from top selected track if a track is selected
+ if True in self.trackSelected:
+ index = self.trackSelected.index(True)
+ instrument = self.getTrackInstrument(index).name
+ else:
+ return
+
+ tid = index
+
+ # pitch, inst and duration for drum recording
+ if tid == Config.NUMBER_OF_TRACKS-1:
+ if GenerationConstants.DRUMPITCH.has_key( pitch ):
+ pitch = GenerationConstants.DRUMPITCH[pitch]
+ if Config.INSTRUMENTS[instrument].kit != None:
+ instrument = Config.INSTRUMENTS[instrument].kit[pitch].name
+ duration = 100
+
+ # Create and play the note
+ self.kb_keydict[key] = CSoundNote(onset = 0,
+ pitch = pitch,
+ amplitude = 1,
+ pan = 0.5,
+ duration = duration,
+ trackId = fakeTrack,
+ instrumentId = Config.INSTRUMENTS[instrument].instrumentId,
+ tied = False,
+ mode = 'edit')
+ self.csnd.play(self.kb_keydict[key], 0.3)
+
+ # doesn't keep track of keys for drum recording
+ if tid == Config.NUMBER_OF_TRACKS-1:
+ del self.kb_keydict[key]
+
+ # remove previosly holded key from dictionary
+ if len(self.kb_keydict) > 1:
+ for k in self.kb_keydict.keys():
+ if k != key:
+ gobject.source_remove( self.durUpdate )
+ self.durUpdate = False
+ self.kb_keydict[k].duration = 0.5
+ self.kb_keydict[k].amplitude = 0
+ self.kb_keydict[k].decay = 0.7
+ self.kb_keydict[k].tied = False
+ self.csnd.play(self.kb_keydict[k], 0.3)
+ if not self.kb_record:
+ del self.kb_keydict[k]
+ return
+ self.removeRecNote(self.csId)
+
+ if not self.kb_record:
+ return
+
+ #record the note on track
+ pageList = self.tuneInterface.getSelectedIds()
+ pid = self.displayedPage
+ minOnset = self.page_onset[pid]
+ onsetQuantized = Config.DEFAULT_GRID * int((self.csnd.loopGetTick() - minOnset) / Config.DEFAULT_GRID + 0.5)
+
+ maxOnset = self.noteDB.getPage(pid).ticks
+ if onsetQuantized >= maxOnset:
+ if pid == pageList[-1]:
+ pid = pageList[0]
+ else:
+ if len(pageList) > 1:
+ pidPos = pageList.index(pid)
+ pid = pageList[pidPos+1]
+ onsetQuantized = 0
+
+ if tid < Config.NUMBER_OF_TRACKS-1:
+ for n in self.noteDB.getNotesByTrack( pid, tid ):
+ if onsetQuantized < n.cs.onset:
+ break
+ if onsetQuantized >= n.cs.onset + n.cs.duration:
+ continue
+ if onsetQuantized < n.cs.onset + n.cs.duration - 2:
+ self.noteDB.deleteNote(n.page, n.track, n.id)
+ elif onsetQuantized - n.cs.onset < 1:
+ self.noteDB.deleteNote(n.page, n.track, n.id)
+ else:
+ self.noteDB.updateNote( n.page, n.track, n.id, PARAMETER.DURATION, onsetQuantized - n.cs.onset )
+ break
+ else:
+ for n in self.noteDB.getNotesByTrack( pid, tid ):
+ if onsetQuantized < n.cs.onset:
+ break
+ if onsetQuantized == n.cs.onset:
+ if pitch < n.cs.pitch:
+ break
+ if pitch == n.cs.pitch:
+ return # don't bother with a new note
+
+ csnote = CSoundNote(onset = 0,
+ pitch = pitch,
+ amplitude = 1,
+ pan = 0.5,
+ duration = duration,
+ trackId = index,
+ instrumentId = Config.INSTRUMENTS[instrument].instrumentId,
+ tied = False,
+ mode = 'edit')
+
+ csnote.onset = onsetQuantized
+ csnote.duration = 1
+ csnote.pageId = pid
+ id = self.noteDB.addNote(-1, pid, tid, csnote)
+ # csId: PageId, TrackId, Onset, Key, DurationSetOnce
+ self.csId = [pid, tid, id, csnote.onset, key, False ]
+ if tid < Config.NUMBER_OF_TRACKS-1:
+ self.durUpdate = gobject.timeout_add( 25, self.durationUpdate )
+
+ def onKeyRelease(self,widget,event):
+ Config.ModKeys.keyRelease( event.hardware_keycode )
+ key = event.hardware_keycode
+
+ if True in self.trackSelected:
+ index = self.trackSelected.index(True)
+ if index == Config.NUMBER_OF_TRACKS-1:
+ return
+ else:
+ return
+
+ if KEY_MAP_PIANO.has_key(key) and self.kb_keydict.has_key(key):
+ if self.kb_record and self.durUpdate:
+ gobject.source_remove( self.durUpdate )
+ self.durUpdate = False
+
+ if Config.INSTRUMENTSID[ self.kb_keydict[key].instrumentId ].csoundInstrumentId == Config.INST_TIED:
+ self.kb_keydict[key].duration = 0.5
+ self.kb_keydict[key].amplitude = 0
+ self.kb_keydict[key].decay = 0.5
+ self.kb_keydict[key].tied = False
+ self.csnd.play(self.kb_keydict[key], 0.3)
+ if not self.kb_record:
+ del self.kb_keydict[key]
+ return
+
+ self.removeRecNote(self.csId)
+
+ def removeRecNote(self, csId):
+ newDuration = (int(self.csnd.loopGetTick()) - self.page_onset[csId[0]]) - csId[3]
+ maxTick = self.noteDB.getPage(csId[0]).ticks
+
+ if not csId[5]: # handle notes that were created right at the end of a page
+ if newDuration > maxTick//2:
+ newDuration = 1
+ else:
+ csId[5] = True
+
+ if newDuration < -Config.DEFAULT_GRID_DIV2: # we looped around
+ newDuration = maxTick - self.csId[3]
+ elif newDuration < 1:
+ newDuration = 1
+
+ if (csId[3] + newDuration) > maxTick:
+ newDuration = maxTick - csId[3]
+
+ for n in self.noteDB.getNotesByTrack( csId[0], csId[1] ):
+ if n.id == csId[2]:
+ continue
+ if csId[3] + newDuration <= n.cs.onset:
+ break
+ if csId[3] >= n.cs.onset + n.cs.duration:
+ continue
+ self.noteDB.deleteNote(n.page, n.track, n.id)
+ break
+
+ self.noteDB.updateNote( csId[0], csId[1], csId[2], PARAMETER.DURATION, newDuration)
+
+ del self.kb_keydict[csId[4]]
+
+ def durationUpdate(self):
+ newDuration = (int(self.csnd.loopGetTick()) - self.page_onset[self.csId[0]]) - self.csId[3]
+
+ maxTick = self.noteDB.getPage(self.csId[0]).ticks
+ stop = False
+
+ if not self.csId[5]: # handle notes that were created right at the end of a page
+ if newDuration > maxTick//2:
+ newDuration = 1
+ else:
+ self.csId[5] = True
+
+ if newDuration < -Config.DEFAULT_GRID_DIV2: # we looped around
+ newDuration = maxTick - self.csId[3]
+ stop = True
+ elif newDuration < 1:
+ newDuration = 1
+
+ if (self.csId[3] + newDuration) > maxTick:
+ stop = True
+ newDuration = maxTick - self.csId[3]
+
+ for n in self.noteDB.getNotesByTrack( self.csId[0], self.csId[1] ):
+ if n.id == self.csId[2]:
+ continue
+ if self.csId[3] + newDuration <= n.cs.onset:
+ break
+ if self.csId[3] >= n.cs.onset + n.cs.duration:
+ continue
+ self.noteDB.deleteNote(n.page, n.track, n.id)
+ break
+
+ self.noteDB.updateNote( self.csId[0], self.csId[1], self.csId[2], PARAMETER.DURATION, newDuration)
+
+ if stop:
+ key = self.csId[4]
+ if Config.INSTRUMENTSID[ self.kb_keydict[key].instrumentId ].csoundInstrumentId == Config.INST_TIED:
+ self.kb_keydict[key].duration = 0.5
+ self.kb_keydict[key].amplitude = 0
+ self.kb_keydict[key].decay = 0.5
+ self.kb_keydict[key].tied = False
+ self.csnd.play(self.kb_keydict[key], 0.3)
+
+ del self.kb_keydict[key]
+ return False
+ return True
+
+ def delete_event( self, widget, event, data = None ):
+ return False
+
+ def onDestroy( self ):
+
+ if (Config.DEBUG > 1): print TP.PrintAll()
+
+ def setContextState( self, context, state ):
+ if context == CONTEXT.TRACK:
+ self.contextTrackActive = state
+ if not state:
+ if self.context == CONTEXT.TRACK:
+ if self.contextNoteActive:
+ self.setContext( CONTEXT.NOTE )
+ else:
+ self.setContext( CONTEXT.PAGE )
+ else:
+ self.contextNoteActive = state
+ if not state:
+ if self.context == CONTEXT.NOTE:
+ self.prevContext()
+
+ def setContext( self, context, force = False ):
+
+ if self.context == context and not force: return
+
+ self.context = context
+
+ if self.context == CONTEXT.NOTE:
+ self._generateToolbar.generationButton.set_sensitive(False)
+ else:
+ self._generateToolbar.generationButton.set_sensitive(True)
+
+ def getContext(self):
+ return self.context
+
+ def prevContext( self ):
+ if self.context == CONTEXT.TRACK:
+ self.setContext( CONTEXT.PAGE )
+ elif self.contextTrackActive:
+ self.setContext( CONTEXT.TRACK )
+ else:
+ self.setContext( CONTEXT.PAGE )
+
+ def nextContext( self ):
+ if self.context == CONTEXT.TRACK:
+ self.setContext( CONTEXT.NOTE )
+ elif self.contextTrackActive:
+ self.setContext( CONTEXT.TRACK )
+ else:
+ self.setContext( CONTEXT.NOTE )
+
+ #-----------------------------------
+ # access functions (not sure if this is the best way to go about doing this)
+ #-----------------------------------
+ def getVolume( self ):
+ return self._data["volume"]
+
+ def getTempo( self ):
+ return self._data["tempo"]
+ #return round( self.tempoAdjustment.value, 0 )
+
+ def getBeatsPerPage( self ):
+ return int(round( self.beatsPerPageAdjustment.value, 0 ))
+
+ def getWindowTitle( self ):
+ return "Tam-Tam [Volume %i, Tempo %i, Beats/Page %i]" % ( self.getVolume(), self.getTempo(), self.getBeatsPerPage() )
+
+
+class InstrumentButton( gtk.DrawingArea ):
+
+ def __init__( self, owner, index, backgroundFill ):
+ gtk.DrawingArea.__init__( self )
+
+ self.index = index
+ self.owner = owner
+
+ 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( Config.FG_COLOR, True, True ),
+ "+/-Highlight": colormap.alloc_color( "#FFF", True, True ) }
+
+ self.pixmap = None
+ self.primary = None
+ self.primaryWidth = self.primaryHeight = 1
+ self.secondary = None
+ self.secondaryWidth = self.secondaryHeight = 1
+
+ self.clicked = None
+ self.hover = None
+
+ self.add_events( gtk.gdk.BUTTON_PRESS_MASK
+ | gtk.gdk.BUTTON_RELEASE_MASK
+ | gtk.gdk.POINTER_MOTION_MASK
+ | gtk.gdk.POINTER_MOTION_HINT_MASK
+ | gtk.gdk.LEAVE_NOTIFY_MASK
+ | gtk.gdk.ENTER_NOTIFY_MASK )
+ self.connect( "size-allocate", self.size_allocate )
+ self.connect( "button-press-event", self.button_press )
+ self.connect( "button-release-event", self.button_release )
+ self.connect( "motion-notify-event", self.motion_notify )
+ self.connect( "enter-notify-event", self.enter_notify )
+ self.connect( "leave-notify-event", self.leave_notify )
+ self.connect( "expose-event", self.expose )
+
+ def size_allocate( self, widget, allocation ):
+ self.alloc = allocation
+ self.pixmap = gtk.gdk.Pixmap( self.win, allocation.width, allocation.height )
+ self.primaryX = (self.alloc.width - self.primaryWidth) // 2
+ self.primaryY = (self.alloc.height - self.primaryHeight) // 2
+ self.secondaryX = (self.alloc.width - self.secondaryWidth) // 2
+ self.secondaryY = self.alloc.height//2
+
+ self.hotspots = [ [ self.alloc.width-24, self.alloc.height-29, self.alloc.width-8, self.alloc.height-13 ],
+ [ self.alloc.width-24, self.alloc.height//2-23, self.alloc.width-8, self.alloc.height//2-7 ] ]
+
+ self.hotspots[0] += [ (self.hotspots[0][0]+self.hotspots[0][2])//2, (self.hotspots[0][1]+self.hotspots[0][3])//2 ]
+ self.hotspots[1] += [ (self.hotspots[1][0]+self.hotspots[1][2])//2, (self.hotspots[1][1]+self.hotspots[1][3])//2 ]
+
+ self._updatePixmap()
+
+ def button_press( self, widget, event ):
+
+ 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"
+
+ elif event.y > self.alloc.height//2:
+ self.clicked = "SECONDARY"
+
+ def button_release( self, widget, event ):
+ if self.clicked == "PRIMARY":
+ self.owner.pickInstrument( self, self.index, True )
+ elif self.clicked == "SECONDARY":
+ self.owner.pickInstrument( self, self.index, False )
+ elif self.clicked == "HOTSPOT_0":
+ if self.secondary != None: # remove secondary
+ self.owner.clearInstrument( self.index, False )
+ else: # add secondary
+ self.owner.pickInstrument( self, self.index, False )
+ else: # HOTSPOT_1, remove primary
+ self.owner.clearInstrument( self.index, True )
+
+ self.clicked = None
+
+ def motion_notify( self, widget, event ):
+
+ if self.clicked != None:
+ return
+
+ if event.is_hint:
+ x, y, state = widget.window.get_pointer()
+ event.x = float(x)
+ event.y = float(y)
+ event.state = state
+
+ 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]:
+ 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] \
+ and event.y >= self.hotspots[1][1] and event.y <= self.hotspots[1][3]:
+ if self.hover != "HOTSPOT_1":
+ self.hover = "HOTSPOT_1"
+ self.queue_draw()
+ else:
+ if self.hover != None:
+ self.hover = None
+ self.queue_draw()
+
+ def leave_notify( self, widget, event ):
+ if event.mode != gtk.gdk.CROSSING_NORMAL:
+ return
+ if self.hover != None:
+ self.hover = None
+ if self.clicked == None:
+ self.queue_draw()
+
+ self.owner.activity.handler_unblock(self.owner.activity.focusOutHandler)
+ self.owner.activity.handler_unblock(self.owner.activity.focusInHandler)
+
+ def enter_notify(self, widget, event):
+ # Block the Focus Out event so that the sound does'nt stop when a Palette is invoked.
+ self.owner.activity.handler_block(self.owner.activity.focusOutHandler)
+ self.owner.activity.handler_block(self.owner.activity.focusInHandler)
+
+ def setPrimary( self, img ):
+ self.primary = img
+ self.primaryWidth = img.get_width()
+ self.primaryHeight = img.get_height()
+ if self.pixmap:
+ self.primaryX = (self.alloc.width - self.primaryWidth) // 2
+ self.primaryY = (self.alloc.height - self.primaryHeight) // 2
+ self._updatePixmap()
+
+ def setSecondary( self, img ):
+ self.secondary = img
+ if img != None:
+ self.secondaryWidth = img.get_width()
+ self.secondaryHeight = img.get_height()
+ self.secondaryOffset = self.secondaryHeight//2
+ if self.pixmap:
+ self.secondaryX = (self.alloc.width - self.secondaryWidth) // 2
+ self.secondaryY = self.alloc.height//2
+ if self.pixmap:
+ self._updatePixmap()
+
+ def _updatePixmap( self ):
+ self.gc.foreground = self.color["background"]
+ self.pixmap.draw_rectangle( self.gc, True, 0, 0, self.alloc.width, self.alloc.height )
+ if self.secondary != None:
+ self.pixmap.draw_pixbuf( self.gc, self.primary, 0, 0, self.primaryX, self.primaryY, self.primaryWidth, self.primaryHeight//2, gtk.gdk.RGB_DITHER_NONE )
+ self.pixmap.draw_pixbuf( self.gc, self.secondary, 0, self.secondaryOffset, self.secondaryX, self.secondaryY, self.secondaryWidth, self.secondaryHeight//2, gtk.gdk.RGB_DITHER_NONE )
+ self.gc.foreground = self.color["divider"]
+ self.gc.set_line_attributes( 2, gtk.gdk.LINE_SOLID, gtk.gdk.CAP_BUTT, gtk.gdk.JOIN_MITER )
+ self.pixmap.draw_line( self.gc, 2, self.alloc.height//2, self.alloc.width-4, self.alloc.height//2 )
+ 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 )
+ if self.secondary != None:
+ if self.clicked == "HOTSPOT_0" or (self.clicked == None and 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] )
+ if self.clicked == "HOTSPOT_1" or (self.clicked == None and self.hover == "HOTSPOT_1" ):
+ self.gc.foreground = self.color["+/-Highlight"]
+ else:
+ 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":
+ 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] )
+
+ def set_palette(self, palette):
+ self._palette = palette
+ self._palette.props.invoker = WidgetInvoker(self)
+ self._palette.props.invoker._position_hint = WidgetInvoker.AT_CURSOR #This is a hack, will change with newer Palette API
+
+
+class instrumentPalette(Palette):
+ def __init__(self, label, trackID, edit):
+ Palette.__init__(self, label)
+
+ self.trackID = trackID
+ self.edit = edit
+
+ self.tooltips = gtk.Tooltips()
+
+ self.volumeBox = gtk.HBox()
+
+ self.muteButton = gtk.CheckButton()
+ self.muteButton.connect("toggled",self.edit.handlemuteButton, self.trackID)
+ self.muteButton.connect("button-press-event",self.edit.handlemuteButtonRightClick, self.trackID)
+ self.muteButton.set_active(True)
+ self.tooltips.set_tip(self.muteButton, _('Left click to mute, right click to solo'))
+
+ if self.trackID < 4:
+ exec "self.volumeSliderAdj = self.edit.GUI['2instrument%svolumeAdjustment']" % str(self.trackID+1)
+ else:
+ self.volumeSliderAdj = self.edit.GUI["2drumvolumeAdjustment"]
+ self.volumeSliderAdj.connect( "value-changed", self.edit.handleTrackVolume, self.trackID)
+ self.volumeSlider = gtk.HScale(adjustment = self.volumeSliderAdj)
+ self.volumeSlider.set_size_request(250, -1)
+ self.volumeSlider.set_inverted(False)
+ self.volumeSlider.set_draw_value(False)
+
+ self.volumeBox.pack_start(self.muteButton, padding = 5)
+ self.volumeBox.pack_start(self.volumeSlider, padding = 5)
+ self.volumeBox.show_all()
+
+ self.set_content(self.volumeBox)
+ \ No newline at end of file