Commits

Brendan Howell committed 71cfc3c

some little hacks for png transparency

Comments (0)

Files changed (2)

pycessing/images.py

 PROJECT_DIR = None
 CTX = None
 
+
 class Image:
     """All-purpose class for cairo-based pixel images in pycessing"""
     def __init__(self, file_name):
 
         self.width = surface.get_width()
         self.height = surface.get_height()
-        ar = pygame.surfarray.array2d(surface)
-        stride = surface.get_width() * 4
-        self.surface = cairo.ImageSurface.create_for_data(ar,
-                                                          cairo.FORMAT_ARGB32, surface.get_width(),
-                                                          surface.get_height(), stride)
+
+        if imagelike.endswith(".png"):
+            self.surface = cairo.ImageSurface.create_from_png(imagelike)
+        else:
+            ar = pygame.surfarray.array2d(surface)
+            stride = surface.get_width() * 4
+            self.surface = cairo.ImageSurface.create_for_data(ar,
+                                                              cairo.FORMAT_ARGB32, surface.get_width(),
+                                                              surface.get_height(), stride)
+
         self.loaded = True
 
     def draw(self, x, y, centerx=0.0, centery=0.0):

pycessing/mainwindow.py

 #TODO: cut and paste from help browser
 
 from PyQt4 import QtGui, QtCore, Qsci, QtWebKit
-import os, subprocess, signal, tempfile, sys, glob
-from pkg_resources import resource_string, resource_stream, resource_listdir, resource_filename
+import os
+import tempfile
+import sys
+import glob
+from pkg_resources import resource_string, resource_filename
+
 
 class MainWindow(QtGui.QMainWindow):
     def __init__(self):
         self.resize(1024, 500)
         self.setWindowTitle('PyCessing')
         self.fileName = None
-        
+
         self.splitter = QtGui.QSplitter(QtCore.Qt.Vertical)
         self.setCentralWidget(self.splitter)
-        
+
         self.setupToolbar()
         self.setupEditor()
         self.setupMessageBox()
         self.statusBar()
-        
+
         self.setupFileMenu()
         self.setupEditMenu()
         self.setupProgramMenu()
         self.setupHelpMenu()
         self.sketchPID = None
 
-        
     def about(self):
-        QtGui.QMessageBox.about(self,"About Pycessing","Copyright 2012 <br />Brendan Howell<br />Licensed Under the GPL3.")
-        
+        QtGui.QMessageBox.about(self, "About Pycessing", "Copyright 2012 <br />Brendan Howell<br />Licensed Under the GPL3.")
+
     #TODO: this should open a new tab (or window)
     def newFile(self):
         response = None
-        
+
         if self.textEdit.isModified():
             #options = QtGui.QMessageBox.Ok + QtGui.QMessageBox.NoButton
-            response = QtGui.QMessageBox.critical(self,"New Program","Current file is not saved.  Are you sure you want to discard your changes?", QtGui.QMessageBox.Discard, QtGui.QMessageBox.Cancel, QtGui.QMessageBox.Save)
-        
+            response = QtGui.QMessageBox.critical(self, "New Program", "Current file is not saved.  Are you sure you want to discard your changes?", QtGui.QMessageBox.Discard, QtGui.QMessageBox.Cancel, QtGui.QMessageBox.Save)
+
         if response == QtGui.QMessageBox.Cancel:
             return False
         elif response == QtGui.QMessageBox.Save:
             self.saveFile()
-        
+
         self.textEdit.clear()
         self.fileName = None
         self.setWindowTitle('PyCessing')
         return True
-        
+
     def openFile(self):
         if not(self.newFile()):
             return
             newFile.close()
             shortname = os.path.basename(str(self.fileName))
             self.setWindowTitle('PyCessing - ' + shortname)
-            
+
     def openExample(self, filename):
         if not(self.newFile()):
             return
-        examplecode = resource_string(__name__,'data/examples/' + filename + '.cess')
+        examplecode = resource_string(__name__, 'data/examples/' + filename + '.cess')
         self.textEdit.setText(examplecode)
         self.setWindowTitle('PyCessing - ' + filename)
-            
+
     def setupEditor(self):
         font = QtGui.QFont()
         font.setFamily("Droid Sans Mono")
         if font.family() != "Droid Sans Mono":
