home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.cs.arizona.edu
/
ftp.cs.arizona.edu.tar
/
ftp.cs.arizona.edu
/
icon
/
historic
/
v941.tgz
/
icon.v941src.tar
/
icon.v941src
/
ipl
/
gprocs
/
drag.icn
< prev
next >
Wrap
Text File
|
2000-07-29
|
5KB
|
170 lines
############################################################################
#
# File: drag.icn
#
# Subject: Procedures for dragging rectangles
#
# Author: Gregg M. Townsend
#
# Date: August 21, 1998
#
############################################################################
#
# This file is in the public domain.
#
############################################################################
#
# These procedures drag rectangular objects in a window.
#
# Drag(x, y, w, h) provides an opaque move.
#
# DragOutline(x, y, w, h) drags only the outline.
#
############################################################################
#
# Drag(x, y, w, h) lets the user move a rectangular area using the
# mouse. Called when a mouse button is pressed, Drag() handles all
# subsequent events until a mouse button is released. As the mouse
# moves, the rectangular area originally at (x,y,w,h) follows it
# across the screen; vacated pixels at the original location are
# filled with the background color. The rectangle cannot be dragged
# off-screen or outside the clipping region. When the mouse button
# is released, Drag() sets &x and &y to the upper-left corner of the
# new location and returns.
#
# DragOutline(x, y, w, h) lets the user move a reverse-mode rectangle
# using the mouse. Called when a mouse button is pressed, DragOutline
# draws a reverse-mode rectangle inside the limits of the rectangle
# (x,y,w,h) and handles all subsequent events until a mouse button is
# released. As the mouse moves, the rectangle follows it. When the
# mouse button is released, the rectangle disappears, and DragOutline
# sets &x and &y to the upper-left corner of the new location. It is
# up to the calling program to update the display as necessary.
#
############################################################################
#
# Requires: Version 9 graphics
#
############################################################################
link graphics
# Drag(x, y, w, h) -- opaque drag
procedure Drag(win, x, y, w, h) #: opaque rectangle drag
local dx, dy, x0, y0, x1, y1
local behind, xoff, yoff, xnew, ynew, xshift, yshift
if type(win) ~== "window" then
return Drag((\&window | runerr(140)), win, x, y, w)
if w < 0 then
x -:= (w := -w)
if h < 0 then
y -:= (h := -h)
dx := WAttrib(win, "dx")
dy := WAttrib(win, "dy")
x0 := -dx # set limits due to window size
y0 := -dy
x1 := WAttrib(win, "width") - dx - w
y1 := WAttrib(win, "height") - dy - h
x0 <:= \WAttrib(win, "clipx") # adjust limits for clipping
y0 <:= \WAttrib(win, "clipy")
x1 >:= \WAttrib(win, "clipx") + \WAttrib(win, "clipw") - w
y1 >:= \WAttrib(win, "clipy") + \WAttrib(win, "cliph") - h
behind := ScratchCanvas(win, , , "__Drag__") |
stop("can't get ScratchCanvas in Drag()")
CopyArea(win, behind, -dx, -dy)
Bg(behind, Bg(win))
EraseArea(behind, x + dx, y + dy, w, h)
xoff := x - &x
yoff := y - &y
until Event(win) === (&lrelease | &mrelease | &rrelease) do {
# move the rectangle
xnew := &x + xoff
ynew := &y + yoff
xnew <:= x0
ynew <:= y0
xnew >:= x1
ynew >:= y1
CopyArea(win, x, y, w, h, xnew, ynew)
# repaint the area exposed by its movement
xshift := xnew - x
yshift := ynew - y
if abs(xshift) >= w | abs(yshift) >= h then {
# completely disjoint from new location
CopyArea(behind, win, x + dx, y + dy, w, h, x, y)
}
else {
# new area overlaps old
if xshift > 0 then
CopyArea(behind, win, x + dx, y + dy, xshift, h, x, y)
else if xshift < 0 then
CopyArea(behind, win,
x + dx + w + xshift, y + dy, -xshift, h, x + w + xshift, y)
if yshift > 0 then
CopyArea(behind, win, x + dx, y + dy, w, yshift, x, y)
else if yshift < 0 then
CopyArea(behind, win,
x + dx, y + dy + h + yshift, w, -yshift, x, y + h + yshift)
}
x := xnew
y := ynew
}
EraseArea(behind)
&x := x
&y := y
return win
end
# DragOutline(x, y, w, h) -- outlined drag
procedure DragOutline(win, x, y, w, h) #: outlined rectangle drag
local wrev, xoff, yoff
if type(win) ~== "window" then
return DragOutline((\&window | runerr(140)), win, x, y, w)
if w < 0 then
x -:= (w := -w)
if h < 0 then
y -:= (h := -h)
wrev := Clone(win, "drawop=reverse")
xoff := x - &x
yoff := y - &y
w -:= 1 # adjust Draw/Fill inconsistency
h -:= 1
DrawRectangle(wrev, x, y, w, h) # draw initial rectangle
until Event(wrev) === (&lrelease | &mrelease | &rrelease) do {
DrawRectangle(wrev, x, y, w, h) # erase old rectangle
x := &x + xoff
y := &y + yoff
DrawRectangle(wrev, x, y, w, h) # draw new rectangle
}
DrawRectangle(wrev, x, y, w, h) # erase final rectangle
Uncouple(wrev)
&x := x
&y := y
return win
end