1/* 2 Project: Graphos 3 GRBox.m 4 5 Copyright (C) 2007-2018 GNUstep Application Project 6 7 Author: Ing. Riccardo Mottola 8 9 Created: 2007-09-21 10 11 This application is free software; you can redistribute it and/or 12 modify it under the terms of the GNU General Public 13 License as published by the Free Software Foundation; either 14 version 2 of the License, or (at your option) any later version. 15 16 This application is distributed in the hope that it will be useful, 17 but WITHOUT ANY WARRANTY; without even the implied warranty of 18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 19 Library General Public License for more details. 20 21 You should have received a copy of the GNU General Public 22 License along with this library; if not, write to the Free 23 Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 24 */ 25 26#import <AppKit/NSColor.h> 27#import <AppKit/NSGraphics.h> 28#import <AppKit/NSGraphicsContext.h> 29#import "GRBox.h" 30#import "GRBoxEditor.h" 31#import "GRFunctions.h" 32 33 34@implementation GRBox 35 36- (GRObjectEditor *)allocEditor 37{ 38 return [[GRBoxEditor alloc] initEditor:self]; 39} 40 41 42/** initializes by using the properties array as defaults */ 43- (id)initInView:(GRDocView *)aView 44 zoomFactor:(CGFloat)zf 45 withProperties:(NSDictionary *)properties 46{ 47 self = [super initInView:aView zoomFactor:zf withProperties:properties]; 48 if(self) 49 { 50 id obj; 51 52 pos = NSMakePoint([[properties objectForKey: @"posx"] floatValue], 53 [[properties objectForKey: @"posy"] floatValue]); 54 size = NSMakeSize([[properties objectForKey: @"width"] floatValue], 55 [[properties objectForKey: @"height"] floatValue]); 56 bounds = GRMakeBounds(pos.x, pos.y, size.width, size.height); 57 58 rotation = 0; 59 obj = [properties objectForKey: @"rotation"]; 60 if (obj) 61 rotation = [obj floatValue]; 62 63 startControlPoint = [[GRObjectControlPoint alloc] initAtPoint: pos zoomFactor:zf]; 64 endControlPoint = [[GRObjectControlPoint alloc] initAtPoint: NSMakePoint(pos.x + size.width, pos.y + size.height) zoomFactor:zf]; 65 [self setZoomFactor: zf]; 66 } 67 68 return self; 69} 70 71/** initializes all parameters from a description dictionary */ 72- (id)initFromData:(NSDictionary *)description 73 inView:(GRDocView *)aView 74 zoomFactor:(CGFloat)zf 75{ 76 self = [super initFromData:description inView:aView zoomFactor:zf]; 77 if(self) 78 { 79 id obj; 80 81 82 pos = NSMakePoint([[description objectForKey: @"posx"] floatValue], 83 [[description objectForKey: @"posy"] floatValue]); 84 size = NSMakeSize([[description objectForKey: @"width"] floatValue], 85 [[description objectForKey: @"height"] floatValue]); 86 bounds = GRMakeBounds(pos.x, pos.y, size.width, size.height); 87 88 rotation = 0; 89 obj = [description objectForKey: @"rotation"]; 90 if (obj) 91 rotation = [obj floatValue]; 92 93 startControlPoint = [[GRObjectControlPoint alloc] initAtPoint: pos zoomFactor:zf]; 94 endControlPoint = [[GRObjectControlPoint alloc] initAtPoint: NSMakePoint(pos.x + size.width, pos.y + size.height) zoomFactor:zf]; 95 [self setZoomFactor: zf]; 96 } 97 return self; 98} 99 100- (id)copyWithZone:(NSZone *)zone 101{ 102 GRBox *objCopy; 103 104 objCopy = [super copyWithZone:zone]; 105 106 objCopy->startControlPoint = [[GRObjectControlPoint alloc] initAtPoint: pos zoomFactor:zmFactor]; 107 objCopy->endControlPoint = [[GRObjectControlPoint alloc] initAtPoint: NSMakePoint(pos.x + size.width, pos.y + size.height) zoomFactor:zmFactor]; 108 objCopy->pos = NSMakePoint(pos.x, pos.y); 109 objCopy->size = NSMakeSize(size.width, size.height); 110 objCopy->bounds = NSMakeRect(bounds.origin.x, bounds.origin.y, bounds.size.width, bounds.size.height); 111 objCopy->boundsZ = NSMakeRect(boundsZ.origin.x, boundsZ.origin.y, boundsZ.size.width, boundsZ.size.height); 112 objCopy->rotation = rotation; 113 114 return objCopy; 115} 116 117- (void)dealloc 118{ 119 [startControlPoint release]; 120 [endControlPoint release]; 121 [super dealloc]; 122} 123 124- (NSDictionary *)objectDescription 125{ 126 NSMutableDictionary *dict; 127 NSString *str; 128 float strokeCol[3]; 129 float fillCol[3]; 130 float strokeAlpha; 131 float fillAlpha; 132 133 strokeCol[0] = [strokeColor redComponent]; 134 strokeCol[1] = [strokeColor greenComponent]; 135 strokeCol[2] = [strokeColor blueComponent]; 136 strokeAlpha = [strokeColor alphaComponent]; 137 138 fillCol[0] = [fillColor redComponent]; 139 fillCol[1] = [fillColor greenComponent]; 140 fillCol[2] = [fillColor blueComponent]; 141 fillAlpha = [fillColor alphaComponent]; 142 143 dict = [NSMutableDictionary dictionaryWithCapacity: 1]; 144 [dict setObject: @"box" forKey: @"type"]; 145 146 str = [NSString stringWithFormat: @"%.3f", pos.x]; 147 [dict setObject: str forKey: @"posx"]; 148 str = [NSString stringWithFormat: @"%.3f", pos.y]; 149 [dict setObject: str forKey: @"posy"]; 150 151 str = [NSString stringWithFormat: @"%.3f", size.width]; 152 [dict setObject: str forKey: @"width"]; 153 str = [NSString stringWithFormat: @"%.3f", size.height]; 154 [dict setObject: str forKey: @"height"]; 155 156 str = [NSString stringWithFormat: @"%.3f", flatness]; 157 [dict setObject: str forKey: @"flatness"]; 158 str = [NSString stringWithFormat: @"%u", (unsigned)linejoin]; 159 [dict setObject: str forKey: @"linejoin"]; 160 str = [NSString stringWithFormat: @"%u", (unsigned)linecap]; 161 [dict setObject: str forKey: @"linecap"]; 162 str = [NSString stringWithFormat: @"%.3f", miterlimit]; 163 [dict setObject: str forKey: @"miterlimit"]; 164 str = [NSString stringWithFormat: @"%.3f", linewidth]; 165 [dict setObject: str forKey: @"linewidth"]; 166 [dict setObject:[NSNumber numberWithBool:stroked] forKey: @"stroked"]; 167 str = [NSString stringWithFormat: @"%.3f %.3f %.3f", 168 strokeCol[0], strokeCol[1], strokeCol[2]]; 169 [dict setObject: str forKey: @"strokecolor"]; 170 str = [NSString stringWithFormat: @"%.3f", strokeAlpha]; 171 [dict setObject: str forKey: @"strokealpha"]; 172 [dict setObject:[NSNumber numberWithBool:filled] forKey: @"filled"]; 173 str = [NSString stringWithFormat: @"%.3f %.3f %.3f", 174 fillCol[0], fillCol[1], fillCol[2]]; 175 [dict setObject: str forKey: @"fillcolor"]; 176 str = [NSString stringWithFormat: @"%.3f", fillAlpha]; 177 [dict setObject: str forKey: @"fillalpha"]; 178 [dict setObject:[NSNumber numberWithBool:visible] forKey: @"visible"]; 179 [dict setObject:[NSNumber numberWithBool:locked] forKey: @"locked"]; 180 181 return dict; 182} 183 184- (void)setStartAtPoint:(NSPoint)aPoint 185{ 186 pos = aPoint; 187 [startControlPoint moveToPoint: aPoint]; 188 [startControlPoint select]; 189} 190 191- (void)setEndAtPoint:(NSPoint)aPoint 192{ 193 size.width = aPoint.x - pos.x; 194 size.height = aPoint.y- pos.y; 195 bounds = GRMakeBounds(pos.x, pos.y, size.width, size.height); 196 197 [endControlPoint moveToPoint: aPoint]; 198 [endControlPoint select]; 199 200 boundsZ = GRMakeBounds(pos.x * zmFactor, pos.y * zmFactor, size.width * zmFactor, size.height * zmFactor); 201} 202 203- (void)remakePath 204{ 205 [self setStartAtPoint:[startControlPoint center]]; 206 [self setEndAtPoint:[endControlPoint center]]; 207 [(GRBoxEditor *)editor setIsDone:YES]; 208} 209 210 211 212- (void)setLocked:(BOOL)value 213{ 214 [super setLocked:value]; 215 if(!locked) 216 [(GRBoxEditor *)editor unselect]; 217 else 218 [(GRBoxEditor *)editor selectAsGroup]; 219} 220 221- (BOOL)objectHitForSelection:(NSPoint)p 222{ 223 return (pointInRect(bounds, p)); 224} 225 226- (BOOL)onControlPoint:(NSPoint)p 227{ 228 if (pointInRect([startControlPoint centerRect], p)) 229 return YES; 230 if (pointInRect([endControlPoint centerRect], p)) 231 return YES; 232 return NO; 233} 234 235- (GRObjectControlPoint *) startControlPoint 236{ 237 return startControlPoint; 238} 239 240- (GRObjectControlPoint *) endControlPoint 241{ 242 return endControlPoint; 243} 244 245- (NSPoint) position 246{ 247 return pos; 248} 249 250- (void)moveAddingCoordsOfPoint:(NSPoint)p 251{ 252 pos.x += p.x; 253 pos.y += p.y; 254 bounds = GRMakeBounds(pos.x, pos.y, size.width, size.height); 255 [startControlPoint moveToPoint: pos]; 256 [endControlPoint moveToPoint: NSMakePoint(pos.x + size.width, pos.y + size.height)]; 257 258 boundsZ = GRMakeBounds(pos.x * zmFactor, pos.y * zmFactor, size.width * zmFactor, size.height * zmFactor); 259} 260 261- (void)setZoomFactor:(CGFloat)f 262{ 263 [super setZoomFactor:f]; 264 265 [startControlPoint setZoomFactor:f]; 266 [endControlPoint setZoomFactor:f]; 267 [self remakePath]; 268} 269 270/** draws the object and calls the editor to draw itself afterwards */ 271- (void)draw 272{ 273 NSBezierPath *bzp; 274 CGFloat linew; 275 NSRect drawBounds; 276 277 drawBounds = bounds; 278 linew = linewidth; 279 if ([[NSGraphicsContext currentContext] isDrawingToScreen]) 280 { 281 drawBounds = boundsZ; 282 linew = linewidth * zmFactor; 283 } 284 285 bzp = [NSBezierPath bezierPath]; 286 [bzp appendBezierPathWithRect:drawBounds]; 287 if(filled) 288 { 289 [NSGraphicsContext saveGraphicsState]; 290 [fillColor set]; 291 [bzp fill]; 292 [NSGraphicsContext restoreGraphicsState]; 293 } 294 if(stroked) 295 { 296 [NSGraphicsContext saveGraphicsState]; 297 [bzp setLineJoinStyle:linejoin]; 298 [bzp setLineCapStyle:linecap]; 299 [bzp setLineWidth:linew]; 300 [strokeColor set]; 301 [bzp stroke]; 302 [NSGraphicsContext restoreGraphicsState]; 303 } 304 305 if ([[NSGraphicsContext currentContext] isDrawingToScreen]) 306 [editor draw]; 307} 308 309 310@end 311