-            droidfile = resource_filename(__name__,'data/fonts/DroidSansMono.ttf')
+            droidfile = resource_filename(__name__, 'data/fonts/DroidSansMono.ttf')
             err = QtGui.QFontDatabase.addApplicationFont(droidfile)
             font.setFamily("Droid Sans Mono")
             if err == -1:
         font.setFixedPitch(True)
         font.setPointSize(13)
         font.setItalic(False)
-        
+
         fontMetrics = QtGui.QFontMetrics(font)
-        
+
         self.textEdit = Qsci.QsciScintilla(self)
         lexer = Qsci.QsciLexerPython()
         lexer.setFont(font)
         self.textEdit.setLexer(lexer)
-        
+
         #TODO: make style 1 - python comments - italic
         #self.textEdit.SendScintilla(Qsci.QsciScintilla.SCI_STYLESETFONT, 1, 'Courier')
-        
+
         self.textEdit.setAutoIndent(True)
         self.textEdit.setIndentationWidth(4)
         self.textEdit.setIndentationsUseTabs(False)
         self.textEdit.setMarginsFont(font)
         self.textEdit.setMarginWidth(0, fontMetrics.width("00000") + 5)
-        self.textEdit.setMarginLineNumbers(0,True)
-        
+        self.textEdit.setMarginLineNumbers(0, True)
+
         self.textEdit.setCaretLineVisible(True)
         self.textEdit.setCaretLineBackgroundColor(QtGui.QColor("#ffe4e4"))
-        
+
         self.textEdit.setEdgeMode(Qsci.QsciScintilla.EdgeLine)
         self.textEdit.setEdgeColumn(80)
         self.textEdit.setWrapMode(Qsci.QsciScintilla.WrapNone)
         self.textEdit.setBraceMatching(Qsci.QsciScintilla.SloppyBraceMatch)
-        
+
         self.splitter.addWidget(self.textEdit)
         #size = self.textEdit.sizeHint()
         #size.setWidth(8)
         #    size.setHeight(300)
         #print "size: " + str(size.width()) + " x " + str(size.height())
         self.textEdit.SendScintilla(Qsci.QsciScintilla.SCI_SETHSCROLLBAR, 0)
-        self.textEdit.setMinimumSize(600,450)
+        self.textEdit.setMinimumSize(600, 450)
+
+        self.textEdit.resize(800, 500)
 
-        self.textEdit.resize(800,500)
-        
     def setupMessageBox(self):
-    	self.messageBox = QtGui.QTextEdit(self)
-    	self.messageBox.setReadOnly(True)
-    	self.splitter.addWidget(self.messageBox)
-    	#self.messageBox.setAutoFormatting(QtGui.QTextBrowser.LogText)
-        
+        self.messageBox = QtGui.QTextEdit(self)
+        self.messageBox.setReadOnly(True)
+
+        self.messageBox.setTextBackgroundColor(QtGui.QColor("#000"))
+        self.messageBox.setTextColor(QtGui.QColor("#FFF"))
+
+
+
+        self.splitter.addWidget(self.messageBox)
+
+        #add keyboard shortcut for copy
+        #self.messageBox.cp = QtGui.QShortcut(self.messageBox)
+        #self.messageBox.cp.setKey(QtGui.QKeySequence(QtGui.QKeySequence.Copy))
+        #self.messageBox.cp.setContext(QtCore.Qt.WidgetShortcut)
+        #self.messageBox.cp.activated.connect(self.messageBox.copy)
+        self.msgcp = QtGui.QAction('msgcp', self.messageBox)
+        self.msgcp.setShortcut(QtGui.QKeySequence(QtGui.QKeySequence.Copy))
+        self.msgcp.setShortcutContext(QtCore.Qt.WidgetShortcut)
+        self.messageBox.addAction(self.msgcp)
+        self.msgcp.triggered.connect(self.messageBox.copy)
+
+        #self.messageBox.setAutoFormatting(QtGui.QTextBrowser.LogText)
+
     def setupFileMenu(self):
-        iconfile = resource_filename(__name__,'data/icons/exit.png')
+        iconfile = resource_filename(__name__, 'data/icons/exit.png')
         exit = QtGui.QAction(QtGui.QIcon(iconfile), '&Quit', self)
         exit.setShortcut('Ctrl+Q')
         exit.setStatusTip('Exit application')
         self.connect(exit, QtCore.SIGNAL('triggered()'), QtCore.SLOT('close()'))
