palmer@tybalt.caltech.edu (David Palmer) (09/19/89)
I just upgraded to Think C 4.0 (WOW!) and am diving in to object-oriented programming. I am writing a special purpose drawing program in Think C 4.0, and I need help. (The drawing portion of the program is a major part of a 3-D simulator.) 1) Has anyone developed a class structure good for drawing that they could place in the public domain? 2) Should the Ancestor class of the drawn objects be CBureaucrat? (Drawn objects respond to commands, keys, and mice, so I guess so.) 3) The documentation for CBureaucrat says that a Bureaucrat should handle Keys and Commands, which are automagically passed to it when it is the gGopher, but it doesn't say what happens to Mouse clicks. Are they also sent to the gGopher? 4) What should the flow of control be? Should the selected drawing object become the gGopher (or the Pane if nothing is selected), or should the Pane (or the Document?) handle mouse clicks and commands, passing them on to the currently selected object? 5) Can an Object be written-to and read-from a file in the standard manner? (with the Mac equivalent of fwrite(*Object, sizeof(object), 1, stream) where *Object is the first argument and singly indirects the handle of Object to get a pointer.) How are objects within objects best handled? (By which I mean references to objects. For instance, each object may have a list of the objects touching it, etc.) I am currently planning to keep all objects in lists, and, at save time, replace the contained object's handle with an index into the list. It is ugly, but I can't think of any other way to do it. Thanks in advance. David Palmer palmer@tybalt.caltech.edu ...rutgers!cit-vax!tybalt.caltech.edu!palmer "Direct quotes don't have to be exact, or even accurate. Truth is as irrelevant to a newspaper as it is to a court of law" - Judge Alarcon, 9th circuit court of appeals (paraphrased)
fjlim@garnet.berkeley.edu (09/21/89)
In article <11945@cit-vax.Caltech.Edu> palmer@tybalt.caltech.edu.UUCP (David Palmer) writes: > >I am writing a special purpose drawing program in Think C 4.0, and I need >help. (The drawing portion of the program is a major part of a 3-D simulator.) > >2) Should the Ancestor class of the drawn objects be CBureaucrat? > (Drawn objects respond to commands, keys, and mice, so I guess so.) > >3) The documentation for CBureaucrat says that a Bureaucrat should handle > Keys and Commands, which are automagically passed to it when it is > the gGopher, but it doesn't say what happens to Mouse clicks. > Are they also sent to the gGopher? > >4) What should the flow of control be? Should the selected drawing object > become the gGopher (or the Pane if nothing is selected), or should > the Pane (or the Document?) handle mouse clicks and commands, passing > them on to the currently selected object? The answers to these three questions are related. It depends on how you want to structure your program. Mouse clicks are "sent" to the Pane which is clicked on. Your drawing objects will not receive DoClick() messages unless you make each one a separate Pane (not a good idea). I recommend making your drawing objects subclasses of CBureaucrat and setting the gGopher to the current selected drawing object. The alternative is making the Pane act as a middleman which dispatches key clicks and menu commands to the appropriate object. This places too much knowledge in the Pane. You would have to change code in the Pane's methods if you added another kind of drawing object. > >5) Can an Object be written-to and read-from a file in the standard > manner? (with the Mac equivalent of > fwrite(*Object, sizeof(object), 1, stream) > where *Object is the first argument and singly indirects the handle > of Object to get a pointer.) How are objects within objects best handled? > (By which I mean references to objects. For instance, each object > may have a list of the objects touching it, etc.) > I am currently planning to keep all objects in lists, and, at save time, > replace the contained object's handle with an index into the list. It > is ugly, but I can't think of any other way to do it. > Objects are stored in memory as handles, so the simplest method of storing them to disk is as resources. Just use AddResource calls. In your case, however, you'll want to use the data fork since there could be many drawing objects. The only data for an object is the values of its instance variables (including those it inherits) and an additional two bytes (BEFORE the instance variables) which is used by the runtime environment for method dispatching. The Mac Toolbox call FSWrite(fileNum, &objSize, *Object+2); will work. As for references to other objects, you'll need to replace the pointer to the object (4 bytes) with some kind of index number for how you're storing objects in your file. When you read the object back into memory, you can replace the index number with a pointer. The Toolbox uses a similar technique for resources within resources (see IM I-127). --- Gregory Dow
ech@cbnewsk.ATT.COM (ned.horvath) (09/23/89)
In article <11945@cit-vax.Caltech.Edu> palmer@tybalt.caltech.edu.UUCP (David Palmer) writes: >I am writing a special purpose drawing program in Think C 4.0, and I need >help. (The drawing portion of the program is a major part of a 3-D simulator.) >2) Should the Ancestor class of the drawn objects be CBureaucrat? > (Drawn objects respond to commands, keys, and mice, so I guess so.) From article <1989Sep21.050812.15192@agate.berkeley.edu>, by fjlim@garnet.berkeley.edu: > ...Mouse clicks are "sent" to the Pane > which is clicked on. Your drawing objects will not receive DoClick() > messages unless you make each one a separate Pane (not a good idea). > I recommend making your drawing objects subclasses of CBureaucrat and > setting the gGopher to the current selected drawing object. The alternative > is making the Pane act as a middleman which dispatches key clicks and > menu commands to the appropriate object. This places too much knowledge > in the Pane. You would have to change code in the Pane's methods if you > added another kind of drawing object. I hate to try to tell grandma how to suck eggs, but... I'm fairly new to this object-oriented way of approaching things, so please bear with me; if I've got my head wedged, please help me get it loose... If the drawn objects are themselves CViews, in the pane's "itsSubviews" CList, then the DispatchClick() routine ought to "do the right thing" without any special knowledge in the pane at all. I'm presuming here that the drawn objects are themselves subclasses of CView (but not necessarily of CPane). By appropriately overriding the Contains() method (and setting wantsClicks), Mr. Palmer's visual objects should get DoClick() messages appropriately. Setting gGopher = this; in the drawn object's DoClick() method would then cause subsequent commands to be sent to the right place. Note that in the class library as distributed, there's no real support for the CDirector::itsGopher variable. It seems to me that a CBureaucrat access method would be a good idea here. Alternatively, you might override DispatchClick in your Document subclass to do something like inherited::DispatchClick(...); itsGopher = gGopher; this would be particularly sensible if CView::DoClick() was gGopher = this; (presently CView::DoClick() does nothing). As a more general comment, any CView might wish to override DispatchClick() to record the fact that one of it's subviews (or descendants) had become the gopher. This is pretty straightforward as things stand: a CView only gets a DispatchClick() message if it has wantsClicks set and it responds TRUE to a Contains() message, i.e. it is true that a CView gets a DispatchClick if and only if it or one of it's subviews receives (the) DoClick message. As a general design rule, any CView that becomes "active" (i.e. the gopher or one of it's visual ancestors) may need to respond in some way (typically a change in appearance). I don't think this is adequately reflected in the pristine class libraries, but again, please correct me if that's a misapprehension. Going the other way, the distributed CDirector/CDocument etc. classes don't do anything to "get the word out" on an Activate message. As a general rule, one would want to not just set "gGopher = itsGopher", one would also like to pass the Activate along to gGopher and its ancestors. Comments? Suggestions? =Ned Horvath=