1/* 2 Project: Graphos 3 GRBezierPathEditor.m 4 5 Copyright (C) 2000-2017 GNUstep Application Project 6 7 Author: Enrico Sersale (original GDRaw implementation) 8 Author: Ing. Riccardo Mottola 9 10 This application is free software; you can redistribute it and/or 11 modify it under the terms of the GNU General Public 12 License as published by the Free Software Foundation; either 13 version 2 of the License, or (at your option) any later version. 14 15 This application is distributed in the hope that it will be useful, 16 but WITHOUT ANY WARRANTY; without even the implied warranty of 17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 18 Library General Public License for more details. 19 20 You should have received a copy of the GNU General Public 21 License along with this library; if not, write to the Free 22 Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 23 */ 24 25#import "GRBezierPathEditor.h" 26#import "GRDocView.h" 27#import "GRFunctions.h" 28 29@implementation GRBezierPathEditor 30 31- (id)initEditor:(GRDrawableObject *)anObject 32{ 33 self = [super initEditor:anObject]; 34 if(self != nil) 35 { 36 } 37 return self; 38} 39 40 41 42- (NSPoint)moveControlAtPoint:(NSPoint)p 43{ 44 GRBezierControlPoint *cp, *pntonpnt; 45 NSEvent *event; 46 CGFloat zFactor; 47 NSPoint pp; 48 BOOL found = NO; 49 NSUInteger i; 50 51 for(i = 0; i < [[(GRBezierPath *)object controlPoints] count]; i++) 52 { 53 cp = [[(GRBezierPath *)object controlPoints] objectAtIndex: i]; 54 if(pointInRect([cp centerRect], p)) 55 { 56 [self selectForEditing]; 57 [(GRBezierPath *)object setCurrentPoint:cp]; 58 [cp select]; 59 found = YES; 60 } 61 } 62 if(!found) 63 return p; 64 65 pp = p; 66 zFactor = [object zoomFactor]; 67 68 event = [[[object view] window] nextEventMatchingMask: NSLeftMouseUpMask | NSLeftMouseDraggedMask]; 69 70 if([event type] == NSLeftMouseDragged) 71 { 72 [[object view] verifyModifiersOfEvent: event]; 73 do 74 { 75 pp = [event locationInWindow]; 76 pp = [[object view] convertPoint: pp fromView: nil]; 77 pp = GRpointDeZoom(pp, zFactor); 78 if([[object view] shiftclick]) 79 pp = pointApplyingCostrainerToPoint(pp, p); 80 81 pntonpnt = [(GRBezierPath *)object pointOnPoint: (GRBezierControlPoint *)[(GRBezierPath *)object currentPoint]]; 82 if(pntonpnt) 83 { 84 if([(GRBezierPath *)object currentPoint] == [(GRBezierPath *)object firstPoint] || pntonpnt == [(GRBezierPath *)object firstPoint]) 85 [pntonpnt moveToPoint: pp]; 86 } 87 [[(GRBezierPath *)object currentPoint] moveToPoint: pp]; 88 [(GRPathObject *)object remakePath]; 89 90 [[object view] setNeedsDisplay: YES]; 91 event = [[[object view] window] nextEventMatchingMask: NSLeftMouseUpMask | NSLeftMouseDraggedMask]; 92 [[object view] verifyModifiersOfEvent: event]; 93 } 94 while([event type] != NSLeftMouseUp); 95 } 96 97 return pp; 98} 99 100- (void)moveControlAtPoint:(NSPoint)oldp toPoint:(NSPoint)newp 101{ 102 GRBezierControlPoint *cp, *pntonpnt; 103 BOOL found = NO; 104 NSUInteger i; 105 106 for(i = 0; i < [[(GRBezierPath *)object controlPoints] count]; i++) 107 { 108 cp = [[(GRBezierPath *)object controlPoints] objectAtIndex: i]; 109 if(pointInRect([cp centerRect], oldp)) 110 { 111 [self selectForEditing]; 112 [(GRBezierPath *)object setCurrentPoint:cp]; 113 [cp select]; 114 found = YES; 115 } 116 } 117 if(!found) 118 return; 119 120 pntonpnt = [(GRBezierPath *)object pointOnPoint: (GRBezierControlPoint *)[(GRBezierPath *)object currentPoint]]; 121 if(pntonpnt) 122 { 123 if([(GRBezierPath *)object currentPoint] == [(GRBezierPath *)object firstPoint] || pntonpnt == [(GRBezierPath *)object firstPoint]) 124 [pntonpnt moveToPoint: newp]; 125 } 126 [[(GRBezierPath *)object currentPoint] moveToPoint: newp]; 127 [(GRPathObject *)object remakePath]; 128 [[object view] setNeedsDisplay: YES]; 129} 130 131- (NSPoint)moveBezierHandleAtPoint:(NSPoint)p 132{ 133 GRBezierControlPoint *cp, *pntonpnt; 134 GRBezierHandle handle; 135 BOOL found = NO; 136 NSEvent *event; 137 NSPoint op, pp, c; 138 NSUInteger i; 139 CGFloat zFactor; 140 141 if(!editSelected) 142 return p; 143 144 pp = NSZeroPoint; 145 for(i = 0; i < [[(GRBezierPath *)object controlPoints] count]; i++) 146 { 147 cp = [[(GRBezierPath *)object controlPoints] objectAtIndex: i]; 148 if([cp isActiveHandle]) 149 { 150 handle = [cp bzHandle]; 151 if(pointInRect(handle.firstHandleRect, p) || pointInRect(handle.secondHandleRect, p)) 152 { 153 [cp select]; 154 [(GRBezierPath *)object setCurrentPoint:cp]; 155 found = YES; 156 } 157 } 158 } 159 if(!found) 160 return p; 161 162 zFactor = [object zoomFactor]; 163 event = [[[object view] window] nextEventMatchingMask: 164 NSLeftMouseUpMask | NSLeftMouseDraggedMask]; 165 if([event type] == NSLeftMouseDragged) 166 { 167 [[object view] verifyModifiersOfEvent: event]; 168 op.x = p.x; 169 op.y = p.y; 170 do 171 { 172 pp = [event locationInWindow]; 173 pp = [[object view] convertPoint: pp fromView: nil]; 174 pp = GRpointDeZoom(pp, zFactor); 175 if([[object view] shiftclick]) 176 { 177 c = [(GRBezierControlPoint *)[(GRBezierPath *)object currentPoint] center]; 178 pp = pointApplyingCostrainerToPoint(pp, c); 179 } 180 181 pntonpnt = [(GRBezierPath *)object pointOnPoint: (GRBezierControlPoint *)[(GRBezierPath *)object currentPoint]]; 182 if(pntonpnt) 183 { 184 if([(GRBezierPath *)object currentPoint] == [(GRBezierPath *)object firstPoint] || pntonpnt == [(GRBezierPath *)object firstPoint]) 185 [pntonpnt moveBezierHandleToPosition: pp oldPosition: op]; 186 } 187 [(GRBezierControlPoint *)[(GRBezierPath *)object currentPoint] moveBezierHandleToPosition: pp oldPosition: op]; 188 [(GRPathObject *)object remakePath]; 189 190 op.x = pp.x; 191 op.y = pp.y; 192 [[object view] setNeedsDisplay: YES]; 193 event = [[[object view] window] nextEventMatchingMask: NSLeftMouseUpMask | NSLeftMouseDraggedMask]; 194 [[object view] verifyModifiersOfEvent: event]; 195 } 196 while([event type] != NSLeftMouseUp); 197 } 198 199 return pp; 200} 201 202- (void)moveBezierHandleAtPoint:(NSPoint)oldp toPoint:(NSPoint)newp 203{ 204 GRBezierControlPoint *cp, *pntonpnt; 205 GRBezierHandle handle; 206 BOOL found = NO; 207 NSUInteger i; 208 209 for(i = 0; i < [[(GRBezierPath *)object controlPoints] count]; i++) 210 { 211 cp = [[(GRBezierPath *)object controlPoints] objectAtIndex: i]; 212 if([cp isActiveHandle]) 213 { 214 handle = [cp bzHandle]; 215 if(pointInRect(handle.firstHandleRect, oldp) 216 || pointInRect(handle.secondHandleRect, oldp)) 217 { 218 [cp select]; 219 [(GRBezierPath *)object setCurrentPoint:cp]; 220 found = YES; 221 } 222 } 223 } 224 if(!found) 225 return; 226 227 pntonpnt = [(GRBezierPath *)object pointOnPoint: (GRBezierControlPoint *)[(GRBezierPath *)object currentPoint]]; 228 if(pntonpnt) 229 { 230 if([(GRBezierPath *)object currentPoint] == [(GRBezierPath *)object firstPoint] || pntonpnt == [(GRBezierPath *)object firstPoint]) 231 [pntonpnt moveBezierHandleToPosition: newp oldPosition: oldp]; 232 } 233 [(GRBezierControlPoint *)[(GRBezierPath *)object currentPoint] moveBezierHandleToPosition: newp oldPosition: oldp]; 234 [(GRPathObject *)object remakePath]; 235 [[object view] setNeedsDisplay: YES]; 236} 237 238 239 240- (void)selectAsGroup 241{ 242 [super selectAsGroup]; 243} 244 245- (void)selectForEditing 246{ 247 [super selectForEditing]; 248} 249 250 251- (NSArray *)selectedControlPoints 252{ 253 NSUInteger i; 254 NSMutableArray *points; 255 256 points = [[NSMutableArray alloc] initWithCapacity:1]; 257 for(i = 0; i < [[(GRBezierPath *)object controlPoints] count]; i++) 258 { 259 GRBezierControlPoint *cp; 260 cp = [[(GRBezierPath *)object controlPoints] objectAtIndex: i]; 261 262 if ([cp isSelect]) 263 [points addObject:cp]; 264 } 265 return [points autorelease]; 266} 267 268- (void)unselect 269{ 270 NSUInteger i; 271 272 [super unselect]; 273 for(i = 0; i < [[(GRBezierPath *)object controlPoints] count]; i++) 274 [[[(GRBezierPath *)object controlPoints] objectAtIndex: i] unselect]; 275} 276 277 278- (void)unselectOtherControls:(GRBezierControlPoint *)cp 279{ 280 GRBezierControlPoint *ctrlp; 281 NSUInteger i; 282 283 [(GRBezierPath *)object setCurrentPoint:cp]; 284 for(i = 0; i < [[(GRBezierPath *)object controlPoints] count]; i++) 285 { 286 ctrlp = [[(GRBezierPath *)object controlPoints] objectAtIndex: i]; 287 if(ctrlp != cp) 288 [ctrlp unselect]; 289 } 290} 291 292 293- (void)draw 294{ 295 GRBezierControlPoint *cp; 296 NSUInteger i; 297 298 if(![[(GRBezierPath *)object controlPoints] count] || ![object visible]) 299 return; 300 301 if(groupSelected) 302 { 303 for(i = 0; i < [[(GRBezierPath *)object controlPoints] count]; i++) 304 { 305 cp = [[(GRBezierPath *)object controlPoints] objectAtIndex: i]; 306 [cp drawControlAsSelected:YES]; 307 } 308 } 309 310 if(editSelected) 311 { 312 for(i = 0; i < [[(GRBezierPath *)object controlPoints] count]; i++) 313 { 314 cp = [[(GRBezierPath *)object controlPoints] objectAtIndex: i]; 315 [cp drawControl]; 316 } 317 } 318} 319 320@end 321 322 323 324