Hi all.
In GUIs, I'm used to, when I get into the Paint or displayOn function, only painting the portion that needs painting. I can't seem to figure out how to get the rectangle (collection of rectangles) that needs painting. I suspect it's in the GraphicsContext that's passed in, but I can't quite get it. Can someone help me?
Even better, is there a document, or a very complete piece of code somewhere?
Regards,
Rick
-- I insist on rapport! _______________________________________________ vwnc mailing list [hidden email] http://lists.cs.uiuc.edu/mailman/listinfo/vwnc |
I have realized that if you try to investigate what's going on by setting breakpoints into methods that are used by the displaying system, bad things can happen. For example, I put a write to the Transcript in VisualPart>>repairDamage, and the system got very, very busy and ignored me. Apparently, that method is used in displaying the Transcript.
It would be much easier to find a writeup. The GUIDevGuide doesn't seem to address this issue.
Regards, Rick
On Sat, Jan 29, 2011 at 7:57 PM, Rick Hedin <[hidden email]> wrote:
-- I insist on rapport! _______________________________________________ vwnc mailing list [hidden email] http://lists.cs.uiuc.edu/mailman/listinfo/vwnc |
On Jan 29, 2011, at 7:47 PM, Rick Hedin wrote: > I have realized that if you try to investigate what's going on by setting breakpoints into methods that are used by the displaying system, bad things can happen. For example, I put a write to the Transcript in VisualPart>>repairDamage, and the system got very, very busy and ignored me. Apparently, that method is used in displaying the Transcript. > > It would be much easier to find a writeup. The GUIDevGuide doesn't seem to address this issue. Damage rectangles are stored in the Window's sensor object. It does it's best to coalesce them into single rectangles as they are accrued. Expose events come either from the OS (a window that was covering your window has been moved and allowed a portion to see thru) OR when your own programming objects issue one of the #invalidate type messages. When outstanding events are processed, the rectangles are handed to the damageRepairPolicy of the Window. The direct drawing policy fetches a graphics context (GC) for the window, and then for each distinct rectangle, sets the clipping rectangle of the GC to that rectangle, and tells the window to display with the GC. When it displays, it basically walks the tree of view objects using the displayOn: aGC method. Well written displayOn: methods will short circuit for themselves (and thus all of their children), when they note that their own frame has no intersection with the current GC. The double buffering display policy (you can send the message useDisplayBuffer to a Window in 7.8) improves some of the flicker caused by the direct policy, by creating a backing store (a Pixmap) for the Window, so that the drawing is done first on the pixmap for all rectangles, and then as a last step, they are copied directly to the screen which goes quite quickly. HTH -- Travis Griggs Objologist "The best way to know you have a mind is to change it" -Judge Pierre Leval _______________________________________________ vwnc mailing list [hidden email] http://lists.cs.uiuc.edu/mailman/listinfo/vwnc |
In reply to this post by Rick Hedin
On Jan 29, 2011, at 7:47 PM, Rick Hedin wrote:
> I have realized that if you try to investigate what's going on by setting breakpoints into methods that are used by the displaying system, bad things can happen. For example, I put a write to the Transcript in VisualPart>>repairDamage, and the system got very, very busy and ignored me. Apparently, that method is used in displaying the Transcript. I use a couple different tricks for things like this. I have to do it often actually, given what I do. First: 'Out' is my friend. Out is a package you can find in the public repository, and I believe it's a contributed parcel as well on the distro. It allows you to send the message #out to any expression. It will then print the receiver in the Transcript. It always returns the receiver, so may be used pretty much anywhere without needing to rewrite the code other than adding the out. Even more often than that, I use the method #stdout. I always run VW from console/terminals. This does the same as out, but emits the values to stdout, rather than the transcript. Often, I use both to capture two different data streams. Adding the line Timestamp now stdout. is a great way of getting a "yes, it's going there" and even counting when, since each is unique usually. Second: When I need to limit things (whether halt, or out, or breakpoints, or trying new prototypical code), I often use the guard clause: InputState default shiftDown ifTrue: [...] or ifFalse. Or ctrlDown. Or altDown. Or various combinations. In this way, I can selectively trap things. In your case, I might have put that guard in your repairDamage trip point. I could have resized a window with the shift key held down, and then let up. Third: Stack walking is your friend. You should never use this trick to accomplish useful things in your application. But it's wonderful for debugging. You can always get the current context and emit information about it. For example: ((1 to: thisContext localSize) collect: [:n | thisContext localAt: n]) stdout. will print all of the arguments and temporaries that a given method is currently working with. Look at the class context for other interesting things. One of my favorite, when I faced with a lot of code and a lot of polymorphism and a spot that doesn't necessarily lend itself to getting a trap in, and I want to to know how we got to a certain point in the code, I do something like: Character cr stdout. "create a break between blocks of output" sender := thisContext sender. 10 timesRepeat: [sender ifNotNil: [sender stdout. sender := sender sender]] Which will print the last 10 message sends that got us to this point. HTH -- Travis Griggs Objologist For every adage, there is an equal and contrary un-adage _______________________________________________ vwnc mailing list [hidden email] http://lists.cs.uiuc.edu/mailman/listinfo/vwnc |
In reply to this post by Rick Hedin
Rick,
Am 30.01.11 04:47 schrieb Rick Hedin: >> In GUIs, I'm used to, when I get into the Paint or displayOn function, only >> painting the portion that needs painting. I can't seem to figure out how to >> get the rectangle (collection of rectangles) that needs painting. I suspect >> it's in the GraphicsContext that's passed in, but I can't quite get it. Can >> someone help me? The GraphicsContext which is passed as the parameter of displayOn: can be asked for its clippingBounds, a Rectangle in the coordinate system of the VisualComponent which is asked to display itself. This will either answer the clippingRectangle of the GraphicsContext if there is one, or the bounds of the DisplayMedium if there is no clipping. If the Window has to be redrawn in more than one place, a VisualComponent will receive as many displayOn: message as there are rectangles to be redrawn. This can lead to flickering in some cases, you can use a DoubleBufferingWindowDisplayPolicy to reduce that (just browse for references to the class for examples of how to do it). You usually end up writing something like this: displayOn: aGraphicsContext | clipBox myBounds | clipBox := aGraphicsContext clippingBounds. myBounds := self boundsForSomethingToDraw. (clipBox intersects: myBounds) ifTrue: ["just an example" aGraphicsContext paint: ColorValue red; displayRectangle: (myBounds intersect: clipBox)] HTH, Joachim Geidel _______________________________________________ vwnc mailing list [hidden email] http://lists.cs.uiuc.edu/mailman/listinfo/vwnc |
In reply to this post by Travis Griggs-4
Travis,
Thanks for the description of what piece collects damage rectangles (sensor), in what fashion they are sent out (serially), and what piece gets the displayOn: message to me (policy-->window-->view). It would have taken me eons to figure that out by study and experiment. So the view's displayOn: method is called once for each damage rectangle, and the rectangle is noted in the gc. That's what I needed to know.
The debugging ideas are quite beautiful. I'm going to run vw from a console and use #stdout quite a lot, I suspect.
Smalltalk is really, really, not C++. I spent the last twenty years using (mostly) C and C++. Rather than clamping a debugger to my program, I can use the introspection abilities of the language. I understand, I really do, but I'm shocked. Pleasantly shocked.
Regards,
Rick
On Sun, Jan 30, 2011 at 12:46 AM, Travis Griggs <[hidden email]> wrote:
_______________________________________________ vwnc mailing list [hidden email] http://lists.cs.uiuc.edu/mailman/listinfo/vwnc |
In reply to this post by Rick Hedin
Thanks for the info Joachim, Terry.
I found the WatchLib.st file. The other technique is to store information in global variables if the method is being called, but the current object is not the object of interest. Just repeating to make sure I got it.
Regards,
Rick
On Sun, Jan 30, 2011 at 7:19 AM, Terry Raymond <[hidden email]> wrote:
_______________________________________________ vwnc mailing list [hidden email] http://lists.cs.uiuc.edu/mailman/listinfo/vwnc |
Free forum by Nabble | Edit this page |