[comp.sys.next] Programming Question

zimmer@calvin.stanford.edu (Andrew Zimmerman) (06/25/91)

I would like change the icon on a Button, depending on which state it is
in.  Rather then having a class which send a message to a button to 
change states, I thought I would just subclass a button.  

However, after looking through the Concepts manuals, and asking a couple 
of people, I'm still a little unclear on one point.  Should I be subclassing
a Button Class, or a ButtonCell Class?  If either is possible, what is
the advantage of one method over the other.

Thanks for any help,

Andrew
zimmer@calvin.stanford.edu

eps@toaster.SFSU.EDU (Eric P. Scott) (06/25/91)

In article <1991Jun25.050118.29467@neon.Stanford.EDU>
	zimmer@calvin.stanford.edu (Andrew Zimmerman) writes:
>I would like change the icon on a Button, depending on which state it is
>in.  Rather then having a class which send a message to a button to 
>change states, I thought I would just subclass a button.

If it's a two-state Button, you shouldn't need to subclass.
You can use setAltImage: or setAltIcon: to display something
different for the "1" state.  (Also, IB lets you set these.)

>However, after looking through the Concepts manuals, and asking a couple 
>of people, I'm still a little unclear on one point.  Should I be subclassing
>a Button Class, or a ButtonCell Class?

ButtonCell.  Controls don't draw--Cells do.

					-=EPS=-

zimmer@calvin.stanford.edu (Andrew Zimmerman) (06/28/91)

In response to a question I had about the Button Class vs that ButtonCell
Class, EPS explained that I should use a subclass of ButtonCell for
my application. (I wanted to have multiple (more then 2) icons to represent
the state of a Button.)

Unfortunately, when I subclass a ButtonCell, I couldn't figure out
how to instantiate the subclass under IB.  It didn't appear in the
class panel or under the custom view panel (Not a surprise).  
Anyway, any help on how to instantiate the new subclass would be
appreciated.  (Or do I have to reclass a Button created with IB?)

Andrew
zimmer@calvin.stanford.edu

PS.  Thanks EPS for answering my first question.

eps@toaster.SFSU.EDU (Eric P. Scott) (06/29/91)

In article <1991Jun28.073504.16199@neon.Stanford.EDU>
	zimmer@calvin.stanford.edu (Andrew Zimmerman) writes:
>In response to a question I had about the Button Class vs that ButtonCell
>Class, EPS explained that I should use a subclass of ButtonCell for
>my application. (I wanted to have multiple (more then 2) icons to represent
>the state of a Button.)

More specifically, override
 calcCellSize:inRect: (ButtonCell)
 doubleValue (ButtonCell)
 drawInside:inView: (ButtonCell)
 drawSelf:inView: (ButtonCell),
 floatValue (ButtonCell)
 getDrawRect: (ButtonCell)
 getIconRect: (ButtonCell)
 incrementState (Cell)
 intValue (ButtonCell)
 read: (ButtonCell)
 setDoubleValue: (ButtonCell)
 setFloatValue: (ButtonCell)
 setIntValue: (ButtonCell)
 setState: (Cell)
 state (Cell)
 write: (ButtonCell)
and possibly also
 calcDrawInfo: (Cell)
 copyFromZone: (ButtonCell)
 free (ButtonCell)
 ...and the state 0 (icon/image) and state 1 (altIcon/altImage)
 methods.

and, of course, you'll need some ways to get the additional icons
in there and to access them.  Even though there's a lot listed
here, most of the code is trivial.

>Unfortunately, when I subclass a ButtonCell, I couldn't figure out
>how to instantiate the subclass under IB.  It didn't appear in the
>class panel or under the custom view panel (Not a surprise).

Cells aren't subclasses of View.

>Anyway, any help on how to instantiate the new subclass would be
>appreciated.  (Or do I have to reclass a Button created with IB?)

Although it's convenient to think of Button as a single object,
it's really two: when you create a Button, you also get a
ButtonCell at the same time.  This sort of "pairing" occurs in
other NeXTstep classes as well--e.g., Windows come with a View
(contentView), a bunch of things come with Lists, etc.

For the "simple" Cells, there is a corresponding "simple" Control
subclass that offers both Control methods *and* Cell methods--
this means that your program doesn't have to understand the
distinction; it can send everything to one place, and the Cell
stuff will just be sent to the associated Cell object so you
don't need to ask for cell or selectedCell all the time.  Button
is arguably a convenience; you could just as well use ButtonCell
with some other Control; for example, a 1x1 Matrix.  (This can be
useful in practice, as Matrix can do things Button cannot, such
as handle double-clicks.)

Why might you want to subclass Button as well as ButtonCell?
One reason might be that you were developing something for
reuse.  It would be a "convincing" replacement, too, responding
favorably to queries like isKindOf:[Button class].

As for using ButtonCell subclasses with IB-created Buttons,
that's not terribly difficult.  One thing I would not use is
setCellClass:--that would turn ALL Buttons into mutant Buttons.
Instead, I'd have an outlet method use setCell: to replace the
original ButtonCell, transfer the instance variables (this CAN be
tricky, since you don't want to inadvertently set yourself up to
free something twice), and free the ButtonCell.  Of course, you
won't be able to use IB's Test Interface facility this way--if
you want that, make a loadable IB palette.

					-=EPS=-