cgpixmapwindow__define.pro
21.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
; docformat = 'rst'
;
; NAME:
; cgPixmapWindow
;
; PURPOSE:
; This is the "object" behind cgPixmap. It is a subclassed cgCmdWindow object
; and behaves almost identically, except that normally the draw widget at the
; heart of the window is invisible. That is, it is a pixmap.
;
;******************************************************************************************;
; ;
; Copyright (c) 2012, by Fanning Software Consulting, Inc. All rights reserved. ;
; ;
; Redistribution and use in source and binary forms, with or without ;
; modification, are permitted provided that the following conditions are met: ;
; ;
; * Redistributions of source code must retain the above copyright ;
; notice, this list of conditions and the following disclaimer. ;
; * Redistributions in binary form must reproduce the above copyright ;
; notice, this list of conditions and the following disclaimer in the ;
; documentation and/or other materials provided with the distribution. ;
; * Neither the name of Fanning Software Consulting, Inc. nor the names of its ;
; contributors may be used to endorse or promote products derived from this ;
; software without specific prior written permission. ;
; ;
; THIS SOFTWARE IS PROVIDED BY FANNING SOFTWARE CONSULTING, INC. ''AS IS'' AND ANY ;
; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES ;
; OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT ;
; SHALL FANNING SOFTWARE CONSULTING, INC. BE LIABLE FOR ANY DIRECT, INDIRECT, ;
; INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED ;
; TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; ;
; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ;
; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ;
; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS ;
; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ;
;******************************************************************************************;
;+
; This is the "object" behind cgPixmap. It is a subclassed cgCmdWindow object
; and behaves almost identically, except that normally the draw widget at the
; heart of the window is invisible. That is, it is a pixmap.
;
; Default properties of the object can be controled with cgWindow_SetDefs and cgControl,
; as with cgWindow. Be sure to delete the pixmap object when you are done with it, by
; using (for example) cgDelete.
;
; :Categories:
; Graphics
;
; :Author:
; FANNING SOFTWARE CONSULTING::
; David W. Fanning
; 1645 Sheely Drive
; Fort Collins, CO 80526 USA
; Phone: 970-221-0438
; E-mail: david@idlcoyote.com
; Coyote's Guide to IDL Programming: http://www.idlcoyote.com
;
; :Copyright:
; Copyright (c) 2012, Fanning Software Consulting, Inc.
;
; :History:
; Change History::
; Created from cgCmdWindow, 7 February 2012. DWF.
; Problem with the ASPECT keyword, which should have been named WASPECT. 7 Oct 2012. DWF.
; Added WDestroyObjects keyword to destroy objects parameters, if needed. 11 November 2012. DWF.
; Confusion trying to change WBackground keyword to Background. Changed it back. Identical to ASPECT
; problem described above. 18 Jan 2013. DWF.
;-
;+
; This method initializes the pixmap object.
;
; :Params:
; parent: in, optional
; The parent base widget for this draw widget object. If not defined,
; the program will create its own top-level base widget.
;
; :Keywords:
; altps_Keywords: in, optional, type=string
; A structure containing alternative keyword names (as tags) and values for
; those keywords to be used when the current device is the PostScript device.
; See http://www.idlcoyote.com/cg_tips/kwexpressions.php and the examples
; below for details on how to use this keyword.
; altps_Params: in, optional, type=IntArr(3)
; A structure containing alternative parameter values to be used when
; the current device is the PostScript device. Structure names are restricted
; to the names "P1", "P2", "P3" and "P4"to correspond to the equivalent positional
; parameter. See http://www.idlcoyote.com/cg_tips/kwexpressions.php and the
; examples below for details on how to use this keyword.
; command: in, required, type=string
; The graphics procedure command to be executed. This parameter
; must be a string and the the command must be a procedure. Examples
; are 'Surface', 'Contour', 'Plot', 'cgPlot', cgContour, etc.
; eraseit: in, optional, type=boolean, default=0
; Set this keyword to cause the window to be erased before graphics commands
; are drawn. This may need to be set, for example, to display images.
; group_leader: in, optional
; The identifier of a widget to serve as a group leader for this program.
; If the group leader is destroyed, this program is also destroyed. Used
; when calling this program from another widget program.
; method: in, optional, type=boolean, default=0
; Set this keyword if the command is an object method call rather than a
; procedure call. If this keyword is set, the first positional parameter, p1,
; must be present and must be a valid object reference.
; multi: in, optional, type=intarr(5)
; Set this keyword in exactly the same way you would set the !P.Multi keyword.
; It will allow you to display multi-plots in the cgWindow graphics window.
; oxmargin: in, optional, type=float
; A two-element array indicating the left and right X outside margins for the
; graphical display. Used only when doing multiple plots with `WMulti`.
; oymargin: in, optional, type=float
; A two-element array indicating the bottom and top Y outside margins for the
; graphical display. Used only when doing multiple plots with `WMulti`.
; p1: in, optional, type=any
; The first positional parameter appropriate for the graphics command.
; p2: in, optional, type=any
; The second positional parameter appropriate for the graphics command.
; p3: in, optional, type=any
; The third positional parameter appropriate for the graphics command.
; p4: in, optional, type=any
; The fourth positional parameter appropriate for the graphics command.
; replacecmd: in, optional, type=boolean, default=0
; Set this keyword to replace a graphics command from an cgWindow.
; If CmdIndex is undefined, *all* commands in the window are replaced. Use
; WinID to identify the cgWindow you are interested in. If WinID is
; undefined, the last cgWindow created is used for the replacement.
; storage: in, optional, type=any
; Any user-defined IDL variable will be stored in the object storage location.
; Defined here for convenience. Same as `Storage` keyword for the SetProperty method.
; waspect: in, optional, type=float, default=normal
; Set this keyword to the aspect ratio you would like the window to have.
; The aspect ratio is calculated as (ysize/xsize). Must be a float value.
; If this keyword is set, the window will maintain this aspect ratio,
; even when it is resized.
; wbackground: in, optional, type=varies, default=!P.Background
; The background color of the window. Specifying a background color
; automatically sets the WErase keyword.
; wdestroyobjects: in, optional, type=boolean, default=0
; If this keyword is set, and any of the input parameters p1-p4 is an object,
; the object parameter will be destroyed when the window is destroyed.
; wxsize: in, optional, type=integer, default=640
; The x size in device coordinates of the graphics window.
; wysize: in, optional, type=integer, default=512
; The y size in device coordinates of the the graphics window.
; _extra: in, optional
; The "extra" keywords for the command that is being added to the window.
;-
FUNCTION cgPixmapWindow::INIT, parent, $
AltPS_Keywords=altps_Keywords, $ ; A structure of PostScript alternative keywords and values.
AltPS_Params=altps_Params, $ ; A structure of PostScript alternative parameters and values.
Command=command, $ ; The graphics "command" to execute.
EraseIt = eraseit, $ ; Set this keyword to erase the display before executing the command.
Group_Leader = group_leader, $ ; The group leader of the cgWindow program.
Method=method, $ ; If set, will use CALL_METHOD instead of CALL_PROCEDURE to execute command.
Multi = multi, $ ; Set this in the same way !P.Multi is used.
OXMargin = oxmargin, $ ; Set the !X.OMargin. A two element array.
OYMargin = oymargin, $ ; Set the !Y.OMargin. A two element array
P1=p1, $ ; The first postitional parameter in a graphics command loaded for display.
P2=p2, $ ; The sedond postitional parameter in a graphics command loaded for display.
P3=p3, $ ; The third postitional parameter in a graphics command loaded for display.
P4=p4, $ ; The fourth postitional parameter in a graphics command loaded for display.
ReplaceCmd=replacecmd, $ ; Replace the current command and execute in the current window.
Storage=storage, $ ; A storage pointer location. Used like a user value in a widget.
Visible=visible, $ ; Set this keyword to make the pixmap visible.
WAspect = waspect, $ ; Set the window aspect ratio to this value.
WBackground = wbackground, $ ; The background color. Set to !P.Background by default.
WDestroyObjects=wdestroyobjects, $ ; Set this keyword to destroy object parameters upon exit.
WXSize = xsize, $ ; The X size of the cgWindow graphics window in pixels. By default: 400.
WYSize = ysize, $ ; The Y size of the cgWindow graphics window in pixels. By default: 400.
_Extra = extra ; Any extra keywords. Usually the "command" keywords.
Compile_Opt idl2
Catch, theError
IF theError NE 0 THEN BEGIN
Catch, /CANCEL
void = cgErrorMsg()
RETURN, 0
ENDIF
; Check keywords.
method = Keyword_Set(method)
visible = Keyword_Set(visible)
currentWindow = !D.Window
; Create the widgets for the program.
IF N_Elements(parent) NE 0 THEN BEGIN
self.tlb = parent
Widget_Control, self.tlb, Map=0
ENDIF ELSE BEGIN
self.tlb = Widget_Base(Map=0, /TLB_SIZE_EVENTS, UNAME='TLB_RESIZE')
ENDELSE
; Get the global defaults.
cgWindow_GetDefs, $
AdjustSize = d_adjustsize, $ ; Adjust charsize to window size.
Aspect = d_aspect, $ ; The aspect ratio of the window.
Background = d_background, $ ; The background color.
Delay = d_delay, $ ; The amount of delay between command execution.
EraseIt = d_eraseit, $ ; Set this keyword to erase the display before executing the commands.
Multi = d_multi, $ ; Set this in the same way !P.Multi is used.
XOMargin = d_xomargin, $ ; Set the !X.OMargin. A two element array.
YOMargin = d_yomargin, $ ; Set the !Y.OMargin. A two element array
XSize = d_xsize, $ ; The X size of the cgWindow graphics window.
YSize = d_ysize, $ ; The Y size of the cgWindow graphics window.
Title = d_title, $ ; The window title.
XPos = d_xpos, $ ; The X offset of the window on the display.
YPos = d_ypos, $ ; The Y offset of the window on the display.
Palette = d_palette, $ ; The color table palette to use for the window.
; PDF properties.
PDF_Unix_Convert_Cmd = d_pdf_unix_convert_cmd, $ ; Command to convert PS to PDF.
PDF_Path = d_pdf_path, $ ; The path to the Ghostscript conversion command.
; ImageMagick Properties.
IM_Transparent = d_im_transparent, $ ; Sets the "alpha" keyword on ImageMagick convert command.
IM_Density = d_im_density, $ ; Sets the density parameter on ImageMagick convert command.
IM_Raster = d_im_raster, $ ; Create raster files via ImageMagick.
IM_Resize = d_im_resize, $ ; Sets the resize parameter on ImageMagick convert command.
IM_Options = d_im_options, $ ; Sets extra ImageMagick options on the ImageMagick convert command.
IM_Width = d_im_width, $ ; Set the width of ImageMagick output.
; PostScript properties.
PS_Decomposed = d_ps_decomposed, $ ; Sets the PostScript color mode.
PS_Delete = d_ps_delete, $ ; Delete PS file when making IM raster.
PS_Metric = d_ps_metric, $ ; Select metric measurements in PostScript output.
PS_Encapsulated = d_ps_encapsulated, $ ; Create Encapsulated PostScript output.
PS_FONT = d_ps_font, $ ; Select the font for PostScript output.
PS_CHARSIZE = d_ps_charsize, $ ; Select the character size for PostScript output.
PS_QUIET = d_ps_quiet, $ ; Select the QUIET keyword for cgPS_Open.
PS_SCALE_FACTOR = d_ps_scale_factor, $ ; Select the scale factor for PostScript output.
PS_TT_FONT = d_ps_tt_font ; Select the true-type font to use for PostScript output.
; If method is set, the first positional parameter must be present,
; and it must be a valid object reference.
IF method THEN BEGIN
IF N_Elements(p1) EQ 0 THEN $
Message, 'The parameter P1 must be present to make a method call.'
IF ~Obj_Valid(p1) THEN $
Message, 'The parameter P1 must be a valid object reference when making method calls.'
ENDIF
SetDefaultValue, xsize, d_xsize
SetDefaultValue, ysize, d_ysize
SetDefaultValue, xpos, d_xpos
SetDefaultValue, ypos, d_ypos
SetDefaultValue, button_events, 0, /Boolean
SetDefaultValue, drop_events, 0, /Boolean
SetDefaultValue, keyboard_events, 0, /Boolean
SetDefaultValue, motion_events, 0, /Boolean
SetDefaultValue, tracking_events, 0, /Boolean
SetDefaultValue, waspect, d_aspect
SetDefaultValue, wheel_events, 0, /Boolean
IF N_Elements(storage) NE 0 THEN self.storage = Ptr_New(storage)
IF N_Elements(wbackground) EQ 0 THEN BEGIN
wbackground = d_background
IF N_Elements(command) EQ 0 THEN eraseit = 1
IF (N_Elements(command) NE 0) && cgCoyoteGraphic(command) THEN eraseit = 1
ENDIF ELSE BEGIN
eraseit = 1
ENDELSE
IF N_Elements(eraseIt) EQ 0 THEN eraseIt = d_eraseit ELSE eraseIt = Keyword_Set(eraseIt)
; The commands will be placed in a linked list for execution.
self.cmds = Obj_New('LinkedList')
IF Obj_Valid(self.cmds) EQ 0 THEN Message, 'Failed to make the LinkedList for the commands.'
; Add a command, if you have one. Otherwise, just make the window.
IF (N_Elements(command) NE 0) THEN BEGIN
thisCommand = Obj_New('cgWindow_Command', COMMAND=command, $
P1=p1, P2=p2, P3=p3, P4=p4, KEYWORDS=extra, TYPE=method, $
ALTPS_KEYWORDS=altps_Keywords, ALTPS_PARAMS=altps_Params, $
DESTROYOBJECTS=Keyword_Set(wdestroyobjects))
IF Obj_Valid(thisCommand) THEN self.cmds -> Add, thisCommand ELSE Message, 'Failed to make command object.'
ENDIF
; If there is a palette, use it. Otherwise, use the current color table vectors.
IF Total(d_palette) NE 0 THEN BEGIN
IF Size(d_palette, /N_DIMENSIONS) NE 2 THEN Message, 'Color palette is not a 3xN array.'
dims = Size(d_palette, /DIMENSIONS)
threeIndex = Where(dims EQ 3)
IF ((threeIndex)[0] LT 0) THEN Message, 'Color palette is not a 3xN array.'
IF threeIndex[0] EQ 0 THEN d_palette = Transpose(d_palette)
self.r = Ptr_New(d_palette[*,0])
self.g = Ptr_New(d_palette[*,1])
self.b = Ptr_New(d_palette[*,2])
ENDIF ELSE BEGIN
TVLCT, rr, gg, bb, /Get
self.r = Ptr_New(rr)
self.g = Ptr_New(gg)
self.b = Ptr_New(bb)
ENDELSE
; Check to see if you have to create a window with a particular aspect ratio.
; If so, your xsize and ysize values will need to be adjusted.
IF waspect NE 0 THEN BEGIN
IF waspect GE 1 THEN BEGIN
xsize = Round(ysize / waspect)
ENDIF ELSE BEGIN
ysize = Round(xsize * waspect)
ENDELSE
ENDIF
; Create draw widget. UNIX versions of IDL have a bug in which creating
; a draw widget as the very first window in an IDL session causes both
; !P.Background and !P.Color to be set to white. I know, it's odd. But
; doing this little trick fixes the problem.
tempBackground = !P.Background
tempColor = !P.Color
retain = (StrUpCase(!Version.OS_Family) EQ 'UNIX') ? 2 : 1
notify_realize = 'cgCmdWindowDrawRealize'
kill_notify = 'cgCmdWindowKillNotify'
self.drawID = Widget_Draw(self.tlb, XSIZE=xsize, YSize=ysize, RETAIN=retain, $
UVALUE=self, UNAME='DRAW_WIDGET', Kill_Notify=kill_notify, NOTIFY_REALIZE=notify_realize)
!P.Background = Temporary(tempBackground)
!P.Color = Temporary(tempColor)
; Load object properties.
self.background = Ptr_New(wbackground)
IF N_Elements(cmdDelay) NE 0 THEN self.delay = cmdDelay ELSE self.delay = d_delay
self.eraseIt = eraseIt
IF N_Elements(multi) NE 0 THEN BEGIN
FOR j=0,N_Elements(multi)-1 DO self.pmulti[j] = multi[j]
ENDIF ELSE self.pmulti = d_multi
IF N_Elements(wxomargin) NE 0 THEN self.xomargin = xomargin ELSE self.xomargin = d_xomargin
IF N_Elements(wyomargin) NE 0 THEN self.yomargin = yomargin ELSE self.yomargin = d_yomargin
self.adjustsize = d_adjustsize
self.destroyObjects = Keyword_Set(wdestroyobjects)
self.im_transparent = d_im_transparent
self.im_density = d_im_density
self.im_options = d_im_options
self.im_raster = d_im_raster
self.im_resize = d_im_resize
self.im_width = d_im_width
self.msysvar = Ptr_New(/Allocate_Heap)
self.pdf_unix_convert_cmd = d_pdf_unix_convert_cmd
self.pdf_path = d_pdf_path
self.ps_decomposed = d_ps_decomposed
self.ps_delete = d_ps_delete
self.ps_encapsulated = d_ps_encapsulated
self.ps_metric = d_ps_metric
self.ps_charsize = d_ps_charsize
self.ps_font = d_ps_font
self.ps_quiet = d_ps_quiet
self.ps_scale_factor = d_ps_scale_factor
self.ps_tt_font = d_ps_tt_font
self.visible = visible
self.waspect = waspect
; Restore the current graphics window, if you can.
IF (currentWindow GE 0) && WindowAvailable(currentWindow) THEN BEGIN
WSet, currentWindow
ENDIF ELSE WSet, -1
; Make the pixmap visible, if needed.
IF visible THEN Widget_Control, self.tlb, MAP=1
Widget_Control, self.tlb, /Realize, Set_UValue=self
XManager, 'cgwindow', self.tlb, /No_Block, $
Event_Handler='cgCmdWindow_Dispatch_Events', $
Cleanup = 'cgCmdWindow_Cleanup', $
Group_Leader=group_leader
RETURN, 1
END
;+
; This method allows you to set the properties of the object. Most properties are
; passed along to the superclass method.
;
; :Keywords:
; visible: in, optional, type=boolean
; Set this keyword to make the pixmap visible.
; _extra: in, optional
; Any keywords appropriate for the SetProperty method of the superclass object.
;-
PRO cgPixmapWindow::SetProperty, VISIBLE=visible, _EXTRA=extra
Compile_Opt idl2
; Error handling.
Catch, theError
IF theError NE 0 THEN BEGIN
Catch, /CANCEL
void = cgErrorMsg()
RETURN
ENDIF
IF N_Elements(visible) NE 0 THEN Widget_Control, self.tlb, MAP=Keyword_Set(visible)
IF N_Elements(extra) NE 0 THEN self -> cgCmdWindow::SetProperty, _STRICT_EXTRA=extra
END
;+
; The definition module for the cgPixmapWindow object
;
; :Params:
; class: out, optional, type=struct
; The object class structure definition. Occasionally useful.
;-
PRO cgPixmapWindow__Define, class
class = {cgPixmapWindow, $
INHERITS cgCmdWindow, $
visible: 0L } ; Set this to make the pixmap visible.
END