Classes 6

From PowerMops
Revision as of 11:35, 15 January 2007 by Nao-sacrada (Talk)

Jump to: navigation, search


Views and Controls

About this chapter

This chapter describes views, which are also used by MacApp, TCL, PowerPlant, the Newton, and most other OOP development systems for GUI (graphical user interface) platforms. A view basically defines a rectangular area within a window within which drawing may take place. For those familiar with MacApp or TCL, there is a small difference in that in those systems a window is itself a view. In Mops, a window isn't a view, but contains a view or views.

Our basic Window class doesn't support views at all; for this you will need the Window+ class. Although you may draw directly in a Window via its Draw handler, we are now trying to discourage this. We don't even guarantee that in future windows will continue to have their own Draw handlers—in fact they probably won't!

You should now use a view within a Window+, and draw either by overriding the DRAW: method for the view, or by using its draw handler. This will give you much greater flexibility as to what you can do within the window. This comes about because a view can contain any number of child views. A child view is another view, but is constrained to be drawn within its parent view.

Class Control, which in earlier versions of Mops was an independent class, is now a subclass of View.


Recommended reading
Mops: Windows


Source files
View
6Ctl zCtl
Scroller
TEScroller  


Using Views

A view must have an owning window. A view has an associated rectangular area within which anything owned by a view is drawn, including any child views.

A Window+ contains one special view (the ContView) which covers the whole drawing area of the window (excluding any scroll bars). All other views within the Window+ must be child views of the ContView (or child views of those child views, etc).

The rectangular area of a view is defined in an ivar which is a rect, ViewRect. To be precise, this rectangle defines the outer boundary of this view, relative to the current grafPort. This rect is used by its owning view to set the clip region and the coordinate origin before calling any method on the view.

However, as we saw in the Tutorial in lesson 18, you will normally specify the size and position of a view by setting the bounds and justification for the four sides. Please see that Tutorial lesson for a full rundown of the various options you have.


Clicks on views

The way we used to handle clicks in earlier versions of Mops, was that CLICK: would be called on the whole hierarchy of views in a window (via Window+ calling CLICK: on its contView, and each view calling it on all its children), until one returned true to say that it had handled the click.

This scheme wasn't always flexible enough—for example, we might have a view which wants to take control of all clicks on it, even if the click was on a child view. But by the time the view found out that the click was in fact on a child view, the child view had already handled it! We needed a way of separating out the decision as to which view is to handle the click, from actually doing the handling.

Hence the new scheme. Clicking on views is now done in two steps. The first step is to decide which view is going to handle the click. The method VIEW_FOR_CLICK?: is now called on the whole hierarchy of views the way CLICK: used to be. This method returns either the address of a view and true, or just false.

So, the process starts with Window+ calling VIEW_FOR_CLICK?: on its contView. If this call returns true, we also have the address of the view that wants to handle the click, so Window+ then calls CLICK: on this view. And note from this that CLICK: no longer returns a result.

So, if your particular view receives a CLICK: message, you know that your view was really clicked—you don't have to test anything.

In the situation I mentioned above, where a view wants to handle clicks on its children, you can now simply override VIEW_FOR_CLICK?: Thus:

:m view_for_click?: ( -- ^view true | false )
   view_for_click?: super
   IF                \ child was clicked
       drop ^base    \ substitute my addr
       true        \ and tell caller we want the click
   ELSE
       false        \ no, don't want it
   THEN
;m


Using Controls

Mops defines a generic Control class, which is a subclass of View, and then has subclasses for the different kinds of standard control—Button, Checkbox, RadioButton, Vscroll and Hscroll.

Since a control is a view, in order to use controls within your application, you must use a Window+ or a subclass of Window+, since these are necessary to support views.

As is the case with other Toolbox objects (such as Windows) control objects have a dual identity. Part of the control's data is maintained by the Toolbox on the heap, and can be accessed by the application via a handle. If you were writing in a conventional language, such as C or Pascal, you would consider the handle to be the control, and you would have to build a lot of structure into your code to support the user's selection of the various parts of the control. Mops, on the other hand, combines the control's Toolbox related data with its own View related data to comprise a single object that contains all it needs to know about managing the various actions that can occur. You need only instantiate and initialize the object properly, and it takes care of the rest. Even much of the initialization is handled automatically via the View class.

