|
|
1.1 ! root 1: // Controller.m ! 2: // By Jayson Adams, NeXT Developer Support Team ! 3: // You may freely copy, distribute and reuse the code in this example. ! 4: // NeXT disclaims any warranty of any kind, expressed or implied, as to its ! 5: // fitness for any particular use. ! 6: ! 7: #import <appkit/appkit.h> ! 8: #import <objc/NXStringTable.h> ! 9: ! 10: #import "Controller.h" ! 11: #import "CustomCell.h" ! 12: #import "NiftyMatrix.h" ! 13: #import "PostScriptView.h" ! 14: ! 15: @implementation Controller:Object ! 16: ! 17: ! 18: /* delegation methods */ ! 19: ! 20: - appDidInit:sender ! 21: { ! 22: /* create a matrix and stick it in the scroll view */ ! 23: [self createScrollingMatrix]; ! 24: ! 25: /* bring the window on screen */ ! 26: [[scrollView window] makeKeyAndOrderFront:NULL]; ! 27: ! 28: [self setupTileView]; ! 29: [[tileScrollView window] orderFront:NULL]; ! 30: ! 31: return self; ! 32: } ! 33: ! 34: /* instance methods */ ! 35: ! 36: - createScrollingMatrix ! 37: { ! 38: NXRect scrollRect, matrixRect; ! 39: NXSize interCellSpacing = {0.0, 0.0}, cellSize; ! 40: ! 41: /* set the scrollView's attributes */ ! 42: [scrollView setBorderType:NX_BEZEL]; ! 43: [scrollView setVertScrollerRequired:YES]; ! 44: [scrollView setHorizScrollerRequired:NO]; ! 45: ! 46: /* get the scrollView's dimensions */ ! 47: [scrollView getFrame:&scrollRect]; ! 48: ! 49: /* determine the matrix bounds */ ! 50: [ScrollView getContentSize:&(matrixRect.size) ! 51: forFrameSize:&(scrollRect.size) ! 52: horizScroller:YES ! 53: vertScroller:YES ! 54: borderType:NX_BEZEL]; ! 55: ! 56: /* prepare a matrix to go inside our scrollView */ ! 57: matrix = [[NiftyMatrix alloc] initFrame:&matrixRect ! 58: mode:NX_LISTMODE ! 59: cellClass:[CustomCell class] ! 60: numRows:0 ! 61: numCols:1]; ! 62: ! 63: /* we don't want any space between the matrix's cells */ ! 64: [matrix setIntercell:&interCellSpacing]; ! 65: ! 66: /* fill the matrix with some cells */ ! 67: [self fillMatrix]; ! 68: ! 69: /* resize the matrix's cells and size the matrix to contain them */ ! 70: [matrix getCellSize:&cellSize]; ! 71: cellSize.width = NX_WIDTH(&matrixRect); ! 72: [matrix setCellSize:&cellSize]; ! 73: [matrix sizeToCells]; ! 74: [matrix setAutosizeCells:YES]; ! 75: ! 76: /* ! 77: * when the user clicks in the matrix and then drags the mouse out of ! 78: * scrollView's contentView, we want the matrix to scroll ! 79: */ ! 80: [matrix setAutoscroll:YES]; ! 81: ! 82: /* stick the matrix in our scrollView */ ! 83: [scrollView setDocView:matrix]; ! 84: ! 85: /* set things up so that the matrix will resize properly */ ! 86: [[matrix superview] setAutoresizeSubviews:YES]; ! 87: [matrix setAutosizing:NX_WIDTHSIZABLE]; ! 88: ! 89: /* set the matrix's single- and double-click actions */ ! 90: [matrix setTarget:self]; ! 91: [matrix setAction:@selector(singleClick:)]; ! 92: [matrix setDoubleAction:@selector(doubleClick:)]; ! 93: ! 94: /* select a cell, for starters */ ! 95: [[matrix selectCellAt:0 :0] sendAction]; ! 96: ! 97: return self; ! 98: } ! 99: ! 100: - fillMatrix ! 101: { ! 102: BOOL done = NO; ! 103: char buffer[10]; ! 104: int i = 0; ! 105: const char *string; ! 106: id newCell; ! 107: ! 108: /* create a cell for each string */ ! 109: while (!done) { ! 110: sprintf(buffer, "%d", i); ! 111: if (string = [stringTable valueForStringKey:buffer]) { ! 112: /* create a new cell if there's a string */ ! 113: [matrix addRow]; ! 114: newCell = [matrix cellAt:i :0]; ! 115: [newCell setTag:(i * 16)]; ! 116: [newCell setStringValueNoCopy:string]; ! 117: } else { ! 118: done = YES; ! 119: } ! 120: i++; ! 121: } ! 122: ! 123: return self; ! 124: } ! 125: ! 126: - setupTileView ! 127: { ! 128: const NXRect *paperRect; ! 129: NXCoord leftMargin, rightMargin, topMargin, bottomMargin; ! 130: NXRect psViewRect; ! 131: ! 132: [tileScrollView setVertScrollerRequired:YES]; ! 133: [tileScrollView setHorizScrollerRequired:YES]; ! 134: [tileScrollView setBorderType:NX_NOBORDER]; ! 135: ! 136: /* get the paper's bounds (8.5 x 11) and margins */ ! 137: paperRect = [[NXApp printInfo] paperRect]; ! 138: [[NXApp printInfo] getMarginLeft:&leftMargin ! 139: right:&rightMargin ! 140: top:&topMargin ! 141: bottom:&bottomMargin]; ! 142: ! 143: /* the docView should fit within the margins */ ! 144: psViewRect = *paperRect; ! 145: psViewRect.size.width -= (leftMargin + rightMargin); ! 146: psViewRect.size.height -= (topMargin + bottomMargin); ! 147: ! 148: /* create the docView and place it within its scrollView */ ! 149: psView = [[PostScriptView alloc] initFrame:&psViewRect]; ! 150: [tileScrollView setDocView:psView]; ! 151: ! 152: return self; ! 153: } ! 154: ! 155: - nextItem:sender ! 156: { ! 157: int nextRow; ! 158: ! 159: /* don't move to the "next" cell if multiple cells selected */ ! 160: if ([self multipleCellsSelected]) { ! 161: NXRunAlertPanel(NULL, ! 162: [stringTable valueForStringKey:"mulCellsSelected"], ! 163: [stringTable valueForStringKey:"oops"], NULL, NULL); ! 164: return self; ! 165: } ! 166: ! 167: /* can't select the next cell if there isn't a currently-selected cell */ ! 168: if (![matrix selectedCell]) { ! 169: NXRunAlertPanel(NULL, ! 170: [stringTable valueForStringKey:"noCurrentCell"], ! 171: [stringTable valueForStringKey:"yikes"], NULL, NULL); ! 172: return self; ! 173: } ! 174: ! 175: /* select the next cell, if it exists */ ! 176: nextRow = [matrix selectedRow] + 1; ! 177: if (nextRow != [matrix cellCount]) { ! 178: [matrix selectCellAt:nextRow :0]; ! 179: ! 180: /* make sure it's visible */ ! 181: [matrix scrollCellToVisible:nextRow :0]; ! 182: ! 183: /* behave as if the user clicked on the newly-selected cell */ ! 184: [matrix sendAction]; ! 185: } else { ! 186: NXRunAlertPanel(NULL, ! 187: [stringTable valueForStringKey:"nextCellNonexistant"], ! 188: [stringTable valueForStringKey:"bummer"], NULL, NULL); ! 189: } ! 190: ! 191: return self; ! 192: } ! 193: ! 194: - previousItem:sender ! 195: { ! 196: int previousRow; ! 197: ! 198: /* don't move to the "previous" cell if multiple cells selected */ ! 199: if ([self multipleCellsSelected]) { ! 200: NXRunAlertPanel(NULL, ! 201: [stringTable valueForStringKey:"mulCellsSelected"], ! 202: [stringTable valueForStringKey:"oops"], NULL, NULL); ! 203: return self; ! 204: } ! 205: ! 206: /* can't select previous cell if there no currently-selected cell */ ! 207: if (![matrix selectedCell]) { ! 208: NXRunAlertPanel(NULL, ! 209: [stringTable valueForStringKey:"noCurrentCell"], ! 210: [stringTable valueForStringKey:"yikes"], NULL, NULL); ! 211: return self; ! 212: } ! 213: ! 214: /* select the previous cell, if it exists */ ! 215: previousRow = [matrix selectedRow] - 1; ! 216: if (previousRow != -1) { ! 217: [matrix selectCellAt:previousRow :0]; ! 218: ! 219: /* make sure the newly-selected cell's visible */ ! 220: [matrix scrollCellToVisible:previousRow :0]; ! 221: ! 222: /* behave as if the user clicked on the newly-selected cell */ ! 223: [matrix sendAction]; ! 224: } else { ! 225: NXRunAlertPanel(NULL, ! 226: [stringTable valueForStringKey:"prevCellNonexistant"], ! 227: [stringTable valueForStringKey:"bummer"], NULL, NULL); ! 228: } ! 229: ! 230: return self; ! 231: } ! 232: ! 233: - (BOOL)multipleCellsSelected ! 234: { ! 235: /* reset the counter */ ! 236: selectedCount = 0; ! 237: ! 238: /* get each selected cell to send the incrementCount method to us */ ! 239: [matrix sendAction:@selector(incrementCount:) to:self forAllCells:NO]; ! 240: ! 241: /* if more than one, return true */ ! 242: return (selectedCount > 1); ! 243: } ! 244: ! 245: - (BOOL)incrementCount:sender ! 246: { ! 247: /* ! 248: * once the counter reaches two, we know that more than one cell's ! 249: * selected; if that's the case, return NO so that the matrix will ! 250: * discontinue having selected cells send incrementCount: to us ! 251: */ ! 252: ! 253: return (++selectedCount < 2); ! 254: } ! 255: ! 256: - singleClick:sender ! 257: { ! 258: if ([self multipleCellsSelected]) { ! 259: [textField setStringValueNoCopy:""]; ! 260: } else { ! 261: [textField setStringValueNoCopy:[[matrix selectedCell] stringValue]]; ! 262: } ! 263: return self; ! 264: } ! 265: ! 266: - doubleClick:sender ! 267: { ! 268: NXRunAlertPanel(NULL, [stringTable valueForStringKey:"doubleClick"], ! 269: [stringTable valueForStringKey:"clickedTwice"], ! 270: NULL, NULL); ! 271: return self; ! 272: } ! 273: ! 274: - displayInfoPanel:sender ! 275: { ! 276: if (!infoPanel) { ! 277: [NXApp loadNibSection:"InfoPanel.nib" owner:self]; ! 278: } ! 279: [infoPanel makeKeyAndOrderFront:NULL]; ! 280: ! 281: return self; ! 282: } ! 283: ! 284: @end
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.