-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmy_box_cursor.pro
185 lines (170 loc) · 4.66 KB
/
my_box_cursor.pro
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
; $Id: my_box_cursor.pro,v 1.1 2004/03/03 18:12:11 cha Exp $
pro my_box_cursor, x0, y0, nx, ny, INIT = init, FIXED_SIZE = fixed_size, $
MESSAGE = message
;+
; NAME:
; BOX_CURSOR
;
; PURPOSE:
; Emulate the operation of a variable-sized box cursor (also known as
; a "marquee" selector).
;
; CATEGORY:
; Interactive graphics.
;
; CALLING SEQUENCE:
; BOX_CURSOR, x0, y0, nx, ny [, INIT = init] [, FIXED_SIZE = fixed_size]
;
; INPUTS:
; No required input parameters.
;
; OPTIONAL INPUT PARAMETERS:
; x0, y0, nx, and ny give the initial location (x0, y0) and
; size (nx, ny) of the box if the keyword INIT is set. Otherwise, the
; box is initially drawn in the center of the screen.
;
; KEYWORD PARAMETERS:
; INIT: If this keyword is set, x0, y0, nx, and ny contain the initial
; parameters for the box.
;
; FIXED_SIZE: If this keyword is set, nx and ny contain the initial
; size of the box. This size may not be changed by the user.
;
; MESSAGE: If this keyword is set, print a short message describing
; operation of the cursor.
;
; OUTPUTS:
; x0: X value of lower left corner of box.
; y0: Y value of lower left corner of box.
; nx: width of box in pixels.
; ny: height of box in pixels.
;
; The box is also constrained to lie entirely within the window.
;
; COMMON BLOCKS:
; None.
;
; SIDE EFFECTS:
; A box is drawn in the currently active window. It is erased
; on exit.
;
; RESTRICTIONS:
; Works only with window system drivers.
;
; PROCEDURE:
; The graphics function is set to 6 for eXclusive OR. This
; allows the box to be drawn and erased without disturbing the
; contents of the window.
;
; Operation is as follows:
; Left mouse button: Move the box by dragging.
; Middle mouse button: Resize the box by dragging. The corner
; nearest the initial mouse position is moved.
; Right mouse button: Exit this procedure, returning the
; current box parameters.
;
; MODIFICATION HISTORY:
; DMS, April, 1990.
; DMS, April, 1992. Made dragging more intutitive.
; June, 1993 - Bill Thompson
; prevented the box from having a negative size.
; 04-18-96 bkc Made the box color more visible.
; 05-28-98 bkc Reset bounding box color
;-
device, get_graphics = old, set_graphics = 6 ;Set xor
col = !d.table_size - 2
if keyword_set(message) then begin
st = [$,
"Drag Left button to move box.",$
"Drag Middle button near a corner to resize box.",$
"Right button when done."]
res=WIDGET_MESSAGE(st)
endif
if keyword_set(init) eq 0 then begin ;Supply default values for box:
if keyword_set(fixed_size) eq 0 then begin
nx = !d.x_size/8 ;no fixed size.
ny = !d.x_size/8
endif
x0 = !d.x_size/2 - nx/2
y0 = !d.y_size/2 - ny/2
endif
if nx lt 0 then begin
x0 = x0 + nx
nx = -nx
endif
if ny lt 0 then begin
y0 = y0 + ny
ny = -ny
endif
x0 = x0 > 0
y0 = y0 > 0
x0 = x0 < (!d.x_size-1 - nx) ;Never outside window
y0 = y0 < (!d.y_size-1 - ny)
px = [x0, x0 + nx, x0 + nx, x0, x0] ;X points
py = [y0, y0, y0 + ny, y0 + ny, y0] ;Y values
plots,px, py, col=col, /dev, thick=3, lines=0 ;Draw the box
cursor, x, y, 2, /dev ;Wait for a button
button = 0
while 1 do begin
old_button = button
cursor, x, y, 2, /dev ;Wait for a button
button = !err
if (old_button eq 0) and (button ne 0) then begin
mx0 = x ;For dragging, mouse locn...
my0 = y
x00 = x0 ;Orig start of ll corner
y00 = y0
endif
if !err eq 1 then begin ;Drag entire box?
x0 = x00 + x - mx0
y0 = y00 + y - my0
endif
if (!err eq 2) and (keyword_set(fixed_size) eq 0) then begin ;New size?
if old_button eq 0 then begin ;Find closest corner
mind = 1e6
for i=0,3 do begin
d = float(px(i)-x)^2 + float(py(i)-y)^2
if d lt mind then begin
mind = d
corner = i
endif
endfor
nx0 = nx ;Save sizes.
ny0 = ny
endif
dx = x - mx0 & dy = y - my0 ;Distance dragged...
case corner of
0: begin x0 = x00 + dx & y0 = y00 + dy
nx = nx0 -dx & ny = ny0 - dy & endcase
1: begin y0 = y00 + dy
nx = nx0 + dx & ny = ny0 - dy & endcase
2: begin nx = nx0 + dx & ny = ny0 + dy & endcase
3: begin x0 = x00 + dx
nx = nx0 - dx & ny = ny0 + dy & endcase
endcase
endif
plots, px, py, col=col, /dev, thick=3, lines=0 ;Erase previous box
empty ;Decwindow bug
if !err eq 4 then begin ;Quitting?
device,set_graphics = old
return
endif
middle:
if nx lt 0 then begin
x0 = x0 + nx
nx = -nx
endif
if ny lt 0 then begin
y0 = y0 + ny
ny = -ny
endif
x0 = x0 > 0
y0 = y0 > 0
x0 = x0 < (!d.x_size-1 - nx) ;Never outside window
y0 = y0 < (!d.y_size-1 - ny)
px = [x0, x0 + nx, x0 + nx, x0, x0] ;X points
py = [y0, y0, y0 + ny, y0 + ny, y0] ;Y values
plots,px, py, col=col, /dev, thick=3, lines=0 ;Draw the box
wait, .1 ;Dont hog it all
endwhile
end