home *** CD-ROM | disk | FTP | other *** search
- Xref: sparky comp.windows.misc:1746 comp.lang.objective-c:703
- Newsgroups: comp.windows.misc,comp.lang.objective-c
- Path: sparky!uunet!psinntp!afs!greg
- From: greg@afs.com (Gregory H. Anderson)
- Subject: Re: Alternative GUI class hierarchies?
- Message-ID: <1992Dec28.170847.420@afs.com>
- Sender: greg@afs.com
- Reply-To: greg@afs.com
- References: <1992Dec27.063724.15059@u.washington.edu>
- Date: Mon, 28 Dec 1992 17:08:47 GMT
- Lines: 122
-
- In article <1992Dec27.063724.15059@u.washington.edu>
- wiml@milton.u.washington.edu (William Lewis) writes:
- >
- > Recently I've been pondering the construction of an object-oriented
- > GUI toolkit (particularly, using gcc-objc over X, but that detail is
- > irrelevant), trying to combine the best attributes of the X intrinsics
- > and NeXTstep (the two OO GUI toolkits I'm familiar with). One thing that
- > strikes me as inelegant about both toolkits is the View/Cell
- > distinction (in X, the Widget/Gadget distinction). Although I understand
- > the utility of a "lightweight view" for menu selections and so forth,
- > I've never really liked it. I've thought of two possible solutions.
- >
- > The first one is really just a workaround. Instead of having
- > separate hierarchies for "heavyweight" and "lightweight" objects, each
- > object could select at instantiation whether it should be lightweight
- > or not. "Views" ("widgets") who are "lightweight" would have to
- > communicate with their closest "heavyweight" ancestor to ask for
- > events, drawing requests, to determine the (x,y) offset at which
- > to draw (since in X at least, drawing coordinates are relative to the
- > destination drawable --- transformation matrices could be very useful
- > here) and so forth. This would require a little more work on the part
- > of object authors, however, to handle both cases; and it still wouldn't
- > simplify the client's structure much (only the display server's).
-
- I think NeXT's architecture solves this problem nicely. TextFields, for
- example, already act primaily as Enclosures. Most of their methods are
- simply "covers" for the underlying Cell methods. The fact that a distinct
- Cell is actually doing the drawing is hidden in the implementation. (So
- well hidden, in fact, that we subclassed TextFields wrong the first time,
- by putting most of the cool new stuff in the View, not the Cell. Duh.)
- Cells draw relative to their bounding (not frame) rectangle, which in fact
- is relative to the destination drawable. So what's the problem?
-
- > The other idea is to divide the object hierarchy even more strictly,
- > so that any given object can *only* be in one or another subhierarchy.
- > Basically, I'm thinking of dividing all graphical objects into two
- > types: those which enclose an area, and those which draw things in
- > an area. Only area-enclosing objects would receive events from the
- > display server and mouse. Area-enclosing objects would be allowed to do
- > a little drawing, say a frame and a background, but nothing complex
- > like text. Under X, for instance, "enclosing" objects would (possibly)
- > have their own window, but "drawing" objects would never have a window.
-
- This is *exactly* the distinction between NeXT Views and Cells. But the
- strict hierarachy is bad, for a different reason: A View can give the
- handle of its Cell to another View, which can then share the draw code. In
- this way, the exact same contents can be drawn on multiple Windows, in
- differently sized (and attributed) Views. We use this. It's nice.
-
- > Immediately, the question is "but what about objects that both
- > enclose area, *and* draw things in that area? Like buttons, sliders,
- > text-boxes, menus ... pretty much everything in fact." For these,
- > I would have a *third* object which "owns" and manages the enclosing
- > and the drawing objects. For example, a Button object might own
- > a SqareEnclosure object and a Text (or SmallImage) object. Only
- > the enclosure and the text objects would have a visible manifestation.
- > The application programmer would interact only with the Button object,
- > but the Button object would use the other two objects to actually
- > do its work. This strikes me as having many advantages. Because each
- > UI element is more modular, it's easy to swap the subparts around:
- > the same Button class could be used for a button with a text label,
- > a button with an iconic label, or a button with some application-defined
- > image, without changing the Button class at all. Similarly, square
- > buttons, rounded buttons, and hexagonal buttons can be created by
- > writing a new "enclosure" class and causing the Button to use that
- > class instead of the "SquareEnclosure". I think this advantage is
- > applicable to other common UI objects as well.
-
- Again, for the most part NeXTSTEP works this way. A Form, for example,
- owns a list of FormCells. The FormCells, in turn, each own a TextField
- cell for the purpose of containing the drawing their titles. All of this
- is hidden in the implementation by using "cover" methods.
-
- On of the great things about the distinction between Views and Cells is
- that you can take a simple View like a TextField, suck out its Cell as the
- prototype for a Matrix, and voila! you have multiple Cells all acting and
- validating like the original. Instant spreadsheet.
-
- > The main *disadvantage* is that, in one sense, I've worsened the
- > original problem: there are now *more* objects floating around in the
- > application program than there are in the usual scenario! Three objects
- > just for a button; more for anything more complex. However, I think this
- > might not be so bad, because
- > - The individual objects are simpler. There are probably also
- > fewer distinct classes in use at any given time, which could reduce the
- > RSS of the application.
- > - If written well, the Enclosure class could offer much greater
- > control over server-side resource use. The idea of having each object
- > select whether it;s lightweight or heavyweight could be used here as
- well.
- > - Changing the "look" of an application -- say, from Motif-y to
- > Next-ish to Mac-like --- might involve changing only the Enclosures
- > and some drawers (like sliders), leaving many application-defined
- > objects alone. This would have to be designed in, though.
-
- In theory, yes. In practice, difficult. NeXT's implementation of the
- Responder chain within responder objects, to give one gotcha example, does
- not port well to X.
-
- > - In Objective-C, all objects are individually dynamically
- > allocated. But with some tweaking, it should be possible to allocate
- > space for a Button and both of its slave objects in one *alloc() call.
- > The space would be freed when the Button was freed; the Button would
- > have the responsibility of calling its component objects' -free methods
- > before it deallocates itself. ([Object free] would have to be rewritten
- > to check for this sort of situation, of course.)
-
- This already happens. When you init a TextField, it allocs its
- TextFieldCell at the same time.
-
- > I think that combining objects in this way would make the increase
- > in the number of objects much less harmful, since the number of
- > malloc() blocks would be the same, or even reduced. It would also
- > improve the locality of reference when responding to events.
-
- If you use allocFromZone, which you should, this problem is solved.
-
- --
- Gregory H. Anderson | Thus spake the master programmer:
- Master Programmer / Manager | "Let the programmers be many and
- Anderson Financial Systems | the managers few; then all will be
- greg@afs.com (Nextmail OK) | productive." -- Tao of Programming
-