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 >
Text File  |  2000-07-29  |  5KB  |  170 lines

  1. ############################################################################
  2. #
  3. #    File:     drag.icn
  4. #
  5. #    Subject:  Procedures for dragging rectangles
  6. #
  7. #    Author:   Gregg M. Townsend
  8. #
  9. #    Date:     August 21, 1998
  10. #
  11. ############################################################################
  12. #
  13. #   This file is in the public domain.
  14. #
  15. ############################################################################
  16. #
  17. #    These procedures drag rectangular objects in a window.
  18. #
  19. #    Drag(x, y, w, h)        provides an opaque move.
  20. #
  21. #    DragOutline(x, y, w, h)        drags only the outline.
  22. #
  23. ############################################################################
  24. #
  25. #  Drag(x, y, w, h) lets the user move a rectangular area using the
  26. #  mouse.  Called when a mouse button is pressed, Drag() handles all
  27. #  subsequent events until a mouse button is released.  As the mouse
  28. #  moves, the rectangular area originally at (x,y,w,h) follows it
  29. #  across the screen; vacated pixels at the original location are
  30. #  filled with the background color.  The rectangle cannot be dragged
  31. #  off-screen or outside the clipping region.  When the mouse button
  32. #  is released, Drag() sets &x and &y to the upper-left corner of the
  33. #  new location and returns.
  34. #
  35. #  DragOutline(x, y, w, h) lets the user move a reverse-mode rectangle
  36. #  using the mouse.  Called when a mouse button is pressed, DragOutline
  37. #  draws a reverse-mode rectangle inside the limits of the rectangle
  38. #  (x,y,w,h) and handles all subsequent events until a mouse button is
  39. #  released.  As the mouse moves, the rectangle follows it.  When the
  40. #  mouse button is released, the rectangle disappears, and DragOutline
  41. #  sets &x and &y to the upper-left corner of the new location.  It is
  42. #  up to the calling program to update the display as necessary.
  43. #
  44. ############################################################################
  45. #
  46. #  Requires: Version 9 graphics
  47. #
  48. ############################################################################
  49.  
  50. link graphics
  51.  
  52.  
  53. #  Drag(x, y, w, h) -- opaque drag
  54.  
  55. procedure Drag(win, x, y, w, h)            #: opaque rectangle drag
  56.    local dx, dy, x0, y0, x1, y1
  57.    local behind, xoff, yoff, xnew, ynew, xshift, yshift
  58.  
  59.    if type(win) ~== "window" then
  60.       return Drag((\&window | runerr(140)), win, x, y, w)
  61.  
  62.    if w < 0 then
  63.       x -:= (w := -w)
  64.    if h < 0 then
  65.       y -:= (h := -h)
  66.  
  67.    dx := WAttrib(win, "dx")
  68.    dy := WAttrib(win, "dy")
  69.  
  70.    x0 := -dx                # set limits due to window size
  71.    y0 := -dy
  72.    x1 := WAttrib(win, "width") - dx - w
  73.    y1 := WAttrib(win, "height") - dy - h
  74.  
  75.    x0 <:= \WAttrib(win, "clipx")    # adjust limits for clipping
  76.    y0 <:= \WAttrib(win, "clipy")
  77.    x1 >:= \WAttrib(win, "clipx") + \WAttrib(win, "clipw") - w
  78.    y1 >:= \WAttrib(win, "clipy") + \WAttrib(win, "cliph") - h
  79.  
  80.    behind := ScratchCanvas(win, , , "__Drag__") |
  81.       stop("can't get ScratchCanvas in Drag()")
  82.    CopyArea(win, behind, -dx, -dy)
  83.    Bg(behind, Bg(win))
  84.    EraseArea(behind, x + dx, y + dy, w, h)
  85.  
  86.    xoff := x - &x
  87.    yoff := y - &y
  88.  
  89.    until Event(win) === (&lrelease | &mrelease | &rrelease) do {
  90.  
  91.       # move the rectangle
  92.       xnew := &x + xoff
  93.       ynew := &y + yoff
  94.       xnew <:= x0
  95.       ynew <:= y0
  96.       xnew >:= x1
  97.       ynew >:= y1
  98.       CopyArea(win, x, y, w, h, xnew, ynew)
  99.  
  100.       # repaint the area exposed by its movement
  101.       xshift := xnew - x
  102.       yshift := ynew - y
  103.  
  104.       if abs(xshift) >= w | abs(yshift) >= h then {
  105.  
  106.          # completely disjoint from new location
  107.          CopyArea(behind, win, x + dx, y + dy, w, h, x, y)
  108.          }
  109.  
  110.       else {
  111.  
  112.          # new area overlaps old
  113.          if xshift > 0 then
  114.             CopyArea(behind, win, x + dx, y + dy, xshift, h, x, y)
  115.          else if xshift < 0 then
  116.             CopyArea(behind, win,
  117.                x + dx + w + xshift, y + dy, -xshift, h, x + w + xshift, y)
  118.          if yshift > 0 then
  119.             CopyArea(behind, win, x + dx, y + dy, w, yshift, x, y)
  120.          else if yshift < 0 then
  121.             CopyArea(behind, win,
  122.                x + dx, y + dy + h + yshift, w, -yshift, x, y + h + yshift)
  123.          }
  124.  
  125.       x := xnew
  126.       y := ynew
  127.       }
  128.  
  129.    EraseArea(behind)
  130.    &x := x            
  131.    &y := y
  132.    return win
  133. end
  134.  
  135.  
  136. #  DragOutline(x, y, w, h) -- outlined drag
  137.  
  138. procedure DragOutline(win, x, y, w, h)        #: outlined rectangle drag
  139.    local wrev, xoff, yoff
  140.  
  141.    if type(win) ~== "window" then
  142.       return DragOutline((\&window | runerr(140)), win, x, y, w)
  143.  
  144.    if w < 0 then
  145.       x -:= (w := -w)
  146.    if h < 0 then
  147.       y -:= (h := -h)
  148.  
  149.    wrev := Clone(win, "drawop=reverse")
  150.    xoff := x - &x
  151.    yoff := y - &y
  152.  
  153.    w -:= 1                    # adjust Draw/Fill inconsistency
  154.    h -:= 1
  155.  
  156.    DrawRectangle(wrev, x, y, w, h)        # draw initial rectangle
  157.    until Event(wrev) === (&lrelease | &mrelease | &rrelease) do {
  158.       DrawRectangle(wrev, x, y, w, h)        # erase old rectangle
  159.       x := &x + xoff
  160.       y := &y + yoff
  161.       DrawRectangle(wrev, x, y, w, h)        # draw new rectangle
  162.       }
  163.    DrawRectangle(wrev, x, y, w, h)        # erase final rectangle
  164.    Uncouple(wrev)
  165.  
  166.    &x := x            
  167.    &y := y
  168.    return win
  169. end
  170.