Controls store the xts of Mops words as action vectors that will be executed when the various parts of the control are selected. Simple controls (class Control) have a single action vector, while scroll bars have 5. You can use these classes as a model for defining your own control classes if you wish to define new types.

When you click in a control, the control object receives a click: message as part of the normal view handling. The click: method in class Control then calls the Toolbox routine FindControl to identify which part of the control has been clicked. After that, two different things may happen, depending on the control type and part number affected.

For buttons, check boxes and scroll bar thumbs, the control is highlighted while the button remains depressed, but no other action is taken. The Toolbox routine TrackControl takes care of highlighting the correct control part while the mouse is in its proximity and the button is down. When the button is released, a late-bound exec: message is sent to the control object, causing it to execute its action handler for the correct part.

For the other parts of a scroll bar, however, it is desirable that a custom routine be executed while the button is held down in the part. For instance, while you hold down the button in the up arrow of a scroll bar, an editor should gradually scroll the document in small increments until the button is released. This can be accomplished by passing a procedural argument to the TrackControl routine, but the procedure must look like a Pascal procedure rather than a Mops word. Mops contains a special compiler that packages Mops words in a way that makes them look like Pascal procedures (:PROC ... ;PROC or :PPC_PROC ... ;PPC_PROC - see Part II Chapter 6). We have created one of these proce-dures to execute the action vector of a control repeatedly while the mouse button is down, and Mops passes this procedure to TrackControl in the case of the non-thumb scroll bar parts. Whatever actions you have defined for these parts will be executed while the part is being selected.

We have also provided a subclass of View named Scroller, which provides for a vertical and horizontal scroll bar along the edges of the view, with action vectors already defined for you.


Creating control objects

Defining a control object requires three steps. First, instantiate the object with a phrase like:

button saveBtn

You should then initialize the newly created object to assign it a position and a title. For example:

100 250 " Save" init: saveBtn
' doSave actions: saveBtn

Here we define saveBtn as a Button, specify that its top left corner will be be at coordinates (100, 250) relative to the view that it will appear in, and give it a title. Then we set doSave as its action word. DoSave will be executed if the user releases the mouse button while the mouse is within saveBtn's control rectangle. Finally, when the program executes, we must use addView: to add the control to its parent view's list of child views. Then when we fire up the window with new: or getNew:, the control will automatically receive a new: message which will cause it to create a Toolbox Control record on the heap and draw itself.

Control action words often need a way to determine which control they have been dispatched from. For example, a common action taken in scroll bar arrows is to get the control's value, add some increment to it, and put the new value in the control. This could be done in the following manner:

: doUpArrow  get: [ thisCtl ] 1- put: [ thisCtl ] -1 scroll: theText ;

In this example, the word thisCtl is actually a Value that Mops provides as a simple way for a control action word to derive its owning control object. thisCtl contains the control object's address as any click on a control puts its address into the value. This allows you to write very general action words that can be assigned to several different control objects simultaneously.


Design issues

Because late-bound messages must be sent to controls and windows, these objects cannot be defined as nor-mal named ivars, because to do so would fail to provide a class pointer for the runtime method lookup. If you wish to make a control or window an ivar, you will need to define a subclass with the General attribute, then use that class. However you don't need to do this with Vscroll or Hscroll, since these have already been defined as General.

Late binding is necessary because there are cases in which the Toolbox returns the address of an object to the application, but is is undesirable to make any assumptions about the actual class of the object. For instance, when you click the mouse button, the Toolbox call FindWindow tells you in which window the click occurred. This requires that a Content: message be sent to the object, but because the programmer is free to define subclasses of class Window, there is no way to know ahead of time what class the window object belongs to.


Dialogs

Mops implements controls in dialogs differently than in normal windows. Since dialogs rely heavily upon resource definitions and don't usually occasion much interaction with the items themselves other than getting or setting values, Mops does not build dialog control items as objects, but rather accesses them through methods in the Dialog class itself. This saves a lot of space, and actually simplifies the interface for the programmer.


Classes

View


View is the generic superclass for everything that can be drawn in a window.

