PathDemo¶
A PyObjC Example without documentation
Sources¶
DemoView.py¶
import random
from math import pi as PI
import Cocoa
import objc
import Quartz
from objc import super # noqa: A004
class DemoView(Cocoa.NSView):
_demoNumber = objc.ivar(type=objc._C_INT)
def initWithFrame_(self, frameRect):
self = super().initWithFrame_(frameRect)
if self is None:
return None
self._demoNumber = 0
return self
def drawRect_(self, rect):
context = Cocoa.NSGraphicsContext.currentContext().graphicsPort()
Quartz.CGContextSetGrayFillColor(context, 1.0, 1.0)
Quartz.CGContextFillRect(context, rect)
if self._demoNumber == 0:
rectangles(context, rect)
elif self._demoNumber == 1:
circles(context, rect)
elif self._demoNumber == 2:
bezierPaths(context, rect)
elif self._demoNumber == 3:
circleClipping(context, rect)
else:
Cocoa.NSLog("Invalid demo number.")
def setDemoNumber_(self, number):
self._demoNumber = number
# The various demo functions
def setRandomFillColor(context):
Quartz.CGContextSetRGBFillColor(
context,
random.uniform(0, 1),
random.uniform(0, 1),
random.uniform(0, 1),
random.uniform(0, 1),
)
def setRandomStrokeColor(context):
Quartz.CGContextSetRGBStrokeColor(
context,
random.uniform(0, 1),
random.uniform(0, 1),
random.uniform(0, 1),
random.uniform(0, 1),
)
def randomPointInRect(rect):
return Quartz.CGPoint(
x=random.uniform(Quartz.CGRectGetMinX(rect), Quartz.CGRectGetMaxX(rect)),
y=random.uniform(Quartz.CGRectGetMinY(rect), Quartz.CGRectGetMaxY(rect)),
)
def randomRectInRect(rect):
p = randomPointInRect(rect)
q = randomPointInRect(rect)
return Quartz.CGRectMake(p.x, p.y, q.x - p.x, q.y - p.y)
def rectangles(context, rect):
# Draw random rectangles (some stroked, some filled).
for k in range(20):
if k % 2 == 0:
setRandomFillColor(context)
Quartz.CGContextFillRect(context, randomRectInRect(rect))
else:
setRandomStrokeColor(context)
Quartz.CGContextSetLineWidth(context, 2 + random.randint(0, 10))
Quartz.CGContextStrokeRect(context, randomRectInRect(rect))
def circles(context, rect):
# Draw random circles (some stroked, some filled).
for k in range(20):
r = randomRectInRect(rect)
w = Quartz.CGRectGetWidth(r)
h = Quartz.CGRectGetHeight(r)
Quartz.CGContextBeginPath(context)
if w < h:
v = w
else:
v = h
Quartz.CGContextAddArc(
context,
Quartz.CGRectGetMidX(r),
Quartz.CGRectGetMidY(r),
v,
0,
2 * PI,
False,
)
Quartz.CGContextClosePath(context)
if k % 2 == 0:
setRandomFillColor(context)
Quartz.CGContextFillPath(context)
else:
setRandomStrokeColor(context)
Quartz.CGContextSetLineWidth(context, 2 + random.randint(0, 10))
Quartz.CGContextStrokePath(context)
def bezierPaths(context, rect):
for k in range(20):
numberOfSegments = 1 + random.randint(0, 8)
Quartz.CGContextBeginPath(context)
p = randomPointInRect(rect)
Quartz.CGContextMoveToPoint(context, p.x, p.y)
for j in range(numberOfSegments):
p = randomPointInRect(rect)
if j % 2 == 0:
Quartz.CGContextAddLineToPoint(context, p.x, p.y)
else:
c1 = randomPointInRect(rect)
c2 = randomPointInRect(rect)
Quartz.CGContextAddCurveToPoint(
context, c1.x, c1.y, c2.x, c2.y, p.x, p.y
)
if k % 2 == 0:
setRandomFillColor(context)
Quartz.CGContextClosePath(context)
Quartz.CGContextFillPath(context)
else:
setRandomStrokeColor(context)
Quartz.CGContextSetLineWidth(context, 2 + random.randint(0, 10))
Quartz.CGContextStrokePath(context)
def circleClipping(context, rect):
# Draw a random path through a circular clip.
w = Quartz.CGRectGetWidth(rect)
h = Quartz.CGRectGetHeight(rect)
Quartz.CGContextBeginPath(context)
if w < h:
v = w
else:
v = h
Quartz.CGContextAddArc(
context,
Quartz.CGRectGetMidX(rect),
Quartz.CGRectGetMidY(rect),
v / 2,
0,
2 * PI,
False,
)
Quartz.CGContextClosePath(context)
Quartz.CGContextClip(context)
# Draw something into the clip.
bezierPaths(context, rect)
# Draw a clip path on top as a black stroked circle.
Quartz.CGContextBeginPath(context)
Quartz.CGContextAddArc(
context,
Quartz.CGRectGetMidX(rect),
Quartz.CGRectGetMidY(rect),
v / 2,
0,
2 * PI,
False,
)
Quartz.CGContextClosePath(context)
Quartz.CGContextSetLineWidth(context, 1)
Quartz.CGContextSetRGBStrokeColor(context, 0, 0, 0, 1)
Quartz.CGContextStrokePath(context)
PathDemoController.py¶
import Cocoa
import objc
class PathDemoController(Cocoa.NSObject):
button = objc.ivar()
popup = objc.ivar()
window = objc.ivar()
demoView = objc.ivar()
def awakeFromNib(self):
# Add the title of your new demo to the END of this array.
titles = ["Rectangles", "Circles", "Bezier Paths", "Circle Clipping"]
self.popup.removeAllItems()
for t in titles:
self.popup.addItemWithTitle_(t)
@objc.IBAction
def runAgain_(self, sender):
self.select_(self)
@objc.IBAction
def select_(self, sender):
self.demoView.setDemoNumber_(self.popup.indexOfSelectedItem())
self.demoView.setNeedsDisplay_(True)
def applicationShouldTerminateAfterLastWindowClosed_(self, application):
return True
main.py¶
import DemoView # noqa: F401
import PathDemoController # noqa: F401
from PyObjCTools import AppHelper
AppHelper.runEventLoop()
setup.py¶
"""
Script for building the example.
Usage:
python3 setup.py py2app
"""
from setuptools import setup
setup(
name="PathDemo",
app=["main.py"],
data_files=["English.lproj"],
setup_requires=["py2app", "pyobjc-framework-Cocoa", "pyobjc-framework-Quartz"],
)