Classes 6
Contents
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.
Mops: | Windows |
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 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Indexed data | None | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||
System objects | None |
Inherits: | Object |
---|
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 | ||||||||||||||||||||||
| ||||||||||||||||||||||
Indexed data | None | |||||||||||||||||||||
System objects | None |
Inherits: | View, Object |
---|
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 |
---|
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 |
---|
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 | ||||||||||||||||||||||
| ||||||||||||||||||||||
Indexed data | None | |||||||||||||||||||||
System objects | None |
Inherits: | Control, View, Object |
---|
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 | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| ||||||||||||||||||||||||||||||||||||||||||||||||||||
Indexed data | None | |||||||||||||||||||||||||||||||||||||||||||||||||||
System objects | None |
Inherits: | View, Object |
---|
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 ‘deprecceted’ 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 | |||||||||||||||||||
| |||||||||||||||||||
Indexed data | None |
Inherits: | Scroller, View, Object |
---|
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 | |||||||
| |||||||
Indexed data | None |
Inherits: | View, Object |
---|
Windows | Classes | |
Documentation |