-               
+
         menubar = self.menuBar()
         fileMenu = menubar.addMenu('&File')
-        
+
         #TODO: ctrl-W should close the tab
         fileMenu.addAction("&New", self.newFile, QtGui.QKeySequence("Ctrl+N"))
         exampleMenu = fileMenu.addMenu("Examples")
         fileMenu.addAction("Save &As", self.saveFileAs, QtGui.QKeySequence("Shift+Ctrl+S"))
         fileMenu.addAction("&Print", self.printFile, QtGui.QKeySequence("Ctrl+P"))
         fileMenu.addAction(exit)
-        
-        exampleDir = resource_filename(__name__,"data/examples/")
+
+        exampleDir = resource_filename(__name__, "data/examples/")
         examples = glob.glob(exampleDir + '*.cess')
         #glob examples
         #TODO: glob sub-directories
         for example in examples:
             example = os.path.basename(example)
-            example = example.replace('.cess','')
+            example = example.replace('.cess', '')
             exMenuItem = exampleMenu.addAction(example)
             receiver = lambda example=example: self.openExample(example)
             self.connect(exMenuItem, QtCore.SIGNAL('triggered()'), receiver)
 
     def setupToolbar(self):
         toolbar = self.addToolBar('Toolbar')
-        iconfile = resource_filename(__name__,'data/icons/play.png')
+        iconfile = resource_filename(__name__, 'data/icons/play.png')
         self.playToggle = QtGui.QAction(QtGui.QIcon(iconfile), 'Run Program', toolbar)
         self.connect(self.playToggle, QtCore.SIGNAL('triggered()'), self.togglePlaying)
         toolbar.addAction(self.playToggle)
-       
-	    #add spacer
+
+        #add spacer
         spacer = QtGui.QWidget(self)
         spacer.setSizePolicy(QtGui.QSizePolicy.MinimumExpanding, QtGui.QSizePolicy.Preferred)
         toolbar.addWidget(spacer)
-        
+
         #add find widget
         self.findEdit = QtGui.QLineEdit(self)
         self.findEdit.setFixedSize(QtCore.QSize(200, self.findEdit.height()))
         toolbar.addWidget(self.findEdit)
-        
+
         #add expandable spacer
-        
+
         # find button
-        iconfile = resource_filename(__name__,"data/icons/Edit-find.png")
+        iconfile = resource_filename(__name__, "data/icons/Edit-find.png")
         self.findbutton = QtGui.QAction(QtGui.QIcon(iconfile), 'Find in Program', toolbar)
         self.connect(self.findbutton, QtCore.SIGNAL('triggered()'), self.findNext)
         toolbar.addAction(self.findbutton)
 
-        #add help browser toggle        
-        iconfile = resource_filename(__name__,"data/icons/help-browser.png")
+        #add help browser toggle
+        iconfile = resource_filename(__name__, "data/icons/help-browser.png")
         self.helptoggle = QtGui.QAction(QtGui.QIcon(iconfile), 'Show / Hide Help', toolbar)
         self.connect(self.helptoggle, QtCore.SIGNAL('triggered()'), self.toggleHelpBrowser)
         #help hide / show action
         toolbar.addAction(self.helptoggle)
-        
+
     def setupHelpMenu(self):
-        iconfile = resource_filename(__name__,'data/icons/about.png')
+        iconfile = resource_filename(__name__, 'data/icons/about.png')
         aboutItem = QtGui.QAction(QtGui.QIcon(iconfile), 'About', self)
         self.connect(aboutItem, QtCore.SIGNAL('triggered()'), self.about)
-    
+
         menubar = self.menuBar()
         helpMenu = menubar.addMenu('&Help')
         helpMenu.addAction(aboutItem)
-        
+
         self.helpwindow = QtGui.QDockWidget("Doc Browser")
         self.helpwindow.setAllowedAreas(QtCore.Qt.RightDockWidgetArea)
         #self.helpwindow.setMinimumWidth(400)
         helpAction.setText("&Help Browser")
         helpAction.setShortcut(QtGui.QKeySequence("F1"))
         helpMenu.addAction(helpAction)
