|
|
1.1 root 1: #import "draw.h"
2:
3: /*
4: * This Ruler should really look at the NXMeasurementUnit default
5: * and, based on that, use the proper units (whether centimeters
6: * or inches) rather than just always using inches.
7: */
8:
9: #define LINE_X (15.0)
10: #define WHOLE_HT (10.0)
11: #define HALF_HT (8.0)
12: #define QUARTER_HT (4.0)
13: #define EIGHTH_HT (2.0)
14: #define NUM_X (3.0)
15:
16: #define WHOLE (72)
17: #define HALF (WHOLE/2)
18: #define QUARTER (WHOLE/4)
19: #define EIGHTH (WHOLE/8)
20:
21: @implementation Ruler
22:
23: + (NXCoord)width
24: {
25: return 23.0;
26: }
27:
28: - initFrame:(const NXRect *)frameRect
29: {
30: [super initFrame:frameRect];
31: [self setFont:[Font systemFontOfSize:8.0 matrix:NX_IDENTITYMATRIX]];
32: startX = [[self class] width];
33: return self;
34: }
35:
36: - setFlipped:(BOOL)flag
37: /*
38: * This view doesn't work when it's "flipped," so we
39: * recycle that idea to mean whether the ruler has "0" at
40: * the origin of the view or not.
41: */
42: {
43: flipped = flag ? YES : NO;
44: return self;
45: }
46:
47: - setFont:(Font *)aFont
48: {
49: NXCoord as, lh;
50:
51: font = aFont;
52: NXTextFontInfo(aFont, &as, &descender, &lh);
53: if (descender < 0.0) descender = -1.0 * descender;
54:
55: return self;
56: }
57:
58: - drawHorizontal:(const NXRect *)rects
59: {
60: NXRect line, clip;
61: int curPos, last, mod, i, j;
62:
63: PSsetgray(NX_LTGRAY);
64: NXRectFill(rects);
65:
66: if (lastlp >= rects->origin.x && lastlp < rects->origin.x + rects->size.width) lastlp = -1.0;
67: if (lasthp >= rects->origin.x && lasthp < rects->origin.x + rects->size.width) lasthp = -1.0;
68:
69: line = bounds; /* draw bottom line */
70: line.size.height = 1.0;
71: PSsetgray(NX_DKGRAY);
72: if (NXIntersectionRect(rects, &line)) NXRectFill(&line);
73:
74: line = bounds;
75: line.size.width = 1.0;
76: line.origin.x = startX - 1.0;
77: if (NXIntersectionRect(rects, &line)) NXRectFill(&line);
78:
79: line = bounds; /* draw ruler line */
80: line.origin.y = LINE_X;
81: line.size.height = 1.0;
82: line.origin.x = startX;
83: line.size.width = bounds.size.width - startX;
84:
85: PSsetgray(NX_BLACK);
86: if (NXIntersectionRect(rects, &line)) NXRectFill(&line);
87:
88: clip = *rects;
89: clip.origin.x = startX;
90: clip.size.width = bounds.size.width - startX;
91: if (NXIntersectionRect(rects, &clip)) {
92: curPos = (int)(NX_X(&clip) - startX);
93: last = (int)(NX_MAXX(&clip) - startX);
94: if (mod = (curPos % EIGHTH)) curPos -= mod;
95: if (mod = (last % EIGHTH)) last -= mod;
96: line.size.width = 1.0;
97: [font set];
98: for (j = curPos; j <= last; j += EIGHTH) {
99: i = flipped ? bounds.size.width - j : j;
100: line.origin.x = startX + (float)i - (flipped ? 1.0 : 0.0);
101: if (!(i % WHOLE)) {
102: char buf[10];
103: line.origin.y = LINE_X - WHOLE_HT;
104: line.size.height = WHOLE_HT;
105: NXRectFill(&line);
106: PSmoveto(((float) j + NUM_X) + startX, descender + line.origin.y - 2.0);
107: sprintf(buf, "%d", i / WHOLE);
108: PSshow(buf);
109: } else if (!(i % HALF)) {
110: line.origin.y = LINE_X - HALF_HT;
111: line.size.height = HALF_HT;
112: NXRectFill(&line);
113: } else if (!(i % QUARTER)) {
114: line.origin.y = LINE_X - QUARTER_HT;
115: line.size.height = QUARTER_HT;
116: NXRectFill(&line);
117: } else if (!(i % EIGHTH)) {
118: line.origin.y = LINE_X - EIGHTH_HT;
119: line.size.height = EIGHTH_HT;
120: NXRectFill(&line);
121: }
122: }
123: }
124:
125: return self;
126: }
127:
128:
129: - drawVertical:(const NXRect *)rects
130: {
131: NXRect line, clip;
132: int curPos, last, mod, i, j;
133:
134: PSsetgray(NX_LTGRAY);
135: NXRectFill(rects);
136:
137: if (lastlp >= rects->origin.y && lastlp < rects->origin.y + rects->size.height) lastlp = -1.0;
138: if (lasthp >= rects->origin.y && lasthp < rects->origin.y + rects->size.height) lasthp = -1.0;
139:
140: line = bounds; /* draw bottom line */
141: line.origin.x = bounds.size.width - 1.0;
142: line.size.width = 1.0;
143: PSsetgray(NX_DKGRAY);
144: if (NXIntersectionRect(rects, &line)) NXRectFill(&line);
145:
146: line = bounds; /* draw ruler line */
147: line.origin.x = bounds.size.width - LINE_X - 2.0;
148: line.size.width = 1.0;
149: PSsetgray(NX_BLACK);
150: if (NXIntersectionRect(rects, &line)) NXRectFill(&line);
151:
152: clip = *rects;
153: line.origin.x++;
154: if (NXIntersectionRect(rects, &clip)) {
155: curPos = (int)(NX_Y(&clip));
156: last = (int)(NX_MAXY(&clip));
157: if (flipped) {
158: if (mod = ((int)(bounds.size.height - curPos) % EIGHTH)) curPos += mod;
159: if (mod = ((int)(bounds.size.height - last) % EIGHTH)) last += mod;
160: } else {
161: if (mod = (curPos % EIGHTH)) curPos -= mod;
162: if (mod = (last % EIGHTH)) last -= mod;
163: }
164: line.size.height = 1.0;
165: [font set];
166: for (j = curPos; j <= last; j += EIGHTH) {
167: i = flipped ? bounds.size.height - j : j;
168: line.origin.y = (float)j - (flipped ? 1.0 : 0.0);
169: if (!(i % WHOLE)) {
170: char buf[10];
171: line.size.width = WHOLE_HT;
172: NXRectFill(&line);
173: PSmoveto(line.origin.x + 5.0, (float)j + (flipped ? - 10.0 : 2.0));
174: sprintf(buf, "%d", i / WHOLE);
175: PSshow(buf);
176: } else if (!(i % HALF)) {
177: line.size.width = HALF_HT;
178: NXRectFill(&line);
179: } else if (!(i % QUARTER)) {
180: line.size.width = QUARTER_HT;
181: NXRectFill(&line);
182: } else if (!(i % EIGHTH)) {
183: line.size.width = EIGHTH_HT;
184: NXRectFill(&line);
185: }
186: }
187: }
188:
189: return self;
190: }
191:
192: - drawSelf:(const NXRect *) rects :(int)rectCount
193: {
194: if (frame.size.width < frame.size.height) {
195: [self drawVertical:rects];
196: } else {
197: [self drawHorizontal:rects];
198: }
199: return self;
200: }
201:
202:
203: #define SETPOSITION(value) (isVertical ? (rect.origin.y = value - (absolute ? 0.0 : 1.0)) : (rect.origin.x = value + (absolute ? 0.0 : startX)))
204: #define SETSIZE(value) (isVertical ? (rect.size.height = value) : (rect.size.width = value))
205: #define SIZE (isVertical ? rect.size.height : rect.size.width)
206:
207: - doShowPosition:(NXCoord)lp :(NXCoord)hp absolute:(BOOL)absolute
208: {
209: NXRect rect;
210: BOOL isVertical = (frame.size.width < frame.size.height);
211:
212: rect = bounds;
213:
214: if (!absolute && !isVertical) {
215: if (lp < 0.0) lp -= startX;
216: if (hp < 0.0) hp -= startX;
217: }
218:
219: SETSIZE(1.0);
220: lastlp = SETPOSITION(lp);
221: NXHighlightRect(&rect);
222: lasthp = SETPOSITION(hp);
223: NXHighlightRect(&rect);
224:
225: return self;
226: }
227:
228: - showPosition:(NXCoord)lp :(NXCoord)hp
229: {
230: [self lockFocus];
231: if (notHidden) [self doShowPosition:lastlp :lasthp absolute:YES];
232: [self doShowPosition:lp :hp absolute:NO];
233: [self unlockFocus];
234: notHidden = YES;
235: return self;
236: }
237:
238: - hidePosition
239: {
240: if (notHidden) {
241: [self lockFocus];
242: [self doShowPosition:lastlp :lasthp absolute:YES];
243: [self unlockFocus];
244: notHidden = NO;
245: }
246: return self;
247: }
248:
249: @end
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.