|
|
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.