Superclass Object
Source file View
Status Core (optional on 68k Mops)
Instance variables
Class Name description
rect viewRect Bounding rectangle, rel to grafport
rect bounds We use this to set the viewRect
ptr ^parent Points to parent (containing) view
ptr ^myWind Points to owning window
ptrList children List of child views
x-addr draw Draw handler
x-addr clickHndlr Click handler
bool alive?
bool enabled?
bool wantsClicks? True if we can accept clicks
bool setClip? True if we need to set the clip (default)
bool canHaveFocus? True if we can have the focus
bool measureFromMe? True if other siblings are to use this view for sibling relative justification modes
byte #updates Counts number of pending updates
byte Ljust Left justification
byte Tjust Top
byte Rjust Right
byte Bjust Bottom
Indexed data None
System objects None


Inherits: Object
Methods
accessing
getViewRect: ( -- l t r b ) Returns the viewRect coordinates
^viewRect: ( -- addr ) Returns the address of the viewRect object
bounds: ( -- l t r b ) Both return the bounds coordinates
getBounds:
getJust: ( -- lj tj rj bj ) Returns the current justification values for the four sides in the usual order
enabled?: ( -- b ) Returns true if this view is enabled
window: ( -- ^wind ) Returns the address of the owning window object
parent: ( -- ^view) Returns the address of the parent view, or nilP if this is the ContView
setWindow: ( ^wind -- ) Sets the owning window to the window whose address is passed in
wantsClicks: ( b -- ) Sets the wantsClicks? ivar to the passed-in boolean value
setClick: ( xt -- ) Sets the click action vector, and sets wantsClicks? to true
setDraw: ( xt -- ) Sets the draw action vector
setParent: ( ^view -- ) Sets the parent view address (which is stored in the ivar ^parent)
update: ( -- ) Generates an update event for the view
clear: ( -- ) Clears the view
view positioning
bounds>viewRect: ( -- ) Used internally by the view mechanism. Uses the current bounds and justification values to set the viewRect
childrenMoved: ( -- ) Used internally by the view mechanism. Signals this view that its children's positions have to be recomputed. Causes this view to send moved: to all its children (see below)
moved: ( -- ) Called when something has happened to change the position of this view (such as the parent view moving, or the bounds or justification parameters changing), requiring the viewRect to be recomputed. This method calls bounds>viewRect: self and childrenMoved: self.
runtime control
Note that addview: must be called at run time, since a view's address is passed in. new: is called at run time, once this view's parent view already exists. However, new: is normally called automatically, when new: is sent to the owning Window+ object. The Window+ calls new: on its contView, and everything continues from there, since new: on a view calls new: on all its child views
setJust: ( lj tj rj bj -- ) Sets the justification values for the four sides in the usual order
setBounds: ( l t r b -- ) Sets the bounds for the four sides in the usual order
measureFrom: ( b -- ) Sets the MeasureFromMe? ivar. If set True, this view will be used as a reference if any of its siblings use sibling-relative justification
focus: ( b -- ) If the passed-in flag is true and this view can take the focus (as indicated by the ivar canHaveFocus? being true), this view becomes the view in focus
addview: ( ^view -- ) Adds the passed-in view to this view's list of child views. This method can only be called at run time
new: ( ^view -- ) Fires up the view at run time, and calls new: on all its child views. The passed-in view is the containing view of this view, or nilP if there is none (i.e. this is the ContView of a window). Note that new: is normally called automatically via a new: on the owning Window+.

manipulation

release: ( -- ) Releases this view and all its child views. This too is normally called automatically via a release: on the owning Window+
classinit: ( -- ) Sets the initial defaults. SetClip? and WantsClicks? are set True. The justification values are set to parLeft, parTop, parLeft, parTop
display
draw: ( -- ) Draws the view (and all its child views). The setting up and winding up is done via the callFirst/callLast mechanism, and here in class View itself the only other action that draw: takes is to execute the Draw handler. Please see the comments in the source code for more detail.
event handling
idle: ( -- ) Called when idle: is sent to the owning window. Does nothing in class View itself, except to call idle: on all the child views
MouseHere?: ( -- b) returns true if the cursor is currently in this view
ClickedHere?: ( -- b) returns true if the last click was in our ViewRect
view_for_click?: ( -- ^view true OR -- false ) Called when a click has occurred in the owning window's content area. Returns True if the click was actually in this view (or one of its child views), as well as the address of the innermost view which got the click. Otherwise returns False
click: ( -- ) The Click handler is executed. If this view can take the focus (as indicated by the ivar canHaveFocus? being true), this view becomes the view in focus
key: ( c -- ) Called when a key event has occured and this view is in focus. Does nothing in class View itself, except to drop the passed-in character
enable: ( -- ) Enables the view. Called from Window+ when the window is enabled
disable: ( -- ) Disables the view. Called from Window+ when the window is disabled
drawX: ( -- ) Can be useful in debugging, when you want to see the view but don't have ‘real’ drawing code yet. It just draws a big X across the view area, joining the diagonally opposite corners.


