CLIM mail archive


Moving objects and incremental redisplay

    Date: Tue, 28 Sep 1993 12:42 EDT
    From: Brian Anderson 234-0878 <>

    CLIM 2.0beta2
    ACL 4.2beta2

What kind of an application are you trying to write?  Hmm, that sounds
like a frivolous question, but it's not.  What I'm trying to find out
is, is is really the right thing to be using incremental redisplay for
this.  If this is a graphical editor sort of thing, you might be better
off doing incremental redisplay "by hand".  More below.

    I am having a problem with incremental redisplay when I "move" the
    bounding rectangle of an object that is displayed in an application
    pane.  What I do is draw the representation of a sequence of objects
    by drawing them each at the position and size of their bounding
    rectangle (each object has clim:standard-bounding-rectangle as a
    component).  Then, to move an object I just adjust its bounding
    rectangle position.  All of this is done in an application pane of
    type :application with :incremental-redisplay t.  The drawing of each
    object is surrounded by a clim:updating-output form whose cache value
    is a counter ("tick") that I increment when something about the
    appearance of the object has changed (e.g. like the text drawn inside
    the bounding rectangle, or its color).

So far, so good.  But are you adjusting the position of the output
record of the object itself, or the updating-output record that
surrounds the object?

    What is happening is that when I move an object, all the objects that
    were drawn "after" the moved object are displaced an amount equivalent
    to the displacement of the moved object.  That is, if I move an object
    to the right, all objects that were drawn "after" the moved object are
    also displaced to the right an equivalent amount.  Also, if I move an
    object "over" another object, then move it off that object, the hidden
    object's appearance is trashed.

Try supplying :FIXED-POSITION T in your calls to UPDATING-OUTPUT to see
what happens.

What may be happening here is that you are moving the wrong output
record (i.e., not moving the updating-output record), so CLIM has the
wrong information with which to compute incremental redisplay.

    I am not "ticking" all objects after a move operation so incremental
    redisplay is not being run on the unmoved objects.  I am ticking the
    object that is moved and it appears in the correct position.  Note
    that all this works correctly if I don't wrap the display of each
    object in a clim:updating-output.

I believe this.

    It seems to me that I should not have to tick an object (and as such
    cause its display code to be run by incremental redisplay) if its
    *appearance* has not changed.  It is debatable whether "moving" an
    object really is changing its "appearance" - I think not.  Its just a
    change of the object's location.  Maybe I shouldn't even have to tick
    the object that was moved.

As far as CLIM is concerned, moving an object most definitely changes
its appearance.

    My question is, shouldn't I be able to update positions of the
    displayed representation of a moved object while also maintaining the
    correct position of the unmoved objects and do so without having to
    resort to redrawing the "correct" set of objects thru incremental
    redisplay?  Also, an object shouldn't have to know that it was
    "hidden" by another object which was moved off of it.  All of this
    seems to be the responsibility of the output recording facility and
    its interaction with incremental redisplay.  What do I have to do in
    order to achieve the desired affect (that is all objects appearing at
    their correct position and hidden objects not having a trashed
    appearance) using the output recording facility?  Is this the correct
    approach?  (It seems pretty expensive to have to blindly redraw
    everything when an object is moved - kinda defeats the purpose of
    incremental redisplay doesn't it?)

Well, remember that incremental redisplay is expensively computing the
set of objects to erase, move, or draw, and then doing the output.
If your application is a graphic editor-like application, I would bet
that you have enough domain-specific knowledge to be able to do these
computations much more efficiently.  That is, in graphic editor-like
applications, the program probably "knows" exactly what has happened at
all times.

For example, in order to move an object you simply:

 1) compute the region of the object
 2) move the object to its new position
 3) replay the output records overlapping the objects old region
 4) replay the output records overlapping the new region

There are optimizations possible for step 3 and 4 that would cause even
less replaying to take place, but you have to be careful.

CLIM's incremental redisplay facility operates at too low a level to be
as efficient as the 4 steps above.  CLIM doesn't know, for example, that
you just moved one little object.  It has to go figure it out by looking
at the whole output record tree.

Anyway, if what you have is a graphic editor sort of thing, I think you
may want to consider not using CLIM's incremental redisplay facility.

Follow-Ups: References:

Main Index | Thread Index