1 | ;+ |
---|
2 | ; NAME: |
---|
3 | ; FSC_PLOTWINDOW |
---|
4 | ; |
---|
5 | ; PURPOSE: |
---|
6 | ; |
---|
7 | ; The purpose of this compound widget is to create a resizeable |
---|
8 | ; "plot window" inside a larger "page window". I'm not sure it |
---|
9 | ; has any value except as a utility routine for the PostScript |
---|
10 | ; configuration object FSC_PSCONFIG__DEFINE, but it's a neat |
---|
11 | ; program anyway. :-) |
---|
12 | ; |
---|
13 | ; AUTHOR: |
---|
14 | ; |
---|
15 | ; FANNING SOFTWARE CONSULTING |
---|
16 | ; David Fanning, Ph.D. |
---|
17 | ; 1645 Sheely Drive |
---|
18 | ; Fort Collins, CO 80526 USA |
---|
19 | ; Phone: 970-221-0438 |
---|
20 | ; E-mail: davidf@dfanning.com |
---|
21 | ; Coyote's Guide to IDL Programming: http://www.dfanning.com/ |
---|
22 | ; |
---|
23 | ; CATEGORY: |
---|
24 | ; |
---|
25 | ; Utility routine for FSC_PSCONFIG__DEFINE. |
---|
26 | ; |
---|
27 | ; CALLING SEQUENCE: |
---|
28 | ; |
---|
29 | ; plotwindowObject = CW_PlotWindow(parent) |
---|
30 | ; |
---|
31 | ; REQUIRED INPUT PARAMETERS: |
---|
32 | ; |
---|
33 | ; parent - The parent base widget of this compound widget. |
---|
34 | ; |
---|
35 | ; RETURN VALUE: |
---|
36 | ; |
---|
37 | ; plotwindowObject - The object reference of the compound widget. |
---|
38 | ; |
---|
39 | ; KEYWORDS: |
---|
40 | ; |
---|
41 | ; COLOR - If set, display the window in "color". This is the default on 24-bit devices. |
---|
42 | ; DEBUG - Set this keyword to turn traceback error handling on in the error handling code. |
---|
43 | ; EVENT_PRO - The event procedure for the widget. Required for events to be generated. Otherwise, all events are handled internally. |
---|
44 | ; LANDSCAPE - If set, display the page in landscape mode. Otherwise the page is display in portrait mode. |
---|
45 | ; PAGESIZE - The "pagesize" of the widget. Possible values are: "LETTER", "LEDGER", "LEGAL", "A4", and "DISPLAY". |
---|
46 | ; UNITS - A string indicating INCHES or CENTIMETER units. DEVICE units represented by a null string, "". |
---|
47 | ; UVALUE - A user value for the caller of this program. |
---|
48 | ; WINDOWCOLOR - A three-element array specifying the background window color (RGB). |
---|
49 | ; WINDOWSIZE - The size of the "window" on the page. A four-element array of normalized coordinates in the form [x0, y0, x1, y1]. |
---|
50 | ; |
---|
51 | ; EVENT STRUCTURE: |
---|
52 | ; |
---|
53 | ; The event structure that is returned from this compound widget is defined like this, |
---|
54 | ; where the sizes and offsets locate the target "window" on the page in normalized units: |
---|
55 | ; |
---|
56 | ; event = {ID:0L, TOP:0L, HANDLER:0L, XSize:0.0, YSize:0.0, XOffset:0.0, YOffset:0.0} |
---|
57 | ; |
---|
58 | ; MODIFICATIONS: |
---|
59 | ; |
---|
60 | ; Written by David Fanning, 31 January 2000. |
---|
61 | ; Fixed a small bug that prevented it working on Macintosh computers. 26 Sept 2000. DWF. |
---|
62 | ; Added a "DISPLAY" page size, so the program can be used to position |
---|
63 | ; plots and other graphics in a display window. The "page area" will |
---|
64 | ; have the same aspect ratio is the current graphics window. 17 March 2001. DWF. |
---|
65 | ; Changed some of the tolerances for "closeness" from 0.1 to 0.025 to allow smaller |
---|
66 | ; sizing for colorbars and other small objects. 6 July 2005. DWF. |
---|
67 | ;- |
---|
68 | ; |
---|
69 | ;########################################################################### |
---|
70 | ; |
---|
71 | ; LICENSE |
---|
72 | ; |
---|
73 | ; This software is OSI Certified Open Source Software. |
---|
74 | ; OSI Certified is a certification mark of the Open Source Initiative. |
---|
75 | ; |
---|
76 | ; Copyright © 2000-2001 Fanning Software Consulting |
---|
77 | ; |
---|
78 | ; This software is provided "as-is", without any express or |
---|
79 | ; implied warranty. In no event will the authors be held liable |
---|
80 | ; for any damages arising from the use of this software. |
---|
81 | ; |
---|
82 | ; Permission is granted to anyone to use this software for any |
---|
83 | ; purpose, including commercial applications, and to alter it and |
---|
84 | ; redistribute it freely, subject to the following restrictions: |
---|
85 | ; |
---|
86 | ; 1. The origin of this software must not be misrepresented; you must |
---|
87 | ; not claim you wrote the original software. If you use this software |
---|
88 | ; in a product, an acknowledgment in the product documentation |
---|
89 | ; would be appreciated, but is not required. |
---|
90 | ; |
---|
91 | ; 2. Altered source versions must be plainly marked as such, and must |
---|
92 | ; not be misrepresented as being the original software. |
---|
93 | ; |
---|
94 | ; 3. This notice may not be removed or altered from any source distribution. |
---|
95 | ; |
---|
96 | ; For more information on Open Source Software, visit the Open Source |
---|
97 | ; web site: http://www.opensource.org. |
---|
98 | ; |
---|
99 | ;########################################################################### |
---|
100 | ; |
---|
101 | |
---|
102 | |
---|
103 | FUNCTION FSC_PLOTWINDOW_Error_Message, theMessage, Traceback=traceback, NoName=noName |
---|
104 | |
---|
105 | On_Error, 2 |
---|
106 | |
---|
107 | ; Check for presence and type of message. |
---|
108 | |
---|
109 | IF N_Elements(theMessage) EQ 0 THEN theMessage = !Error_State.Msg |
---|
110 | s = Size(theMessage) |
---|
111 | messageType = s[s[0]+1] |
---|
112 | IF messageType NE 7 THEN BEGIN |
---|
113 | Message, "The message parameter must be a string." |
---|
114 | ENDIF |
---|
115 | |
---|
116 | ; Get the call stack and the calling routine's name. |
---|
117 | |
---|
118 | Help, Calls=callStack |
---|
119 | callingRoutine = (StrSplit(StrCompress(callStack[1])," ", /Extract))[0] |
---|
120 | |
---|
121 | ; Are widgets supported? Doesn't matter in IDL 5.3 and higher. |
---|
122 | |
---|
123 | widgetsSupported = ((!D.Flags AND 65536L) NE 0) OR Float(!Version.Release) GE 5.3 |
---|
124 | IF widgetsSupported THEN BEGIN |
---|
125 | IF Keyword_Set(noName) THEN answer = Dialog_Message(theMessage) ELSE BEGIN |
---|
126 | IF StrUpCase(callingRoutine) EQ "$MAIN$" THEN answer = Dialog_Message(theMessage) ELSE $ |
---|
127 | answer = Dialog_Message(StrUpCase(callingRoutine) + ": " + theMessage) |
---|
128 | ENDELSE |
---|
129 | ENDIF ELSE BEGIN |
---|
130 | Message, theMessage, /Continue, /NoPrint, /NoName, /NoPrefix |
---|
131 | Print, '%' + callingRoutine + ': ' + theMessage |
---|
132 | answer = 'OK' |
---|
133 | ENDELSE |
---|
134 | |
---|
135 | ; Provide traceback information if requested. |
---|
136 | |
---|
137 | IF Keyword_Set(traceback) THEN BEGIN |
---|
138 | Help, /Last_Message, Output=traceback |
---|
139 | FOR j=0,N_Elements(traceback)-1 DO Print, traceback[j] |
---|
140 | ENDIF |
---|
141 | |
---|
142 | RETURN, answer |
---|
143 | END ;---------------------------------------------------------------------------------- |
---|
144 | |
---|
145 | |
---|
146 | |
---|
147 | FUNCTION FSC_PLOTWINDOW_Normalize, range, Position=position |
---|
148 | |
---|
149 | On_Error, 1 |
---|
150 | IF N_Params() EQ 0 THEN Message, 'Please pass range vector as argument.' |
---|
151 | |
---|
152 | IF (N_Elements(position) EQ 0) THEN position = [0.0, 1.0] ELSE $ |
---|
153 | position=Float(position) |
---|
154 | range = Float(range) |
---|
155 | |
---|
156 | scale = [((position[0]*range[1])-(position[1]*range[0])) / $ |
---|
157 | (range[1]-range[0]), (position[1]-position[0])/(range[1]-range[0])] |
---|
158 | |
---|
159 | RETURN, scale |
---|
160 | END ;---------------------------------------------------------------------------------- |
---|
161 | |
---|
162 | |
---|
163 | |
---|
164 | PRO FSC_PLOTWINDOW::Refresh |
---|
165 | self.theWindow->Draw, self.theView |
---|
166 | END ;---------------------------------------------------------------------------------- |
---|
167 | |
---|
168 | |
---|
169 | |
---|
170 | PRO FSC_PLOTWINDOW::SetWindowColor, theColor |
---|
171 | |
---|
172 | ; Set the background color of the view. |
---|
173 | |
---|
174 | self.theView->SetProperty, Color=theColor |
---|
175 | self.theWindow->Draw, self.theView |
---|
176 | END ;---------------------------------------------------------------------------------- |
---|
177 | |
---|
178 | |
---|
179 | |
---|
180 | FUNCTION FSC_PLOTWINDOW::GetUValue |
---|
181 | |
---|
182 | ; Get the user value of the compound widget. |
---|
183 | |
---|
184 | parent = Widget_Info(self.drawID, /Parent) |
---|
185 | Widget_Control, parent, Get_UValue=theValue |
---|
186 | RETURN, theValue |
---|
187 | END ;---------------------------------------------------------------------------------- |
---|
188 | |
---|
189 | |
---|
190 | |
---|
191 | PRO FSC_PLOTWINDOW::SetColor, on_off |
---|
192 | |
---|
193 | ; Sets the color of the plot window. Different colors |
---|
194 | ; depending on depth of visual class. |
---|
195 | |
---|
196 | IF on_off THEN BEGIN |
---|
197 | self.theBackground->SetProperty, Color=[255,255,150] |
---|
198 | self.thePlot->SetProperty, Color=[255, 0, 0] |
---|
199 | ENDIF ELSE BEGIN |
---|
200 | Device, Get_Visual_Depth=theDepth |
---|
201 | IF theDepth GT 8 THEN backColor = [210, 200, 180] ELSE backColor = [220, 220, 220] |
---|
202 | self.theBackground->SetProperty, Color=backColor |
---|
203 | self.thePlot->SetProperty, Color=[0, 0, 0] |
---|
204 | ENDELSE |
---|
205 | |
---|
206 | ; Draw the view. |
---|
207 | |
---|
208 | IF Obj_Valid(self.theWindow) THEN self.theWindow->Draw, self.theView |
---|
209 | END ;---------------------------------------------------------------------------------- |
---|
210 | |
---|
211 | |
---|
212 | |
---|
213 | PRO FSC_PLOTWINDOW::SetUnits, units |
---|
214 | |
---|
215 | ; Sets the type of units to report in. |
---|
216 | |
---|
217 | possibleUnits = ["INCHES", "CENTIMETERS", ""] |
---|
218 | units = StrUpCase(units) |
---|
219 | index = WHERE(possibleUnits EQ units, count) |
---|
220 | IF count EQ 0 THEN BEGIN |
---|
221 | ok = Dialog_Message('Unknown units: ' + units + '. Returning...') |
---|
222 | RETURN |
---|
223 | ENDIF |
---|
224 | self.units = units |
---|
225 | END ;---------------------------------------------------------------------------------- |
---|
226 | |
---|
227 | |
---|
228 | |
---|
229 | PRO FSC_PLOTWINDOW::GetWindowLocation, xsize, ysize, xoffset, yoffset |
---|
230 | |
---|
231 | ; Returns the current size and offsets of the plot window in |
---|
232 | ; units of inches or centimeters, as appropriate. |
---|
233 | |
---|
234 | xsize = self.xlength |
---|
235 | ysize = self.ylength |
---|
236 | xoffset = self.x1 |
---|
237 | yoffset = self.y1 |
---|
238 | |
---|
239 | factor = Float(self.pixels_per_inch) |
---|
240 | |
---|
241 | CASE self.units OF |
---|
242 | 'INCHES': BEGIN |
---|
243 | xsize_in_pixels = (xsize * self.xsize) |
---|
244 | ysize_in_pixels = (ysize * self.ysize) |
---|
245 | xoff_in_pixels = (xoffset * self.xsize) |
---|
246 | yoff_in_pixels = (yoffset * self.ysize) |
---|
247 | xsize = (xsize_in_pixels / factor) |
---|
248 | ysize = (ysize_in_pixels / factor) |
---|
249 | xoffset = (xoff_in_pixels / factor) |
---|
250 | yoffset = (yoff_in_pixels / factor) |
---|
251 | ENDCASE |
---|
252 | 'CENTIMETERS': BEGIN |
---|
253 | xsize_in_pixels = (xsize * self.xsize) |
---|
254 | ysize_in_pixels = (ysize * self.ysize) |
---|
255 | xoff_in_pixels = (xoffset * self.xsize) |
---|
256 | yoff_in_pixels = (yoffset * self.ysize) |
---|
257 | xsize = (xsize_in_pixels / factor * 2.54) |
---|
258 | ysize = (ysize_in_pixels / factor * 2.54) |
---|
259 | xoffset = (xoff_in_pixels / factor * 2.54) |
---|
260 | yoffset = (yoff_in_pixels / factor * 2.54) |
---|
261 | ENDCASE |
---|
262 | "" : |
---|
263 | ELSE: ok = Dialog_Message('Unknown units: ' + self.units + '. Returning...') |
---|
264 | ENDCASE |
---|
265 | |
---|
266 | END ;---------------------------------------------------------------------------------- |
---|
267 | |
---|
268 | |
---|
269 | |
---|
270 | PRO FSC_PLOTWINDOW::SetWindowLocation, xsize, ysize, xoffset, yoffset |
---|
271 | |
---|
272 | ; Sets the location of the plot window in the view. |
---|
273 | ; Converts inches or centimeters to pixels. |
---|
274 | |
---|
275 | factor = Float(self.pixels_per_inch) |
---|
276 | |
---|
277 | CASE self.units OF |
---|
278 | 'INCHES': BEGIN |
---|
279 | xsize_in_pixels = (xsize * factor) |
---|
280 | ysize_in_pixels = (ysize * factor) |
---|
281 | xoff_in_pixels = (xoffset * factor) |
---|
282 | yoff_in_pixels = (yoffset * factor) |
---|
283 | x1 = 0.0 > (xoff_in_pixels / self.xsize) < 0.85 |
---|
284 | y1 = 0.0 > (yoff_in_pixels / self.ysize) < 0.85 |
---|
285 | x2 = (x1 + (xsize_in_pixels / self.xsize)) < 1.0 |
---|
286 | y2 = (y1 + (ysize_in_pixels / self.ysize)) < 1.0 |
---|
287 | ENDCASE |
---|
288 | 'CENTIMETERS': BEGIN |
---|
289 | xsize_in_pixels = (xsize * factor / 2.54) |
---|
290 | ysize_in_pixels = (ysize * factor / 2.54) |
---|
291 | xoff_in_pixels = (xoffset * factor / 2.54) |
---|
292 | yoff_in_pixels = (yoffset * factor / 2.54) |
---|
293 | x1 = 0.0 > (xoff_in_pixels / self.xsize) < 0.85 |
---|
294 | y1 = 0.0 > (yoff_in_pixels / self.ysize) < 0.85 |
---|
295 | x2 = (x1 + (xsize_in_pixels / self.xsize)) < 1.0 |
---|
296 | y2 = (y1 + (ysize_in_pixels / self.ysize)) < 1.0 |
---|
297 | ENDCASE |
---|
298 | "" : |
---|
299 | ELSE: ok = Dialog_Message('Unknown units: ' + self.units + '. Returning...') |
---|
300 | ENDCASE |
---|
301 | |
---|
302 | self.xlength = x2 - x1 |
---|
303 | self.ylength = y2 - y1 |
---|
304 | self.x1 = x1 |
---|
305 | self.x2 = x2 |
---|
306 | self.y1 = y1 |
---|
307 | self.y2 = y2 |
---|
308 | self->SetWindowSize, [x1, y1, x2, y2] |
---|
309 | |
---|
310 | END ;---------------------------------------------------------------------------------- |
---|
311 | |
---|
312 | PRO FSC_PLOTWINDOW::SetWindowSize, position |
---|
313 | |
---|
314 | ; Set the size of the plot window. Axes have to be |
---|
315 | ; rescaled appropriately. |
---|
316 | |
---|
317 | IF N_Elements(position) EQ 0 THEN position = [0.2, 0.2, 0.8, 0.8] |
---|
318 | |
---|
319 | x1 = position[0] |
---|
320 | y1 = position[1] |
---|
321 | x2 = position[2] |
---|
322 | y2 = position[3] |
---|
323 | |
---|
324 | new = FltArr(2,5) |
---|
325 | new[0,*] = [x1, x1, x2, x2, x1] |
---|
326 | new[1,*] = [y1, y2, y2, y1, y1] |
---|
327 | |
---|
328 | ; Modify the graphics objects. |
---|
329 | |
---|
330 | self.theBackground->SetProperty, Data=new |
---|
331 | xs = FSC_PlotWindow_Normalize([0,100], Position=[new[0,0]+0.05, new[0,2]-0.05]) |
---|
332 | ys = FSC_PlotWindow_Normalize([-1,1], Position=[new[1,0]+0.05, new[1,1]-0.05]) |
---|
333 | |
---|
334 | self.theXAxis->SetProperty, XCoord_Conv=xs, Location=[1000, new[1,0]+0.05, 0] |
---|
335 | self.theYAxis->SetProperty, YCoord_Conv=ys, Location=[new[0,0]+.05, 1000, 0] |
---|
336 | self.thePlot->SetProperty, XCoord_Conv=xs, YCoord_Conv=ys |
---|
337 | self.x1 = new[0,0] |
---|
338 | self.x2 = new[0,2] |
---|
339 | self.y1 = new[1,0] |
---|
340 | self.y2 = new[1,1] |
---|
341 | self.xlength = self.x2 - self.x1 |
---|
342 | self.ylength = self.y2 - self.y1 |
---|
343 | |
---|
344 | ; Draw the view after resetting the transformation matrix. |
---|
345 | |
---|
346 | self.theModel->Reset |
---|
347 | self.theWindow->Draw, self.theView |
---|
348 | END ;---------------------------------------------------------------------------------- |
---|
349 | |
---|
350 | |
---|
351 | |
---|
352 | PRO FSC_PLOTWINDOW::SetPageSize, pagesize, Landscape=landscape, TLB=tlb |
---|
353 | |
---|
354 | ; Sets the page size of the window. |
---|
355 | |
---|
356 | ; 200 pixels = 11 inches. |
---|
357 | ; Letter 8.5 x 11. |
---|
358 | ; Ledger 11 x 17. |
---|
359 | ; Legal 8.5 x 14. |
---|
360 | ; A4 8.27 x 11.7. |
---|
361 | |
---|
362 | STANDARD_SIZE = self.pixels_per_inch * 11.0 |
---|
363 | |
---|
364 | IF N_Elements(pagesize) EQ 0 THEN pagesize = "LETTER" |
---|
365 | pagesize = StrUpCase(pagesize) |
---|
366 | IF N_Elements(tlb) EQ 0 THEN tlb = self.base |
---|
367 | |
---|
368 | CASE pagesize OF |
---|
369 | 'LETTER': BEGIN |
---|
370 | xsize = STANDARD_SIZE * (8.5/11.0) |
---|
371 | ysize = STANDARD_SIZE |
---|
372 | ENDCASE |
---|
373 | 'LEDGER': BEGIN |
---|
374 | xsize = STANDARD_SIZE |
---|
375 | ysize = STANDARD_SIZE * (17.0/11.0) |
---|
376 | ENDCASE |
---|
377 | 'LEGAL': BEGIN |
---|
378 | xsize = STANDARD_SIZE * (8.5/11.0) |
---|
379 | ysize = STANDARD_SIZE * (14.0/11.0) |
---|
380 | ENDCASE |
---|
381 | 'A4': BEGIN |
---|
382 | xsize = STANDARD_SIZE * (8.27/11.0) |
---|
383 | ysize = STANDARD_SIZE * (11.7/11.0) |
---|
384 | ENDCASE |
---|
385 | 'DISPLAY': BEGIN |
---|
386 | xsize = 300 |
---|
387 | ratio = Float(!D.Y_Size) / !D.X_Size |
---|
388 | ysize = 300 * ratio |
---|
389 | ENDCASE |
---|
390 | ELSE: BEGIN |
---|
391 | ok = Dialog_Message('Unknown page size: ' + pagesize + '. Returning...') |
---|
392 | RETURN |
---|
393 | ENDCASE |
---|
394 | ENDCASE |
---|
395 | |
---|
396 | IF Keyword_Set(landscape) THEN BEGIN |
---|
397 | temp = xsize |
---|
398 | xsize = ysize |
---|
399 | ysize = temp |
---|
400 | ENDIF |
---|
401 | |
---|
402 | self.xsize = ROUND(xsize) |
---|
403 | self.ysize = ROUND(ysize) |
---|
404 | self.pagesize = pagesize |
---|
405 | |
---|
406 | ; Bugs in X windows implementation of window resizing necessitate |
---|
407 | ; destroying and re-creating the draw widget window. |
---|
408 | |
---|
409 | IF !D.Name NE 'X' THEN BEGIN |
---|
410 | |
---|
411 | self.theWindow->SetProperty, Dimensions=[xsize, ysize] |
---|
412 | |
---|
413 | ENDIF ELSE BEGIN |
---|
414 | |
---|
415 | Widget_Control, tlb, Update=0 |
---|
416 | Widget_Control, self.drawID, Kill_Notify="" |
---|
417 | Widget_Control, self.drawID, /Destroy |
---|
418 | self.drawID = Widget_Draw(self.base, Button_Events=1, Expose_Events=1, $ |
---|
419 | Retain=0, Graphics_Level=2, XSize=xsize, YSize=ysize, $ |
---|
420 | Event_Pro='FSC_PLOTWINDOW_Events', UValue=self, Renderer=1, $ |
---|
421 | Kill_Notify='FSC_PLOTWINDOW_Kill_Notify', Motion_Events=1) |
---|
422 | Widget_Control, self.drawID, /Realize |
---|
423 | Widget_Control, self.drawID, Get_Value=theWindow |
---|
424 | self.theWindow = theWindow |
---|
425 | Widget_Control, tlb, Update=1 |
---|
426 | |
---|
427 | ENDELSE |
---|
428 | |
---|
429 | self.thewindow->Draw, self.theView |
---|
430 | |
---|
431 | END ;---------------------------------------------------------------------------------- |
---|
432 | |
---|
433 | |
---|
434 | |
---|
435 | FUNCTION FSC_PLOTWINDOW::GetPagePixels, pagesize, Landscape=landscape |
---|
436 | |
---|
437 | ; Given the page size or type, returns the xsize and ysize |
---|
438 | ; of the draw widget in pixels. |
---|
439 | |
---|
440 | ; 198 pixels = 11 inches. |
---|
441 | ; Letter 8.5 x 11. |
---|
442 | ; Ledger 11 x 17. |
---|
443 | ; Legal 8.5 x 14. |
---|
444 | ; A4 8.27 x 11.7. |
---|
445 | |
---|
446 | STANDARD_SIZE = self.pixels_per_inch * 11.0 |
---|
447 | |
---|
448 | IF N_Elements(pagesize) EQ 0 THEN pagesize = "LETTER" |
---|
449 | pagesize = StrUpCase(pagesize) |
---|
450 | |
---|
451 | CASE pagesize OF |
---|
452 | 'LETTER': BEGIN |
---|
453 | xsize = STANDARD_SIZE * (8.5/11.0) |
---|
454 | ysize = STANDARD_SIZE |
---|
455 | ENDCASE |
---|
456 | 'LEDGER': BEGIN |
---|
457 | xsize = STANDARD_SIZE |
---|
458 | ysize = STANDARD_SIZE * (17.0/11.0) |
---|
459 | ENDCASE |
---|
460 | 'LEGAL': BEGIN |
---|
461 | xsize = STANDARD_SIZE * (8.5/11.0) |
---|
462 | ysize = STANDARD_SIZE * (14.0/11.0) |
---|
463 | ENDCASE |
---|
464 | 'A4': BEGIN |
---|
465 | xsize = STANDARD_SIZE * (8.27/11.0) |
---|
466 | ysize = STANDARD_SIZE * (11.7/11.0) |
---|
467 | ENDCASE |
---|
468 | 'DISPLAY': BEGIN |
---|
469 | xsize = 300 |
---|
470 | ratio = Float(!D.Y_Size) / !D.X_Size |
---|
471 | ; Check for *very* strange windows. |
---|
472 | IF ratio LT 0.2 THEN ratio = 1.0 |
---|
473 | IF ratio GT 5 THEN ratio = 1.0 |
---|
474 | ysize = 300 * ratio |
---|
475 | ENDCASE |
---|
476 | ENDCASE |
---|
477 | |
---|
478 | IF Keyword_Set(landscape) THEN BEGIN |
---|
479 | temp = xsize |
---|
480 | xsize = ysize |
---|
481 | ysize = temp |
---|
482 | ENDIF |
---|
483 | |
---|
484 | RETURN, [ROUND(xsize), ROUND(ysize)] |
---|
485 | |
---|
486 | END ;---------------------------------------------------------------------------------- |
---|
487 | |
---|
488 | |
---|
489 | |
---|
490 | FUNCTION FSC_PLOTWINDOW::GetPosition |
---|
491 | |
---|
492 | ; Returns the current position of the plot window in |
---|
493 | ; the view. Normalized coordinates. |
---|
494 | |
---|
495 | RETURN, [self.x1, self.y1, self.x2, self.y2] |
---|
496 | END ;---------------------------------------------------------------------------------- |
---|
497 | |
---|
498 | |
---|
499 | |
---|
500 | PRO FSC_PLOTWINDOW::Resize, event, direction |
---|
501 | |
---|
502 | ; Performs window resizing, depending upon which of eight |
---|
503 | ; possible directions you can move the window. |
---|
504 | |
---|
505 | IF direction EQ 'NONE' OR direction EQ 'MOVE' THEN BEGIN |
---|
506 | RETURN |
---|
507 | ENDIF |
---|
508 | |
---|
509 | ; Calculate movement in normalized coordinates. Update start coords. |
---|
510 | |
---|
511 | deltax = (event.x - self.currentX) / self.xsize |
---|
512 | deltay = (event.y - self.currentY) / self.ysize |
---|
513 | self.currentX = event.x |
---|
514 | self.currentY = event.y |
---|
515 | |
---|
516 | CASE direction OF |
---|
517 | 'SE': BEGIN |
---|
518 | x1 = self.x1 |
---|
519 | x2 = (self.x2 + deltax) < 1.0 |
---|
520 | y1 = (self.y1 + deltay) > 0.0 |
---|
521 | y2 = self.y2 |
---|
522 | IF x2 LE x1 + 0.025 THEN x2 = x1 + 0.025 |
---|
523 | IF y1 GE y2 - 0.025 THEN y1 = y2 - 0.025 |
---|
524 | END |
---|
525 | 'E' : BEGIN |
---|
526 | x1 = self.x1 |
---|
527 | x2 = (self.x2 + deltax) < 1.0 |
---|
528 | y1 = self.y1 |
---|
529 | y2 = self.y2 |
---|
530 | IF x2 LE x1 + 0.025 THEN x2 = x1 + 0.1 |
---|
531 | END |
---|
532 | 'SW': BEGIN |
---|
533 | x1 = (self.x1 + deltax) > 0.0 |
---|
534 | x2 = self.x2 |
---|
535 | y1 = (self.y1 + deltay) > 0.0 |
---|
536 | y2 = self.y2 |
---|
537 | IF x1 GE x2 - 0.025 THEN x1 = x2 - 0.025 |
---|
538 | IF y1 GE y2 - 0.025 THEN y1 = y2 - 0.025 |
---|
539 | END |
---|
540 | 'S' : BEGIN |
---|
541 | x1 = self.x1 |
---|
542 | x2 = self.x2 |
---|
543 | y1 = (self.y1 + deltay) > 0.0 |
---|
544 | y2 = self.y2 |
---|
545 | IF y1 GE y2 - 0.025 THEN y1 = y2 - 0.025 |
---|
546 | END |
---|
547 | 'N' : BEGIN |
---|
548 | x1 = self.x1 |
---|
549 | x2 = self.x2 |
---|
550 | y1 = self.y1 |
---|
551 | y2 = (self.y2 + deltay) < 1.0 |
---|
552 | IF y2 LE y1 + 0.025 THEN y2 = y1 + 0.025 |
---|
553 | END |
---|
554 | 'NE': BEGIN |
---|
555 | x1 = self.x1 |
---|
556 | x2 = (self.x2 + deltax) < 1.0 |
---|
557 | y1 = self.y1 |
---|
558 | y2 = (self.y2 + deltay) < 1.0 |
---|
559 | IF x2 LE x1 + 0.025 THEN x2 = x1 + 0.025 |
---|
560 | IF y2 LE y1 + 0.025 THEN y2 = y1 + 0.025 |
---|
561 | END |
---|
562 | 'W' : BEGIN |
---|
563 | x1 = (self.x1 + deltax) > 0.0 |
---|
564 | x2 = self.x2 |
---|
565 | y1 = self.y1 |
---|
566 | y2 = self.y2 |
---|
567 | IF x1 GE x2 - 0.025 THEN x1 = x2 - 0.025 |
---|
568 | END |
---|
569 | 'NW': BEGIN |
---|
570 | x1 = (self.x1 + deltax) > 0.0 |
---|
571 | x2 = self.x2 |
---|
572 | y1 = self.y1 |
---|
573 | y2 = (self.y2 + deltay) < 1.0 |
---|
574 | IF x1 GE x2 - 0.025 THEN x1 = x2 - 0.025 |
---|
575 | IF y2 LE y1 + 0.025 THEN y2 = y1 + 0.025 |
---|
576 | |
---|
577 | END |
---|
578 | ENDCASE |
---|
579 | |
---|
580 | new = FltArr(2,5) |
---|
581 | new[0,*] = [x1, x1, x2, x2, x1] |
---|
582 | new[1,*] = [y1, y2, y2, y1, y1] |
---|
583 | |
---|
584 | ; Modify the graphics objects. |
---|
585 | |
---|
586 | self.theBackground->SetProperty, Data=new |
---|
587 | |
---|
588 | xs = FSC_PlotWindow_Normalize([0,100], Position=[new[0,0]+0.05, new[0,2]-0.05]) > 10e-6 |
---|
589 | ys = FSC_PlotWindow_Normalize([-1,1], Position=[new[1,0]+0.05, new[1,1]-0.05]) > 10e-6 |
---|
590 | |
---|
591 | self.theXAxis->SetProperty, XCoord_Conv=xs, Location=[1000, new[1,0]+0.05, 0] |
---|
592 | self.theYAxis->SetProperty, YCoord_Conv=ys, Location=[new[0,0]+.05, 1000, 0] |
---|
593 | self.thePlot->SetProperty, XCoord_Conv=xs, YCoord_Conv=ys |
---|
594 | self.x1 = new[0,0] |
---|
595 | self.x2 = new[0,2] |
---|
596 | self.y1 = new[1,0] |
---|
597 | self.y2 = new[1,1] |
---|
598 | self.xlength = self.x2 - self.x1 |
---|
599 | self.ylength = self.y2 - self.y1 |
---|
600 | |
---|
601 | ; Draw the view after resetting the transformation matrix. |
---|
602 | |
---|
603 | self.theModel->Reset |
---|
604 | self.theWindow->Draw, self.theView |
---|
605 | |
---|
606 | END ;---------------------------------------------------------------------------------- |
---|
607 | |
---|
608 | |
---|
609 | |
---|
610 | PRO FSC_PLOTWINDOW::CenterPlot, event |
---|
611 | |
---|
612 | ; Centers the plot in the window. |
---|
613 | |
---|
614 | new = FltArr(2,5) |
---|
615 | self.x1 = (1.0 - self.xlength) / 2.0 |
---|
616 | self.x2 = self.x1 + self.xlength |
---|
617 | self.y1 = (1.0 - self.ylength) / 2.0 |
---|
618 | self.y2 = self.y1 + self.ylength |
---|
619 | |
---|
620 | new[0,*] = [self.x1, self.x1, self.x2, self.x2, self.x1] |
---|
621 | new[1,*] = [self.y1, self.y2, self.y2, self.y1, self.y1] |
---|
622 | |
---|
623 | ; Modify the graphics objects. |
---|
624 | |
---|
625 | self.theBackground->SetProperty, Data=new |
---|
626 | |
---|
627 | xs = FSC_PlotWindow_Normalize([0,100], Position=[new[0,0]+0.05, new[0,2]-0.05]) |
---|
628 | ys = FSC_PlotWindow_Normalize([-1,1], Position=[new[1,0]+0.05, new[1,1]-0.05]) |
---|
629 | |
---|
630 | self.theXAxis->SetProperty, XCoord_Conv=xs, Location=[1000, new[1,0]+0.05, 0] |
---|
631 | self.theYAxis->SetProperty, YCoord_Conv=ys, Location=[new[0,0]+.05, 1000, 0] |
---|
632 | self.thePlot->SetProperty, XCoord_Conv=xs, YCoord_Conv=ys |
---|
633 | self.x1 = new[0,0] |
---|
634 | self.x2 = new[0,2] |
---|
635 | self.y1 = new[1,0] |
---|
636 | self.y2 = new[1,1] |
---|
637 | |
---|
638 | ; Draw the view after resetting the transformation matrix. |
---|
639 | |
---|
640 | self.theModel->Reset |
---|
641 | self.theWindow->Draw, self.theView |
---|
642 | |
---|
643 | END ;---------------------------------------------------------------------------------- |
---|
644 | |
---|
645 | |
---|
646 | |
---|
647 | PRO FSC_PLOTWINDOW::MovePlot, event |
---|
648 | |
---|
649 | ; Calculate movement in normalized coordinates. Update start coords. |
---|
650 | |
---|
651 | deltax = (event.x - self.currentX) / self.xsize |
---|
652 | deltay = (event.y - self.currentY) / self.ysize |
---|
653 | self.currentX = event.x |
---|
654 | self.currentY = event.y |
---|
655 | |
---|
656 | ; Translate the selected model. |
---|
657 | |
---|
658 | self.theModel->Translate, deltax, deltay, 0 |
---|
659 | |
---|
660 | ; Get the current transformation matrix. |
---|
661 | |
---|
662 | matrix = self.theModel->GetCTM() |
---|
663 | |
---|
664 | ; Get the vertices of the polygon object. |
---|
665 | |
---|
666 | self.theBackground->GetProperty, Data=vertices |
---|
667 | |
---|
668 | ; Apply the transformation matrix to the vertices. |
---|
669 | |
---|
670 | new = FltArr(2,5) |
---|
671 | FOR j=0,4 DO BEGIN |
---|
672 | v = [vertices[*, j], 0.0, 1.0] |
---|
673 | new[*, j] = (matrix ## v)[0:1] |
---|
674 | ENDFOR |
---|
675 | |
---|
676 | IF new[0,0] LT 0.0 THEN new[0,*] = [0.0, 0.0, self.xlength, self.xlength, 0.0] |
---|
677 | IF new[0,2] GT 1.0 THEN new[0,*] = [1.0-self.xlength, 1.0-self.xlength, 1.0, 1.0, 1.0-self.xlength] |
---|
678 | IF new[1,0] LT 0.0 THEN new[1,*] = [0.0, self.ylength, self.ylength, 0.0, 0.0] |
---|
679 | IF new[1,1] GT 1.0 THEN new[1,*] = [1.0-self.ylength, 1.0, 1.0, 1.0-self.ylength, 1.0-self.ylength] |
---|
680 | |
---|
681 | ; Modify the graphics objects. |
---|
682 | |
---|
683 | self.theBackground->SetProperty, Data=new |
---|
684 | |
---|
685 | xs = FSC_PlotWindow_Normalize([0,100], Position=[new[0,0]+0.05, new[0,2]-0.05]) |
---|
686 | ys = FSC_PlotWindow_Normalize([-1,1], Position=[new[1,0]+0.05, new[1,1]-0.05]) |
---|
687 | |
---|
688 | self.theXAxis->SetProperty, XCoord_Conv=xs, Location=[1000, new[1,0]+0.05, 0] |
---|
689 | self.theYAxis->SetProperty, YCoord_Conv=ys, Location=[new[0,0]+.05, 1000, 0] |
---|
690 | self.thePlot->SetProperty, XCoord_Conv=xs, YCoord_Conv=ys |
---|
691 | self.x1 = new[0,0] |
---|
692 | self.x2 = new[0,2] |
---|
693 | self.y1 = new[1,0] |
---|
694 | self.y2 = new[1,1] |
---|
695 | |
---|
696 | ; Draw the view after resetting the transformation matrix. |
---|
697 | |
---|
698 | self.theModel->Reset |
---|
699 | self.theWindow->Draw, self.theView |
---|
700 | |
---|
701 | END ;---------------------------------------------------------------------------------- |
---|
702 | |
---|
703 | |
---|
704 | |
---|
705 | FUNCTION FSC_PLOTWINDOW::WhichButtonReleased, event |
---|
706 | |
---|
707 | ; Determines which button was used. |
---|
708 | |
---|
709 | buttons = ['NONE', 'LEFT', 'MIDDLE', 'NONE', 'RIGHT'] |
---|
710 | RETURN, buttons[event.release] |
---|
711 | END ;---------------------------------------------------------------------------------- |
---|
712 | |
---|
713 | |
---|
714 | |
---|
715 | FUNCTION FSC_PLOTWINDOW::WhichButtonPressed, event |
---|
716 | |
---|
717 | ; Determines which button was used. |
---|
718 | |
---|
719 | buttons = ['NONE', 'LEFT', 'MIDDLE', 'NONE', 'RIGHT'] |
---|
720 | RETURN, buttons[event.press] |
---|
721 | END ;---------------------------------------------------------------------------------- |
---|
722 | |
---|
723 | |
---|
724 | |
---|
725 | FUNCTION FSC_PLOTWINDOW::InTarget, x, y, DIRECTION=direction |
---|
726 | |
---|
727 | ; Given a location of the cursor in the window returns the |
---|
728 | ; target location and the direction the window should be |
---|
729 | ; resized in. Have to be within 2.5% of window edge to be |
---|
730 | ; in moveable target. |
---|
731 | |
---|
732 | x = x / self.xsize |
---|
733 | y = y / self.ysize |
---|
734 | |
---|
735 | xtest = -1 |
---|
736 | IF x GE self.x1 AND x LE self.x1 + 0.025 THEN xtest = 0 |
---|
737 | IF x GT self.x1 + 0.025 AND x LT self.x2 - 0.025 THEN xtest = 1 |
---|
738 | IF x GE self.x2 - 0.025 AND x LE self.x2 THEN xtest = 2 |
---|
739 | ytest = -1 |
---|
740 | IF y GE self.y1 AND y LE self.y1 + 0.1 THEN ytest = 0 |
---|
741 | IF y GT self.y1 + 0.025 AND y LT self.y2 - 0.025 THEN ytest = 1 |
---|
742 | IF y GE self.y2 - 0.025 AND y LE self.y2 THEN ytest = 2 |
---|
743 | |
---|
744 | IF xtest EQ -1 OR ytest EQ -1 THEN BEGIN |
---|
745 | retVal = 'ORIGINAL' |
---|
746 | direction = 'NONE' |
---|
747 | ENDIF |
---|
748 | IF xtest EQ 0 AND ytest EQ 0 THEN BEGIN |
---|
749 | retVal = 'SIZE_SW' |
---|
750 | direction = 'SW' |
---|
751 | ENDIF |
---|
752 | IF xtest EQ 0 AND ytest EQ 1 THEN BEGIN |
---|
753 | retVal = 'SIZE_EW' |
---|
754 | direction = 'W' |
---|
755 | ENDIF |
---|
756 | IF xtest EQ 0 AND ytest EQ 2 THEN BEGIN |
---|
757 | retVal = 'SIZE_NW' |
---|
758 | direction = 'NW' |
---|
759 | ENDIF |
---|
760 | IF xtest EQ 1 AND ytest EQ 0 THEN BEGIN |
---|
761 | retVal = 'SIZE_NS' |
---|
762 | direction = 'S' |
---|
763 | ENDIF |
---|
764 | IF xtest EQ 1 AND ytest EQ 1 THEN BEGIN |
---|
765 | retVal = 'MOVE' |
---|
766 | direction = 'MOVE' |
---|
767 | ENDIF |
---|
768 | IF xtest EQ 1 AND ytest EQ 2 THEN BEGIN |
---|
769 | retVal = 'SIZE_NS' |
---|
770 | direction = 'N' |
---|
771 | ENDIF |
---|
772 | IF xtest EQ 2 AND ytest EQ 0 THEN BEGIN |
---|
773 | retVal = 'SIZE_SE' |
---|
774 | direction = 'SE' |
---|
775 | ENDIF |
---|
776 | IF xtest EQ 2 AND ytest EQ 1 THEN BEGIN |
---|
777 | retVal = 'SIZE_EW' |
---|
778 | direction = 'E' |
---|
779 | ENDIF |
---|
780 | IF xtest EQ 2 AND ytest EQ 2 THEN BEGIN |
---|
781 | retVal = 'SIZE_NE' |
---|
782 | direction = 'NE' |
---|
783 | ENDIF |
---|
784 | |
---|
785 | RETURN, retVal |
---|
786 | END ;---------------------------------------------------------------------------------- |
---|
787 | |
---|
788 | |
---|
789 | |
---|
790 | PRO FSC_PLOTWINDOW::Realize |
---|
791 | |
---|
792 | Widget_Control, self.drawID, Get_Value=theWindow |
---|
793 | self.theWindow = theWindow |
---|
794 | END ;---------------------------------------------------------------------------------- |
---|
795 | |
---|
796 | |
---|
797 | |
---|
798 | PRO FSC_PLOTWINDOW_Notify_Realize, drawID |
---|
799 | Widget_Control, drawID, Get_UValue=self |
---|
800 | self->Realize |
---|
801 | END ;---------------------------------------------------------------------------------- |
---|
802 | |
---|
803 | |
---|
804 | |
---|
805 | PRO FSC_PLOTWINDOW::Process_Events, event |
---|
806 | |
---|
807 | ; Handles draw widget events. |
---|
808 | |
---|
809 | possibleEvents = ['DOWN', 'UP', 'MOTION', 'SCROLL', 'EXPOSE'] |
---|
810 | thisEvent = possibleEvents[event.type] |
---|
811 | |
---|
812 | ; Are we inside a target? If so, change cursor. |
---|
813 | |
---|
814 | target = self->InTarget(event.x, event.y, Direction=direction) |
---|
815 | self.theWindow->SetCurrentCursor, target |
---|
816 | |
---|
817 | |
---|
818 | ; What kind of event is this? |
---|
819 | |
---|
820 | CASE thisEvent OF |
---|
821 | 'EXPOSE': self.theWindow->Draw, self.theView |
---|
822 | 'UP': BEGIN |
---|
823 | thisButton = self->WhichButtonReleased(event) |
---|
824 | Widget_Control, event.id, Clear_Events=1 |
---|
825 | CASE self.action OF |
---|
826 | 'MOVE': BEGIN |
---|
827 | self.currentX = -1 |
---|
828 | self.currentY = -1 |
---|
829 | self.action = "" |
---|
830 | self->GetWindowLocation, xsize, ysize, xoffset, yoffset |
---|
831 | IF self.event_pro NE "" THEN BEGIN |
---|
832 | thisEvent = {ID:event.id, TOP:event.top, HANDLER:event.handler, $ |
---|
833 | xsize:xsize, ysize:ysize, xoffset:xoffset, yoffset:yoffset} |
---|
834 | Call_Procedure, self.event_pro, thisEvent |
---|
835 | ENDIF |
---|
836 | ENDCASE |
---|
837 | 'ORIGINAL': |
---|
838 | 'RESIZE': BEGIN |
---|
839 | self.currentX = -1 |
---|
840 | self.currentY = -1 |
---|
841 | self.action = "" |
---|
842 | self.direction = "NONE" |
---|
843 | self->GetWindowLocation, xsize, ysize, xoffset, yoffset |
---|
844 | IF self.event_pro NE "" THEN BEGIN |
---|
845 | thisEvent = {ID:event.id, TOP:event.top, HANDLER:event.handler, $ |
---|
846 | xsize:xsize, ysize:ysize, xoffset:xoffset, yoffset:yoffset} |
---|
847 | Call_Procedure, self.event_pro, thisEvent |
---|
848 | ENDIF |
---|
849 | ENDCASE |
---|
850 | ELSE: |
---|
851 | ENDCASE |
---|
852 | ENDCASE |
---|
853 | 'DOWN': BEGIN |
---|
854 | thisButton = self->WhichButtonPressed(event) |
---|
855 | IF thisButton EQ 'MIDDLE' THEN BEGIN |
---|
856 | self->CenterPlot, event |
---|
857 | self->GetWindowLocation, xsize, ysize, xoffset, yoffset |
---|
858 | IF self.event_pro NE "" THEN BEGIN |
---|
859 | thisEvent = {ID:event.id, TOP:event.top, HANDLER:event.handler, $ |
---|
860 | xsize:xsize, ysize:ysize, xoffset:xoffset, yoffset:yoffset} |
---|
861 | Call_Procedure, self.event_pro, thisEvent |
---|
862 | ENDIF |
---|
863 | RETURN |
---|
864 | ENDIF |
---|
865 | CASE target OF |
---|
866 | 'ORIGINAL': RETURN |
---|
867 | 'MOVE': BEGIN |
---|
868 | self.currentX = event.x |
---|
869 | self.currentY = event.y |
---|
870 | self.action = 'MOVE' |
---|
871 | ENDCASE |
---|
872 | ELSE: BEGIN |
---|
873 | self.currentX = event.x |
---|
874 | self.currentY = event.y |
---|
875 | self.action = 'RESIZE' |
---|
876 | self.direction = direction |
---|
877 | ENDCASE |
---|
878 | ENDCASE |
---|
879 | ENDCASE |
---|
880 | 'MOTION': BEGIN |
---|
881 | CASE self.action OF |
---|
882 | 'MOVE': self->MovePlot, event |
---|
883 | 'RESIZE': self->Resize, event, self.direction |
---|
884 | ELSE: |
---|
885 | ENDCASE |
---|
886 | ENDCASE |
---|
887 | ENDCASE |
---|
888 | |
---|
889 | END ;---------------------------------------------------------------------------------- |
---|
890 | |
---|
891 | |
---|
892 | |
---|
893 | PRO FSC_PLOTWINDOW_Events, event |
---|
894 | |
---|
895 | ; Widget event handler. Calls event handler method. |
---|
896 | |
---|
897 | Widget_Control, event.id, Get_UValue=self |
---|
898 | self->Process_Events, event |
---|
899 | END ;---------------------------------------------------------------------------------- |
---|
900 | |
---|
901 | |
---|
902 | |
---|
903 | PRO FSC_PLOTWINDOW_Kill_Notify, drawID |
---|
904 | |
---|
905 | ; Destroy the plot window object when the window is destroyed. |
---|
906 | |
---|
907 | Widget_Control, drawID, Get_UValue=self |
---|
908 | Obj_Destroy, self |
---|
909 | END ;---------------------------------------------------------------------------------- |
---|
910 | |
---|
911 | |
---|
912 | |
---|
913 | PRO FSC_PLOTWINDOW::CLEANUP |
---|
914 | Obj_Destroy, self.theModel |
---|
915 | Obj_Destroy, self.theWindow |
---|
916 | Obj_Destroy, self.theView |
---|
917 | Obj_Destroy, self.plotModel |
---|
918 | END ;---------------------------------------------------------------------------------- |
---|
919 | |
---|
920 | |
---|
921 | |
---|
922 | FUNCTION FSC_PLOTWINDOW::INIT, $ |
---|
923 | parent, $ ; The parent base widget of this compound widget. Required. |
---|
924 | PageSize=pagesize, $ ; The "pagesize" of the widget. Possible values are: "LETTER", "LEDGER", "LEGAL", "A4", and "DISPLAY". |
---|
925 | WindowSize=windowsize, $ ; The size of the "window" on the page. A four-element array of normalized coordinates in the form [x0, y0, x1, y1]. |
---|
926 | Event_Pro=event_pro, $ ; The event procedure for the widget. |
---|
927 | Units=units, $ ; A string indicating INCHES or CENTIMETER units. DEVICE units represented by a null string, "". |
---|
928 | UValue=uvalue, $ ; A user value for the caller of this program. |
---|
929 | Landscape=landscape, $ ; If set, display the page in landscape mode. Otherwise the page is display in portrait mode. |
---|
930 | Color=color, $ ; If set, display the window in "color". This is the default on 24-bit devices. |
---|
931 | Debug=debug, $ ; Set this keyword to turn traceback error handling on in the error handling code. |
---|
932 | WindowColor=windowColor ; A three-element array specifying the background window color (RGB). |
---|
933 | |
---|
934 | Catch, theError |
---|
935 | IF theError NE 0 THEN BEGIN |
---|
936 | Catch, /Cancel |
---|
937 | ok = FSC_PlotWindow_Error_Message(Traceback=Keyword_Set(debug)) |
---|
938 | RETURN, 0 |
---|
939 | ENDIF |
---|
940 | |
---|
941 | IF N_Elements(pagesize) EQ 0 THEN pageSize = 'LETTER' |
---|
942 | IF N_Elements(windowsize) EQ 0 THEN windowsize = [0.2, 0.2, 0.8, 0.8] |
---|
943 | IF N_Elements(event_pro) EQ 0 THEN event_pro = "" |
---|
944 | IF N_Elements(units) EQ 0 THEN units="" |
---|
945 | IF N_Elements(uvalue) EQ 0 THEN uvalue="" |
---|
946 | IF N_Elements(landscape) EQ 0 THEN landscape = 0 |
---|
947 | Device, Get_Visual_Depth=theDepth |
---|
948 | self.pixels_per_inch = 18 |
---|
949 | sizes = self->GetPagePixels(pageSize, Landscape=landscape) |
---|
950 | xsize = sizes[0] |
---|
951 | ysize = sizes[1] |
---|
952 | IF N_Elements(windowColor) EQ 0 THEN $ |
---|
953 | IF theDepth GT 8 THEN windowColor = [60, 140, 140] ELSE windowColor = [80, 80, 80] |
---|
954 | |
---|
955 | IF N_Elements(color) EQ 0 THEN BEGIN |
---|
956 | Device, Get_Visual_Depth=theDepth |
---|
957 | IF theDepth GT 8 THEN color = 1 ELSE color = 0 |
---|
958 | ENDIF ELSE color = Keyword_Set(color) |
---|
959 | |
---|
960 | x1 = windowsize[0] |
---|
961 | x2 = windowsize[2] |
---|
962 | y1 = windowsize[1] |
---|
963 | y2 = windowsize[3] |
---|
964 | |
---|
965 | data = Findgen(101) |
---|
966 | data = Sin(data/5) / Exp(data/20) |
---|
967 | |
---|
968 | self.thePlot = Obj_New('IDLgrPlot', data, Color=[0,0,0]) |
---|
969 | self.thePlot->SetProperty, XCoord_Conv=FSC_PlotWindow_Normalize([0,100], $ |
---|
970 | Position=[x1+0.05, x2-0.05]) > 10e-6, $ |
---|
971 | YCoord_Conv=FSC_PlotWindow_Normalize([-1,1], Position=[y1+0.05, y2-0.05]) > 10e-6 |
---|
972 | |
---|
973 | self.theXAxis = Obj_New('IDLgrAxis', 0, Color=[0,0,0], Ticklen=0.025, $ |
---|
974 | Minor=4, Range=[0,100], Location=[1000, y1+0.05 , 0.0], /NoText) |
---|
975 | self.theXAxis->SetProperty, XCoord_Conv=FSC_PlotWindow_Normalize([0,100], $ |
---|
976 | Position=[x1+0.05, x2-0.05]) > 10e-6 |
---|
977 | |
---|
978 | self.theYAxis = Obj_New('IDLgrAxis', 1, Color=[0,0,0], Ticklen=0.025, $ |
---|
979 | Minor=4, Range=[-1,1], Location=[x1+0.05, 1000, 0.0], /NoText) |
---|
980 | self.theYAxis->SetProperty, YCoord_Conv=FSC_PlotWindow_Normalize([-1,1], $ |
---|
981 | Position=[y1+0.05, y2-0.05]) > 10e-6 |
---|
982 | |
---|
983 | self.plotModel = Obj_New('IDLgrModel') |
---|
984 | |
---|
985 | IF theDepth GT 8 THEN theColor = [210, 200, 180] ELSE theColor = [255,255,255] |
---|
986 | self.theBackground = Obj_New('IDLgrPolygon', Color=theColor, $ |
---|
987 | [x1, x1, x2, x2, x1], [y1, y2, y2, y1, y1]) |
---|
988 | |
---|
989 | self.theModel = Obj_New('IDLgrModel', Select_Target=1) |
---|
990 | self.theModel->Add, self.theBackground |
---|
991 | |
---|
992 | self.plotModel->Add, self.theXAxis |
---|
993 | self.plotModel->Add, self.theYAxis |
---|
994 | self.plotModel->Add, self.thePlot |
---|
995 | self.plotModel->Translate, 0, 0, 0.1 |
---|
996 | |
---|
997 | self.theView = Obj_New('IDLgrView', Color=windowColor, Viewplane_Rect=[0,0,1,1]) |
---|
998 | self.theView->Add, self.theModel |
---|
999 | self.theView->Add, self.plotModel |
---|
1000 | |
---|
1001 | self.base = Widget_Base(parent, UValue=uvalue) |
---|
1002 | self.drawID = Widget_Draw(self.base, Button_Events=1, Expose_Events=1, $ |
---|
1003 | Retain=0, Graphics_Level=2, XSize=xsize, YSize=ysize, $ |
---|
1004 | Event_Pro='FSC_PLOTWINDOW_Events', UValue=self, Renderer=1, $ |
---|
1005 | Kill_Notify='FSC_PLOTWINDOW_Kill_Notify', Motion_Events=1, $ |
---|
1006 | Notify_Realize='FSC_PLOTWINDOW_Notify_Realize') |
---|
1007 | |
---|
1008 | self.pagesize = pagesize |
---|
1009 | self.landscape = Keyword_Set(landscape) |
---|
1010 | self.x1 = x1 |
---|
1011 | self.x2 = x2 |
---|
1012 | self.y1 = y1 |
---|
1013 | self.y2 = y2 |
---|
1014 | self.xsize = Float(xsize) |
---|
1015 | self.ysize = Float(ysize) |
---|
1016 | self.currentX = -1 |
---|
1017 | self.currentY = -1 |
---|
1018 | self.xlength = x2 - x1 |
---|
1019 | self.ylength = y2 - y1 |
---|
1020 | self.units = units |
---|
1021 | self.event_pro = event_pro |
---|
1022 | self.color = color |
---|
1023 | self->SetColor, color |
---|
1024 | RETURN, 1 |
---|
1025 | END ;---------------------------------------------------------------------------------- |
---|
1026 | |
---|
1027 | |
---|
1028 | |
---|
1029 | PRO FSC_PLOTWINDOW__DEFINE |
---|
1030 | |
---|
1031 | struct = { FSC_PLOTWINDOW, $ ; The object class name. |
---|
1032 | action:"", $ ; A flag to indicate whether you are moving or resizing the plot window. |
---|
1033 | base: 0L, $ ; The top-level base of the compound widget. |
---|
1034 | color:0, $ ; A flag to indicate if the window is in "color" or not. |
---|
1035 | currentX:0, $ ; The starting X location for resizing. |
---|
1036 | currentY:0, $ ; The starting Y location for resizing. |
---|
1037 | direction:"", $ ; The direction of resizing movement. |
---|
1038 | event_pro:"", $ ; The name of an event handler to call. |
---|
1039 | drawID:0L, $ ; The draw widget identifier. |
---|
1040 | pageSize:"", $ ; A string to indicate the "type" of page: Letter, A4, etc. |
---|
1041 | pixels_per_inch:0, $ ; The pixel per inch scaling. 18 pixels/inch hardcoded. |
---|
1042 | landscape: 0, $ ; A flag to indicate the window should be in landscape mode. |
---|
1043 | plotModel:Obj_New(), $ ; The model for the plot and axes objects. |
---|
1044 | theBackground:Obj_New(), $ ; The background filled polygon. |
---|
1045 | thePlot:Obj_New(), $ ; The plot object. |
---|
1046 | theModel:Obj_New(), $ ; The model for the background object. |
---|
1047 | theView:Obj_New(), $ ; The object view. |
---|
1048 | theWindow:Obj_New(), $ ; The object window. |
---|
1049 | theXAxis:Obj_New(), $ ; The X axis object. |
---|
1050 | theYAxis:Obj_New(), $ ; The Y axis object. |
---|
1051 | units:"", $ ; A string indicating INCHES or CENTIMETER units. |
---|
1052 | x1:0.0, $ ; The x location of lower-left corner of plot window. (Normalized coordinates.) |
---|
1053 | x2:0.0, $ ; The x location of upper-right corner of plot window. (Normalized coordinates.) |
---|
1054 | xlength:0.0, $ ; The length of the plot window in x. (Normalized coordinates.) |
---|
1055 | xsize:0.0, $ ; The current X size of the draw widget. (Device coordinates.) |
---|
1056 | y1:0.0, $ ; The y location of lower-left corner of plot window. (Normalized coordinates.) |
---|
1057 | y2:0.0, $ ; The yx location of upper-right corner of plot window. (Normalized coordinates.) |
---|
1058 | ylength:0.0, $ ; The length of the plot window in y. (Normalized coordinates.) |
---|
1059 | ysize:0.0 $ ; The current X size of the draw widget. (Device coordinates.) |
---|
1060 | } |
---|
1061 | END ;---------------------------------------------------------------------------------- |
---|
1062 | |
---|
1063 | |
---|
1064 | |
---|
1065 | FUNCTION FSC_PLOTWINDOW, parent, PageSize=pagesize, WindowSize=windowsize, $ |
---|
1066 | Event_Pro=event_pro, Units=units, UValue=uvalue, Landscape=landscape, $ |
---|
1067 | Color=color |
---|
1068 | |
---|
1069 | ; A wrapper function so this object can be treated as a compound |
---|
1070 | ; widget function. |
---|
1071 | |
---|
1072 | IF N_Elements(pagesize) EQ 0 THEN pageSize = 'LETTER' |
---|
1073 | IF N_Elements(windowsize) EQ 0 THEN windowsize = [0.15, 0.15, 0.85, 0.85] |
---|
1074 | IF N_Elements(event_pro) EQ 0 THEN event_pro = "" |
---|
1075 | IF N_Elements(units) EQ 0 THEN units="" |
---|
1076 | color = Keyword_Set(color) |
---|
1077 | landscape = Keyword_Set(landscape) |
---|
1078 | IF N_Elements(parent) EQ 0 THEN BEGIN |
---|
1079 | ok = Dialog_Message('Parent parameter is required. Returning...') |
---|
1080 | RETURN, Obj_New() |
---|
1081 | ENDIF |
---|
1082 | |
---|
1083 | RETURN, Obj_New('FSC_PLOTWINDOW', parent, PageSize=pagesize, WindowSize=windowsize, $ |
---|
1084 | Event_Pro=event_pro, Units=units, UValue=uvalue, Landscape=landscape, Color=color) |
---|
1085 | END ;---------------------------------------------------------------------------------- |
---|