Text Box objects
Volume Number: 7
Issue Number: 8
Column Tag: Jörg's Folder
Text Box View Objects
By Jörg Langowski, MacTutor Editorial Board
Text box view objects”
We are proceeding quite a bit on our way to a full drawing program (with objects
of different shape and text boxes); this month we’ll finally see how to create text boxes
in a window as independent views. Next month, then, we’ll put it all together and maybe
even start adding the disk I/O code.
Some Forth news first
First of all, though, I’d like to let you know that Palo Alto Shipping still exists. I
had them on the phone just a couple of days ago, the old number (415) 688-1111 still
works. They are still supporting Mach2, and even working on a version that is System 7
compatible. But unfortunately, Forth has become their side activity. As I understood it,
they are mainly working on hardware developments now, such as modems, and are
doing the Mach2 support only as a service to faithful Forthers. Anyway, Rick Wiley
assured me that the System 7-compatible version should be out at the end of the
summer. Otherwise, he stated, “there is just no market for Forth on the Macintosh”.
Too bad; people still ask me every now and then about what’s happening with Mach2,
and some quite complex programs seem to have been developed with this system. The
Mach2 roundtable on GEnie has been inactive for a long time; in fact, it is supposed to be
taken down soon.
Still, there are quite a number of Forth systems around for the Macintosh.
Mach2, if PASC keeps its promise to get the System 7 upgrade out at the end of the
summer (however, if you compare Bay Area summer temperatures to those we have
here in France this year, that might well be in November); MacForth Plus by Creative
Solutions - but we rarely hear anything from MacForth people here at MacTutor,
although there seems to be quite a big crowd out there using MacForth; then the public
domain systems, starting with PocketForth by Chris Heilman, and the two object
oriented systems, Yerk (ex-NEON) and Mops, which you’ve read about in this column.
Thus, if you need a Forth for the Macintosh, there are still quite a few possibilities.
When (if ever) I receive a System 7-compatible version of Mach2, I’ll devote a
column to it. Until then, let’s continue our C++/MacApp explorations.
C++ text boxes
Last month’s example showed you how to create two text views as subviews of a
scroller, and how to make either one of them the application’s target, i.e., the place
where key down events are sent. The application was very simple, it contained just one
window which was open at startup, and had no means to save the view’s data in a
document.
Of course, the drawing application that we are going to create is useless if we
can’t save our drawings. Therefore we’ll have to restructure our example for being
able to deal with documents. Also, at the end we’d like to add as many text boxes as we
like to our drawing; therefore we’ll have to put them in a list which is part of the
document, where all the other shapes (rectangles, lines, polygons...) are also kept.
A MacApp application that is supposed to deal with documents needs to define the
method DoMakeDocument, which is called when a new document is created (by selecting
New from the File menu) or an existing one opened. In our case (see example) this
method will just create the new document through the new operator. We have only one
class of documents. For applications that can deal with different document types, the
parameter itsCmdNumber will indicate which type of document has been opened.
Initialization of the new document is done by the constructor
TEditDocument::TEditDocument(). We do not need to call a special initializing method,
as we would have to in Pascal. However, we need to call the generic IDocument method
from within our constructor.
The document’s window and views within that window are created by the
DoMakeViews() method, which is called by MacApp. In the case of a document which is
opened for printing, the flag forPrinting would be set to true; we ignore it here since
we make no distinction between a document opened for display or for printing.
We create the document window from a view template which was created with
ViewEdit. This template contains a TEditView, which is a subclass of TScroller (see last
month’s column). That view contains four subviews of type TBoxView, our text boxes
which we want to draw. Although TEditView contains a list of its subviews, we’ll keep
references to the text boxes in a separate list, fShapeList, to which we can later add
other types of shapes (rectangles, lines, etc.), which are not views. This will be the
list of objects to be drawn in our window.
Thus, we will define a new subclass of TShape, TEditBox, which contains a
pointer to its document and to the TBoxView as instance variables. A TEditBox can then
be accessed through the generic ForEachShapeDo method in TEditView, just as all the
other shapes in the shape list. Here, the view’s frame is drawn by the method
TEditBox::DrawYourself. The view itself will be drawn independently, because it is
installed as a subview in the document window. (We could handle the drawing of text
boxes completely separately from the other objects in the shape list, by defining an
Adorn method for TBoxView; the way I’ve done it here is just one possibility).
A TBoxView should respond to mouse clicks by becoming the target for text input.
Thus, we define a method TBoxView::DoMouseCommand, whose only two statements are:
/* 1 */
this->GetWindow()->SetTarget(this);
inherited::DoMouseCommand(theMouse, info, hysteresis);
Thus, it sets the currently active target to itself and then calls
DoMouseCommand from its superclass, so that the standard text selection mouse
commands work.
DoMakeViews() gets references to the four subviews of the TEditView and creates
TEditBoxes containing those views. This is just for testing purposes; later, we’ll add a
palette selection which will create a new text box and install it in the shape list, and its
TBoxView in the list of subviews of the document window. I should point out here that,
in order to get the view’s enclosing rectangles (their ‘extents’) with the GetFrame
method, one has to focus on the superview containing them. Focusing means: setting the
GrafPort to the window in which the view is installed, setting the window’s origin to the
origin of the view, and setting the clip region to the view’s superview. One can only
focus a view whose window is visible, so we have to show the window first
(aWindow->Show(true,false)).
Once the views have been created and installed in the window, they will respond
to mouse clicks as you expect; when you type text in the active text box, you can select
it with the mouse, cut, copy and paste; and when you click in an inactive text box, the
blinking caret will appear there.
When you try out the example, note that the bottom left text box initially is set
to the Courier font, while all the others are Geneva. When you copy text from one box to
the other, you’ll notice that you can mix fonts in each box; Geneva text stays Geneva,
irrespectively of which box you copy it to. Yes, MacApp text views are styled. We’ll
explore this property further in the coming columns, and add a style selection menu as
well.
Finally, I’ll give you three screen dumps which show the ViewEdit settings for
the view resources in the editor.rsrc file. They should allow those of you who don’t get
the source code disks to recreate the example from scratch. Although I recommend
subscribing to the source disks, if only to avoid typographic errors.
See you next month.
Screen 1: Example view hierarchy (the view in the background is the TEditView)
Screen 2: TWindow parameters for the example (target setting is not important since
the program changes the target anyway)