aboutsummaryrefslogtreecommitdiff
path: root/gripdMain.py
diff options
context:
space:
mode:
Diffstat (limited to 'gripdMain.py')
-rw-r--r--gripdMain.py2337
1 files changed, 2337 insertions, 0 deletions
diff --git a/gripdMain.py b/gripdMain.py
new file mode 100644
index 0000000..1e20cb5
--- /dev/null
+++ b/gripdMain.py
@@ -0,0 +1,2337 @@
+## GrIPD v0.1.1 - Graphical Interface for Pure Data
+## Copyright (C) 2003 Joseph A. Sarlo
+##
+## This program is free software; you can redistribute it and/or
+## modify it under the terms of the GNU General Public License
+## as published by the Free Software Foundation; either version 2
+## of the License, or (at your option) any later version.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+##
+## jsarlo@ucsd.edu
+
+from wxPython.wx import *
+from gripdControls import *
+from gripdFunctions import *
+from socket import *
+from string import *
+
+midi = 0
+joystick = 0
+DEFMAINFRAMESIZE = (600, 400)
+DEFCONTROLPOS = (20,20)
+ID_ABOUT = 100
+ID_EXIT = 101
+ID_ADD = 102
+ID_EDITMODE = 103
+ID_EDIT = 104
+ID_DELETE = 105
+ID_CONNECT = 106
+ID_OPEN = 107
+ID_SAVE = 108
+ID_OPTIONS = 109
+ID_BUTTONMENU = 110
+ID_SLIDERMENU = 111
+ID_GAUGEMENU = 112
+ID_SELECTALL = 113
+ID_NEW = 114
+ID_DUPLICATE = 115
+ID_ALIGNVERT = 116
+ID_ALIGNHORZ = 117
+ID_REFRESH = 118
+ID_BUTTON = 200
+ID_TOGGLE = 201
+ID_VSLIDER = 202
+ID_HSLIDER = 203
+ID_RECT = 204
+ID_TEXT = 205
+ID_SETOPTS = 206
+ID_DISCONNECT = 207
+ID_VGAUGE = 208
+ID_HGAUGE = 209
+ID_CHECKBOX = 210
+ID_TEXTBOX = 211
+ID_SPINBUTTON = 212
+ID_MOUSEAREA = 213
+ID_ENABLEJOY = 214
+ID_ENABLEKEY = 215
+ID_LOCKONPERF = 216
+ID_RADIOBUTTON = 217
+ID_IMAGE = 218
+ID_ALWAYSONTOP = 219
+ID_SHOWGRID = 220
+ID_SNAPTOGRID = 221
+ID_ENABLEMIDI = 222
+ID_GRAPH = 223
+COMMANDCHAR = '!'
+DEFHOST = 'localhost'
+DEFPORT = 3490
+CONNECTINTERVAL = 1000
+TIMEOUT = 20
+HIDECOMMAND = "!hide"
+SHOWCOMMAND = "!show"
+EXITCOMMAND = "!exit"
+LOCKCOMMAND = "!lock"
+UNLOCKCOMMAND = "!unlock"
+SETTITLECOMMAND = "!settitle"
+CLOSECOMMAND = "!disconnect"
+PINGCOMMAND = "!ping"
+OPENPANELCOMMAND = "!openpanel"
+SAVEPANELCOMMAND = "!savepanel"
+BEGINCONTROLMARKER = "!BEGIN-CONTROL"
+ENDCONTROLMARKER = "!END-CONTROL"
+DEFOPTIONSPOS = (5, 5)
+DUPPOSOFFSET = (10, 10)
+SMALLCHARMOVE = 1
+LARGECHARMOVE = 20
+BGCOLORDIF = 30
+DEFSOCKETTIMERTIME = 5
+DEFJOYPOLLTIME = 10
+DEFMIDIPOLLTIME = 5
+DEFMIDIDEVICE1 = 0
+DEFMIDIDEVICE2 = 1
+PAIRSEPCHAR = chr(29)
+SYMMSGSEP = chr(31)
+FILETOKENSEP = "|"
+MAXPINGCOUNT = 10
+PINGPOLLTIME = 1000
+MIDINOTEMESSAGE = "9"
+MIDICTLMESSAGE = "b"
+MIDIPGMMESSAGE = "c"
+SETARRAYSTRING = "!setArray"
+
+if (os.name == "posix"):
+ FUGEFACTOR = 1
+ DEFJOYDEVICE1 = "/dev/js0"
+ DEFJOYDEVICE2 = "/dev/js1"
+else:
+ FUGEFACTOR = 2
+ DEFJOYDEVICE1 = "1"
+ DEFJOYDEVICE2 = "2"
+
+# Main application class
+class mainApp(wxPySimpleApp):
+ def __init__(self, args):
+ self.args = args
+ wxApp.__init__(self, False)
+ try:
+ wxLog_SetLogLevel(0)
+ except:
+ pass
+ def OnInit(self):
+ global midi
+ global joystick
+ openAuto = False
+ newPort = 0
+ filename = ""
+ locked = False
+ self.path = scrubPath(getDirectory(self.args[0]))
+ setDebugFile(self.path + "/log.txt")
+ self.filepath = ""
+ if (len(self.args) > 1):
+ filename = self.args[1]
+ self.filepath = getDirectory(filename)
+ if (self.filepath == ""):
+ self.filepath = self.path
+ self.filepath = makeAbsolutePath(self.path, self.filepath)
+ if (len(self.args) > 2):
+ newPort = atoi(self.args[2])
+ if (len(self.args) > 3):
+ openAuto = atoi(self.args[3])
+ if (len(self.args) > 4):
+ locked = atoi(self.args[4])
+ self.midiAvailable = True
+ self.joystickAvailable = True
+ try:
+ optionsFile = open(self.path + "/gripd.opt", 'r', -1)
+ options = optionsFile.readlines()
+ for option in options:
+ [key, value] = split(option, '=')
+ key = strip(key)
+ value = strip(value)
+ if (lower(key) == 'midi'):
+ if (lower(value) == 'false'):
+ self.midiAvailable = False
+ if (lower(key) == 'joystick'):
+ if (lower(value) == 'false'):
+ self.joystickAvailable = False
+ except:
+ pass
+ if (self.midiAvailable):
+ import midi
+ if (self.joystickAvailable):
+ import joystick
+ wxInitAllImageHandlers()
+ if (not os.name == "posix"):
+ self.icon = wxIcon(self.path + "icon.pic", wxBITMAP_TYPE_ICO)
+ self.jsImage = wxImage(self.path + "joystick.xpm",
+ wxBITMAP_TYPE_XPM).ConvertToBitmap()
+ self.jsImageX = wxImage(self.path + "joystickX.xpm",
+ wxBITMAP_TYPE_XPM).ConvertToBitmap()
+ self.jsImageA = wxImage(self.path + "joystickA.xpm",
+ wxBITMAP_TYPE_XPM).ConvertToBitmap()
+ self.midiImage = wxImage(self.path + "midi.xpm",
+ wxBITMAP_TYPE_XPM).ConvertToBitmap()
+ self.midiImageX = wxImage(self.path + "midiX.xpm",
+ wxBITMAP_TYPE_XPM).ConvertToBitmap()
+ self.midiImageA = wxImage(self.path + "midiA.xpm",
+ wxBITMAP_TYPE_XPM).ConvertToBitmap()
+ self.connectImage = wxImage(self.path + "connect.xpm",
+ wxBITMAP_TYPE_XPM).ConvertToBitmap()
+ self.connectImageX = wxImage(self.path + "connectX.xpm",
+ wxBITMAP_TYPE_XPM).ConvertToBitmap()
+ self.editMode = False
+ # socket stuff
+ self.host = DEFHOST
+ self.port = DEFPORT
+ self.connection = nullConnection()
+ self.connected = False
+ # All controls (on mainPanel)
+ self.controlList = []
+ # Selected controls, Should speed up editing
+ # DO NOT use to loop through selected controls to deselect
+ # <control>.deselect() modifies selectedControlList
+ self.selectedControlList = []
+ # If currently using selecting with selectRect
+ self.selecting = False
+ # If currently dragging a control
+ self.dragging = False
+ # Keys currently depressed
+ self.keysDown = []
+ # If left mouse was clicked on panel
+ # not on control or tag, for selectRect
+ self.leftDownOnPanel = False
+ # If current GUI has been changed since last save
+ self.edited = False
+ # control counters (for send/receive syms)
+ self.resetControlIndecies()
+ # timer to check connection status
+ self.pTimer = pingTimer(self)
+ # set ping count
+ self.pingCount = 0
+ # timer to poll for connections
+ self.cTimer = connectionTimer(self)
+ # socket polling time
+ self.pollTime = DEFSOCKETTIMERTIME
+ # timer to poll socket for receive messages
+ self.sTimer = socketTimer(self)
+ # timer to poll joystick
+ self.joyTimer = joystickTimer(self)
+ # joystick poll time
+ self.joyPollTime = DEFJOYPOLLTIME
+ # joystick device string
+ self.joyDevice1 = DEFJOYDEVICE1
+ self.joyDevice2 = DEFJOYDEVICE2
+ # joystick device id
+ self.joyID1 = -1
+ self.joyID2 = -1
+ # joystick on
+ self.joystickEnabled = False
+ self.jsOn1 = False
+ self.jsOn2 = False
+ # timer to poll midi
+ self.midiTimer = midiTimer(self)
+ # midi poll time
+ self.midiPollTime = DEFMIDIPOLLTIME
+ # midi device numbers
+ self.midiDevice1 = DEFMIDIDEVICE1
+ self.midiDevice2 = DEFMIDIDEVICE2
+ # midi device id
+ self.midiID1 = -1
+ self.midiID2 = -1
+ # midi on
+ self.midiEnabled = False
+ self.midiOn1 = False
+ self.midiOn2 = False
+ # send keystrokes
+ self.sendKeys = True
+ # grid sized
+ self.gridSpace = 10
+ # display grid
+ self.showGrid = False
+ # snap moved controls to grid
+ self.snapToGrid = False
+ # locked or unlocked GUI
+ self.locked = locked
+ self.openAuto = openAuto
+ self.frameTitle = "GrIPD"
+ self.alwaysOnTop = False
+ self.resizable = False
+ self.mainFrame = gripdFrame(self, -1, self.frameTitle,
+ (-1, -1),
+ self.resizable, self.locked,
+ self.alwaysOnTop)
+ self.SetTopWindow(self.mainFrame)
+ # for catching keystokes
+ EVT_CHAR(self.mainFrame.mainPanel, self.eChar)
+ EVT_KEY_UP(self.mainFrame.mainPanel, self.eKeyUp)
+ EVT_KEY_DOWN(self.mainFrame.mainPanel, self.eKeyDown)
+ if (not os.name == "posix"):
+ EVT_CHAR_HOOK(self.mainFrame, self.eChar)
+ EVT_CLOSE(self.mainFrame, self.eClose)
+ EVT_SIZE(self.mainFrame, self.eSize)
+ self.mainFrame.positionIcons()
+ if ((filename != "0") and (filename != "")):
+ self.openFromDisk(filename)
+ if (newPort):
+ self.port = newPort
+ if (self.openAuto):
+ self.connect()
+ else:
+ self.mainFrame.Show(True)
+ return True
+
+## Functions ##
+
+ def createControl(self, type, tIndex, tString, filepath = ""):
+ if (self.editMode and not self.dragging):
+ indexStr = tString + repr(tIndex)
+ clientMousePos = self.mainFrame.mainPanel.ScreenToClient( \
+ wxGetMousePosition())
+ coords = (clientMousePos[0] + 4, clientMousePos[1] + 4)
+ control = self.addControl(type, indexStr, coords,
+ "s" + indexStr, "r" + indexStr, filepath)
+ control.select()
+ # I'm not sure why this is necessary
+ try:
+ wxYield()
+ except:
+ pass
+ control.grab()
+ def addControl(self, type, label, pos, sSym, rSym, filepath = ""):
+ tControl = NULL
+ if (type == MBUTTONTYPE):
+ self.buttonIndex = self.buttonIndex + 1
+ tControl = mButton(self, type, -1,
+ label, pos, sSym, rSym, self.connection)
+ if (type == MTOGGLETYPE):
+ self.toggleIndex = self.toggleIndex + 1
+ tControl = mToggle(self, type, -1,
+ label, pos, sSym, rSym, self.connection)
+ if (type == MVSLIDERTYPE):
+ self.sliderIndex = self.sliderIndex + 1
+ tControl = mSlider(self, type, -1, label, pos,
+ wxSL_VERTICAL, sSym, rSym, self.connection)
+ if (type == MHSLIDERTYPE):
+ self.sliderIndex = self.sliderIndex + 1
+ tControl = mSlider(self, type, -1, label, pos,
+ wxSL_HORIZONTAL, sSym, rSym, self.connection)
+ if (type == MRECTTYPE):
+ self.rectIndex = self.rectIndex + 1
+ tControl = mRectangle(self, type, -1,
+ label, pos, sSym, rSym, self.connection)
+ if (type == MTEXTTYPE):
+ self.textIndex = self.textIndex + 1
+ tControl = mText(self, type, -1,
+ label, pos, sSym, rSym, self.connection)
+ if (type == MVGAUGETYPE):
+ self.gaugeIndex = self.gaugeIndex + 1
+ tControl = mGauge(self, type, -1, label, pos,
+ wxGA_VERTICAL, sSym, rSym, self.connection)
+ if (type == MHGAUGETYPE):
+ self.gaugeIndex = self.gaugeIndex + 1
+ tControl = mGauge(self, type, -1, label, pos,
+ wxGA_HORIZONTAL, sSym, rSym, self.connection)
+ if (type == MCHECKBOXTYPE):
+ self.checkBoxIndex = self.checkBoxIndex + 1
+ tControl = mCheckBox(self, type, -1,
+ label, pos, sSym, rSym, self.connection)
+ if (type == MRADIOBUTTONTYPE):
+ self.radioButtonIndex = self.radioButtonIndex + 1
+ tControl = mRadioButton(self, type, -1,
+ label, pos, sSym, rSym, 0, self.connection)
+ if (type == MRADIONEWTYPE):
+ self.radioButtonIndex = self.radioButtonIndex + 1
+ tControl = mRadioButton(self, type, -1,
+ label, pos, sSym, rSym, wxRB_GROUP,
+ self.connection)
+ if (type == MTEXTBOXTYPE):
+ self.textBoxIndex = self.textBoxIndex + 1
+ tControl = mTextBox(self, type, -1, label,
+ pos, sSym, rSym, self.connection)
+ if (type == MSPINBUTTONTYPE):
+ self.spinButtonIndex = self.spinButtonIndex + 1
+ tControl = mSpinButton(self, type, -1, label,
+ pos, sSym, rSym, self.connection)
+ if (type == MMOUSEAREATYPE):
+ self.mouseAreaIndex = self.mouseAreaIndex + 1
+ tControl = mMouseArea(self, type, -1,
+ pos, sSym, rSym, self.connection)
+ if (type == MIMAGETYPE):
+ if (filepath == ""):
+ filepath = label
+ filepath = makeAbsolutePath(self.filepath, filepath)
+ self.imageIndex = self.imageIndex + 1
+ try:
+ tControl = mImage(self, type, -1,
+ filepath, pos, sSym, rSym, self.connection)
+ except:
+ tControl = NULL
+ if (type == MGRAPHTYPE):
+ self.graphIndex = self.graphIndex + 1
+ tControl = mGraph(self, type, -1, label, pos, sSym,
+ rSym, self.connection)
+ if (tControl != NULL):
+ self.controlList.append(tControl)
+ return (tControl)
+ def findControlByID(self, id):
+ for control in self.controlList:
+ if (control.GetId() == id):
+ return(control)
+ def startMoveControls(self):
+ for control in self.selectedControlList:
+ control.startMove()
+ def moveSelectedControls(self, deltaPos):
+ self.edited = True
+ for control in self.selectedControlList:
+ control.move(deltaPos)
+ def endMoveControls(self):
+ for control in self.selectedControlList:
+ control.endMove()
+ def endDragMoveControls(self):
+ for control in self.selectedControlList:
+ control.endDragMove()
+ def resizeSelectedControls(self, deltaPos):
+ self.edited = True
+ for control in self.selectedControlList:
+ control.resize(deltaPos)
+ def moveKey(self, deltaPos):
+ self.moveSelectedControls(deltaPos)
+ for control in self.selectedControlList:
+ control.endMove()
+ def alignControls(self, dir):
+ otherDir = 1 - dir
+ alignVal = 1
+ alignPos = [0, 0]
+ for control in self.selectedControlList:
+ alignVal = max(alignVal, control.GetPosition()[dir])
+ alignPos[dir] = alignVal
+ for control in self.selectedControlList:
+ alignPos[otherDir] = control.GetPosition()[otherDir]
+ control.setPosition(alignPos)
+ def deselectOthers(self, calledByID):
+ # Not using selectedControlList since we are removing from it
+ # as we cycle through the list
+ for control in self.controlList:
+ if ((control.GetId() != calledByID) and control.isSelected()):
+ control.deselect()
+ def raiseControlTags(self):
+ if (self.editMode):
+ for control in self.selectedControlList:
+ control.relocateTags()
+ control.refreshTags()
+ def traverseFocus(self, multi):
+ if ((len(self.controlList) > 0) and (self.editMode)):
+ i = -1
+ newIndex = 0
+ for control in self.controlList:
+ i = i + 1
+ if (control.isSelected()):
+ newIndex = i + 1
+ newIndex = newIndex % len(self.controlList)
+ self.controlList[newIndex].select()
+ if (not multi):
+ self.deselectOthers(self.controlList[newIndex].GetId())
+ def parseReceiveBuffer(self, receiveBuffer):
+ # remove trailing PAIRSEPCHAR
+ receiveBuffer = receiveBuffer[0:-1]
+ messagePairs = split(receiveBuffer, PAIRSEPCHAR)
+ for pair in messagePairs:
+ (symName, value) = split(pair, SYMMSGSEP)
+ if (symName[0] == COMMANDCHAR):
+ if (symName == CLOSECOMMAND):
+ self.disconnect()
+ dlg = wxMessageDialog(self.mainFrame,
+ "Connection closed by PD",
+ "Connection", wxOK)
+ dlg.ShowModal()
+ dlg.Destroy()
+ if (symName == EXITCOMMAND):
+ self.close()
+ elif (symName == LOCKCOMMAND):
+ self.lock()
+ elif (symName == UNLOCKCOMMAND):
+ self.unlock()
+ elif (symName == SETTITLECOMMAND):
+ self.frameTitle = value
+ self.setFrameTitle(value)
+ elif (symName == HIDECOMMAND):
+ self.mainFrame.Show(False)
+ self.connection.send(HIDECOMMAND + \
+ SYMMSGSEP + "0" + \
+ PAIRSEPCHAR)
+ elif (symName == SHOWCOMMAND):
+ self.mainFrame.Show(True)
+ self.connection.send(SHOWCOMMAND + \
+ SYMMSGSEP + "0" + \
+ PAIRSEPCHAR)
+ elif (symName == PINGCOMMAND):
+ self.pingCount = 0
+ elif (symName == OPENPANELCOMMAND):
+ self.mainFrame.openpanel()
+ elif (symName == SAVEPANELCOMMAND):
+ self.mainFrame.savepanel()
+ else:
+ for control in self.controlList:
+ if (symName == control.getReceiveSymbol()):
+ control.PDAction(value)
+ def writeControls(self, list, file):
+ for control in list:
+ file.write(repr(control.getType()) + "\n")
+ if (control.type == MIMAGETYPE):
+ file.write(makeRelativePath(self.filepath,
+ control.GetLabel()) + "\n")
+ else:
+ file.write(control.GetLabel() + "\n")
+ file.write(repr(control.GetPosition()[0]) + "\n")
+ file.write(repr(control.GetPosition()[1]) + "\n")
+ file.write(repr(control.GetSize()[0]) + "\n")
+ file.write(repr(control.GetSize()[1]) + "\n")
+ file.write(control.getSendSymbol() + "\n")
+ file.write(control.getReceiveSymbol() + "\n")
+ if (control.GetBackgroundColour().Ok()):
+ file.write("#" + colorTuple2HexString((control.\
+ GetBackgroundColour().Red(),
+ control.\
+ GetBackgroundColour().Green(),
+ control.\
+ GetBackgroundColour().Blue()))\
+ + "\n")
+ else:
+ file.write("#00000\n")
+ if (control.GetForegroundColour().Ok()):
+ file.write("#" + colorTuple2HexString((control.\
+ GetForegroundColour().Red(),
+ control.\
+ GetForegroundColour().Green(),
+ control.\
+ GetForegroundColour().Blue()))\
+ + "\n")
+ else:
+ file.write("#000000\n")
+ if (not control.GetFont().Ok()):
+ control.SetFont(wxNORMAL_FONT)
+ file.write(repr(control.GetFont().GetPointSize()) + "\n")
+ file.write(repr(control.GetFont().GetFamily()) + "\n")
+ file.write(repr(control.GetFont().GetStyle()) + "\n")
+ file.write(repr(control.GetFont().GetWeight()) + "\n")
+ file.write(repr(control.GetFont().GetUnderlined()) + "\n")
+ file.write(control.GetFont().GetFaceName() + "\n")
+ if (isinstance(control, mSlider)):
+ file.write(repr(control.GetMin()) + "\n")
+ file.write(repr(control.GetMax()) + "\n")
+ file.write(repr(control.getDirection()) + "\n")
+ file.write(ENDCONTROLMARKER + "\n")
+ def readControls(self, list):
+ newList = []
+ for i in range(0, list.count(ENDCONTROLMARKER)):
+ params = list[0:list.index(ENDCONTROLMARKER)]
+ type = atoi(params[0])
+ label = params[1]
+ pos = (atoi(params[2]), atoi(params[3]))
+ size = (atoi(params[4]), atoi(params[5]))
+ sSym = params[6]
+ rSym = params[7]
+ bColor = params[8]
+ fColor = params[9]
+ try:
+ fontSize = atoi(params[10])
+ fontFam = atoi(params[11])
+ fontStyle = atoi(params[12])
+ fontWeight = atoi(params[13])
+ fontULine = atoi(params[14])
+ fontFace = params[15]
+ except:
+ print "Font Error!!!"
+ if (type == MVSLIDERTYPE or \
+ type == MHSLIDERTYPE or \
+ type == MVGAUGETYPE or \
+ type == MHGAUGETYPE):
+ min = atoi(params[16])
+ max = atoi(params[17])
+ dir = atoi(params[18])
+ label = [label, min, max, dir]
+ if (type == MGRAPHTYPE):
+ min = atof(params[16])
+ max = atof(params[17])
+ dir = eval(params[18])
+ label = [label, min, max, dir]
+ control = self.addControl(type, label, pos, sSym, rSym)
+ control.setSize(size)
+ control.SetBackgroundColour(bColor)
+ control.SetForegroundColour(fColor)
+ font = wxFont(fontSize, fontFam, fontStyle, fontWeight,
+ fontULine, fontFace, wxFONTENCODING_SYSTEM)
+ control.SetFont(font)
+ control.setEditMode(self.editMode)
+ # +1 to include ENDCONTROLMARKER
+ del list[0:(list.index(ENDCONTROLMARKER) + 1)]
+ newList.append(control)
+ return newList
+ def connect(self):
+ if (not self.locked):
+ self.mainFrame.fileMenu.Enable(ID_DISCONNECT, True)
+ if (not self.cTimer.IsRunning()):
+ self.cTimer.timeCount = 0
+ self.cTimer.Start(CONNECTINTERVAL)
+ def disconnect(self):
+ if (self.sTimer.IsRunning()):
+ self.sTimer.Stop()
+ try:
+ self.connection.send(CLOSECOMMAND + SYMMSGSEP + \
+ "0" + PAIRSEPCHAR)
+ except:
+ pass
+ self.connection.close()
+ self.connection = nullConnection()
+ for control in self.controlList:
+ control.connection = self.connection
+ self.cTimer.Stop()
+ self.pTimer.Stop()
+ self.pingCount = 0
+ if (not self.locked):
+ self.mainFrame.fileMenu.Enable(ID_CONNECT, True)
+ self.mainFrame.fileMenu.Enable(ID_DISCONNECT, False)
+ self.mainFrame.connectIcon.SetBitmap(self.connectImageX)
+ self.connected = False
+ def saveToDisk(self, filename):
+ try:
+ if (lower(filename[len(filename) - 4:len(filename)]) != ".gpd"):
+ filename = filename + ".gpd"
+ file = open(filename, 'w', -1)
+ self.filepath = getDirectory(filename)
+ self.filepath = makeAbsolutePath(self.path, self.filepath)
+ if (self.filepath == ""):
+ self.filepath = self.path
+ file.write(repr(self.mainFrame.GetSize()[0]) + "\n")
+ file.write(repr(self.mainFrame.GetSize()[1]) + "\n")
+ file.write("#" + colorTuple2HexString((self.mainFrame.mainPanel.\
+ GetBackgroundColour().Red(),
+ self.mainFrame.mainPanel.\
+ GetBackgroundColour().Green(),
+ self.mainFrame.mainPanel.\
+ GetBackgroundColour().Blue())) + "\n")
+ file.write(self.host + "\n")
+ file.write(repr(self.port) + FILETOKENSEP +
+ self.joyDevice1 + FILETOKENSEP +
+ self.joyDevice2 + FILETOKENSEP +
+ repr(self.pollTime) + FILETOKENSEP +
+ repr(self.joyPollTime) + FILETOKENSEP +
+ repr(self.joystickEnabled) + FILETOKENSEP +
+ repr(self.sendKeys) + FILETOKENSEP +
+ self.frameTitle + FILETOKENSEP +
+ repr(self.alwaysOnTop) + FILETOKENSEP +
+ repr(self.showGrid) + FILETOKENSEP +
+ repr(self.snapToGrid) + FILETOKENSEP +
+ repr(self.midiDevice1) + FILETOKENSEP +
+ repr(self.midiDevice2) + FILETOKENSEP +
+ repr(self.midiPollTime) + FILETOKENSEP +
+ repr(self.midiEnabled) + "\n")
+ self.writeControls(self.controlList, file)
+ file.close()
+ self.edited = False
+ except Exception:
+ strerror = str(sys.exc_info()[1])
+ dlg = wxMessageDialog(self.mainFrame, "Unable to save to " + \
+ filename + ":\n\n" + strerror,
+ "File Error", wxOK)
+ dlg.ShowModal()
+ dlg.Destroy()
+ def openFromDisk(self, filename):
+ try:
+ file = open(filename, 'r', -1)
+ try:
+ self.filepath = getDirectory(filename)
+ self.filepath = makeAbsolutePath(self.path, self.filepath)
+ fullFileList = file.readlines()
+ for control in self.controlList:
+ control.mDestroy()
+ self.controlList = []
+ self.selectedControlList = []
+ self.resetControlIndecies()
+ # remove line endings (need Perl's chomp())
+ for i in range(0, len(fullFileList)):
+ fullFileList[i] = replace(fullFileList[i], "\n", "")
+ frameSize = (atoi(fullFileList[0]), atoi(fullFileList[1]))
+ panelColor = (fullFileList[2])
+ panelHost = (fullFileList[3])
+ otherArgs = split(fullFileList[4], FILETOKENSEP)
+ if (len(otherArgs) > 0):
+ panelPort = otherArgs[0]
+ if (len(otherArgs) > 1):
+ jDev1 = otherArgs[1]
+ else:
+ jDev1 = DEFJOYDEVICE1
+ if (len(otherArgs) > 2):
+ jDev2 = otherArgs[2]
+ else:
+ jDev2 = DEFJOYDEVICE2
+ if (len(otherArgs) > 3):
+ sockPollTime = atoi(otherArgs[3])
+ else:
+ sockPollTime = DEFSOCKETTIMERTIME
+ if (len(otherArgs) > 4):
+ joyPollTime = atoi(otherArgs[4])
+ else:
+ joyPollTime = DEFJOYPOLLTIME
+ if (len(otherArgs) > 5 and self.joystickAvailable):
+ self.joystickEnabled = atoi(otherArgs[5])
+ if (self.joystickEnabled):
+ self.startJoystick()
+ else:
+ self.stopJoystick()
+ if (not self.locked):
+ self.mainFrame.optionsMenu.Check(ID_ENABLEJOY,
+ self.joystickEnabled)
+ if (len(otherArgs) > 6):
+ self.sendKeys = atoi(otherArgs[6])
+ if (not self.locked):
+ self.mainFrame.optionsMenu.Check(ID_ENABLEKEY,
+ self.sendKeys)
+ if (len(otherArgs) > 7):
+ self.setFrameTitle(otherArgs[7])
+ if (len(otherArgs) > 8):
+ self.alwaysOnTop = atoi(otherArgs[8])
+ if (len(otherArgs) > 9):
+ self.showGrid = atoi(otherArgs[9])
+ if (len(otherArgs) > 10):
+ self.snapToGrid = atoi(otherArgs[10])
+ if (len(otherArgs) > 11):
+ self.midiDevice1 = atoi(otherArgs[11])
+ if (len(otherArgs) > 12):
+ self.midiDevice2 = atoi(otherArgs[12])
+ if (len(otherArgs) > 13):
+ self.midiPollTime = atoi(otherArgs[13])
+ if (len(otherArgs) > 14 and self.midiAvailable):
+ self.midiEnabled = atoi(otherArgs[14])
+ if (self.midiEnabled):
+ self.startMidi()
+ else:
+ self.stopMidi()
+ if (not self.locked):
+ self.mainFrame.optionsMenu.Check(ID_ENABLEMIDI,
+ self.midiEnabled)
+
+ self.mainFrame.SetSize(frameSize)
+ self.mainFrame.mainPanel.SetBackgroundColour(panelColor)
+ self.host = panelHost
+ self.port = atoi(panelPort)
+ self.joyDevice1 = jDev1
+ self.joyDevice2 = jDev2
+ self.pollTime = sockPollTime
+ self.joyPollTime = joyPollTime
+ del fullFileList[0:5]
+ self.readControls(fullFileList)
+ self.edited = False
+ self.recreateFrame()
+ self.mainFrame.mainPanel.Refresh()
+ except Exception:
+ strerror = "File is invalid"
+ #FIXME
+ strerror = str(sys.exc_info()[1])
+ dlg = wxMessageDialog(self.mainFrame, "Unable to open file " + \
+ filename + ":\n\n" + strerror,
+ "File Error", wxOK)
+ dlg.ShowModal()
+ dlg.Destroy()
+ except Exception:
+ strerror = str(sys.exc_info()[1])
+ dlg = wxMessageDialog(self.mainFrame, "Unable to open file " + \
+ filename + ":\n\n" + strerror,
+ "File Error", wxOK)
+ dlg.ShowModal()
+ dlg.Destroy()
+ self.mainFrame.positionIcons()
+ self.setEditMode(False)
+ def resetControlIndecies(self):
+ self.buttonIndex = 0
+ self.toggleIndex = 0
+ self.sliderIndex = 0
+ self.textIndex = 0
+ self.rectIndex = 0
+ self.gaugeIndex = 0
+ self.checkBoxIndex = 0
+ self.textBoxIndex = 0
+ self.spinButtonIndex = 0
+ self.mouseAreaIndex = 0
+ self.radioButtonIndex = 0
+ self.imageIndex = 0
+ self.graphIndex = 0
+ def startJoystick(self):
+ self.joystickEnabled = True
+ self.joyID1 = joystick.openDevice(self.joyDevice1)
+ self.joyID2 = joystick.openDevice(self.joyDevice2)
+ if ((self.joyID1 > -1) or (self.joyID2 > -1)):
+ self.joyTimer.Start(self.joyPollTime)
+ if (self.joyID1 == -1):
+ self.jsOn1 = False
+ if (not self.locked):
+ self.mainFrame.jsIcon1.SetBitmap(self.jsImageX)
+ else:
+ self.jsOn1 = True
+ if (not self.locked):
+ self.mainFrame.jsIcon1.SetBitmap(self.jsImage)
+ if (self.joyID2 == -1):
+ self.jsOn2 = False
+ if (not self.locked):
+ self.mainFrame.jsIcon2.SetBitmap(self.jsImageX)
+ else:
+ self.jsOn2 = True
+ if (not self.locked):
+ self.mainFrame.jsIcon2.SetBitmap(self.jsImage)
+ if (not self.locked):
+ self.mainFrame.positionIcons()
+ self.mainFrame.jsIcon1.Show(not self.locked)
+ self.mainFrame.jsIcon1.Refresh()
+ self.mainFrame.jsIcon2.Show(not self.locked)
+ self.mainFrame.jsIcon2.Refresh()
+ def stopJoystick(self):
+ self.joyTimer.Stop()
+ joystick.closeDevice(self.joyID1)
+ joystick.closeDevice(self.joyID2)
+ self.joystickEnabled = False
+ self.jsOn1 = False
+ self.jsOn2 = False
+ if (not self.locked):
+ self.mainFrame.jsIconFlasher1.Stop()
+ self.mainFrame.jsIconFlasher2.Stop()
+ self.mainFrame.positionIcons()
+ self.mainFrame.jsIcon1.Show(False)
+ self.mainFrame.jsIcon2.Show(False)
+ def showJoystickActive(self, jsNum):
+ if (self.joystickEnabled and not self.locked):
+ if (jsNum == 1):
+ self.mainFrame.jsIconFlasher1.Start(250)
+ else:
+ self.mainFrame.jsIconFlasher2.Start(250)
+ def startMidi(self):
+ self.midiEnabled = True
+ self.midiID1 = midi.openDevice(self.midiDevice1)
+ self.midiID2 = midi.openDevice(self.midiDevice2)
+ if ((self.midiID1 > -1) or (self.midiID2 > -1)):
+ self.midiTimer.Start(self.midiPollTime)
+ if (self.midiID1 == -1):
+ self.midiOn1 = False
+ if (not self.locked):
+ self.mainFrame.midiIcon1.SetBitmap(self.midiImageX)
+ else:
+ self.midiOn1 = True
+ if (not self.locked):
+ self.mainFrame.midiIcon1.SetBitmap(self.midiImage)
+ if (self.midiID2 == -1):
+ self.midiOn2 = False
+ if (not self.locked):
+ self.mainFrame.midiIcon2.SetBitmap(self.midiImageX)
+ else:
+ self.midiOn2 = True
+ if (not self.locked):
+ self.mainFrame.midiIcon2.SetBitmap(self.midiImage)
+ if (not self.locked):
+ self.mainFrame.positionIcons()
+ self.mainFrame.midiIcon1.Show(not self.locked)
+ self.mainFrame.midiIcon1.Refresh()
+ self.mainFrame.midiIcon2.Show(not self.locked)
+ self.mainFrame.midiIcon2.Refresh()
+ def stopMidi(self):
+ self.midiTimer.Stop()
+ midi.closeDevice(self.midiID1)
+ midi.closeDevice(self.midiID2)
+ self.midiEnabled = False
+ self.midiOn1 = False
+ self.midiOn2 = False
+ if (not self.locked):
+ self.mainFrame.midiIconFlasher1.Stop()
+ self.mainFrame.midiIconFlasher2.Stop()
+ self.mainFrame.positionIcons()
+ self.mainFrame.midiIcon1.Show(False)
+ self.mainFrame.midiIcon2.Show(False)
+ def showMidiActive(self, midiNum):
+ if (self.midiEnabled and not self.locked):
+ if (midiNum == 1):
+ self.mainFrame.midiIconFlasher1.Start(250)
+ else:
+ self.mainFrame.midiIconFlasher2.Start(250)
+ def sendCharDown(self, charCode):
+ self.sendChar(charCode, 1)
+ def sendCharUp(self, charCode):
+ self.sendChar(charCode, 0)
+ def sendChar(self, charCode, downOrUp):
+ if (self.sendKeys):
+ self.connection.send("keystroke" +
+ SYMMSGSEP +
+ repr(charCode) +
+ " " +
+ repr(downOrUp) +
+ PAIRSEPCHAR)
+ def lock(self):
+ if (not self.locked):
+ if (self.editMode):
+ self.setEditMode(False)
+ self.locked = True
+ self.recreateFrame()
+ def unlock(self):
+ if (self.locked):
+ self.locked = False
+ self.recreateFrame()
+ def setEditMode(self, value):
+ self.editMode = value
+ self.resizable = value
+ self.mainFrame.SetCursor(wxHOURGLASS_CURSOR)
+ self.mainFrame.mainPanel.SetCursor(wxHOURGLASS_CURSOR)
+ try:
+ wxYield()
+ except:
+ pass
+ self.recreateFrame()
+ if (value):
+ EVT_PAINT(self.mainFrame.mainPanel, self.ePaint)
+ EVT_LEFT_DOWN(self.mainFrame.mainPanel, self.eLeftDown)
+ EVT_LEFT_UP(self.mainFrame.mainPanel, self.eLeftUp)
+ EVT_RIGHT_DOWN(self.mainFrame.mainPanel, self.eRightPopUp)
+ for control in self.controlList:
+ control.setEditMode(True)
+ self.editMode = True
+ if (not self.locked):
+ self.mainFrame.editMenu.Enable(ID_ADD, True)
+ self.mainFrame.editMenu.Enable(ID_EDIT, True)
+ self.mainFrame.editMenu.Enable(ID_DELETE, True)
+ self.mainFrame.editMenu.Enable(ID_SELECTALL, True)
+ self.mainFrame.editMenu.Enable(ID_DUPLICATE, True)
+ self.mainFrame.editMenu.Enable(ID_ALIGNVERT, True)
+ self.mainFrame.editMenu.Enable(ID_ALIGNHORZ, True)
+ self.mainFrame.setEditModeText("Edit Mode")
+ self.mainFrame.positionIcons()
+ self.selectedControlList = []
+ self.edited = True
+ if (self.showGrid):
+ self.mainFrame.mainPanel.Refresh()
+ else:
+ self.mainFrame.mainPanel.Disconnect(-1, wxEVT_PAINT)
+ self.mainFrame.mainPanel.Disconnect(-1, wxEVT_LEFT_DOWN)
+ self.mainFrame.mainPanel.Disconnect(-1, wxEVT_LEFT_UP)
+ self.mainFrame.mainPanel.Disconnect(-1, wxEVT_RIGHT_DOWN)
+ for control in self.controlList:
+ control.setEditMode(False)
+ self.editMode = False
+ if (not self.locked):
+ self.mainFrame.editMenu.Enable(ID_ADD, False)
+ self.mainFrame.editMenu.Enable(ID_EDIT, False)
+ self.mainFrame.editMenu.Enable(ID_DELETE, False)
+ self.mainFrame.editMenu.Enable(ID_SELECTALL, False)
+ self.mainFrame.editMenu.Enable(ID_DUPLICATE, False)
+ self.mainFrame.editMenu.Enable(ID_ALIGNVERT, False)
+ self.mainFrame.editMenu.Enable(ID_ALIGNHORZ, False)
+ self.mainFrame.setEditModeText("Performance Mode")
+ self.mainFrame.positionIcons()
+ for control in self.controlList:
+ control.Refresh()
+ self.mainFrame.SetCursor(wxSTANDARD_CURSOR)
+ self.mainFrame.mainPanel.SetCursor(wxSTANDARD_CURSOR)
+ self.mainFrame.mainPanel.SetFocus()
+ def recreateFrame(self):
+ position = self.mainFrame.GetPosition()
+ newWindow = gripdFrame(self,
+ -1,
+ self.frameTitle,
+ position,
+ self.resizable,
+ self.locked,
+ self.alwaysOnTop)
+ shown = self.mainFrame.IsShown()
+ self.copyFrame(newWindow)
+ if (shown):
+ self.mainFrame.Show(True)
+ try:
+ wxYield()
+ except:
+ pass
+ self.setFrameTitle(self.frameTitle)
+ def copyFrame(self, newWindow):
+ newWindow.SetSize(self.mainFrame.GetSize())
+ if (not self.locked):
+ newWindow.editMenu.Check(ID_EDITMODE,
+ self.editMode)
+ newWindow.optionsMenu.Check(ID_ENABLEJOY,
+ self.joystickEnabled)
+ newWindow.optionsMenu.Check(ID_ENABLEMIDI,
+ self.midiEnabled)
+ newWindow.optionsMenu.Check(ID_ENABLEKEY,
+ self.sendKeys)
+ newWindow.positionIcons()
+ newWindow.jsIcon1.Show(self.joystickEnabled)
+ newWindow.jsIcon2.Show(self.joystickEnabled)
+ newWindow.midiIcon1.Show(self.midiEnabled)
+ newWindow.midiIcon2.Show(self.midiEnabled)
+ if (self.jsOn1 and not self.locked):
+ newWindow.jsIcon1.SetBitmap(self.jsImage)
+ elif (not self.locked):
+ newWindow.jsIcon1.SetBitmap(self.jsImageX)
+ if (self.jsOn2 and not self.locked):
+ newWindow.jsIcon2.SetBitmap(self.jsImage)
+ elif (not self.locked):
+ newWindow.jsIcon2.SetBitmap(self.jsImageX)
+ if (self.midiOn1 and not self.locked):
+ newWindow.midiIcon1.SetBitmap(self.midiImage)
+ elif (not self.locked):
+ newWindow.midiIcon1.SetBitmap(self.midiImageX)
+ if (self.midiOn2 and not self.locked):
+ newWindow.midiIcon2.SetBitmap(self.midiImage)
+ elif (not self.locked):
+ newWindow.midiIcon2.SetBitmap(self.midiImageX)
+ newWindow.mainPanel.SetBackgroundColour(\
+ self.mainFrame.mainPanel.GetBackgroundColour())
+ self.mainFrame.Destroy()
+ if (self.connected and not self.locked):
+ newWindow.fileMenu.Enable(ID_CONNECT, False)
+ newWindow.fileMenu.Enable(ID_DISCONNECT, True)
+ newWindow.connectIcon.SetBitmap(self.connectImage)
+ elif (not self.locked):
+ newWindow.fileMenu.Enable(ID_CONNECT, True)
+ newWindow.fileMenu.Enable(ID_DISCONNECT, False)
+ newWindow.connectIcon.SetBitmap(self.connectImageX)
+ self.SetTopWindow(newWindow)
+ self.mainFrame = newWindow
+ EVT_KEY_UP(self.mainFrame.mainPanel, self.eKeyUp)
+ EVT_KEY_DOWN(self.mainFrame.mainPanel, self.eKeyDown)
+ EVT_CHAR(self.mainFrame.mainPanel, self.eChar)
+ if (not os.name == "posix"):
+ EVT_CHAR_HOOK(self.mainFrame, self.eChar)
+ EVT_CLOSE(self.mainFrame, self.eClose)
+ EVT_SIZE(self.mainFrame, self.eSize)
+ list = []
+ container = duplicationContainer()
+ for control in self.controlList:
+ list.append(control)
+ self.controlList = []
+ self.writeControls(list, container)
+ container.chomp()
+ self.readControls(container.getList())
+ def setFrameTitle(self, value):
+ self.frameTitle = value
+ if (self.editMode):
+ self.mainFrame.SetTitle(value + " [ Edit ]")
+ else:
+ self.mainFrame.SetTitle(value)
+ def pingTimeout(self):
+ if (self.openAuto):
+ debugLog("timeout")
+ self.disconnect()
+ self.close()
+ else:
+ self.disconnect()
+ def getNearestGridPoint(self, point):
+ x = self.gridSpace * round((float(point[0]) / self.gridSpace))
+ y = self.gridSpace * round((float(point[1]) / self.gridSpace))
+ gridPoint = (int(x), int(y))
+ return gridPoint
+ def close(self):
+ self.openAuto = False
+ if ((self.edited) and (len(self.controlList) > 0)):
+ self.mainFrame.Show(True)
+ dlg = wxMessageDialog(self.mainFrame,
+ "Current GUI not saved. Close anyway?",
+ "GUI Not Saved", wxOK | wxCANCEL)
+ if (dlg.ShowModal() == wxID_OK):
+ dlg.Destroy()
+ self.mainFrame.Destroy()
+ try:
+ self.disconnect()
+ except:
+ pass
+ else:
+ return
+ else:
+ self.mainFrame.Show(True)
+ self.mainFrame.Destroy()
+ try:
+ self.disconnect()
+ except:
+ pass
+ if (self.joystickEnabled):
+ self.stopJoystick()
+ if (self.midiEnabled):
+ self.stopMidi()
+ self.ExitMainLoop()
+
+## Events ##
+
+ def eOpenConnection(self, event):
+ cString = "Connect to " + self.host + ":" + repr(self.port) + "\n "
+ dlg = wxMessageDialog(self.mainFrame.mainPanel, cString, "Connect",
+ wxOK | wxCANCEL)
+ if (dlg.ShowModal() == wxID_OK):
+ self.connect()
+ dlg.Destroy()
+ def eCloseConnection(self, event):
+ self.disconnect()
+ def eToggleJoystick(self, event):
+ if (not self.locked):
+ self.joystickEnabled = self.mainFrame.optionsMenu.\
+ IsChecked(ID_ENABLEJOY)
+ if (self.joystickEnabled):
+ self.startJoystick()
+ else:
+ self.stopJoystick()
+ def eToggleMidi(self, event):
+ if (not self.locked):
+ self.midiEnabled = self.mainFrame.optionsMenu.\
+ IsChecked(ID_ENABLEMIDI)
+ if (self.midiEnabled):
+ self.startMidi()
+ else:
+ self.stopMidi()
+ def eToggleKeySend(self, event):
+ if (not self.locked):
+ self.sendKeys = self.mainFrame.optionsMenu.IsChecked(ID_ENABLEKEY)
+ def eToggleAlwaysOnTop(self, event):
+ if (not self.locked and os.name != "posix"):
+ self.alwaysOnTop = self.mainFrame.optionsMenu.\
+ IsChecked(ID_ALWAYSONTOP)
+ self.recreateFrame()
+ def eToggleShowGrid(self, event):
+ self.showGrid = self.mainFrame.optionsMenu.IsChecked(ID_SHOWGRID)
+ if (not self.showGrid):
+ self.snapToGrid = False
+ if (not self.locked):
+ self.mainFrame.optionsMenu.Check(ID_SNAPTOGRID, False)
+ else:
+ if (self.editMode):
+ self.mainFrame.mainPanel.Refresh()
+ self.mainFrame.mainPanel.Refresh()
+ def eToggleSnapToGrid(self, event):
+ self.snapToGrid = self.mainFrame.optionsMenu.IsChecked(ID_SNAPTOGRID)
+ if (self.snapToGrid):
+ self.showGrid = True
+ if (not self.locked):
+ self.mainFrame.optionsMenu.Check(ID_SHOWGRID, True)
+ if (self.editMode):
+ self.mainFrame.mainPanel.Refresh()
+ def eRightPopUp(self, event):
+ if ((not self.locked) and (not self.selecting)):
+ self.mainFrame.PopupMenuXY(self.mainFrame.editMenu,
+ event.GetX(),
+ event.GetY())
+ def eLeftDown(self, event):
+ # Editing stuff (mostly for selectRect)
+ if (self.editMode):
+ EVT_MOTION(self.mainFrame.mainPanel, self.eMotion)
+ self.mouseDownPos = event.GetPosition()
+ self.mainFrame.mainPanel.CaptureMouse()
+ self.leftDownOnPanel = True
+ if (not event.m_controlDown):
+ self.deselectOthers(-1)
+ def eLeftUp(self, event):
+ if (self.editMode):
+ if (self.leftDownOnPanel):
+ self.mainFrame.mainPanel.ReleaseMouse()
+ self.mainFrame.mainPanel.Disconnect(-1, wxEVT_MOTION)
+ if (self.selecting):
+ self.selecting = False
+ for control in self.controlList:
+ if (selectIntersect(control.GetRect(),
+ self.mainFrame.selectRect)):
+ control.select()
+ elif ((not event.m_controlDown) and control.isSelected()):
+ control.deselect()
+ self.mainFrame.mainPanel.Refresh()
+ self.leftDownOnPanel = False
+ def eMotion(self, event):
+ if (event.LeftIsDown() and self.editMode and self.leftDownOnPanel):
+ self.selecting = True
+ width = abs(event.GetPosition()[0] - self.mouseDownPos[0])
+ height = abs(event.GetPosition()[1] - self.mouseDownPos[1])
+ leftBound = min(self.mouseDownPos[0], event.GetPosition()[0])
+ topBound = min(self.mouseDownPos[1], event.GetPosition()[1])
+ clearRegion = wxRegion(self.mainFrame.selectRect[0],
+ self.mainFrame.selectRect[1],
+ self.mainFrame.selectRect[2],
+ self.mainFrame.selectRect[3])
+ self.mainFrame.selectRect = [leftBound, topBound,
+ width, height]
+ clearRegion.Union(leftBound, topBound, width, height)
+ self.mainFrame.mainPanel.Refresh(False, clearRegion.GetBox())
+ def ePaint(self, event):
+ event.Skip()
+ myDC = wxPaintDC(self.mainFrame.mainPanel)
+ myDC.BeginDrawing()
+ if (self.editMode):
+ if (self.showGrid):
+ self.mainFrame.drawGrid(myDC)
+ else:
+ self.mainFrame.drawCleanBackground(myDC)
+ if (self.selecting):
+ self.mainFrame.drawSelectRect(myDC)
+ myDC.EndDrawing()
+ def eAddButton(self, event):
+ self.createControl(MBUTTONTYPE, self.buttonIndex, "button")
+ def eAddToggle(self, event):
+ self.createControl(MTOGGLETYPE, self.toggleIndex, "toggle")
+ def eAddVSlider(self, event):
+ self.createControl(MVSLIDERTYPE, self.sliderIndex, "slider")
+ def eAddHSlider(self, event):
+ self.createControl(MHSLIDERTYPE, self.sliderIndex, "slider")
+ def eAddRect(self, event):
+ self.createControl(MRECTTYPE, self.rectIndex, "rectangle")
+ def eAddText(self, event):
+ self.createControl(MTEXTTYPE, self.textIndex, "text")
+ def eAddVGauge(self, event):
+ self.createControl(MVGAUGETYPE, self.gaugeIndex, "gauge")
+ def eAddHGauge(self, event):
+ self.createControl(MHGAUGETYPE, self.gaugeIndex, "gauge")
+ def eAddCheckBox(self, event):
+ self.createControl(MCHECKBOXTYPE, self.checkBoxIndex, "checkbox")
+ def eAddRadioButtons(self, event):
+ if (self.editMode and not self.dragging):
+ txtDialog = wxTextEntryDialog(self.mainFrame.mainPanel,
+ "Number of radio buttons to add:",
+ "Create Radio Buttons", "2")
+ if (txtDialog.ShowModal() == wxID_OK):
+ numRadButs = atoi(txtDialog.GetValue())
+ txtDialog.Destroy()
+ if (numRadButs > 1):
+ indexStr = "radiobutton" + repr(self.radioButtonIndex)
+ pos = self.mainFrame.mainPanel.ScreenToClient( \
+ wxGetMousePosition())
+ controlN = self.addControl(MRADIONEWTYPE,
+ indexStr,
+ pos,
+ "s" + indexStr,
+ "r" + indexStr)
+ coords = pos
+ for i in range(1, numRadButs):
+ indexStr = "radiobutton" + repr(self.radioButtonIndex)
+ coords = [coords[0], coords[1] + 25]
+ maxPos = self.mainFrame.mainPanel.GetSize()[1] - 10
+ minPos = 0
+ if (coords[1] > maxPos):
+ coords[0] = pos[0] + 40
+ coords[1] = pos[1]
+ control = self.addControl(MRADIOBUTTONTYPE,
+ indexStr,
+ coords,
+ "s" + indexStr,
+ "r" + indexStr)
+ control.select()
+ controlN.select()
+ try:
+ wxYield()
+ except:
+ pass
+ controlN.grab()
+ def eAddTextBox(self, event):
+ self.createControl(MTEXTBOXTYPE, self.textBoxIndex, "textbox")
+ def eAddSpinButton(self, event):
+ self.createControl(MSPINBUTTONTYPE, self.spinButtonIndex, "spinbutton")
+ def eAddMouseArea(self, event):
+ self.createControl(MMOUSEAREATYPE, self.mouseAreaIndex, "mousearea")
+ def eAddImage(self, event):
+ if (self.editMode and not self.dragging):
+ dlg = wxFileDialog(self.mainFrame, "Open file", self.filepath,
+ "", "*.*", wxOPEN)
+ if (dlg.ShowModal() == wxID_OK):
+ filepath = dlg.GetPath()
+ self.createControl(MIMAGETYPE,
+ self.imageIndex,
+ "image",
+ filepath)
+ dlg.Destroy()
+ def eAddGraph(self, event):
+ self.createControl(MGRAPHTYPE, self.graphIndex, "graph")
+ def eEditMode(self, event):
+ if (not self.locked):
+ newEditMode = self.mainFrame.editMenu.IsChecked(ID_EDITMODE)
+ self.setEditMode(newEditMode)
+ def eEditControl(self, event):
+ self.edited = True
+ if (len(self.selectedControlList) > 0):
+ self.selectedControlList[0].eEdit(event)
+ # extra array needed because we're removing items from the array
+ # we are cycling through (selectedControlList)
+ def eDeleteControl(self, event):
+ deleteList = []
+ for control in self.selectedControlList:
+ deleteList.append(control)
+ for control in deleteList:
+ self.controlList.remove(control)
+ self.selectedControlList.remove(control)
+ control.mDestroy()
+ def eSelectAll(self, event):
+ for control in self.controlList:
+ control.select()
+ def eDuplicate(self, event):
+ list = []
+ container = duplicationContainer()
+ # Not using selectedControlList since we are removing from it
+ # as we cycle through the list
+ for control in self.controlList:
+ if (control.isSelected()):
+ list.append(control)
+ control.deselect()
+ self.writeControls(list, container)
+ container.chomp()
+ for control in self.readControls(container.getList()):
+ control.select()
+ control.move(DUPPOSOFFSET)
+ def eAlignVertical(self, event):
+ self.alignControls(0)
+ def eAlignHorizontal(self, event):
+ self.alignControls(1)
+ def eRefresh(self, event):
+ for control in self.controlList:
+ control.Refresh()
+ if (control.isSelected()):
+ control.relocateTags()
+ self.mainFrame.mainPanel.Refresh(True)
+ def eNew(self, event):
+ flag = 0;
+ if ((self.edited) and (len(self.controlList) > 0)):
+ flag = 1
+ dlg = wxMessageDialog(self.mainFrame,
+ "Current GUI not saved. Clear anyway?",
+ "GUI Not Saved", wxOK | wxCANCEL)
+ if (dlg.ShowModal() == wxID_OK):
+ flag = 0
+ if (not flag):
+ for control in self.controlList:
+ control.mDestroy()
+ self.controlList = []
+ self.selectedControlList = []
+ self.resetControlIndecies()
+ self.mainFrame.mainPanel.SetBackgroundColour(\
+ self.mainFrame.defBgColor)
+ self.mainFrame.mainPanel.Refresh()
+ self.filepath = ""
+ def eOpen(self, event):
+ if ((self.edited) and (len(self.controlList) > 0)):
+ dlg2 = wxMessageDialog(self.mainFrame,
+ "Current GUI not saved. Open anyway?",
+ "GUI Not Saved", wxOK | wxCANCEL)
+ if (dlg2.ShowModal() == wxID_OK):
+ dlg = wxFileDialog(self.mainFrame,
+ "Open file", self.filepath, "", "*.gpd",
+ wxOPEN)
+ if (dlg.ShowModal() == wxID_OK):
+ self.openFromDisk(dlg.GetPath())
+ # FIXME
+ # dlg.Destroy()
+ # FIXME
+ # dlg2.Destroy()
+ else:
+ dlg = wxFileDialog(self.mainFrame,
+ "Open file", self.filepath, "", "*.gpd",
+ wxOPEN)
+ if (dlg.ShowModal() == wxID_OK):
+ self.openFromDisk(dlg.GetPath())
+ # FIXME
+ # dlg.Destroy()
+ self.mainFrame.mainPanel.Refresh()
+ def eSave(self, event):
+ dlg = wxFileDialog(self.mainFrame, "Save file", self.filepath,
+ "", "*.gpd", wxSAVE)
+ if (dlg.ShowModal() == wxID_OK):
+ filename = dlg.GetPath()
+ try:
+ file = open(filename, 'r', -1)
+ file.close()
+ dlg2 = wxMessageDialog(self.mainFrame, "File " + filename \
+ + " already exists. Overwrite?",
+ "File Exists", wxOK | wxCANCEL)
+ if (dlg2.ShowModal() == wxID_OK):
+ self.saveToDisk(filename)
+ dlg2.Destroy()
+ except:
+ self.saveToDisk(filename)
+ dlg.Destroy()
+ def eSetOptions(self, event):
+ dlg = optionsDialog(self)
+ dlg.ShowModal()
+ self.host = dlg.addrBox.GetValue()
+ try:
+ self.port = atoi(dlg.portBox.GetValue())
+ except:
+ errDlg = wxMessageDialog(self.mainFrame,
+ "Invalid Port",
+ "Options Error",
+ wxOK)
+ errDlg.ShowModal()
+ errDlg.Destroy()
+ try:
+ self.pollTime = atoi(dlg.pollBox.GetValue())
+ except:
+ errDlg = wxMessageDialog(self.mainFrame,
+ "Invalid Socket Poll Time",
+ "Options Error",
+ wxOK)
+ errDlg.ShowModal()
+ errDlg.Destroy()
+ self.joyDevice1 = dlg.joyDevBox1.GetValue()
+ self.joyDevice2 = dlg.joyDevBox2.GetValue()
+ try:
+ self.joyPollTime = atoi(dlg.joyPollBox.GetValue())
+ except:
+ errDlg = wxMessageDialog(self.mainFrame,
+ "Invalid Joystick Poll Time",
+ "Options Error",
+ wxOK)
+ errDlg.ShowModal()
+ errDlg.Destroy()
+ try:
+ self.midiDevice1 = atoi(dlg.midiDevBox1.GetValue())
+ except:
+ errDlg = wxMessageDialog(self.mainFrame,
+ "Invalid MIDI Device 0\nShould be an integer.",
+ "Options Error",
+ wxOK)
+ errDlg.ShowModal()
+ errDlg.Destroy()
+ try:
+ self.midiDevice2 = atoi(dlg.midiDevBox2.GetValue())
+ except:
+ errDlg = wxMessageDialog(self.mainFrame,
+ "Invalid MIDI Device 1\nShould be an integer.",
+ "Options Error",
+ wxOK)
+ errDlg.ShowModal()
+ errDlg.Destroy()
+ try:
+ self.midiPollTime = atoi(dlg.midiPollBox.GetValue())
+ except:
+ errDlg = wxMessageDialog(self.mainFrame,
+ "Invalid MIDI Poll Time",
+ "Options Error",
+ wxOK)
+ errDlg.ShowModal()
+ errDlg.Destroy()
+ self.setFrameTitle(dlg.titleBox.GetValue())
+ if (self.sTimer.IsRunning):
+ self.sTimer.Stop()
+ self.sTimer.Start(self.pollTime)
+ if (not self.locked):
+ if (self.mainFrame.optionsMenu.IsChecked(ID_ENABLEJOY)):
+ self.stopJoystick()
+ self.startJoystick()
+ if (self.mainFrame.optionsMenu.IsChecked(ID_ENABLEMIDI)):
+ self.stopMidi()
+ self.startMidi()
+ dlg.Destroy()
+ self.mainFrame.Refresh(True)
+ self.mainFrame.mainPanel.Refresh(True)
+ for control in self.controlList:
+ control.Refresh()
+ def eAbout(self, event):
+ aboutString = "GrIPD v" + VERSION + ": "
+ aboutString = aboutString \
+ + "Graphical Interface for Pure Data\n\n"
+ aboutString = aboutString \
+ + "(C) Copyright 2003 Joseph A. Sarlo\nGNU "
+ aboutString = aboutString \
+ + "General Public License\njsarlo@ucsd.edu"
+ dlg = wxMessageDialog(self.mainFrame, aboutString , "About GrIPD",
+ wxOK | wxICON_INFORMATION)
+ dlg.ShowModal()
+ dlg.Destroy()
+ def eQuit(self, event):
+ self.mainFrame.Close(True)
+ def eKeyDown(self, event):
+ # already depressed
+ try:
+ self.keysDown.index(event.GetKeyCode())
+ # first time
+ except:
+ self.keysDown.append(event.GetKeyCode())
+ if (not self.editMode):
+ self.sendCharDown(event.GetKeyCode())
+ event.Skip()
+ def eKeyUp(self, event):
+ try:
+ self.keysDown.remove(event.GetKeyCode())
+ self.sendCharUp(event.GetKeyCode())
+ except:
+ pass
+ event.Skip()
+ def eChar(self, event):
+ if (self.editMode and not self.dragging):
+ if (event.m_controlDown):
+ deltaPos = LARGECHARMOVE
+ else:
+ deltaPos = SMALLCHARMOVE
+ if (event.GetKeyCode() == WXK_LEFT):
+ self.moveKey((-deltaPos, 0))
+ return
+ if (event.GetKeyCode() == WXK_RIGHT):
+ self.moveKey((deltaPos, 0))
+ return
+ if (event.GetKeyCode() == WXK_UP):
+ self.moveKey((0, -deltaPos))
+ return
+ if (event.GetKeyCode() == WXK_DOWN):
+ self.moveKey((0, deltaPos))
+ return
+ if (event.GetKeyCode() == WXK_TAB):
+ self.traverseFocus(event.m_controlDown)
+ return
+ if (not self.editMode or (self.editMode and not self.dragging)):
+ # Allow accelerators to be called
+ event.Skip()
+ def eRepaintControlTags(self, event):
+ event.getControl().refreshTags()
+ def eClose(self, event):
+ if (self.openAuto and self.connected):
+ self.mainFrame.Show(False)
+ try:
+ self.connection.send(HIDECOMMAND + SYMMSGSEP + \
+ "0" + PAIRSEPCHAR)
+ except:
+ self.close()
+ else:
+ self.close()
+ def eSize(self, event):
+ self.mainFrame.positionIcons()
+ event.Skip()
+
+# Frame class
+class gripdFrame(wxFrame):
+# Setup
+ def __init__(self, parent, ID, title, position,
+ resizable, locked, alwaysOnTop):
+ self.mParent = parent
+ self.resizable = resizable
+ self.alwaysOnTop = alwaysOnTop
+ self.locked = locked
+ if (self.resizable):
+ style = wxDEFAULT_FRAME_STYLE
+ else:
+ style = wxDEFAULT_FRAME_STYLE & (~wxRESIZE_BORDER) & \
+ (~wxMAXIMIZE_BOX)
+ if (self.alwaysOnTop):
+ style = style | wxSTAY_ON_TOP
+ if (position == (-1, -1)):
+ position = wxDefaultPosition
+ wxFrame.__init__(self, NULL, ID, title, position,
+ DEFMAINFRAMESIZE,
+ style)
+ if (not os.name == "posix"):
+ self.SetIcon(self.mParent.icon)
+ if (not self.locked):
+ # Menu accelerator stuff
+ aclList = []
+ aclList.append(wxAcceleratorEntry(wxACCEL_NORMAL,
+ WXK_DELETE,
+ ID_DELETE))
+ aclList.append(wxAcceleratorEntry(wxACCEL_NORMAL, WXK_F1,
+ ID_BUTTON))
+ aclList.append(wxAcceleratorEntry(wxACCEL_NORMAL, WXK_F2,
+ ID_TOGGLE))
+ aclList.append(wxAcceleratorEntry(wxACCEL_NORMAL, WXK_F3,
+ ID_SPINBUTTON))
+ aclList.append(wxAcceleratorEntry(wxACCEL_NORMAL, WXK_F4,
+ ID_RADIOBUTTON))
+ aclList.append(wxAcceleratorEntry(wxACCEL_NORMAL, WXK_F5,
+ ID_VSLIDER))
+ aclList.append(wxAcceleratorEntry(wxACCEL_NORMAL, WXK_F6,
+ ID_HSLIDER))
+ aclList.append(wxAcceleratorEntry(wxACCEL_NORMAL, WXK_F7,
+ ID_VGAUGE))
+ aclList.append(wxAcceleratorEntry(wxACCEL_NORMAL, WXK_F8,
+ ID_HGAUGE))
+ aclList.append(wxAcceleratorEntry(wxACCEL_NORMAL, WXK_F9,
+ ID_CHECKBOX))
+ aclList.append(wxAcceleratorEntry(wxACCEL_NORMAL, WXK_F10,
+ ID_TEXTBOX))
+ aclList.append(wxAcceleratorEntry(wxACCEL_NORMAL, WXK_F11,
+ ID_MOUSEAREA))
+ aclList.append(wxAcceleratorEntry(wxACCEL_NORMAL, WXK_F12,
+ ID_RECT))
+ aclList.append(wxAcceleratorEntry(wxACCEL_ALT, ord("1"),
+ ID_TEXT))
+ aclList.append(wxAcceleratorEntry(wxACCEL_ALT, ord("2"),
+ ID_IMAGE))
+ self.SetAcceleratorTable(wxAcceleratorTable(aclList))
+ self.menuBar = wxMenuBar()
+ self.SetMenuBar(self.menuBar)
+ self.createMenu()
+ self.CreateStatusBar(3)
+ self.jsIcon1 = wxStaticBitmap(self.GetStatusBar(), -1,
+ self.mParent.jsImageX, (0, 0),
+ wxDefaultSize)
+ self.jsIcon2 = wxStaticBitmap(self.GetStatusBar(), -1,
+ self.mParent.jsImageX, (0, 0),
+ wxDefaultSize)
+ self.midiIcon1 = wxStaticBitmap(self.GetStatusBar(), -1,
+ self.mParent.midiImageX, (0, 0),
+ wxDefaultSize)
+ self.midiIcon2 = wxStaticBitmap(self.GetStatusBar(), -1,
+ self.mParent.midiImageX, (0, 0),
+ wxDefaultSize)
+ self.connectIcon = wxStaticBitmap(self.GetStatusBar(),
+ -1,
+ self.mParent.connectImageX,
+ (0, 0),
+ wxDefaultSize)
+ # timers to flash icons
+ self.jsIconFlasher1 = iconFlasher(self.jsIcon1,
+ self.mParent.jsImage,
+ self.mParent.jsImageA,
+ 1)
+ self.jsIconFlasher2 = iconFlasher(self.jsIcon2,
+ self.mParent.jsImage,
+ self.mParent.jsImageA,
+ 1)
+ self.midiIconFlasher1 = iconFlasher(self.midiIcon1,
+ self.mParent.midiImage,
+ self.mParent.midiImageA,
+ 1)
+ self.midiIconFlasher2 = iconFlasher(self.midiIcon2,
+ self.mParent.midiImage,
+ self.mParent.midiImageA,
+ 1)
+ self.editModeText = wxStaticText(self.GetStatusBar(),
+ -1,
+ "Performance Mode",
+ (0, 0),
+ wxDefaultSize,
+ wxALIGN_CENTRE | \
+ wxST_NO_AUTORESIZE)
+ self.editModeText.Show(True)
+ self.jsIcon1.Show(False)
+ self.jsIcon2.Show(False)
+ self.midiIcon1.Show(False)
+ self.midiIcon2.Show(False)
+ self.connectIcon.Show(True)
+ # left, top, width, height of selection rect (for drawing)
+ self.selectRect = [0, 0, 0, 0]
+ # mainPanel stuff
+ self.mainPanel = wxPanel(self, -1, wxDefaultPosition,
+ wxDefaultSize,
+ wxSTATIC_BORDER)
+ self.defBgColor = wxColour(self.mainPanel.GetBackgroundColour().Red() \
+ - BGCOLORDIF,
+ self.mainPanel.GetBackgroundColour().Green() \
+ - BGCOLORDIF,
+ self.mainPanel.GetBackgroundColour().Blue() \
+ - BGCOLORDIF)
+ self.mainPanel.SetBackgroundColour(self.defBgColor)
+ self.mainPanel.Show(True)
+ if (self.locked):
+ self.lock()
+ else:
+ self.unlock()
+ def createMenu(self):
+ self.fileMenu = wxMenu()
+ self.fileMenu.Append(ID_NEW, "&New\tCtrl-N", "Clear current GUI")
+ self.fileMenu.Append(ID_OPEN, "&Open\tCtrl-O", "Open a GUI")
+ self.fileMenu.Append(ID_SAVE, "&Save\tCtrl-S", "Save current GUI")
+ self.fileMenu.AppendSeparator()
+ self.fileMenu.Append(ID_CONNECT, "&Connect\tAlt-C",
+ "Connect to PD")
+ self.fileMenu.Append(ID_DISCONNECT, "&Disconnect\tAlt-D",
+ "Disconnect from PD")
+ self.fileMenu.AppendSeparator()
+ self.fileMenu.Append(ID_EXIT, "E&xit\tCtrl-Q", "Quit GrIPD")
+ self.editMenu = wxMenu()
+ self.editMenu.Append(ID_EDITMODE, "Edit &mode\tCtrl-E",
+ "Toggle Edit/Performance Modes", True)
+ self.editMenu.AppendSeparator()
+ self.addMenu = wxMenu()
+ self.buttonMenu = wxMenu()
+ self.buttonMenu.Append(ID_BUTTON, "&Push Button\tF1",
+ "Add a push button")
+ self.buttonMenu.Append(ID_TOGGLE, "&Toggle Button\tF2",
+ "Add a toggle button")
+ self.buttonMenu.Append(ID_SPINBUTTON, "&Spin Button\tF3",
+ "Add a spin button")
+ self.buttonMenu.Append(ID_RADIOBUTTON, "&Radio Buttons\tF4",
+ "Add radio buttons")
+ self.addMenu.AppendMenu(ID_BUTTONMENU, "&Button", self.buttonMenu);
+ self.sliderMenu = wxMenu()
+ self.sliderMenu.Append(ID_VSLIDER, "&Vertical Slider\tF5",
+ "Add a vertical slider")
+ self.sliderMenu.Append(ID_HSLIDER, "&Horizontal Slider\tF6",
+ "Add a horizontal slider")
+ self.addMenu.AppendMenu(ID_SLIDERMENU, "&Slider", self.sliderMenu);
+ self.gaugeMenu = wxMenu()
+ self.gaugeMenu.Append(ID_VGAUGE, "&Vertical Gauge\tF7",
+ "Add a vertical gauge")
+ self.gaugeMenu.Append(ID_HGAUGE, "&Horizontal Gauge\tF8",
+ "Add a horizontal gauge")
+ self.addMenu.AppendMenu(ID_GAUGEMENU, "&Gauge", self.gaugeMenu);
+ self.addMenu.Append(ID_CHECKBOX, "&Checkbox\tF9",
+ "Add a labeld checkbox")
+ self.addMenu.Append(ID_TEXTBOX, "Te&xtbox\tF10",
+ "Add a box for entering text")
+ self.addMenu.Append(ID_MOUSEAREA, "&Mouse Area\tF11",
+ "Add a mouse capture area")
+ self.addMenu.Append(ID_RECT, "&Rectangle\tF12",
+ "Add a boundary rectangle")
+ self.addMenu.Append(ID_TEXT, "&Text\tAlt-1", "Add text")
+ self.addMenu.Append(ID_IMAGE, "&Image\tAlt-2", "Add an image")
+ self.addMenu.Append(ID_GRAPH, "&Graph\tAlt-3", "Add a graph")
+ self.editMenu.AppendMenu(ID_ADD, "&Add", self.addMenu)
+ self.editMenu.Append(ID_EDIT, "&Edit", "Edit selected controls")
+ self.editMenu.Append(ID_DELETE, "&Delete", "Delete selected controls")
+ self.editMenu.AppendSeparator()
+ self.editMenu.Append(ID_SELECTALL, "&Select All\tCtrl-A",
+ "Select all controls")
+ self.editMenu.Append(ID_DUPLICATE, "D&uplicate\tCtrl-D",
+ "Duplicate selected controls")
+ self.editMenu.AppendSeparator()
+ self.editMenu.Append(ID_ALIGNVERT, "Align &Vertical\tCtrl-V",
+ "Vertically align selected controls")
+ self.editMenu.Append(ID_ALIGNHORZ, "Align &Horizontal\tCtrl-H",
+ "Horizontally align selected controls")
+ self.editMenu.AppendSeparator()
+ self.editMenu.Append(ID_REFRESH, "&Refresh\tCtrl-R", "Refresh screen")
+ self.optionsMenu = wxMenu()
+ if (os.name != "posix"):
+ self.optionsMenu.Append(ID_ALWAYSONTOP, "Always On Top",
+ "Window will stay above all other windows",
+ True)
+ self.optionsMenu.AppendSeparator()
+ self.optionsMenu.Append(ID_ENABLEMIDI, "Enable &MIDI",
+ "Enables the use of MIDI input",
+ True)
+ self.optionsMenu.Append(ID_ENABLEJOY, "Enable &Joystick(s)",
+ "Enables the use of a joystick",
+ True)
+ self.optionsMenu.Append(ID_ENABLEKEY, "Send &Keystrokes",
+ "Send all keystrokes to PD 'keystroke' symbol",
+ True)
+ self.optionsMenu.AppendSeparator()
+ self.optionsMenu.Append(ID_SHOWGRID, "Show Grid",
+ "Show Edit Grid", True)
+ self.optionsMenu.Append(ID_SNAPTOGRID, "Snap To Grid",
+ "Snap controls to edit grid", True)
+ self.optionsMenu.AppendSeparator()
+ self.optionsMenu.Append(ID_SETOPTS, "&Configure\tCtrl-C",
+ "Set GUI options")
+ self.helpMenu = wxMenu()
+ self.helpMenu.Append(ID_ABOUT, "&About",
+ "GrIPD: Graphical Interface for Pure Data")
+ self.menuBar.Append(self.fileMenu, "&File")
+ self.menuBar.Append(self.editMenu, "&Edit")
+ self.menuBar.Append(self.optionsMenu, "&Options")
+ self.menuBar.Append(self.helpMenu, "&Help")
+ self.fileMenu.Enable(ID_DISCONNECT, False)
+ self.editMenu.Enable(ID_ADD, False)
+ self.editMenu.Enable(ID_EDIT, False)
+ self.editMenu.Enable(ID_DELETE, False)
+ self.editMenu.Enable(ID_SELECTALL, False)
+ self.editMenu.Enable(ID_DUPLICATE, False)
+ self.editMenu.Enable(ID_ALIGNVERT, False)
+ self.editMenu.Enable(ID_ALIGNHORZ, False)
+ if (self.mParent.joystickAvailable):
+ self.optionsMenu.Check(ID_ENABLEJOY, self.mParent.joystickEnabled)
+ if (self.mParent.midiAvailable):
+ self.optionsMenu.Check(ID_ENABLEMIDI, self.mParent.midiEnabled)
+ self.optionsMenu.Check(ID_ENABLEKEY, self.mParent.sendKeys)
+ if (os.name != "posix"):
+ self.optionsMenu.Check(ID_ALWAYSONTOP, self.alwaysOnTop)
+ self.optionsMenu.Check(ID_SHOWGRID, self.mParent.showGrid)
+ self.optionsMenu.Check(ID_SNAPTOGRID, self.mParent.snapToGrid)
+ self.optionsMenu.Enable(ID_ENABLEJOY,
+ self.mParent.joystickAvailable)
+ self.optionsMenu.Enable(ID_ENABLEMIDI,
+ self.mParent.midiAvailable)
+ EVT_MENU(self, ID_NEW, self.mParent.eNew)
+ EVT_MENU(self, ID_ABOUT, self.mParent.eAbout)
+ EVT_MENU(self, ID_EXIT, self.mParent.eQuit)
+ EVT_MENU(self, ID_CONNECT, self.mParent.eOpenConnection)
+ EVT_MENU(self, ID_DISCONNECT, self.mParent.eCloseConnection)
+ EVT_MENU(self, ID_OPEN, self.mParent.eOpen)
+ EVT_MENU(self, ID_SAVE, self.mParent.eSave)
+ EVT_MENU(self, ID_BUTTON, self.mParent.eAddButton)
+ EVT_MENU(self, ID_TOGGLE, self.mParent.eAddToggle)
+ EVT_MENU(self, ID_SPINBUTTON, self.mParent.eAddSpinButton)
+ EVT_MENU(self, ID_VSLIDER, self.mParent.eAddVSlider)
+ EVT_MENU(self, ID_HSLIDER, self.mParent.eAddHSlider)
+ EVT_MENU(self, ID_RECT, self.mParent.eAddRect)
+ EVT_MENU(self, ID_VGAUGE, self.mParent.eAddVGauge)
+ EVT_MENU(self, ID_HGAUGE, self.mParent.eAddHGauge)
+ EVT_MENU(self, ID_CHECKBOX, self.mParent.eAddCheckBox)
+ EVT_MENU(self, ID_RADIOBUTTON, self.mParent.eAddRadioButtons)
+ EVT_MENU(self, ID_TEXTBOX, self.mParent.eAddTextBox)
+ EVT_MENU(self, ID_TEXT, self.mParent.eAddText)
+ EVT_MENU(self, ID_IMAGE, self.mParent.eAddImage)
+ EVT_MENU(self, ID_MOUSEAREA, self.mParent.eAddMouseArea)
+ EVT_MENU(self, ID_GRAPH, self.mParent.eAddGraph)
+ EVT_MENU(self, ID_EDITMODE, self.mParent.eEditMode)
+ EVT_MENU(self, ID_EDIT, self.mParent.eEditControl)
+ EVT_MENU(self, ID_DELETE, self.mParent.eDeleteControl)
+ EVT_MENU(self, ID_SELECTALL, self.mParent.eSelectAll)
+ EVT_MENU(self, ID_DUPLICATE, self.mParent.eDuplicate)
+ EVT_MENU(self, ID_ALIGNVERT, self.mParent.eAlignVertical)
+ EVT_MENU(self, ID_ALIGNHORZ, self.mParent.eAlignHorizontal)
+ EVT_MENU(self, ID_REFRESH, self.mParent.eRefresh)
+ EVT_MENU(self, ID_SETOPTS, self.mParent.eSetOptions)
+ EVT_MENU(self, ID_ENABLEJOY, self.mParent.eToggleJoystick)
+ EVT_MENU(self, ID_ENABLEMIDI, self.mParent.eToggleMidi)
+ EVT_MENU(self, ID_ENABLEKEY, self.mParent.eToggleKeySend)
+ if (os.name != "posix"):
+ EVT_MENU(self, ID_ALWAYSONTOP, self.mParent.eToggleAlwaysOnTop)
+ EVT_MENU(self, ID_SHOWGRID, self.mParent.eToggleShowGrid)
+ EVT_MENU(self, ID_SNAPTOGRID, self.mParent.eToggleSnapToGrid)
+ def createLockedMenu(self):
+ self.fileMenu = wxMenu()
+ self.fileMenu.Append(ID_EXIT, "E&xit\tCtrl-Q", "Quit GrIPD")
+ self.helpMenu = wxMenu()
+ self.helpMenu.Append(ID_ABOUT, "&About",
+ "GrIPD: Graphical Interface for Pure Data")
+ self.menuBar.Append(self.fileMenu, "&File")
+ self.menuBar.Append(self.helpMenu, "&Help")
+ EVT_MENU(self, ID_ABOUT, self.mParent.eAbout)
+ EVT_MENU(self, ID_EXIT, self.mParent.eQuit)
+ def removeMenu(self):
+ for i in range(0, self.GetMenuBar().GetMenuCount()):
+ self.GetMenuBar().Remove(0)
+ def drawCleanBackground(self, myDC, rect = ()):
+ box = self.mainPanel.GetUpdateRegion().GetBox()
+ if (rect == ()):
+ rect = tuple((box[0],
+ box[1],
+ box[0] + box[2],
+ box[1] + box[3]))
+ myDC.SetPen(wxPen(self.mainPanel.GetBackgroundColour(),
+ 1,
+ wxTRANSPARENT))
+ myDC.SetBrush(wxBrush(self.mainPanel.GetBackgroundColour(), wxSOLID))
+ myDC.DrawRectangle(rect[0],
+ rect[1],
+ rect[2],
+ rect[3])
+ def drawGrid(self, myDC, rect = ()):
+ box = self.mainPanel.GetUpdateRegion().GetBox()
+ if (rect == ()):
+ rect = tuple((box[0],
+ box[1],
+ box[0] + box[2],
+ box[1] + box[3]))
+ color = self.mainPanel.GetBackgroundColour()
+ newColorTuple = [color.Red() - 50,
+ color.Green() - 50,
+ color.Blue() - 50]
+ if (newColorTuple[0] < 0 or \
+ newColorTuple[1] < 0 or \
+ newColorTuple[2] < 0):
+ newColorTuple = [color.Red() + 50,
+ color.Green() + 50,
+ color.Blue() + 50]
+ for i in range(0, 3):
+ if (newColorTuple[i] > 255 or newColorTuple[i] < 0):
+ newColorTuple[i] = 0
+ myDC.SetPen(wxPen(self.mainPanel.GetBackgroundColour(),
+ 1,
+ wxTRANSPARENT))
+ myDC.SetBrush(wxBrush(self.mainPanel.GetBackgroundColour(), wxSOLID))
+ myDC.DrawRectangle(rect[0],
+ rect[1],
+ rect[2],
+ rect[3])
+ myDC.SetPen(wxPen(wxColour(newColorTuple[0],
+ newColorTuple[1],
+ newColorTuple[2]),
+ 1,
+ wxSOLID))
+ myDC.SetBrush(wxBrush("#000000", wxTRANSPARENT))
+ for i in range(rect[0], rect[2]):
+ if (i% self.mParent.gridSpace == 0):
+ myDC.DrawLine(i, rect[1], i, rect[3])
+ for i in range(rect[1], rect[3]):
+ if (i % self.mParent.gridSpace == 0):
+ myDC.DrawLine(rect[0], i, rect[2], i)
+ def drawSelectRect(self, myDC):
+ myDC.SetPen(wxPen("#000000", 1, wxDOT))
+ myDC.SetBrush(wxBrush(self.mainPanel.GetBackgroundColour(),
+ wxTRANSPARENT))
+ myDC.DrawRectangle(self.selectRect[0], self.selectRect[1],
+ self.selectRect[2], self.selectRect[3])
+ def setEditModeText(self, text):
+ if (not self.locked):
+ self.editModeText.SetLabel(text)
+ self.editModeText.SetSize(( \
+ self.GetStatusBar().GetFieldRect(1)[2] - 10,
+ self.editModeText.GetSize()[1]))
+ self.editModeText.Show(True)
+ pos = (((self.GetStatusBar().GetFieldRect(1)[2] - \
+ self.editModeText.GetSize()[0]) / 2) + \
+ self.GetStatusBar().GetFieldRect(1)[0] + 1,
+ ((self.GetStatusBar().GetFieldRect(1)[3] - \
+ self.editModeText.GetSize()[1]) / 2) + \
+ self.GetStatusBar().GetFieldRect(1)[1] + \
+ -1 * (FUGEFACTOR - 2))
+ self.editModeText.Move(pos)
+ def lock(self):
+ self.locked = True
+ def unlock(self):
+ self.locked = False
+ def positionIcons(self):
+ if (not self.locked):
+ self.setEditModeText(self.editModeText.GetLabel())
+ pos = (self.GetStatusBar().GetFieldRect(2)[0] + 3,
+ self.GetStatusBar().GetFieldRect(2)[3] - \
+ self.connectIcon.GetSize()[1] + 1)
+ self.connectIcon.Move(pos)
+ self.midiIcon1.Move((self.connectIcon.GetPosition()[0] + \
+ self.connectIcon.GetSize()[0] + 5,
+ pos[1]))
+ self.midiIcon2.Move((self.midiIcon1.GetPosition()[0] + \
+ self.midiIcon1.GetSize()[0] + 3, pos[1]))
+ if (self.mParent.midiEnabled):
+ self.jsIcon1.Move((self.midiIcon2.GetPosition()[0] + \
+ self.midiIcon2.GetSize()[0] + 5,
+ pos[1]))
+ else:
+ self.jsIcon1.Move((self.connectIcon.GetPosition()[0] + \
+ self.connectIcon.GetSize()[0] + 5,
+ pos[1]))
+ self.jsIcon2.Move((self.jsIcon1.GetPosition()[0] + \
+ self.jsIcon1.GetSize()[0] + 3, pos[1]))
+
+ self.Refresh()
+ def openpanel(self):
+ dlg = wxFileDialog(self, "Open file", self.mParent.filepath,
+ "", "*.*", wxOPEN)
+ if (dlg.ShowModal() == wxID_OK):
+ filename = dlg.GetPath()
+ self.mParent.connection.send('openpanel' \
+ + SYMMSGSEP \
+ + filename \
+ + PAIRSEPCHAR)
+
+
+ def savepanel(self):
+ dlg = wxFileDialog(self, "Save file", self.mParent.filepath,
+ "", "*.*", wxSAVE)
+ if (dlg.ShowModal() == wxID_OK):
+ filename = dlg.GetPath()
+ self.mParent.connection.send('savepanel' \
+ + SYMMSGSEP \
+ + filename \
+ + PAIRSEPCHAR)
+ def stopIconFlashers(self):
+ self.jsIconFlasher1.Stop()
+ self.jsIconFlasher2.Stop()
+ self.midiIconFlasher1.Stop()
+ self.midiIconFlasher2.Stop()
+ def Destroy(self):
+ if (not self.locked):
+ self.stopIconFlashers()
+ wxFrame.Destroy(self)
+
+
+# Classes used by mainFrame
+# Class to poll for connection to server
+class connectionTimer(wxTimer):
+ def __init__(self, parent):
+ wxTimer.__init__(self)
+ self.mParent = parent
+ self.timeCount = 0
+ def connect(self):
+ try:
+ if (not self.mParent.locked):
+ self.mParent.mainFrame.fileMenu.Enable(ID_CONNECT, False)
+ tempConn = socket(AF_INET, SOCK_STREAM)
+ tempConn.connect((self.mParent.host, self.mParent.port))
+ tempConn.setblocking(0)
+ rcvrList = self.mParent.connection.rcvrList
+ self.mParent.connection = tempConn
+ self.Stop()
+ self.mParent.sTimer.Start(self.mParent.pollTime)
+ self.mParent.connection.send(rcvrList)
+ for control in self.mParent.controlList:
+ control.connection = self.mParent.connection
+ self.mParent.connected = True
+ self.mParent.pingCount = 0
+ self.mParent.pTimer.Start(PINGPOLLTIME)
+ if (not self.mParent.locked):
+ self.mParent.mainFrame.connectIcon.SetBitmap(\
+ self.mParent.connectImage)
+ self.mParent.mainFrame.connectIcon.Refresh()
+ self.mParent.connection.send(SHOWCOMMAND + \
+ SYMMSGSEP + "0" + \
+ PAIRSEPCHAR)
+ self.mParent.mainFrame.Show(True)
+ except:
+ self.timeCount = self.timeCount + 1
+ def Notify(self):
+ self.connect()
+ if (self.timeCount >= TIMEOUT):
+ self.Stop()
+ dlg = wxMessageDialog(self.mParent.mainFrame, "Connection Timeout",
+ "Connection", wxOK)
+ dlg.ShowModal()
+ dlg.Destroy()
+ if (not self.mParent.locked):
+ self.mParent.mainFrame.fileMenu.Enable(ID_CONNECT, True)
+
+# Class to poll socket for receive string
+class socketTimer(wxTimer):
+ def __init__(self, parent):
+ wxTimer.__init__(self)
+ self.mParent = parent
+ def Notify(self):
+ try:
+ receiveBuffer = self.mParent.connection.recv(16384)
+ numBytes = len(strip(receiveBuffer))
+ if (numBytes > 0):
+ self.mParent.parseReceiveBuffer(receiveBuffer)
+ except:
+ pass
+
+# Class to check connection status
+class pingTimer(wxTimer):
+ def __init__(self, parent):
+ wxTimer.__init__(self)
+ self.mParent = parent
+ def Notify(self):
+ try:
+ self.mParent.connection.send(PINGCOMMAND + SYMMSGSEP + \
+ "0" + PAIRSEPCHAR)
+
+ except:
+ self.Stop()
+ self.mParent.pingTimeout()
+
+# Class to poll joystick
+class joystickTimer(wxTimer):
+ def __init__(self, parent):
+ wxTimer.__init__(self)
+ self.mParent = parent
+ def Notify(self):
+ if (self.mParent.joyID1 > -1):
+ numEvents1 = joystick.readEvents(self.mParent.joyID1)
+ if (numEvents1 > 0):
+ self.mParent.showJoystickActive(1)
+ for i in range(0, numEvents1):
+ if (joystick.getEventType(self.mParent.joyID1, i) == 0):
+ try:
+ self.mParent.connection.send('joy0axis'
+ + repr(joystick.getEventNumber(
+ self.mParent.joyID1,
+ i)) \
+ + SYMMSGSEP \
+ + repr(joystick.getEventValue(
+ self.mParent.joyID1,
+ i)) \
+ + PAIRSEPCHAR)
+ except:
+ self.mParent.close()
+ if (joystick.getEventType(self.mParent.joyID1,i) == 1):
+ try:
+ self.mParent.connection.send('joy0button'
+ + repr(joystick.getEventNumber(
+ self.mParent.joyID1,
+ i)) \
+ + SYMMSGSEP \
+ + repr(joystick.getEventValue(
+ self.mParent.joyID1,
+ i)) \
+ + PAIRSEPCHAR)
+ except:
+ self.mParent.close()
+ if (self.mParent.joyID2 > -1):
+ numEvents2 = joystick.readEvents(self.mParent.joyID2)
+ if (numEvents2 > 0):
+ self.mParent.showJoystickActive(2)
+ for i in range(0, numEvents2):
+ if (joystick.getEventType(self.mParent.joyID2, i) == 0):
+ try:
+ self.mParent.connection.send('joy1axis'
+ + repr(joystick.getEventNumber(
+ self.mParent.joyID2,
+ i)) \
+ + SYMMSGSEP \
+ + repr(joystick.getEventValue(
+ self.mParent.joyID2,
+ i)) \
+ + PAIRSEPCHAR)
+ except:
+ self.mParent.close()
+ if (joystick.getEventType(self.mParent.joyID2,i) == 1):
+ try:
+ self.mParent.connection.send('joy1button'
+ + repr(joystick.getEventNumber(
+ self.mParent.joyID2,
+ i)) \
+ + SYMMSGSEP \
+ + repr(joystick.getEventValue(
+ self.mParent.joyID2,
+ i)) \
+ + PAIRSEPCHAR)
+ except:
+ self.mParent.close()
+
+# Class to poll midi
+class midiTimer(wxTimer):
+ def __init__(self, parent):
+ wxTimer.__init__(self)
+ self.mParent = parent
+ def Notify(self):
+ if (self.mParent.midiID1 > -1):
+ numEvents1 = midi.readEvents(self.mParent.midiID1)
+ if (numEvents1 > 0):
+ self.mParent.showMidiActive(1)
+ for i in range(0, numEvents1):
+ midiCommand = midi.getEventCommand(self.mParent.midiID1, i)
+ midiCommand = hex(midiCommand)
+ midiP1 = midi.getEventP1(self.mParent.midiID1, i)
+ midiP2 = midi.getEventP2(self.mParent.midiID1, i)
+ messageType = midiCommand[2]
+ channel = repr(atoi(midiCommand[3]) + 1)
+ try:
+ if (messageType == MIDINOTEMESSAGE):
+ self.mParent.connection.send('midi0note'
+ + SYMMSGSEP \
+ + repr(midiP1) \
+ + " " \
+ + repr(midiP2) \
+ + " " \
+ + channel \
+ + PAIRSEPCHAR)
+ elif (messageType == MIDICTLMESSAGE):
+ self.mParent.connection.send('midi0ctl'
+ + SYMMSGSEP \
+ + repr(midiP1) \
+ + " " \
+ + repr(midiP2) \
+ + " " \
+ + channel \
+ + PAIRSEPCHAR)
+ elif (messageType == MIDIPGMMESSAGE):
+ self.mParent.connection.send('midi0pgm'
+ + SYMMSGSEP \
+ + repr(midiP1) \
+ + " " \
+ + channel \
+ + PAIRSEPCHAR)
+ except:
+ self.mParent.close()
+ if (self.mParent.midiID2 > -1):
+ numEvents2 = midi.readEvents(self.mParent.midiID2)
+ if (numEvents2 > 0):
+ self.mParent.showMidiActive(2)
+ for i in range(0, numEvents2):
+ midiCommand = midi.getEventCommand(self.mParent.midiID2, i)
+ midiCommand = hex(midiCommand)
+ midiP1 = midi.getEventP1(self.mParent.midiID2, i)
+ midiP2 = midi.getEventP2(self.mParent.midiID2, i)
+ messageType = midiCommand[2]
+ channel = repr(atoi(midiCommand[3]) + 1)
+ try:
+ if (messageType == MIDINOTEMESSAGE):
+ self.mParent.connection.send('midi1note'
+ + SYMMSGSEP \
+ + repr(midiP1) \
+ + " " \
+ + repr(midiP2) \
+ + " " \
+ + channel \
+ + PAIRSEPCHAR)
+ elif (messageType == MIDICTLMESSAGE):
+ self.mParent.connection.send('midi1ctl'
+ + SYMMSGSEP \
+ + repr(midiP1) \
+ + " " \
+ + repr(midiP2) \
+ + " " \
+ + channel \
+ + PAIRSEPCHAR)
+ elif (messageType == MIDIPGMMESSAGE):
+ self.mParent.connection.send('midi1pgm'
+ + SYMMSGSEP \
+ + repr(midiP1) \
+ + " " \
+ + channel \
+ + PAIRSEPCHAR)
+ except:
+ self.mParent.close()
+
+# Class to flash icon between 2 bitmaps
+class iconFlasher(wxTimer):
+ def __init__(self, icon, bitmap1, bitmap2, nFlashes):
+ wxTimer.__init__(self)
+ self.icon = icon
+ self.bitmap1 = bitmap1
+ self.bitmap2 = bitmap2
+ self.nFlashes = nFlashes
+ self.running = False
+ def Start(self, ms):
+ if (not self.running):
+ self.running = True
+ self.flashCount = 0
+ self.activeBitmap = 1
+ wxTimer.Start(self, ms)
+ def Stop(self):
+ self.running = False
+ self.icon.SetBitmap(self.bitmap1)
+ wxTimer.Stop(self)
+ def Notify(self):
+ if (self.flashCount >= self.nFlashes):
+ self.icon.SetBitmap(self.bitmap1)
+ self.icon.Refresh()
+ self.Stop()
+ else:
+ if (self.activeBitmap == 1):
+ self.icon.SetBitmap(self.bitmap2)
+ self.icon.Refresh()
+ self.activeBitmap = 2
+ self.flashCount = self.flashCount + 1
+ else:
+ self.icon.SetBitmap(self.bitmap1)
+ self.activeBitmap = 1
+ self.icon.Refresh()
+
+# Class to hold commands (receive names) while not connected
+class nullConnection:
+ def __init__(self):
+ self.rcvrList = ""
+ def send(self, receiveBuffer):
+ (symName, value) = split(receiveBuffer,SYMMSGSEP)
+ if (symName[0] == COMMANDCHAR):
+ if (symName == SETRCVRCOMMAND):
+ self.rcvrList = self.rcvrList + receiveBuffer
+ def close(self):
+ pass
+
+# Class for holding control info for duplicate (sort of emulates file object)
+class duplicationContainer:
+ def __init__(self):
+ self.list = []
+ def write(self, string):
+ self.list.append(string)
+ def chomp(self):
+ for i in range(0, len(self.list)):
+ self.list[i] = replace(self.list[i], "\n", "")
+ def getList(self):
+ return self.list
+
+# Class for setting options
+class optionsDialog(wxDialog):
+ def __init__(self, parent):
+ self.parent = parent
+ wxDialog.__init__(self, parent.mainFrame, -1, "Configure",
+ wxDefaultPosition, wxDefaultSize,
+ wxDIALOG_MODAL | wxCAPTION)
+
+ titleText = wxStaticText(self, -1, "Window Title:",
+ (DEFOPTIONSPOS[0] + 10,
+ DEFOPTIONSPOS[1] + 20))
+ self.titleBox = wxTextCtrl(self, -1, parent.frameTitle,
+ (titleText.GetPosition()[0] \
+ + titleText.GetSize()[0] + 80,
+ titleText.GetPosition()[1] - 4))
+
+ addrText = wxStaticText(self, -1, "Connection Address:",
+ (titleText.GetPosition()[0],
+ titleText.GetPosition()[1] \
+ + titleText.GetSize()[1] + 15))
+ self.addrBox = wxTextCtrl(self, -1, parent.host,
+ (self.titleBox.GetPosition()[0],
+ addrText.GetPosition()[1] - 4))
+
+ portText = wxStaticText(self, -1, "Connection Port:",
+ (addrText.GetPosition()[0],
+ addrText.GetPosition()[1] \
+ + addrText.GetSize()[1] + 15))
+ self.portBox = wxTextCtrl(self, -1, repr(parent.port),
+ (self.titleBox.GetPosition()[0],
+ portText.GetPosition()[1] - 4))
+
+ pollText = wxStaticText(self, -1, "Socket Poll Time (ms): ",
+ (addrText.GetPosition()[0],
+ portText.GetPosition()[1] \
+ + portText.GetSize()[1] + 15))
+ self.pollBox = wxTextCtrl(self, -1, repr(parent.pollTime),
+ (self.titleBox.GetPosition()[0],
+ pollText.GetPosition()[1] - 4))
+
+ joyDevText1 = wxStaticText(self, -1, "Joystick Device 0: ",
+ (addrText.GetPosition()[0],
+ pollText.GetPosition()[1] \
+ + pollText.GetSize()[1] + 15))
+ self.joyDevBox1 = wxTextCtrl(self, -1, parent.joyDevice1,
+ (self.titleBox.GetPosition()[0],
+ joyDevText1.GetPosition()[1] - 4))
+
+ joyDevText2 = wxStaticText(self, -1, "Joystick Device 1: ",
+ (addrText.GetPosition()[0],
+ joyDevText1.GetPosition()[1] \
+ + joyDevText1.GetSize()[1] + 15))
+ self.joyDevBox2 = wxTextCtrl(self, -1, parent.joyDevice2,
+ (self.titleBox.GetPosition()[0],
+ joyDevText2.GetPosition()[1] - 4))
+
+ joyPollText = wxStaticText(self, -1, "Joystick Poll Time (ms): ",
+ (addrText.GetPosition()[0],
+ joyDevText2.GetPosition()[1] \
+ + joyDevText2.GetSize()[1] + 15))
+ self.joyPollBox = wxTextCtrl(self, -1, repr(parent.joyPollTime),
+ (self.titleBox.GetPosition()[0],
+ joyPollText.GetPosition()[1] - 4))
+
+ midiDevText1 = wxStaticText(self, -1, "MIDI Device 0: ",
+ (addrText.GetPosition()[0],
+ joyPollText.GetPosition()[1] \
+ + joyPollText.GetSize()[1] + 15))
+ self.midiDevBox1 = wxTextCtrl(self, -1, repr(parent.midiDevice1),
+ (self.titleBox.GetPosition()[0],
+ midiDevText1.GetPosition()[1] - 4))
+
+ midiDevText2 = wxStaticText(self, -1, "MIDI Device 1: ",
+ (addrText.GetPosition()[0],
+ midiDevText1.GetPosition()[1] \
+ + midiDevText1.GetSize()[1] + 15))
+ self.midiDevBox2 = wxTextCtrl(self, -1, repr(parent.midiDevice2),
+ (self.titleBox.GetPosition()[0],
+ midiDevText2.GetPosition()[1] - 4))
+
+ midiPollText = wxStaticText(self, -1, "MIDI Poll Time (ms): ",
+ (addrText.GetPosition()[0],
+ midiDevText2.GetPosition()[1] \
+ + midiDevText2.GetSize()[1] + 15))
+ self.midiPollBox = wxTextCtrl(self, -1, repr(parent.midiPollTime),
+ (self.titleBox.GetPosition()[0],
+ midiPollText.GetPosition()[1] - 4))
+
+ bColorText = wxStaticText(self, -1, "Background Color:",
+ (addrText.GetPosition()[0],
+ midiPollText.GetPosition()[1] \
+ + midiPollText.GetSize()[1] + 15))
+ bColorButton = wxButton(self, -1, "Set",
+ (self.titleBox.GetPosition()[0],
+ bColorText.GetPosition()[1] - 4),
+ self.midiPollBox.GetSize())
+
+ rect = wxStaticBox(self, -1, "Options", DEFOPTIONSPOS,
+ (self.addrBox.GetPosition()[0] \
+ + self.addrBox.GetSize()[0] + 10,
+ bColorButton.GetPosition()[1] + \
+ bColorButton.GetSize()[1] + 20))
+ line = wxStaticLine(self, -1, (DEFOPTIONSPOS[0],
+ bColorButton.GetPosition()[1] \
+ + bColorButton.GetSize()[1] + 30),
+ (rect.GetSize()[0], 1))
+ okButton = wxButton(self, -1, "OK", (0, line.GetPosition()[1] + 10))
+ self.SetSize((rect.GetSize()[0] + 15,
+ okButton.GetPosition()[1] + \
+ (FUGEFACTOR * okButton.GetSize()[1]) + \
+ (okButton.GetPosition()[1] - line.GetPosition()[1]) + 4))
+ okButton.Center(wxHORIZONTAL)
+ okButton.Move((okButton.GetPosition()[0], line.GetPosition()[1] + 10))
+ EVT_BUTTON(self, okButton.GetId(), self.eOK)
+ EVT_BUTTON(self, bColorButton.GetId(), self.eBColor)
+ def eOK(self, event):
+ self.EndModal(wxID_OK)
+ def eBColor(self, event):
+ color = getColorFromDialog(self,
+ self.parent.mainFrame.mainPanel.GetBackgroundColour())
+ self.parent.mainFrame.mainPanel.SetBackgroundColour(color)
+ for control in self.parent.controlList:
+ if (control.resetBackground):
+ control.SetBackgroundColour(color)