Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/Edit
diff options
context:
space:
mode:
authorNat <natcl@hotmail.com>2007-09-13 16:01:09 (GMT)
committer Nat <natcl@hotmail.com>2007-09-13 16:01:09 (GMT)
commit6d7e6f83bec91d4c3e49fe64d7793f12d1d3509b (patch)
tree013613f48b4f4a3f91d3ea9f1c0511153cd6f2b4 /Edit
parente12dbff4dda5aafbaac98f75f0467ef00dc06c32 (diff)
split
Diffstat (limited to 'Edit')
-rw-r--r--Edit/EditToolbars.py1430
-rw-r--r--Edit/HitInterface.py195
-rw-r--r--Edit/KeyboardInput.py97
-rw-r--r--Edit/MainWindow.py2091
-rw-r--r--Edit/NoteInterface.py345
-rw-r--r--Edit/Properties.py808
-rw-r--r--Edit/TrackInterface.py1364
-rw-r--r--Edit/TuneInterface.py645
-rw-r--r--Edit/__init__.py0
-rw-r--r--Edit/rm/BackgroundView.py501
-rw-r--r--Edit/rm/NoteView.py253
-rw-r--r--Edit/rm/PageBankView.py85
-rw-r--r--Edit/rm/PageView.py65
-rw-r--r--Edit/rm/PositionIndicator.py47
-rw-r--r--Edit/rm/TrackView.py263
-rw-r--r--Edit/rm/TunePageView.py17
-rw-r--r--Edit/rm/TuneView.py123
17 files changed, 0 insertions, 8329 deletions
diff --git a/Edit/EditToolbars.py b/Edit/EditToolbars.py
deleted file mode 100644
index 408416d..0000000
--- a/Edit/EditToolbars.py
+++ /dev/null
@@ -1,1430 +0,0 @@
-#!/usr/bin/env python
-
-import gtk
-
-import Config
-from sugar.graphics.toolbutton import ToolButton
-from sugar.graphics.toggletoolbutton import ToggleToolButton
-from sugar.graphics.radiotoolbutton import RadioToolButton
-from sugar.graphics.palette import Palette
-from sugar.graphics.icon import Icon
-from Util.ThemeWidgets import *
-from gettext import gettext as _
-
-#Generation palette
-import gobject
-from Generation.Generator import GenerationParameters
-#Generation palette and Properties palette
-from Generation.GenerationConstants import GenerationConstants
-from Generation.GenerationRythm import GenerationRythm
-from Generation.GenerationPitch import GenerationPitch
-
-#Properties palette
-from Util.NoteDB import PARAMETER
-from Generation.Drunk import *
-import Generation.Utils as Utils
-from types import *
-from math import sqrt
-from random import *
-
-class mainToolbar(gtk.Toolbar):
- def __init__(self,toolbox, edit):
- gtk.Toolbar.__init__(self)
-
- def _insertSeparator(x = 1):
- for i in range(x):
- self.separator = gtk.SeparatorToolItem()
- self.separator.set_expand(True)
- self.separator.set_draw(True)
- self.insert(self.separator,-1)
- self.separator.show()
-
- self.toolbox = toolbox
- self.edit = edit
-
- self.tooltips = gtk.Tooltips()
-
- #Play button
- self.playButton = ToggleToolButton('media-playback-start')
- self.playButtonHandler = self.playButton.connect('toggled', self.handlePlayPause)
- self.insert(self.playButton, -1)
- self.playButton.show()
- self.playButton.set_tooltip(_('Play / Pause'))
-
- #Stop button
- self.stopButton = ToolButton('media-playback-stop')
- self.stopButton.connect('clicked', self.handleStop)
- self.insert(self.stopButton, -1)
- self.stopButton.show()
- self.stopButton.set_tooltip(_('Stop'))
-
- #Play button Image
- self.playButtonImg = gtk.Image()
- self.playButtonImg.set_from_icon_name('media-playback-start', gtk.ICON_SIZE_LARGE_TOOLBAR)
- self.playButtonImg.show()
-
- #Pause button Image
- self.pauseButtonImg = gtk.Image()
- self.pauseButtonImg.set_from_icon_name('media-playback-pause', gtk.ICON_SIZE_LARGE_TOOLBAR)
- self.pauseButtonImg.show()
-
- #Record button
- self.recordButton = ToggleToolButton('recordK')
- self.recordButton.connect('clicked', self.edit.handleKeyboardRecordButton)
- self.insert(self.recordButton, -1)
- self.recordButton.show()
- self.recordButton.set_tooltip(_('Record keyboard'))
-
- #RecordOgg button
- self.recordOggButton = ToggleToolButton('recordO')
- self.recordOggButton.connect('clicked', self.edit.handleAudioRecord)
- self.insert(self.recordOggButton, -1)
- self.recordOggButton.show()
- self.recordOggButton.set_tooltip(_('Record to ogg'))
-
- _insertSeparator(1)
-
- #Pointer button
- self._pointerPalette = pointerPalette(_('Select Tool'), self.edit)
- self.pointerButton = RadioToolButton('edit-pointer', group = None)
- self.pointerButton.set_palette(self._pointerPalette)
- self.pointerButton.connect('toggled', self.edit.handleToolClick, 'default')
- self.pointerButton.get_child().connect('enter-notify-event', self.edit.blockFocus)
- self.pointerButton.get_child().connect('leave-notify-event', self.edit.unblockFocus)
- self.insert(self.pointerButton, -1)
- self.pointerButton.show()
-
- #Draw button
- self._drawPalette = drawPalette(_('Draw Tool'), self.edit)
- self.drawButton = RadioToolButton('edit-pencil', group = self.pointerButton)
- self.drawButton.set_palette(self._drawPalette)
- self.drawButton.connect('toggled', self.edit.handleToolClick, 'draw')
- self.drawButton.get_child().connect('enter-notify-event', self.edit.blockFocus)
- self.drawButton.get_child().connect('leave-notify-event', self.edit.unblockFocus)
- self.insert(self.drawButton, -1)
- self.drawButton.show()
-
- #Paint button
- self._paintPalette = paintPalette(_('Paint Tool'), self.edit)
- self.paintButton = RadioToolButton('edit-brush', group = self.pointerButton)
- self.paintButton.set_palette(self._paintPalette)
- self.paintButton.connect('toggled', self.edit.handleToolClick, 'paint')
- self.paintButton.get_child().connect('enter-notify-event', self.edit.blockFocus)
- self.paintButton.get_child().connect('leave-notify-event', self.edit.unblockFocus)
- self.insert(self.paintButton, -1)
- self.paintButton.show()
-
- _insertSeparator(1)
-
- #Duplicate button
- self.duplicateButton = ToggleToolButton('duplicate')
- self.duplicateButton.connect('toggled', self.handleDuplicate)
- self.insert(self.duplicateButton, -1)
- self.duplicateButton.show()
- self.duplicateButton.set_tooltip(_('Duplicate'))
-
- #Volume / Tempo button
- self._volumeTempoPalette = volumeTempoPalette(_('Volume / Tempo'), self.edit)
- self.volumeTempoButton = ToggleToolButton('voltemp')
- self.volumeTempoButton.set_palette(self._volumeTempoPalette)
- self.volumeTempoButton.get_child().connect('enter-notify-event', self.edit.blockFocus)
- self.volumeTempoButton.get_child().connect('leave-notify-event', self.edit.unblockFocus)
- self.insert(self.volumeTempoButton, -1)
- self.volumeTempoButton.show()
-
- def handlePlayPause(self, widget, data = None):
- if widget.get_active():
- self.edit.handlePlay(widget)
- widget.set_icon_widget(self.pauseButtonImg)
- else:
- self.edit.handleStop(widget, False)
- widget.set_icon_widget(self.playButtonImg)
-
- def handleStop(self, widget, data = None):
- self.edit.handleStop(widget, True)
- self.playButton.set_active(False)
- if self.recordButton.get_active():
- self.recordButton.set_active(False)
-
- def handleDuplicate(self, widget):
- if widget.get_active():
- if self.edit.getContext() == 0: #Page
- self.edit.pageDuplicate()
- elif self.edit.getContext() == 1: #Track
- self.edit.trackDuplicateWidget(widget)
- elif self.edit.getContext() == 2: #Note
- self.edit.noteDuplicateWidget(widget)
- widget.set_active(False)
-
-class generateToolbar(gtk.Toolbar):
- def __init__(self,toolbox, edit):
- gtk.Toolbar.__init__(self)
-
- def _insertSeparator(x = 1):
- for i in range(x):
- self.separator = gtk.SeparatorToolItem()
- self.separator.set_expand(True)
- self.separator.set_draw(False)
- self.insert(self.separator,-1)
- self.separator.show()
-
- self.toolbox = toolbox
- self.edit = edit
-
- self.tooltips = gtk.Tooltips()
-
- #BigGeneration button
- self.bigGenerationButton = ToolButton('diceB')
- self.bigGenerationButton.connect('clicked', self.edit.createNewTune)
- self.insert(self.bigGenerationButton, -1)
- self.bigGenerationButton.show()
- self.bigGenerationButton.set_tooltip(_('Generate Tune'))
-
- _insertSeparator(1)
-
- #Generation button
- self._generationPalette = generationPalette(_('Generation'), self.edit)
- self.generationButton = ToggleToolButton('dice')
- #self.generationButton.connect(None)
- self.generationButton.set_palette(self._generationPalette)
- self.generationButton.get_child().connect('enter-notify-event', self.edit.blockFocus)
- self.generationButton.get_child().connect('leave-notify-event', self.edit.unblockFocus)
- self.insert(self.generationButton, -1)
- self.generationButton.show()
-
- #Properties button
- self._propertiesPalette = propertiesPalette(_('Properties'), self.edit)
- self.propsButton = ToggleToolButton('props')
- self.propsButton.set_palette(self._propertiesPalette)
- self.propsButton.get_child().connect('enter-notify-event', self.edit.blockFocus)
- self.propsButton.get_child().connect('leave-notify-event', self.edit.unblockFocus)
- self.insert(self.propsButton, -1)
- self.propsButton.show()
-
-class pointerPalette(Palette):
- def __init__(self, label, edit):
- Palette.__init__(self, label)
-
- self.edit = edit
-
- self.pointerBox = gtk.VBox()
-
- self.snapGridHBox = gtk.HBox()
- self.snapGridImage = gtk.Image()
- self.snapGridImage.set_from_file(Config.TAM_TAM_ROOT + '/icons/grid.svg')
- self.snapGridBox = BigComboBox()
- self.snapGridBox.connect('changed', self.handleSnapGrid)
- self.gridDurs = [1, 2, 3, 4, 6, 12, 24]
- durs = [_('1/12'), _('1/6'), _('1/4'), _('1/3'), _('1/2'), _('1'), _('2') ]
- for dur in durs:
- self.snapGridBox.append_item(durs.index(dur),dur)
- self.snapGridBox.set_active(0)
- self.snapGridHBox.pack_start(self.snapGridImage, False, False, padding = 5)
- self.snapGridHBox.pack_start(self.snapGridBox, False, False, padding = 5)
-
- self.pointerBox.pack_start(self.snapGridHBox, False, False, padding = 5)
- self.pointerBox.show_all()
-
- self.set_content(self.pointerBox)
-
- pass
- #self.noteDur = widget.props.value
-
- def handleSnapGrid(self, widget):
- data = widget.props.value
- grid = int(self.gridDurs[data])
- self.edit.trackInterface.setPointerGrid(grid)
-
-class drawPalette(Palette):
- def __init__(self, label, edit):
- Palette.__init__(self, label)
-
- self.edit = edit
-
- self.drawBox = gtk.VBox()
-
- self.snapGridHBox = gtk.HBox()
- self.snapGridImage = gtk.Image()
- self.snapGridImage.set_from_file(Config.TAM_TAM_ROOT + '/icons/grid.svg')
- self.snapGridBox = BigComboBox()
- self.snapGridBox.connect('changed', self.handleSnapGrid)
- self.gridDurs = [1, 2, 3, 4, 6, 12, 24]
- durs = [_('1/12'), _('1/6'), _('1/4'), _('1/3'), _('1/2'), _('1'), _('2') ]
- for dur in durs:
- self.snapGridBox.append_item(durs.index(dur),dur)
- self.snapGridBox.set_active(0)
- self.snapGridHBox.pack_start(self.snapGridImage, False, False, padding = 5)
- self.snapGridHBox.pack_start(self.snapGridBox, False, False, padding = 5)
-
- self.drawBox.pack_start(self.snapGridHBox, False, False, padding = 5)
- self.drawBox.show_all()
-
- self.set_content(self.drawBox)
-
- pass
- #self.noteDur = widget.props.value
-
- def handleSnapGrid(self, widget):
- data = widget.props.value
- grid = int(self.gridDurs[data])
- self.edit.trackInterface.setDrawGrid(grid)
-
-class paintPalette(Palette):
- def __init__(self, label, edit):
- Palette.__init__(self, label)
-
- self.edit = edit
-
- self.paintBox = gtk.VBox()
-
- self.noteDurHBox = gtk.HBox()
- self.noteDurImage = gtk.Image()
- self.noteDurImage.set_from_file(Config.TAM_TAM_ROOT + '/icons/notedur.svg')
- self.noteDurBox = BigComboBox()
- self.noteDurBox.connect('changed', self.handleNoteDur)
- self.noteDurs = [1, 2, 3, 4, 6, 12, 24]
- self.durs = [_('1/12'), _('1/6'), _('1/4'), _('1/3'), _('1/2'), _('1'), _('2') ]
- for dur in self.durs:
- self.noteDurBox.append_item(self.durs.index(dur),dur)
- self.noteDurBox.set_active(2)
- self.noteDurHBox.pack_start(self.noteDurImage, False, False, padding = 5)
- self.noteDurHBox.pack_start(self.noteDurBox, False, False, padding = 5)
-
- self.snapGridHBox = gtk.HBox()
- self.snapGridImage = gtk.Image()
- self.snapGridImage.set_from_file(Config.TAM_TAM_ROOT + '/icons/grid.svg')
- self.snapGridBox = BigComboBox()
- self.snapGridBox.connect('changed', self.handleSnapGrid)
- self.gridDurs = [1, 2, 3, 4, 6, 12, 24]
- durs = [_('1/12'), _('1/6'), _('1/4'), _('1/3'), _('1/2'), _('1'), _('2')]
- for dur in durs:
- self.snapGridBox.append_item(durs.index(dur),dur)
- self.snapGridBox.set_active(2)
- self.snapGridHBox.pack_start(self.snapGridImage, False, False, padding = 5)
- self.snapGridHBox.pack_start(self.snapGridBox, False, False, padding = 5)
-
- self.paintBox.pack_start(self.noteDurHBox, False, False, padding = 5)
- self.paintBox.pack_start(self.snapGridHBox, False, False, padding = 5)
- self.paintBox.show_all()
-
- self.set_content(self.paintBox)
-
- def resizeNoteDur(self):
- oldActive = self.noteDurBox.get_active()
- len = self.snapGridBox.get_active()
- self.noteDurBox.remove_all()
- for dur in self.durs[0:len+1]:
- self.noteDurBox.append_item(self.durs.index(dur), dur)
- if oldActive <= len:
- self.noteDurBox.set_active(oldActive)
- else:
- self.noteDurBox.set_active(len)
-
- def handleNoteDur(self, widget):
- data = widget.props.value
- noteDur = int(self.noteDurs[data])
- self.edit.trackInterface.setPaintNoteDur(noteDur)
-
- def handleSnapGrid(self, widget):
- data = widget.props.value
- grid = int(self.gridDurs[data])
- self.edit.trackInterface.setPaintGrid(grid)
- self.resizeNoteDur()
-
-class volumeTempoPalette(Palette):
- def __init__(self, label, edit):
- Palette.__init__(self, label)
-
- self.edit = edit
-
- self.volumeTempoBox = gtk.VBox()
-
- self.volumeSliderBox = gtk.HBox()
- self.volumeSliderLabel = gtk.Label(_('Volume'))
- self.volumeSliderAdj = gtk.Adjustment(Config.DEFAULT_VOLUME, 0, 100, 1, 1, 0)
- self.volumeSliderAdj.connect('value-changed', self.edit.handleVolume)
- 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.volumeSliderBox.pack_start(self.volumeSliderLabel, False, False, padding = 5)
- self.volumeSliderBox.pack_end(self.volumeSlider, False, False, padding = 5)
-
- self.tempoSliderBox = gtk.HBox()
- self.tempoSliderLabel = gtk.Label(_('Tempo'))
- self.tempoSliderAdj = gtk.Adjustment(Config.PLAYER_TEMPO, 40, 240, 1, 1, 0)
- self.tempoSliderAdj.connect('value-changed', self.edit.handleTempo)
- self.tempoSlider = gtk.HScale(adjustment = self.tempoSliderAdj)
- self.tempoSlider.set_size_request(250,-1)
- self.tempoSlider.set_inverted(False)
- self.tempoSlider.set_draw_value(False)
- self.tempoSliderBox.pack_start(self.tempoSliderLabel, False, False, padding = 5)
- self.tempoSliderBox.pack_end(self.tempoSlider, False, False, padding = 5)
-
- self.volumeTempoBox.pack_start(self.volumeSliderBox, padding = 5)
- self.volumeTempoBox.pack_start(self.tempoSliderBox, padding = 5)
- self.volumeTempoBox.show_all()
-
- self.set_content(self.volumeTempoBox)
-
-class generationPalette(Palette):
- def __init__(self, label, edit):
- Palette.__init__(self, label)
-
- self.edit = edit
-
- self.rythmDensity = GenerationConstants.DEFAULT_DENSITY
- self.rythmRegularity = GenerationConstants.DEFAULT_RYTHM_REGULARITY
- self.pitchRegularity = GenerationConstants.DEFAULT_PITCH_REGULARITY
- self.pitchStep = GenerationConstants.DEFAULT_STEP
- self.duration = GenerationConstants.DEFAULT_DURATION
- self.silence = GenerationConstants.DEFAULT_SILENCE
- self.rythmMethod = GenerationConstants.DEFAULT_RYTHM_METHOD
- self.pitchMethod = GenerationConstants.DEFAULT_PITCH_METHOD
- self.pattern = GenerationConstants.DEFAULT_PATTERN
- self.scale = GenerationConstants.DEFAULT_SCALE
-
- self.mainBox = gtk.VBox()
- self.slidersBox = gtk.HBox()
- self.scaleModeBox = gtk.VBox()
- self.decisionBox = gtk.HBox()
-
- self.XYSlider1MainBox = gtk.VBox()
- self.XYSlider1TopLabel = gtk.Label(_('Rythm'))
- self.XSlider1BottomLabelBox = gtk.HBox()
- self.XSlider1Img = gtk.Image()
- self.XSlider1Img.set_from_file(Config.TAM_TAM_ROOT + '/icons/sideR.svg')
- self.XSlider1BottomLabel = gtk.Label(_('Density'))
- self.YSlider1BottomLabelBox = gtk.HBox()
- self.YSlider1Img = gtk.Image()
- self.YSlider1Img.set_from_file(Config.TAM_TAM_ROOT + '/icons/updownR.svg')
- self.YSlider1BottomLabel = gtk.Label(_('Regularity'))
- self.XYSliderBox1 = RoundFixed(fillcolor = '#CCCCCC', bordercolor = '#000000')
- self.XYSliderBox1.set_size_request(200,200)
- self.XYButton1 = ImageToggleButton( Config.TAM_TAM_ROOT + '/icons/XYBut.svg', Config.TAM_TAM_ROOT + '/icons/XYButDown.svg')
- self.XAdjustment1 = gtk.Adjustment(self.rythmDensity * 100, 0, 100, 1, 1, 1)
- self.XAdjustment1.connect("value-changed", self.handleXAdjustment1)
- self.YAdjustment1 = gtk.Adjustment(self.rythmRegularity * 100, 0, 100, 1, 1, 1)
- self.YAdjustment1.connect("value-changed", self.handleYAdjustment1)
- self.XYSlider1 = XYSlider( self.XYSliderBox1, self.XYButton1, self.XAdjustment1, self.YAdjustment1, False, True )
- self.XSlider1BottomLabelBox.pack_start(self.XSlider1Img, False, False, padding = 5)
- self.XSlider1BottomLabelBox.pack_start(self.XSlider1BottomLabel, False, False, padding = 5)
- self.YSlider1BottomLabelBox.pack_start(self.YSlider1Img, False, False, padding = 5)
- self.YSlider1BottomLabelBox.pack_start(self.YSlider1BottomLabel, False, False, padding = 5)
- self.XYSlider1MainBox.pack_start(self.XYSlider1TopLabel, False, False, padding = 5)
- self.XYSlider1MainBox.pack_start(self.XYSlider1, False, False, padding = 2)
- self.XYSlider1MainBox.pack_start(self.XSlider1BottomLabelBox, False, False, padding = 2)
- self.XYSlider1MainBox.pack_start(self.YSlider1BottomLabelBox, False, False, padding = 2)
-
- self.XYSlider2MainBox = gtk.VBox()
- self.XYSlider2TopLabel = gtk.Label(_('Pitch'))
- self.XSlider2BottomLabelBox = gtk.HBox()
- self.XSlider2Img = gtk.Image()
- self.XSlider2Img.set_from_file(Config.TAM_TAM_ROOT + '/icons/sideR.svg')
- self.XSlider2BottomLabel = gtk.Label(_('Regularity'))
- self.YSlider2BottomLabelBox = gtk.HBox()
- self.YSlider2Img = gtk.Image()
- self.YSlider2Img.set_from_file(Config.TAM_TAM_ROOT + '/icons/updownR.svg')
- self.YSlider2BottomLabel = gtk.Label(_('Maximum step'))
- self.XYSliderBox2 = RoundFixed(fillcolor = '#CCCCCC', bordercolor = '#000000')
- self.XYSliderBox2.set_size_request(200,200)
- self.XYButton2 = ImageToggleButton( Config.TAM_TAM_ROOT + '/icons/XYBut.svg', Config.TAM_TAM_ROOT + '/icons/XYButDown.svg')
- self.XAdjustment2 = gtk.Adjustment(self.pitchRegularity * 100, 0, 100, 1, 1, 1)
- self.XAdjustment2.connect("value-changed", self.handleXAdjustment2)
- self.YAdjustment2 = gtk.Adjustment(self.pitchStep * 100, 0, 100, 1, 1, 1)
- self.YAdjustment2.connect("value-changed", self.handleYAdjustment2)
- self.XYSlider2 = XYSlider( self.XYSliderBox2, self.XYButton2, self.XAdjustment2, self.YAdjustment2, False, True )
- self.XSlider2BottomLabelBox.pack_start(self.XSlider2Img, False, False, padding = 5)
- self.XSlider2BottomLabelBox.pack_start(self.XSlider2BottomLabel, False, False, padding = 5)
- self.YSlider2BottomLabelBox.pack_start(self.YSlider2Img, False, False, padding = 5)
- self.YSlider2BottomLabelBox.pack_start(self.YSlider2BottomLabel, False, False, padding = 5)
- self.XYSlider2MainBox.pack_start(self.XYSlider2TopLabel, False, False, padding = 5)
- self.XYSlider2MainBox.pack_start(self.XYSlider2, False, False, padding = 2)
- self.XYSlider2MainBox.pack_start(self.XSlider2BottomLabelBox, False, False, padding = 2)
- self.XYSlider2MainBox.pack_start(self.YSlider2BottomLabelBox, False, False, padding = 2)
-
- self.XYSlider3MainBox = gtk.VBox()
- self.XYSlider3TopLabel = gtk.Label(_('Duration'))
- self.XSlider3BottomLabelBox = gtk.HBox()
- self.XSlider3Img = gtk.Image()
- self.XSlider3Img.set_from_file(Config.TAM_TAM_ROOT + '/icons/sideR.svg')
- self.XSlider3BottomLabel = gtk.Label(_('Note duration'))
- self.YSlider3BottomLabelBox = gtk.HBox()
- self.YSlider3Img = gtk.Image()
- self.YSlider3Img.set_from_file(Config.TAM_TAM_ROOT + '/icons/updownR.svg')
- self.YSlider3BottomLabel = gtk.Label(_('Silence density'))
- self.XYSliderBox3 = RoundFixed(fillcolor = '#CCCCCC', bordercolor = '#000000')
- self.XYSliderBox3.set_size_request(200,200)
- self.XYButton3 = ImageToggleButton( Config.TAM_TAM_ROOT + '/icons/XYBut.svg', Config.TAM_TAM_ROOT + '/icons/XYButDown.svg')
- self.XAdjustment3 = gtk.Adjustment(self.duration * 100, 0, 100, 1, 1, 1)
- self.XAdjustment3.connect("value-changed", self.handleXAdjustment3)
- self.YAdjustment3 = gtk.Adjustment(self.silence * 100, 0, 100, 1, 1, 1)
- self.YAdjustment3.connect("value-changed", self.handleYAdjustment3)
- self.XYSlider3 = XYSlider( self.XYSliderBox3, self.XYButton3, self.XAdjustment3, self.YAdjustment3, False, True )
- self.XSlider3BottomLabelBox.pack_start(self.XSlider3Img, False, False, padding = 5)
- self.XSlider3BottomLabelBox.pack_start(self.XSlider3BottomLabel, False, False, padding = 5)
- self.YSlider3BottomLabelBox.pack_start(self.YSlider3Img, False, False, padding = 5)
- self.YSlider3BottomLabelBox.pack_start(self.YSlider3BottomLabel, False, False, padding = 5)
- self.XYSlider3MainBox.pack_start(self.XYSlider3TopLabel, False, False, padding = 5)
- self.XYSlider3MainBox.pack_start(self.XYSlider3, False, False, padding = 2)
- self.XYSlider3MainBox.pack_start(self.XSlider3BottomLabelBox, False, False, padding = 2)
- self.XYSlider3MainBox.pack_start(self.YSlider3BottomLabelBox, False, False, padding = 2)
-
- self.slidersBox.pack_start(self.XYSlider1MainBox, False, False, padding = 5)
- self.slidersBox.pack_start(self.XYSlider2MainBox, False, False, padding = 5)
- self.slidersBox.pack_start(self.XYSlider3MainBox, False, False, padding = 5)
-
- self.previewBox = gtk.HBox()
- self.previewDA = gtk.DrawingArea()
- self.previewDA.set_size_request( -1, 100 )
- self.previewDA.connect( "size-allocate", self.handlePreviewAlloc )
- self.previewDA.connect( "expose-event", self.handlePreviewExpose )
- self.previewBox.pack_start( self.previewDA, True, True, padding = 5 )
-
- self.scaleBoxHBox = gtk.HBox()
- self.scaleBoxLabel = gtk.Label(_('Scale: '))
- self.scaleBox = BigComboBox()
- scales = [_('Major scale'), _('Harmonic minor scale'), _('Natural minor scale'), _('Phrygian scale'), _('Dorian scale'), _('Lydian scale'), _('Myxolidian scale')]
- for scale in scales:
- self.scaleBox.append_item(scales.index(scale), scale)
- self.scaleBox.connect('changed', self.handleScale)
-
- self.modeBoxHBox = gtk.HBox()
- self.modeBoxLabel = gtk.Label(_('Mode: '))
- self.modeBox = BigComboBox()
- modes = [_('Drunk'), _('Drone and Jump'), _('Repeater'), _('Loop segments')]
- for mode in modes:
- self.modeBox.append_item(modes.index(mode), mode)
- self.modeBox.connect('changed', self.handleMode)
-
- self.scaleBoxHBox.pack_start(self.scaleBoxLabel, False, False, padding = 10)
- self.scaleBoxHBox.pack_start(self.scaleBox, False, False, padding = 10)
- self.modeBoxHBox.pack_start(self.modeBoxLabel, False, False, padding = 10)
- self.modeBoxHBox.pack_start(self.modeBox, False, False, padding = 10)
- self.scaleModeBox.pack_start(self.scaleBoxHBox, False, False, padding = 5)
- self.scaleModeBox.pack_start(self.modeBoxHBox, False, False, padding = 5)
-
- self.acceptButton = ImageButton(Config.TAM_TAM_ROOT + '/icons/accept.svg')
- self.acceptButton.connect('clicked',self.generate)
- self.cancelButton = ImageButton(Config.TAM_TAM_ROOT + '/icons/cancel.svg')
- self.cancelButton.connect('clicked',self.cancel)
- self.decisionBox.pack_start(self.cancelButton, False, False, padding = 5)
- self.decisionBox.pack_start(self.acceptButton, False, False, padding = 5)
-
- self.mainBox.pack_start(self.slidersBox, False, False, padding = 5)
- self.mainBox.pack_start( self.previewBox, False, False, padding = 5 )
- self.mainBox.pack_start(self.scaleModeBox, False, False, padding = 5)
- self.mainBox.pack_start(self.decisionBox, False, False, padding = 5)
- self.mainBox.show_all()
-
- self.set_content(self.mainBox)
-
- #-- preview drawing -----------------------------------
- win = gtk.gdk.get_default_root_window()
- self.gc = gtk.gdk.GC( win )
- self.parametersDirty = False
- self.drawingPreview = False
- self.predrawTarget = 0
- self.predrawIdleAbort = False
- self.predrawBuffer = False
- # self.predrawBuffer is initialized in handlePreviewAlloc
- pix = gtk.gdk.pixbuf_new_from_file( Config.IMAGE_ROOT+"sampleBG.png" )
- self.sampleBg = gtk.gdk.Pixmap( win, pix.get_width(), pix.get_height() )
- self.sampleBg.draw_pixbuf( self.gc, pix, 0, 0, 0, 0, pix.get_width(), pix.get_height(), gtk.gdk.RGB_DITHER_NONE )
- self.sampleBg.endOffset = pix.get_width()-5
- self.sampleNoteHeight = 7
- if True: # load clipmask
- pix = gtk.gdk.pixbuf_new_from_file(Config.IMAGE_ROOT+'sampleNoteMask.png')
- pixels = pix.get_pixels()
- stride = pix.get_rowstride()
- channels = pix.get_n_channels()
- bitmap = ""
- byte = 0
- shift = 0
- for j in range(pix.get_height()):
- offset = stride*j
- for i in range(pix.get_width()):
- r = pixels[i*channels+offset]
- if r != "\0": byte += 1 << shift
- shift += 1
- if shift > 7:
- bitmap += "%c" % byte
- byte = 0
- shift = 0
- if shift > 0:
- bitmap += "%c" % byte
- byte = 0
- shift = 0
- self.sampleNoteMask = gtk.gdk.bitmap_create_from_data( None, bitmap, pix.get_width(), pix.get_height() )
- self.sampleNoteMask.endOffset = pix.get_width()-3
-
- colormap = self.previewDA.get_colormap()
- self.colors = { "Beat_Line": colormap.alloc_color( "#959595", True, True ),
- "Note_Border": colormap.alloc_color( Config.BG_COLOR, True, True ),
- "Note_Fill": colormap.alloc_color( Config.FG_COLOR, True, True ) }
-
- self.scaleBox.set_active(0)
- self.modeBox.set_active(0)
-
-
- def handleXAdjustment1( self, data ):
- self.rythmDensity = self.XAdjustment1.value * .01
- self.parametersChanged()
-
- def handleYAdjustment1( self, data ):
- self.rythmRegularity = self.YAdjustment1.value * .01
- self.parametersChanged()
-
- def handleXAdjustment2( self, data ):
- self.pitchRegularity = self.XAdjustment2.value * .01
- self.parametersChanged()
-
- def handleYAdjustment2( self, data ):
- self.pitchStep = self.YAdjustment2.value * .01
- self.parametersChanged()
-
- def handleXAdjustment3( self, data ):
- self.duration = self.XAdjustment3.value * .01
- self.parametersChanged()
-
- def handleYAdjustment3( self, data ):
- self.silence = self.YAdjustment3.value * .01
- self.parametersChanged()
-
- def handleScale(self, widget, data = None):
- self.scale = widget.props.value
- self.edit.scale = self.scale
- self.parametersChanged()
-
- def handleMode( self, widget, data = None ):
- self.pattern = [widget.props.value for x in range(4)]
- self.parametersChanged()
-
- def getGenerationParameters( self ):
- return GenerationParameters( self.rythmDensity,
- self.rythmRegularity,
- self.pitchStep,
- self.pitchRegularity,
- self.duration,
- self.silence,
- self.rythmMethod,
- self.pitchMethod,
- self.pattern,
- self.scale )
-
- def cancel(self, widget, data = None):
- self.popdown(True)
-
- def generate(self, widget, data=None):
- context = self.edit.getContext()
- if context == 0: # Page
- mode = 'page'
- elif context == 1: # Track
- mode = 'track'
- elif context == 2: # Note
- self.popdown(True)
- return
- self.edit.setPageGenerateMode(mode)
- self.edit.generate(self.getGenerationParameters())
- self.popdown(True)
-
- ############ generate a preview melody ##############s
- def previewGenerator(self, parameters):
- makeRythm = GenerationRythm()
- makePitch = GenerationPitch()
- table_duration = Utils.scale(parameters.articule, GenerationConstants.ARTICULATION_SCALE_MIN_MAPPING, GenerationConstants.ARTICULATION_SCALE_MAX_MAPPING, GenerationConstants.ARTICULATION_SCALE_STEPS)
- table_pitch = GenerationConstants.SCALES[parameters.scale]
- beat = self.edit.noteDB.pages[self.edit.tuneInterface.getSelectedIds()[0]].beats
- barLength = Config.TICKS_PER_BEAT * beat
- trackNotes = []
-
- rythmSequence = makeRythm.celluleRythmSequence(parameters, barLength)
- pitchSequence = makePitch.drunkPitchSequence(len(rythmSequence),parameters, table_pitch, 0)
- gainSequence = self.makeGainSequence(rythmSequence)
- durationSequence = self.makeDurationSequence(rythmSequence, parameters, table_duration, barLength)
-
- for i in range(len(rythmSequence)):
- if random() > parameters.silence:
- trackNotes.append([rythmSequence[i], pitchSequence[i], gainSequence[i], durationSequence[i]])
- #print "-------------------------------------------------------",trackNotes
- return ( trackNotes, beat )
-
- def makeGainSequence( self, onsetList ):
- gainSequence = []
- max = GenerationConstants.GAIN_MAX_BOUNDARY
- midMax = GenerationConstants.GAIN_MID_MAX_BOUNDARY
- midMin = GenerationConstants.GAIN_MID_MIN_BOUNDARY
- min = GenerationConstants.GAIN_MIN_BOUNDARY
- for onset in onsetList:
- if onset == 0:
- gainSequence.append(uniform(midMax, max))
- elif ( onset % Config.TICKS_PER_BEAT) == 0:
- gainSequence.append(uniform(midMin, midMax))
- else:
- gainSequence.append(uniform(min, midMin))
- return gainSequence
-
- def makeDurationSequence( self, onsetList, parameters, table_duration, barLength ):
- durationSequence = []
- if len( onsetList ) > 1:
- for i in range(len(onsetList) - 1):
- durationSequence.append((onsetList[i+1] - onsetList[i]) * Utils.prob2( table_duration ))
- durationSequence.append(( barLength - onsetList[-1]) * Utils.prob2( table_duration ))
- elif len( onsetList ) == 1:
- durationSequence.append( ( barLength - onsetList[0] ) * Utils.prob2( table_duration ))
- return durationSequence
-
- def parametersChanged( self ):
- if not self.drawingPreview:
- self.drawPreview()
- else:
- self.parametersDirty = True
-
- def drawPreview( self, force = False ):
- if not self.predrawBuffer:
- return # not alloc'ed yet
-
- if self.drawingPreview and not force:
- return # should never happen
-
- notes, beats = self.previewGenerator( self.getGenerationParameters() )
- self.parametersDirty = False
-
- if force:
- if self.drawingPreview:
- self.predrawIdleAbort = True
- self._idleDraw( notes, beats, True, True )
- else:
- self.drawingPreview = True
- gobject.idle_add( self._idleDraw, notes, beats, True, False )
-
- def _idleDraw( self, notes, beats, fresh, force ):
- if self.predrawIdleAbort and not force:
- self.predrawIdleAbort = False
- return False
-
- pixmap = self.predrawBuffer[self.predrawTarget]
-
- if fresh:
- # draw bg
- pixmap.draw_drawable( self.gc, self.sampleBg, 0, 0, 0, 0, self.previewDA.width-5, self.previewDA.height )
- pixmap.draw_drawable( self.gc, self.sampleBg, self.sampleBg.endOffset, 0, self.previewDA.width-5, 0, 5, self.previewDA.height )
- # draw beat lines
- self.gc.set_line_attributes( Config.BEAT_LINE_SIZE, gtk.gdk.LINE_ON_OFF_DASH, gtk.gdk.CAP_BUTT, gtk.gdk.JOIN_MITER )
- self.gc.foreground = self.colors["Beat_Line"]
- for i in range(1,beats):
- x = self.beatSpacing[beats][i]
- pixmap.draw_line( self.gc, x, 1, x, self.previewDA.height-1 )
-
- if not force:
- gobject.idle_add( self._idleDraw, notes, beats, False, False )
- return False
-
- if force: N = len(notes)
- else: N = min( 3, len( notes ) ) # adjust this value to get a reasonable response
-
- self.gc.set_clip_mask( self.sampleNoteMask )
- for i in range( N ): # draw N notes
- note = notes.pop()
- x = self.ticksToPixels( beats, note[0] )
- endX = self.ticksToPixels( beats, note[0] + note[3] ) - 3 # include end cap offset
- width = endX - x
- y = self.pitchToPixels( note[1] )
- # draw fill
- self.gc.foreground = self.colors["Note_Fill"]
- self.gc.set_clip_origin( x, y-self.sampleNoteHeight )
- pixmap.draw_rectangle( self.gc, True, x+1, y+1, width+1, self.sampleNoteHeight-2 )
- # draw border
- self.gc.foreground = self.colors["Note_Border"]
- self.gc.set_clip_origin( x, y )
- pixmap.draw_rectangle( self.gc, True, x, y, width, self.sampleNoteHeight )
- self.gc.set_clip_origin( endX-self.sampleNoteMask.endOffset, y )
- pixmap.draw_rectangle( self.gc, True, endX, y, 3, self.sampleNoteHeight )
- self.gc.set_clip_rectangle( self.clearClipMask )
-
- if not len(notes):
- self.predrawTarget = not self.predrawTarget
- self.previewDA.queue_draw()
-
- self.drawingPreview = False
-
- if self.parametersDirty:
- self.drawPreview()
-
- return False
-
- return True
-
- def handlePreviewAlloc( self, widget, allocation ):
- win = gtk.gdk.get_default_root_window()
- self.previewDA.width = allocation.width
- self.previewDA.height = allocation.height
- self.predrawBuffer = [ gtk.gdk.Pixmap( win, allocation.width, allocation.height ),
- gtk.gdk.Pixmap( win, allocation.width, allocation.height ) ]
- self.clearClipMask = gtk.gdk.Rectangle( 0, 0, allocation.width, allocation.height )
-
- self.pitchPerPixel = float(Config.NUMBER_OF_POSSIBLE_PITCHES-1) / (self.previewDA.height - self.sampleNoteHeight)
- self.pixelsPerPitch = float(self.previewDA.height - self.sampleNoteHeight)/(Config.MAXIMUM_PITCH - Config.MINIMUM_PITCH)
- self.pixelsPerTick = [0] + [ self.previewDA.width/float(i*Config.TICKS_PER_BEAT) for i in range(1,Config.MAXIMUM_BEATS+1) ]
- self.ticksPerPixel = [0] + [ 1.0/self.pixelsPerTick[i] for i in range(1,Config.MAXIMUM_BEATS+1) ]
-
- self.beatSpacing = [[0]]
- for i in range(1,Config.MAXIMUM_BEATS+1):
- self.beatSpacing.append( [ self.ticksToPixels( i, Config.TICKS_PER_BEAT*j ) for j in range(i) ] )
-
- self.drawPreview( True )
-
- def handlePreviewExpose( self, widget, event ):
- widget.window.draw_drawable( self.gc, self.predrawBuffer[not self.predrawTarget], event.area.x, event.area.y, event.area.x, event.area.y, event.area.width, event.area.height )
-
- def ticksToPixels( self, beats, ticks ):
- return int(round( ticks * self.pixelsPerTick[beats] ))
- def pitchToPixels( self, pitch ):
- return int(round( ( Config.MAXIMUM_PITCH - pitch ) * self.pixelsPerPitch ))
-
-
-class propertiesPalette(Palette):
- def __init__(self, label, edit):
- Palette.__init__(self, label)
- self.connect('popup', self.handlePopup)
- self.connect('popdown', self.handlePopdown)
-
- self.edit = edit
-
- self.filterTypes = [_('None'), _('Lowpass'), _('Bandpass'), _('Highpass')]
- self.geneTypes = [_('Line'),_('Drunk'),_('Drone and Jump'),_('Repeater'),_('Loop Segments')]
- self.colors = [_('Purple'), _('Green'), _('Blue'), _('Yellow')]
- self.currentFilterType = self.filterTypes[0]
-
- self.line = Line(0, 100)
- self.drunk = Drunk(0, 100)
- self.droneAndJump = DroneAndJump(0, 100)
- self.repeter = Repeter(0, 100)
- self.loopseg = Loopseg(0, 100)
- self.algoTypes = [self.line, self.drunk, self.droneAndJump, self.repeter, self.loopseg]
- self.algorithm = self.algoTypes[0]
- self.geneMinimum = 0
- self.geneMaximum = 100
- self.geneRandom = 20
-
- self.setup = False
- self.hidden = False
- self.geneCheckButtonDic = {}
-
- self.pageIds = []
- self.context = "page"
-
- self.mainBox = gtk.VBox()
-
- self.gridDivisionBox = gtk.HBox()
- self.gridDivisionLabel = gtk.Label(_('Grid division: '))
- self.gridDivisionSliderAdj = gtk.Adjustment(4, 2, 12, 1, 1, 0)
- self.gridDivisionSlider = gtk.HScale(adjustment = self.gridDivisionSliderAdj)
- self.gridDivisionSlider.set_digits(0)
- self.gridDivisionSlider.connect('button-release-event', self.handleBeat)
- self.gridDivisionSlider.set_size_request(200,-1)
- self.gridDivisionSlider.set_value_pos(gtk.POS_RIGHT)
- self.gridDivisionBox.pack_start(self.gridDivisionLabel, False, False, padding = 5)
- self.gridDivisionBox.pack_end(self.gridDivisionSlider, False, False, padding = 52)
-
- self.pageColorBox = gtk.HBox()
- self.pageColorLabel = gtk.Label(_('Page color: '))
- self.pageColorComboBox = BigComboBox()
- for color in (0,1,2,3):
- self.pageColorComboBox.append_item(color, text = None, icon_name = Config.IMAGE_ROOT + 'pageThumbnailBG' + str(color) + '.png', size = (30,40))
- self.pageColorComboBox.set_active(0)
- self.pageColorComboBox.connect('changed', self.handleColor)
- self.pageColorBox.pack_start(self.pageColorLabel, False, False, padding = 5)
- self.pageColorBox.pack_end(self.pageColorComboBox, False, False, padding = 55)
-
- self.pageSeparator = gtk.HSeparator()
- self.pageSeparator.set_size_request(20, -1)
-
- self.transposeBox = gtk.HBox()
- self.transposeLabel = gtk.Label(_('Transposition: '))
- self.transposeDownButton = ImageButton(Config.TAM_TAM_ROOT + '/icons/arrow-down.svg')
- self.transposeDownButton.connect('clicked', self.stepPitch, -1)
- self.transposeUpButton = ImageButton(Config.TAM_TAM_ROOT + '/icons/arrow-up.svg')
- self.transposeUpButton.connect('clicked', self.stepPitch, 1)
- self.transposeCheckButton = gtk.CheckButton()
- self.transposeCheckButton.connect('toggled', self.handleGeneCheckButton)
- self.geneCheckButtonDic['transpose'] = self.transposeCheckButton
- self.transposeBox.pack_start(self.transposeLabel, False, False, padding = 5)
- self.transposeBox.pack_end(self.transposeCheckButton, False, False, padding = 5)
- self.transposeBox.pack_end(self.transposeUpButton, False, False, padding = 50)
- self.transposeBox.pack_end(self.transposeDownButton, False, False, padding = 5)
-
- self.volumeBox = gtk.HBox()
- self.volumeLabel = gtk.Label(_('Volume: '))
- self.volumeDownButton = ImageButton(Config.TAM_TAM_ROOT + '/icons/arrow-down.svg')
- self.volumeDownButton.connect('clicked', self.stepVolume, -0.1)
- self.volumeUpButton = ImageButton(Config.TAM_TAM_ROOT + '/icons/arrow-up.svg')
- self.volumeUpButton.connect('clicked', self.stepVolume, 0.1)
- self.volumeCheckButton = gtk.CheckButton()
- self.volumeCheckButton.connect('toggled', self.handleGeneCheckButton)
- self.geneCheckButtonDic['volume'] = self.volumeCheckButton
- self.volumeBox.pack_start(self.volumeLabel, False, False, padding = 5)
- self.volumeBox.pack_end(self.volumeCheckButton, False, False, padding = 5)
- self.volumeBox.pack_end(self.volumeUpButton, False, False, padding = 50)
- self.volumeBox.pack_end(self.volumeDownButton, False, False, padding = 5)
-
- self.panBox = gtk.HBox()
- self.panLabel = gtk.Label(_('Pan: '))
- self.panSliderAdj = gtk.Adjustment(0.5, 0, 1, .1, .1, 0)
- self.panSliderAdj.connect('value-changed', self.handlePan)
- self.panSlider = gtk.HScale(adjustment = self.panSliderAdj)
- self.panSlider.set_size_request(200,-1)
- self.panSlider.set_value_pos(gtk.POS_RIGHT)
- self.panSlider.set_update_policy(gtk.UPDATE_DISCONTINUOUS)
- self.panCheckButton = gtk.CheckButton()
- self.panCheckButton.connect('toggled', self.handleGeneCheckButton)
- self.geneCheckButtonDic['pan'] = self.panCheckButton
- self.panBox.pack_start(self.panLabel, False, False, padding = 5)
- self.panBox.pack_end(self.panCheckButton, False, False, padding = 5)
- self.panBox.pack_end(self.panSlider, False, False, padding = 5)
-
- self.reverbBox = gtk.HBox()
- self.reverbLabel = gtk.Label(_('Reverb: '))
- self.reverbSliderAdj = gtk.Adjustment(0.1, 0, 1, 0.1, 0.1, 0)
- self.reverbSliderAdj.connect("value-changed", self.handleReverb)
- self.reverbSlider = gtk.HScale(adjustment = self.reverbSliderAdj)
- self.reverbSlider.set_size_request(200,-1)
- self.reverbSlider.set_value_pos(gtk.POS_RIGHT)
- self.reverbSlider.set_update_policy(gtk.UPDATE_DISCONTINUOUS)
- self.reverbCheckButton = gtk.CheckButton()
- self.reverbCheckButton.connect('toggled', self.handleGeneCheckButton)
- self.geneCheckButtonDic['reverb'] = self.reverbCheckButton
- self.reverbBox.pack_start(self.reverbLabel, False, False, padding = 5)
- self.reverbBox.pack_end(self.reverbCheckButton, False, False, padding = 5)
- self.reverbBox.pack_end(self.reverbSlider, False, False, padding = 5)
-
- self.attackDurBox = gtk.HBox()
- self.attackDurLabel = gtk.Label(_('Attack duration: '))
- self.attackDurSliderAdj = gtk.Adjustment(0.04, 0.03, 1, .01, .01, 0)
- self.attackDurSliderAdj.connect('value-changed', self.handleAttack)
- self.attackDurSlider = gtk.HScale(adjustment = self.attackDurSliderAdj)
- self.attackDurSlider.set_size_request(200,-1)
- self.attackDurSlider.set_value_pos(gtk.POS_RIGHT)
- self.attackDurSlider.set_update_policy(gtk.UPDATE_DISCONTINUOUS)
- self.attackDurCheckButton = gtk.CheckButton()
- self.attackDurCheckButton.connect('toggled', self.handleGeneCheckButton)
- self.geneCheckButtonDic['attack'] = self.attackDurCheckButton
- self.attackDurBox.pack_start(self.attackDurLabel, False, False, padding = 5)
- self.attackDurBox.pack_end(self.attackDurCheckButton, False, False, padding = 5)
- self.attackDurBox.pack_end(self.attackDurSlider, False, False, padding = 5)
-
- self.decayDurBox = gtk.HBox()
- self.decayDurLabel = gtk.Label(_('Decay duration: '))
- self.decayDurSliderAdj = gtk.Adjustment(0.31, 0.03, 1, .01, .01, 0)
- self.decayDurSliderAdj.connect('value-changed', self.handleDecay)
- self.decayDurSlider = gtk.HScale(adjustment = self.decayDurSliderAdj)
- self.decayDurSlider.set_size_request(200,-1)
- self.decayDurSlider.set_value_pos(gtk.POS_RIGHT)
- self.decayDurSlider.set_update_policy(gtk.UPDATE_DISCONTINUOUS)
- self.decayDurCheckButton = gtk.CheckButton()
- self.decayDurCheckButton.connect('toggled', self.handleGeneCheckButton)
- self.geneCheckButtonDic['decay'] = self.decayDurCheckButton
- self.decayDurBox.pack_start(self.decayDurLabel, False, False, padding = 5)
- self.decayDurBox.pack_end(self.decayDurCheckButton, False, False, padding = 5)
- self.decayDurBox.pack_end(self.decayDurSlider, False, False, padding = 5)
-
- self.filterTypeBox = gtk.HBox()
- self.filterTypeLabel = gtk.Label(_('Filter Type: '))
- self.filterTypeComboBox = BigComboBox()
- for filtertype in self.filterTypes:
- self.filterTypeComboBox.append_item(self.filterTypes.index(filtertype), filtertype, Config.TAM_TAM_ROOT + '/icons/test.svg', (30,30))
- self.filterTypeComboBox.connect('changed', self.handleFilterTypes)
- self.filterTypeBox.pack_start(self.filterTypeLabel, False, False, padding = 5)
- self.filterTypeBox.pack_end(self.filterTypeComboBox, False, False, padding = 55)
-
- self.filterCutoffBox = gtk.HBox()
- self.filterCutoffLabel = gtk.Label(_('Filter cutoff: '))
- self.filterCutoffSliderAdj = gtk.Adjustment(1000, 100, 7000, 100, 100, 0)
- self.filterCutoffSliderAdj.connect('value-changed', self.handleFilter)
- self.filterCutoffSlider = gtk.HScale(adjustment = self.filterCutoffSliderAdj)
- self.filterCutoffSlider.set_size_request(200,-1)
- self.filterCutoffSlider.set_value_pos(gtk.POS_RIGHT)
- self.filterCutoffSlider.set_update_policy(gtk.UPDATE_DISCONTINUOUS)
- self.filterCutoffCheckButton = gtk.CheckButton()
- self.filterCutoffCheckButton.connect('toggled', self.handleGeneCheckButton)
- self.geneCheckButtonDic['filter'] = self.filterCutoffCheckButton
- self.filterCutoffBox.pack_start(self.filterCutoffLabel, False, False, padding = 5)
- self.filterCutoffBox.pack_end(self.filterCutoffCheckButton, False, False, padding = 5)
- self.filterCutoffBox.pack_end(self.filterCutoffSlider, False, False, padding = 5)
-
- self.generationMainBox = gtk.VBox()
- self.generationSeparator = gtk.HSeparator()
- self.generationLabel = gtk.Label(_('Generation'))
-
- self.generationTypeBox = gtk.HBox()
- self.generationTypeLabel = gtk.Label(_('Type: '))
- self.generationTypeComboBox = BigComboBox()
- for genetype in self.geneTypes:
- self.generationTypeComboBox.append_item(self.geneTypes.index(genetype), genetype, Config.TAM_TAM_ROOT + '/icons/test.svg', (30,30))
- self.generationTypeComboBox.connect('changed', self.handleGeneTypes)
- self.generationTypeComboBox.set_active(0)
- self.generationTypeBox.pack_start(self.generationTypeLabel, False, False, padding = 5)
- self.generationTypeBox.pack_end(self.generationTypeComboBox, False, False, padding = 55)
-
- self.minimumBox = gtk.HBox()
- self.minimumLabel = gtk.Label(_('Minimum: '))
- self.minimumSliderAdj = gtk.Adjustment(0, 0, 100, 1, 1, 0)
- self.minimumSliderAdj.connect('value-changed', self.handleMinimum)
- self.minimumSlider = gtk.HScale(adjustment = self.minimumSliderAdj)
- self.minimumSlider.set_size_request(200,-1)
- self.minimumSlider.set_update_policy(gtk.UPDATE_DISCONTINUOUS)
- self.minimumSlider.set_value_pos(gtk.POS_RIGHT)
- self.minimumBox.pack_start(self.minimumLabel, False, False, padding = 5)
- self.minimumBox.pack_end(self.minimumSlider, False, False, padding = 52)
-
- self.maximumBox = gtk.HBox()
- self.maximumLabel = gtk.Label(_('Maximum: '))
- self.maximumSliderAdj = gtk.Adjustment(100, 0, 100, 1, 1, 0)
- self.maximumSliderAdj.connect('value-changed', self.handleMaximum)
- self.maximumSlider = gtk.HScale(adjustment = self.maximumSliderAdj)
- self.maximumSlider.set_size_request(200,-1)
- self.maximumSlider.set_update_policy(gtk.UPDATE_DISCONTINUOUS)
- self.maximumSlider.set_value_pos(gtk.POS_RIGHT)
- self.maximumBox.pack_start(self.maximumLabel, False, False, padding = 5)
- self.maximumBox.pack_end(self.maximumSlider, False, False, padding = 52)
-
- self.randomBox = gtk.HBox()
- self.randomLabel = gtk.Label(_('Random: '))
- self.randomSliderAdj = gtk.Adjustment(20, 0, 100, 1, 1, 0)
- self.randomSliderAdj.connect('value-changed', self.handleRandom)
- self.randomSlider = gtk.HScale(adjustment = self.randomSliderAdj)
- self.randomSlider.set_size_request(200,-1)
- self.randomSlider.set_update_policy(gtk.UPDATE_DISCONTINUOUS)
- self.randomSlider.set_value_pos(gtk.POS_RIGHT)
- self.randomBox.pack_start(self.randomLabel, False, False, padding = 5)
- self.randomBox.pack_end(self.randomSlider, False, False, padding = 52)
-
- self.decisionBox = gtk.HBox()
- self.acceptButton = ImageButton(Config.TAM_TAM_ROOT + '/icons/accept.svg')
- self.acceptButton.connect('clicked', self.acceptGeneration)
- self.cancelButton = ImageButton(Config.TAM_TAM_ROOT + '/icons/cancel.svg')
- self.cancelButton.connect('clicked', self.resetGeneCheckButton)
- self.decisionBox.pack_start(self.cancelButton, False, False, padding = 5)
- self.decisionBox.pack_start(self.acceptButton, False, False, padding = 5)
-
- self.mainBox.pack_start(self.gridDivisionBox, padding = 3)
- self.mainBox.pack_start(self.pageColorBox, padding = 3)
- self.mainBox.pack_start(self.pageSeparator, padding = 10)
- self.mainBox.pack_start(self.transposeBox, padding = 3)
- self.mainBox.pack_start(self.volumeBox, padding = 3)
- self.mainBox.pack_start(self.panBox, padding = 3)
- self.mainBox.pack_start(self.reverbBox, padding = 3)
- self.mainBox.pack_start(self.attackDurBox, padding = 3)
- self.mainBox.pack_start(self.decayDurBox, padding = 3)
- self.mainBox.pack_start(self.filterTypeBox, padding = 3)
- self.mainBox.pack_start(self.filterCutoffBox, padding = 3)
- self.generationMainBox.pack_start(self.generationSeparator, padding = 5)
- self.generationMainBox.pack_start(self.generationLabel, padding = 10)
- self.generationMainBox.pack_start(self.generationTypeBox, padding = 3)
- self.generationMainBox.pack_start(self.minimumBox, padding = 3)
- self.generationMainBox.pack_start(self.maximumBox, padding = 3)
- self.generationMainBox.pack_start(self.randomBox, padding = 3)
- self.generationMainBox.pack_start(self.decisionBox, padding = 3)
- self.mainBox.pack_start(self.generationMainBox, padding = 3)
- self.mainBox.show_all()
-
- self.generationMainBox.hide()
-
- self.set_content(self.mainBox)
-
- def handlePopup(self, widget, data = None):
- if self.edit.getContext() == 0: #Page
- self.setContext('page', self.edit._generateToolbar._generationPalette.scale, self.edit.tuneInterface.getSelectedIds())
- elif self.edit.getContext() == 1: #Track
- self.setContext('track', self.edit._generateToolbar._generationPalette.scale, self.edit.tuneInterface.getSelectedIds(), [ i for i in range(Config.NUMBER_OF_TRACKS) if self.edit.trackSelected[i] ])
- elif self.edit.getContext() == 2: #Note
- ids = self.edit.trackInterface.getSelectedNotes()
- notes = { self.edit.displayedPage: {} }
- for t in range(Config.NUMBER_OF_TRACKS):
- if len(ids[t]):
- notes[self.edit.displayedPage][t] = [ self.edit.noteDB.getNote( self.edit.displayedPage, t, id ) for id in ids[t] ]
- self.setContext('note', self.edit._generateToolbar._generationPalette.scale, notes = notes)
-
- def handlePopdown(self, widget, data = None):
- self.resetGeneCheckButton(self.cancelButton)
-
- def setContext( self, context, scale, pageIds = None, trackIds = None, notes = {} ):
- self.context = context
- self.scale = GenerationConstants.SCALES[scale]
- self.notes = {}
- self.pageIds = pageIds
- self.trackIds = trackIds
-
- if context == "page":
- self.trackIds = [0,1,2,3,4]
- for p in pageIds:
- self.notes[p] = {}
- for t in range(Config.NUMBER_OF_TRACKS):
- self.notes[p][t] = self.edit.noteDB.getNotesByTrack( p, t )
- page = self.edit.noteDB.getPage(pageIds[0])
- self.gridDivisionSliderAdj.set_value(page.beats)
- elif context == "track":
- for p in pageIds:
- self.notes[p] = {}
- for t in trackIds:
- self.notes[p][t] = self.edit.noteDB.getNotesByTrack( p, t )
- else:
- self.notes = notes
- self.pageIds = self.notes.keys()
- self.trackIds = self.notes[self.pageIds[0]].keys()
-
- for p in self.notes:
- for t in self.notes[p]:
- if len(self.notes[p][t]):
- # initialize values from first note
- self.setup = True
- n = self.notes[p][t][0]
- self.panSliderAdj.set_value( n.cs.pan )
- self.reverbSliderAdj.set_value( n.cs.reverbSend )
- self.attackDurSliderAdj.set_value( n.cs.attack )
- self.decayDurSliderAdj.set_value( n.cs.decay )
- self.filterTypeComboBox.set_active(n.cs.filterType)
- self.currentFilterType = n.cs.filterType
- self.filterCutoffSliderAdj.set_value( n.cs.filterCutoff )
- self.setup = False
-
- def acceptGeneration( self, widget ):
- valList = [self.geneMinimum, self.geneMaximum, self.geneRandom]
- if self.geneCheckButtonDic['transpose'].get_active(): self.algoPitch(valList, self.algorithm)
- if self.geneCheckButtonDic['volume'].get_active(): self.algoVolume(valList, self.algorithm)
- if self.geneCheckButtonDic['pan'].get_active(): self.algoPan(valList, self.algorithm)
- if self.geneCheckButtonDic['reverb'].get_active(): self.algoReverb(valList, self.algorithm)
- if self.geneCheckButtonDic['attack'].get_active(): self.algoAttack(valList, self.algorithm)
- if self.geneCheckButtonDic['decay'].get_active(): self.algoDecay(valList, self.algorithm)
- if self.geneCheckButtonDic['filter'].get_active(): self.algoCutoff(valList, self.algorithm)
-
- def resetGeneCheckButton(self, widget):
- if self.hidden:
- self.generationMainBox.hide()
-
- for key in self.geneCheckButtonDic:
- self.geneCheckButtonDic[key].set_active(False)
-
- def handleGeneCheckButton(self, widget, data = None):
- self.hidden = True
- if widget.get_active():
- self.generationMainBox.show()
- else:
- for key in self.geneCheckButtonDic:
- if self.geneCheckButtonDic[key].get_active():
- self.hidden = False
- if self.hidden:
- self.generationMainBox.hide()
-
-
- def handleBeat(self, widget, signal_id):
- beats = int(widget.get_adjustment().value)
- stream = []
- for page in self.pageIds:
- stream += [ page, beats ]
- if len(stream):
- self.edit.noteDB.updatePages( [ PARAMETER.PAGE_BEATS, len(stream)//2 ] + stream )
-
- def handleColor(self, widget):
- index = widget.props.value
- stream = []
- for page in self.pageIds:
- stream += [ page, index ]
- if len(stream):
- self.edit.noteDB.updatePages( [ PARAMETER.PAGE_COLOR, len(stream)//2 ] + stream )
-
- def stepPitch(self, widget, step):
- stream = []
- for p in self.notes:
- for t in self.notes[p]:
- substream = []
- if step > 0:
- if t != Config.NUMBER_OF_TRACKS-1: # regular note
- for n in self.notes[p][t]:
- if n.cs.pitch != Config.MAXIMUM_PITCH:
- substream += [ n.id, min( Config.MAXIMUM_PITCH, n.cs.pitch + step ) ]
- else: # drum note
- for n in self.notes[p][t]:
- if n.cs.pitch != Config.MAXIMUM_PITCH_DRUM:
- substream += [ n.id, min( Config.MAXIMUM_PITCH_DRUM, n.cs.pitch + step*Config.PITCH_STEP_DRUM ) ]
- else:
- if t != Config.NUMBER_OF_TRACKS-1: # regular note
- for n in self.notes[p][t]:
- if n.cs.pitch != Config.MINIMUM_PITCH:
- substream += [ n.id, max( Config.MINIMUM_PITCH, n.cs.pitch + step ) ]
- else: # drum note
- for n in self.notes[p][t]:
- if n.cs.pitch != Config.MINIMUM_PITCH_DRUM:
- substream += [ n.id, max( Config.MINIMUM_PITCH_DRUM, n.cs.pitch + step*Config.PITCH_STEP_DRUM ) ]
- if len(substream):
- stream += [ p, t, PARAMETER.PITCH, len(substream)//2 ] + substream
- if len(stream):
- self.edit.noteDB.updateNotes( stream + [-1] )
-
- def algoPitch( self, list, algorithm ):
- maxValue = max(list[0], list[1])
- scaleLength = len(self.scale)-1
- stream = []
- for t in range(len(self.trackIds)):
- trackLength = 0
- for p in range(len(self.pageIds)):
- trackLength += len(self.notes[self.pageIds[p]][self.trackIds[t]])
- algorithm.__init__(list[0], list[1], trackLength)
- for p in range(len(self.pageIds)):
- substream = []
- if self.trackIds[t] != Config.NUMBER_OF_TRACKS-1:
- for n in self.notes[self.pageIds[p]][self.trackIds[t]]:
- val = algorithm.getNextValue(list[2], maxValue)
- substream += [ n.id, self.scale[int(val*0.01*scaleLength)]+36 ]
- if len(substream):
- stream += [ self.pageIds[p], self.trackIds[t], PARAMETER.PITCH, len(substream)//2 ] + substream
- else:
- for n in self.notes[self.pageIds[p]][self.trackIds[t]]:
- val = algorithm.getNextValue(list[2], maxValue)
- val = int((val*0.12)*2+24)
- if val in GenerationConstants.DRUMPITCH.keys():
- val = GenerationConstants.DRUMPITCH[val]
- substream += [ n.id, val ]
- if len(substream):
- stream += [ self.pageIds[p], self.trackIds[t], PARAMETER.PITCH, len(substream)//2 ] + substream
- if len(stream):
- self.edit.noteDB.updateNotes( stream + [-1] )
-
- def stepVolume(self, widget, step):
- stream = []
- for p in self.notes:
- for t in self.notes[p]:
- substream = []
- if step > 0:
- for n in self.notes[p][t]:
- if n.cs.amplitude != Config.MAXIMUM_AMPLITUDE:
- substream += [ n.id, min( Config.MAXIMUM_AMPLITUDE, n.cs.amplitude + step ) ]
- else:
- for n in self.notes[p][t]:
- if n.cs.amplitude != Config.MINIMUM_AMPLITUDE:
- substream += [ n.id, max( Config.MINIMUM_AMPLITUDE, n.cs.amplitude + step ) ]
- if len(substream):
- stream += [ p, t, PARAMETER.AMPLITUDE, len(substream)//2 ] + substream
- if len(stream):
- self.edit.noteDB.updateNotes( stream + [-1] )
-
-
- def algoVolume( self, list, algorithm ):
- maxValue = max(list[0], list[1])
- stream = []
- for t in range(len(self.trackIds)):
- trackLength = 0
- for p in range(len(self.pageIds)):
- trackLength += len(self.notes[self.pageIds[p]][self.trackIds[t]])
- algorithm.__init__(list[0], list[1], trackLength)
- for p in range(len(self.pageIds)):
- substream = []
- for n in self.notes[self.pageIds[p]][self.trackIds[t]]:
- val = algorithm.getNextValue(list[2], maxValue)
- substream += [ n.id, min( Config.MAXIMUM_AMPLITUDE, val*0.01 ) ]
- if len(substream):
- stream += [ self.pageIds[p], self.trackIds[t], PARAMETER.AMPLITUDE, len(substream)//2 ] + substream
- if len(stream):
- self.edit.noteDB.updateNotes( stream + [-1] )
-
- def handlePan(self, adjust):
- if not self.setup:
- stream = []
- for p in self.notes:
- for t in self.notes[p]:
- if len(self.notes[p][t]):
- stream += [ p, t, PARAMETER.PAN, len(self.notes[p][t]) ]
- for n in self.notes[p][t]:
- stream += [ n.id, adjust.value ]
- if len(stream):
- self.edit.noteDB.updateNotes( stream + [-1] )
-
- def algoPan( self, list, algorithm ):
- maxValue = max(list[0], list[1])
- stream = []
- for t in range(len(self.trackIds)):
- trackLength = 0
- for p in range(len(self.pageIds)):
- trackLength += len(self.notes[self.pageIds[p]][self.trackIds[t]])
- algorithm.__init__(list[0], list[1], trackLength)
- for p in range(len(self.pageIds)):
- substream = []
- for n in self.notes[self.pageIds[p]][self.trackIds[t]]:
- val = algorithm.getNextValue(list[2], maxValue)
- substream += [ n.id, val*0.01 ]
- if len(substream):
- stream += [ self.pageIds[p], self.trackIds[t], PARAMETER.PAN, len(substream)//2 ] + substream
- if len(stream):
- self.edit.noteDB.updateNotes( stream + [-1] )
-
- def handleReverb(self, adjust):
- if not self.setup:
- stream = []
- for p in self.notes:
- for t in self.notes[p]:
- if len(self.notes[p][t]):
- stream += [ p, t, PARAMETER.REVERB, len(self.notes[p][t]) ]
- for n in self.notes[p][t]:
- stream += [ n.id, adjust.value ]
- if len(stream):
- self.edit.noteDB.updateNotes( stream + [-1] )
-
- def algoReverb( self, list, algorithm ):
- maxValue = max(list[0], list[1])
- stream = []
- for t in range(len(self.trackIds)):
- trackLength = 0
- for p in range(len(self.pageIds)):
- trackLength += len(self.notes[self.pageIds[p]][self.trackIds[t]])
- algorithm.__init__(list[0], list[1], trackLength)
- for p in range(len(self.pageIds)):
- substream = []
- for n in self.notes[self.pageIds[p]][self.trackIds[t]]:
- val = algorithm.getNextValue(list[2], maxValue)
- substream += [ n.id, val*0.02 ]
- if len(substream):
- stream += [ self.pageIds[p], self.trackIds[t], PARAMETER.REVERB, len(substream)//2 ] + substream
- if len(stream):
- self.edit.noteDB.updateNotes( stream + [-1] )
-
- def handleAttack(self, adjust):
- if not self.setup:
- stream = []
- for p in self.notes:
- for t in self.notes[p]:
- if len(self.notes[p][t]):
- stream += [ p, t, PARAMETER.ATTACK, len(self.notes[p][t]) ]
- for n in self.notes[p][t]:
- stream += [ n.id, adjust.value ]
- if len(stream):
- self.edit.noteDB.updateNotes( stream + [-1] )
-
- def algoAttack( self, list, algorithm ):
- maxValue = max(list[0], list[1])
- stream = []
- for t in range(len(self.trackIds)):
- trackLength = 0
- for p in range(len(self.pageIds)):
- trackLength += len(self.notes[self.pageIds[p]][self.trackIds[t]])
- algorithm.__init__(list[0], list[1], trackLength)
- for p in range(len(self.pageIds)):
- substream = []
- for n in self.notes[self.pageIds[p]][self.trackIds[t]]:
- val = algorithm.getNextValue(list[2], maxValue)
- substream += [ n.id, val*0.01 ]
- if len(substream):
- stream += [ self.pageIds[p], self.trackIds[t], PARAMETER.ATTACK, len(substream)//2 ] + substream
- if len(stream):
- self.edit.noteDB.updateNotes( stream + [-1] )
-
- def handleDecay(self, adjust):
- if not self.setup:
- stream = []
- for p in self.notes:
- for t in self.notes[p]:
- if len(self.notes[p][t]):
- stream += [ p, t, PARAMETER.DECAY, len(self.notes[p][t]) ]
- for n in self.notes[p][t]:
- stream += [ n.id, adjust.value ]
- if len(stream):
- self.edit.noteDB.updateNotes( stream + [-1] )
-
-
- def algoDecay( self, list, algorithm ):
- maxValue = max(list[0], list[1])
- stream = []
- for t in range(len(self.trackIds)):
- trackLength = 0
- for p in range(len(self.pageIds)):
- trackLength += len(self.notes[self.pageIds[p]][self.trackIds[t]])
- algorithm.__init__(list[0], list[1], trackLength)
- for p in range(len(self.pageIds)):
- substream = []
- for n in self.notes[self.pageIds[p]][self.trackIds[t]]:
- val = algorithm.getNextValue(list[2], maxValue)
- substream += [ n.id, val*0.01 ]
- if len(substream):
- stream += [ self.pageIds[p], self.trackIds[t], PARAMETER.DECAY, len(substream)//2 ] + substream
- if len(stream):
- self.edit.noteDB.updateNotes( stream + [-1] )
-
- def handleFilterTypes(self, widget):
- self.currentFilterType = widget.props.value
-
- if not self.currentFilterType:
- self.filterCutoffSlider.set_sensitive(False)
- else:
- self.filterCutoffSlider.set_sensitive(True)
-
- if not self.setup:
- if self.currentFilterType:
- typestream = []
- cutoffstream = []
- cutoff = self.filterCutoffSliderAdj.value
- for p in self.notes:
- for t in self.notes[p]:
- if len(self.notes[p][t]):
- substream = []
- typestream += [ p, t, PARAMETER.FILTERTYPE, len(self.notes[p][t]) ]
- for n in self.notes[p][t]:
- typestream += [ n.id, self.currentFilterType ]
- if n.cs.filterCutoff != cutoff:
- substream += [ n.id, cutoff ]
- if len(substream):
- cutoffstream += [ p, t, PARAMETER.FILTERCUTOFF, len(substream)//2 ] + substream
- if len(typestream):
- self.edit.noteDB.updateNotes( typestream + [-1] )
- if len(cutoffstream):
- self.edit.noteDB.updateNotes( cutoffstream + [-1] )
- else:
- self.currentFilterType = 0
- typestream = []
- for p in self.notes:
- for t in self.notes[p]:
- if len(self.notes[p][t]):
- typestream += [ p, t, PARAMETER.FILTERTYPE, len(self.notes[p][t]) ]
- for n in self.notes[p][t]:
- typestream += [ n.id, 0 ]
- if len(typestream):
- self.edit.noteDB.updateNotes( typestream + [-1] )
-
- def handleFilter(self, adjust):
- stream = []
- for p in self.notes:
- for t in self.notes[p]:
- if len(self.notes[p][t]):
- stream += [ p, t, PARAMETER.FILTERCUTOFF, len(self.notes[p][t]) ]
- for n in self.notes[p][t]:
- stream += [ n.id, adjust.value ]
- if len(stream):
- self.edit.noteDB.updateNotes( stream + [-1] )
-
- def algoCutoff( self, list, algorithm ):
- maxValue = max(list[0], list[1])
- stream = []
- for t in range(len(self.trackIds)):
- trackLength = 0
- for p in range(len(self.pageIds)):
- trackLength += len(self.notes[self.pageIds[p]][self.trackIds[t]])
- algorithm.__init__(list[0], list[1], trackLength)
- for p in range(len(self.pageIds)):
- substream = []
- for n in self.notes[self.pageIds[p]][self.trackIds[t]]:
- val = algorithm.getNextValue(list[2], maxValue)
- substream += [ n.id, val*70+100 ]
- if len(substream):
- stream += [ self.pageIds[p], self.trackIds[t], PARAMETER.FILTERCUTOFF, len(substream)//2 ] + substream
- if len(stream):
- self.edit.noteDB.updateNotes( stream + [-1] )
-
- def handleGeneTypes(self, widget):
- self.algorithm = self.algoTypes[widget.props.value]
-
- def handleMinimum(self, adjust):
- self.geneMinimum = int(adjust.value)
-
- def handleMaximum(self, adjust):
- self.geneMaximum = int(adjust.value)
-
- def handleRandom(self, adjust):
- self.geneRandom = int(adjust.value)
diff --git a/Edit/HitInterface.py b/Edit/HitInterface.py
deleted file mode 100644
index 6e77908..0000000
--- a/Edit/HitInterface.py
+++ /dev/null
@@ -1,195 +0,0 @@
-import pygtk
-pygtk.require( '2.0' )
-import gtk
-
-from Util.NoteDB import PARAMETER
-from Edit.NoteInterface import NoteInterface
-import Config
-
-class HitInterface( NoteInterface ):
-
- def __init__( self, noteDB, owner, note ):
- NoteInterface.__init__( self, noteDB, owner, note )
-
- self.width = self.height = Config.HIT_HEIGHT
- self.imgWidth = self.imgHeight = Config.HIT_HEIGHT + Config.HIT_IMAGE_PADDING_MUL2
-
- self.firstTransform = True
- self.updateTransform()
-
- def updateTransform( self ):
- if self.note.page in self.owner.getActivePages():
- if not self.firstTransform:
- oldX = self.imgX
- oldY = self.imgY
- oldEndX = self.imgX + self.imgWidth
- dirty = True
- else:
- dirty = False
-
- beats = self.noteDB.getPage( self.note.page ).beats
- if self.note.cs.onset != self.oldOnset or beats != self.oldBeats:
- self.x = self.owner.ticksToPixels( beats, self.note.cs.onset )
- self.x += self.origin[0]
- self.imgX = self.x - Config.NOTE_IMAGE_PADDING
- self.oldOnset = self.note.cs.onset
- self.oldBeats = beats
- if self.note.cs.pitch != self.oldPitch:
- self.y = self.owner.pitchToPixelsDrum( self.note.cs.pitch ) + self.origin[1]
- self.imgY = self.y - Config.NOTE_IMAGE_PADDING
- self.oldPitch = self.note.cs.pitch
-
- if dirty:
- if self.firstTransform:
- self.owner.invalidate_rect( self.imgX, self.imgY, self.imgWidth, self.imgHeight, self.note.page )
- self.firstTransform = False
- else:
- x = min( self.imgX, oldX )
- y = min( self.imgY, oldY )
- endx = max( self.imgX + self.imgWidth, oldEndX )
- endy = max( self.imgY, oldY ) + self.imgHeight
- self.owner.invalidate_rect( x, y, endx-x, endy-y, self.note.page )
-
- self.firstTransform = False
-
- def updateDragLimits( self, dragLimits, leftBound, rightBound, widthBound, maxRightBound ):
- left = 0 - self.note.cs.onset
- right = maxRightBound - self.note.cs.duration - self.note.cs.onset
- up = Config.MAXIMUM_PITCH_DRUM - self.note.cs.pitch
- down = Config.MINIMUM_PITCH_DRUM - self.note.cs.pitch
-
- if dragLimits[0][0] < left: dragLimits[0][0] = left
- if dragLimits[0][1] > right: dragLimits[0][1] = right
- if dragLimits[1][0] < down: dragLimits[1][0] = down
- if dragLimits[1][1] > up: dragLimits[1][1] = up
-
- # store the current loc as a reference point
- self.baseOnset = self.note.cs.onset
- self.basePitch = self.note.cs.pitch
-
- #=======================================================
- # Events
-
- # handleButtonPress returns:
- # -1, event occurs before us so don't bother checking any later notes
- # 0, event didn't hit
- # 1, event was handled
- def handleButtonPress( self, emitter, event ):
- eX = event.x - self.x
- if eX < 0:
- return -1 # event occurs before us, no point in checking further
- if eX > self.width:
- return 0 # no X overlap
-
- eY = event.y - self.y
- if eY < 0 or eY > self.height:
- return 0 # not a hit
-
- if event.button == 3:
- print "Show some note parameters!?!"
- #self.noteParameters = NoteParametersWindow( self.note, self.getNoteParameters )
- return 1 # handled
-
- playSample = False
-
- if event.type == gtk.gdk._2BUTTON_PRESS: # select bar
- self.potentialDeselect = False
- start = 0
- check = self.note.cs.onset - Config.TICKS_PER_BEAT
- while start <= check: start += Config.TICKS_PER_BEAT
- stop = start + Config.TICKS_PER_BEAT
- check += 1
- while stop < check: stop += Config.TICKS_PER_BEAT
- emitter.selectNotesByBar( self.note.track, start, stop )
- elif event.type == gtk.gdk._3BUTTON_PRESS: # select track
- self.potentialDeselect = False
- emitter.selectNotesByTrack( self.note.track )
- else:
- if self.getSelected(): # we already selected, might want to delected
- self.potentialDeselect = True
- else:
- emitter.selectNotes( { self.note.track: [ self ] } )
- playSample = True
-
- percent = eX/self.width
- if percent < 0.5: emitter.setCurrentAction( "note-drag-onset", self )
- else:
- emitter.setCurrentAction( "note-drag-pitch-drum", self )
- if playSample: self.playSampleNote()
-
- return 1
-
- def noteDragPitch( self, dp, stream ):
- self.potentialDeselect = False
- if dp != self.lastDragP and not dp%2:
- self.lastDragP = dp
- stream += [ self.note.id, self.basePitch + dp ]
-
- def noteDragDuration( self, dd, stream ):
- return
-
- def noteDecOnset( self, step, leftBound, stream ):
- if self.selected:
- if leftBound < self.note.cs.onset:
- onset = max( self.note.cs.onset+step, leftBound )
- stream += [ self.note.id, onset ]
- return leftBound
-
- def noteIncOnset( self, step, rightBound, stream ):
- if self.selected:
- if rightBound > self.end:
- onset = min( self.end+step, rightBound ) - self.note.cs.duration
- stream += [ self.note.id, onset ]
- return rightBound
-
- def noteDecPitch( self, step, stream ):
- if self.note.cs.pitch > Config.MINIMUM_PITCH_DRUM:
- stream += [ self.note.id, max( self.note.cs.pitch+2*step, Config.MINIMUM_PITCH_DRUM ) ]
-
- def noteIncPitch( self, step, stream ):
- if self.note.cs.pitch < Config.MAXIMUM_PITCH_DRUM:
- stream += [ self.note.id, min( self.note.cs.pitch+2*step, Config.MAXIMUM_PITCH_DRUM ) ]
-
- def noteDecDuration( self, step, stream ):
- return
-
- def noteIncDuration( self, step, rightBound, stream ):
- return
-
- # updateTooltip returns:
- # -1, event occurs before us so don't bother checking any later notes
- # 0, event didn't hit
- # 1, event was handled
- def updateTooltip( self, emitter, event ):
- eX = event.x - self.x
- if eX < 0:
- return -1 # event occurs before us, no point in checking further
- if eX > self.width:
- return 0 # no X overlap
-
- eY = event.y - self.y
- if eY < 0 or eY > self.height:
- return 0 # not a hit
-
- percent = eX/self.width
- if percent < 0.5: emitter.setCursor("drag-onset")
- else: emitter.setCursor("drag-pitch")
-
- return 1 # we handled it
-
- #=======================================================
- # Draw
-
- def draw( self, win, gc, startX, stopX ):
- if stopX < self.imgX: return False # we don't need to draw and no one after us will draw
- if startX > self.imgX + self.imgWidth: return True # we don't need to draw, but maybe a later note does
-
- gc.foreground = self.color
- win.draw_rectangle( gc, True, self.x+2, self.y+2, self.width-4, self.height-4 )
-
- if self.selected: img = self.imageSelected
- else: img = self.image
- win.draw_pixbuf( gc, img, 0, 0, self.imgX, self.imgY, self.imgWidth, self.imgHeight, gtk.gdk.RGB_DITHER_NONE )
-
- return True # we drew something
-
diff --git a/Edit/KeyboardInput.py b/Edit/KeyboardInput.py
deleted file mode 100644
index d1a0d83..0000000
--- a/Edit/KeyboardInput.py
+++ /dev/null
@@ -1,97 +0,0 @@
-import pygtk
-pygtk.require( '2.0' )
-import gtk
-
-from Framework import Note
-from Framework.CSound.CSoundConstants import CSoundConstants
-from Framework.Generation.GenerationConstants import GenerationConstants
-from GUI.Core.KeyMapping import KEY_MAP
-
-
-class KeyboardInput:
- def __init__( self , getCurrentTick , getTrackInstruments , getTrackDictionary , getSelectedTrackIDs , mainWindowUpdateCallback , pagePlayerUpdateCallback , getCurrentPageIDCallback ):
- self.active = False
- self.record = False
- self.monophonic = False
- self.key_dict = dict()
-
- self.getCurrentTick = getCurrentTick
- self.getTrackInstruments = getTrackInstruments
- self.getTrackDictionary = getTrackDictionary
- self.getSelectedTrackIDs = getSelectedTrackIDs
- self.mainWindowUpdateCallback = mainWindowUpdateCallback
- self.pagePlayerUpdateCallback = pagePlayerUpdateCallback
- self.getCurrentPageIDCallback = getCurrentPageIDCallback
-
- def onKeyPress(self,widget,event):
- if not self.active:
- return
- if self.record:
- self.monophonic = False
-
- key = event.hardware_keycode
- # If the key is already in the dictionnary, exit function (to avoir key repeats)
- if self.key_dict.has_key(key):
- return
- # Assign on which track the note will be created according to the number of keys pressed
- track = len(self.key_dict)+10
- if self.monophonic:
- track = 10
- # If the pressed key is in the keymap
- if KEY_MAP.has_key(key):
- # CsoundNote parameters
- onset = self.getCurrentTick()
- pitch = KEY_MAP[key]
- duration = -1
- instrument = self.getTrackInstruments()[0]
- # get instrument from top selected track if a track is selected
- if self.getSelectedTrackIDs():
- instrument = self.getTrackInstruments()[min(self.getSelectedTrackIDs())]
-
- if instrument == 'drum1kit':
- if GenerationConstants.DRUMPITCH.has_key( pitch ):
- instrument = CSoundConstants.DRUM1INSTRUMENTS[ GenerationConstants.DRUMPITCH[ pitch ] ]
- else:
- instrument = CSoundConstants.DRUM1INSTRUMENTS[ pitch ]
- pitch = 36
- duration = 100
-
- if CSoundConstants.INSTRUMENTS[instrument].csoundInstrumentID == 102:
- duration = 100
-
- # Create and play the note
- self.key_dict[key] = Note.note_new(onset = 0,
- pitch = pitch,
- amplitude = 1,
- pan = 0.5,
- duration = duration,
- trackID = track,
- fullDuration = False,
- instrument = instrument,
- instrumentFlag = instrument)
- Note.note_play(self.key_dict[key])
-
- def onKeyRelease(self,widget,event):
- if not self.active:
- return
- key = event.hardware_keycode
-
- if KEY_MAP.has_key(key):
- self.key_dict[key]['duration'] = 0
- self.key_dict[key]['amplitude'] = 0
- self.key_dict[key]['dirty'] = True
- Note.note_play(self.key_dict[key])
- self.key_dict[key]['duration'] = self.getCurrentTick() - self.key_dict[key]['onset']
- #print "onset",self.key_dict[key].onset
- #print "dur",self.key_dict[key].duration
- if self.record and len( self.getSelectedTrackIDs() ) != 0:
- self.key_dict[key]['amplitude'] = 1
- self.getTrackDictionary()[min(self.getSelectedTrackIDs())][self.getCurrentPageIDCallback()].append(self.key_dict[key])
- self.mainWindowUpdateCallback()
- self.pagePlayerUpdateCallback()
- del self.key_dict[key]
-
-
- def onButtonPress(self,widget,event):
- pass
-
diff --git a/Edit/MainWindow.py b/Edit/MainWindow.py
deleted file mode 100644
index 58f82f1..0000000
--- a/Edit/MainWindow.py
+++ /dev/null
@@ -1,2091 +0,0 @@
-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
diff --git a/Edit/NoteInterface.py b/Edit/NoteInterface.py
deleted file mode 100644
index a5035dd..0000000
--- a/Edit/NoteInterface.py
+++ /dev/null
@@ -1,345 +0,0 @@
-import pygtk
-pygtk.require( '2.0' )
-import gtk
-
-import Config
-
-from Util.NoteDB import PARAMETER
-from Util.CSoundClient import new_csound_client
-
-class NoteInterface:
-
- def __init__( self, noteDB, owner, note ):
- self.noteDB = noteDB
- self.owner = owner
- self.note = note
-
- self.origin = self.owner.getTrackOrigin( note.track )
- self.firstTransform = True
- self.x = 0
- self.y = 0
- self.width = 1
- self.height = Config.NOTE_HEIGHT
- self.imgX = 0
- self.imgY = 0
- self.imgWidth = 1
- self.imgHeight = self.height + Config.NOTE_IMAGE_PADDING_MUL2
-
- self.selected = False
- self.potentialDeselect = False
-
- self.oldOnset = -1
- self.oldEnd = -1
- self.oldPitch = -1
- self.oldAmplitude = -1
- self.oldBeats = -1
- self.lastDragO = 0
- self.lastDragP = 0
- self.lastDragD = 0
-
- self.image, self.imageSelected, self.colormap, self.baseColors = self.owner.getDrawingPackage( note.track )
-
- self.updateParameter( None, None )
-
- def destroy( self ):
- if self.selected:
- self.owner.deselectNotes( { self.note.track: [self] } )
- else: # if we were deselected above the rect has already been invalidated
- self.owner.invalidate_rect( self.imgX, self.imgY, self.imgWidth, self.imgHeight, self.note.page, True )
-
- def updateParameter( self, parameter, value ):
- self.end = self.note.cs.onset + self.note.cs.duration
-
- if self.oldAmplitude != self.note.cs.amplitude:
- r = self.baseColors[0][0] + int(self.baseColors[1][0]*self.note.cs.amplitude)
- g = self.baseColors[0][1] + int(self.baseColors[1][1]*self.note.cs.amplitude)
- b = self.baseColors[0][2] + int(self.baseColors[1][2]*self.note.cs.amplitude)
- self.color = self.colormap.alloc_color( r, g, b, True, True ) # TODO potential memory leak?
- self.oldAmplitude = self.note.cs.amplitude
-
- self.updateTransform()
-
- def getId( self ):
- return self.note.id
-
- def getStartTick( self ):
- return self.note.cs.onset
-
- def getEndTick( self ):
- return self.end
-
- def testOnset( self, start, stop ):
- return self.note.cs.onset >= start and self.note.cs.onset < stop
-
- def getPitch( self ):
- return self.note.cs.pitch
-
- def updateTransform( self ):
- if self.note.page in self.owner.getActivePages():
- if not self.firstTransform:
- oldX = self.imgX
- oldY = self.imgY
- oldEndX = self.imgX + self.imgWidth
- dirty = True
- else:
- dirty = False
-
- beats = self.noteDB.getPage( self.note.page ).beats
- if self.note.cs.onset != self.oldOnset or beats != self.oldBeats:
- self.x = self.owner.ticksToPixels( beats, self.note.cs.onset )
- self.x += self.origin[0]
- self.imgX = self.x - Config.NOTE_IMAGE_PADDING
- self.oldOnset = self.note.cs.onset
- if self.end != self.oldEnd or self.note.cs.onset != self.oldOnset or beats != self.oldBeats:
- self.width = self.owner.ticksToPixels( beats, self.end ) - self.x + self.origin[0]
- self.imgWidth = self.width + Config.NOTE_IMAGE_PADDING_MUL2
- self.oldEnd = self.end
- if self.note.cs.pitch != self.oldPitch:
- self.y = self.owner.pitchToPixels( self.note.cs.pitch ) + self.origin[1]
- self.imgY = self.y - Config.NOTE_IMAGE_PADDING
- self.oldPitch = self.note.cs.pitch
- self.oldBeats = beats
-
- if dirty:
- if self.firstTransform:
- self.owner.invalidate_rect( self.imgX, self.imgY, self.imgWidth, self.imgHeight, self.note.page, True )
- else:
- x = min( self.imgX, oldX )
- y = min( self.imgY, oldY )
- endx = max( self.imgX + self.imgWidth, oldEndX )
- endy = max( self.imgY, oldY ) + self.imgHeight
- self.owner.invalidate_rect( x, y, endx-x, endy-y, self.note.page, True )
-
- self.firstTransform = False
-
- def updateDragLimits( self, dragLimits, leftBound, rightBound, widthBound, maxRightBound ):
- left = leftBound - self.note.cs.onset
- right = rightBound - self.note.cs.duration - self.note.cs.onset
- up = Config.MAXIMUM_PITCH - self.note.cs.pitch
- down = Config.MINIMUM_PITCH - self.note.cs.pitch
- short = Config.MINIMUM_NOTE_DURATION - self.note.cs.duration
- long = widthBound - self.note.cs.duration - self.note.cs.onset
-
- if dragLimits[0][0] < left: dragLimits[0][0] = left
- if dragLimits[0][1] > right: dragLimits[0][1] = right
- if dragLimits[1][0] < down: dragLimits[1][0] = down
- if dragLimits[1][1] > up: dragLimits[1][1] = up
- if dragLimits[2][0] < short: dragLimits[2][0] = short
- if dragLimits[2][1] > long: dragLimits[2][1] = long
-
- # store the current loc as a reference point
- self.baseOnset = self.note.cs.onset
- self.basePitch = self.note.cs.pitch
- self.baseDuration = self.note.cs.duration
-
- def playSampleNote( self, full=True ):
- secs_per_tick = 0.025
- csnd = new_csound_client()
-
- if full:
- onset = self.note.cs.onset
- self.note.cs.onset = 0
- csnd.play( self.note.cs, 0.024)
- self.note.cs.onset = onset
- else:
- (onset,duration) = ( self.note.cs.onset, self.note.cs.duration)
- ( self.note.cs.onset, self.note.cs.duration) = (0, 10)
- csnd.play( self.note.cs, 0.024)
- ( self.note.cs.onset, self.note.cs.duration) = (onset,duration)
-
- #=======================================================
- # Events
-
- # handleButtonPress returns:
- # -2, not a hit but there was X overlap
- # -1, event occurs before us so don't bother checking any later notes
- # 0, event didn't hit
- # 1, event was handled
- def handleButtonPress( self, emitter, event ):
- eX = event.x - self.x
- if eX < 0:
- return -1 # event occurs before us, no point in checking further
- if eX > self.width:
- return 0 # no X overlap
-
- eY = event.y - self.y
- if eY < 0 or eY > self.height:
- return -2 # not a hit, but it was in our X range
-
- if event.button == 3:
- print "Show some note parameters!?!"
- #self.noteParameters = NoteParametersWindow( self.note, self.getNoteParameters )
- return 1 # handled
-
- playSample = False
-
- if event.type == gtk.gdk._2BUTTON_PRESS: # select bar
- self.potentialDeselect = False
- start = 0
- check = self.note.cs.onset - Config.TICKS_PER_BEAT
- while start <= check: start += Config.TICKS_PER_BEAT
- stop = start + Config.TICKS_PER_BEAT
- check += self.note.cs.duration
- while stop < check: stop += Config.TICKS_PER_BEAT
- emitter.selectNotesByBar( self.note.track, start, stop )
- elif event.type == gtk.gdk._3BUTTON_PRESS: # select track
- self.potentialDeselect = False
- emitter.selectNotesByTrack( self.note.track )
- else:
- if self.selected: # we already selected, might want to delected
- self.potentialDeselect = True
- else:
- emitter.selectNotes( { self.note.track: [ self ] } )
- playSample = True
-
- percent = eX/self.width
- if percent < 0.3: emitter.setCurrentAction( "note-drag-onset", self )
- elif percent > 0.7: emitter.setCurrentAction( "note-drag-duration", self )
- else:
- emitter.setCurrentAction( "note-drag-pitch", self )
- if playSample: self.playSampleNote()
-
- return 1
-
- def handleButtonRelease( self, emitter, event, buttonPressCount ):
-
- if self.potentialDeselect:
- self.potentialDeselect = False
- emitter.deselectNotes( { self.note.track: [ self ] } )
-
- emitter.doneCurrentAction()
-
- return True
-
- def noteDragOnset( self, do, stream ):
- self.potentialDeselect = False
- if do != self.lastDragO:
- self.lastDragO = do
- stream += [ self.note.id, self.baseOnset + do ]
-
- def noteDragPitch( self, dp, stream ):
- self.potentialDeselect = False
- if dp != self.lastDragP:
- self.lastDragP = dp
- stream += [ self.note.id, self.basePitch + dp ]
-
- def noteDragDuration( self, dd, stream ):
- self.potentialDeselect = False
- if dd != self.lastDragD:
- self.lastDragD = dd
- stream += [ self.note.id, self.baseDuration + dd ]
-
- def doneNoteDrag( self, emitter ):
- self.baseOnset = self.note.cs.onset
- self.basePitch = self.note.cs.pitch
- self.baseDuration = self.note.cs.duration
-
- self.lastDragO = 0
- self.lastDragP = 0
- self.lastDragD = 0
-
- def noteDecOnset( self, step, leftBound, stream ):
- if self.selected:
- if leftBound < self.note.cs.onset:
- onset = max( self.note.cs.onset+step, leftBound )
- stream += [ self.note.id, onset ]
- return onset + self.note.cs.duration
- return self.end
-
- def noteIncOnset( self, step, rightBound, stream ):
- if self.selected:
- if rightBound > self.end:
- onset = min( self.end+step, rightBound ) - self.note.cs.duration
- stream += [ self.note.id, onset ]
- return onset
- return self.note.cs.onset
-
- def noteDecPitch( self, step, stream ):
- if self.note.cs.pitch > Config.MINIMUM_PITCH:
- stream += [ self.note.id, max( self.note.cs.pitch+step, Config.MINIMUM_PITCH ) ]
-
- def noteIncPitch( self, step, stream ):
- if self.note.cs.pitch < Config.MAXIMUM_PITCH:
- stream += [ self.note.id, min( self.note.cs.pitch+step, Config.MAXIMUM_PITCH ) ]
-
- def noteDecDuration( self, step, stream ):
- if self.note.cs.duration > Config.MINIMUM_NOTE_DURATION:
- stream += [ self.note.id, max( self.note.cs.duration+step, Config.MINIMUM_NOTE_DURATION ) ]
-
- def noteIncDuration( self, step, rightBound, stream ):
- if self.selected:
- if self.end < rightBound:
- stream += [ self.note.id, min( self.end+step, rightBound ) - self.note.cs.onset ]
-
- def noteDecVolume( self, step, stream ):
- if self.note.cs.amplitude > 0:
- stream += [ self.note.id, max( self.note.cs.amplitude+step, 0 ) ]
-
- def noteIncVolume( self, step, stream ):
- if self.note.cs.amplitude < 1:
- stream += [ self.note.id, min( self.note.cs.amplitude+step, 1 ) ]
-
- def handleMarqueeSelect( self, emitter, start, stop ):
- intersectionY = [ max(start[1],self.y), min(stop[1],self.y+self.height) ]
- if intersectionY[0] > intersectionY[1]:
- return False
-
- intersectionX = [ max(start[0],self.x), min(stop[0],self.x+self.width) ]
- if intersectionX[0] > intersectionX[1]:
- return False
-
- return True
-
- # updateTooltip returns:
- # -2, not a hit but there was X overlap
- # -1, event occurs before us so don't bother checking any later notes
- # 0, event didn't hit
- # 1, event was handled
- def updateTooltip( self, emitter, event ):
- eX = event.x - self.x
- if eX < 0:
- return -1 # event occurs before us, no point in checking further
- if eX > self.width:
- return 0 # no X overlap
-
- eY = event.y - self.y
- if eY < 0 or eY > self.height:
- return -2 # not a hit, but it was in our X range
-
- percent = eX/self.width
- if percent < 0.3: emitter.setCursor("drag-onset")
- elif percent > 0.7: emitter.setCursor("drag-duration")
- else: emitter.setCursor("drag-pitch")
-
- return 1 # we handled it
-
- #=======================================================
- # Selection
-
- def setSelected( self, state ):
- if self.selected != state:
- self.selected = state
- self.owner.invalidate_rect( self.imgX, self.imgY, self.imgWidth, self.imgHeight, self.note.page )
- return True # state changed
- return False # state is the same
-
- def getSelected( self ):
- return self.selected
-
- #=======================================================
- # Draw
-
- def draw( self, win, gc, startX, stopX ):
- if stopX < self.imgX: return False # we don't need to draw and no one after us will draw
- if startX > self.imgX + self.imgWidth: return True # we don't need to draw, but maybe a later note does
-
- gc.foreground = self.color
- win.draw_rectangle( gc, True, self.x+1, self.y+1, self.width-2, self.height-2 )
-
- if self.selected: img = self.imageSelected
- else: img = self.image
- win.draw_pixbuf( gc, img, 0, 0, self.imgX, self.imgY, self.imgWidth-Config.NOTE_IMAGE_ENDLENGTH, self.imgHeight, gtk.gdk.RGB_DITHER_NONE )
- win.draw_pixbuf( gc, img, Config.NOTE_IMAGE_TAIL, 0, self.imgX+self.imgWidth-Config.NOTE_IMAGE_ENDLENGTH, self.imgY, Config.NOTE_IMAGE_ENDLENGTH, self.imgHeight, gtk.gdk.RGB_DITHER_NONE )
-
- return True # we drew something
-
diff --git a/Edit/Properties.py b/Edit/Properties.py
deleted file mode 100644
index b0caae0..0000000
--- a/Edit/Properties.py
+++ /dev/null
@@ -1,808 +0,0 @@
-import pygtk
-pygtk.require('2.0')
-import gtk
-from types import *
-from math import sqrt
-from random import *
-from Generation.Drunk import *
-from Generation.GenerationConstants import GenerationConstants
-from Util.ThemeWidgets import *
-from Util.NoteDB import PARAMETER
-import Config
-Tooltips = Config.Tooltips()
-
-class Properties( gtk.VBox ):
- def __init__( self, noteDB, doneHandler, popup ):
- gtk.VBox.__init__( self )
- self.tooltips = gtk.Tooltips()
- self.noteDB = noteDB
- #self.doneHandler = doneHandler
- self.popup = popup
- self.popup.resize( 545, 378 )
-
- self.context = "page"
- self.notes = {} # notes indexed by page and track
- self.setup = False # flag to block note updates durning setup
-
- self.line = Line(0, 100)
- self.drunk = Drunk(0, 100)
- self.droneAndJump = DroneAndJump(0, 100)
- self.repeter = Repeter(0, 100)
- self.loopseg = Loopseg(0, 100)
- self.algoTypes = [self.line, self.drunk, self.droneAndJump, self.repeter, self.loopseg]
- self.algorithm = self.algoTypes[0]
-
- #self.set_size_request( 300, 200 )
-
- self.filterType = 0
- self.minValue = 0.
- self.maxValue = 100.
- self.paraValue = 20.
-
- self.activeWidget = None
-
- self.pageIds = []
-
- self.GUI = {}
- self.parametersBox = RoundHBox(fillcolor=Config.INST_BCK_COLOR, bordercolor=Config.PANEL_BCK_COLOR)
- #self.parametersBox.set_border_width(1)
- self.parametersBox.set_radius(10)
- self.pack_start(self.parametersBox)
- self.fixed = gtk.Fixed()
- self.parametersBox.pack_start( self.fixed )
-
- self.controlsBox = gtk.HBox()
-
- #-- Page Properties ------------------------------------------------
- self.pageBox = RoundHBox(fillcolor=Config.PANEL_COLOR, bordercolor=Config.INST_BCK_COLOR)
- self.pageBox.set_size_request( 125, -1 )
- self.pageBox.set_border_width(3)
- self.pageBox.set_radius(10)
- beatBox = gtk.VBox()
- self.beatAdjust = gtk.Adjustment( 4, 2, 12, 1, 1, 0)
- self.GUI['beatSlider'] = ImageVScale( Config.TAM_TAM_ROOT + "/Resources/Images/sliderEditVolume.png", self.beatAdjust, 7 )
- self.GUI['beatSlider'].connect("button-release-event", self.handleBeat)
- self.GUI['beatSlider'].set_snap( 1 )
- self.GUI['beatSlider'].set_inverted(True)
- self.GUI['beatSlider'].set_size_request(50, 200)
- beatBox.pack_start( self.GUI['beatSlider'] )
- self.beatLabel = gtk.Image()
- self.beatLabel.set_from_file(Config.IMAGE_ROOT + 'volume3.png')
- self.beatAdjust.connect("value-changed", self.updateBeatLabel)
- self.updateBeatLabel( self.beatAdjust )
- beatBox.pack_start( self.beatLabel )
- self.pageBox.pack_start( beatBox )
- colorBox = gtk.VBox()
- self.GUI["color0Button"] = ImageRadioButton( None, Config.IMAGE_ROOT+"pageThumbnailBut0.png", Config.IMAGE_ROOT+"pageThumbnailBut0Down.png", backgroundFill = Config.PANEL_COLOR )
- self.GUI["color0Button"].set_size_request( 80, -1 )
- self.GUI["color0Button"].connect( "clicked", self.handleColor, 0 )
- colorBox.pack_start( self.GUI["color0Button"] )
- self.GUI["color1Button"] = ImageRadioButton( self.GUI["color0Button"], Config.IMAGE_ROOT+"pageThumbnailBut1.png", Config.IMAGE_ROOT+"pageThumbnailBut1Down.png", backgroundFill = Config.PANEL_COLOR )
- self.GUI["color1Button"].connect( "clicked", self.handleColor, 1 )
- colorBox.pack_start( self.GUI["color1Button"] )
- self.GUI["color2Button"] = ImageRadioButton( self.GUI["color0Button"], Config.IMAGE_ROOT+"pageThumbnailBut2.png", Config.IMAGE_ROOT+"pageThumbnailBut2Down.png", backgroundFill = Config.PANEL_COLOR )
- self.GUI["color2Button"].connect( "clicked", self.handleColor, 2 )
- colorBox.pack_start( self.GUI["color2Button"] )
- self.GUI["color3Button"] = ImageRadioButton( self.GUI["color0Button"], Config.IMAGE_ROOT+"pageThumbnailBut3.png", Config.IMAGE_ROOT+"pageThumbnailBut3Down.png", backgroundFill = Config.PANEL_COLOR )
- self.GUI["color3Button"].connect( "clicked", self.handleColor, 3 )
- colorBox.pack_start( self.GUI["color3Button"] )
- self.pageBox.pack_start( colorBox )
- self.pageBox.show_all()
- #self.controlsBox.pack_start(self.pageBox)
-
- #-- Note Properties ------------------------------------------------
- pitchBox = RoundVBox(fillcolor=Config.PANEL_COLOR, bordercolor=Config.INST_BCK_COLOR)
- pitchBox.set_border_width(3)
- pitchBox.set_radius(10)
- self.GUI['pitchUp'] = ImageButton( Config.IMAGE_ROOT+"arrowEditUp.png", Config.IMAGE_ROOT+"arrowEditUpDown.png", Config.IMAGE_ROOT+"arrowEditUpOver.png", backgroundFill = Config.PANEL_COLOR )
- self.GUI['pitchUp'].connect( "clicked", lambda w:self.stepPitch( 1 ) )
- self.GUI['pitchGen'] = ImageToggleButton( Config.IMAGE_ROOT+"diceProp.png", Config.IMAGE_ROOT+"dicePropSel.png", Config.IMAGE_ROOT+"dicePropSel.png", backgroundFill = Config.PANEL_COLOR )
- self.GUI['pitchGen'].connect( "clicked", self.openAlgoBox, 'pitch' )
- pitchBox.pack_start( self.GUI['pitchGen'], False, False, 5 )
- pitchBox.pack_start( self.GUI['pitchUp'] )
- self.pitchIcon = gtk.Image()
- self.pitchIcon.set_from_file(Config.IMAGE_ROOT + 'propPitch2.png')
- pitchBox.pack_start(self.pitchIcon)
- self.GUI['pitchDown'] = ImageButton( Config.IMAGE_ROOT+"arrowEditDown.png", Config.IMAGE_ROOT+"arrowEditDownDown.png", Config.IMAGE_ROOT+"arrowEditDownOver.png", backgroundFill = Config.PANEL_COLOR )
- self.GUI['pitchDown'].connect( "clicked", lambda w:self.stepPitch( -1 ) )
- pitchBox.pack_start( self.GUI['pitchDown'] )
- self.controlsBox.pack_start(pitchBox)
-
- volumeBox = RoundVBox(fillcolor=Config.PANEL_COLOR, bordercolor=Config.INST_BCK_COLOR)
- volumeBox.set_border_width(3)
- volumeBox.set_radius(10)
- self.GUI['volumeUp'] = ImageButton( Config.IMAGE_ROOT+"arrowEditUp.png", Config.IMAGE_ROOT+"arrowEditUpDown.png", Config.IMAGE_ROOT+"arrowEditUpOver.png", backgroundFill = Config.PANEL_COLOR )
- self.GUI['volumeUp'].connect( "clicked", lambda w:self.stepVolume( 0.1 ) )
- self.GUI['volumeGen'] = ImageToggleButton( Config.IMAGE_ROOT+"diceProp.png", Config.IMAGE_ROOT+"dicePropSel.png", Config.IMAGE_ROOT+"dicePropSel.png", backgroundFill = Config.PANEL_COLOR )
- self.GUI['volumeGen'].connect( "clicked", self.openAlgoBox, 'volume' )
- volumeBox.pack_start( self.GUI['volumeGen'], False, False, 5 )
- volumeBox.pack_start( self.GUI['volumeUp'] )
- self.volumeIcon = gtk.Image()
- self.volumeIcon.set_from_file(Config.IMAGE_ROOT + 'volume3.png')
- volumeBox.pack_start(self.volumeIcon)
- self.GUI['volumeDown'] = ImageButton( Config.IMAGE_ROOT+"arrowEditDown.png", Config.IMAGE_ROOT+"arrowEditDownDown.png", Config.IMAGE_ROOT+"arrowEditDownOver.png", backgroundFill = Config.PANEL_COLOR )
- self.GUI['volumeDown'].connect( "clicked", lambda w:self.stepVolume( -0.1 ) )
- volumeBox.pack_start( self.GUI['volumeDown'] )
- self.controlsBox.pack_start(volumeBox)
-
- panBox = RoundVBox(fillcolor=Config.PANEL_COLOR, bordercolor=Config.INST_BCK_COLOR)
- panBox.set_border_width(3)
- panBox.set_radius(10)
- self.panAdjust = gtk.Adjustment( 0.5, 0, 1, .1, .1, 0)
- self.GUI['panSlider'] = ImageVScale( Config.TAM_TAM_ROOT + "/Resources/Images/sliderEditVolume.png", self.panAdjust, 7 )
- self.panAdjust.connect("value-changed", self.handlePan)
- self.GUI['panSlider'].set_snap( 0.1 )
- self.GUI['panSlider'].set_inverted(True)
- self.GUI['panSlider'].set_size_request(50, 200)
- self.panLabel = gtk.Image()
- self.handlePan( self.panAdjust )
- self.GUI['panGen'] = ImageToggleButton( Config.IMAGE_ROOT+"diceProp.png", Config.IMAGE_ROOT+"dicePropSel.png", Config.IMAGE_ROOT+"dicePropSel.png", backgroundFill = Config.PANEL_COLOR )
- self.GUI['panGen'].connect( "clicked", self.openAlgoBox, 'pan' )
- panBox.pack_start(self.GUI['panGen'], True, True, 5)
- panBox.pack_start(self.GUI['panSlider'], True, True, 5)
- panBox.pack_start(self.panLabel, False, padding=10)
- self.controlsBox.pack_start(panBox)
-
- reverbBox = RoundVBox(fillcolor=Config.PANEL_COLOR, bordercolor=Config.INST_BCK_COLOR)
- reverbBox.set_border_width(3)
- reverbBox.set_radius(10)
- self.reverbAdjust = gtk.Adjustment(0.1, 0, 1, 0.1, 0.1, 0)
- self.GUI['reverbSlider'] = ImageVScale( Config.TAM_TAM_ROOT + "/Resources/Images/sliderEditVolume.png", self.reverbAdjust, 7 )
- self.reverbAdjust.connect("value-changed", self.handleReverb)
- self.GUI['reverbSlider'].set_snap( 0.1 )
- self.GUI['reverbSlider'].set_inverted(True)
- self.GUI['reverbSlider'].set_size_request(50, 200)
- self.reverbLabel = gtk.Image()
- self.handleReverb( self.reverbAdjust )
- self.GUI['reverbGen'] = ImageToggleButton( Config.IMAGE_ROOT+"diceProp.png", Config.IMAGE_ROOT+"dicePropSel.png", Config.IMAGE_ROOT+"dicePropSel.png", backgroundFill = Config.PANEL_COLOR )
- self.GUI['reverbGen'].connect( "clicked", self.openAlgoBox, 'reverb' )
- reverbBox.pack_start(self.GUI['reverbGen'], True, True, 5)
- reverbBox.pack_start(self.GUI['reverbSlider'], True, True, 5)
- reverbBox.pack_start(self.reverbLabel, False, padding=10)
- self.controlsBox.pack_start(reverbBox)
-
- attackBox = RoundVBox(fillcolor=Config.PANEL_COLOR, bordercolor=Config.INST_BCK_COLOR)
- attackBox.set_border_width(3)
- attackBox.set_radius(10)
- self.attackAdjust = gtk.Adjustment(0.04, 0.03, 1, .01, .01, 0)
- self.GUI['attackSlider'] = ImageVScale( Config.TAM_TAM_ROOT + "/Resources/Images/sliderEditVolume.png", self.attackAdjust, 7 )
- self.attackAdjust.connect("value-changed", self.handleAttack)
- self.GUI['attackSlider'].set_snap( 0.01 )
- self.GUI['attackSlider'].set_inverted(True)
- self.GUI['attackSlider'].set_size_request(50, 200)
- self.attackLabel = gtk.Image()
- self.handleAttack( self.attackAdjust )
- self.GUI['attackGen'] = ImageToggleButton( Config.IMAGE_ROOT+"diceProp.png", Config.IMAGE_ROOT+"dicePropSel.png", Config.IMAGE_ROOT+"dicePropSel.png", backgroundFill = Config.PANEL_COLOR )
- self.GUI['attackGen'].connect( "clicked", self.openAlgoBox, 'attack' )
- attackBox.pack_start(self.GUI['attackGen'], True, True, 5)
- attackBox.pack_start(self.GUI['attackSlider'], True, True, 5)
- attackBox.pack_start(self.attackLabel, False, padding=10)
- self.controlsBox.pack_start(attackBox)
-
- decayBox = RoundVBox(fillcolor=Config.PANEL_COLOR, bordercolor=Config.INST_BCK_COLOR)
- decayBox.set_border_width(3)
- decayBox.set_radius(10)
- self.decayAdjust = gtk.Adjustment(0.31, 0.03, 1, .01, .01, 0)
- self.GUI['decaySlider'] = ImageVScale( Config.TAM_TAM_ROOT + "/Resources/Images/sliderEditVolume.png", self.decayAdjust, 7 )
- self.decayAdjust.connect("value-changed", self.handleDecay)
- self.GUI['decaySlider'].set_snap( 0.01 )
- self.GUI['decaySlider'].set_inverted(True)
- self.GUI['decaySlider'].set_size_request(50, 200)
- self.decayLabel = gtk.Image()
- self.handleDecay( self.decayAdjust )
- self.GUI['decayGen'] = ImageToggleButton( Config.IMAGE_ROOT+"diceProp.png", Config.IMAGE_ROOT+"dicePropSel.png", Config.IMAGE_ROOT+"dicePropSel.png", backgroundFill = Config.PANEL_COLOR )
- self.GUI['decayGen'].connect( "clicked", self.openAlgoBox, 'decay' )
- decayBox.pack_start(self.GUI['decayGen'], True, True, 5)
- decayBox.pack_start(self.GUI['decaySlider'], True, True, 5)
- decayBox.pack_start(self.decayLabel, False, padding=10)
- self.controlsBox.pack_start(decayBox)
-
- filterBox = RoundHBox(fillcolor=Config.PANEL_COLOR, bordercolor=Config.INST_BCK_COLOR)
- filterBox.set_border_width(3)
- filterBox.set_radius(10)
-
- filterTypeBox = gtk.VBox()
- self.GUI['filterTypeLowButton'] = ImageToggleButton(Config.IMAGE_ROOT + 'propLow3.png', Config.IMAGE_ROOT + 'propLow3Sel.png', Config.IMAGE_ROOT + 'propLow3Over.png')
- self.GUI['filterTypeLowButton'].connect( "toggled", self.handleFilterType, 1 )
- filterTypeBox.pack_start( self.GUI['filterTypeLowButton'] )
- self.GUI['filterTypeHighButton'] = ImageToggleButton(Config.IMAGE_ROOT + 'propHi3.png', Config.IMAGE_ROOT + 'propHi3Sel.png', Config.IMAGE_ROOT + 'propHi3Over.png')
- self.GUI['filterTypeHighButton'].connect( "toggled", self.handleFilterType, 2 )
- filterTypeBox.pack_start( self.GUI['filterTypeHighButton'] )
- self.GUI['filterTypeBandButton'] = gtk.ToggleButton( "B" )
- self.GUI['filterTypeBandButton'] = ImageToggleButton(Config.IMAGE_ROOT + 'propBand3.png', Config.IMAGE_ROOT + 'propBand3Sel.png', Config.IMAGE_ROOT + 'propBand3Over.png')
- self.GUI['filterTypeBandButton'].connect( "toggled", self.handleFilterType, 3 )
- filterTypeBox.pack_start( self.GUI['filterTypeBandButton'] )
- filterBox.pack_start( filterTypeBox )
-
- self.filterSliderBox = gtk.VBox()
- self.filterSliderBox.set_size_request(50, -1)
- self.cutoffAdjust = gtk.Adjustment(1000, 100, 7000, 100, 100, 0)
- self.GUI['cutoffSlider'] = ImageVScale( Config.TAM_TAM_ROOT + "/Resources/Images/sliderEditVolume.png", self.cutoffAdjust, 7 )
- self.GUI['cutoffSlider'].set_snap(100)
- self.cutoffAdjust.connect("value-changed", self.handleFilter)
- self.GUI['cutoffSlider'].set_inverted(True)
- self.GUI['cutoffSlider'].set_size_request(50, 200)
- self.GUI['cutoffGen'] = ImageToggleButton( Config.IMAGE_ROOT+"diceProp.png", Config.IMAGE_ROOT+"dicePropSel.png", Config.IMAGE_ROOT+"dicePropSel.png", backgroundFill = Config.PANEL_COLOR )
- self.GUI['cutoffGen'].connect( "clicked", self.openAlgoBox, 'cutoff' )
- self.filterSliderBox.pack_start(self.GUI['cutoffGen'], True, True, 5)
- self.filterSliderBox.pack_start(self.GUI['cutoffSlider'], True, True, 5)
- self.filterLabel = gtk.Image()
- self.filterLabel.set_from_file(Config.IMAGE_ROOT + 'propFilter1.png')
- self.filterSliderBox.pack_start(self.filterLabel, False, padding=10)
-
- filterBox.pack_start(self.filterSliderBox)
-
- self.controlsBox.pack_start(filterBox)
-
- self.algoBox = RoundVBox(fillcolor=Config.PANEL_COLOR, bordercolor=Config.INST_BCK_COLOR)
- self.algoBox.set_size_request( -1, 378 )
- self.algoBox.set_border_width(3)
- self.algoBox.set_radius(10)
- #self.algoBox = gtk.VBox()
-
- algoUpperBox = gtk.HBox()
-
- algoRadioButtonBox = gtk.VBox()
- algoRadioButtonBox.set_size_request(100, 150)
- #algoRadioButtonBox = RoundHBox(fillcolor=Config.PANEL_COLOR, bordercolor=Config.INST_BCK_COLOR)
- #algoRadioButtonBox.set_border_width(3)
- #algoRadioButtonBox.set_radius(10)
-
- self.GUI['line'] = ImageRadioButton( None, Config.IMAGE_ROOT + 'propLine.png', Config.IMAGE_ROOT + 'propLineDown.png', Config.IMAGE_ROOT + 'propLineOver.png' )
- self.GUI['line'].connect( "toggled", self.handleAlgo, 0 )
- algoRadioButtonBox.pack_start( self.GUI['line'], False, False, 1 )
- self.GUI['drunk'] = ImageRadioButton( self.GUI['line'], Config.IMAGE_ROOT + 'propDrunk.png', Config.IMAGE_ROOT + 'propDrunkDown.png', Config.IMAGE_ROOT + 'propDrunkOver.png' )
- self.GUI['drunk'].connect( "toggled", self.handleAlgo, 1 )
- algoRadioButtonBox.pack_start( self.GUI['drunk'], False, False, 1 )
- self.GUI['droneJump'] = ImageRadioButton( self.GUI['line'], Config.IMAGE_ROOT + 'propDroneJump.png', Config.IMAGE_ROOT + 'propDroneJumpDown.png', Config.IMAGE_ROOT + 'propDroneJumpOver.png' )
- self.GUI['droneJump'].connect( "toggled", self.handleAlgo, 2 )
- algoRadioButtonBox.pack_start( self.GUI['droneJump'], False, False, 1 )
- self.GUI['repeater'] = ImageRadioButton( self.GUI['line'], Config.IMAGE_ROOT + 'propRepeater.png', Config.IMAGE_ROOT + 'propRepeaterDown.png', Config.IMAGE_ROOT + 'propRepeaterOver.png' )
- self.GUI['repeater'].connect( "toggled", self.handleAlgo, 3 )
- algoRadioButtonBox.pack_start( self.GUI['repeater'], False, False, 1 )
- self.GUI['loopseg'] = ImageRadioButton( self.GUI['line'], Config.IMAGE_ROOT + 'propLoopseg.png', Config.IMAGE_ROOT + 'propLoopsegDown.png', Config.IMAGE_ROOT + 'propLoopsegOver.png' )
- self.GUI['loopseg'].connect( "toggled", self.handleAlgo, 4 )
- algoRadioButtonBox.pack_start( self.GUI['loopseg'], False, False, 1 )
-
- algoUpperBox.pack_start(algoRadioButtonBox)
-
- algoSlidersBox = gtk.HBox()
- algoSlidersBox.set_size_request(150, 320)
- #algoSlidersBox = RoundHBox(fillcolor=Config.PANEL_COLOR, bordercolor=Config.INST_BCK_COLOR)
- #algoSlidersBox.set_border_width(3)
- #algoSlidersBox.set_radius(10)
- minBox = gtk.VBox()
- self.minAdjust = gtk.Adjustment(0, 0, 100, 1, 1, 0)
- self.GUI['minSlider'] = ImageVScale( Config.TAM_TAM_ROOT + "/Resources/Images/sliderEditVolume.png", self.minAdjust, 7 )
- self.GUI['minSlider'].set_snap(1)
- self.minAdjust.connect("value-changed", self.handleMin)
- self.GUI['minSlider'].set_inverted(True)
- self.GUI['minSlider'].set_size_request(50, 200)
- minBox.pack_start(self.GUI['minSlider'], True, True, 5)
- algoSlidersBox.pack_start(minBox)
-
- maxBox = gtk.VBox()
- self.maxAdjust = gtk.Adjustment(100, 0, 100, 1, 1, 0)
- self.GUI['maxSlider'] = ImageVScale( Config.TAM_TAM_ROOT + "/Resources/Images/sliderEditVolume.png", self.maxAdjust, 7 )
- self.GUI['maxSlider'].set_snap(1)
- self.maxAdjust.connect("value-changed", self.handleMax)
- self.GUI['maxSlider'].set_inverted(True)
- self.GUI['maxSlider'].set_size_request(50, 200)
- maxBox.pack_start(self.GUI['maxSlider'], True, True, 5)
- algoSlidersBox.pack_start(maxBox)
-
- paraBox = gtk.VBox()
- self.paraAdjust = gtk.Adjustment(20, 0, 100, 1, 1, 0)
- self.GUI['paraSlider'] = ImageVScale( Config.TAM_TAM_ROOT + "/Resources/Images/sliderEditVolume.png", self.paraAdjust, 7 )
- self.GUI['paraSlider'].set_snap(1)
- self.paraAdjust.connect("value-changed", self.handlePara)
- self.GUI['paraSlider'].set_inverted(True)
- self.GUI['paraSlider'].set_size_request(50, 200)
- paraBox.pack_start(self.GUI['paraSlider'], True, True, 5)
- algoSlidersBox.pack_start(paraBox)
-
- algoUpperBox.pack_start(algoSlidersBox)
-
- self.algoBox.pack_start(algoUpperBox)
-
- #transButtonBox = RoundHBox(fillcolor=Config.PANEL_COLOR, bordercolor=Config.INST_BCK_COLOR)
- #transButtonBox.set_border_width(3)
- #transButtonBox.set_radius(10)
- transButtonBox = gtk.HBox()
- transButtonBox.set_size_request(150, 50)
-
- # create cancel/check button
- self.GUI["checkButton"] = ImageButton(Config.IMAGE_ROOT + 'check.png', backgroundFill=Config.PANEL_COLOR )
- self.GUI["checkButton"].connect("clicked", self.apply)
-
- self.GUI["cancelButton"] = ImageButton(Config.IMAGE_ROOT + 'closeA.png', backgroundFill=Config.PANEL_COLOR )
- self.GUI["cancelButton"].connect("clicked", self.cancel)
-
- transButtonBox.pack_end(self.GUI["checkButton"], False, False, 10)
- transButtonBox.pack_end(self.GUI["cancelButton"], False, False)
- self.algoBox.pack_start(transButtonBox)
-
- self.fixed.put( self.controlsBox, 0, 0 )
- self.algoBox.show_all()
-
- # set tooltips
- for key in self.GUI:
- if Tooltips.PROP.has_key(key):
- self.tooltips.set_tip(self.GUI[key],Tooltips.PROP[key])
- self.tooltips.set_tip(self.GUI['paraSlider'], 'Random')
-
-
- self.show_all()
-
- def openAlgoBox( self, widget, data=None ):
- if widget.get_active() == True:
- self.property = data
- if self.activeWidget:
- self.activeWidget.set_active(False)
- self.activeWidget = widget
- if self.context == "page":
- if self.algoBox.parent == None: self.fixed.put( self.algoBox, 671, 0 )
- else: self.fixed.move( self.algoBox, 671, 0 )
- self.popup.resize( 927, 378 )
- else:
- self.popup.resize( 801, 378 )
- if self.algoBox.parent == None: self.fixed.put( self.algoBox, 545, 0 )
- else: self.fixed.move( self.algoBox, 545, 0 )
- else:
- self.property = None
- self.activeWidget = None
- if self.algoBox.parent != None:
- if self.context == "page": self.popup.resize( 671, 378 )
- else: self.popup.resize( 545, 378 )
- self.fixed.remove( self.algoBox )
-
- def setContext( self, context, scale, pageIds = None, trackIds = None, notes = {} ):
- self.context = context
- self.scale = GenerationConstants.SCALES[scale]
- self.notes = {}
- self.pageIds = pageIds
- self.trackIds = trackIds
-
- try:
- self.activeWidget.set_active(False)
- self.activeWidget = None
- except:
- self.activeWidget = None
-
- if context == "page":
- if self.pageBox.parent == None:
- self.controlsBox.pack_start( self.pageBox )
- self.controlsBox.reorder_child( self.pageBox, 0 )
- self.controlsBox.set_size_request( 671, 378 )
- self.popup.resize( 671, 378 )
- self.trackIds = [0,1,2,3,4]
- for p in pageIds:
- self.notes[p] = {}
- for t in range(Config.NUMBER_OF_TRACKS):
- self.notes[p][t] = self.noteDB.getNotesByTrack( p, t )
- page = self.noteDB.getPage(pageIds[0])
- self.beatAdjust.set_value(page.beats)
- btn = "color%dButton" % page.color
- self.GUI[btn].set_active(True)
- elif context == "track":
- if self.pageBox.parent != None:
- self.controlsBox.remove( self.pageBox )
- self.controlsBox.set_size_request( 545, 378 )
- self.popup.resize( 545, 378 )
- for p in pageIds:
- self.notes[p] = {}
- for t in trackIds:
- self.notes[p][t] = self.noteDB.getNotesByTrack( p, t )
- else:
- if self.pageBox.parent != None:
- self.controlsBox.remove( self.pageBox )
- self.controlsBox.set_size_request( 545, 378 )
- self.popup.resize( 545, 378 )
- self.notes = notes
- self.pageIds = self.notes.keys()
- self.trackIds = self.notes[self.pageIds[0]].keys()
-
- for p in self.notes:
- for t in self.notes[p]:
- if len(self.notes[p][t]):
- # initialize values from first note
- self.setup = True
- n = self.notes[p][t][0]
- self.panAdjust.set_value( n.cs.pan )
- self.reverbAdjust.set_value( n.cs.reverbSend )
- self.attackAdjust.set_value( n.cs.attack )
- self.decayAdjust.set_value( n.cs.decay )
- if n.cs.filterType == 0:
- self.GUI['filterTypeLowButton'].set_active(False)
- self.GUI['filterTypeHighButton'].set_active(False)
- self.GUI['filterTypeBandButton'].set_active(False)
- self.filterLabel.hide()
- self.GUI['cutoffSlider'].hide()
- self.GUI['cutoffGen'].hide()
- else:
- if n.cs.filterType == 1:
- self.GUI['filterTypeLowButton'].set_active(True)
- if n.cs.filterType == 2:
- self.GUI['filterTypeHighButton'].set_active(True)
- if n.cs.filterType == 3:
- self.GUI['filterTypeBandButton'].set_active(True)
- self.filterLabel.show()
- self.GUI['cutoffSlider'].show()
- self.GUI['cutoffGen'].show()
- self.filterType = n.cs.filterType
- self.cutoffAdjust.set_value( n.cs.filterCutoff )
- self.setup = False
- return
-
- def handleColor( self, widget, index ):
- stream = []
- for page in self.pageIds:
- stream += [ page, index ]
- if len(stream):
- self.noteDB.updatePages( [ PARAMETER.PAGE_COLOR, len(stream)//2 ] + stream )
-
- def updateBeatLabel( self, adjust ):
- beats = int(adjust.value)
- self.beatLabel.set_from_file(Config.IMAGE_ROOT + 'propBeats' + str(beats) + '.png')
-
- def handleBeat( self, widget, signal_id ):
- beats = int(widget.get_adjustment().value)
- stream = []
- for page in self.pageIds:
- stream += [ page, beats ]
- if len(stream):
- self.noteDB.updatePages( [ PARAMETER.PAGE_BEATS, len(stream)//2 ] + stream )
-
-
- def stepPitch( self, step ):
- stream = []
- for p in self.notes:
- for t in self.notes[p]:
- substream = []
- if step > 0:
- if t != Config.NUMBER_OF_TRACKS-1: # regular note
- for n in self.notes[p][t]:
- if n.cs.pitch != Config.MAXIMUM_PITCH:
- substream += [ n.id, min( Config.MAXIMUM_PITCH, n.cs.pitch + step ) ]
- else: # drum note
- for n in self.notes[p][t]:
- if n.cs.pitch != Config.MAXIMUM_PITCH_DRUM:
- substream += [ n.id, min( Config.MAXIMUM_PITCH_DRUM, n.cs.pitch + step*Config.PITCH_STEP_DRUM ) ]
- else:
- if t != Config.NUMBER_OF_TRACKS-1: # regular note
- for n in self.notes[p][t]:
- if n.cs.pitch != Config.MINIMUM_PITCH:
- substream += [ n.id, max( Config.MINIMUM_PITCH, n.cs.pitch + step ) ]
- else: # drum note
- for n in self.notes[p][t]:
- if n.cs.pitch != Config.MINIMUM_PITCH_DRUM:
- substream += [ n.id, max( Config.MINIMUM_PITCH_DRUM, n.cs.pitch + step*Config.PITCH_STEP_DRUM ) ]
- if len(substream):
- stream += [ p, t, PARAMETER.PITCH, len(substream)//2 ] + substream
- if len(stream):
- self.noteDB.updateNotes( stream + [-1] )
-
- def algoPitch( self, list, algorithm ):
- maxValue = max(list[0], list[1])
- scaleLength = len(self.scale)-1
- stream = []
- for t in range(len(self.trackIds)):
- trackLength = 0
- for p in range(len(self.pageIds)):
- trackLength += len(self.notes[self.pageIds[p]][self.trackIds[t]])
- algorithm.__init__(list[0], list[1], trackLength)
- for p in range(len(self.pageIds)):
- substream = []
- if self.trackIds[t] != Config.NUMBER_OF_TRACKS-1:
- for n in self.notes[self.pageIds[p]][self.trackIds[t]]:
- val = algorithm.getNextValue(list[2], maxValue)
- substream += [ n.id, self.scale[int(val*0.01*scaleLength)]+36 ]
- if len(substream):
- stream += [ self.pageIds[p], self.trackIds[t], PARAMETER.PITCH, len(substream)//2 ] + substream
- else:
- for n in self.notes[self.pageIds[p]][self.trackIds[t]]:
- val = algorithm.getNextValue(list[2], maxValue)
- val = int((val*0.12)*2+24)
- if val in GenerationConstants.DRUMPITCH.keys():
- val = GenerationConstants.DRUMPITCH[val]
- substream += [ n.id, val ]
- if len(substream):
- stream += [ self.pageIds[p], self.trackIds[t], PARAMETER.PITCH, len(substream)//2 ] + substream
- if len(stream):
- self.noteDB.updateNotes( stream + [-1] )
-
- def stepVolume( self, step ):
- stream = []
- for p in self.notes:
- for t in self.notes[p]:
- substream = []
- if step > 0:
- for n in self.notes[p][t]:
- if n.cs.amplitude != Config.MAXIMUM_AMPLITUDE:
- substream += [ n.id, min( Config.MAXIMUM_AMPLITUDE, n.cs.amplitude + step ) ]
- else:
- for n in self.notes[p][t]:
- if n.cs.amplitude != Config.MINIMUM_AMPLITUDE:
- substream += [ n.id, max( Config.MINIMUM_AMPLITUDE, n.cs.amplitude + step ) ]
- if len(substream):
- stream += [ p, t, PARAMETER.AMPLITUDE, len(substream)//2 ] + substream
- if len(stream):
- self.noteDB.updateNotes( stream + [-1] )
-
- def algoVolume( self, list, algorithm ):
- maxValue = max(list[0], list[1])
- stream = []
- for t in range(len(self.trackIds)):
- trackLength = 0
- for p in range(len(self.pageIds)):
- trackLength += len(self.notes[self.pageIds[p]][self.trackIds[t]])
- algorithm.__init__(list[0], list[1], trackLength)
- for p in range(len(self.pageIds)):
- substream = []
- for n in self.notes[self.pageIds[p]][self.trackIds[t]]:
- val = algorithm.getNextValue(list[2], maxValue)
- substream += [ n.id, min( Config.MAXIMUM_AMPLITUDE, val*0.01 ) ]
- if len(substream):
- stream += [ self.pageIds[p], self.trackIds[t], PARAMETER.AMPLITUDE, len(substream)//2 ] + substream
- if len(stream):
- self.noteDB.updateNotes( stream + [-1] )
-
- def handlePan( self, adjust ):
- img = min( 4, int(adjust.value * 5) )
- self.panLabel.set_from_file(Config.IMAGE_ROOT + 'propPan' + str(img) + '.png')
- if not self.setup:
- stream = []
- for p in self.notes:
- for t in self.notes[p]:
- if len(self.notes[p][t]):
- stream += [ p, t, PARAMETER.PAN, len(self.notes[p][t]) ]
- for n in self.notes[p][t]:
- stream += [ n.id, adjust.value ]
- if len(stream):
- self.noteDB.updateNotes( stream + [-1] )
-
- def algoPan( self, list, algorithm ):
- maxValue = max(list[0], list[1])
- stream = []
- for t in range(len(self.trackIds)):
- trackLength = 0
- for p in range(len(self.pageIds)):
- trackLength += len(self.notes[self.pageIds[p]][self.trackIds[t]])
- algorithm.__init__(list[0], list[1], trackLength)
- for p in range(len(self.pageIds)):
- substream = []
- for n in self.notes[self.pageIds[p]][self.trackIds[t]]:
- val = algorithm.getNextValue(list[2], maxValue)
- substream += [ n.id, val*0.01 ]
- if len(substream):
- stream += [ self.pageIds[p], self.trackIds[t], PARAMETER.PAN, len(substream)//2 ] + substream
- if len(stream):
- self.noteDB.updateNotes( stream + [-1] )
-
- def handleReverb( self, adjust ):
- img = min( 5, int(adjust.value * 6) )
- self.reverbLabel.set_from_file(Config.IMAGE_ROOT + 'propReverb' + str(img) + '.png')
- if not self.setup:
- stream = []
- for p in self.notes:
- for t in self.notes[p]:
- if len(self.notes[p][t]):
- stream += [ p, t, PARAMETER.REVERB, len(self.notes[p][t]) ]
- for n in self.notes[p][t]:
- stream += [ n.id, adjust.value ]
- if len(stream):
- self.noteDB.updateNotes( stream + [-1] )
-
- def algoReverb( self, list, algorithm ):
- maxValue = max(list[0], list[1])
- stream = []
- for t in range(len(self.trackIds)):
- trackLength = 0
- for p in range(len(self.pageIds)):
- trackLength += len(self.notes[self.pageIds[p]][self.trackIds[t]])
- algorithm.__init__(list[0], list[1], trackLength)
- for p in range(len(self.pageIds)):
- substream = []
- for n in self.notes[self.pageIds[p]][self.trackIds[t]]:
- val = algorithm.getNextValue(list[2], maxValue)
- substream += [ n.id, val*0.02 ]
- if len(substream):
- stream += [ self.pageIds[p], self.trackIds[t], PARAMETER.REVERB, len(substream)//2 ] + substream
- if len(stream):
- self.noteDB.updateNotes( stream + [-1] )
-
- def handleAttack( self, adjust ):
- val = adjust.value #*adjust.value
- img = min( 4, int(val * 4) )
- self.attackLabel.set_from_file(Config.IMAGE_ROOT + 'propAtt' + str(img) + '.png')
- if not self.setup:
- stream = []
- for p in self.notes:
- for t in self.notes[p]:
- if len(self.notes[p][t]):
- stream += [ p, t, PARAMETER.ATTACK, len(self.notes[p][t]) ]
- for n in self.notes[p][t]:
- stream += [ n.id, adjust.value ]
- if len(stream):
- self.noteDB.updateNotes( stream + [-1] )
-
- def algoAttack( self, list, algorithm ):
- maxValue = max(list[0], list[1])
- stream = []
- for t in range(len(self.trackIds)):
- trackLength = 0
- for p in range(len(self.pageIds)):
- trackLength += len(self.notes[self.pageIds[p]][self.trackIds[t]])
- algorithm.__init__(list[0], list[1], trackLength)
- for p in range(len(self.pageIds)):
- substream = []
- for n in self.notes[self.pageIds[p]][self.trackIds[t]]:
- val = algorithm.getNextValue(list[2], maxValue)
- substream += [ n.id, val*0.01 ]
- if len(substream):
- stream += [ self.pageIds[p], self.trackIds[t], PARAMETER.ATTACK, len(substream)//2 ] + substream
- if len(stream):
- self.noteDB.updateNotes( stream + [-1] )
-
- def handleDecay( self, adjust ):
- val = adjust.value #*adjust.value
- img = min( 4, int(val * 4) )
- self.decayLabel.set_from_file(Config.IMAGE_ROOT + 'propDec' + str(img) + '.png')
- if not self.setup:
- stream = []
- for p in self.notes:
- for t in self.notes[p]:
- if len(self.notes[p][t]):
- stream += [ p, t, PARAMETER.DECAY, len(self.notes[p][t]) ]
- for n in self.notes[p][t]:
- stream += [ n.id, adjust.value ]
- if len(stream):
- self.noteDB.updateNotes( stream + [-1] )
-
- def algoDecay( self, list, algorithm ):
- maxValue = max(list[0], list[1])
- stream = []
- for t in range(len(self.trackIds)):
- trackLength = 0
- for p in range(len(self.pageIds)):
- trackLength += len(self.notes[self.pageIds[p]][self.trackIds[t]])
- algorithm.__init__(list[0], list[1], trackLength)
- for p in range(len(self.pageIds)):
- substream = []
- for n in self.notes[self.pageIds[p]][self.trackIds[t]]:
- val = algorithm.getNextValue(list[2], maxValue)
- substream += [ n.id, val*0.01 ]
- if len(substream):
- stream += [ self.pageIds[p], self.trackIds[t], PARAMETER.DECAY, len(substream)//2 ] + substream
- if len(stream):
- self.noteDB.updateNotes( stream + [-1] )
-
- def handleFilterType( self, widget, type ):
-
- if widget.get_active():
- if self.filterType == 0:
- self.filterLabel.show()
- self.GUI['cutoffSlider'].show()
- self.GUI['cutoffGen'].show()
-
- self.filterType = type
- self.updateFilterLabel()
-
- if widget != self.GUI['filterTypeLowButton'] and self.GUI['filterTypeLowButton'].get_active():
- self.GUI['filterTypeLowButton'].set_active( False )
- if widget != self.GUI['filterTypeBandButton'] and self.GUI['filterTypeBandButton'].get_active():
- self.GUI['filterTypeBandButton'].set_active( False )
- if widget != self.GUI['filterTypeHighButton'] and self.GUI['filterTypeHighButton'].get_active():
- self.GUI['filterTypeHighButton'].set_active( False )
- if not self.setup:
- typestream = []
- cutoffstream = []
- cutoff = self.cutoffAdjust.value
- for p in self.notes:
- for t in self.notes[p]:
- if len(self.notes[p][t]):
- substream = []
- typestream += [ p, t, PARAMETER.FILTERTYPE, len(self.notes[p][t]) ]
- for n in self.notes[p][t]:
- typestream += [ n.id, type ]
- if n.cs.filterCutoff != cutoff:
- substream += [ n.id, cutoff ]
- if len(substream):
- cutoffstream += [ p, t, PARAMETER.FILTERCUTOFF, len(substream)//2 ] + substream
- if len(typestream):
- self.noteDB.updateNotes( typestream + [-1] )
- if len(cutoffstream):
- self.noteDB.updateNotes( cutoffstream + [-1] )
-
- elif type == self.filterType:
- self.filterType = 0
- self.filterLabel.hide()
- self.GUI['cutoffSlider'].hide()
- self.GUI['cutoffGen'].hide()
- if not self.setup:
- typestream = []
- for p in self.notes:
- for t in self.notes[p]:
- if len(self.notes[p][t]):
- typestream += [ p, t, PARAMETER.FILTERTYPE, len(self.notes[p][t]) ]
- for n in self.notes[p][t]:
- typestream += [ n.id, 0 ]
- if len(typestream):
- self.noteDB.updateNotes( typestream + [-1] )
-
- def handleFilter( self, adjust ):
- stream = []
- for p in self.notes:
- for t in self.notes[p]:
- if len(self.notes[p][t]):
- stream += [ p, t, PARAMETER.FILTERCUTOFF, len(self.notes[p][t]) ]
- for n in self.notes[p][t]:
- stream += [ n.id, adjust.value ]
- if len(stream):
- self.noteDB.updateNotes( stream + [-1] )
-
- def algoCutoff( self, list, algorithm ):
- maxValue = max(list[0], list[1])
- stream = []
- for t in range(len(self.trackIds)):
- trackLength = 0
- for p in range(len(self.pageIds)):
- trackLength += len(self.notes[self.pageIds[p]][self.trackIds[t]])
- algorithm.__init__(list[0], list[1], trackLength)
- for p in range(len(self.pageIds)):
- substream = []
- for n in self.notes[self.pageIds[p]][self.trackIds[t]]:
- val = algorithm.getNextValue(list[2], maxValue)
- substream += [ n.id, val*70+100 ]
- if len(substream):
- stream += [ self.pageIds[p], self.trackIds[t], PARAMETER.FILTERCUTOFF, len(substream)//2 ] + substream
- if len(stream):
- self.noteDB.updateNotes( stream + [-1] )
-
- self.updateFilterLabel()
-
- def handleAlgo( self, widget, data ):
- self.algorithm = self.algoTypes[data]
- paraTooltips = ['Random', 'Maximum step', 'Maximum step', 'Maximum step', 'Maximum step']
- self.tooltips.set_tip(self.GUI['paraSlider'], paraTooltips[data])
-
- def handleMin( self, adjust ):
- self.minValue = adjust.value
-
- def handleMax( self, adjust ):
- self.maxValue = adjust.value
-
- def handlePara( self, adjust ):
- self.paraValue = adjust.value
-
- def apply( self, widget, data=None ):
- valList = [self.minValue, self.maxValue, self.paraValue]
- if self.property == 'pitch':
- self.algoPitch(valList, self.algorithm)
- elif self.property == 'volume':
- self.algoVolume(valList, self.algorithm)
- elif self.property == 'pan':
- self.algoPan(valList, self.algorithm)
- elif self.property == 'reverb':
- self.algoReverb(valList, self.algorithm)
- elif self.property == 'attack':
- self.algoAttack(valList, self.algorithm)
- elif self.property == 'decay':
- self.algoDecay(valList, self.algorithm)
- elif self.property == 'cutoff':
- self.algoCutoff(valList, self.algorithm)
- self.cancel(self.activeWidget)
-
- def cancel( self, widget, data=None ):
- self.activeWidget.set_active(False)
-
- def updateFilterLabel( self ):
- val = (self.cutoffAdjust.value-self.cutoffAdjust.lower)/(self.cutoffAdjust.upper-self.cutoffAdjust.lower)
- img = min( 5, int(val * 6) )
- self.filterLabel.set_from_file(Config.IMAGE_ROOT + 'propFilter%d.%d' % (self.filterType, img) + '.png')
-
-
-
-
-
-
diff --git a/Edit/TrackInterface.py b/Edit/TrackInterface.py
deleted file mode 100644
index b8a3a27..0000000
--- a/Edit/TrackInterface.py
+++ /dev/null
@@ -1,1364 +0,0 @@
-import pygtk
-pygtk.require( '2.0' )
-import gtk
-
-import gobject
-
-from math import floor
-import time
-
-import Config
-from Edit.NoteInterface import NoteInterface
-from Edit.HitInterface import HitInterface
-from Edit.MainWindow import CONTEXT
-
-from Util.NoteDB import PARAMETER
-from Util.CSoundNote import CSoundNote
-from Generation.GenerationConstants import GenerationConstants
-from Util.Profiler import TP
-
-class SELECTNOTES:
- ALL = -1
- NONE = 0
- ADD = 1
- REMOVE = 2
- FLIP = 3
- EXCLUSIVE = 4
-
-class INTERFACEMODE:
- DEFAULT = 0
- DRAW = 1
- PASTE_NOTES = 2
- PASTE_TRACKS = 3
- PAINT = 4
-
-class TrackInterfaceParasite:
- def __init__( self, noteDB, owner, note ):
- if note.track == Config.NUMBER_OF_TRACKS-1: # drum track
- self.parasite = HitInterface( noteDB, owner, note )
- else:
- self.parasite = NoteInterface( noteDB, owner, note )
-
- def attach( self ):
- return self.parasite
-
-class TrackInterface( gtk.EventBox ):
-
- def __init__( self, noteDB, owner, getScaleFunction ):
- gtk.EventBox.__init__( self )
-
- self.noteDB = noteDB
- self.owner = owner
- self.getScale = getScaleFunction
-
- self.drawingArea = gtk.DrawingArea()
- self.drawingAreaDirty = False # are we waiting to draw?
- self.add( self.drawingArea )
- self.dirtyRectToAdd = gtk.gdk.Rectangle() # used by the invalidate_rect function
-
- self.fullWidth = 1 # store the maximum allowed width
- self.width = 1
- self.height = 1
-
- self.interfaceMode = INTERFACEMODE.DEFAULT
-
- self.curPage = -1 # this isn't a real page at all!
- self.curBeats = 4
- self.painting = False
- self.pointerGrid = 1
- self.drawGrid = Config.DEFAULT_GRID
- self.paintGrid = Config.DEFAULT_GRID
- self.paintNoteDur = Config.DEFAULT_GRID
-
- self.selectedNotes = [ [] for i in range(Config.NUMBER_OF_TRACKS) ]
-
- self.curAction = False # stores the current mouse action
- self.curActionObject = False # stores the object that in handling the action
-
- self.lastDO = self.lastDP = self.lastDrumDP = self.lastDD = None
-
- self.clickButton = 0 # used in release and motion events to make sure we where actually the widget originally clicked. (hack for popup windows)
- self.buttonPressCount = 1 # used on release events to indicate double/triple releases
- self.clickLoc = [0,0] # location of the last click
- self.marqueeLoc = False # current drag location of the marquee
- self.marqueeRect = [[0,0],[0,0]]
-
- self.pasteTick = -1
- self.pasteTrack = -1
- self.pasteRect = False
-
- self.playheadT = 0
- self.playheadX = Config.TRACK_SPACING_DIV2
-
- self.cursor = { \
- "default": None, \
- "drag-onset": gtk.gdk.Cursor(gtk.gdk.SB_RIGHT_ARROW), \
- "drag-pitch": gtk.gdk.Cursor(gtk.gdk.BOTTOM_SIDE), \
- "drag-duration": gtk.gdk.Cursor(gtk.gdk.RIGHT_SIDE), \
- "drag-playhead": gtk.gdk.Cursor(gtk.gdk.SB_H_DOUBLE_ARROW), \
- "pencil": gtk.gdk.Cursor(gtk.gdk.PENCIL), \
- "paste": gtk.gdk.Cursor(gtk.gdk.CENTER_PTR), \
- "error": None }
-
- self.add_events(gtk.gdk.POINTER_MOTION_MASK|gtk.gdk.POINTER_MOTION_HINT_MASK)
-
- self.connect( "size-allocate", self.size_allocate )
-
- self.drawingArea.connect( "expose-event", self.expose )
- self.connect( "button-press-event", self.handleButtonPress )
- self.connect( "button-release-event", self.handleButtonRelease )
- self.connect( "motion-notify-event", self.handleMotion )
-
- # prepare drawing stuff
- hexToInt = { "0":0, "1":1, "2":2, "3":3, "4":4, "5":5, "6":6, "7":7, "8":8, "9":9, "A":10, "B":11, "C":12, "D":13, "E":14, "F":15, "a":10, "b":11, "c":12, "d":13, "e":14, "f":15 }
- self.trackColors = []
- for i in Config.TRACK_COLORS:
- low = ( 256*(hexToInt[i[0][1]]*16+hexToInt[i[0][2]]), 256*(hexToInt[i[0][3]]*16+hexToInt[i[0][4]]), 256*(hexToInt[i[0][5]]*16+hexToInt[i[0][6]]) )
- high = ( 256*(hexToInt[i[1][1]]*16+hexToInt[i[1][2]]), 256*(hexToInt[i[1][3]]*16+hexToInt[i[1][4]]), 256*(hexToInt[i[1][5]]*16+hexToInt[i[1][6]]) )
- delta = ( high[0]-low[0], high[1]-low[1], high[2]-low[2] )
- self.trackColors.append( (low, delta) )
-
- colormap = self.drawingArea.get_colormap()
- self.beatColor = colormap.alloc_color( Config.BEAT_COLOR, True, True )
- self.playheadColor = colormap.alloc_color( Config.PLAYHEAD_COLOR, True, True )
- self.marqueeColor = colormap.alloc_color( Config.MARQUEE_COLOR, True, True )
-
- self.image = {}
- win = gtk.gdk.get_default_root_window()
- self.gc = gtk.gdk.GC( win )
-
- def prepareDrawable( name ):
- pix = gtk.gdk.pixbuf_new_from_file( Config.IMAGE_ROOT+name+".png" )
- self.image[name] = gtk.gdk.Pixmap( win, pix.get_width(), pix.get_height() )
- self.image[name].draw_pixbuf( self.gc, pix, 0, 0, 0, 0, pix.get_width(), pix.get_height(), gtk.gdk.RGB_DITHER_NONE )
- def preparePixbuf( name ):
- self.image[name] = gtk.gdk.pixbuf_new_from_file( Config.IMAGE_ROOT+name+".png" )
-
- prepareDrawable( "trackBG" )
- prepareDrawable( "trackBGSelected" )
- prepareDrawable( "trackBGDrum" )
- prepareDrawable( "trackBGDrumSelected" )
- preparePixbuf( "note" )
- preparePixbuf( "noteSelected" )
- preparePixbuf( "hit" )
- preparePixbuf( "hitSelected" )
-
- # define dimensions
- self.width = self.trackFullWidth = self.image["trackBG"].get_size()[0]
- self.trackWidth = self.width - Config.TRACK_SPACING
- self.trackFullHeight = self.image["trackBG"].get_size()[1]
- self.trackHeight = self.trackFullHeight - Config.TRACK_SPACING
- self.trackFullHeightDrum = self.image["trackBGDrum"].get_size()[1]
- self.trackHeightDrum = self.trackFullHeightDrum - Config.TRACK_SPACING
- self.height = self.trackHeight*(Config.NUMBER_OF_TRACKS-1) + self.trackHeightDrum + Config.TRACK_SPACING*Config.NUMBER_OF_TRACKS
- self.trackLimits = []
- self.trackRect = []
- self.drumIndex = Config.NUMBER_OF_TRACKS-1
- for i in range(self.drumIndex):
- start = i*(self.trackFullHeight)
- self.trackLimits.append( (start,start+self.trackFullHeight) )
- self.trackRect.append( gtk.gdk.Rectangle(Config.TRACK_SPACING_DIV2,start+Config.TRACK_SPACING_DIV2, self.trackWidth, self.trackHeight ) )
- self.trackLimits.append( ( self.height - self.trackFullHeightDrum, self.height ) )
- self.trackRect.append( gtk.gdk.Rectangle( Config.TRACK_SPACING_DIV2, self.height - self.trackFullHeightDrum + Config.TRACK_SPACING_DIV2, self.trackWidth, self.trackHeightDrum ) )
-
- self.pitchPerPixel = float(Config.NUMBER_OF_POSSIBLE_PITCHES-1) / (self.trackHeight - Config.NOTE_HEIGHT)
- self.pixelsPerPitch = float(self.trackHeight-Config.NOTE_HEIGHT)/(Config.MAXIMUM_PITCH - Config.MINIMUM_PITCH)
- self.pitchPerPixelDrum = float(Config.NUMBER_OF_POSSIBLE_PITCHES_DRUM-1)*Config.PITCH_STEP_DRUM / (self.trackHeightDrum - Config.HIT_HEIGHT)
- self.pixelsPerPitchDrum = float(self.trackHeightDrum-Config.HIT_HEIGHT)/(Config.MAXIMUM_PITCH_DRUM - Config.MINIMUM_PITCH_DRUM )
-
- self.pixelsPerTick = [0] + [ self.trackWidth/float(i*Config.TICKS_PER_BEAT) for i in range(1,Config.MAXIMUM_BEATS+1) ]
-
- self.ticksPerPixel = [0] + [ 1.0/self.pixelsPerTick[i] for i in range(1,Config.MAXIMUM_BEATS+1) ]
-
- self.beatSpacing = [[0]]
- for i in range(1,Config.MAXIMUM_BEATS+1):
- self.beatSpacing.append( [ self.ticksToPixels( i, Config.TICKS_PER_BEAT*j ) for j in range(i) ] )
-
- # screen buffers
- self.screenBuf = [ gtk.gdk.Pixmap( win, self.width, self.height ), \
- gtk.gdk.Pixmap( win, self.width, self.height ) ]
- self.screenBufPage = [ -1, -1 ]
- self.screenBufBeats = [ -1, -1 ]
- self.screenBufDirtyRect = [ gtk.gdk.Rectangle(), gtk.gdk.Rectangle() ]
- self.screenBufDirty = [ False, False ]
- self.screenBufResume = [ [0,0], [0,0] ] # allows for stopping and restarting in the middle of a draw
- self.curScreen = 0
- self.preScreen = 1
- self.predrawTimeout = False
-
- #-- private --------------------------------------------
-
- def _updateClipboardArea( self ):
- self.clipboardArea = self.owner.getClipboardArea( self.curPage )
- self.clipboardTrackTop = 0
- for t in range(self.drumIndex):
- if self.clipboardArea["tracks"][t]: break
- self.clipboardTrackTop += 1
- self.clipboardDrumTrack = self.clipboardArea["tracks"][self.drumIndex]
-
- #=======================================================
- # NoteDB notifications
-
- def notifyPageAdd( self, id, at ):
- return
-
- def notifyPageDelete( self, which, safe ):
- if self.screenBufPage[self.preScreen] in which:
- self.screenBufPage[self.preScreen] = -1
-
- def notifyPageDuplicate( self, new, at ):
- return
-
- def notifyPageMove( self, which, low, high ):
- return
-
- def notifyPageUpdate( self, page, parameter, value ):
- if parameter == PARAMETER.PAGE_BEATS:
- notes = self.noteDB.getNotesByPage( page, self )
- for note in notes:
- note.updateTransform()
-
- if page == self.screenBufPage[self.curScreen]:
- self.screenBufBeats[self.curScreen] = value
- self.curBeats = value
- if self.playheadT >= value*Config.TICKS_PER_BEAT:
- self.playheadT = value*Config.TICKS_PER_BEAT - 1
- self.playheadX = self.ticksToPixels( self.curBeats, self.playheadT ) + Config.TRACK_SPACING_DIV2
- self.invalidate_rect( 0, 0, self.width, self.height, page )
- if page == self.screenBufPage[self.preScreen]:
- self.screenBufBeats[self.preScreen] = value
- self.invalidate_rect( 0, 0, self.width, self.height, page )
- self.predrawPage()
-
-
- #=======================================================
- # Module Interface
-
- def getDrawingPackage( self, track ):
- if track == self.drumIndex:
- return ( self.image["hit"], self.image["hitSelected"], self.drawingArea.get_colormap(), self.trackColors[track] )
- else:
- return ( self.image["note"], self.image["noteSelected"], self.drawingArea.get_colormap(), self.trackColors[track] )
-
- def getActivePages( self ):
- return self.screenBufPage
-
- def setPredrawPage( self, page ):
- if self.screenBufPage[self.preScreen] != page:
- self.screenBufPage[self.preScreen] = page
- self.screenBufBeats[self.preScreen] = self.noteDB.getPage(page).beats
- self.invalidate_rect( 0, 0, self.width, self.height, page )
- return True
- return False
-
- def predrawPage( self ):
- if self.screenBufPage[self.preScreen] == -1: return True # no page to predraw
- if not self.predrawTimeout:
- self.predrawTimeout = gobject.timeout_add( 50, self._predrawTimeout )
-
- def abortPredrawPage( self ):
- if self.predrawTimeout:
- gobject.source_remove( self.predrawTimeout )
- self.predrawTimeout = False
-
- def _predrawTimeout( self ):
- if self.preScreen == -1: return False # no page to predraw
- if self.draw( self.preScreen, False, time.time() + 0.020 ): # 20 ms time limit
- self.predrawTimeout = False
- return False
- return True
-
-
-
- def displayPage( self, page, predraw = -1 ):
- if page == self.curPage:
- if predraw >= 0 and self.screenBufPage[self.preScreen] != predraw:
- self.screenBufPage[self.preScreen] = predraw
- self.screenBufBeats[self.preScreen] = self.noteDB.getPage(predraw).beats
- self.invalidate_rect( 0, 0, self.width, self.height, predraw )
- return
-
- if self.curPage >= 0 and self.curPage != page: clearNotes = True
- else: clearNotes = False
-
- oldPage = self.curPage
- self.curPage = page
- self.curBeats = self.noteDB.getPage(page).beats
-
- if self.screenBufPage[self.preScreen] == self.curPage: # we predrew this page, so smart!
- t = self.preScreen
- self.preScreen = self.curScreen
- self.curScreen = t
- self.invalidate_rect( 0, 0, self.width, self.height, self.curPage, False )
- else: # we need to draw this page from scratch
- self.screenBufPage[self.curScreen] = self.curPage
- self.screenBufBeats[self.curScreen] = self.curBeats
- self.invalidate_rect( 0, 0, self.width, self.height, self.curPage )
-
- if predraw >= 0 and self.screenBufPage[self.preScreen] != predraw:
- self.screenBufPage[self.preScreen] = predraw
- self.screenBufBeats[self.preScreen] = self.noteDB.getPage(predraw).beats
- self.invalidate_rect( 0, 0, self.width, self.height, predraw )
-
- if clearNotes: # clear the notes now that we've sorted out the screen buffers
- self.clearSelectedNotes( oldPage )
-
- if self.curAction == "paste":
- self._updateClipboardArea()
-
- def getPlayhead( self ):
- return self.playheadT
-
- def setPlayhead( self, ticks ):
- if self.playheadT != ticks:
- self.invalidate_rect( self.playheadX-Config.PLAYHEAD_SIZE/2, 0, Config.PLAYHEAD_SIZE, self.height, self.curPage, False )
- self.playheadX = self.ticksToPixels( self.curBeats, ticks ) + Config.TRACK_SPACING_DIV2
- self.invalidate_rect( self.playheadX-Config.PLAYHEAD_SIZE/2, 0, Config.PLAYHEAD_SIZE, self.height, self.curPage, False )
- self.playheadT = ticks
-
- def setInterfaceMode( self, mode ):
- self.doneCurrentAction()
-
- if mode == "tool":
- mode = self.owner.getTool()
-
- if mode == "draw":
- self.interfaceMode = INTERFACEMODE.DRAW
- elif mode == "paint":
- self.interfaceMode = INTERFACEMODE.PAINT
- elif mode == "paste_notes":
- self.interfaceMode = INTERFACEMODE.PASTE_NOTES
- self.setCurrentAction("paste", self)
- elif mode == "paste_tracks":
- self.interfaceMode = INTERFACEMODE.PASTE_TRACKS
- self.setCurrentAction("paste", self )
- else:
- self.interfaceMode = INTERFACEMODE.DEFAULT
-
- def getSelectedNotes( self ):
- ids = []
- for t in range(Config.NUMBER_OF_TRACKS):
- ids.append( [ n.note.id for n in self.selectedNotes[t] ] )
- return ids
-
- #=======================================================
- # Event Callbacks
-
- def size_allocate( self, widget, allocation ):
- self.alloc = allocation
- width = allocation.width
- height = allocation.height
-
- self.drawingArea.set_size_request( width, height )
-
- if self.window != None:
- self.invalidate_rect( 0, 0, width, height, self.curPage, False )
-
- def setPointerGrid(self, value):
- self.pointerGrid = value
-
- def setDrawGrid(self, value):
- self.drawGrid = value
-
- def setPaintGrid(self, value):
- self.paintGrid = value
-
- def setPaintNoteDur(self, value):
- self.paintNoteDur = value
-
- def handleButtonPress( self, widget, event ):
-
- TP.ProfileBegin( "TI::handleButtonPress" )
-
- self.clickButton = event.button
-
- if event.type == gtk.gdk._2BUTTON_PRESS: self.buttonPressCount = 2
- elif event.type == gtk.gdk._3BUTTON_PRESS: self.buttonPressCount = 3
- else: self.buttonPressCount = 1
-
- self.clickLoc = [ int(event.x), int(event.y) ]
-
-
- if self.curAction == "paste":
- self.doPaste()
- self.setCurrentAction("block-track-select")
- TP.ProfileEnd( "TI::handleButtonPress" )
- return
-
-
- # check if we clicked on the playhead
- if event.x >= self.playheadX and event.x <= self.playheadX + Config.PLAYHEAD_SIZE:
- self.setCurrentAction( "playhead-drag", self )
- TP.ProfileEnd( "TI::handleButtonPress" )
- return
-
- for i in range(Config.NUMBER_OF_TRACKS):
- if self.trackLimits[i][0] > event.y: break
- if self.trackLimits[i][1] < event.y: continue
-
- handled = 0
- notes = self.noteDB.getNotesByTrack( self.curPage, i, self )
- last = len(notes)-1
- for n in range(last+1):
- if i == self.drumIndex and n < last: # check to see if the next hit overlaps this one
- if notes[n].getStartTick() == notes[n+1].getStartTick() and notes[n].getPitch() == notes[n+1].getPitch():
- continue
- handled = notes[n].handleButtonPress( self, event )
- if handled == 0:
- continue
- elif handled == 1:
- if not self.curAction: self.curAction = True # it was handled but no action was declared, set curAction to True anyway
- TP.ProfileEnd( "TI::handleButtonPress" )
- return
- else: # all other options mean we can stop looking
- break
-
- if self.interfaceMode == INTERFACEMODE.DRAW:
- if not handled or handled == -1: # event didn't overlap any notes, so we can draw
- if i == self.drumIndex: pitch = min( self.pixelsToPitchDrumFloor( self.clickLoc[1] - self.trackLimits[i][1] + Config.HIT_HEIGHT//2 )//Config.PITCH_STEP_DRUM, Config.NUMBER_OF_POSSIBLE_PITCHES_DRUM-1)*Config.PITCH_STEP_DRUM + Config.MINIMUM_PITCH_DRUM
- else: pitch = min( self.pixelsToPitchFloor( self.clickLoc[1] - self.trackLimits[i][1] + Config.NOTE_HEIGHT//2 ), Config.NUMBER_OF_POSSIBLE_PITCHES-1) + Config.MINIMUM_PITCH
- onset = self.pixelsToTicksFloor( self.curBeats, self.clickLoc[0] - self.trackRect[i].x)
- snapOnset = self.drawGrid * int(onset / float(self.drawGrid) + 0.5)
- cs = CSoundNote( snapOnset,
- pitch,
- 0.75,
- 0.5,
- 1,
- i,
- instrumentId = self.owner.getTrackInstrument(i).instrumentId )
- cs.pageId = self.curPage
- id = self.noteDB.addNote( -1, self.curPage, i, cs )
- n = self.noteDB.getNote( self.curPage, i, id, self )
- self.selectNotes( { i:[n] }, True )
- n.playSampleNote( False )
-
- noteS = self.noteDB.getNotesByTrack(self.curPage, i)
- for note in noteS:
- if note.cs.onset < snapOnset and (note.cs.onset + note.cs.duration) > snapOnset:
- self.noteDB.updateNote(self.curPage, i, note.id, PARAMETER.DURATION, snapOnset - note.cs.onset)
-
- if i != self.drumIndex: # switch to drag duration
- self.updateDragLimits()
- self.clickLoc[0] += self.ticksToPixels( self.curBeats, 1 )
- self.setCurrentAction( "note-drag-duration", n )
- self.setCursor("drag-duration")
- else:
- self.curAction = True # we handled this, but there's no real action
-
- TP.ProfileEnd( "TI::handleButtonPress" )
- return
- elif self.interfaceMode == INTERFACEMODE.PAINT:
- self.scale = self.getScale()
- self.painting = True
- self.paintTrack = i
- if i == self.drumIndex:
- pitch = min( self.pixelsToPitchDrumFloor( self.clickLoc[1] - self.trackLimits[i][1] + Config.HIT_HEIGHT//2 )//Config.PITCH_STEP_DRUM, Config.NUMBER_OF_POSSIBLE_PITCHES_DRUM-1)*Config.PITCH_STEP_DRUM + Config.MINIMUM_PITCH_DRUM
- if pitch < 24:
- pitch = 24
- elif pitch > 48:
- pitch = 48
- else:
- pitch = pitch
- else:
- pitch = min( self.pixelsToPitchFloor( self.clickLoc[1] - self.trackLimits[i][1] + Config.NOTE_HEIGHT//2 ), Config.NUMBER_OF_POSSIBLE_PITCHES-1) + Config.MINIMUM_PITCH
- if pitch < 24:
- pitch = 24
- elif pitch > 48:
- pitch = 48
- else:
- pitch = pitch
-
- minDiff = 100
- for pit in GenerationConstants.SCALES[self.scale]:
- diff = abs(pitch-(pit+36))
- if diff < minDiff:
- minDiff = diff
- nearestPit = pit
- pitch = nearestPit+36
-
- onset = self.pixelsToTicksFloor( self.curBeats, self.clickLoc[0] - self.trackRect[i].x )
- onset = self.paintGrid * int(onset / self.paintGrid + 0.5)
- self.pLastPos = onset
- if i != self.drumIndex:
- noteS = self.noteDB.getNotesByTrack(self.curPage, i)
- ids = []
- stream = []
- for n in noteS:
- if n.cs.onset >= onset and n.cs.onset < (onset + self.paintNoteDur):
- ids.append(n.id)
- if onset > n.cs.onset and onset < (n.cs.onset + n.cs.duration):
- ids.append(n.id)
- if len(ids):
- stream += [self.curPage, i, len(ids)] + ids
- self.noteDB.deleteNotes( stream + [-1] )
-
- cs = CSoundNote( int(onset),
- pitch,
- 0.75,
- 0.5,
- 1,
- i,
- instrumentId = self.owner.getTrackInstrument(i).instrumentId )
- cs.pageId = self.curPage
- id = self.noteDB.addNote( -1, self.curPage, i, cs )
- self.noteDB.updateNote(self.curPage, i, id, PARAMETER.DURATION, self.paintNoteDur)
- n = self.noteDB.getNote( self.curPage, i, id, self )
- self.selectNotes( { i:[n] }, True )
- n.playSampleNote( False )
- self.curAction = True
-
- TP.ProfileEnd( "TI::handleButtonPress" )
-
-
- def handleButtonRelease( self, widget, event ):
- if not self.clickButton: return # we recieved this event but were never clicked! (probably a popup window was open)
- self.clickButton = 0
- self.painting = False
-
- TP.ProfileBegin( "TI::handleButtonRelease" )
-
- if event.button != 1:
- TP.ProfileEnd( "TI::handleButtonRelease" )
- return
-
- if not self.curAction: #do track selection stuff here so that we can also handle marquee selection
- for i in range(Config.NUMBER_OF_TRACKS):
- if self.trackLimits[i][0] > event.y: break
- if self.trackLimits[i][1] < event.y: continue
- if event.button == 1:
- if self.buttonPressCount == 1: self.owner.toggleTrack( i, False )
- elif self.buttonPressCount == 2: self.owner.toggleTrack( i, True )
- else: self.owner.clearTracks()
- break
-
- TP.ProfileEnd( "TI::handleButtonRelease" )
- return
-
- if not self.curActionObject: # there was no real action to carry out
- self.curAction = False
- TP.ProfileEnd( "TI::handleButtonRelease" )
- return
-
- if self.curActionObject != self:
- self.curActionObject.handleButtonRelease( self, event, self.buttonPressCount )
- self.updateTooltip( event )
- else:
- # we're doing the action ourselves
- if self.curAction == "marquee": self.doneMarquee( event )
- elif self.curAction == "playhead-drag": self.donePlayhead( event )
- self.updateTooltip( event )
-
-
- TP.ProfileEnd( "TI::handleButtonRelease" )
- return
-
- def handleMotion( self, widget, event ):
- TP.ProfileBegin( "TI::handleMotion::Common" )
-
- if event.is_hint:
- x, y, state = self.window.get_pointer()
- event.x = float(x)
- event.y = float(y)
- event.state = state
-
- if self.painting:
- i = self.paintTrack
- curPos = self.pixelsToTicksFloor(self.curBeats, event.x - self.trackRect[i].x)
- gridPos = self.paintGrid * int(curPos / self.paintGrid + 0.5)
- if gridPos >= self.curBeats * Config.TICKS_PER_BEAT:
- return
- if gridPos != self.pLastPos:
- self.pLastPos = gridPos
- if i == self.drumIndex:
- pitch = min( self.pixelsToPitchDrumFloor( int(event.y) - self.trackLimits[i][1] + Config.HIT_HEIGHT//2 )//Config.PITCH_STEP_DRUM, Config.NUMBER_OF_POSSIBLE_PITCHES_DRUM-1)*Config.PITCH_STEP_DRUM + Config.MINIMUM_PITCH_DRUM
- if pitch < 24:
- pitch = 24
- elif pitch > 48:
- pitch = 48
- else:
- pitch = pitch
- else:
- pitch = min( self.pixelsToPitchFloor( int(event.y) - self.trackLimits[i][1] + Config.NOTE_HEIGHT//2 ), Config.NUMBER_OF_POSSIBLE_PITCHES-1) + Config.MINIMUM_PITCH
- if pitch < 24:
- pitch = 24
- elif pitch > 48:
- pitch = 48
- else:
- pitch = pitch
- minDiff = 100
- for pit in GenerationConstants.SCALES[self.scale]:
- diff = abs(pitch-(pit+36))
- if diff < minDiff:
- minDiff = diff
- nearestPit = pit
- pitch = nearestPit+36
-
- onset = gridPos
- if i != self.drumIndex:
- noteS = self.noteDB.getNotesByTrack(self.curPage, i)
- ids = []
- stream = []
- for n in noteS:
- if n.cs.onset >= onset and n.cs.onset < (onset + self.paintNoteDur):
- ids.append(n.id)
- if onset > n.cs.onset and onset < (n.cs.onset + n.cs.duration):
- ids.append(n.id)
- if len(ids):
- stream += [self.curPage, i, len(ids)] + ids
- self.noteDB.deleteNotes( stream + [-1] )
-
- cs = CSoundNote( int(onset),
- pitch,
- 0.75,
- 0.5,
- 1,
- i,
- instrumentId = self.owner.getTrackInstrument(i).instrumentId )
- cs.pageId = self.curPage
- id = self.noteDB.addNote( -1, self.curPage, i, cs )
- self.noteDB.updateNote(self.curPage, i, id, PARAMETER.DURATION, self.paintNoteDur)
- n = self.noteDB.getNote( self.curPage, i, id, self )
- self.selectNotes( { i:[n] }, True )
- n.playSampleNote( False )
- self.curAction = True
-
-
- TP.ProfileEnd( "TI::handleMotion::Common" )
-
- if not self.clickButton and self.curAction != "paste": # we recieved this event but were never clicked! (probably a popup window was open)
- TP.ProfileBegin( "TI::handleMotion::Hover" )
- self.updateTooltip( event )
- TP.ProfileEnd( "TI::handleMotion::Hover" )
- return
-
- if self.curAction == "paste":
- TP.ProfileBegin( "TI::handleMotion::Paste" )
- top = Config.NUMBER_OF_TRACKS
- for i in range(Config.NUMBER_OF_TRACKS):
- if self.trackLimits[i][0] > event.y: break
- if self.trackLimits[i][1] < event.y: continue
- top = i
- break
- self.updatePaste( self.pixelsToTicksFloor( self.curBeats, event.x ), top )
- TP.ProfileEnd( "TI::handleMotion::Paste" )
- elif event.state & gtk.gdk.BUTTON1_MASK:
- TP.ProfileBegin( "TI::handleMotion::Drag" )
-
- if not self.curAction: # no action is in progress yet we're dragging, start a marquee
- self.setCurrentAction( "marquee", self )
-
- if self.curAction == "note-drag-onset":
- self.noteDragOnset( event )
-
- elif self.curAction == "note-drag-duration":
- self.noteDragDuration( event )
-
- elif self.curAction == "note-drag-pitch":
- self.noteDragPitch( event )
-
- elif self.curAction == "note-drag-pitch-drum":
- self.noteDragPitch( event, True )
-
- elif self.curAction == "marquee":
- self.updateMarquee( event )
-
- elif self.curAction == "playhead-drag":
- self.updatePlayhead( event )
-
- TP.ProfileEnd( "TI::handleMotion::Drag" )
- else:
- TP.ProfileBegin( "TI::handleMotion::Hover" )
- self.updateTooltip( event )
- TP.ProfileEnd( "TI::handleMotion::Hover" )
-
- return
-
- #=======================================================
- # Actions
-
- def setCurrentAction( self, action, obj = None ):
- if self.curAction:
- self.doneCurrentAction()
-
- self.curAction = action
- self.curActionObject = obj
-
- if action == "note-drag-onset": self.updateDragLimits()
- elif action == "note-drag-duration": self.updateDragLimits()
- elif action == "note-drag-pitch": self.updateDragLimits()
- elif action == "note-drag-pitch-drum": self.updateDragLimits()
- elif action == "paste":
- self._updateClipboardArea()
- self.setCursor("paste")
-
- def doneCurrentAction( self ):
- if not self.curAction: return
- action = self.curAction
- self.curAction = False
-
- if action == "note-drag-onset": self.doneNoteDrag( action )
- elif action == "note-drag-duration": self.doneNoteDrag( action )
- elif action == "note-drag-pitch": self.doneNoteDrag( action )
- elif action == "note-drag-pitch-drum": self.doneNoteDrag( action )
- elif action == "paste":
- self.owner.cleanupClipboard()
-
- def trackToggled( self, trackN = -1 ):
- if trackN == -1: self.invalidate_rect( 0, 0, self.width, self.height )
- else: self.invalidate_rect( 0, self.trackLimits[trackN][0], self.width, self.trackLimits[trackN][1]-self.trackLimits[trackN][0] )
-
- def selectionChanged( self ):
- if self.curAction == "note-drag-onset": self.updateDragLimits()
- elif self.curAction == "note-drag-duration": self.updateDragLimits()
- elif self.curAction == "note-drag-pitch": self.updateDragLimits()
- elif self.curAction == "note-drag-pitch-drum": self.updateDragLimits()
- for i in range(Config.NUMBER_OF_TRACKS):
- if len(self.selectedNotes[i]):
- self.owner.setContextState( CONTEXT.NOTE, True )
- self.owner.setContext( CONTEXT.NOTE )
- return
- self.owner.setContextState( CONTEXT.NOTE, False )
-
- def applyNoteSelection( self, mode, trackN, which, page = -1 ):
- if page == -1: page = self.curPage
- if mode == SELECTNOTES.ALL:
- track = self.noteDB.getNotesByTrack( page, trackN, self )
- map( lambda note:note.setSelected( True ), track )
- self.selectedNotes[trackN] = []
- map( lambda note:self.selectedNotes[trackN].append(note), track )
- elif mode == SELECTNOTES.NONE:
- track = self.selectedNotes[trackN] #self.noteDB.getNotesByTrack( page, trackN, self )
- map( lambda note:note.setSelected( False ), track )
- self.selectedNotes[trackN] = []
- elif mode == SELECTNOTES.ADD:
- for note in which:
- if note.setSelected( True ):
- self.selectedNotes[trackN].append( note )
- elif mode == SELECTNOTES.REMOVE:
- for note in which:
- if note.setSelected( False ):
- self.selectedNotes[trackN].remove( note )
- elif mode == SELECTNOTES.FLIP:
- for note in which:
- if note.getSelected():
- note.setSelected( False )
- self.selectedNotes[trackN].remove( note )
- else:
- note.setSelected( True )
- self.selectedNotes[trackN].append( note )
- elif mode == SELECTNOTES.EXCLUSIVE:
- notes = self.noteDB.getNotesByTrack( page, trackN, self )
- for n in range(len(notes)):
- if notes[n] in which:
- if notes[n].setSelected( True ):
- self.selectedNotes[trackN].append( notes[n] )
- else:
- if notes[n].setSelected( False ):
- self.selectedNotes[trackN].remove( notes[n] )
-
- def selectNotesByBar( self, trackN, start, stop, page = -1 ):
- for i in range(Config.NUMBER_OF_TRACKS):
- if i == trackN:
- notes = []
- track = self.noteDB.getNotesByTrack( self.curPage, trackN, self )
- for n in range(len(track)):
- if track[n].testOnset( start, stop ): notes.append(track[n])
- if not Config.ModKeys.ctrlDown: self.applyNoteSelection( SELECTNOTES.EXCLUSIVE, trackN, notes, page )
- else: self.applyNoteSelection( SELECTNOTES.ADD, trackN, notes, page )
- else:
- if not Config.ModKeys.ctrlDown: self.applyNoteSelection( SELECTNOTES.NONE, i, [], page )
- self.selectionChanged()
-
- def selectNotesByTrack( self, trackN, page = -1 ):
- if Config.ModKeys.ctrlDown:
- self.applyNoteSelection( SELECTNOTES.ALL, trackN, [], page )
- else:
- for i in range(Config.NUMBER_OF_TRACKS):
- if i == trackN: self.applyNoteSelection( SELECTNOTES.ALL, trackN, [], page )
- else: self.applyNoteSelection( SELECTNOTES.NONE, i, [], page )
- self.selectionChanged()
-
- def selectNotes( self, noteDic, ignoreCtrl = False, page = -1 ):
- if Config.ModKeys.ctrlDown and not ignoreCtrl:
- for i in noteDic:
- self.applyNoteSelection( SELECTNOTES.FLIP, i, noteDic[i], page )
- else:
- for i in range(Config.NUMBER_OF_TRACKS):
- if i in noteDic: self.applyNoteSelection( SELECTNOTES.EXCLUSIVE, i, noteDic[i], page )
- else: self.applyNoteSelection( SELECTNOTES.NONE, i, [], page )
- self.selectionChanged()
-
- def deselectNotes( self, noteDic, page = -1 ):
- for i in noteDic:
- self.applyNoteSelection( SELECTNOTES.REMOVE, i, noteDic[i], page )
- self.selectionChanged()
-
- def clearSelectedNotes( self, page = -1 ):
- for i in range(Config.NUMBER_OF_TRACKS):
- self.applyNoteSelection( SELECTNOTES.NONE, i, [], page )
- self.selectionChanged()
-
- def updateDragLimits( self ):
- self.dragLimits = [ [-9999,9999], [-9999,9999], [-9999,9999] ] # initialize to big numbers!
- maxRightBound = self.noteDB.getPage(self.curPage).ticks
-
- for i in range(Config.NUMBER_OF_TRACKS):
- if not len(self.selectedNotes[i]): continue # no selected notes here
-
- track = self.noteDB.getNotesByTrack( self.curPage, i, self )
- leftBound = 0
- skip = True # skip the first note
- for n in range(len(track)):
- if skip:
- skip = False
- thisNote = track[n]
- continue
- nextNote = track[n]
- if not thisNote.getSelected():
- leftBound = thisNote.getEndTick()
- else:
- if not nextNote.getSelected():
- rightBound = min( nextNote.getStartTick(), maxRightBound )
- widthBound = rightBound
- else:
- rightBound = maxRightBound
- widthBound = min( nextNote.getStartTick(), maxRightBound )
- thisNote.updateDragLimits( self.dragLimits, leftBound, rightBound, widthBound, maxRightBound )
- thisNote = nextNote
- # do the last note
- if thisNote.getSelected():
- thisNote.updateDragLimits( self.dragLimits, leftBound, maxRightBound, maxRightBound, maxRightBound )
-
- def noteDragOnset( self, event ):
- do = self.pixelsToTicks( self.curBeats, event.x - self.clickLoc[0] )
- do = min( self.dragLimits[0][1], max( self.dragLimits[0][0], do ) )
- do = self.pointerGrid * int(do / self.pointerGrid)
-
- if do != self.lastDO:
- self.lastDO = do
- stream = []
- for i in range(Config.NUMBER_OF_TRACKS):
- tstream = []
- for note in self.selectedNotes[i]:
- note.noteDragOnset( do, tstream )
- if len(tstream):
- stream += [ self.curPage, i, PARAMETER.ONSET, len(tstream)//2 ] + tstream
- if len(stream):
- self.noteDB.updateNotes( stream + [-1] )
-
- def noteDragDuration( self, event ):
- dd = self.pixelsToTicks( self.curBeats, event.x - self.clickLoc[0] )
- dd = min( self.dragLimits[2][1], max( self.dragLimits[2][0], dd ) )
-
- if dd != self.lastDD:
- self.lastDD = dd
- stream = []
- for i in range(Config.NUMBER_OF_TRACKS):
- tstream = []
- for note in self.selectedNotes[i]:
- note.noteDragDuration( dd, tstream )
- if len(tstream):
- stream += [ self.curPage, i, PARAMETER.DURATION, len(tstream)//2 ] + tstream
- if len(stream):
- self.noteDB.updateNotes( stream + [-1] )
-
- def noteDragPitch( self, event, drum = False ):
- if not drum: dp = self.pixelsToPitch( event.y - self.clickLoc[1] )
- else: dp = self.pixelsToPitchDrum( event.y - self.clickLoc[1] )
- dp = min( self.dragLimits[1][1], max( self.dragLimits[1][0], dp ) )
-
- if dp != self.lastDP:
- self.lastDP = dp
- stream = []
- for i in range(Config.NUMBER_OF_TRACKS):
- tstream = []
- for note in self.selectedNotes[i]:
- note.noteDragPitch( dp, tstream )
- if len(tstream):
- stream += [ self.curPage, i, PARAMETER.PITCH, len(tstream)//2 ] + tstream
- if len(stream):
- self.noteDB.updateNotes( stream + [-1] )
-
- if self.curActionObject.note.track != self.drumIndex:
- self.curActionObject.playSampleNote( True )
- elif dp != self.lastDrumDP and not dp%2: # only play of "full" drum pitches
- self.lastDrumDP = dp
- self.curActionObject.playSampleNote( False )
-
- def doneNoteDrag( self, action ):
- # if action == "note-drag-pitch" or action == "note-drag-pitch-drum":
- # self.curActionObject.playSampleNote()
-
- self.lastDO = self.lastDP = self.lastDrumDP = self.lastDD = None
-
- for i in range(Config.NUMBER_OF_TRACKS):
- for note in self.selectedNotes[i]:
- note.doneNoteDrag( self )
-
- def noteStepOnset( self, step ):
- stream = []
- for i in range(Config.NUMBER_OF_TRACKS):
- if not len(self.selectedNotes[i]): continue # no selected notes here
-
- tstream = []
- track = self.noteDB.getNotesByTrack( self.curPage, i, self )
- if step < 0: # moving to the left, iterate forwards
- leftBound = 0
- for n in range(len(track)):
- leftBound = track[n].noteDecOnset( step, leftBound, tstream )
- else: # moving to the right, iterate backwards
- rightBound = self.noteDB.getPage(self.curPage).ticks
- for n in range(len(track)-1, -1, -1 ):
- rightBound = track[n].noteIncOnset( step, rightBound, tstream )
-
- if len(tstream):
- stream += [ self.curPage, i, PARAMETER.ONSET, len(tstream)//2 ] + tstream
-
- if len(stream):
- self.noteDB.updateNotes( stream + [-1] )
-
- def noteStepPitch( self, step ):
- stream = []
- for i in range(Config.NUMBER_OF_TRACKS):
- if not len(self.selectedNotes[i]): continue # no selected notes here
-
- tstream = []
- if step < 0:
- for n in self.selectedNotes[i]:
- n.noteDecPitch( step, tstream )
- else:
- for n in self.selectedNotes[i]:
- n.noteIncPitch( step, tstream )
-
- if len(tstream):
- stream += [ self.curPage, i, PARAMETER.PITCH, len(tstream)//2 ] + tstream
-
- if len(stream):
- self.noteDB.updateNotes( stream + [-1] )
-
- def noteStepDuration( self, step ):
- stream = []
- for i in range(Config.NUMBER_OF_TRACKS):
- if not len(self.selectedNotes[i]): continue # no selected notes here
-
- tstream = []
- if step < 0:
- for n in self.selectedNotes[i]:
- n.noteDecDuration( step, tstream )
- else:
- track = self.noteDB.getNotesByTrack( self.curPage, i, self )
- for j in range(len(track)-1):
- track[j].noteIncDuration( step, track[j+1].getStartTick(), tstream )
- track[len(track)-1].noteIncDuration( step, self.noteDB.getPage(self.curPage).ticks, tstream )
-
- if len(tstream):
- stream += [ self.curPage, i, PARAMETER.DURATION, len(tstream)//2 ] + tstream
-
- if len(stream):
- self.noteDB.updateNotes( stream + [-1] )
-
- def noteStepVolume( self, step ):
- stream = []
- for i in range(Config.NUMBER_OF_TRACKS):
- if not len(self.selectedNotes[i]): continue # no selected notes here
-
- tstream = []
- if step < 0:
- for n in self.selectedNotes[i]:
- n.noteDecVolume( step, tstream )
- else:
- for n in self.selectedNotes[i]:
- n.noteIncVolume( step, tstream )
-
- if len(tstream):
- stream += [ self.curPage, i, PARAMETER.AMPLITUDE, len(tstream)//2 ] + tstream
-
- if len(stream):
- self.noteDB.updateNotes( stream + [-1] )
-
-
- def updateMarquee( self, event ):
- if self.marqueeLoc:
- oldX = self.marqueeRect[0][0]
- oldEndX = self.marqueeRect[0][0] + self.marqueeRect[1][0]
- oldY = self.marqueeRect[0][1]
- oldEndY = self.marqueeRect[0][1] + self.marqueeRect[1][1]
- else:
- oldX = oldEndX = self.clickLoc[0]
- oldY = oldEndY = self.clickLoc[1]
-
- self.marqueeLoc = [ int(event.x), int(event.y) ]
- if self.marqueeLoc[0] < 0: self.marqueeLoc[0] = 0
- elif self.marqueeLoc[0] > self.width: self.marqueeLoc[0] = self.width
- if self.marqueeLoc[1] < 0: self.marqueeLoc[1] = 0
- elif self.marqueeLoc[1] > self.height: self.marqueeLoc[1] = self.height
-
- if self.marqueeLoc[0] > self.clickLoc[0]:
- self.marqueeRect[0][0] = self.clickLoc[0]
- self.marqueeRect[1][0] = self.marqueeLoc[0] - self.clickLoc[0]
- else:
- self.marqueeRect[0][0] = self.marqueeLoc[0]
- self.marqueeRect[1][0] = self.clickLoc[0] - self.marqueeLoc[0]
- if self.marqueeLoc[1] > self.clickLoc[1]:
- self.marqueeRect[0][1] = self.clickLoc[1]
- self.marqueeRect[1][1] = self.marqueeLoc[1] - self.clickLoc[1]
- else:
- self.marqueeRect[0][1] = self.marqueeLoc[1]
- self.marqueeRect[1][1] = self.clickLoc[1] - self.marqueeLoc[1]
-
- x = min( self.marqueeRect[0][0], oldX )
- width = max( self.marqueeRect[0][0] + self.marqueeRect[1][0], oldEndX ) - x
- y = min( self.marqueeRect[0][1], oldY )
- height = max( self.marqueeRect[0][1] + self.marqueeRect[1][1], oldEndY ) - y
- self.invalidate_rect( x-1, y-1, width+2, height+2, self.curPage, False )
-
- def doneMarquee( self, event ):
- if self.marqueeLoc:
- stop = [ self.marqueeRect[0][0] + self.marqueeRect[1][0], self.marqueeRect[0][1] + self.marqueeRect[1][1] ]
-
- select = {}
-
- for i in range(Config.NUMBER_OF_TRACKS):
- intersectionY = [ max(self.marqueeRect[0][1],self.trackLimits[i][0]), min(stop[1],self.trackLimits[i][1]) ]
- if intersectionY[0] > intersectionY[1]:
- continue
-
- notes = []
- track = self.noteDB.getNotesByTrack( self.curPage, i, self )
- for n in range(len(track)):
- hit = track[n].handleMarqueeSelect( self,
- [ self.marqueeRect[0][0], intersectionY[0] ], \
- [ stop[0], intersectionY[1] ] )
- if hit: notes.append(track[n])
-
- if len(notes): select[i] = notes
-
- self.selectNotes( select )
-
- self.marqueeLoc = False
- self.doneCurrentAction()
-
- self.invalidate_rect( self.marqueeRect[0][0]-1, self.marqueeRect[0][1]-1, self.marqueeRect[1][0]+2, self.marqueeRect[1][1]+2, self.curPage, False )
-
- def updatePlayhead( self, event ):
- x = min( self.trackWidth - self.pixelsPerTick[self.curBeats], max( Config.TRACK_SPACING_DIV2, event.x ) )
- self.setPlayhead( self.pixelsToTicks( self.curBeats, x ) )
-
- def donePlayhead( self, event ):
- x = min( self.trackWidth - self.pixelsPerTick[self.curBeats], max( Config.TRACK_SPACING_DIV2, event.x ) )
- ticks = self.pixelsToTicks( self.curBeats, x )
- print "set playhead to %d ticks" % (ticks)
- self.doneCurrentAction()
-
- def updatePaste( self, tick, track ):
- if self.interfaceMode == INTERFACEMODE.PASTE_TRACKS: tick = 0
- if self.pasteTick == tick and self.pasteTrack == track: return
- if self.noteDB.getPage(self.curPage).ticks < tick < 0 \
- or track > self.drumIndex \
- or ( track == self.drumIndex and not self.clipboardDrumTrack ):
- if self.pasteRect:
- self.invalidate_rect( self.pasteRect[0][0], self.pasteRect[0][1], self.pasteRect[1][0], self.pasteRect[1][1], self.curPage, False )
- self.pasteTick = self.pasteTrack = -1
- self.pasteRect = False
- return
- if self.pasteRect:
- self.invalidate_rect( self.pasteRect[0][0], self.pasteRect[0][1], self.pasteRect[1][0], self.pasteRect[1][1], self.curPage, False )
- if self.clipboardDrumTrack:
- bottom = self.drumIndex
- else:
- bottom = self.drumIndex - 1
- for t in range(self.drumIndex-1,self.clipboardTrackTop-1,-1):
- if self.clipboardArea["tracks"][t]: break
- bottom -= 1
- end = -tick + min( self.noteDB.getPage(self.curPage).ticks, tick + self.clipboardArea["limit"][1]-self.clipboardArea["limit"][0] )
- self.pasteTick = tick
- self.pasteTrack = track
- self.pasteRect = [ [ self.ticksToPixels( self.curBeats, tick ), \
- self.trackLimits[track][0] ], \
- [ self.ticksToPixels( self.curBeats, end), \
- self.trackLimits[bottom][1] ] ]
- self.invalidate_rect( self.pasteRect[0][0], self.pasteRect[0][1], self.pasteRect[1][0], self.pasteRect[1][1], self.curPage, False )
-
- def doPaste( self ):
- if self.pasteTrack == -1:
- self.doneCurrentAction()
- return
-
- trackMap = {}
- for t in range(self.pasteTrack,self.drumIndex):
- ind = t+self.clipboardTrackTop-self.pasteTrack
- if ind >= self.drumIndex: break
- if not self.clipboardArea["tracks"][ind]:
- continue
- trackMap[t] = ind
- if self.clipboardDrumTrack:
- trackMap[self.drumIndex] = self.drumIndex
- new = self.owner.pasteClipboard( self.pasteTick - self.clipboardArea["limit"][0], trackMap )
- if self.interfaceMode == INTERFACEMODE.PASTE_NOTES and self.curPage in new:
- noteDic = {}
- for t in range(Config.NUMBER_OF_TRACKS):
- if len(new[self.curPage][t]):
- noteDic[t] = [ self.noteDB.getNote( self.curPage, t, n, self ) for n in new[self.curPage][t] ]
- self.selectNotes(noteDic)
- elif self.interfaceMode == INTERFACEMODE.PASTE_TRACKS:
- for t in range(self.drumIndex):
- ind = t + self.clipboardTrackTop - self.pasteTrack
- if ind >= self.drumIndex or ind < 0: self.owner.setTrack( t, False )
- else: self.owner.setTrack( t, self.clipboardArea["tracks"][ind] )
- self.owner.setTrack( self.drumIndex, self.clipboardDrumTrack )
-
- self.doneCurrentAction()
-
- def donePaste( self ):
- if self.pasteRect:
- self.invalidate_rect( self.pasteRect[0][0], self.pasteRect[0][1], self.pasteRect[1][0], self.pasteRect[1][1], self.curPage, False )
- self.pasteTick = self.pasteTrack = -1
- self.pasteRect = False
- self.setInterfaceMode("tool")
- # make a fake event for updateTooltip
- event = gtk.gdk.Event(gtk.gdk.MOTION_NOTIFY)
- x, y, state = self.window.get_pointer()
- event.x = float(x)
- event.y = float(y)
- event.state = state
- self.updateTooltip( event )
-
- def updateTooltip( self, event ):
-
- # check clicked the playhead
- if event.x >= self.playheadX and event.x <= self.playheadX + Config.PLAYHEAD_SIZE:
- self.setCursor("drag-playhead")
- return
-
- for i in range(Config.NUMBER_OF_TRACKS):
- if self.trackLimits[i][0] > event.y: break
- if self.trackLimits[i][1] < event.y: continue
-
- notes = self.noteDB.getNotesByTrack( self.curPage, i, self )
- handled = 0
- for n in range(len(notes)):
- handled = notes[n].updateTooltip( self, event )
- if handled == 0: continue
- elif handled == 1: return # event was handled
- else: break
-
- # note wasn't handled, could potentially draw a note
- if self.interfaceMode == INTERFACEMODE.DRAW:
- if handled == -2: # event X overlapped with a note
- self.setCursor("default")
- return
-
- self.setCursor("pencil")
- return
-
- break
-
- self.setCursor("default")
-
- def setCursor( self, cursor ):
- self.window.set_cursor(self.cursor[cursor])
-
- #=======================================================
- # Drawing
-
- def draw( self, buf, noescape = True, timeout = 0 ):
- if not self.screenBufDirty[buf]: return True
-
- TP.ProfileBegin( "TrackInterface::draw" )
-
- startX = self.screenBufDirtyRect[buf].x
- startY = self.screenBufDirtyRect[buf].y
- stopX = self.screenBufDirtyRect[buf].x + self.screenBufDirtyRect[buf].width
- stopY = self.screenBufDirtyRect[buf].y + self.screenBufDirtyRect[buf].height
-
- beatStart = Config.TRACK_SPACING_DIV2
- beats = self.screenBufBeats[buf]
-
- pixmap = self.screenBuf[buf]
-
- resume = self.screenBufResume[buf]
-
- self.gc.set_clip_rectangle( self.screenBufDirtyRect[buf] )
-
- self.gc.set_line_attributes( Config.BEAT_LINE_SIZE, gtk.gdk.LINE_ON_OFF_DASH, gtk.gdk.CAP_BUTT, gtk.gdk.JOIN_MITER )
- # regular tracks
- for i in range( resume[0], self.drumIndex ):
- if resume[1] == 0:
- if startY > self.trackLimits[i][1]: continue
- if stopY < self.trackLimits[i][0]: break
-
- # draw background
- if self.owner.getTrackSelected( i ):
- pixmap.draw_drawable( self.gc, self.image["trackBGSelected"], 0, 0, 0, self.trackLimits[i][0], self.trackFullWidth, self.trackFullHeight )
- else:
- pixmap.draw_drawable( self.gc, self.image["trackBG"], 0, 0, 0, self.trackLimits[i][0], self.trackFullWidth, self.trackFullHeight )
-
- # draw beat lines
- self.gc.foreground = self.beatColor
- for j in range(1,self.screenBufBeats[buf]):
- x = beatStart + self.beatSpacing[beats][j]
- pixmap.draw_line( self.gc, x, self.trackRect[i].y, x, self.trackRect[i].y+self.trackRect[i].height )
-
- resume[1] = 1 # background drawn
-
- # draw notes
- TP.ProfileBegin("TI::draw notes")
- notes = self.noteDB.getNotesByTrack( self.screenBufPage[buf], i, self )
- for n in range( resume[2], len(notes) ):
- # check escape
- if not noescape and time.time() > timeout:
- resume[0] = i
- resume[2] = n
- TP.ProfilePause( "TrackInterface::draw" )
- return False
-
- if not notes[n].draw( pixmap, self.gc, startX, stopX ): break
- TP.ProfileEnd("TI::draw notes")
-
- # finished a track, reset the resume values for the next one
- resume[1] = 0
- resume[2] = 0
-
- # drum track
- if stopY > self.trackLimits[self.drumIndex][0]:
-
- if resume[1] == 0:
- # draw background
- if self.owner.getTrackSelected( self.drumIndex ):
- pixmap.draw_drawable( self.gc, self.image["trackBGDrumSelected"], 0, 0, 0, self.trackLimits[self.drumIndex][0], self.trackFullWidth, self.trackFullHeightDrum )
- else:
- pixmap.draw_drawable( self.gc, self.image["trackBGDrum"], 0, 0, 0, self.trackLimits[self.drumIndex][0], self.trackFullWidth, self.trackFullHeightDrum )
-
- # draw beat lines
- self.gc.foreground = self.beatColor
- for j in range(1,self.screenBufBeats[buf]):
- x = beatStart + self.beatSpacing[beats][j]
- pixmap.draw_line( self.gc, x, self.trackRect[self.drumIndex].y, x, self.trackRect[self.drumIndex].y+self.trackRect[self.drumIndex].height )
-
- resume[1] = 1 # background drawn
-
- # draw notes
- notes = self.noteDB.getNotesByTrack( self.screenBufPage[buf], self.drumIndex, self )
- for n in range( resume[2], len(notes) ):
- # check escape
- if not noescape and time.time() > timeout:
- resume[0] = i
- resume[2] = n
- TP.ProfilePause( "TrackInterface::draw" )
- return False
- if not notes[n].draw( pixmap, self.gc, startX, stopX ): break
-
- self.screenBufDirty[buf] = False
-
- TP.ProfileEnd( "TrackInterface::draw" )
-
- return True
-
- def expose( self, DA, event ):
-
- if self.screenBufDirty[self.curScreen]:
- self.draw( self.curScreen )
-
- TP.ProfileBegin( "TrackInterface::expose" )
-
- startX = event.area.x
- startY = event.area.y
- stopX = event.area.x + event.area.width
- stopY = event.area.y + event.area.height
-
- #print "%d %d %d %d" % (startX,startY,stopX,stopY)
-
- self.gc.set_clip_rectangle( event.area )
-
- # draw base
- DA.window.draw_drawable( self.gc, self.screenBuf[self.curScreen], startX, startY, startX, startY, event.area.width, event.area.height )
-
- # draw playhead
- self.gc.set_line_attributes( Config.PLAYHEAD_SIZE, gtk.gdk.LINE_SOLID, gtk.gdk.CAP_BUTT, gtk.gdk.JOIN_MITER )
- self.gc.foreground = self.playheadColor
- DA.window.draw_line( self.gc, self.playheadX, startY, self.playheadX, stopY )
-
- if self.marqueeLoc: # draw the selection rect
- self.gc.set_line_attributes( Config.MARQUEE_SIZE, gtk.gdk.LINE_ON_OFF_DASH, gtk.gdk.CAP_BUTT, gtk.gdk.JOIN_MITER )
- self.gc.foreground = self.marqueeColor
- DA.window.draw_rectangle( self.gc, False, self.marqueeRect[0][0], self.marqueeRect[0][1], self.marqueeRect[1][0], self.marqueeRect[1][1] )
-
- if self.pasteRect: # draw the paste highlight
- self.gc.set_function( gtk.gdk.INVERT )
- for t in range(self.pasteTrack,self.drumIndex):
- ind = t+self.clipboardTrackTop-self.pasteTrack
- if ind >= self.drumIndex: break
- if not self.clipboardArea["tracks"][ind]:
- continue
- DA.window.draw_rectangle( self.gc, True, self.pasteRect[0][0], self.trackLimits[t][0] + Config.TRACK_SPACING_DIV2, self.pasteRect[1][0], self.trackHeight )
- if self.clipboardDrumTrack:
- DA.window.draw_rectangle( self.gc, True, self.pasteRect[0][0], self.trackLimits[self.drumIndex][0] + Config.TRACK_SPACING_DIV2, self.pasteRect[1][0], self.trackHeightDrum )
- self.gc.set_function( gtk.gdk.COPY )
-
- self.drawingAreaDirty = False
-
- TP.ProfileEnd( "TrackInterface::expose" )
-
- def invalidate_rect( self, x, y, width, height, page = -1, base = True ):
- #print "%d %d %d %d Page %d CurPage %d" % (x,y,width,height,page,self.curPage)
- self.dirtyRectToAdd.x = x
- self.dirtyRectToAdd.y = y
- self.dirtyRectToAdd.width = width
- self.dirtyRectToAdd.height = height
-
- #print "dirty %d %d %d %d %d %d" % (x, y, width, height, x+width, y+height)
- if page == self.curPage or page == -1:
- if base: # the base image has been dirtied
- if not self.screenBufDirty[self.curScreen]:
- self.screenBufDirtyRect[self.curScreen].x = x
- self.screenBufDirtyRect[self.curScreen].y = y
- self.screenBufDirtyRect[self.curScreen].width = width
- self.screenBufDirtyRect[self.curScreen].height = height
- else:
- self.screenBufDirtyRect[self.curScreen] = self.screenBufDirtyRect[self.curScreen].union( self.dirtyRectToAdd )
- self.screenBufResume[self.curScreen] = [0,0,0]
- self.screenBufDirty[self.curScreen] = True
- if self.drawingArea.window != None:
- self.drawingArea.window.invalidate_rect( self.dirtyRectToAdd, True )
- self.drawingAreaDirty = True
-
- if page == self.screenBufPage[self.preScreen] or page == -1:
- if not self.screenBufDirty[self.preScreen]:
- self.screenBufDirtyRect[self.preScreen].x = x
- self.screenBufDirtyRect[self.preScreen].y = y
- self.screenBufDirtyRect[self.preScreen].width = width
- self.screenBufDirtyRect[self.preScreen].height = height
- else:
- self.screenBufDirtyRect[self.preScreen] = self.screenBufDirtyRect[self.preScreen].union( self.dirtyRectToAdd )
- self.screenBufResume[self.preScreen] = [0,0,0]
- self.screenBufDirty[self.preScreen] = True
-
- #self.queue_draw()
-
- def getTrackOrigin( self, track ):
- return ( self.trackRect[track].x, self.trackRect[track].y )
-
- def ticksToPixels( self, beats, ticks ):
- return int(round( ticks * self.pixelsPerTick[beats] ))
- def pixelsToTicks( self, beats, pixels ):
- return int(round( pixels * self.ticksPerPixel[beats] ))
- def ticksToPixelsFloor( self, beats, ticks ):
- return int( ticks * self.pixelsPerTick[beats] )
- def pixelsToTicksFloor( self, beats, pixels ):
- return int( pixels * self.ticksPerPixel[beats] )
- def pitchToPixels( self, pitch ):
- return int(round( ( Config.MAXIMUM_PITCH - pitch ) * self.pixelsPerPitch ))
- def pixelsToPitch( self, pixels ):
- return int(round(-pixels*self.pitchPerPixel))
- def pitchToPixelsFloor( self, pitch ):
- return int(( Config.MAXIMUM_PITCH - pitch ) * self.pixelsPerPitch )
- def pixelsToPitchFloor( self, pixels ):
- return int(-pixels*self.pitchPerPixel)
- def pitchToPixelsDrum( self, pitch ):
- return int(round( ( Config.MAXIMUM_PITCH_DRUM - pitch ) * self.pixelsPerPitchDrum ))
- def pixelsToPitchDrum( self, pixels ):
- return int(round(-pixels*self.pitchPerPixelDrum))
- def pitchToPixelsDrumFloor( self, pitch ):
- return int( ( Config.MAXIMUM_PITCH_DRUM - pitch ) * self.pixelsPerPitchDrum )
- def pixelsToPitchDrumFloor( self, pixels ):
- return int(-pixels*self.pitchPerPixelDrum)
diff --git a/Edit/TuneInterface.py b/Edit/TuneInterface.py
deleted file mode 100644
index 3682a57..0000000
--- a/Edit/TuneInterface.py
+++ /dev/null
@@ -1,645 +0,0 @@
-import pygtk
-pygtk.require( '2.0' )
-import gtk
-
-import Config
-
-from Util.Profiler import TP
-from Edit.MainWindow import CONTEXT
-
-from Util.NoteDB import PARAMETER
-
-class TuneInterfaceParasite:
-
- def __init__( self, noteDB, owner, note ):
- self.noteDB = noteDB
- self.owner = owner
- self.note = note
-
- self.x = self.y = self.width = -1
-
- def attach( self ):
- self.updateParameter( None, None )
- return self
-
- def destroy( self ):
- self.owner.invalidate_thumbnail( self.note.page, self.x, self.y, self.width, 1 )
-
- def updateParameter( self, parameter, value ):
- if parameter == PARAMETER.AMPLITUDE: return
- x = 2 + Config.THUMBNAIL_TRACK_RECT[self.note.track][0] + self.owner.ticksToPixels( self.noteDB.getPage( self.note.page).beats, self.note.cs.onset )
- if self.note.track == Config.NUMBER_OF_TRACKS-1: # drum track
- y = Config.THUMBNAIL_TRACK_RECT[self.note.track][1] + self.owner.pitchToPixelsDrum( self.note.cs.pitch )
- if x != self.x or y != self.y:
- if parameter != None: # not the first update
- xx = min( self.x, x )
- yy = min( self.y, y )
- endxx = max( self.endx, x + 1 )
- endyy = max( self.y, y ) + 1
- self.x = x
- self.endx = x + 1
- self.y = y
- self.owner.invalidate_thumbnail( self.note.page, xx, yy, endxx-xx, endyy-yy )
- else:
- self.x = x
- self.endx = x + 1
- self.y = y
- self.owner.invalidate_thumbnail( self.note.page, x, y, 1, 1 )
- else:
- y = Config.THUMBNAIL_TRACK_RECT[self.note.track][1] + self.owner.pitchToPixels( self.note.cs.pitch )
- width = max( 1, self.owner.ticksToPixels( self.noteDB.getPage( self.note.page).beats, self.note.cs.duration ) )
- if x != self.x or y != self.y or width != self.width:
- if parameter != None: # not the first update
- xx = min( self.x, x )
- yy = min( self.y, y )
- endxx = max( self.endx, x + width )
- endyy = max( self.y, y ) + 1
- self.x = x
- self.endx = x + width
- self.y = y
- self.width = width
- self.owner.invalidate_thumbnail( self.note.page, xx, yy, endxx-xx, endyy-yy )
- else:
- self.x = x
- self.endx = x + width
- self.y = y
- self.width = width
- self.owner.invalidate_thumbnail( self.note.page, x, y, width, 1 )
-
- def draw( self, win, gc, startX, stopX ):
- if stopX < self.x: return False # we don't need to draw and no one after us will draw
- if startX > self.endx: return True # we don't need to draw, but maybe a later note does
-
- win.draw_line( gc, self.x, self.y, self.endx, self.y )
-
- return True # we drew something
-
-
-class TuneInterface( gtk.EventBox ):
-
- DRAG_BLOCK = -1 # block other drag events
- DRAG_SELECT = 1
- DRAG_DESELECT = 2
- DRAG_MOVE = 3
-
- def __init__( self, noteDB, owner, adjustment ):
- gtk.EventBox.__init__( self )
-
- self.noteDB = noteDB
- self.owner = owner
- self.adjustment = adjustment
- #adjustment.connect( "changed", self.adjustmentChanged )
- adjustment.connect( "value-changed", self.adjustmentValue )
-
- self.drawingArea = gtk.DrawingArea()
- self.drawingAreaDirty = False # is the drawingArea waiting to draw?
- self.add( self.drawingArea )
- self.dirtyRectToAdd = gtk.gdk.Rectangle() # used by the invalidate_rect function
-
- self.selectedIds = []
- self.displayedPage = -1
-
- self.drumIndex = Config.NUMBER_OF_TRACKS-1
-
- self.trackRect = Config.THUMBNAIL_TRACK_RECT
- self.thumbnail = {}
- self.thumbnailDirty = {}
- self.thumbnailDirtyRect = {}
- self.defaultwin = gtk.gdk.get_default_root_window() # used when creating pixmaps
- self.gc = gtk.gdk.GC( self.defaultwin )
- colormap = self.drawingArea.get_colormap()
- self.bgColor = colormap.alloc_color( Config.TOOLBAR_BCK_COLOR, True, True )
- self.lineColor = colormap.alloc_color( Config.THUMBNAIL_DRAG_COLOR, True, True )
- self.displayedColor = colormap.alloc_color( Config.THUMBNAIL_DISPLAYED_COLOR, True, True )
- self.selectedColor = colormap.alloc_color( Config.THUMBNAIL_SELECTED_COLOR, True, True )
-
- # prepare thumbnail
- self.thumbnailBG = []
- self.gc.foreground = self.bgColor
- for i in range(4):
- pix = gtk.gdk.pixbuf_new_from_file( Config.IMAGE_ROOT+"pageThumbnailBG%d.png"%i )
- self.thumbnailBG.append( gtk.gdk.Pixmap( self.defaultwin, Config.PAGE_THUMBNAIL_WIDTH, Config.PAGE_THUMBNAIL_HEIGHT ) )
- self.thumbnailBG[i].draw_rectangle( self.gc, True, 0, 0, Config.PAGE_THUMBNAIL_WIDTH, Config.PAGE_THUMBNAIL_HEIGHT )
- self.thumbnailBG[i].draw_pixbuf( self.gc, pix, 0, 0, 0, 0, Config.PAGE_THUMBNAIL_WIDTH, Config.PAGE_THUMBNAIL_HEIGHT, gtk.gdk.RGB_DITHER_NONE )
-
- # load clipmask
- pix = gtk.gdk.pixbuf_new_from_file(Config.IMAGE_ROOT+'pageThumbnailMask.png')
- pixels = pix.get_pixels()
- stride = pix.get_rowstride()
- channels = pix.get_n_channels()
- bitmap = ""
- byte = 0
- shift = 0
- for j in range(pix.get_height()):
- offset = stride*j
- for i in range(pix.get_width()):
- if pixels[i*channels+offset] != "\0":
- byte += 1 << shift
- shift += 1
- if shift > 7:
- bitmap += "%c" % byte
- byte = 0
- shift = 0
- if shift:
- bitmap += "%c" % byte
- byte = 0
- shift = 0
- self.clipMask = gtk.gdk.bitmap_create_from_data( None, bitmap, pix.get_width(), pix.get_height() )
- self.clearMask = gtk.gdk.Rectangle( 0, 0, 1200, 800 )
-
- self.pageOffset = 5 # offset the first page by this
- self.dropWidth = 5 # line thickness of the drop head
- self.dropWidthDIV2 = self.dropWidth//2
-
- self.pixelsPerPitch = float(self.trackRect[0][3]-1)/(Config.MAXIMUM_PITCH - Config.MINIMUM_PITCH)
- self.pixelsPerPitchDrum = float(self.trackRect[self.drumIndex][3]-1)/(Config.MAXIMUM_PITCH_DRUM - Config.MINIMUM_PITCH_DRUM )
- self.pixelsPerTick = [0] + [ float(self.trackRect[0][2]-4)/(i*Config.TICKS_PER_BEAT) for i in range(1,Config.MAXIMUM_BEATS+1) ]
-
- self.alloced = False
- self.width = self.baseWidth = self.height = -1
- self.waitingForAlloc = True
- self.scrollTo = None
- self.clickX = -1
-
- self.set_size_request( self.width, self.height )
-
- self.button1Down = False
- self.dragMode = None
- self.dropAt = -1
- self.dropAtX = 0
-
- self.visibleX = 0
- self.visibleEndX = 0
-
- self.add_events(gtk.gdk.POINTER_MOTION_MASK|gtk.gdk.POINTER_MOTION_HINT_MASK)
-
- self.connect( "size-allocate", self.size_allocated )
- self.drawingArea.connect( "expose-event", self.draw )
- self.connect( "button-press-event", self.handleButtonPress )
- self.connect( "button-release-event", self.handleButtonRelease )
- self.connect( "motion-notify-event", self.handleMotion )
-
- def size_allocated( self, widget, allocation ):
- if not self.alloced:
- self.baseWidth = allocation.width
- self.visibleEndX = self.baseWidth
- self.baseHeight = allocation.height
- self.alloced = True
- self.updateSize()
- self.width = allocation.width
- self.height = allocation.height
- self.drawingArea.set_size_request( self.width, self.height )
- self.clearMask.height = self.height
- self.clearMask.width = self.width
-
- self.pageY = 2 + (self.height-Config.PAGE_THUMBNAIL_HEIGHT)//2
-
- if self.scrollTo != None:
- if self.scrollTo >= 0: self.adjustment.set_value( self.scrollTo )
- else: self.adjustment.set_value( self.width - self.baseWidth )
- self.scrollTo = None
-
- self.waitingForAlloc = False
-
- def adjustmentValue( self, adj ):
- self.visibleX = int(adj.value)
- self.visibleEndX = self.visibleX + self.baseWidth
-
- def updateSize( self ):
- width = self.noteDB.getPageCount()*Config.PAGE_THUMBNAIL_WIDTH + 5 # add extra 5 for the first page
- self.waitingForAlloc = True
- if width < self.baseWidth:
- self.pageOffset = ( self.baseWidth - width ) // 2 + 5
- else:
- self.pageOffset = 5
-
- if self.alloced:
- self.set_size_request( max( self.baseWidth, width), -1 )
- self.invalidate_rect( self.visibleX, 0, self.baseWidth, self.height )
-
- def handleButtonPress( self, widget, event ):
- if event.button != 1:
- # bring up properties or something
- return
-
- self.button1Down = True
-
- self.owner.abortPredrawPage()
-
- ind = int(event.x-self.pageOffset)//Config.PAGE_THUMBNAIL_WIDTH
- if ind >= self.noteDB.getPageCount():
- if self.dragMode != self.DRAG_MOVE:
- self.dragMode = self.DRAG_BLOCK
- return
- if ind < 0: ind = 0
-
- self.clickX = event.x
-
- id = self.noteDB.getPageByIndex( ind )
-
- if event.type == gtk.gdk._3BUTTON_PRESS: # triple click -> select all
- self.owner.displayPage( id )
- self.selectAll()
- elif event.type == gtk.gdk._2BUTTON_PRESS: # double click -> exclusive select
- self.owner.displayPage( id )
- self.selectPage( id )
- else:
- if Config.ModKeys.ctrlDown:
- if id in self.selectedIds: # ctrl click, selected page -> remove page from selection
- if self.deselectPage( id ):
- self.dragMode = self.DRAG_DESELECT
- self.dragLastInd = ind
- else:
- self.dragMode = self.DRAG_SELECT # special case, they clicked on the last selected page and it wasn't deselected
- self.dragLastInd = ind
- else: # ctrl click, unselected page -> add page to selection (but don't display it)
- self.selectPage( id, False )
- self.dragMode = self.DRAG_SELECT
- self.dragLastInd = ind
- elif id in self.selectedIds: # click, selected page -> display this page but don't change the selection
- self.owner.displayPage( id )
- else: # click, unselected page -> exclusive select
- self.owner.displayPage( id )
- self.selectPage( id )
-
-
- self.owner.setContext( CONTEXT.PAGE )
-
- def handleButtonRelease( self, widget, event ):
- if event.button != 1:
- return
-
- self.button1Down = False
-
- if self.dragMode == self.DRAG_MOVE:
- self.invalidate_rect( self.dropAtX - self.dropWidthDIV2, 0, self.dropWidth, self.height ) # drop head
-
- if self.dropAt > 0: after = self.noteDB.getPageByIndex( self.dropAt-1 )
- else: after = False
-
- self.noteDB.movePages( self.selectedIds, after )
-
- self.dropAt = -1
-
- self.dragMode = None
-
- def handleMotion( self, widget, event ):
-
- if event.is_hint:
- x, y, state = self.window.get_pointer()
- event.x = float(x)
- event.y = float(y)
- event.state = state
-
- if self.button1Down: # clicking
- if Config.ModKeys.ctrlDown and (self.dragMode == None or self.dragMode == self.DRAG_MOVE):
- self.dropAt = -1
- self.dragMode = self.DRAG_SELECT
- if event.x >= self.pageOffset: ind = int(event.x-self.pageOffset)//Config.PAGE_THUMBNAIL_WIDTH
- else: ind = 0
- self.dragLastInd = ind
-
- if self.dragMode == self.DRAG_SELECT: # select on drag
- if event.x > self.pageOffset: ind = int(event.x-self.pageOffset)//Config.PAGE_THUMBNAIL_WIDTH
- else: ind = 0
- pageCount = self.noteDB.getPageCount()
- if ind >= pageCount: ind = pageCount-1
- for i in range( min(ind,self.dragLastInd), max(ind,self.dragLastInd)+1):
- self.selectPage( self.noteDB.getPageByIndex(i), False )
- self.dragLastInd = ind
- elif self.dragMode == self.DRAG_DESELECT: # deselect on drag
- if event.x > self.pageOffset: ind = int(event.x-self.pageOffset)//Config.PAGE_THUMBNAIL_WIDTH
- else: ind = 0
- pageCount = self.noteDB.getPageCount()
- if ind >= pageCount: ind = pageCount-1
- for i in range( min(ind,self.dragLastInd), max(ind,self.dragLastInd)+1):
- self.deselectPage( self.noteDB.getPageByIndex(i) )
- self.dragLastInd = ind
- elif self.dragMode == None and abs(self.clickX-event.x) > 20: # drag and drop
- self.dragMode = self.DRAG_MOVE
-
- if self.dragMode == self.DRAG_MOVE:
- if self.dropAt >= 0: lastX = self.dropAtX
- else: lastX = -1
- if event.x > self.pageOffset: self.dropAt = int(event.x-self.pageOffset+Config.PAGE_THUMBNAIL_WIDTH_DIV2)//Config.PAGE_THUMBNAIL_WIDTH
- else: self.dropAt = 0
- c = self.noteDB.getPageCount()
- if self.dropAt > c: self.dropAt = c
- self.dropAtX = self.pageOffset + self.dropAt*Config.PAGE_THUMBNAIL_WIDTH - self.dropWidthDIV2 - 1
- if lastX >= 0 and lastX != self.dropAtX:
- if lastX < self.dropAtX:
- x = lastX - self.dropWidthDIV2
- w = self.dropAtX - lastX + self.dropWidth
- else:
- x = self.dropAtX - self.dropWidthDIV2
- w = lastX - self.dropAtX + self.dropWidth
- self.invalidate_rect( x, 0, w, self.height )
- elif lastX == -1:
- self.invalidate_rect( self.dropAtX-self.dropWidthDIV2, 0, self.dropWidth, self.height )
-
- else: # hovering
- ind = int(event.x-self.pageOffset)//Config.PAGE_THUMBNAIL_WIDTH
- if ind != self.lastPredrawInd and 0 <= ind < self.noteDB.getPageCount():
- id = self.noteDB.getPageByIndex(ind)
- if id != self.displayedPage:
- self.owner.predrawPage( id )
- self.lastPredrawInd = ind
-
-
- def trackToggled( self, i ):
- self.invalidate_rect( self.visibleX, 0, self.baseWidth, self.height )
-
- def displayPage( self, id ):
- if self.displayedPage == id: return -1
-
- self.lastPredrawInd = -1
-
- if self.displayedPage != -1:
- ind = self.noteDB.getPageIndex( self.displayedPage )
- self.invalidate_rect( self.pageOffset + ind*Config.PAGE_THUMBNAIL_WIDTH, 0, Config.PAGE_THUMBNAIL_WIDTH, self.height )
-
- if not self.thumbnail.has_key( id ):
- # premptive add
- self.thumbnail[id] = gtk.gdk.Pixmap( self.defaultwin, Config.PAGE_THUMBNAIL_WIDTH, Config.PAGE_THUMBNAIL_HEIGHT )
- self.thumbnailDirtyRect[id] = gtk.gdk.Rectangle( 0, 0, Config.PAGE_THUMBNAIL_WIDTH, Config.PAGE_THUMBNAIL_HEIGHT )
- self.thumbnailDirty[id] = True
- self.selectPage( id )
- self.updateSize()
-
- self.displayedPage = id
-
- if id not in self.selectedIds:
- self.selectPage( id )
-
- ind = self.noteDB.getPageIndex( id )
-
- startX = self.pageOffset + ind*Config.PAGE_THUMBNAIL_WIDTH
- stopX = startX + Config.PAGE_THUMBNAIL_WIDTH
-
- if self.adjustment.value > startX:
- scroll = startX + Config.PAGE_THUMBNAIL_WIDTH + Config.PAGE_THUMBNAIL_WIDTH_DIV2 - self.baseWidth
- if scroll < 0: scroll = 0
- self.adjustment.set_value( scroll )
- elif self.adjustment.value + self.baseWidth < stopX:
- scroll = startX - Config.PAGE_THUMBNAIL_WIDTH_DIV2
- if scroll + self.baseWidth > self.width:
- if self.waitingForAlloc:
- self.scrollTo = -1
- else:
- self.adjustment.set_value( self.width - self.baseWidth )
- else:
- if self.waitingForAlloc:
- self.scrollTo = scroll
- else:
- self.adjustment.set_value( scroll )
-
- self.invalidate_rect( startX, 0, Config.PAGE_THUMBNAIL_WIDTH, self.height )
-
- def selectPage( self, id, exclusive = True ):
- if exclusive:
- self._clearSelection()
-
- if id in self.selectedIds: return False # no change
-
- ind = self.noteDB.getPageIndex( id )
- l = len(self.selectedIds)
- i = 0 # in case len(self.selectedIds) == 0
- while i < l:
- if self.noteDB.getPageIndex( self.selectedIds[i] ) > ind: break
- i += 1
-
- self.selectedIds.insert( i, id )
-
- self.invalidate_rect( self.pageOffset + ind*Config.PAGE_THUMBNAIL_WIDTH, 0, Config.PAGE_THUMBNAIL_WIDTH, self.height )
-
- self.owner.updatePageSelection( self.selectedIds )
-
- return True # page added to selection
-
- def deselectPage( self, id, force = False, skip_redraw = False, noUpdate = False ):
- if not id in self.selectedIds: return False # page isn't selected
-
- if not force:
- if len(self.selectedIds) <= 1: return False # don't deselect the last page
-
- if self.displayedPage == id:
- i = self.selectedIds.index(id)
- if i == 0: self.owner.displayPage( self.selectedIds[1] )
- else: self.owner.displayPage( self.selectedIds[i-1] )
-
- self.selectedIds.remove( id )
- if not skip_redraw:
- ind = self.noteDB.getPageIndex( id )
- self.invalidate_rect( self.pageOffset + ind*Config.PAGE_THUMBNAIL_WIDTH, 0, Config.PAGE_THUMBNAIL_WIDTH, self.height )
-
- if not noUpdate:
- self.owner.updatePageSelection( self.selectedIds )
-
- return True # page removed from the selection
-
- def selectPages( self, which ):
- self._clearSelection()
- self.selectedIds += which
-
- self.owner.updatePageSelection( self.selectedIds )
-
- def selectAll( self ):
- self.selectedIds = self.noteDB.getTune()[:]
- self.invalidate_rect( self.visibleX, 0, self.baseWidth, self.height )
-
- self.owner.updatePageSelection( self.selectedIds )
-
- def _clearSelection( self ):
- self.selectedIds = []
- self.invalidate_rect( self.visibleX, 0, self.baseWidth, self.height )
-
- def getSelectedIds( self ):
- return self.selectedIds
-
- def getDisplayedIndex( self ):
- return self.selectedIds.index( self.displayedPage )
-
- def getFirstSelected( self ):
- return self.selectedIds[0]
-
- def getLastSelected( self ):
- return self.selectedIds[-1]
-
- #=======================================================
- # NoteDB notifications
-
- def notifyPageAdd( self, id, at ):
- if not self.thumbnail.has_key(id):
- self.thumbnail[id] = gtk.gdk.Pixmap( self.defaultwin, Config.PAGE_THUMBNAIL_WIDTH, Config.PAGE_THUMBNAIL_HEIGHT )
- self.thumbnailDirtyRect[id] = gtk.gdk.Rectangle( 0, 0, Config.PAGE_THUMBNAIL_WIDTH, Config.PAGE_THUMBNAIL_HEIGHT )
- self.thumbnailDirty[id] = True
- self.selectPage( id )
- self.updateSize()
-
- def notifyPageDelete( self, which, safe ):
- if self.displayedPage in which:
- noUpdate = True
- else:
- noUpdate = False
- for id in self.selectedIds:
- if id in which:
- self.deselectPage( id, True, True, noUpdate )
- for id in which:
- del self.thumbnail[id]
- del self.thumbnailDirtyRect[id]
- del self.thumbnailDirty[id]
- if self.displayedPage in which:
- self.displayedPage = -1
- self.updateSize()
-
- def notifyPageDuplicate( self, new, at ):
- for id in new:
- self.thumbnail[new[id]] = gtk.gdk.Pixmap( self.defaultwin, Config.PAGE_THUMBNAIL_WIDTH, Config.PAGE_THUMBNAIL_HEIGHT )
- self.thumbnailDirtyRect[new[id]] = gtk.gdk.Rectangle( 0, 0, Config.PAGE_THUMBNAIL_WIDTH, Config.PAGE_THUMBNAIL_HEIGHT )
- self.thumbnailDirty[new[id]] = True
- self.updateSize()
-
- def notifyPageMove( self, which, low, high ):
- self.invalidate_rect( self.visibleX, 0, self.baseWidth, self.height )
-
- def notifyPageUpdate( self, page, parameter, value ):
- if parameter == PARAMETER.PAGE_BEATS:
- notes = self.noteDB.getNotesByPage( page, self )
- for note in notes:
- note.updateParameter( -1, -1 ) # force update transform
-
- elif parameter == PARAMETER.PAGE_COLOR:
- self.invalidate_thumbnail( page, 0, 0, Config.PAGE_THUMBNAIL_WIDTH, Config.PAGE_THUMBNAIL_HEIGHT )
-
- #=======================================================
- # Drawing
-
- def drawThumbnail( self, id, pixmap, rect ):
- startX = rect.x
- startY = rect.y
- stopX = rect.x + rect.width
- stopY = rect.y + rect.height
-
- # draw background
- pixmap.draw_drawable( self.gc, self.thumbnailBG[self.noteDB.getPage(id).color], startX, startY, startX, startY, rect.width, rect.height+1 )
-
- # draw regular tracks
- self.gc.foreground = self.lineColor
- self.gc.set_line_attributes( 1, gtk.gdk.LINE_SOLID, gtk.gdk.CAP_BUTT, gtk.gdk.JOIN_MITER )
- for i in range(self.drumIndex):
- if startY >= self.trackRect[i+1][1]: continue
- if stopY < self.trackRect[i][1]: break
-
- # draw notes
- notes = self.noteDB.getNotesByTrack( id, i, self )
- for n in range( len(notes) ):
- if not notes[n].draw( pixmap, self.gc, startX, stopX ): break
- # drum track
- if stopY > self.trackRect[self.drumIndex][0]:
- # draw notes
- notes = self.noteDB.getNotesByTrack( id, self.drumIndex, self )
- for n in range( len(notes) ):
- if not notes[n].draw( pixmap, self.gc, startX, stopX ): break
-
- self.thumbnailDirty[id] = False
-
-
- def draw( self, drawingArea, event ):
-
- startX = event.area.x
- startY = event.area.y
- stopX = event.area.x + event.area.width
- stopY = event.area.y + event.area.height
-
- self.gc.set_clip_rectangle( self.clearMask )
-
- # draw background
- self.gc.foreground = self.bgColor
- drawingArea.window.draw_rectangle( self.gc, True, startX, startY, event.area.width, event.area.height )
-
- tracks = [ self.owner.getTrackSelected(i) for i in range(Config.NUMBER_OF_TRACKS) ]
-
- # draw pages
- self.gc.set_clip_mask( self.clipMask )
-
- x = self.pageOffset
- endx = x + Config.PAGE_THUMBNAIL_WIDTH
- for pageId in self.noteDB.getTune():
- if endx < startX:
- x = endx
- endx += Config.PAGE_THUMBNAIL_WIDTH
- continue
- if x > stopX: break
-
- # draw thumbnail
- if self.thumbnailDirty[pageId]:
- self.gc.set_clip_origin( 0, 0 )
- self.drawThumbnail( pageId, self.thumbnail[pageId], self.thumbnailDirtyRect[pageId] )
- self.gc.set_clip_origin( x, self.pageY )
- drawingArea.window.draw_drawable( self.gc, self.thumbnail[pageId], 0, 0, x, self.pageY, Config.PAGE_THUMBNAIL_WIDTH, Config.PAGE_THUMBNAIL_HEIGHT )
-
- # draw border if necessary
- if pageId == self.displayedPage: # displayed page border
- self.gc.set_function( gtk.gdk.INVERT )
- for i in range(Config.NUMBER_OF_TRACKS):
- if tracks[i]:
- drawingArea.window.draw_rectangle( self.gc, True, x + self.trackRect[i][0], self.pageY + self.trackRect[i][1], self.trackRect[i][2], self.trackRect[i][3] )
- self.gc.set_function( gtk.gdk.COPY )
- self.gc.foreground = self.displayedColor
- self.gc.set_clip_origin( x - Config.PAGE_THUMBNAIL_WIDTH, self.pageY )
- drawingArea.window.draw_rectangle( self.gc, True, x, self.pageY, Config.PAGE_THUMBNAIL_WIDTH, Config.PAGE_THUMBNAIL_HEIGHT )
- elif pageId in self.selectedIds: # selected page border
- self.gc.set_function( gtk.gdk.INVERT )
- for i in range(Config.NUMBER_OF_TRACKS):
- if tracks[i]:
- drawingArea.window.draw_rectangle( self.gc, True, x + self.trackRect[i][0], self.pageY + self.trackRect[i][1], self.trackRect[i][2], self.trackRect[i][3] )
- self.gc.set_function( gtk.gdk.COPY )
- self.gc.foreground = self.selectedColor
- self.gc.set_clip_origin( x - Config.PAGE_THUMBNAIL_WIDTH, self.pageY )
- drawingArea.window.draw_rectangle( self.gc, True, x, self.pageY, Config.PAGE_THUMBNAIL_WIDTH, Config.PAGE_THUMBNAIL_HEIGHT )
-
- x += Config.PAGE_THUMBNAIL_WIDTH
-
- # draw drop marker
- if self.dropAt >= 0:
- self.gc.set_clip_rectangle( self.clearMask )
- self.gc.set_line_attributes( self.dropWidth, gtk.gdk.LINE_SOLID, gtk.gdk.CAP_ROUND, gtk.gdk.JOIN_MITER )
- self.gc.foreground = self.lineColor
- drawingArea.window.draw_line( self.gc, self.dropAtX, self.pageY+2, self.dropAtX, self.pageY+Config.PAGE_THUMBNAIL_HEIGHT-4 )
-
- def invalidate_rect( self, x, y, width, height ):
- if self.alloced == False: return
- if x < self.visibleX: x = self.visibleX
- if x + width > self.visibleEndX: width = self.visibleEndX - x
- if width <= 0: return
-
- self.dirtyRectToAdd.x = x
- self.dirtyRectToAdd.y = y
- self.dirtyRectToAdd.width = width
- self.dirtyRectToAdd.height = height
- self.drawingArea.window.invalidate_rect( self.dirtyRectToAdd, True )
- self.drawingAreaDirty = True
-
- def invalidate_thumbnail( self, id, x, y, width, height ):
- if not self.thumbnailDirty[id]:
- self.thumbnailDirtyRect[id].x = x
- self.thumbnailDirtyRect[id].y = y
- self.thumbnailDirtyRect[id].width = width
- self.thumbnailDirtyRect[id].height = height
- self.thumbnailDirty[id] = True
- else:
- self.dirtyRectToAdd.x = x
- self.dirtyRectToAdd.y = y
- self.dirtyRectToAdd.width = width
- self.dirtyRectToAdd.height = height
- self.thumbnailDirtyRect[id] = self.thumbnailDirtyRect[id].union( self.dirtyRectToAdd )
-
- ind = self.noteDB.getPageIndex( id )
- self.invalidate_rect( self.pageOffset + ind*Config.PAGE_THUMBNAIL_WIDTH, 0, Config.PAGE_THUMBNAIL_WIDTH, self.height )
-
- def ticksToPixels( self, beats, ticks ):
- return int(round( ticks * self.pixelsPerTick[beats] ))
- def pitchToPixels( self, pitch ):
- return int(round( ( Config.MAXIMUM_PITCH - pitch ) * self.pixelsPerPitch ))
- def pitchToPixelsDrum( self, pitch ):
- return int(round( ( Config.MAXIMUM_PITCH_DRUM - pitch ) * self.pixelsPerPitchDrum ))
diff --git a/Edit/__init__.py b/Edit/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/Edit/__init__.py
+++ /dev/null
diff --git a/Edit/rm/BackgroundView.py b/Edit/rm/BackgroundView.py
deleted file mode 100644
index ff6e75f..0000000
--- a/Edit/rm/BackgroundView.py
+++ /dev/null
@@ -1,501 +0,0 @@
-import pygtk
-pygtk.require( '2.0' )
-import gtk
-
-from math import floor
-
-from Framework.Constants import Constants
-from GUI.GUIConstants import GUIConstants
-from GUI.Core.NoteParametersWindow import NoteParametersWindow
-
-from Framework.Core.Profiler import TP
-
-class SELECTNOTES:
- ALL = -1
- NONE = 0
- ADD = 1
- REMOVE = 2
- EXCLUSIVE = 3
-
-#-------------------------------------------------------------
-# This is a TEMPORARY implementaion of the BackgroundView,
-# it was written quickly to get track selections working
-#-------------------------------------------------------------
-
-# TODO: Do I really have to subclass gtk.EventBox to get the button-press-event?
-# (I wasn't getting it subclassing directly from DrawingArea)
-class BackgroundView( gtk.EventBox ):
- #-----------------------------------
- # initialization
- #-----------------------------------
- def __init__( self, trackIDs, selectedTrackIDs, selectionChangedCallback, mutedTrackIDs, beatsPerPageAdjustment, trackDictionary, selectedPageIDs, updatePageCallback ):
- gtk.EventBox.__init__( self )
-
- self.drawingArea = gtk.DrawingArea()
- self.add( self.drawingArea )
-
- self.sizeInitialized = False
-
- self.trackViews = {}
- self.trackIDs = trackIDs
- self.selectedTrackIDs = selectedTrackIDs
- self.selectionChangedCallback = selectionChangedCallback
- self.mutedTrackIDs = mutedTrackIDs
- self.beatsPerPageAdjustment = beatsPerPageAdjustment
- self.trackDictionary = trackDictionary
- self.selectedPageIDs = selectedPageIDs
- self.updatePageCallback = updatePageCallback
-
- self.curAction = False # stores the current mouse action
- self.curActionObject = False # stores the object that in handling the action
-
- self.buttonPressCount = 1 # used on release events to indicate double/triple releases
- self.clickLoc = [0,0] # location of the last click
- self.marqueeLoc = False # current drag location of the marquee
-
- self.drawingArea.connect( "expose-event", self.draw )
- self.connect( "button-press-event", self.handleButtonPress )
- self.connect( "button-release-event", self.handleButtonRelease )
- self.connect( "motion-notify-event", self.handleMotion )
-
- #-----------------------------------
- # access methods
- #-----------------------------------
- def getTrackRect( self, trackID ):
- return gtk.gdk.Rectangle( GUIConstants.BORDER_SIZE,
- self.getTrackYLocation( trackID ),
- self.getTrackWidth(),
- self.getTrackHeight() )
-
- def getTrackWidth( self ):
- return self.get_allocation().width - 2 * ( GUIConstants.BORDER_SIZE + 2 )
-
- def getFullHeight( self ):
- return int( floor( self.get_allocation().height / len( self.trackIDs ) ) )
-
- def getTrackHeight( self ):
- return int( self.getFullHeight() - 2 * self.getTrackSpacing() )
-
- #TODO-> trackIDs should probably be ordered!
- # we're just using trackID as an index here (this will only work until you can remove tracks)
- def getTrackYLocation( self, trackID ):
- if self.getTrackHeight() < 0:
- return 0
- else:
- trackIndex = trackID
-
- trackHeight = int( floor( self.get_allocation().height / len( self.trackIDs ) ) )
- trackBackgroundYValue = trackHeight * trackIndex
- return trackBackgroundYValue + GUIConstants.BORDER_SIZE
-
- def getTrackSpacing( self ):
- return GUIConstants.TRACK_SPACING
-
- #-----------------------------------
- # callback methods
- #-----------------------------------
- def set_size_request( self, width, height ):
- self.sizeInitialized = True
- self.drawingArea.set_size_request( width, height )
- self.height = height
- self.width = width
-
- numTracks = len(self.trackIDs)
- trackSpacing = self.getTrackSpacing()
- if numTracks: self.trackHeight = int( floor( (height - trackSpacing*(numTracks-1)) / numTracks ) )
- else: self.trackHeight = 1
- self.trackWidth = width
-
- trackCount = 0
- for trackID in self.trackIDs:
- self.trackViews[trackID].set_size_request( self.trackWidth, self.trackHeight )
- self.trackViews[trackID].setPositionOffset( (0, trackCount*(self.trackHeight+trackSpacing)) )
- trackCount += 1
-
- def setCurrentTracks( self, trackViews ):
-
- oldLen = len(self.trackViews)
-
- if oldLen and trackViews != self.trackViews: self.clearSelectedNotes() # clear all the currently selected notes
-
- self.trackViews = trackViews
-
- numTracks = len(self.trackViews)
- if oldLen != numTracks and self.sizeInitialized:
- trackSpacing = self.getTrackSpacing()
- if numTracks: self.trackHeight = int( floor( (self.height - trackSpacing*(numTracks-1)) / numTracks ) )
- else: self.trackHeight = 1
- trackCount = 0
- for trackID in self.trackIDs:
- self.trackViews[trackID].set_size_request( self.trackWidth, self.trackHeight )
- self.trackViews[trackID].setPositionOffset( (0, trackCount*(self.trackHeight+trackSpacing)) )
- trackCount += 1
-
- self.dirty()
-
-
- def getNoteParameters( self ):
- for trackID in self.selectedTrackIDs:
- for pageID in self.selectedPageIDs:
- for note in self.trackDictionary[ trackID ][ pageID ]:
- newPitch = note.pitch + self.noteParameters.pitchAdjust.value
- newAmplitude = note.amplitude * self.noteParameters.amplitudeAdjust.value
- newPan = self.noteParameters.panAdjust.value
- newReverbSend = note.reverbSend * self.noteParameters.reverbSendAdjust.value
- newAttack = self.noteParameters.attackAdjust.value
- newDecay = self.noteParameters.decayAdjust.value
- newFilterType = self.noteParameters.filterType
- newFilterCutoff = self.noteParameters.filterCutoff
- newTied = self.noteParameters.tied
- newOverlap = self.noteParameters.overlap
-
- note.pitch = self.noteParametersBoundaries( newPitch, note.pitch, Constants.MINIMUM_PITCH, Constants.MAXIMUM_PITCH )
- note.amplitude = self.noteParametersBoundaries( newAmplitude, note.amplitude, Constants.MINIMUM_AMPLITUDE, Constants.MAXIMUM_AMPLITUDE )
- note.reverbSend = self.noteParametersBoundaries( newReverbSend, note.reverbSend, Constants.MINIMUM_AMPLITUDE,
- Constants.MAXIMUM_AMPLITUDE )
- if newPan != note.pan:
- note.pan = newPan
-
- if newAttack != note.attack:
- note.attack = newAttack
-
- if newDecay != note.decay:
- note.decay = newDecay
-
- if newFilterType != note.filterType:
- note.filterType = newFilterType
-
- if newFilterCutoff != note.filterCutoff:
- note.filterCutoff = newFilterCutoff
-
- if newTied != note.tied:
- note.tied = newTied
-
- if newOverlap != note.overlap:
- note.overlap = newOverlap
-
- self.updatePageCallback()
-
- def noteParametersBoundaries( self, newValue, noteValue, minBoundary, maxBoundary ):
- if newValue != noteValue:
- if newValue >= minBoundary and newValue <= maxBoundary:
- return newValue
- elif newValue < minBoundary:
- return minBoundary
- elif newValue > maxBoundary:
- return maxBoundary
- else:
- return noteValue
-
- #-----------------------------------
- # action and event methods
- #-----------------------------------
- def setCurrentAction( self, action, obj ):
- if self.curAction:
- print "BackgroundView - Action already in progress!"
-
- self.curAction = action
- self.curActionObject = obj
-
- if action == "note-drag-onset": self.updateDragLimits()
- elif action == "note-drag-duration": self.updateDragLimits()
- elif action == "note-drag-pitch": self.updateDragLimits()
-
- def doneCurrentAction( self ):
- if self.curAction == "note-drag-onset": self.doneNoteDrag()
- elif self.curAction == "note-drag-duration": self.doneNoteDrag()
- elif self.curAction == "note-drag-pitch": self.doneNoteDrag()
-
- self.curAction = False
- self.curActionObject = False
-
- def toggleTrack( self, trackID, exclusive ):
- if exclusive:
- self.selectedTrackIDs.clear()
- self.selectedTrackIDs.add( trackID )
- else:
- if trackID in self.selectedTrackIDs:
- self.selectedTrackIDs.discard( trackID )
- else:
- self.selectedTrackIDs.add( trackID )
-
- def selectionChanged( self ):
- if self.curAction == "note-drag-onset": self.updateDragLimits()
- elif self.curAction == "note-drag-duration": self.updateDragLimits()
- elif self.curAction == "note-drag-pitch": self.updateDragLimits()
- self.dirty()
-
- def selectNotesByBar( self, selID, startX, stopX ):
- beatCount = int(round( self.beatsPerPageAdjustment.value, 0 ))
- for trackID in self.trackIDs:
- if trackID == selID:
- notes = self.trackViews[trackID].getNotesByBar( beatCount, startX, stopX )
- self.trackViews[trackID].selectNotes( SELECTNOTES.EXCLUSIVE, notes )
- else:
- self.trackViews[trackID].selectNotes( SELECTNOTES.NONE, [] )
- self.selectionChanged()
-
- def selectNotesByTrack( self, selID ):
- for trackID in self.trackIDs:
- if trackID == selID: self.trackViews[trackID].selectNotes( SELECTNOTES.ALL, [] )
- else: self.trackViews[trackID].selectNotes( SELECTNOTES.NONE, [] )
- self.selectionChanged()
-
- def selectNotes( self, noteDic ):
- for trackID in self.trackIDs:
- if trackID in noteDic: self.trackViews[trackID].selectNotes( SELECTNOTES.EXCLUSIVE, noteDic[trackID] )
- else: self.trackViews[trackID].selectNotes( SELECTNOTES.NONE, [] )
- self.selectionChanged()
-
- def addNotesToSelection( self, noteDic ):
- for trackID in self.trackIDs:
- if trackID in noteDic: self.trackViews[trackID].selectNotes( SELECTNOTES.ADD, noteDic[trackID] )
- self.selectionChanged()
-
- def deselectNotes( self, noteDic ):
- for trackID in self.trackIDs:
- if trackID in noteDic: self.trackViews[trackID].selectNotes( SELECTNOTES.REMOVE, noteDic[trackID] )
- self.selectionChanged()
-
- def clearSelectedNotes( self ):
- for trackID in self.trackIDs:
- self.trackViews[trackID].selectNotes( SELECTNOTES.NONE, [] )
- self.selectionChanged()
-
- def updateDragLimits( self ):
- self.dragLimits = [ [-9999,9999], [-9999,9999], [-9999,9999] ] # initialize to big numbers!
- for trackID in self.trackIDs:
- self.trackViews[trackID].updateDragLimits( self.dragLimits )
-
- def noteDragOnset( self, event ):
- dx = event.x - self.clickLoc[0]
- dx = min( self.dragLimits[0][1], max( self.dragLimits[0][0], dx ) )
- dy = 0
- dw = 0
-
- for trackID in self.trackIDs:
- self.trackViews[trackID].noteDrag( self, dx, dy, dw )
- self.dirty()
-
- def noteDragDuration( self, event ):
- dx = 0
- dy = 0
- dw = event.x - self.clickLoc[0]
- dw = min( self.dragLimits[2][1], max( self.dragLimits[2][0], dw ) )
-
- for trackID in self.trackIDs:
- self.trackViews[trackID].noteDrag( self, dx, dy, dw )
- self.dirty()
-
- def noteDragPitch( self, event ):
- dx = 0
- dy = event.y - self.clickLoc[1]
- dy = min( self.dragLimits[1][1], max( self.dragLimits[1][0], dy ) )
- dw = 0
-
- for trackID in self.trackIDs:
- self.trackViews[trackID].noteDrag( self, dx, dy, dw )
- self.dirty()
-
- def doneNoteDrag( self ):
- for trackID in self.trackIDs:
- self.trackViews[trackID].doneNoteDrag( self )
-
- def updateMarquee( self, event ):
- self.marqueeLoc = [ event.x, event.y ]
- parentRect = self.get_allocation()
- if self.marqueeLoc[0] < 0: self.marqueeLoc[0] = 0
- elif self.marqueeLoc[0] > parentRect.width: self.marqueeLoc[0] = parentRect.width
- if self.marqueeLoc[1] < 0: self.marqueeLoc[1] = 0
- elif self.marqueeLoc[1] > parentRect.height: self.marqueeLoc[1] = parentRect.height
-
- self.dirty()
-
- def doneMarquee( self, event ):
- if self.marqueeLoc:
- start = [ min(self.clickLoc[0],self.marqueeLoc[0]), \
- min(self.clickLoc[1],self.marqueeLoc[1]) ]
- stop = [ max(self.clickLoc[0],self.marqueeLoc[0]), \
- max(self.clickLoc[1],self.marqueeLoc[1]) ]
-
- select = {}
-
- trackSpacing = self.getTrackSpacing()
- trackTop = 0
- for trackID in self.trackIDs:
- notes = self.trackViews[trackID].handleMarqueeSelect( self, start, stop )
- if notes: select[trackID] = notes
- trackTop += self.trackHeight + trackSpacing
- if trackTop > stop[1]: break
-
- self.selectNotes( select )
-
- self.marqueeLoc = False
- self.doneCurrentAction()
-
- self.dirty()
-
- def handleButtonPress( self, drawingArea, event ):
-
- TP.ProfileBegin( "BV::handleButtonPress" )
-
- if event.type == gtk.gdk._2BUTTON_PRESS: self.buttonPressCount = 2
- elif event.type == gtk.gdk._3BUTTON_PRESS: self.buttonPressCount = 3
- else: self.buttonPressCount = 1
-
- self.clickLoc = [ event.x, event.y ]
-
- trackSpacing = self.getTrackSpacing()
- trackTop = 0
- for trackID in self.trackIDs:
- handled = self.trackViews[trackID].handleButtonPress( self, event )
- trackTop += self.trackHeight + trackSpacing
- if handled or trackTop > event.y: break
-
- if handled:
- if not self.curAction: self.curAction = True # it was handled maybe no action was declared, set curAction to True anyway
- TP.ProfileEnd( "BV::handleButtonPress" )
- return
-
- if event.button == 3:
- self.noteParameters = NoteParametersWindow( self.trackDictionary, self.getNoteParameters )
- self.setCurrentAction( "noteParameters", False )
-
- TP.ProfileEnd( "BV::handleButtonPress" )
-
-
- def handleButtonRelease( self, drawingArea, event ):
- TP.ProfileBegin( "BV::handleButtonRelease" )
-
- if not self.curAction: #do track selection stuff here so that we can also handle marquee selection
- trackSpacing = self.getTrackSpacing()
- trackTop = 0
- for trackID in self.trackIDs:
- handled = self.trackViews[trackID].handleButtonRelease( self, event, self.buttonPressCount )
- trackTop += self.trackHeight + trackSpacing
- if handled or trackTop > event.y: break
-
- if handled: self.dirty()
-
- TP.ProfileEnd( "BV::handleButtonRelease" )
- return
-
- if not self.curActionObject: # there was no real action to carry out
- self.curAction = False
- TP.ProfileEnd( "BV::handleButtonRelease" )
- return
-
- if self.curActionObject != self:
- if self.curActionObject.handleButtonRelease( self, event, self.buttonPressCount ):
- self.dirty()
- TP.ProfileEnd( "BV::handleButtonRelease" )
- return
-
-
- # we're doing the action ourselves
-
- if self.curAction == "marquee": self.doneMarquee( event )
-
- TP.ProfileEnd( "BV::handleButtonRelease" )
- return
-
- def handleMotion( self, drawingArea, event ):
- TP.ProfileBegin( "BV::handleMotion" )
-
- if not self.curAction: # no action is in progress yet we're dragging, start a marquee
- self.setCurrentAction( "marquee", self )
-
- if self.curAction == "note-drag-onset":
- self.noteDragOnset( event )
- TP.ProfileEnd( "BV::handleMotion" )
- return
-
- if self.curAction == "note-drag-duration":
- self.noteDragDuration( event )
- TP.ProfileEnd( "BV::handleMotion" )
- return
-
- if self.curAction == "note-drag-pitch":
- self.noteDragPitch( event )
- TP.ProfileEnd( "BV::handleMotion" )
- return
-
- # we're doing the action ourselves
-
- if self.curAction == "marquee": self.updateMarquee( event )
-
- TP.ProfileEnd( "BV::handleMotion" )
- return
-
- def TEMPOLDSTUFF(self):
-
- #TODO change this to accomodate the space between tracks
- trackHeight = ( drawingArea.get_allocation().height - 1 ) / len( self.trackIDs )
- trackID = int( floor( event.y / trackHeight ) )
-
- if event.type == gtk.gdk.BUTTON_PRESS:
- #single click toggles track selection
- if trackID in self.selectedTrackIDs:
- self.selectedTrackIDs.discard( trackID )
- else:
- self.selectedTrackIDs.add( trackID )
- elif event.type == gtk.gdk._2BUTTON_PRESS:
- #double click selects a single track
- self.selectedTrackIDs.clear()
- self.selectedTrackIDs.add( trackID )
-
- self.drawingArea.queue_draw()
- self.selectionChangedCallback()
- if event.button == 3:
- self.noteParameters = NoteParametersWindow( self.trackDictionary, self.getNoteParameters )
-
- #-----------------------------------
- # drawing methods
- #-----------------------------------
- def draw( self, drawingArea, event ):
- TP.ProfileBegin( "BackgroundView::draw" )
-
- context = drawingArea.window.cairo_create()
- context.set_antialias(0) # I don't know what to set this to to turn it off, and it doesn't seem to work anyway!?
-
- #parentRect = self.get_allocation()
-
- beatCount = int(round( self.beatsPerPageAdjustment.value, 0 ))
-
- for trackID in self.trackIDs:
- self.trackViews[trackID].draw( context,
- beatCount,
- trackID in self.selectedTrackIDs )
-
- # if self.curAction == "note-drag": # draw a cross at clickLoc
- # lineW = 1
- # context.set_line_width( lineW )
- # lineWDIV2 = lineW/2.0
- # context.set_source_rgb( 1, 1, 1 )
-
- # context.move_to( self.clickLoc[0] + lineWDIV2 - 3, self.clickLoc[1] + lineWDIV2 )
- # context.rel_line_to( 6, 0 )
- # context.stroke()
- # context.move_to( self.clickLoc[0] + lineWDIV2, self.clickLoc[1] + lineWDIV2 - 3)
- # context.rel_line_to( 0, 6 )
- # context.stroke()
-
- if self.marqueeLoc: # draw the selection rect
- lineW = 1
- context.set_line_width( lineW )
- lineWDIV2 = lineW/2.0
-
- context.move_to( self.clickLoc[0] + lineWDIV2, self.clickLoc[1] + lineWDIV2 )
- context.line_to( self.marqueeLoc[0] + lineWDIV2, self.clickLoc[1] + lineWDIV2 )
- context.line_to( self.marqueeLoc[0] + lineWDIV2, self.marqueeLoc[1] + lineWDIV2 )
- context.line_to( self.clickLoc[0] + lineWDIV2, self.marqueeLoc[1] + lineWDIV2 )
- context.close_path()
- context.set_source_rgb( 1, 1, 1 )
- context.stroke()
-
- TP.ProfileEnd( "BackgroundView::draw" )
-
- def dirty( self ):
- self.queue_draw()
-
-
diff --git a/Edit/rm/NoteView.py b/Edit/rm/NoteView.py
deleted file mode 100644
index ac139a1..0000000
--- a/Edit/rm/NoteView.py
+++ /dev/null
@@ -1,253 +0,0 @@
-import pygtk
-pygtk.require( '2.0' )
-import gtk
-
-from Framework.Constants import Constants
-from Framework.CSound.CSoundConstants import CSoundConstants
-from GUI.GUIConstants import GUIConstants
-from GUI.Core.NoteParametersWindow import NoteParametersWindow
-
-from BackgroundView import SELECTNOTES
-
-#----------------------------------------------------------------------
-# TODO: currently we are only using CSoundNotes,
-# - this should updated to handle generic Note objects
-#----------------------------------------------------------------------
-
-#----------------------------------------------------------------------
-# A view for the (CSound)Note class
-#----------------------------------------------------------------------
-class NoteView:
- #-----------------------------------
- # initialization
- # TODO: not sure if passing in beatsPerPageAdjustment is the best way to go about it
- #-----------------------------------
- def __init__( self, note, track, beatsPerPageAdjustment ):
- self.note = note
-
- self.track = track
- self.beatsPerPageAdjustment = beatsPerPageAdjustment
- self.posOffset = (0,0)
-
- self.baseOnset = self.basePitch = self.baseDuration = self.lastDragX = self.lastDragY = self.lastDragW = 0 # note dragging properties
-
- self.sampleNote = None
-
- self.parentSize = False
-
- self.selected = False
- self.potentialDeselect = False
-
-
- def getNoteParameters( self ):
- self.note.pitch = self.noteParameters.pitchAdjust.value
- self.note.amplitude = self.noteParameters.amplitudeAdjust.value
- self.note.pan = self.noteParameters.panAdjust.value
- self.note.attack = self.noteParameters.attackAdjust.value
- self.note.decay = self.noteParameters.decayAdjust.value
- self.note.reverbSend = self.noteParameters.reverbSendAdjust.value
- self.note.filterType = self.noteParameters.filterType
- self.note.filterCutoff = self.noteParameters.filterCutoff
- self.note.tied = self.noteParameters.tied
- self.note.overlap = self.noteParameters.overlap
-
- def handleButtonPress( self, emitter, event ):
- eX = event.x - self.x
- eY = event.y - self.y
-
- if eX < 0 or eX > self.width \
- or eY < 0 or eY > self.height:
- return False
-
- if event.button == 3:
- self.noteParameters = NoteParametersWindow( self.note, self.getNoteParameters )
- return True
-
- if event.type == gtk.gdk._2BUTTON_PRESS: # select bar
- self.potentialDeselect = False
- emitter.selectNotesByBar( self.track.getID(), self.x, self.x+self.width )
- elif event.type == gtk.gdk._3BUTTON_PRESS: # select track
- self.potentialDeselect = False
- emitter.selectNotesByTrack( self.track.getID() )
- else:
- if self.getSelected(): # we already selected, might want to delected
- self.potentialDeselect = True
- else:
- emitter.selectNotes( { self.track.getID(): [ self ] } )
- self.updateSampleNote( self.note.pitch )
-
- percent = eX/self.width
- if percent < 0.3: emitter.setCurrentAction( "note-drag-onset", self )
- elif percent > 0.7: emitter.setCurrentAction( "note-drag-duration", self )
- else: emitter.setCurrentAction( "note-drag-pitch", self )
-
-
- emitter.dirty()
-
- return True
-
- def handleButtonRelease( self, emitter, event, buttonPressCount ):
-
- if self.potentialDeselect:
- self.potentialDeselect = False
- emitter.deselectNotes( { self.track.getID(): [ self ] } )
-
- self.clearSampleNote()
-
- emitter.doneCurrentAction()
-
- return True
-
- def noteDrag( self, emitter, dx, dy, dw ):
- self.potentialDeselect = False
-
- ticksPerPixel = (round( self.beatsPerPageAdjustment.value, 0 ) * Constants.TICKS_PER_BEAT) / self.parentSize[0]
- stepPerPixel = (Constants.NUMBER_OF_POSSIBLE_PITCHES-1) / (self.parentSize[1] - self.height)
- pitchPerStep = (Constants.MAXIMUM_PITCH-Constants.MINIMUM_PITCH)/(Constants.NUMBER_OF_POSSIBLE_PITCHES-1)
-
- if dx != self.lastDragX:
- self.lastDragX = dx
- self.note.onset = self.baseOnset + int(dx*ticksPerPixel)
-
- if dy != self.lastDragY:
- self.lastDragY = dy
- newPitch = self.basePitch + round(-dy*stepPerPixel)*pitchPerStep
- self.note.pitch = newPitch
- self.updateSampleNote( newPitch )
-
- if dw != self.lastDragW:
- self.lastDragW = dw
- self.note.duration = self.baseDuration + int(dw*ticksPerPixel)
-
- self.updateTransform( False )
-
- def doneNoteDrag( self, emitter ):
- self.baseOnset = self.note.onset
- self.basePitch = self.note.pitch
- self.baseDuration = self.note.duration
-
- self.lastDragX = 0
- self.lastDragY = 0
- self.lastDragW = 0
-
- self.clearSampleNote()
-
-
- def handleMarqueeSelect( self, emitter, start, stop ):
- intersectionY = [ max(start[1],self.y), min(stop[1],self.y+self.height) ]
- if intersectionY[0] > intersectionY[1]:
- return False
-
- intersectionX = [ max(start[0],self.x), min(stop[0],self.x+self.width) ]
- if intersectionX[0] > intersectionX[1]:
- return False
-
- return True
-
- #-----------------------------------
- # draw
- #-----------------------------------
-
- def setPositionOffset( self, offset ):
- self.posOffset = offset
- if self.parentSize: self.updateTransform( False )
-
- def draw( self, context ):
- lineW = GUIConstants.NOTE_BORDER_SIZE
- lineWDIV2 = lineW/2.0
- context.set_line_width( lineW )
-
- context.move_to( self.x + lineWDIV2, self.y + lineWDIV2 )
- context.rel_line_to( self.width - lineW, 0 )
- context.rel_line_to( 0, self.height - lineW )
- context.rel_line_to( -self.width + lineW, 0 )
- context.close_path()
-
- #background
- colour = 1 - ( ( self.note.amplitude * 0.7 ) + 0.3 )
- context.set_source_rgb( colour, colour, colour )
- context.fill_preserve()
-
- #border
- if self.selected: context.set_source_rgb( 1, 1, 1 )
- else: context.set_source_rgb( 0, 0, 0 )
- context.stroke()
-
- #-----------------------------------
- # update
- #-----------------------------------
-
- def updateTransform( self, parentSize ):
- if parentSize: self.parentSize = parentSize
- self.width = int( self.parentSize[0] * self.note.duration / (round( self.beatsPerPageAdjustment.value, 0 ) * Constants.TICKS_PER_BEAT) )
- self.height = round( max( GUIConstants.MINIMUM_NOTE_HEIGHT, self.parentSize[1] / (Constants.NUMBER_OF_POSSIBLE_PITCHES-1) ) )
- self.x = int( self.parentSize[0] * self.note.onset / (round( self.beatsPerPageAdjustment.value, 0 ) * Constants.TICKS_PER_BEAT) ) \
- + self.posOffset[0]
- self.y = round( (self.parentSize[1]-self.height) * ( Constants.MAXIMUM_PITCH - self.note.pitch ) / (Constants.NUMBER_OF_POSSIBLE_PITCHES-1) ) \
- + self.posOffset[1]
-
- def checkX( self, startx, stopx ):
- if self.x >= startx and self.x < stopx: return True
- else: return False
-
- def getStartTick( self ):
- return self.note.onset
-
- def getEndTick( self ):
- return self.note.onset + self.note.duration
-
- def updateDragLimits( self, dragLimits, leftBound, rightBound, widthBound ):
- pixelsPerTick = self.parentSize[0] / (round( self.beatsPerPageAdjustment.value, 0 ) * Constants.TICKS_PER_BEAT)
- pixelsPerPitch = (self.parentSize[1] - self.height) / (Constants.MAXIMUM_PITCH - Constants.MINIMUM_PITCH)
- left = (leftBound - self.note.onset) * pixelsPerTick
- right = (rightBound - self.note.duration - self.note.onset) * pixelsPerTick
- up = (self.note.pitch - Constants.MAXIMUM_PITCH) * pixelsPerPitch
- down = (self.note.pitch - Constants.MINIMUM_PITCH) * pixelsPerPitch
- short = (Constants.MINIMUM_NOTE_DURATION - self.note.duration) * pixelsPerTick
- long = (widthBound - self.note.duration - self.note.onset) * pixelsPerTick
-
- if dragLimits[0][0] < left: dragLimits[0][0] = left
- if dragLimits[0][1] > right: dragLimits[0][1] = right
- if dragLimits[1][0] < up: dragLimits[1][0] = up
- if dragLimits[1][1] > down: dragLimits[1][1] = down
- if dragLimits[2][0] < short: dragLimits[2][0] = short
- if dragLimits[2][1] > long: dragLimits[2][1] = long
-
- # store the current loc as a reference point
- self.baseOnset = self.note.onset
- self.basePitch = self.note.pitch
- self.baseDuration = self.note.duration
-
- def updateSampleNote( self, pitch ):
- if self.sampleNote == None:
- self.sampleNote = self.note.clone()
- #TODO clean this up:
- if CSoundConstants.INSTRUMENTS[ self.sampleNote.instrumentFlag ].csoundInstrumentID == 103:
- self.sampleNote.duration = 100
- else:
- self.sampleNote.duration = -1
- self.sampleNote.play()
-
- elif self.sampleNote.pitch != pitch:
- self.sampleNote.pitch = pitch
- self.sampleNote.play()
-
- def clearSampleNote( self ):
- if self.sampleNote != None:
- self.sampleNote.duration = 0
- self.sampleNote.play()
- del self.sampleNote
- self.sampleNote = None
-
- #-----------------------------------
- # Selection
- #-----------------------------------
-
- def setSelected( self, state ):
- if self.selected != state:
- self.selected = state
- return True # state changed
- return False # state is the same
-
- def getSelected( self ):
- return self.selected
diff --git a/Edit/rm/PageBankView.py b/Edit/rm/PageBankView.py
deleted file mode 100644
index fedadef..0000000
--- a/Edit/rm/PageBankView.py
+++ /dev/null
@@ -1,85 +0,0 @@
-import pygtk
-pygtk.require( '2.0' )
-import gtk
-
-from GUI.GUIConstants import GUIConstants
-from GUI.Core.PageView import PageView
-
-class PageBankView( gtk.Frame ):
-
- NO_PAGE = -1
-
- def __init__( self, selectPageCallback, pageDropCallback ):
- gtk.Frame.__init__( self )
- self.table = gtk.Table( 1, GUIConstants.NUMBER_OF_PAGE_BANK_COLUMNS )
- self.add( self.table )
- self.drag_dest_set( gtk.DEST_DEFAULT_ALL, [ ( "tune page", gtk.TARGET_SAME_APP, 11 )], gtk.gdk.ACTION_COPY|gtk.gdk.ACTION_MOVE )
- self.connect( "drag_data_received", self.dragDataReceived )
- self.selectPageCallback = selectPageCallback
- self.pageDropCallback = pageDropCallback
- self.selectedPageIds = set([])
- self.pageIndexDictionary = {}
- self.pageViews = {}
-
- def dragDataReceived( self, widget, context, x, y, selectionData, info, time):
- self.pageDropCallback( selectionData.data )
-
- def addPage( self, pageId, invokeCallback = True ):
- pageIndex = len( self.pageViews.keys() )
- self.pageIndexDictionary[ pageIndex ] = pageId
-
- #TODO: resize table to suit number of pages?
- #if pageIndex > ( self.table.n-rows * self.table.n_columns ):
- # self.table.resize( self.table.n_rows + 1, self.table.n_columns )
-
- pageView = PageView( pageIndex, self.selectPage, True )
- self.pageViews[ pageIndex ] = pageView
-
- columnIndex = pageIndex % GUIConstants.NUMBER_OF_PAGE_BANK_COLUMNS
- rowIndex = int( pageIndex / GUIConstants.NUMBER_OF_PAGE_BANK_COLUMNS )
- self.table.attach( pageView, columnIndex, columnIndex + 1, rowIndex, rowIndex + 1, gtk.SHRINK, gtk.SHRINK )
-
- self.updateSize( pageView )
-
- pageView.drag_source_set( gtk.gdk.BUTTON1_MASK,
- [ ( "bank page", gtk.TARGET_SAME_APP, 10 ) ],
- gtk.gdk.ACTION_COPY )
-
- self.selectPage( pageId, True, invokeCallback )
-
- pageView.show()
-
- def set_size_request( self, width, height ):
- gtk.Frame.set_size_request( self, width, height )
- self.table.set_size_request( width, height )
- for pageId in self.pageViews.keys():
- self.updateSize( self.pageViews[ pageId ] )
-
- def updateSize( self, pageView ):
- pageView.set_size_request( self.get_allocation().width / GUIConstants.NUMBER_OF_PAGE_BANK_COLUMNS,
- GUIConstants.PAGE_HEIGHT - 1 )
-
- def selectPage( self, selectedPageId, invokeCallback = True, deselectOthers = True ):
- if deselectOthers:
- for pageId in self.pageViews.keys():
- self.pageViews[ pageId ].setSelected( pageId == selectedPageId )
- if pageId != selectedPageId:
- self.selectedPageIds.discard( pageId )
- else:
- self.selectedPageIds.add( pageId )
- #nb: pageId might be NO_PAGE, and selectedPageIds can be empty here
-
- else:
- self.pageViews[ selectedPageId ].toggleSelected()
- if self.pageViews[ selectedPageId ].selected:
- self.selectedPageIds.add( selectedPageId )
- else:
- self.selectedPageIds.discard( selectedPageId )
-
- if invokeCallback:
- self.selectPageCallback( selectedPageId )
-
- def getSelectedPageIds( self ):
- rval = filter( lambda id: self.pageViews[id].selected == True, self.pageViews.keys())
- return rval
-
diff --git a/Edit/rm/PageView.py b/Edit/rm/PageView.py
deleted file mode 100644
index 00b650b..0000000
--- a/Edit/rm/PageView.py
+++ /dev/null
@@ -1,65 +0,0 @@
-import pygtk
-pygtk.require( '2.0' )
-import gtk
-
-import pango
-
-from GUI.GUIConstants import GUIConstants
-
-class PageView( gtk.DrawingArea ):
- def __init__( self, pageID, selectPageCallback, selected = False ):
- gtk.DrawingArea.__init__( self )
-
- self.pageID = pageID
- self.selectPageCallback = selectPageCallback
- self.selected = selected
-
- self.add_events( gtk.gdk.BUTTON_PRESS_MASK )
-
- self.connect( "expose-event", self.handleExposeEvent )
- self.connect( "button-press-event", self.handleButtonPress )
- self.connect( "drag_data_get", self.getData )
-
- def handleButtonPress( self, widget, event ):
- if event.button == 1 or event.button == 3:
- self.selectPageCallback( self.pageID, event.button == 1 )
-
- def getData( self, widget, context, selection, targetType, eventTime ):
- return selection.set( gtk.gdk.SELECTION_PRIMARY, 32, "p %d" % self.pageID )
-
- def toggleSelected( self ):
- self.selected = not self.selected
- self.queue_draw()
-
- def setSelected( self, selected ):
- if self.selected != selected:
- self.selected = selected
- self.queue_draw()
-
- # TODO: this is temporary: replace with a visual representation of the page
- def handleExposeEvent( self, drawingArea, event ):
- size = self.get_allocation()
- context = self.window.cairo_create()
-
- if self.selected:
- context.set_line_width( GUIConstants.PAGE_SELECTED_BORDER_SIZE )
- else:
- context.set_line_width( GUIConstants.PAGE_BORDER_SIZE )
- context.move_to( 0, 0 )
- context.rel_line_to( size.width, 0 )
- context.rel_line_to( 0, size.height )
- context.rel_line_to( -size.width, 0 )
- context.close_path()
-
- #blue background
- context.set_source_rgb( 0.75, 0.75, 0.75 )
- context.fill_preserve()
-
- #black border
- context.set_source_rgb( 0, 0, 0 )
- context.stroke()
-
- #text
- layout = self.create_pango_layout( "%d" % ( self.pageID + 1 ) )
- layout.set_font_description( pango.FontDescription( 'Sans 10' ) )
- self.window.draw_layout( self.window.new_gc(), 5, 5, layout )
diff --git a/Edit/rm/PositionIndicator.py b/Edit/rm/PositionIndicator.py
deleted file mode 100644
index aadc4f4..0000000
--- a/Edit/rm/PositionIndicator.py
+++ /dev/null
@@ -1,47 +0,0 @@
-import pygtk
-pygtk.require( '2.0' )
-import gtk
-
-#----------------------------------------------------------------------
-# A verical bar used to show the current point in time on a page
-# TODO: modify this class to change the current point in time
-# on click and drag
-#----------------------------------------------------------------------
-class PositionIndicator( gtk.DrawingArea ):
- #-----------------------------------
- # initialization
- #-----------------------------------
- def __init__( self, trackIDs, selectedTrackIDs, mutedTrackIDs ):
- gtk.DrawingArea.__init__( self )
-
- self.trackIDs = trackIDs
- self.selectedTrackIDs = selectedTrackIDs
- self.mutedTrackIDs = mutedTrackIDs
-
- self.connect( "expose-event", self.draw )
-
- def draw( self, drawingArea, event ):
- indicatorSize = self.get_allocation()
- trackHeight = indicatorSize.height / len( self.trackIDs )
-
- context = drawingArea.window.cairo_create()
-
- trackIndex = 0
- for trackID in self.trackIDs:
- height = trackIndex * trackHeight
-
- context.move_to( 0, height )
- context.rel_line_to( indicatorSize.width, 0 )
- context.rel_line_to( 0, height + trackHeight )
- context.rel_line_to( -indicatorSize.width, 0 )
- context.close_path()
-
- if trackID not in self.mutedTrackIDs:
- context.set_source_rgb( 0, 0, 0 ) #black
- else:
- context.set_source_rgb( 0.6, 0.6, 0.6 ) #grey
-
- context.fill_preserve()
- context.stroke()
-
- trackIndex += 1 \ No newline at end of file
diff --git a/Edit/rm/TrackView.py b/Edit/rm/TrackView.py
deleted file mode 100644
index 0b66abd..0000000
--- a/Edit/rm/TrackView.py
+++ /dev/null
@@ -1,263 +0,0 @@
-import pygtk
-pygtk.require( '2.0' )
-import gtk
-
-from Framework.Constants import Constants
-from GUI.GUIConstants import GUIConstants
-
-from BackgroundView import SELECTNOTES
-from NoteView import NoteView
-
-
-#----------------------------------------------------------------------
-# This view class is used to show the contents of a NoteTrack
-# i.e. a Collection of Note objects
-#----------------------------------------------------------------------
-class TrackView:
- #-----------------------------------
- # initialization functions
- #-----------------------------------
- def __init__( self, trackID, beatsPerPageAdjustment ):
- self.trackID = trackID
- self.beatsPerPageAdjustment = beatsPerPageAdjustment
- self.noteViews = []
- self.posOffset = (0,0)
- self.selectedNotes = []
-
- def getID( self ):
- return self.trackID
-
- #-----------------------------------
- # modification methods
- #-----------------------------------
- def setNotes( self, notes ):
- self.clearNotes()
-
- lineW = self.getBorderWidth()
-
- for note in notes:
- noteView = NoteView( note, self, self.beatsPerPageAdjustment )
- self.noteViews.append( noteView )
- noteView.setPositionOffset( (self.posOffset[0]+lineW, self.posOffset[1]+lineW ) )
-
- self.updateNoteTransforms()
-
- def clearNotes( self ):
- del self.noteViews
- self.noteViews = []
- self.selectedNotes = []
-
- def selectNotes( self, mode, which ):
- if mode == SELECTNOTES.ALL:
- for note in self.noteViews: note.setSelected( True )
- self.selectedNotes = self.noteViews[:]
- elif mode == SELECTNOTES.NONE:
- for note in self.noteViews: note.setSelected( False )
- self.selectedNotes = []
- elif mode == SELECTNOTES.ADD:
- for note in which:
- if note.setSelected( True ):
- self.selectedNotes.insert( 0, note )
- elif mode == SELECTNOTES.REMOVE:
- for note in which:
- if note.setSelected( False ):
- self.selectedNotes.remove( note )
- elif mode == SELECTNOTES.EXCLUSIVE:
- for note in self.noteViews:
- if note in which:
- if note.setSelected( True ):
- self.selectedNotes.insert( 0, note )
- else:
- if note.setSelected( False ):
- self.selectedNotes.remove( note )
-
- def updateDragLimits( self, dragLimits ):
- if not len(self.selectedNotes): return # no selected notes here
-
- leftBound = 0
- maxRightBound = round( self.beatsPerPageAdjustment.value, 0 ) * Constants.TICKS_PER_BEAT
- last = len(self.noteViews)-1
- for i in range(0,last):
- if not self.noteViews[i].getSelected():
- leftBound = self.noteViews[i].getEndTick()
- else:
- if not self.noteViews[i+1].getSelected():
- rightBound = min( self.noteViews[i+1].getStartTick(), maxRightBound )
- widthBound = rightBound
- else:
- rightBound = maxRightBound
- widthBound = min( self.noteViews[i+1].getStartTick(), maxRightBound )
- self.noteViews[i].updateDragLimits( dragLimits, leftBound, rightBound, widthBound )
- if self.noteViews[last].getSelected():
- self.noteViews[last].updateDragLimits( dragLimits, leftBound, maxRightBound, maxRightBound )
-
- def getNotesByBar( self, beatCount, startX, stopX ):
- beatWidth = self.getBeatLineSpacing( beatCount )
- beatStart = self.getBeatLineStart()
- while beatStart+beatWidth <= startX:
- beatStart += beatWidth
- beatStop = beatStart + beatWidth
- while beatStop+beatWidth < stopX:
- beatStop += beatWidth
-
- notes = []
- for note in self.noteViews:
- if note.checkX( beatStart, beatStop ):
- notes.insert(0,note)
- return notes
-
- #-----------------------------------
- # event methods
- #-----------------------------------
-
- def handleButtonPress( self, emitter, event ):
- eX = event.x - self.posOffset[0]
- eY = event.y - self.posOffset[1]
- if eX < 0 or eX > self.width or eY < 0 or eY > self.height:
- return False
-
- for note in self.noteViews:
- handled = note.handleButtonPress( emitter, event )
- if handled: return handled
-
- return False
-
- def handleButtonRelease( self, emitter, event, buttonPressCount ):
- eX = event.x - self.posOffset[0]
- eY = event.y - self.posOffset[1]
-
- if eX < 0 or eX > self.width or eY < 0 or eY > self.height:
- return False
-
- if event.button == 1:
- if buttonPressCount == 1: emitter.toggleTrack( self.trackID, False )
- else: emitter.toggleTrack( self.trackID, True )
-
- return True
-
- def handleMarqueeSelect( self, emitter, start, stop ):
- intersectionY = [ max(start[1],self.posOffset[1]), min(stop[1],self.posOffset[1]+self.height) ]
- if intersectionY[0] > intersectionY[1]:
- return False
-
- intersectionX = [ max(start[0],self.posOffset[0]), min(stop[0],self.posOffset[0]+self.width) ]
- if intersectionX[0] > intersectionX[1]:
- return False
-
-
- hits = []
- for note in self.noteViews:
- hit = note.handleMarqueeSelect( emitter,
- [ intersectionX[0], intersectionY[0] ], \
- [ intersectionX[1], intersectionY[1] ] )
- if hit: hits.insert(0,note)
-
- if len(hits): return hits
-
- return False
-
- def noteDrag( self, emitter, dx, dy, dw ):
- for note in self.selectedNotes:
- note.noteDrag( emitter, dx, dy, dw )
-
- def doneNoteDrag( self, emitter ):
- for note in self.selectedNotes:
- note.doneNoteDrag( emitter )
-
- #-----------------------------------
- # drawing methods
- #-----------------------------------
-
- def getBorderWidth( self ): #should return a constant value, otherwise we have to recalculate sizing and positioning everyframe!
- return GUIConstants.BORDER_SIZE
-
- def getBeatLineWidth( self ):
- return GUIConstants.BEAT_LINE_SIZE #should return a constant value, otherwise we have to recalculate sizing and positioning everyframe!
-
- def getBeatLineSpacing( self, beatCount ):
- return (self.width - 2*self.getBorderWidth() + self.getBeatLineWidth())/beatCount
-
- def getBeatLineStart( self ):
- return self.posOffset[0] + self.getBorderWidth() - self.getBeatLineWidth()/2.0
-
- def setPositionOffset( self, offset ):
- self.posOffset = offset
-
- lineW = self.getBorderWidth()
- for note in self.noteViews:
- note.setPositionOffset( ( self.posOffset[0]+lineW, self.posOffset[1]+lineW ) )
-
- def draw( self, context, beatCount, selected ):
- #if selected: lineW = GUIConstants.SELECTED_BORDER_SIZE
- #else: lineW = GUIConstants.BORDER_SIZE
- lineW = self.getBorderWidth()
- context.set_line_width( lineW )
- lineWDIV2 = lineW/2.0
-
- context.move_to( self.posOffset[0] + lineWDIV2, self.posOffset[1] + lineWDIV2 )
- context.rel_line_to( self.width - lineW, 0 )
- context.rel_line_to( 0, self.height - lineW )
- context.rel_line_to( -self.width + lineW, 0 )
- context.close_path()
-
- #draw the background
- context.set_source_rgb( 0.75, 0.75, 0.75 )
- context.fill_preserve()
-
- #draw the border
- if selected: context.set_source_rgb( 1, 1, 1 )
- else: context.set_source_rgb( 0, 0, 0 )
- context.stroke()
-
- #draw the beat lines
- beatLineWidth = self.getBeatLineWidth()
- context.set_line_width( beatLineWidth )
- beatWidth = self.getBeatLineSpacing( beatCount )
- beatStart = self.getBeatLineStart()
- context.set_source_rgb( 0, 0, 0 )
- for i in range(1,beatCount):
- context.move_to( beatStart + i*beatWidth, self.posOffset[1] + lineW )
- context.rel_line_to( 0, self.height - 2*lineW )
- context.stroke()
-
- #draw the notes
- for note in self.noteViews:
- note.draw( context )
-
- #-----------------------------------
- # sizing methods
- #-----------------------------------
-
- def updateNoteTransforms( self ):
- width = self.width - 2*self.getBorderWidth()
- height = self.height - 2*self.getBorderWidth() # adjust for actual note drawing area
- for noteView in self.noteViews:
- noteView.updateTransform( (width, height) )
-
- def set_size_request( self, width, height ):
- self.width = width
- self.height = height
- self.updateNoteTransforms()
-
-
-#unused for now...
-class NoteViewPool:
- def __init__( self, parentContainer, beatsPerPageAdjustment ):
- self.parentContainer = parentContainer
- self.beatsPerPageAdjustment = beatsPerPageAdjustment
- self.pool = []
-
- def addNoteView( self, noteView ):
- #noteView.hide()
- self.pool.append( noteView )
-
- def addNoteViews( self, noteViews ):
- for noteView in noteViews:
- self.addNoteView( noteView )
-
- def getNoteView( self ):
- poolSize = len( pool )
- if poolSize != 0:
- return pool.pop( poolSize )
-
- return NoteView( None, self.parentContainer, self.beatsPerPageAdjustment )
diff --git a/Edit/rm/TunePageView.py b/Edit/rm/TunePageView.py
deleted file mode 100644
index 501504f..0000000
--- a/Edit/rm/TunePageView.py
+++ /dev/null
@@ -1,17 +0,0 @@
-import pygtk
-pygtk.require( '2.0' )
-import gtk
-
-from PageView import PageView
-
-class TunePageView( PageView ):
- def __init__( self, pageID, tuneIndex, selectPageCallback, selected = False ):
- PageView.__init__( self, pageID, selectPageCallback, selected )
-
- self.pageIndex = tuneIndex
-
- def handleButtonPress( self, widget, data ):
- self.selectPageCallback( self.tuneIndex )
-
- def getData( self, widget, context, selection, targetType, eventTime ):
- return selection.set( gtk.gdk.SELECTION_PRIMARY, 32, "t %d %d" % (self.pageID,self.pageIndex) )
diff --git a/Edit/rm/TuneView.py b/Edit/rm/TuneView.py
deleted file mode 100644
index 63cf468..0000000
--- a/Edit/rm/TuneView.py
+++ /dev/null
@@ -1,123 +0,0 @@
-import pygtk
-pygtk.require( '2.0' )
-import gtk
-
-from GUI.GUIConstants import GUIConstants
-from GUI.Core.TunePageView import TunePageView
-
-def swap(l,i,j):
- e = l[i]
- l[i] = l[j]
- l[j] = e
-
-class TuneView( gtk.ScrolledWindow ):
-
- NO_PAGE = -1
-
- def _page_width(self):
- return self.pageContainer.get_allocation().width / GUIConstants.NUMBER_OF_PAGE_BANK_COLUMNS
-
- def __init__( self, selectPageCallback ):
- gtk.ScrolledWindow.__init__( self )
-
- #selectPageCallback(): currently connected to pagePlayer.setPlayTune, which skips to a given page of the tune.
- self.selectPageCallback = selectPageCallback
- self.selectedPageIndex = self.NO_PAGE
-
- self.set_policy( gtk.POLICY_ALWAYS, gtk.POLICY_AUTOMATIC )
- self.set_placement( gtk.CORNER_TOP_LEFT )
-
- #self.pageViews: list of our custom PageView widgets
- self.pageViews = []
- self.pageContainer = gtk.HBox( False )
- self.add_with_viewport( self.pageContainer )
-
- #the old part
- self.pageContainer.drag_dest_set( gtk.DEST_DEFAULT_ALL,
- [ ( "bank page", gtk.TARGET_SAME_APP, 10 ),
- ( "tune page", gtk.TARGET_SAME_APP, 11 )],
- gtk.gdk.ACTION_COPY|gtk.gdk.ACTION_MOVE )
-
- self.pageContainer.connect( "drag_data_received", self.dragDataReceived )
-
- #private method: called by gtk when pages get dragged onto the tune-view
- def dragDataReceived( self, widget, context, x, y, selectionData, info, time ):
- print 'dragDataReceived: ', selectionData.data, info, selectionData.data
- recv = selectionData.data.split()
- if recv[0] == 'p':
- pageId = int( recv[1] )
- self.addPage( pageId, min( x / self._page_width(), len( self.pageViews )) )
- elif recv[0] == 't':
- self.moveSelectedPage( min( x / self._page_width(), len( self.pageViews ) -1))
- else:
- raise 'ERROR'
-
- #public method: called by MainWindow on file load
- def syncFromPagePlayer(self):
- raise 'never call this'
- map( lambda pv:pv.destroy(), self.pageViews )
- self.pageViews = []
- tunePages = self.tunePagesCallback()
- for i in range( len(tunePages)):
- self.addPage( tunePages[i], i, False)
-
-
- def addPage( self, pageID, position ):
- #create a new widget
- pageView = TunePageView( pageID, position, self.selectPage )
- self.pageViews.insert( position, pageView )
- self.pageContainer.pack_start( pageView, False )
- self.pageContainer.reorder_child( pageView, position )
-
- pageView.set_size_request( self.pageContainer.get_allocation().width / GUIConstants.NUMBER_OF_PAGE_BANK_COLUMNS,
- GUIConstants.PAGE_HEIGHT )
- pageView.show()
-
- for i in range( len(self.pageViews)) :
- self.pageViews[i].tuneIndex = i
- self.pageViews[i].setSelected( i == position)
- self.selectPageCallback( pageID, position )
- pageView.drag_source_set(
- gtk.gdk.BUTTON1_MASK,
- [ ( "tune page", gtk.TARGET_SAME_APP, 11 ) ],
- gtk.gdk.ACTION_COPY|gtk.gdk.ACTION_MOVE )
-
- def moveSelectedPage( self, position):
- self.pageContainer.reorder_child( self.pageViews[self.selectedPageIndex], position )
- swap( self.pageViews, self.selectedPageIndex, position )
- self.selectedPageIndex = position
- for i in range( len(self.pageViews) ) :
- self.pageViews[i].tuneIndex = i
- self.pageViews[i].setSelected( i == position)
-
- def removePage( self, position ):
- pv = self.pageViews[position]
- self.pageViews[position:position+1] = []
- if self.selectedPageIndex >= position : self.selectedPageIndex -= 1
- for i in range( len(self.pageViews)) :
- self.pageViews[i].tuneIndex = i
- self.pageViews[i].setSelected( i == position)
- self.pageContainer.remove(pv)
- del pv
-
- def selectPage( self, selectedPageIndex, invokeCallback = True ):
- if selectedPageIndex >= len( self.pageViews ): selectedPageIndex = self.NO_PAGE
- self.selectedPageIndex = selectedPageIndex
- if selectedPageIndex == self.NO_PAGE:
- for pv in self.pageViews: pv.setSelected(False)
- if invokeCallback: self.selectPageCallback( -1, -1 )
- else:
- if not self.pageViews[ selectedPageIndex ].selected:
- map( lambda pv: pv.setSelected( pv.tuneIndex == selectedPageIndex), self.pageViews)
- if invokeCallback: self.selectPageCallback( self.pageViews[selectedPageIndex].pageID, selectedPageIndex )
-
- def set_size_request( self, width, height ):
- gtk.ScrolledWindow.set_size_request( self, width, height )
- map( lambda pv: pv.set_size_request( width / GUIConstants.NUMBER_OF_PAGE_BANK_COLUMNS, GUIConstants.PAGE_HEIGHT ), self.pageViews)
-
- def getPageId( self, idx):
- return self.pageViews[idx].pageID
-
- def getTune( self ):
- return [ p.pageID for p in self.pageViews ]
-