From 6d7e6f83bec91d4c3e49fe64d7793f12d1d3509b Mon Sep 17 00:00:00 2001 From: Nat Date: Thu, 13 Sep 2007 16:01:09 +0000 Subject: split --- (limited to 'Edit') 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 ] - -- cgit v0.9.1