I'm reimplementing the drag-output-record, dragging-output to be more closer to CLIM specification. This work is almost done. However, a behaviour of drag-output-record is underspecified in some places.
My questions are about `feedback' argument of drag-output-record. The following is what the CLIM specification says about feedback function and that's all what we have:
------------------------------------------------------------------------ `feedback' allows the programmer to identify a "feedback" function of seven arguments: the output record, the stream, the initial x and y position of the pointer, the current x and y position of the pointer, and a drawing argument (either :erase or :draw). It has dynamic extent. The default is nil, meaning that the feedback behavior will be for the output record to track the pointer. (The feedback argument is used when the programmer desires more complex feedback behavior, such as drawing a "rubber band" line as the user moves the mouse.) Note that if feedback is supplied, erase is ignored. ------------------------------------------------------------------------
My current solution. Notes: (i) the numbers with star means that the action is performed by user in the `feedback' function; (ii) (INITIAL-X INITIAL-Y) is the pointer coordinate when the user initially clicks the button on the desired record; (iii) (X-OLD Y-OLD) is remembered previous pointer coordinate.
The user calls drag-output-record. In drag-output-record:
1* Call (feedback RECORD STREAM INITIAL-X INITIAL-Y INITIAL-X INITIAL-Y :DRAW)
2. Set X-OLD := INITIAL-X; Y-OLD := INITIAL-Y
3. User moves the pointer. Now X Y is a new pointer position.
4* Call (feedback RECORD STREAM INITIAL-X INITIAL-Y X-OLD Y-OLD :ERASE). Erase previous feedback effect and output record.
5. Change output-record-position of the RECORD to a new location.
6* Call (feedback RECORD STREAM INITIAL-X INITIAL-Y X Y :DRAW) where the user draws the record at it's new position and draws feedback effect. Note, that RECORD already has the new coordinates in output-record-position.
7. X-OLD := X; Y-OLD := Y
8. Repeat from 4
...
9. User clicks a pointer button
10* Call (feedback RECORD STREAM INITIAL-X INITIAL-Y X Y :ERASE). Erase last feedback effect and the output record.
11. Replay the output record without feedback effect at it's final position.
12. Exit
---
Qusetion about my solution. ===========================
Q: Where the dragged output record should be erased and redrawn (i. e. replayed) when the `feedback' is supplied: in the `feedback' function by user or inside the drag-output-record function?
My solution: I've delegated the erasing and redrawing the dragged record to the user. The situation with erasing is more clear. CLIM specification states that if `feedback' argument is supplied, the `erase' argument is ignored. As far as user already had the possibility to provide the `erase' argument with custom function (`erase-output-record' by default), then this possibility only migrates to the :ERASE part of `feedback' function. A situation with `feedback :DRAW' is unclear. The redrawing of dragged output record can be accomplished either (i) in the drag-output-record before `feedback :DRAW' or (ii) by user in `feedback :DRAW', manually replaying the record and the desired feedback effect.
In other words, there are two algorithms, which are almost equivalent in the sense of visible effect, but not equivalent with respect to the user.
(I) My current solution. Erasing/redrawing of output record and feedback effect is accompishing by user.
1. Call `feedback :ERASE' where user erases the dragged output record and additional feedback effect from their previous position (with possible replaying).
2. Change output-record-position to a new position inside drag-output-record.
3. Call 'feedback :DRAW' where user draws the dragged output record and then the additional feedback effect at the new position.
(II) Alternative solution. The output record is redrawing in the drag-output-record.
1. Call `feedback :ERASE' where user erases the dragged output record and additional feedback effect from previous position (with possible replaying).
2. Change output-record-position to a new position inside drag-output-record
3. Draw the dragged output record at it's new position inside the drag-output-record by replaying required region that contains the output record.
4. Call 'feedback :DRAW' where user draws only the additional feedback effect.
What to prefer? The former provides more flexibility to control output record appearence as it's dragged. For example, I could implement dragging that is snapped to a grid by erasing/redrawing output record and additional feedback effect only when the pointer occures in the next grid cell area. This is not possible with (II), bacause we cannot control the redrawing of output record. How it was implemented in original CLIM? Does anyone have any legacy code or examples that use the drag-output-record with `feedback'?
---
Q: When the `feedback' is called with :DRAW, does the RECORD already have a new position on STREAM, i. e. the coordinates where it will be drawn?
My solution: See item 5. I'm changing output-record-position in the drag-output-record just before calling `feedback :DRAW'. Only the original CLIM implementation could clear how this was implemented.
---
Q: Am I right when passing the X-OLD Y-OLD to the `feedback :ERASE'?
My solution: If we are using the current pointer coordinates to draw feedback effect in `feedback :DRAW' (for example, to draw line with flipping ink from 0,0 to current pointer location), then to erase this feedback effect in subsequent :ERASE the previous pointer coordinates are required, not the current. However, CLIM spec says, that only current pointer coordinates are passed to feedback :ERASE/:DRAW. Alternative solution: user somewhere remembers coordinates that are passed to `feedback :DRAW' and use them when it's required to erase previous feedback.
Hello,
I started an issue tracker for McCLIM on Launchpad. Here is the URL:
https://bugs.launchpad.net/mcclim
The initial goal is to clean up the demos:
* Remove old useless demos.
* Add reasonable ones to the demodemo that aren't already in there.
* Make sure the demos used in demodemo work correctly.
* Clean up the code of the demos if necessary.
So, if you have any lingering bugs to report, in the demos or elsewhere, please post them to the issue tracker.
Regards,