main.py
from PyObjCTools import AppHelper
import AppDelegate
import MyBaseGradientView
import MyBezierGradientView
import MyRectGradientView
import MyWindowController
AppHelper.runEventLoop()
This example shows how to use NSGradient.
from Cocoa import *
from MyWindowController import *
class AppDelegate (NSObject):
myWindowController = objc.ivar()
@objc.IBAction
def newDocument_(self, sender):
if self.myWindowController is None:
self.myWindowController = MyWindowController.alloc().initWithWindowNibName_("TestWindow")
self.myWindowController.showWindow_(self)
def applicationDidFinishLaunching_(self, notification):
self.newDocument_(self)
def validateMenuItem_(self, theMenuItem):
enable = self.respondsToSelector_(theMenuItem.action())
# disable "New" if the window is already up
if theMenuItem.action() == 'newDocument:':
if self.myWindowController.window().isKeyWindow():
enable = False
return enable
from Cocoa import *
class MyBaseGradientView (NSView):
myGradient = objc.ivar()
myStartColor = objc.ivar()
myEndColor = objc.ivar()
forceColorChange = objc.ivar.bool()
myAngle = objc.ivar.double()
myIsRadial = objc.ivar.bool()
myOffsetPt = objc.ivar.NSPoint()
def resetGradient(self):
if self.forceColorChange and self.myGradient is not None:
self.myGradient = None
if self.myGradient is None:
self.myGradient = NSGradient.alloc().initWithStartingColor_endingColor_(
self.myStartColor, self.myEndColor)
self.forceColorChange = False
def setStartColor_(self, startColor):
self.myStartColor = startColor
self.forceColorChange = True
self.setNeedsDisplay_(True)
def setEndColor_(self, endColor):
self.myEndColor = endColor;
self.forceColorChange = True
self.setNeedsDisplay_(True)
def setAngle_(self, angle):
self.myAngle = angle
self.setNeedsDisplay_(True)
def setRadialDraw_(self, isRadial):
self.myIsRadial = isRadial
self.setNeedsDisplay_(True)
def getRelativeCenterPositionFromEvent_(self, theEvent):
curMousePt = self.convertPoint_fromView_(theEvent.locationInWindow(), None)
pt = NSMakePoint( (curMousePt.x - NSMidX(self.bounds())) / (self.bounds().size.width / 2.0),
(curMousePt.y - NSMidY(self.bounds())) / (self.bounds().size.height / 2.0))
return pt
def mouseDown_(self, theEvent):
if self.myIsRadial:
self.myOffsetPt = self.getRelativeCenterPositionFromEvent_(theEvent)
self.setNeedsDisplay_(True)
def mouseDragged_(self, theEvent):
if self.myIsRadial:
self.myOffsetPt = self.getRelativeCenterPositionFromEvent_(theEvent)
self.setNeedsDisplay_(True)
from MyBaseGradientView import *
class MyBezierGradientView (MyBaseGradientView):
def init(self):
self = super(MyBaseGradientView, self).init()
if self is None:
return None
self.myOffsetPt = NSMakePoint(0.0, 0.0)
return self
def drawRect_(self, rect):
self.resetGradient()
bezierPath = NSBezierPath.alloc().init()
bezierPath.appendBezierPathWithOvalInRect_(rect)
if self.myIsRadial:
self.myGradient.drawInBezierPath_relativeCenterPosition_(bezierPath, self.myOffsetPt)
else:
self.myGradient.drawInBezierPath_angle_(bezierPath, self.myAngle)
from MyBaseGradientView import *
class MyRectGradientView (MyBaseGradientView):
def init(self):
self = super(MyRectGradientView, self).init()
if self is None:
return self
self.myOffsetPt = NSMakePoint(0.0, 0.0)
return self
def drawRect_(self, rect):
self.resetGradient()
# if the "Radial Gradient" checkbox is turned on, draw using 'myOffsetPt'
if self.myIsRadial:
self.myGradient.drawInRect_relativeCenterPosition_(self.bounds(), self.myOffsetPt)
else:
self.myGradient.drawInRect_angle_(self.bounds(), self.myAngle)
from Cocoa import *
class MyWindowController (NSWindowController):
rectGradientView = objc.IBOutlet()
bezierGradientView = objc.IBOutlet()
startColorWell = objc.IBOutlet()
endColorWell = objc.IBOutlet()
angle = objc.IBOutlet()
angleSlider = objc.IBOutlet()
radialCheck = objc.IBOutlet()
radialExplainText = objc.IBOutlet()
def initWithPath_(self, newPath):
return super(MyWindowController, self).initWithWindowNibName_("TestWindow")
def awakeFromNib(self):
# make sure our angle text input keep the right format
formatter = NSNumberFormatter.alloc().init()
formatter.setNumberStyle_(NSNumberFormatterDecimalStyle)
self.angle.cell().setFormatter_(formatter)
# setup the initial start color
self.rectGradientView.setStartColor_(NSColor.orangeColor())
self.bezierGradientView.setStartColor_(NSColor.orangeColor())
self.startColorWell.setColor_(NSColor.orangeColor())
# setup the initial end color
self.rectGradientView.setEndColor_(NSColor.blueColor())
self.bezierGradientView.setEndColor_(NSColor.blueColor())
self.endColorWell.setColor_(NSColor.blueColor())
# setup the initial angle value
self.rectGradientView.setAngle_(90.0)
self.bezierGradientView.setAngle_(90.0)
self.angle.setStringValue_("90.0")
self.angleSlider.setFloatValue_(90.0)
@objc.IBAction
def swapColors_(self, sender):
startColor = self.startColorWell.color()
endColor = self.endColorWell.color()
# change all our view's start and end colors
self.rectGradientView.setStartColor_(endColor)
self.rectGradientView.setEndColor_(startColor)
self.bezierGradientView.setStartColor_(endColor)
self.bezierGradientView.setEndColor_(startColor)
# fix our color wells
self.startColorWell.setColor_(endColor)
self.endColorWell.setColor_(startColor)
@objc.IBAction
def startColor_(self, sender):
newColor = sender.color()
self.rectGradientView.setStartColor_(newColor)
self.bezierGradientView.setStartColor_(newColor)
@objc.IBAction
def endColor_(self, sender):
newColor = sender.color()
self.rectGradientView.setEndColor_(newColor)
self.bezierGradientView.setEndColor_(newColor)
def controlTextDidEndEditing_(self, notification):
theAngle = self.angle.floatValue()
self.rectGradientView.setAngle_(theAngle)
self.bezierGradientView.setAngle_(theAngle)
theAngleDougle = self.angle.doubleValue()
self.angleSlider.setDoubleValue_(theAngleDougle)
self.angleSlider.setNeedsDisplay_(True)
@objc.IBAction
def angleSliderChange_(self, sender):
angleValue = sender.floatValue()
self.rectGradientView.setAngle_(angleValue)
self.bezierGradientView.setAngle_(angleValue)
self.angle.setDoubleValue_(angleValue)
@objc.IBAction
def radialDraw_(self, sender):
self.rectGradientView.setRadialDraw_(sender.selectedCell().state())
self.bezierGradientView.setRadialDraw_(sender.selectedCell().state())
# angle factor does not relate to radial draws
self.angleSlider.setEnabled_(not sender.selectedCell().state())
self.angle.setEnabled_(not sender.selectedCell().state())
# hide/show the explain text for radial gradients
self.radialExplainText.setHidden_(not sender.selectedCell().state())
from PyObjCTools import AppHelper
import AppDelegate
import MyBaseGradientView
import MyBezierGradientView
import MyRectGradientView
import MyWindowController
AppHelper.runEventLoop()
"""
Script for building the example.
Usage:
python setup.py py2app
"""
from distutils.core import setup
import py2app
setup(
name="Grady",
app=["main.py"],
data_files=["English.lproj"],
)