Error messages - None


Control


Control is a generic superclass for controls. In Carbon PowerMops, the name is changed to be "RootCtl".


Superclass View
Source file 6Ctl zCtl
Status Core (optional on 68k Mops)
Instance variables
Class Name description
int procID The control definition ID for the Toolbox
int resID The control's resource ID
handle CtlHndl Handle to the control record
int myValue Contains a copy of the numeric value of the control
int titleLen Length of the control's title
32 bytes title The text of the title
Indexed data None
System objects None


Inherits: View, Object
Methods
accessing
putResID: ( resID -- ) Stores the resource ID for the control. Used if the control is defined via a resource
get: ( -- val ) Returns the value of the control
put: ( val -- ) Sets the value of the control
handle: ( -- hndl ) Returns the control handle
setTitle: ( addr len -- ) Sets title of control
getTitle: ( -- addr len ) Gets title of control
exec: ( part# -- ) Executes the control's action handler
manipulation
moved: ( -- ) Same as moved: on the superclass View, but also contains a call to MoveControl to inform the system of the control's new position
hilite: ( hiliteState -- ) Highlights, disables, or enables the entire control
enable: ( -- ) Enables the control
disable: ( -- ) Disables the control
hide: ( -- ) Calls Toolbox HideControl
show: ( -- ) Calls Toolbox ShowControl
click: ( -- ) As for click: on the superclass View, but contains some necessary toolbox calls as described above in the introduction to this class
initialization
classinit: ( -- ) Sets default control to type ‘button’ with null click action, and a zero length title.

runtime control

new: ( -- ) As for new: on the superclass View, but contains a call to NewControl to create a new control in the Toolbox for this control object. The initial value is 0, and the range is 0 to 1
getnew: ( -- ) Same as new:, but uses a resource. The resource ID must already have been set via putResID:
release: ( -- ) Releases the control handle, then calls release: super to do the nor-mal View releasing action
display
draw: ( -- ) As for draw: on the superclass View, but contains a call to Draw1Control so that the system will do the actual drawing of the control


Error messages - None


TitledCtl


TitledCtl just adds a convenient init: method for setting up a control with a title, where the width of the control's rect is determined by what the title is. We assume the font will be Chicago and the height of the control is 20. This may be overridden in subclasses as necessary.


Superclass Control
Source file 6Ctl zCtl
Status Core (optional on 68k Mops)
Instance variables None (see Control)
Indexed data None
System objects None


Inherits: Control, View, Object
Methods
initialization
init: ( x y addr len -- ) Initializes the control (may be done at compile time). Sets up the control with a title. x and y are the initial top left Bounds values (using whatever justification is in effect). (addr len) gives the title


Error messages - None


Button, RadioButton, CheckBox


Button, RadioButton and CheckBox provide support for those types of control. The only real change from TitledCtl is the customization of classinit: to set the appropriate proc ID so that the system will draw the right kind of control.


Superclass TitledCtl
Source file 6Ctl zCtl
Status Core (optional on 68k Mops)
Instance variables None
Indexed data None


Inherits: TitledCtl, Control, View, Object
Methods
The next three methods are for RadioButton and CheckBox only
Set: ( -- ) Set the control to the 'on' state
Clear: ( -- ) Again, RadioButton and CheckBox only. Set the control to the 'off' state
Click: ( -- ) Calls click: super, then sets or clears the control as appropriate
classinit: ( -- ) Initializes the control with the appropriate proc ID


Error messages - None


Vscroll, Hscroll


Vscroll and Hscroll provide support for vertical and horizontal scroll bars. Class Hscroll is set up as a sub-class of Vscroll, and just overrides classinit: to set the ivar horiz? to true. It takes no other special action. Several methods interrogate this ivar and do the appropriate thing.


Superclass Control
Source file 6Ctl zCtl
Status Core (optional on 68k Mops)
Instance variables
Class Name description
var minval The current minimum value for the control
var maxval The current maximum value
int scale
5 ordered-col parts Give the part IDs for the various parts of a scroll bar
5 x-array actions The corresponding action handlers
bool horiz? True if this is a horizontal scroll bar; false if vertical scroll bar
Indexed data None
System objects None


Inherits: Control, View, Object
Methods
accessing
actions: ( up dn pgUp pgDn thumb 5 -- ) Sets up the action handlers for the 5 parts. up etc. are xts, and we require a 5 on top of the stack as an xt count, as for all actions: methods
put: ( val -- ) Sets the value of the scroll bar. The value is coerced to not fall outside the current minimum and maximum
get: ( -- val ) Gets the value of the scroll bar
putMax: ( val -- ) Sets the maximum value
putMin: ( val -- ) Sets the minimum value
putRange: ( lo hi -- ) Sets the minimum and maximum
initialization
classinit: ( -- ) Sets action handlers to null and selects scrollbar type control.

Class Hscroll is set up as a subclass of Vscroll, and overrides classinit: to set the ivar horiz? to true. It takes no other special action.

init: ( top left len -- ) Initializes the scroll bar (may be done at compile time).
runtime control
new: ( ^view -- ) Creates a new control in the Toolbox for this scroll bar object. ^view is the address of the owning view, within which the control will appear. new: will normally be called automatically when new: is done on the view
getNew: ( resID ^view -- ) Creates a new control in the Toolbox for this scroll bar object, using a resource
display
hide: ( -- ) causes the OS to draw only the outline of the scroll bar rectangle; use when the window is disabled
disable: ( -- ) Sets entire control to 255 hiliting (disabled)
enable: ( -- ) Sets entire control to enabled hiliting.
execution
exec: ( part# -- ) Called from the event handling code when there is a mouse-down in the given part of the scroll bar. Executes the corresponding action handler.


Error messages - None


Scroller


Scroller is a view which has support for a vertical and horizontal scroll bar along the right hand and bottom edge respectively. We implement it with three child views: mainView, which is the display area, and the two scroll bars themselves. These child views are ivars of Scroller. MainView is an instance of a one-off class, Mview. This class has a rectangle, PanRect, which normally ought to enclose all the child views of the Mview. The usual scenario is that PanRect is larger than the viewRect, and scrolling amounts to shifting the child views (and PanRect) around within the viewRect—which, from another point of view, can be thought of as ‘panning’ the viewRect over the PanRect area. Mview has appropriate methods for returning the distances by which PanRect falls outside the viewRect area, so that the parent Scroller can set the scroll bar values appropriately. One unusual thing we do here is to override addView: on Scroller so that it becomes an addView: on MainView, since this is usually what we really mean. In the case where you want to really addView: on the Scroller, such as to add another child view alongside one of the scroll bars, you should sub-class Scroller with the extra views as ivars, and at run time do addView: super as we do for the scroll bars (see the new: method). Another approach we could have taken to implementing MainView would have been as a pointer, with late binding. That way MainView could have been any view subclass. That would have been more flexible, but possibly overkill for what we usually want to do—it would have required a more complex setting-up process, with the MainView address having to be passed in after new: has been done. But if you need the extra flexibility, feel free to clone Scroller and make the changes!

PanRect can obviously be very big, so we don't implement it as a regular rect, but define a new class, BigRect, which uses vars rather than ints for the coordinates.


Superclass View
Source file Scroller
Status Optional
Instance variables
Class Name description
Mview mainView
vscroll theVscroll
hscroll theHscroll
bool vscroll? True if v scroll bar to be used
bool hscroll? True if h scroll bar to be used
bool usePanRect? True if we're to use PanRect
var Hpan Horizontal panning range
var Hpos Current vertical posn
var Vpan Vertical ditto
var Vpos
int Hunit # pixels for one horizontal arrow click
int Vunit # pixels for one vertical arrow click
int Lgap gap (in pixels) at the left end of the scroll bar
int Tgap
int Rgap
int Bgap
Indexed data None
System objects None


Inherits: View, Object
Methods
accessing
Vscroll: ( b -- ) Passed-in boolean is true if this Scroller is to have a vertical scroll bar
Hscroll: ( b -- ) Passed-in boolean is true if this Scroller is to have a horizontal scroll bar
putPanRect: ( l t r b -- ) Sets the PanRect directly. The default, however, is to use the rectangle bounding all the child views
addview: ( ^view -- ) adds the passed in view as a child of Mainview; nmust be done at run time
>Hunit: ( n -- ) Sets the Hunit—the number of pixels for one horizontal arrow click
>Vunit: ( n -- ) Sets the Vunit
>Hrange: ( lo hi -- ) Sets the lower and upper limits for the horizontal scroll bar. This will normally be done automatically whenever the size of the PanRect is set
>Vrange: ( lo hi -- ) Sets the lower and upper limits for the vertical scroll bar
>gaps: ( l t r b -- ) Sets the values for the gaps left at the ends of the scroll bars. These will normally be all zero, but would make it easier to leave room for something else at the bottom or side of the window.
initialization
classinit: ( -- ) Initializes the Scroller to the default configuration—with both scroll bars, and both Hunit and Vunit set to 4. The justifications of the scroll bars are set so that they will be placed along the right and bottom edge of the Scroller. The action handlers of both bars are set to call the appropriate methods above.
runtime control
new: ( -- ) Fires up the Scroller at run time. Calls addView: self with mainView and the two scroll bars, since as they are child views as well as ivars. Note that new: is normally called automatically via a new: on the owning Window+
manipulation
 ?Venable: ( -- ) Enables the vertical scroll bar, if there is one and there is a scrolling range (that is, if the PanRect extends beyond the ViewRect in the vertical direction)
 ?Henable: ( -- ) Enables the horizontal scroll bar, if there is one and there is a scrolling range
enable: ( -- ) Enables the Scroller. The above two methods are called to set the enabled/disabled status of the scroll bars appropriately
disable: ( -- ) Disables the Scroller
moved: ( left top -- ) Same as moved: on a View, but includes handling of the scroll bars
pan: ( dx dy -- ) Pans the view over the child views by the given distance. The scroll bars aren't altered—use panRight: etc. for this, since they adjust the appropriate scroll bar and then call pan:.

Note that panning doesn't actually move the view within its parent view, but the panning is accomplised by shifting the child views in the opposite direction. Our convention is that positive dx and dy correspond to a pan to the right and down, which means that the child views are being shifted to the left and up, which is a ‘negative’ shift

panRight: ( dx -- ) Pans the view to the right by dx pixels, or until the scroll limit is reached. Adjusts the horizontal scroll bar appropriately
panLeft: ( dx -- ) Pans the view to the left by dx pixels likewise
panUp: ( dy -- ) Pans the view up by dy pixels likewise
panDown ( dy -- ) Pans the view down by dy pixels likewise
Hpage: ( -- #pixels ) Returns the number of pixels corresponding to a ‘page’ in the horizontal direction
Vpage: ( -- #pixels ) Returns the number of pixels corresponding to a ‘page’ in the vertical direction
1right: ( -- ) Handles a click in the right arrow of the horizontal scroll bar
1left: ( -- ) Handles a click in the left arrow of the horizontal scroll bar
1up: ( -- ) Handles a click in the up arrow of the vertical scroll bar
1down: ( -- ) Handles a click in the down arrow of the vertical scroll bar
pgRight: ( -- ) Handles a click in the “page right” region of the horizontal scroll bar
pgLeft: ( -- ) Handles a click in the “page left” region of the horizontal scroll bar
pgUp: ( -- ) Handles a click in the “page up” region of the vertical scroll bar
pgDown: ( -- ) Handles a click in the “page down” region of the vertical scroll bar
Hdrag: ( -- ) Handles a drag of the horizontal scroll bar thumb
Vdrag: ( -- ) Handles a drag of the vertical scroll bar thumb
view_for_click?: ( -- ^view T | F) As normal, but always sets this view to be the ClickedScroller, even if we are not the scroller clicked.


Error messages - None


TEScroller


TEScroller is a view which displays a TextEdit record in mainView (the main display area). All the customary text editing operations are supported, including (of course) scrolling. The main part of the Mops window (excluding the stack display) is a TEScroller. The TextEdit record is handled via an ivar theTE, which is an instance of the class TextEdit. Class TextEdit is probably not much use in isolation, (it would normally be used via this TEScroller class), so we won't document it in detail here in the manual. However the source code (in file TextEdit) should be reasonably self-explanatory.

In Carbon, TextEdit is ‘deprecated’ and some of the functionalities may not work. So you should use MLTEView instead of following clases on PowerMops.


Superclass Scroller
Source file TEScroller
Status Optional
Instance variables
Class Name description
TextEdit theTE  
rect rPanRect TE needs a rect, not a bigRect. So we mirror our PanRect here
bool wrap? Do we wrap the displayed text?
bool scroll_on_insert? Do we auto-scroll on insert: or $insert: ? You can set this false if you're inserting a large amount of text, and you want to be able to read it while the insertion is still going on, without it scrolling away from where you're reading
byte mouse_was_here?  
Indexed data None


Inherits: Scroller, View, Object
Methods
Note: Many of the methods are just overridden versions of the methods of the superclass Scroller, where there is an additional action to perform to the TextEdit object, but where the behavior of the method is really the same. We won't list these individually, but concentrate on the methods that are new in this class.
accessing
textHandle: ( -- hndl ) Returns a handle to the text in the TextEdit object
handle: ( -- TEhndl ) Returns the TEHandle
size: ( -- n ) Returns the number of characters in the text
getSelect: ( -- addr len ) Returns the selection range. Start and end are character offsets in the text
getSelect&lock: (-- hState addr len) As the previous method, but locks the TE before returning. The handleState (hState) parameter can be reset using the method >hState: (below), leaving the handle in the same state, either locked or unlocked, as it was before the method was used
getText: ( -- addr len) gets all the text in the TE
getText&Lock: (-- hState addr len) As the previous method, but locks the TE before returning. The handleState (hState) parameter can be reset using the method >hState: (below), leaving the handle in the same state, either locked or unlocked, as it was before the method was used
selStart: ( -- n ) Returns the offset of the start of the selected range
selEnd: ( -- n ) Returns the offset of the end of the selected range
getLine: ( -- start end ) Returns the offset of the start and end of the line with the cursor. No text need be selected
lineEnd: ( -- n ) Returns the offset of the end of the line with the cursor
wrapit: ( -- ) Sets the TE to wrap text in the window
NoWrap: ( -- ) Opposite of the above
>hState: (hState -- ) sets the state of the handle to the text in the TE
editing
 ?scroll: ( x y -- ) If necessary, does a scroll so that the point (x, y) is in view. X and y are relative to the window, not the view
setSelect: ( start end -- ) Sets the selection range
SelectAll: ( -- ) Selects all the text in the TE
SelectLine: ( -- ) Selects the current line
SelectLineN: ( n -- )
caretLoc: ( -- x y ) Returns the (window-relative) coordinates of the caret position
caretIntoView: ( -- ) Scrolls if necessary so that the caret is in view
key: ( c -- ) Handles a typed key, by passing it to the TextEdit object which will call TEKey
insert: ( addr len -- ) Inserts the passed-in string into the text
$insert: ( ^str -- ) Inserts the active part of the passed-in Sring object
chinsert: ( c -- ) Inserts the passed-in character
cut: ( -- ) Handles a cut operation. The TextEdit object will call TECut
copy: ( -- ) Handles a copy operation
paste: ( -- ) Handles a paste operation
clear: ( -- ) Handles a clear operation
clearAll: ( -- ) Clears all the text
>font: ( font# -- ) Sets the font of the text to the font whose resource ID is passed in
>fontSize: ( n -- ) Sets the point size of the text to the passed-in value
>color: ( red green blue -- ) Sets the color of the text to the passed-in (red, green, blue) values. These are all values from 0 to 32767
>style: ( n -- ) Sets the style of the text. n is a ‘style’ byte as defined in Inside Macintosh.

styled_TEScroller


styled_TEScroller is a subclass of TEScroller, whose only variation is that the flag is set in the TextEdit record which makes it ‘styled’. This means that the text can have multiple fonts, styles, etc. When the font, etc. is changed, only the selected text is changed (or, if there's no selection, the change applies to whatever text is subsequently typed).


Superclass TEScroller
Source file TEScroller
Status Optional
Instance variables None (see TEScroller)
Indexed data None
System objects


Inherits: TEScroller, Scroller, View, Object


TEView


TEView is a simple non-scrolling TextEdit view. It has some code lifted from TEScroller, but is much simpler. The methods are basically the same as in TEScroller, except that the scrolling-related methods are missing. We'll therefore omit a full listing.


Superclass View
Source file TEView
Status Optional
Instance variables
Classs Name description
TextEdit theTE  
Indexed data None


Inherits: View, Object



Windows Classes Menus
  Documentation