Mercurial > hg > xemacs-beta
comparison pkg-src/tree-nx/TreeView.m @ 163:0132846995bd r20-3b8
Import from CVS: tag r20-3b8
author | cvs |
---|---|
date | Mon, 13 Aug 2007 09:43:35 +0200 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
162:4de2936b4e77 | 163:0132846995bd |
---|---|
1 | |
2 #import "TreeView.h" | |
3 #import "TreeButton.h" | |
4 #import "NamedTree.h" | |
5 #import "Line.h" | |
6 | |
7 // constants to determine how the buttons are laid out | |
8 #define BUTTONWIDTH 155.0 | |
9 #define BUTTONHEIGHT 24.0 | |
10 #define VERTSPACING 8.0 | |
11 #define HORIZSPACING 40.0 | |
12 | |
13 @implementation TreeView | |
14 | |
15 - initFrame:(const NXRect *)frameRect | |
16 { | |
17 [super initFrame:frameRect]; | |
18 [self setAutosizing:(unsigned int) (NX_WIDTHSIZABLE | NX_HEIGHTSIZABLE)]; | |
19 | |
20 currentButton = nil; | |
21 lineList = nil; | |
22 priorButton = nil; | |
23 [selectedField setNextText: selectedField]; | |
24 [selectedField setPreviousText: selectedField]; | |
25 currScale = 1.0; | |
26 | |
27 [self registerForDragging]; | |
28 [self setOpaque:YES]; | |
29 | |
30 return self; | |
31 } | |
32 | |
33 - buildTreeFromNode:aNode bottom:(double)ybot | |
34 top:(double)ytop atX:(double)xpos parent:(NXPoint *)pos | |
35 { // add a button representing the node to the View | |
36 // This method is recursive. | |
37 NXRect butFrame = {{(xpos + HORIZSPACING), | |
38 (ybot + (ytop - ybot) / 2 - BUTTONHEIGHT / 2)}, | |
39 {BUTTONWIDTH, BUTTONHEIGHT}}; | |
40 id newButton = [[[TreeButton alloc] initFrame:&butFrame] | |
41 setTreeNode:aNode]; | |
42 id kid, kids = [aNode branches]; | |
43 int numBranches = [kids count]; | |
44 int i, treeWidth; double diff, accum = ybot; | |
45 NXPoint myCenter = {(NX_X(&butFrame)), | |
46 (NX_Y(&butFrame) + BUTTONHEIGHT / 2)}; | |
47 id newLine; | |
48 | |
49 [newButton setTitle:[aNode label]]; | |
50 [self addSubview:newButton]; | |
51 // line to parent: | |
52 if (pos) { // NULL if root, so no line | |
53 NXPoint parentRight = { pos->x + BUTTONWIDTH, pos->y }; | |
54 newLine = [[Line alloc] init]; | |
55 [newLine setStart:&parentRight end:&myCenter]; | |
56 [lineList addObject:newLine]; | |
57 } | |
58 // now add any children and the lines to them. | |
59 for (i=numBranches - 1; i >= 0; i--) { // loop isn't entered if no kids. | |
60 kid = [kids objectAt:i]; | |
61 treeWidth = [kid width]; | |
62 diff = (treeWidth * (BUTTONHEIGHT + VERTSPACING)); | |
63 [self buildTreeFromNode:kid bottom:accum | |
64 top:(accum + diff + VERTSPACING) | |
65 atX:(xpos + BUTTONWIDTH + HORIZSPACING) | |
66 parent:&myCenter]; | |
67 accum += diff; | |
68 } | |
69 return self; | |
70 } | |
71 | |
72 - attachTree:aTree | |
73 { | |
74 int treeWidth = [aTree width]; | |
75 int treeDepth = [aTree depth]; | |
76 double height = (treeWidth * (BUTTONHEIGHT + VERTSPACING) + VERTSPACING); | |
77 double width = (treeDepth * (BUTTONWIDTH + HORIZSPACING) + HORIZSPACING); | |
78 | |
79 treeRoot = aTree; | |
80 if (lineList) [[lineList freeObjects] free]; | |
81 lineList = [[List alloc] init]; | |
82 // resize the View to accomodate the Buttons | |
83 [self sizeTo:width :height]; | |
84 [self buildTreeFromNode:aTree bottom:0.0 top:height atX:0.0 parent:NULL]; | |
85 | |
86 return self; | |
87 } | |
88 | |
89 - drawSelf:(NXRect *)rects :(int)rectCount // standard rendering method | |
90 { | |
91 NXColor color = [[self window] backgroundColor]; | |
92 | |
93 if (NXEqualColor(color, NX_COLORLTGRAY)) | |
94 color = NX_COLORDKGRAY; | |
95 | |
96 // PSsetgray(NX_DKGRAY); | |
97 NXSetColor(color); | |
98 NXRectFill(&bounds); | |
99 // PSsetgray(NX_BLACK); | |
100 NXSetColor(NX_COLORBLACK); | |
101 PSsetlinewidth(2.0); | |
102 | |
103 [lineList makeObjectsPerform:@selector(render)]; | |
104 [[self subviews] makeObjectsPerform:@selector(display)]; | |
105 return self; | |
106 } | |
107 | |
108 - scale:sender | |
109 { | |
110 id popUp = [sender window]; | |
111 short index = [popUp indexOfItem:[popUp selectedItem]]; | |
112 // 25% 50% 75% 100% 125% 150% 200% SizeToFit | |
113 // 0 1 2 3 4 5 6 7 | |
114 float factors[] = {0.25, 0.50, 0.75, 1.0, 1.25, 1.50, 2.0, 0.20}; | |
115 NXPoint center; | |
116 NXCoord scale = factors[index]; | |
117 | |
118 // Initialize width and height bounds when view is not scaled. | |
119 if (currScale == 1.0) | |
120 { | |
121 origWidth = NX_WIDTH(&bounds); | |
122 origHeight = NX_HEIGHT(&bounds); | |
123 } | |
124 | |
125 // Remember the center to we can reset it after the scaling. | |
126 center.x = NX_X(&bounds) + NX_WIDTH(&bounds) / 2; | |
127 center.y = NX_Y(&bounds) + NX_HEIGHT(&bounds) / 2; | |
128 | |
129 // Scale the view to its new size | |
130 if (index == 3) // 100% (Normal Size) | |
131 { | |
132 [self setDrawSize:origWidth :origHeight]; | |
133 currScale = 1.0; | |
134 } | |
135 else | |
136 { | |
137 currScale *= scale; | |
138 [self setDrawSize:NX_WIDTH(&bounds) / currScale | |
139 :NX_HEIGHT(&bounds) / currScale]; | |
140 } | |
141 | |
142 // Reset the center point | |
143 [self setDrawOrigin:center.x - NX_WIDTH(&bounds) / 2 | |
144 :center.y - NX_HEIGHT(&bounds) / 2]; | |
145 | |
146 // Ensure that selected button, if any, is visible. | |
147 [self displayBut:currentButton]; | |
148 | |
149 [self update]; | |
150 | |
151 return self; | |
152 } | |
153 | |
154 - setCurrentButton:but | |
155 { | |
156 if (but) | |
157 { | |
158 priorButton = currentButton; | |
159 if (priorButton) | |
160 { | |
161 [priorButton setType:NX_MOMENTARYPUSH]; | |
162 [priorButton setState:0]; | |
163 } | |
164 currentButton = but; | |
165 [currentButton setType:NX_ONOFF]; [currentButton setState:1]; | |
166 // [selectedField setStringValueNoCopy: [but title]]; | |
167 } | |
168 return but; | |
169 } | |
170 | |
171 - setCurrButtonByName:sender | |
172 { | |
173 id currBut = [self getButByName:[sender stringValue]]; | |
174 | |
175 [self displayBut:[self setCurrentButton:currBut]]; | |
176 [treeRoot act:currBut]; | |
177 return currBut; | |
178 } | |
179 | |
180 - getButByName:(const char*)name | |
181 { | |
182 id butList = [self subviews]; | |
183 id but = nil; | |
184 id currBut = nil; | |
185 int i = 0; | |
186 | |
187 while (!currBut && (but = [butList objectAt:i++])) | |
188 { | |
189 if (!strcmp([but title], name)) | |
190 currBut = but; | |
191 } | |
192 return currBut; | |
193 } | |
194 | |
195 - displayButByName:sender | |
196 { | |
197 id but = [self getButByName:[sender stringValue]]; | |
198 | |
199 if (but) | |
200 [self displayBut:but]; | |
201 return but; | |
202 } | |
203 | |
204 - displayBut:but | |
205 { | |
206 NXRect butRect; | |
207 | |
208 if (but) | |
209 { | |
210 [[but getBounds:&butRect] convertRectToSuperview:&butRect]; | |
211 [self scrollRectToVisible:&butRect]; | |
212 } | |
213 return self; | |
214 } | |
215 | |
216 @end | |
217 | |
218 | |
219 | |
220 // Color dragging support | |
221 | |
222 BOOL includesType(const NXAtom *types, NXAtom type) | |
223 { | |
224 if (types) | |
225 while (*types) | |
226 if (*types++ == type) | |
227 return YES; | |
228 return NO; | |
229 } | |
230 | |
231 @implementation TreeView(Drag) | |
232 | |
233 - registerForDragging | |
234 { | |
235 [self registerForDraggedTypes:&NXColorPboardType count:1]; | |
236 return self; | |
237 } | |
238 | |
239 - (NXDragOperation)draggingEntered:(id <NXDraggingInfo>)sender | |
240 { | |
241 NXDragOperation sourceMask = [sender draggingSourceOperationMask]; | |
242 Pasteboard *pboard = [sender draggingPasteboard]; | |
243 | |
244 return ((includesType([pboard types], NXColorPboardType)) | |
245 ? NX_DragOperationGeneric : NX_DragOperationNone); | |
246 } | |
247 | |
248 - (BOOL)prepareForDragOperation:(id <NXDraggingInfo>)sender | |
249 { | |
250 return YES; | |
251 } | |
252 | |
253 - (BOOL)performDragOperation:(id <NXDraggingInfo>)sender | |
254 { | |
255 Pasteboard *pboard = [sender draggingPasteboard]; | |
256 | |
257 if (includesType([pboard types], NXColorPboardType)) | |
258 { | |
259 NXColor color = NXReadColorFromPasteboard(pboard); | |
260 [[self window] setBackgroundColor:color]; | |
261 [self display]; // reflect color change | |
262 return YES; | |
263 } | |
264 else | |
265 return NO; | |
266 } | |
267 | |
268 - concludeDragOperation:(id <NXDraggingInfo>)sender | |
269 { | |
270 // Return value ignored. | |
271 return nil; | |
272 } | |
273 | |
274 @end |