Reference 11

From PowerMops
Jump to: navigation, search


Coding V. 5.1 and Later

Introduction

The reason for this document is that Mops has undergone some significant evolution since the last edition of the full Manual which was done for Mops version 4.0. A full Manual update will take a while, so in the meantime there's a need to provide proper documentation of the changes to the Mops system which have occurred since the 4.0 release.

Carbon

In the Apple world, ‘Carbon’ is the name given to a new set of conventions for doing system calls—the “Application Program Interface” or API. Basically, the reason for Carbon is OSX. This is really a completely new Operating System with its own API. However, completely rewriting ‘classic’ Mac applications would have been a lost cause, so Carbon provides a solution. It does this in two ways. Firstly, it provides a new API which is sufficiently similar to the classic Mac OS API that older applications can be converted to run under it without a huge amount of work (in theory at least”see below). Secondly, it provides an implementation via the shared library CarbonLib, that runs on both OSX and OS9 (and even later versions of OS8). Thus applications that have been converted to run under Carbon (i.e. ‘Carbonized’), will run natively under both OS9 and OSX.

Now I did use the phrase “without a huge amount of work”, but having Carbonized Mops, I can only say that this is somewhat debatable! Still, the hope is that the impact on Mops source code will be minimal. Most of the changes are in the internals of different classes, and if your code hasn't been making too many assumptions about how classes are implemented, moving to Carbon Mops should be fairly painless.

An example will make this clearer. Under the classic Mac API, a Window is represented in memory as a block of information which has a Grafport as its first section. The details of both the Grafport and Window data have been documented by Apple in the early Inside Macintosh editions, and programs could freely make use of this information—and indeed, needed to in order to perform normal user interface functions.

Under OSX, however, programs don't need to know anything about the internals of windows or Grafports, and in fact these internals are no longer publicly documented. This allows Apple the freedom to implement enhancements in future, making whatever changes to the internal structures that might be necessary. Therefore, under Carbon, a Window is something that is represented to the program as a “window reference” or WindowRef. (Don't confuse this use of the word ‘reference’ to Mops references, which are a kind of pointer to an object.) We aren't allowed to know anything more about what a WindowRef is — it's just a 32-bit quantity. Any operations we want to perform on Windows are provided under Carbon by API calls which take a WindowRef as one of their parameters.

However, Mops programs using Window objects don't normally need to know anything about how the windows are implemented internally, and as long as your code just calls the usual methods to manipulate windows, the Carbonization changes won't affect your code in any way.

In moving to Carbon, however, there are a few changes that may affect your code. One obvious change is that Standard File doesn't exist any more, and has been replaced by Navigation Services Manager support. (See the file ‘Nav’ in ‘PPC Source’.) This is still rather preliminary, but provides the basic functionality we need. Thanks to Gorazd Krosl for this.

Another significant change is that TextEdit doesn't run reliably under OSX, so we now have a MLTE class (Multilingual Text Engine). Apple intends MLTE to replace TE. One immediate advantage is that the Mops editing window is no longer limited to 32k of text.

