CLIM mail archive

[Prev][Next][Index][Thread]

Moving objects and incremental redisplay



> Date: Tue, 28 Sep 1993 13:57 -0400
> From: Scott McKay <SWM@stony-brook.scrc.symbolics.com>
> 
>     Date: Tue, 28 Sep 1993 12:42 EDT
>     From: Brian Anderson 234-0878 <bha@ata.ca.boeing.com>
> 
>     CLIM 2.0beta2
>     ACL 4.2beta2
>     Sparc
> 
> 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.

Well, I have been working with CER to implement a graph layout
mechanism that uses the graph formatting engine to compute an initial
layout, capture those positions in each node object (the node object
has clim:standard-bounding-rectangle as a component in order to
capture that position), then explicitly draw each node at the position
of the bounding rectangle.  The node drawer has a clim:updating-output
surrounding it.  I am *not* currently messing with output records -
all I do is set the position of the node (by setting its bounding
rectangle position) and let incremental redisplay do its thing.  I
eventually want to not only change the "position" of a node but also
its graphical appearance (such as color, width, height, etc.).

> 
>     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?

Neither.  Maybe I should capture the updating-output record, set its
position to the position of the node that it surrounds and replay the
updating output record?  I suppose that I have to mess with converting
absolute to relative coordinates in the updating-output record vs the
absolute position of the node 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.

Again, should I be adjusting the position of the updating-output
record?

> 
>     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.

Yes, I think that I would always "know" what has happened to a node
that has been operated on.  For example, I can trap changing its
position, or its color, or its textual contents, etc.  Is this what
you mean?

> 
> For example, in order to move an object you simply:
> 
>  1) compute the region of the object

Which is the nodes bounding rectangle.

>  2) move the object to its new position

By setting the nodes bounding rectangle position and the nodes output
record position (in appropriate relative coordinates)?  Maybe a node
should itself be a specialized output record?  If so, how would I do
this.

>  3) replay the output records overlapping the objects old region
>  4) replay the output records overlapping the new region

clim:map-over-output-records-overlapping-region calling
clim:replay-output-record or supply a region to clim:replay?
> 
> 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.

So, I should bag incremental redisplay even for changes of appearance
such as size, color, text string, etc.?

References:

Main Index | Thread Index