leivian@axon.sps.mot.com (Bob Leivian) (05/17/91)
first of all thanks to all who helped with by previous requests,
I now have a pretty compilcated application ported to NeXTStep
and know alot more about NeXT and OBJ C but... (he's back...)
I would like to draw lines into the current view in XOR mode to do
rubberbanding, I can't find anything on this except composite, which
has an XOR mode but do I need to have two full window rectangles and
clear one and draw into it and then composite them?
I would like to do something like this
mouseMoved: e
{
...
PSmoveto(old.x, old.y);
PS..setXORmode... (); /* where is this */
PSlineto(anchor.x, anchor.y);
PSlineto(e->location.x, e->location.y);
old = e->location;
...
}
also bonus question for extra brownie points...
In IB I created a .nib that has a controlPanel (subclass of panel)
that has the buttons and sliders set up to control an instance of
an object that is dynamically created by the program. However when I
'new' the panel (with a loadNibSection in the +new method) I still
just get an empty panel, no buttons or sliders, even though the loadNib
comes back without an error -- any hints of where to look
thanks for any help -- Bob
--
Bob Leivian leivian@email.pcrl.sps.mot.com
Neural Network Development Group (602) 897-5117
2100 E. Elliot MD508 Tempe, AZ 85284
Peter_King@NeXT.COM (Peter King) (05/18/91)
In article <1004@nddsun1.sps.mot.com> leivian@axon.sps.mot.com (Bob Leivian) writes: > > ... > > I would like to draw lines into the current view in XOR mode to do > rubberbanding, I can't find anything on this except composite, which > has an XOR mode but do I need to have two full window rectangles and > clear one and draw into it and then composite them? > I would like to do something like this > Check out instance drawing. Here's a little snippet of code that does temporary line drawing in response to a mouse-down method. -mouseDown:(NXEvent *)theEvent { int looping; /* Flag for while in modal loop */ int oldMask; /* Old event mask */ NXPoint startPoint; /* Location of mouseDown */ NXPoint currentPoint; /* Location of mouseDragged/mouseUp */ /* Allow mouseDragged events */ oldMask = [window addToEventMask:NX_MOUSEDRAGGEDMASK]; /* Get the location of the mouseDown in view coordinates */ startPoint = theEvent->location; [self convertPoint:&startPoint fromView:nil]; /* Initialize the drawing context */ [self lockFocus]; PSsetgray(0.0); /* Turn on instance drawing */ PSsetinstance (YES); /* Run modal loop until mouse up */ looping = YES; while (looping) { /* Get the next mouseDragged/mouseUp event */ theEvent=[NXApp getNextEvent:NX_MOUSEUPMASK|NX_MOUSEDRAGGEDMASK]; /* Convert location to view coordinates */ currentPoint = theEvent->location; [self convertPoint:¤tPoint fromView:nil]; /* Erase all previous instance drawing */ PSnewinstance(); /* Handle the event */ if (theEvent->type==NX_MOUSEDRAGGED) { /* * On mouseDragged, instance draw a line * from starting point to current point. */ PSmoveto(startPoint.x, startPoint.y); PSlineto(currentPoint.x, currentPoint.y); PSstroke(); } else { /* * On mouse up, we stop the modal loop and draw * a real line from starting point to current * point. */ looping = NO; PSsetinstance(NO); /* Turn off instance drawing */ PSmoveto(startPoint.x, startPoint.y); PSlineto(currentPoint.x, currentPoint.y); PSstroke(); /* * Since we're not called from display, flush the * window buffer. */ [window flushWindow]; } } /* Release the drawing context and restore the event mask */ [self unlockFocus]; [window setEventMask:oldMask]; return self; } This causes a little bit of flicker (acceptable when rubber-banding). If you want to avoid the flicker, then you'd need to do double-buffering with off-screen windows and compositing. I'll leave this as an exercise for the reader. > In IB I created a .nib that has a controlPanel (subclass of panel) > that has the buttons and sliders set up to control an instance of > an object that is dynamically created by the program. However when I > 'new' the panel (with a loadNibSection in the +new method) I still > just get an empty panel, no buttons or sliders, even though the loadNib > comes back without an error -- any hints of where to look > You never need to "new" the panel; loadNibSection:owner: will instantiate it for you. What you want to do is add an outlet to your "custom object that is instantiated programmatically" which points to the control panel. In the nib file, set the File's Owner object to be the same class as your custom object, and drag a connection from the outlet you just created to your panel. When instantiating -->your custom object<--, call loadNibSection:owner: and pass in the id of the new custom object as the argument to owner:. When loadNibSection:owner: returns, the outlet in the custom object will have been initialized to point to the new panel (with buttons and all). Peter ----------Disclaimers? No such thing. Everything's the truth---------- Peter F. King Developer Trainer NeXT Computer, Inc. USPS: 900 Chesapeake Dr. Redwood City, CA 94063 Internet: Peter_King@NeXT.COM
glenn@heaven.woodside.ca.us (Glenn Reid) (05/19/91)
Peter King writes > Check out instance drawing. Here's a little snippet of code that does > temporary line drawing in response to a mouse-down method. [ code omitted ] > This causes a little bit of flicker (acceptable when rubber-banding). If you > want to avoid the flicker, then you'd need to do double-buffering with > off-screen windows and compositing. I'll leave this as an exercise for the > reader. I'm curious; why isn't instance drawing implemented to avoid flickering in the manner you suggest? It seems that this would be a better implementation, and just as easy, unless I'm missing something. -- Glenn Reid RightBrain Software glenn@heaven.woodside.ca.us NeXT/PostScript developers ..{adobe,next}!heaven!glenn 415-326-2974 (NeXTfax 326-2977)
duggie@pengyou (Doug Felt) (05/20/91)
In article <507@heaven.woodside.ca.us> glenn@heaven.woodside.ca.us (Glenn Reid) writes: > Peter King writes > > > Check out instance drawing. Here's a little snippet of code that does > > temporary line drawing in response to a mouse-down method. > > [ code omitted ] > > > This causes a little bit of flicker (acceptable when rubber-banding). If you > > want to avoid the flicker, then you'd need to do double-buffering with > > off-screen windows and compositing. I'll leave this as an exercise for the > > reader. > > I'm curious; why isn't instance drawing implemented to avoid flickering in > the manner you suggest? It seems that this would be a better > implementation, and just as easy, unless I'm missing something. > > -- > Glenn Reid RightBrain Software > glenn@heaven.woodside.ca.us NeXT/PostScript developers > ..{adobe,next}!heaven!glenn 415-326-2974 (NeXTfax 326-2977) I'm curious too, but the answer is probably buried in the depths of history. One day at an 'informal developer camp' back the summer before the NeXT was announced I remember talking to someone from Adobe about this, and he said that was how the specs were defined, and implied that the people from NeXT had something to do with it. I never followed up. In my opinion flicker is never acceptable, not even for rubberbanding, if you want a professional-looking product. Offscreen buffering is the way to go, although unfortunately this is high overhead when you are selecting large areas of the screen. Doug Felt
jmartin@trouble2 (Jeff Martin) (05/23/91)
In article <507@heaven.woodside.ca.us> glenn@heaven.woodside.ca.us (Glenn Reid) writes: > Peter King writes > > > Check out instance drawing. Here's a little snippet of code that does > > temporary line drawing in response to a mouse-down method. > > [ code omitted ] > > > This causes a little bit of flicker (acceptable when rubber-banding). If you > > want to avoid the flicker, then you'd need to do double-buffering with > > off-screen windows and compositing. I'll leave this as an exercise for the > > reader. > > I'm curious; why isn't instance drawing implemented to avoid flickering in > the manner you suggest? It seems that this would be a better > implementation, and just as easy, unless I'm missing something. The answer is memory consumption and compositing overhead. Every window would have to have two buffers, one that holds the real image (secondary) and one that holds that image with some type of overlay (primary) (imagine how much more memory the system would need!). Then at each step you would have to update the primary buffer from the secondary buffer, draw the overlaying graphics, then flush the primary buffer to the screen. Flickering is the trade-off for saving memory and time. Instance drawing should be used sparingly - and just for wireframes and such in response to user actions with the mouse. Memory is the highest commodity on the NeXT. Instance drawing is a good solution for many apps.
Peter_King@NeXT.COM (Peter King) (05/29/91)
In article <507@heaven.woodside.ca.us> glenn@heaven.woodside.ca.us (Glenn Reid) writes: > > I'm curious; why isn't instance drawing implemented to avoid flickering in > the manner you suggest? It seems that this would be a better > implementation, and just as easy, unless I'm missing something. > I wasn't there when the instance drawing mechanism was designed, but I suppose it is a classic "aesthetics vs. performance" tradeoff. An example of this kind of tradeoff is the different styles of window buffering available (Buffered/Retained/NonRetained). You can get a cleaner, snappier look if you are willing to pay in virtual memory for the buffered window. In a demand-paged system such as NeXT's, using more virtual memory effects the performance of the overall system. When you do double-buffered compositing for dynamic drawing, you need to allocate an off-screen window to hold the on-screen window's current state. Let's look at a worst-case scenario: we are writing a Draw like program that works in color on the NeXTdimension. An 8.5 by 11 page will take 612 pixels * 792 pixels * 4 bytes per pixel = 1938816 bytes Almost 2MB for the off-screen window. This will undoubtably cause paging to happen. If you have limited physical memory, this may not perform as fast as needed. Instance drawing gives you the option of using the window's backing store to erase from so you can avoid burning memory for the off-screen window. The tradeoff is that you get flicker. As with a lot of performance critical areas in NeXTstep application design, NeXT has provided the developer with a set of alternatives. Only the developer knows which alternative is appropriate for his or her application. If the flicker is unacceptable, use double-buffering. Peter ----------Disclaimers? Always. Everything's Subjective---------- Peter F. King Developer Trainer NeXT Computer, Inc. USPS: 900 Chesapeake Dr. Redwood City, CA 94063 Internet: Peter_King@NeXT.COM
dmg@ssc-vax (David M Geary) (05/31/91)
Peter King writes: ] In article <507@heaven.woodside.ca.us> glenn@heaven.woodside.ca.us (Glenn Reid) ] writes: ]] ]] I'm curious; why isn't instance drawing implemented to avoid flickering in ]] the manner you suggest? It seems that this would be a better ]] implementation, and just as easy, unless I'm missing something. ]] ] You can get a cleaner, snappier look if you ] are willing to pay in virtual memory for the buffered window. In a ] demand-paged system such as NeXT's, using more virtual memory effects the ] performance of the overall system. ] When you do double-buffered compositing for dynamic drawing, you need to ] allocate an off-screen window to hold the on-screen window's current state. ] Let's look at a worst-case scenario: we are writing a Draw like program that ] works in color on the NeXTdimension. An 8.5 by 11 page will take ] 612 pixels * 792 pixels * 4 bytes per pixel = 1938816 bytes ] Almost 2MB for the off-screen window. This will undoubtably cause paging to ] happen. If you have limited physical memory, this may not perform as fast as ] needed. ... Excuse me for jumping in on this thread because I do not own or even work on a NeXT, but having designed my own GUI from the ground up at work, and having implemented rubber banding ... If all you want to do is rubber-banding without the flicker, why allocate an off-screen buffer for the *entire* window? Instead, why not allocate 4 buffers,each of which is one pixel wide by screen width (or height) long: 1 pixel * 792 pixels * 4 bytes per pixel = 3168 bytes 3168 bytes * 4 (one for each line in rubber band rectangle) = 12672 This results in only 12K of ram vs. 2M. This seems quite reasonable to me. After all, it is not necessary to continually save and restore what the rubber banding rectangle *encloses*, just the portion of the screen that the rubber banding rectangle's lines are going to be drawn over. I have used this exact technique on a slow dinasour of a workstation (a Sun 3/60) and I have no flicker at all. Sorry if I'm way off base (see above disclaimer)... -- |----------------------------------------------------------------- | David Geary, Boeing Aerospace, Seattle, WA. | | | | Seattle - America's most attractive city... to the *jetstream* |
blanford@spf.trw.com (Ronald P. Blanford) (05/31/91)
In article <4043@ssc-bee.ssc-vax.UUCP> dmg@ssc-vax (David M Geary) writes: > If all you want to do is rubber-banding without the flicker, > why allocate an off-screen buffer for the *entire* window? > Instead, why not allocate 4 buffers,each of which is one pixel > wide by screen width (or height) long: I didn't want to jump in earlier since I didn't do the work and am not familiar with the code, but one of our applications implements a Rubberband class using just this technique. Besides reducing flicker, it improved performance by an order of magnitude.
Peter_King@NeXT.COM (Peter King) (06/01/91)
In article <4043@ssc-bee.ssc-vax.UUCP> dmg@ssc-vax (David M Geary) writes: > > If all you want to do is rubber-banding without the flicker, why allocate an > off-screen buffer for the *entire* window? Instead, why not allocate 4 buffers,each of which is one pixel wide by screen width (or height) long: > This is really an extension of the double-buffered compositing I was talking about earlier, but you're being much smarter about choosing which background pixels to retain. Would you call this quadruple buffering??? :-) The mechanism I suggested (buffering the whole window) works well when the dynamic drawing you're doing isn't a simple rubber-band. For example, you might be doing a draw program and you want to drag out a filled rectangle. This could potentially cover the whole window. But, as you say, if you are doing a simple rubber-band, four one-pixel-wide buffers work really well. Peter -- ----------Disclaimers? Always. Everything's Subjective---------- Peter F. King Developer Trainer NeXT Computer, Inc. USPS: 900 Chesapeake Dr. Redwood City, CA 94063 Internet: Peter_King@NeXT.COM
scott@mcs-server.gac.edu (Scott Hess) (06/04/91)
In article <4043@ssc-bee.ssc-vax.UUCP> dmg@ssc-vax (David M Geary) writes:
] When you do double-buffered compositing for dynamic drawing, you need to
] allocate an off-screen window to hold the on-screen window's current
] state. Let's look at a worst-case scenario: we are writing a Draw
] like program that works in color on the NeXTdimension. An 8.5 by 11
] page will take
] 612 pixels * 792 pixels * 4 bytes per pixel = 1938816 bytes
] Almost 2MB for the off-screen window. This will undoubtably
] cause paging to happen. If you have limited physical memory,
] this may not perform as fast as needed. ...
Excuse me for jumping in on this thread because I do not own or even
work on a NeXT, but having designed my own GUI from the ground up at
work, and having implemented rubber banding ...
If all you want to do is rubber-banding without the flicker, why
allocate an off-screen buffer for the *entire* window? Instead,
why not allocate 4 buffers,each of which is one pixel wide by
screen width (or height) long:
1 pixel * 792 pixels * 4 bytes per pixel = 3168 bytes
3168 bytes * 4 (one for each line in rubber band rectangle) = 12672
This results in only 12K of ram vs. 2M. This seems quite reasonable
to me. After all, it is not necessary to continually save and restore
what the rubber banding rectangle *encloses*, just the portion of the
screen that the rubber banding rectangle's lines are going to be drawn
over. I have used this exact technique on a slow dinasour of a
workstation (a Sun 3/60) and I have no flicker at all.
The best way to implement the above on a NeXT is to use 4 actual
_windows_ that overlay the selection. This is what's used in
the AppKit for the Window resizing rubber-banding, and a similar
technique is used in InterfaceBuilder to draw the connections that
go between windows.
Basically, you have 4 narrow windows, 2 horizontal, 2 vertical. Then,
you move them around as needed. This is relatively flicker-free
(well, you can't get much less, as anything you do will, in the
end, depend on Display Postscript, and this should be about as good
as it gets for rubber-banding.) To get an inkling of the method
to use, look in /usr/lib/NextStep/windowPackage.ps - therein
resides code that's loaded into the server that can be used to
check out system-wide windows for such a use. If you can wait,
I've been working on a modified Window class which uses this for
its resizing, so hopefully there will be a real example out there
at some time in the future.
Note that this is probably not a NeXT-supported method of rubber-
banding (ie, using the code in the windowPackage). But, the
technique should work fine, regardless.
Lastly, a point for Mr King - the instance drawing he is speaking
of is generalized - it's not limited to rubber-banding. You can
draw arbitrary postscript as the instance drawing, and then have
it go away when you tell it to. That's nice for some things -
unfortunately, you do lose either WRT the look of the drawing
(flicker), or memory. Fortunately, many rubber-band effects are
rectilinear, so that can be worked around in some special cases . . .
Later,
--
scott hess scott@gac.edu
Independent NeXT Developer Graduated GAC Undergrad!
<I still speak for nobody>
Note: I have moved home for a time. My email address will still be
valid. Any SnailMail should be redirected, along with phone calls.
At the least, my parents can tell you how to get hold of me, or
forward any mail . . .
Old: PO 829, GAC, St. Peter, MN 56082 (507) 933-8466
New: RR#4 Box 227 Pipestone, MN 56164 (507) 825-2788