- 
+
         self.addDockWidget(QtCore.Qt.RightDockWidgetArea, self.helpwindow)
-        #self.helpwindow.resize(400, self.height())       
-        
+        #self.helpwindow.resize(400, self.height())
+
         helpbrowser = QtWebKit.QWebView(self.helpwindow)
-        indexpath = resource_filename(__name__,"data/help/index.html")
+        indexpath = resource_filename(__name__, "data/help/index.html")
         url = QtCore.QUrl("file://" + indexpath)
         helpbrowser.load(url)
         helpbrowser.show()
         helpbrowser.updateGeometry()
         helpbrowser.update()
-        
+
         helpbrowser.setMinimumWidth(400)
-        helpbrowser.setMinimumHeight( self.helpwindow.height())
+        helpbrowser.setMinimumHeight(self.helpwindow.height())
         self.helpwindow.setWidget(helpbrowser)
 
-        #sizepolicy = self.helpwindow.sizePolicy()
-        #sizepolicy.setVerticalStretch(QtGui.QSizePolicy.Expanding)
-        
-
-        
-##        helpbrowser = QtGui.QTextBrowser(self.helpwindow)
-##        csspath = resource_filename(__name__,"data/help/media/css/style.css")
-##        csstxt = open(csspath).read()
-##        helpbrowser.document().setDefaultStyleSheet(csstxt)
-##        helpbrowser.setOpenExternalLinks(True)
-##        
-##        indexpath = resource_filename(__name__,"data/help/index.html")
-##        url = QtCore.QUrl("file://" + indexpath)
-##        helpbrowser.setSource(url)
-##        helpbrowser.resize(400, self.helpwindow.height())
-
-        
     def setupEditMenu(self):
         menubar = self.menuBar()
         editMenu = menubar.addMenu('&Edit')
-        
+
         editMenu.addAction('&Undo', self.textEdit.undo, QtGui.QKeySequence("Ctrl+Z"))
         editMenu.addAction('&Redo', self.textEdit.redo, QtGui.QKeySequence("Shift+Ctrl+Z"))
-        
+
         editMenu.addSeparator()
-        
+
         editMenu.addAction('Cu&t', self.textEdit.cut, QtGui.QKeySequence("Ctrl+X"))
         editMenu.addAction('&Copy', self.textEdit.copy, QtGui.QKeySequence("Ctrl+C"))
         editMenu.addAction('&Paste', self.textEdit.paste, QtGui.QKeySequence("Ctrl+V"))
         #editMenu.addAction('&Delete', self.textEdit.delete, QtGui.QKeySequence("Del"))
-        
+
         editMenu.addSeparator()
-        
+
         editMenu.addAction('&Indent', self.doIndent, QtGui.QKeySequence("Ctrl+T"))
         editMenu.addAction('&Un-indent', self.doUnIndent, QtGui.QKeySequence("Shift+Ctrl+T"))
-        
+
     def setupProgramMenu(self):
         menubar = self.menuBar()
         progMenu = menubar.addMenu("&Program")
-        
+
         progMenu.addAction('&Run / Stop', self.togglePlaying, QtGui.QKeySequence("Ctrl+R"))
-    
-    #TODO: catch file exceptions    
+
+    #TODO: catch file exceptions
     def saveFile(self):
         if not(self.fileName):
             self.saveFileAs()
         fp = open(self.fileName, "w")
         fp.write(self.textEdit.text())
         fp.close()
-        
+
     def saveFileAs(self):
         self.fileName = QtGui.QFileDialog.getSaveFileName(self, "Save File", "", "Pycessing program (*.cess)")
         if not(self.fileName.endsWith(".cess")):
         self.saveFile()
         shortname = os.path.basename(str(self.fileName))
         self.setWindowTitle('PyCessing - ' + shortname)
-        
+
     def printFile(self):
-        pass 
-        
+        pass
+
     def helpContents(self):
         QtGui.QDesktopServices.openUrl(QtCore.QUrl("help/index.html"))
-        
+
     def doIndent(self):
         (lineFrom, indexFrom, lineTo, indexTo) = self.textEdit.getSelection()
         if(lineFrom == -1):
             line, index = self.textEdit.getCursorPosition()
             self.textEdit.indent(line)
         else:
-            for curLine in range(lineFrom, lineTo+1):
+            for curLine in range(lineFrom, lineTo + 1):
                 self.textEdit.indent(curLine)
-                
+
     def doUnIndent(self):
         (lineFrom, indexFrom, lineTo, indexTo) = self.textEdit.getSelection()
         if(lineFrom == -1):
             line, index = self.textEdit.getCursorPosition()
             self.textEdit.unindent(line)
         else:
-            for curLine in range(lineFrom, lineTo+1):
+            for curLine in range(lineFrom, lineTo + 1):
                 self.textEdit.unindent(curLine)
-    
+
     def _saveTmp(self):
         #FIXME: this might be kinda insecure
         if self.textEdit.isModified():
             fp = open(self.tempFile, "w")
             fp.write(self.textEdit.text())
             fp.close()
-        
+
     def togglePlaying(self):
-        if(self.running):         
+        if(self.running):
             self.sketchPID.kill()
-            
+
         else:
             self.messageBox.clear()
-            self.messageBox.append("starting...")            
+            self.messageBox.append("starting...")
             print "starting program"
-            
+
             #fork the child process
             self._saveTmp()
             #app = "/opt/local/bin/python"
             app = sys.executable
-            if self.fileName != None:
+            if self.fileName is not None:
                 progdir = os.path.dirname(str(self.fileName))
             else:
-                progdir = resource_filename(__name__,'data/examples/')
-            run_py = resource_filename(__name__,"run.py")
+                progdir = resource_filename(__name__, 'data/examples/')
+            run_py = resource_filename(__name__, "run.py")
             args = ["-u", run_py, self.tempFile, progdir]
             self.sketchPID = QtCore.QProcess(self)
-                              
+
             self.connect(self.sketchPID, QtCore.SIGNAL('finished(int,QProcess::ExitStatus)'), self._progStopped)
             self.connect(self.sketchPID, QtCore.SIGNAL('readyReadStandardOutput()'), self._outMessage)
             self.connect(self.sketchPID, QtCore.SIGNAL('readyReadStandardError()'), self._errorMessage)
             self.sketchPID.start(app, args)
             self.sketchPID.waitForStarted()
-            
+
             self.running = True
-            iconfile = resource_filename(__name__,'data/icons/Process-stop.png')
+            iconfile = resource_filename(__name__, 'data/icons/Process-stop.png')
             self.playToggle.setIcon(QtGui.QIcon(iconfile))
             self.playToggle.setToolTip("Stop running program")
             self.statusBar().showMessage("Program Running...")
-            
+
     def toggleHelpBrowser(self):
         self.helpwindow.setVisible(not(self.helpwindow.isVisible()))
-        
-        
+
     def findNext(self):
-    	searchString = self.findEdit.text()
-    	self.textEdit.findFirst(searchString, False, False, False, True)
-            
+        searchString = self.findEdit.text()
+        self.textEdit.findFirst(searchString, False, False, False, True)
+
     def _progStopped(self, exitcode, exitstatus):
         print "program stopped:"
         print exitstatus
         #Normal exit actually means python errored out, crash means it was stopped by user
         if exitstatus == QtCore.QProcess.CrashExit:
-	        self.statusBar().showMessage("Program Stopped")
+            self.statusBar().showMessage("Program Stopped")
         else:
             self.statusBar().showMessage("Oops! Program Crashed")
         self.running = False
-        iconfile = resource_filename(__name__,'data/icons/play.png')
+        iconfile = resource_filename(__name__, 'data/icons/play.png')
         self.playToggle.setIcon(QtGui.QIcon(iconfile))
         self.playToggle.setToolTip("Run program")
-    	
+
     def _errorMessage(self):
         self.sketchPID.setReadChannel(QtCore.QProcess.StandardError)
+        self.messageBox.setTextColor(QtGui.QColor("#F00"))
         while(self.sketchPID.canReadLine()):
             self.messageBox.append(QtCore.QString(self.sketchPID.readLine()))
-    
+
     def _outMessage(self):
         self.sketchPID.setReadChannel(QtCore.QProcess.StandardOutput)
+        self.messageBox.setTextColor(QtGui.QColor("#FFF"))
         while(self.sketchPID.canReadLine()):
             self.messageBox.append(QtCore.QString(self.sketchPID.readLine()))
-
-          
-