1/* dvTile.m 2 * DocView addition for batch production 3 * 4 * Copyright (C) 1996-2011 by vhf interservice GmbH 5 * Author: Georg Fleischmann 6 * 7 * created: 1996-05-10 8 * modified: 2011-09-08 (-setTileWithLimits:, -buildTileCopies: sort sequence from down to up to down) 9 * 2008-07-24 (Prefs_IncrementSerial removed in -incrementSerialNumbers) 10 * 11 * This program is free software; you can redistribute it and/or 12 * modify it under the terms of the vhf Public License as 13 * published by vhf interservice GmbH. Among other things, the 14 * License requires that the copyright notices and this notice 15 * be preserved on all copies. 16 * 17 * This program is distributed in the hope that it will be useful, 18 * but WITHOUT ANY WARRANTY; without even the implied warranty of 19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 20 * See the vhf Public License for more details. 21 * 22 * You should have received a copy of the vhf Public License along 23 * with this program; see the file LICENSE. If not, write to vhf. 24 * 25 * vhf interservice GmbH, Im Marxle 3, 72119 Altingen, Germany 26 * eMail: info@vhf.de 27 * http://www.vhf.de 28 */ 29 30#include <AppKit/AppKit.h> 31#include "DocView.h" 32#include "TilePanel.h" 33#include "TileObject.h" 34#include "PreferencesMacros.h" 35 36@implementation DocView(Tile) 37 38- (NSMutableArray*)tileOriginList { return tileOriginList; } 39- (BOOL)tileLimitSize { return tileLimitSize; } 40- (NSPoint)tileDistance { return tileDistance; } 41//- (NSPoint)useAbsoluteDistance { return useAbsoluteDistance; } 42- (NSPoint)tileLimits { return tileLimits; } 43//- (BOOL)mustMoveMasterToOrigin { return moveMasterToOrigin; } 44 45- (int)numberOfTiles 46{ int xCnt, yCnt; 47 48 if (tileLimitSize) 49 { NSRect rect = [self tileBounds]; 50 51 xCnt = tileLimits.x / (rect.size.width + tileDistance.x); 52 yCnt = tileLimits.y / (rect.size.height + tileDistance.y); 53 } 54 else 55 { 56 xCnt = tileLimits.x; 57 yCnt = tileLimits.y; 58 } 59 return xCnt * yCnt; 60} 61 62 63/* 64 * limits the size or number of items in x/y direction 65 * distance the distance between tiles 66 * 67 * modified: 2005-10-15 68 */ 69- (void)setTileWithLimits:(NSPoint)limits 70 limitSize:(BOOL)limitSize 71 distance:(NSPoint)dist 72 moveToOrigin:(BOOL)moveToOrigin 73{ NSRect rect; 74 int l, x, xCnt, y, yCnt; 75 BOOL setDirty = NO; 76 NSPoint pOrigin = [origin pointWithNum:0], pMaster; 77 78 if (tileDistance.x != dist.x || tileDistance.y != dist.y) 79 { setDirty = YES; 80 tileDistance = dist; 81 } 82 if (tileLimits.x != limits.x || tileLimits.y != limits.y) 83 { setDirty = YES; 84 tileLimits = limits; 85 } 86 if (tileLimitSize != limitSize) 87 { setDirty = YES; 88 tileLimitSize = limitSize; 89 } 90 [self serialNumber]; // determine serial number 91 rect = [self tileBounds]; 92 93 if (!tileLimits.x || !tileLimits.y) 94 { 95 [tileOriginList release]; 96 tileOriginList = nil; 97 return; 98 } 99 100 [tileOriginList release]; 101 tileOriginList = [[NSMutableArray allocWithZone:[self zone]] init]; 102 103 /* move master to lower/left position 104 */ 105 if ( moveToOrigin && 106 (rect.origin.x != tileDistance.x || rect.origin.y != tileDistance.y) ) 107 { NSPoint p; 108 int i; 109 110 p.x = pOrigin.x - rect.origin.x; 111 p.y = pOrigin.y - rect.origin.y; 112 //p.x = tileDistance.x - rect.origin.x; 113 //p.y = tileDistance.y - rect.origin.y; 114 for (l=[layerList count]-1; l>=0; l--) 115 { NSMutableArray *list = [[layerList objectAtIndex:l] list]; 116 117 if ( ![[layerList objectAtIndex:l] useForTile] ) 118 continue; 119 for (i=[list count]-1; i>=0; i--) 120 [[list objectAtIndex:i] moveBy:p]; 121 } 122 } 123 124 if (setDirty) 125 { 126 for ( l=[layerList count]-1; l>=0; l-- ) 127 if ( [[layerList objectAtIndex:l] useForTile] ) 128 [[layerList objectAtIndex:l] setDirty:YES]; 129 [document setDirty:YES]; 130 } 131 132 /* create tileOriginList */ 133 pMaster = [self tileBounds].origin; 134 xCnt = (int)(tileLimitSize) ? (limits.x/(rect.size.width + tileDistance.x)) : limits.x; 135 yCnt = (int)(tileLimitSize) ? (limits.y/(rect.size.height + tileDistance.y)) : limits.y; 136 for ( x=0; x<xCnt; x++) 137 { 138 //for (y=0; y<yCnt; y++) 139 for ( (Even(x)) ? (y=0) : (y=yCnt-1); (Even(x)) ? (y<yCnt) : (y>=0); (Even(x)) ? (y++) : (y--) ) 140 { TileObject *obj; 141 NSPoint p; 142 143 obj = [[TileObject allocWithZone:[self zone]] autorelease]; 144 p.x = pMaster.x/*tileDistance.x*/ + x * (rect.size.width +tileDistance.x); 145 p.y = pMaster.y/*tileDistance.y*/ + y * (rect.size.height+tileDistance.y); 146 [obj setPosition:p]; 147 [tileOriginList addObject:obj]; 148 } 149 } 150 151 /* increase working area, if necessary */ 152 { NSSize size, frameSize = [self frame].size; 153 154 size = NSMakeSize(xCnt*(rect.size.width +tileDistance.x), yCnt*(rect.size.height+tileDistance.y)); 155 [self setFrameSize:NSMakeSize(Max(frameSize.width, size.width*scale), 156 Max(frameSize.height, size.height*scale))]; 157 } 158 159 [self drawAndDisplay]; 160} 161 162- (void)removeTiles 163{ int l; 164 165 for ( l=[layerList count]-1; l>=0; l-- ) 166 if ( [[layerList objectAtIndex:l] useForTile] ) 167 [[layerList objectAtIndex:l] setDirty:YES]; 168 [document setDirty:YES]; 169 170 [tileOriginList removeAllObjects]; 171 [tileOriginList release]; 172 tileOriginList = nil; 173 174 [self drawAndDisplay]; 175} 176 177/* modified: 2005-10-15 178 */ 179- (void)buildTileCopies:(NSPoint)limits 180 limitSize:(BOOL)limitSize 181 distance:(NSPoint)dist 182 moveToOrigin:(BOOL)moveToOrigin 183{ NSRect rect; 184 int i, iCnt, l, x, xCnt, y, yCnt, copyCnt = 1; 185 NSMutableArray *masterIndexes = [NSMutableArray array]; 186 NSPoint pOrigin = [origin pointWithNum:0]; 187 188 tileDistance = dist; 189 //tileAbsoluteDistance = absoluteDistance; 190 tileLimits = limits; 191 tileLimitSize = limitSize; 192 //tileMoveMasterToOrigin = moveToOrigin; 193 [self serialNumber]; 194 rect = [self tileBounds]; 195 196 [tileOriginList release]; 197 tileOriginList = nil; 198 199 /* move master to lower/left position (crosshair origin) 200 */ 201 if ( moveToOrigin && 202 (rect.origin.x != tileDistance.x || rect.origin.y != tileDistance.y) ) 203 { NSPoint p; 204 205 p.x = pOrigin.x - rect.origin.x; 206 p.y = pOrigin.y - rect.origin.y; 207 //p.x = tileDistance.x - rect.origin.x; 208 //p.y = tileDistance.y - rect.origin.y; 209 for (l=[layerList count]-1; l>=0; l--) 210 { NSMutableArray *list = [[layerList objectAtIndex:l] list]; 211 212 if ( ![[layerList objectAtIndex:l] useForTile] ) 213 continue; 214 for (i=[list count]-1; i>=0; i--) 215 [[list objectAtIndex:i] moveBy:p]; 216 } 217 } 218 219 [document setDirty:YES]; 220 221 /* remember master indexes */ 222 for (l=0; l<(int)[layerList count]; l++) 223 [masterIndexes addObject:[NSNumber numberWithInt:[[[layerList objectAtIndex:l] list] count]]]; 224 225 xCnt = (int)(tileLimitSize) ? (limits.x/(rect.size.width + tileDistance.x)) : limits.x; 226 yCnt = (int)(tileLimitSize) ? (limits.y/(rect.size.height + tileDistance.y)) : limits.y; 227 for ( x=0; x<xCnt; x++ ) 228 { 229 //for ( y=0; y<yCnt; y++ ) 230 for ( (Even(x)) ? (y=0) : (y=yCnt-1); (Even(x)) ? (y<yCnt) : (y>=0); (Even(x)) ? (y++) : (y--) ) 231 { NSPoint p; 232 233 if ( !x && !y ) 234 continue; 235 p.x = x * (rect.size.width +tileDistance.x); 236 p.y = y * (rect.size.height+tileDistance.y); 237 for (l=[layerList count]-1; l>=0; l--) 238 { LayerObject *layer = [layerList objectAtIndex:l]; 239 NSMutableArray *slist = [slayList objectAtIndex:l]; 240 241 if ( ![[layerList objectAtIndex:l] useForTile] ) 242 continue; 243 for (i=0, iCnt=[[masterIndexes objectAtIndex:l] intValue]; i<iCnt; i++) 244 { id g = [[[[layer list] objectAtIndex:i] copy] autorelease]; 245 246 if ( [g respondsToSelector:@selector(isSerialNumber)] && [g isSerialNumber] ) 247 [g incrementSerialNumberBy:copyCnt]; 248 [g moveBy:p]; 249 [layer addObjectWithoutCheck:g]; // faster 250 if ( [g isSelected] ) 251 [slist addObject:g]; 252 } 253 } 254 copyCnt++; 255 } 256 } 257 258 /* increase working area, if necessary */ 259 { NSSize size, frameSize = [self frame].size; 260 261 size = NSMakeSize(xCnt*(rect.size.width +tileDistance.x), yCnt*(rect.size.height+tileDistance.y)); 262 [self setFrameSize:NSMakeSize(Max(frameSize.width, size.width*scale), 263 Max(frameSize.height, size.height*scale))]; 264 } 265 266 if ( [self window] && [[self window] windowNumber] >= 0 ) 267 [self drawAndDisplay]; 268} 269 270/* get the serial number 271 */ 272- (id)serialNumber 273{ int l, i; 274 275 serialNumber = nil; 276 for (l=[layerList count]-1; l>=0; l--) 277 { NSMutableArray *list = [[layerList objectAtIndex:l] list]; 278 279 if ( ![[layerList objectAtIndex:l] useForTile] ) 280 continue; 281 for (i=[list count]-1; i>=0; i--) 282 { id g = [list objectAtIndex:i]; 283 284 if ( [g respondsToSelector:@selector(isSerialNumber)] && [g isSerialNumber] ) 285 { serialNumber = g; 286 l = 0; 287 break; 288 } 289 } 290 } 291 return serialNumber; 292} 293 294- (void)incrementSerialNumbers 295{ int cnt = 1; 296 297 if (tileOriginList) 298 cnt = [self numberOfTiles]; 299 300 [[self serialNumber] incrementSerialNumberBy:cnt]; 301 302 [document setDirty:YES]; 303 [self drawAndDisplay]; 304} 305 306- (NSRect)tileBounds 307{ int l; 308 NSRect bRect = NSZeroRect, rect; 309 310 tileSize.width = tileSize.height = 0.0; 311 for (l=[layerList count]-1; l>=0; l--) 312 { NSMutableArray *list = [[layerList objectAtIndex:l] list]; 313 314 if ( ![[layerList objectAtIndex:l] useForTile] ) 315 continue; 316 rect = [self coordBoundsOfArray:list]; 317 if (rect.origin.x || rect.origin.y || rect.size.width || rect.size.height) 318 bRect = (!bRect.size.width && !bRect.size.height) ? rect : VHFUnionRect(rect, bRect); 319 } 320 321 tileSize = bRect.size; 322 return bRect; 323} 324 325@end 326