Another change is to callbacks. These have always been nasty, and have proved so again. On the PowerPC, to pass a callback to a system call, we have to use a UPP. Pre-Carbon, there was a generic NewRoutineDescriptor call which we could use for all callbacks, and our :PPC_ENTRY syntax was based on this mechanism. However, under Carbon, NewRoutineDescriptor has gone away, and we have to use calls NewxxxUPP and DisposexxxUPP (in which xxx is a name which is specific to the particular callback we're doing.)

This has forced a new callback syntax, :CALLBACK and ;CALLBACK. You have to push the addresses of the NewxxxUPP and DisposexxxUPP syscalls before :CALLBACK. See the file ‘CarbonEvents’ for more comments and some actual examples you can copy.

Changed Classes

The following classes are those that have needed significant changes with Carbonization. The following descriptions should be read in place of the descriptions in Part III of the manual.

The intent has always been to minimize the impact on existing Mops programs, and hopefully we have achieved this. By far the majority of changes are in the internal implementation details; the actual methods and their parameters and results are by and large unchanged. The biggest changes are in Event handling.

Window

Window is the basic class of windows without controls:

Superclass Object
Source file zWindowMod.txt
Status Core

Carbon Changes

Windows are no longer subclassed from GrafPort. The first ivar is theWindowRef, which is a (MacOS) WindowRef for this window. To obtain the window's GrafPort, call the method getPort:.

The other significant change is that the old ProcID parameter which was passed to the New: method is now obsolete, so we've replaced it with the (32-bit) attribute flags value. The new Carbon window attributes are many and varied, and are all described in Apple's Carbon documentation. To make things easier, we have redefined the old ProcID constants such as DocWind, to the appropriate attributes value. Thus calling New: with DocWind as the fourth parameter, will have the same effect as before, and create a generic document-style window.

Instance variables
var theWindowRef Window reference”under Carbon this is opaque
rect PortRect a local copy of window's portRect”also used to tell if the window's size has changed when we get a bounds changed event
rect contRect The rectangle defining the content region
rect growRect Contains the window's current grow limits
rect dragRect Contains the window's current drag limits
ool growFlg True if the window is growable
bool dragFlg True if the window is draggable
bool Alive True if the window is alive in the Toolbox
var Attributes Carbon window attributes
bool ScrollFlg True if window contents are to be scrollable
bool Color? True if this is a color grafPort
x-addr Idle The window's idle event action vector
x-addr Deact The window's deactivate event action vector
x-addr Content The window's content click action vector
x-addr Draw The window's update event action vector
x-addr Enact The window's activate event action vector
x-addr Close The window's close box action vector
int ResID Resource id for GetNewWindow
bool ClipGrowLeft True if you want to not outline unused VScroll
bool ClipGrowTop Ditto for unused HScroll
rect thefprect Temporary storage to save fpRect over a Draw: ptr
^view_in_focus Points to view which gets keys etc


Indexed data
None
System objects
fWind The Mops system window used by the nucleus.


Methods
setting characteristics
SetLimits: ( -- ) Sets GrowRect and DragRect to reasonable default values according to the current screen size at the time the grow or drag is done
setContRect: ( -- ) Sets the content rectangle after the window has been resized. Also sets Mops's scrolling rectangle, used byCR, equal to the content rectangle
SetColor: (b -- ) Sets the flag for whether the window is to be a color grafPort or a B&W one. Must be used before the window is created
SetClipGrowLeft: (b --)
SetClipGrowTop: (b --) A pair of methods for setting the ClipGrow flags in the ivar list
setGrow: ( l t r b T or F -- ) Sets the window's grow limits. The old action was that if the boolean was true, the rectangle coordinates deter-mined the mini-mum and maximum x and y values that the window could be grown. However the current action is to ignore these coordinates and use a SCREENBITS call instead. If the boolean is false, the window will not be growable
setDrag: ( l t r b T or F -- ) Sets the window's drag limits. The old action was that if the boolean was true, the rectangle coordinates deter-mined the mini-mum and maximum x and y values that the window could be dragged. However the current action is to ignore these coordinates and use a SCREENBITS call instead. If the boolean is false, the window will not be draggable
setScroll ( b -- ) The passed-in boolean indicates whether scrolling is enabled for this window or not. This is primarily intended for the Mops win-dow fWind, which supports scrolling text, and uses the temporary rectangle fpRect for this purpose. If a window doesn't support scrolling, then fpRect won't be altered when that window is active, so you can use it for your own purposes without conflict. Note however, that the ˜proper' way to support scrolling text is via a Scroller view within a Window+
setIdle: ( xt -- ) Sets the word which will execute in response to idle messages to the window
set: ( -- ) Makes this window the current grafPort
select: ( -- ) Makes this window the frontmost, active window
size: ( w h -- ) Sets the dimensions of the window to the given width and height, without moving the window's upper-left corner
setSize: ( w h -- ) The same as size:”this is for naming consistency with Rects and Views
move: ( x y -- ) Moves the upper-left corner of the window to global coordinates x and y without changing its size
center: ( -- ) Centers the window on the screen
show: ( -- ) Calls ShowWindow to make the window visible
hide: ( -- ) Calls HideWindow to make the window invisible
actions: ( close enact draw
content 4 -- )
Sets action vectors with the xts provided. We require an xt count (4 in this case) as this is standard for all actions: methods
setAct: ( enact deact -- ) Sets the activate and deactivate vectors with the xts provided
setDraw: ( drawXt -- ) Sets only the Draw action vector
title: ( addr len -- ) Sets the title of the window to the passed-in string
name: ( addr len -- ) An alias for title: (above)
putRect: ( -- l t r b ) Sets the window's port rectangle coordinates. This and GetRect: are actually methods of the superclass GrafPort
querying
getName: ( -- addr len ) Returns the window's title string
getRect: ( -- l t r b ) Returns the window's port rectangle coordinates
getPort: ( -- portAddr ) Under Carbon , windows aren't GrafPorts any more, so this method returns the port for this window
getVSRect: ( -- l t r b ) Returns the window's default vertical scroll bar rectangle coordi-nates. (Does not require a scroll bar to be present, but if it were, this is where it would be)
getHSRect: ( -- l t r b ) Returns the window's default horizontal scroll bar rectangle coordinates
maxX: ( -- x ) Returns the x coordinate value which the top left corner of the window would have if the window were to be moved all the way to the right of the current screen (so the window's right hand edge would coincide with the right of the screen). Thus it is the maximum x coordinate value which the window could have without being in any way obscured. Doesn't actually move the window
maxY: ( -- y ) Likewise, returns the y coordinate value which the top left corner of the window would have if the window were to be moved all the way to the bottom of the current screen
active: ( -- b ) Returns true if the window is currently active
alive: ( -- b ) Returns true if the window is currently alive in the Toolbox
event handling
draw: ( -- ) This method is executed when an update event occurs for the win-dow. If the win-dow is growable, a grow icon is drawn with scroll bar delimiters. The window's Draw action vector is executed
idle: ( -- ) This method may be used for background processing. Whenever fEvent gets a null event out of the event queue (for instance, while waiting for the user to type a character) a late-bound idle: message is sent to the front (active) window. That win-dow's idle: method can then do any background processing necessary (such as updat-ing a clock picture). The idle method defaults to a do-nothing method in class Window, and should be kept short enough to keep from bogging down responsive-ness to user input
enable: ( -- ) This method is executed when an activate event occurs for the win-dow. The win-dow's Enact action vector is executed
disable: ( -- ) This method is executed when a deactivate event occurs for the window. Does nothing in class Window
update: ( -- ) Forces an update event to occur that will redraw the entire window. The window will not actually be redrawn until KEY is called and event handling is active
close: ( -- ) This method is executed when the user clicks the window's close box. The window's Close action vector is executed, and the Mac API call DisposeWindow is called
release: ( -- ) The same as close:”this is our standard destructor name
drag: ( -- ) This method is executed when a mouse-down event occurs in the window's drag region. The Toolbox is called to pull a gray outline around with the mouse. If inac-tive, the window is made active after dragging
zoom: ( part -- ) This method is executed in response to a click in the zoom box. part is supplied by the system when the Event code calls FindWindow”it will be 7 if the window is to be zoomed in, or 8 if it is to be zoomed out. Note that although this method is included in class Window, the remainder of zoomable window support is in class Window+, so a zoomable window should therefore be a Window+
grow: ( -- ) This method is executed when a mouse-down event occurs in the window's grow region. The Toolbox is called to pull a gray out-line around with the mouse. If inactive, the window is made active after growing
content: ( -- ) This method is executed when a mouse-down event occurs in the window's content region. The window's Content action vector is executed
key: ( c -- ) Called when a key is typed and this window is active. Here in class Window, we simply drop the key. In the subclass Window+, the key is sent to the view which is ˜in focus'”i.e. the view pointed to by the ^view_in_focus ivar
initialization
classinit: ( -- ) All objects of class Window are initially set to non-growable, draggable windows with null action vectors
runtime control
new: ( ^rect tAddr
tLen attrsvisible
goAway -- )
Calls the Toolbox to create a new window using this object's data as the window record. STACKeters determine the window's bounds in global coordinates, the title, the attribute flags (giving the window type), and whether it is visible and has a close box
getNew: ( resID -- ) Same as new:, but uses the resource template with resource id resID
test: ( -- ) Creates a test object of class Window
Error messages
None

Reference 10 Reference Reference 12
Documentation