Lisp HUG Maillist Archive

Trying to draw a "selection rectangle"

Hi

I have a pinboard layout where I draw some objects.

Now I want to select them using a standard "let's draw a dashed 
rectangle around them" technique.
The core of my code is the following.

MY-PINBOARD-LAYOUT is a class that keeps track of SELECTION-AREA-START 
and SELECTION-AREA-END (which are two "points" - nothing special about 
them) via the button press and button release input methods.

The problem is that the drawing and the redrawing is not working 
properly (at least on LWM).  It seems that the calls to CLEAR-RECTANGLE 
and DRAW-RECTANGLE are not handled in the appropriate order.  Note that 
I also tried to interleave calls to FORCE-SCREEN-UPDATE and/or using 
WIT-ATOMIC-REDISPLAY.  Nothing seems to work.

Can anybody see if I am missing something totally obvious?

Thanks for the help

Marco





(defmethod draw-selecting-highlight ((gp my-pinboard-layout) x y)
   (let ((selection-area-start (selection-area-start gp))
         (selection-area-end (selection-area-end gp))
         )
     (when selection-area-start
       ;; The following is somewhat wasteful.  I could cache the
       ;; rectangles I draw. I think the code is easier to read and
       ;; maintain this way.
       (let* ((s-x (point-x selection-area-start))
              (s-y (point-y selection-area-start))
              (e-x (if selection-area-end (point-x selection-area-end) 
x))
              (e-y (if selection-area-end (point-y selection-area-end) 
y))
              (old-start-x (min s-x e-x))
              (old-start-y (min s-y e-y))
              (old-width (abs (- e-x s-x)))
              (old-height (abs (- e-y s-y)))
              (start-x (min s-x x))
              (start-y (min s-y y))
              (width (abs (- x s-x)))
              (height (abs (- y s-y)))
              )

         (gp:clear-rectangle gp old-start-x old-start-y (1+ old-width) 
(1+ old-height))
         (capi:redraw-pinboard-layout gp old-start-x old-start-y (1+ 
old-width) (1+ old-height))
         (gp:draw-rectangle gp start-x start-y width height
                            :dashed t)
         ))
     ))

--
Marco Antoniotti
NYU Courant Bioinformatics Group		tel. +1 - 212 - 998 3488
715 Broadway 10th FL				fax. +1 - 212 - 998 3484
New York, NY, 10003, U.S.A.


________________________________________________________________________
This email has been scanned for all viruses by the MessageLabs Email
Security System. For more information on a proactive email security
service working around the clock, around the globe, visit
http://www.messagelabs.com
________________________________________________________________________

Re: Trying to draw a "selection rectangle"

On Tuesday 19 August 2003 08:00 pm, Marco Antoniotti wrote:
> Can anybody see if I am missing something totally obvious?

This is probably a tangential answer since it doesn't directly address your 
problem...

Selection rectangles should, in general, be drawn and undrawn using XOR 
operations.

For example, if an edge of your selection rectangle intersects with some 
graphic object, then clearing the rectangle will leave potholes in the object 
where the rectangle has been cleared to the background colour.  This is 
probably why your code snippet contains a redraw of a chunk of the pinboard 
layout.   This approach is likely to be dog slow when you start selecting 
larger areas.

The "standard" way of remembering what was underneath the selection is to XOR 
the selection rectangle in, then XOR it back out again.  Draw the rectangle 
with XOR.  To remove it, draw it again with XOR (in the same location, with 
the same colours, dashed-ness, etc.).

pt

ps.  Looking at the code snippet:  It seems to me that the call to 
gp:clear-rectangle is superfluous.  You immediately redraw over top of the 
cleared rectangle.  Remove the clear-rectangle line and see if anything 
changes (it shouldn't, unless you have calculated the bounds incorrectly 
(something I do every time :-)).


________________________________________________________________________
This email has been scanned for all viruses by the MessageLabs Email
Security System. For more information on a proactive email security
service working around the clock, around the globe, visit
http://www.messagelabs.com
________________________________________________________________________

Re: Trying to draw a "selection rectangle"

> Selection rectangles should, in general, be drawn and undrawn using XOR 
> operations.

a selection rectangle done this way will have variable colors
along its border; unless the original destination pixels are 
all of the same value.  if you prefer the border of a selection
rectangle to display the same color and do it fast, just copy 
the image of the area to be affected, draw the selection rectangle,
and bitblt the old image back after the selection is done.  This 
is faster than you think.

best,

-cph


________________________________________________________________________
This email has been scanned for all viruses by the MessageLabs Email
Security System. For more information on a proactive email security
service working around the clock, around the globe, visit
http://www.messagelabs.com
________________________________________________________________________

Re: Trying to draw a "selection rectangle"

Ok.

I made changes to my code and came to the conclusion that it is an 
ordering problem.

The REDISPLAY-PINBOARD-LAYOUT (or GP:INVALIDATE-RECTANGLE) call does 
not complete before the call to DRAW-RECTANGLE.  The calls to 
FORCE-SCREEN-UPDATE do not seem to help.

Any ideas/ suggestions?  Has anybody experienced similar problems?

Please help.  I am in a bind.  Thanks

Cheers

Marco





(defmethod draw-selecting-highlight ((gp my-pinboard-layout) x y)
   (declare (type fixnum x y))
   (let ((selection-area-start (selection-area-start gp))
         (selection-area-end (selection-area-end gp))
         )
     (when selection-area-start
       ;; The following is somewhat wasteful.  I could cache the
       ;; rectangles I draw. I think the code is easier to read and
       ;; maintain this way.
       (let* ((s-x (point-x selection-area-start))
              (s-y (point-y selection-area-start))
              (e-x (if selection-area-end (point-x selection-area-end) 
x))
              (e-y (if selection-area-end (point-y selection-area-end) 
y))
              (old-start-x (min s-x e-x))
              (old-start-y (min s-y e-y))
              (old-width (abs (- e-x s-x)))
              (old-height (abs (- e-y s-y)))
              (start-x (min s-x x))
              (start-y (min s-y y))
              (width (abs (- x s-x)))
              (height (abs (- y s-y)))
              )
         (capi:redraw-pinboard-layout gp	; Redraw conservatively.
                                      (min start-x old-start-x) (min 
start-y old-start-y)
                                      (max width old-width) (max height 
old-height))
         (capi:force-screen-update :screen gp)
         (gp:draw-rectangle gp start-x start-y width height
                            :dashed nil ; T
                            :operation 'boole-xor)
         (capi:force-screen-update :screen gp)
         ))
     ))

--
Marco Antoniotti
NYU Courant Bioinformatics Group		tel. +1 - 212 - 998 3488
715 Broadway 10th FL				fax. +1 - 212 - 998 3484
New York, NY, 10003, U.S.A.


________________________________________________________________________
This email has been scanned for all viruses by the MessageLabs Email
Security System. For more information on a proactive email security
service working around the clock, around the globe, visit
http://www.messagelabs.com
________________________________________________________________________

Updated at: 2020-12-10 08:59 UTC