1import objc 2from Foundation import * 3from AppKit import * 4from math import pi, sin, cos 5from fieldMath import * 6 7# Convience global variables 8x, y = 0, 1 9llc, sze = 0, 1 # Left Lower Corner, Size 10 11#____________________________________________________________ 12class CGraphView(NSView): 13 14 azmuthSlider = objc.IBOutlet() 15 mapOffsetEWSlider = objc.IBOutlet() 16 mapOffsetNSSlider = objc.IBOutlet() 17 mapScaleSlider = objc.IBOutlet() 18 mapVisibleSlider = objc.IBOutlet() 19 azmuthDisplay = objc.IBOutlet() 20 mapOffsetEWDisplay = objc.IBOutlet() 21 mapOffsetNSDisplay = objc.IBOutlet() 22 mapScaleDisplay = objc.IBOutlet() 23 24 def initWithFrame_(self, frame): 25 super(CGraphView, self).initWithFrame_(frame) 26 self.setGridColor() 27 self.setRmsColor() 28 self.setGraphColor() 29 self.graphMargin = 2 30 self.mapImage = 0 31 self.mapRect = 0 32 self.mapVisible = 0.70 33 self.mapScale = 3.0 34 self.mapOffsetEW = 0.27 35 self.mapOffsetNS = 0.40 36 self.mapBaseRadius = 200 37 38 self.lines = 2 39 self.gain = 0.5 40 return self 41 42 def awakeFromNib(self): 43 self.setCrossCursor() 44 self.mapVisibleSlider.setFloatValue_(self.mapVisible) 45 self.setAzmuth(125) 46 self.setMapRect() 47 48 def setCrossCursor(self): 49 crosshairImage = NSImage.imageNamed_("CrossCursor") 50 imageSize = crosshairImage.size() 51 self.crossCursor = NSCursor.alloc().initWithImage_hotSpot_(crosshairImage, (8, 8)) 52 rect = self.bounds() 53 self.trackingRect = self.addTrackingRect_owner_userData_assumeInside_(self.bounds(), self, 0, 0) 54 55 def setGridColor(self, color=NSColor.greenColor()): 56 self.gridColor = color 57 58 def setRmsColor(self, color=NSColor.blueColor()): 59 self.rmsColor = color 60 61 def setGraphColor(self, color=NSColor.blackColor()): 62 self.graphColor = color 63 64 def setGain(self, gain, total): 65 self.gain = gain 66 self.totalField = total 67 68 def setLines(self, lines): 69 self.lines = lines 70 71 def setMapImage(self, mapImage): 72 self.mapImage = mapImage 73 self.mapRect = ((0, 0), mapImage.size()) 74 75 def setPath(self, path, maxMag): 76 self.path = path 77 self.maxMag = maxMag 78 self.setNeedsDisplay_(1) 79 80 81 def drawRect_(self, rect): 82 frame = self.frame() 83 self.origin = frame[0] 84 self.graphCenter = (frame[sze][x]/2, frame[sze][y]/2) 85 self.graphRadius = (min(frame[sze][x], frame[sze][y]) / 2) - self.graphMargin 86 87 NSColor.whiteColor().set() 88 NSRectFill(self.bounds()) 89 90 self.drawMap() 91 self.drawGrid() 92 self.drawRMS() 93 self.drawField() 94 95 def drawMap(self): 96 if self.mapImage == 0: 97 return 98 99 scale = self.mapScale * (self.graphRadius / self.mapBaseRadius) * self.gain / self.totalField 100 xImageSize = scale * self.mapRect[sze][x] 101 yImageSize = scale * self.mapRect[sze][y] 102 xCenterMove = self.graphCenter[x] - self.graphRadius 103 yCenterMove = self.graphCenter[y] - self.graphRadius 104 105 xOffset = -((1 - self.mapOffsetEW) / 2) * xImageSize 106 yOffset = -((1 + self.mapOffsetNS) / 2) * yImageSize 107 xOffset += self.graphRadius + xCenterMove 108 yOffset += self.graphRadius + yCenterMove 109 110 drawInRect = ((xOffset, yOffset), (xImageSize, yImageSize)) 111 112 self.mapImage.drawInRect_fromRect_operation_fraction_(drawInRect, self.mapRect, NSCompositeSourceOver, self.mapVisible) 113 114 def drawGrid(self): 115 self.gridColor.set() 116 self.drawCircle(1.0) 117 self.drawAxisLines() 118 119 def drawCircle(self, scale): 120 center = self.graphCenter 121 radius = self.graphRadius*scale 122 x, y = 0, 1 123 if radius >= 1: 124 dotRect = ((center[x]-radius, center[y]-radius), (2*radius, 2*radius)) 125 path = NSBezierPath.bezierPathWithOvalInRect_(dotRect) 126 path.stroke() 127 128 def drawRMS(self): 129 self.rmsColor.set() 130 self.drawCircle(self.gain) 131 132 def drawAxisLines(self): 133 center = self.graphCenter 134 radius = self.graphRadius 135 x, y = 0, 1 136 path = NSBezierPath.bezierPath() 137 for i in range(1, self.lines+1): 138 iR = pi / i 139 cosR = cos(iR) * radius 140 sinR = sin(iR) * radius 141 142 path.moveToPoint_((center[x] - cosR, center[y] - sinR)) 143 path.lineToPoint_((center[x] + cosR, center[y] + sinR)) 144 path.closePath() 145 path.stroke() 146 147 def drawField(self): 148 if self.maxMag: # Don't want to divide by zero in the pathological case 149 self.graphColor.set() 150 path = self.path.copy() 151 152 transform = NSAffineTransform.transform() 153 transform.rotateByRadians_(-(pi / 2.0) - self.azmuth) 154 path.transformUsingAffineTransform_(transform) 155 156 transform = NSAffineTransform.transform() 157 center = self.graphCenter 158 transform.translateXBy_yBy_(center[0], center[1]) 159 transform.scaleBy_(self.graphRadius / self.maxMag) 160 path.transformUsingAffineTransform_(transform) 161 162 path.stroke() 163 164 165#____________________________________________________________ 166# Handle GUI values 167 @objc.IBAction 168 def mapVisibleSlider_(self, sender): 169 self.mapVisible = (sender.floatValue()) 170 self.setNeedsDisplay_(1) 171 172 @objc.IBAction 173 def azmuthDisplay_(self, sender): 174 self.setAzmuth(sender.floatValue()) 175 176 @objc.IBAction 177 def azmuthSlider_(self, sender): 178 self.setAzmuth(sender.floatValue()) 179 180 def setAzmuth(self, value): 181 self.azmuth = degToRad(value) 182 self.azmuthSlider.setFloatValue_(value) 183 self.azmuthDisplay.setFloatValue_(value) 184 self.setNeedsDisplay_(1) 185 186 @objc.IBAction 187 def mapScaleDisplay_(self, sender): 188 self.mapScale = sender.floatValue() 189 self.setMapRect() 190 191 @objc.IBAction 192 def mapScaleSlider_(self, sender): 193 self.mapScale = sender.floatValue() 194 self.setMapRect() 195 196 @objc.IBAction 197 def mapOffsetNSDisplay_(self, sender): 198 self.mapOffsetNS = sender.floatValue() 199 self.setMapRect() 200 201 @objc.IBAction 202 def mapOffsetNSSlider_(self, sender): 203 self.mapOffsetNS = sender.floatValue() 204 self.setMapRect() 205 206 @objc.IBAction 207 def mapOffsetEWDisplay_(self, sender): 208 self.mapOffsetEW = sender.floatValue() 209 self.setMapRect() 210 211 @objc.IBAction 212 def mapOffsetEWSlider_(self, sender): 213 self.mapOffsetEW = sender.floatValue() 214 self.setMapRect() 215 216 def mouseUp_(self, event): 217 loc = event.locationInWindow() 218 xLoc = loc[x] - self.origin[x] 219 yLoc = loc[y] - self.origin[y] 220 xDelta = self.graphCenter[x] - xLoc 221 yDelta = self.graphCenter[y] - yLoc 222 223 224 scale = 0.5 * self.mapScale * (self.gain / self.totalField) * (self.graphRadius / self.mapBaseRadius) 225 xOffset = xDelta / (scale * self.mapRect[sze][x]) 226 yOffset = yDelta / (scale * self.mapRect[sze][y]) 227 228 self.mapOffsetEW += xOffset 229 self.mapOffsetNS -= yOffset 230 self.setMapRect() 231 232 def mouseDown_(self, event): 233 self.crossCursor.set() 234 235 236 def setMapRect(self): 237 self.mapScaleDisplay.setFloatValue_(self.mapScale) 238 self.mapScaleSlider.setFloatValue_(self.mapScale) 239 self.mapOffsetEWDisplay.setFloatValue_(self.mapOffsetEW) 240 self.mapOffsetEWSlider.setFloatValue_(self.mapOffsetEW) 241 self.mapOffsetNSDisplay.setFloatValue_(self.mapOffsetNS) 242 self.mapOffsetNSSlider.setFloatValue_(self.mapOffsetNS) 243 self.setNeedsDisplay_(1) 244 245 def mouseEntered_(self, event): 246 print 'CGraphView: mouseEntered_' 247 248 def mouseExited_(self, event): 249 print 'CGraphView: mouseExited_' 250