previous chapter contents
page top
page next chapter

Viewable

April 5, 1992last updated August 28, 1994

Defined in Viewable.Def
Abstract
Inherits from Linkable



Class Description

Class Viewable provides the fundamental behavior for all objects that are displayed on the screen. Viewable is an abstract class, so you'll never create or encounter any objects of this class. Instead, you'll use objects that come from subclasses of this class.

Remember that if the documentation and the software (especially the definition files) disagree, always trust the software.


Programming Information

Instantiate: neverSubclass: rarelyCall its methods: often

Class Viewable provides the fundamental behavior for objects that are displayed on the screen. Viewable is an abstract class, so you'll never create or see any objects of this class. Instead, you'll use objects that come from concrete subclasses of this class, such as Box, Coupon, Card, and so on.

Viewable is one of the most important classes in the system. Every item that appears on the screen is a member of a subclass of Viewable. Magic Cap defines a large number of classes that are subclasses of Viewable. Because of these, when you want to create a new class of objects that will be visible on the screen, you'll probably create a subclass of one of the many built-in subclasses of Viewable, rather than creating a subclass of Viewable directly.

Description Of Fields

Class Viewable defines the following fields:

Field Type Description
Inherited from SingleLinkable
next Object Next item in view list
Inherited from Linkable
previous Object Previous item in view list
Defined by Viewable
superview Viewable Container for this object
subview Viewable First object contained by this object
relativeOrigin Dot Origin relative to superview
contentSize Dot Size of content rectangle
viewFlags Unsigned Property settings
labelStyle TextStyle Text style of viewable's label
color Unsigned Color of viewable's content
altColor Unsigned Alternative color (used only by Control and DrawShadowedImage)
shadow Shadow Shadow drawn with object
sound Sound Sound associated with object

Description Of Methods

Viewable has a lot of methods--many more than any other class. The tables below list all of its methods, grouped by general topic. The method description section of this chapter gives more detail about the methods you might call or override. For your convenience, the method description section lists methods in the same order as this table.


Object Management

These methods are overrides of methods inherited from class Object.

Method Description
Init Initialize view system and set up globals
Install Initialize the view cache and the screen box
Copy Copy the object and objects it refers to
EachReference Check each subview in addition to calling inherited method
DestroyContents Call destroysubviews
Stabilize Stabilize all the subviews of the viewable
MakeValid Get rid of first subviews so they don't alias later on


Drawing

These methods control how the viewable item is drawn. You will override several of these methods when you subclass Viewable.

Method Description
Drawing The Viewable
Draw Draw the viewable
DrawAutoCopy Draw the "shadow" image (called by DrawWithLabel)
DrawWithLabel Draw label and call draw
DrawWithContents Draw viewable and contents (uses DrawWithLabel)
Render Create an image of the viewable for printing or faxing (used by RenderIntoPage)
RenderIntoPage Split into pages and add headers and footers for printing or faxing (called by the render server)
Content Boxes
ContentSize Return the size of this viewable
SetContentSize Set the size of this viewable
ContentHeight Get the height of the viewable
ContentWidth Get the width of the viewable
ContentBox Get a box that describes viewable's contents
SetContentBox Set the viewable's content box
CalcContentBox Compute a content box for the viewable
ScrolledContentBox Get virtual bounding box of viewable, including amount of scroll
ContentPath Get a path that describes viewable's contents
AdjustSize Recalculate the viewable's content box
MustAdjustContainerSizeFirst Test if the viewable's size depends on its container's size in some way; returns false by default
KeepOnScreen Move viewable entirely onto screen if any part is off
More Boxes
BorderBox Get outer edge of the viewable's border
CalcBorderBox Compute box outset from content for framing and adornment
BoundsBox Get the box that describes the viewable's bounds
CalcBoundsBox Compute a bounds box for the viewable by finding the box that holds content + shadow + label
BoundsPath Return in the border parameter a path describing content + border + label if viewable is visible
OpaqueBox Return box for part of viewable that is opaque
CalcOpaqueBox Override to specify what part of viewable is opaque
Clipping
ClipPath Get a path that describes clipped viewable
Clipped Test if the given box is clipped by superviews or subviews
Getting And Setting Origins
RelativeOrigin Return the origin of this view relative to the origin of the superview
SetRelativeOrigin Set the origin of this view relative to the origin of the superview then redraw
Origin Return the origin of this view (computed from RelativeOrigin)
SetOrigin Set the origin of this view


Redrawing

Class Viewable defines a number of methods which manage redrawing objects that have changed or been obscured in some way. Three methods that you will probably call often are DirtyHide, DirtyShow, and DirtyBounds. You'll want to read the full discussion of those methods.

Method Description
RedrawNow Do all pending redrawing now
RedrawNowWithEffect Redraw with a visual effect
RedrawNowOffscreen Do all pending redrawing off-screen only (please don't use this method--it might vanish)
DontDirty Don't bother to mark anything dirty in any future methods that affect viewables
DoDirty Okay to dirty again
ShouldDirty Return true if viewable methods should pay attention to optional dirtying
ResetDirty Reset dirty disable count to 0, thus closing all dontdirty calls
DirtyContent Request a redraw of the content of this viewable
DirtyBox Request a redraw for a specific box within this viewable
ConsiderDirtyBox A framework routine used by DirtyBox, DirtyBounds, and DirtyContent
DirtyBounds Request a redraw of all of this viewable
DirtyHide Request a redraw of everything behind this viewable
DirtyShow Request a redraw to make this viewable appear (call on something not yet shown on the screen)
DirtyAll Request a redraw of all viewables; clears the viewable cache
DirtyOffscreen Invalidate any cached bits in the topmost viewable of off screen hierarchy
RevealBehind If you do any bit caching behind your viewable, call this when disappearing
SetUpBufferDrawing Turn on buffered drawing
CopyBufferToScreen Copy a buffer to the screen
CaptureScreen Framework routine used in redrawing
RestoreScreen Framework routine used in redrawing
SubviewOriginChanged Update bounds cache for subviews
BoundsChanged Invalidate bounds cache


Drawing Components Of The Viewable

These methods draw various pieces of the viewable object, such as any images associated with it, shadows, and highlights.

Method Description
Balloons And Spouts
BalloonDot Put the viewable's origin into balloonDot
BalloonColor Get the color that the balloon spout should be by looking at where it spouts from
Drawing Images
DrawShadowedImage Draw the viewable's image and shadow
Image Get the viewable's image
SetImage Set the viewable's image
ImageOrigin Get the place where the image should be drawn
ImageBox Get the box where the image should be drawn
InsideImage Test whether dot is in image, shadow, or neither
ApplyImage Apply a new image to the viewable
FinePointing Return the value of the fine pointing view flag
Drawing Shadows
Shadow Get the viewable's shadow
ShadowOffset Get the offset of viewable's shadow from viewable
Growing Cards
CanExtendBottom Inquire whether a viewable's bottom should be lowered when growing a card
ExtendBottom Lower the bottom of viewable and subviews (as when growing a card)
ExtendBottomOne Lower the bottom of this viewable only (called from extendbottom)
ExtendBottomOfSubviews Lower the bottom of subviews (called from extendbottom)
Part Colors
PartColor Get color object for part of the viewable
SetPartColor Set the color for part of the viewable
CanBeTransparent Test whether the viewable can accept a transparent color coupon (returns false by default)
Highlighting
HiliteOrigin Put the viewable's origin into hiliteorigin
HiliteForErase Highlight a viewable before it's deleted
Disabled Test whether the viewable is disabled
Hilited Test whether the viewable is highlighted
SetHilited Set whether the viewable is highlighted
ContentsCanHilite,
SetContentsCanHilite
Return true if the viewable's contents can highlight
Orientation
Orientation Get the viewable's rotation orientation
ChangeOrientation Change the viewable's rotation orientation


Managing the view hierarchy

These methods control and get information about the view hierarchy.

Method Description
Superviews
OnScreen Test whether the viewable is in the view list
Superview Get the viewable's container
SetSuperview Set the viewable's container
IsSubviewOf Test if viewable is a subview of candidatesuperview
SwitchContainer Remove viewable from current superview and put it in a new container
Unlink Detach viewable and all of its subviews from its superview
SendToBack Make the viewable the rearmost subview
BringToFront Make the viewable the frontmost subview
CanBringToFront Test if the viewable can come to the front during dragging
HealSystem Fix up the viewable chain after an error
InvalViewCache Reset the view cache
EnclosingCard Call to find card that is this viewable or a superview of this viewable (if
any)
EnclosingScene Call to find scene that is this viewable or a superview of this viewable (if
any)
EnclosingWindow Call to find window that is this viewable or a superview of this viewable
(if any)
Subviews
FirstSubview Get the viewable's rearmost subview
SetFirstSubview Set the viewable's rearmost subview, changing its subview field appropriately
SetSubview Set the viewable's rearmost subview
EachSubview Call a function for every subview of the viewable and the subviews' subviews
ShallowEachSubview Call to invoke a routine repeatedly for every subview of this viewable
Empty Return true if viewable has no subviews
DestroySubviews Call destroy on all of this viewable's subviews
Erasing
Erase Destroy all subviews of the viewable
EraseRecent Erase the most recent subview; erase all subviews if the option key is
down
ErasablePiece Break off and return the most recent piece for erasing (normally this
viewable)
Changing Visibility
Visible Test whether the viewable is visible
SetVisible Set the viewable's visibility status
ShowSubviews Set subview and its peers to visible; does not affect subviews


Labels And Text

These methods affect the viewable's label and text data.

Method Description
Manipulating Labels
Label Get the viewable's name as displayed in its label
LabelBox Get the box that encloses the viewable's label
CalcLabelBox Compute the label's box for standard positions; return whether label
should be clipped to this box
LabelLoc Get the location of the viewable's label
ShowLabel Test whether viewable's label is shown
CanShowLabel Test whether viewable's label can be shown
BorderLabel Return true if label is bordered by testing a view flag
SetUseScriptName Use or don't use script name for label (sets view flag)
SetName Set the viewable's name to the given string
Manipulating Text And Names
SetTextData Call to set the viewable's label to the given text
ContentTextStyle Get the text style of the viewable's contents
TextStyle Get the text style of the viewable's label
SetTextStyle Set the label's text style
Searching
MatchText Check for the given string in viewable's subviews
MatchViewable Find a given viewable in the viewable's subviews
SearchFor Search for text, an image, or a viewable
Searchable Return true if it's useful to search this viewable


Playing Sounds

Class Viewable defines these methods for controlling the sound that's played when the viewable is touched.

Method Description
Sound Get the viewable's sound
PlaySound Play the viewable's sound
PlaySoundWithDefault Play viewable's sound or a default sound if it doesn't have one


Idling, Notifying, And Timing

These methods control periodic work done by the viewable, or actions that depend on other actions.

Method Description
Performing Periodic Work
Idle Called when system is at idle, also sends idle to subviews
SoonerIdle Return sooner of two idle intervals
Notifying
AboutToShow Do any necessary preparation before viewable appears on screen
AboutToHide Do any necessary preparation before this viewable disappears from screen
TimedAction Do something at date/time of datebook appointment that this is attached to
Confirm Do something with pending changes
Confirmed
Returning Returning via stepback
ValueChangeNotice Do something when a switch subview's value changes
SetAuthoringMode Do something when user level changes
InstallInto Install a new subview into the viewable, updating the package install list
RemoveFromSystem Remove an object


Hit Testing

These methods allow viewable objects to control how they're touched.

Method Description
HitTest Test everything on the screen for a hit
ConstrainHit Constrain hits
InsidePart Test whether the given dot is inside the viewable
CalcInsidePart Return which part of the viewable the given dot is inside


Touching

Viewable objects, since they're on the screen, are often touched by the user. These methods control how the viewable responds when it's touched in various ways.

Method Description
FlushTouches Set a flag to throw away touches at next redraw
ConstrainToolTarget Allow viewables to alter touch behavior to handle viewables that refuse drawing and autodrawable viewables
MustTrack Test whether an object can be dragged in the MagicWindow instead of magically dropping
IsWritingTool Return false; allows viewables to be used as tools
TouchKind Classify a touch as tap, press, or don't know
WaitTouchKind Classify a touch as tap or press by waiting until it's possible to know
TapPressCriteria Get criteria for distinguishing tap/press
Touch Send touch if tool is touch tool; call tap, touching, touched, and press when appropriate
Touching Called repeatedly while user is touching
Action Called when action should happen, same as touched if still inside viewable
Tap Called if user taps
Press Called if user presses
Pressing Called repeatedly while user is pressing
Pressed Called after user releases a press
Untouchable Find out if viewable is disabled (that is, can't be touched)
TapCenter Tap in center of viewable (usually called from magic scripts)
TapHere Tap a particular location on viewable (usually called from magic scripts)
ArrowState Get 4 booleans corresponding to 'can scroll' in 4 directions


Moving, Copying, And Stretching

These methods control how the viewable is moved, copied, and stretched.

Method Description
Moving And Copying
MoveTouch Handle a touch with the move tool
MovePress Handle a press with the move tool
CopyTouch Handle a touch with the copy tool, chooses between press and tap
CopyPress Handle a press with the copy tool
DragTrack Track the user's action while dragging a viewable, thus doing the actual moving or copying of a viewable
ConstrainMove Limit how the viewable moves
DontCopyToPackage If set, leave this viewable in the system when the user drops it in a package
DragAsGhost Return whether object should be drawn semi-transparent during dragging
CanMove Test whether viewable can be moved
AutoMove Test whether viewable can be moved without the move tool
CanCopy Test whether viewable can be copied by checking view flag
AutoCopy Test whether viewable copies itself without the copy tool by checking view flag
CanDelete Test whether viewable can be thrown away by checking view flag
CanDragContents Test whether viewable's contents can be moved by checking view flag
CanPlaceOnLockedCard Test whether viewable can be placed on a card even though it's locked
AllowedToLeaveScene Test whether viewable can leave the scene it's in
Stretching
StretchTouch Touch a viewable with the stretch tool
StretchPress Press a viewable with the stretch tool
StretchTrack Do actual stretching of a viewable
CanStretch Test whether the viewable can be stretched
Centered Return the value of the centered view flag
ConstrainSize Constrain the size to the minimum and maximum allowed (12 to 1024 by default)


Tinkering And Scripting

Class Viewable defines these methods for tinkering and scripting viewable objects.

Method Description
Tinker Show a tinker window for the viewable
OpeningTinkerWindow Call after opening a tinker window
ClosingTinkerWindow Call before closing a tinker window; updates script from coupon
MakeTinkerControl Make a control for a viewable's attribute for display in a tinker window
MakeTinkerCoupon Make a coupon from a coupon object for display in a tinker window
Scripting
SetScript Set the viewable's script


Dropping And Swallowing

These methods control whether the viewable can be dropped, can have objects dropped into it, can be swallowed, or can swallow other objects. ("Swallowing" implies digestion: the viewable doesn't simply become the morsel's new superview, but processes the morsel in some manner that you define.)

Method Description
AvoidOverlap Reposition viewable to avoid overlapping siblings
CanAccept Test whether candidate can be a subview of this viewable; return true if CanContain is true
AcceptCouponInForm Test whether coupons dropped on forms should be accepted without confirmation; returns false by default
CanContain Test whether viewable can have subviews by checking view flag
CanAcceptCoupon Test whether viewable can accept a coupon
CanBeSwallowed Test whether viewable can be swallowed
DroppedFromWindow Called after an object is dropped from the magic hat
Swallow Make viewable try to swallow a morsel
SwallowFeedback Indicate willingness to swallow a morsel
CanChangeContainers Test whether viewable can move to a new superview
ChangedContainers Do something when viewable changes superviews
ChangedContents Do something when objects move in or out
MovedContents Do something when viewable's contents move
AttachmentPosition Calculate location to put attachment as subview
FindContainerPosition Calculate unoccupied position in container
Hop Animate viewable to end position
HopFancy Animate viewable to end position with control over speed and acceleration
HopToViewable Animate viewable to position of another viewable
HopToToteBag Animate viewable into satchel gadget
HopToTrash Animate viewable into trash gadget
PutAway Call put away on each immediate subview; or put away the current viewable


Typing And Scribbling

Class Viewable defines three methods that affect typing and scribbling on viewable objects.

Method Description
TypeKeys Simulate typing characters if subclass accepts typing; return number of characters accepted
CanDrawIn Test whether scribble can be drawn inside the viewable
EraseParts Allow eraser tool to erase portions of this viewable, returning true if any part of the viewable was really erased


Selecting

These methods control how selections are manipulated and displayed.

Method Description
Selected Get the viewable's selection
SelectFirstTextField Return activated text field if your subclass has editable text
SelectNextTextField Return activated text field after currentfield if your class has multiple fields
ActivateForTyping Activate the frontmost textfield subview, returning true if successful
PositionCursor Returns cursor's position and whether we should leave viewable
RevealSelection Make viewable selection visible


Manipulating Entities

An "entity" is a person (or rather, the address card connected to the person) associated with an object in some way. For example, the entity associated with a telecard is the card's sender. The entity associated with the system is the current user. If your viewable subclass has the concept of entities associated with its objects, you should override these methods.

Method Description
Entity Get the viewable's entity
SetEntity Set the viewable's entity

Methods You Might Override

Whenever you create a subclass of class Viewable, you should override the following methods:

Method Description
Draw Draw the viewable on the screen

Class Viewable defines many methods that it doesn't implement itself, but that its subclasses might need to implement. Also, the default behavior of some of class Viewable's methods might not suit all subclasses. The table below lists, in alphabetical order, methods that you might override under the described circumstances. This list probably isn't complete, though it does mention the methods you'll override most often. Feel free to override other methods when you need to.

Method When to override
AutoMove To allow viewables of your subclass to be moved without the move tool
AboutToHide To do something just before this viewable disappears from screen
AboutToShow To do something just before this viewable appears on screen
AdjustSize To allow your class to adjust its size to fit its content or some other criteria
CalcLabelBox If your subclass defines nonstandard label positions
CalcInsidePart If your subclass has subpieces other than label and content
CanAccept To use custom tests when deciding to accept
CanAcceptCoupon To change which coupons are accepted by your subclass
CanBringToFront To prevent viewables from coming to the front
CanChangeContainers To restrict viewables from changing superviews
CanContain To use other tests when deciding to contain
CanCopy If viewables of your class can never be copied
CanMove If viewables of your class can never be moved
CanShowLabel If labels are never shown by your subclass
ChangedContainers To perform action when changing superviews
ChangedContents To perform action when subviews are changed
Closing To perform action when a window closes
ClosingTinkerWindow If your subclass defers accepting changes from any controls
Confirm If there is pending data to be processed, accept it in confirm
Confirmed
ConstrainHits To constrain hits on viewables of your subclass
ConstrainSize To customize constraint for viewables of your class
ConstrainToolTarget To add constraints to the existing tool target constraints
ContentsCanHilite If the contents of your viewable can't highlight
CopyPress To perform action when pressed with copy tool
CopyTouch To perform action when touched with copy tool
DroppedFromWindow To do something special when a viewable is dropped from the magic hat
Entity If viewables of your class have entities
EraseParts Do nothing by default; override to allow eraser tool to erase portions of this viewable; returns true if any part of the viewable was really erased
ExtendBottom To perform some action when bottom expands
FinePointing If viewable of your class use masks for hit-testing
Idle To perform some action when system is idle
Image To return the viewable's image, if objects of your class have images
Label To customize technique for setting label's text
MatchText If viewables of your class contain searchable text
MatchViewable To customize criteria for matching viewables
MovedContents To do something when a viewable's contents move
MovePress To perform action when pressed with move tool
MoveTouch To perform action when touched with move tool
Opening To perform action when a window or another object opens
OpeningTinkerWindow Call after opening a tinker window; override to put in controls appropriate for your subclass
PartColor If your class defines new parts with color
Press To perform some action when pressed
RevealSelection Override to make viewable selection visible (possibly by scrolling or expanding)
Searchable Return true if it's useful to search this viewable
Selected To return the selected object if viewables of your class have selections
SelectFirstTextField To return activated text field if your subclass has editable text
SelectNextTextField To return activated text field after currentfield if your subclass has multiple fields
SetAuthoringMode If your subclass should do something when user level changes
SetContentBox To perform some action when box is changed
SetEntity If viewables of your class have entities
SetImage If your class's viewables have an image
SetPartColor If your class defines new parts with color
SetTextData If your class's viewables have text data
SetTextStyle If your class's viewables have text data
StretchPress To perform action when pressed with stretch tool
StretchTouch To perform action when touched with stretch tool
Swallow If viewables of your class ever swallow objects
SwallowFeedback To indicate willingness to swallow a morsel
TimedAction To do something at date/time of datebook appointment that this is attached to
TypeKeys To simulate typing characters if your subclass accepts typing
Validate To perform additional validity checking
ValueChangeNotice To do something when a switch subview's value changes

Constants Used with Viewable Objects

This section lists two sets of Viewable constants: the view flags and the part codes. There are other sets of constants that are used with specific methods of class Viewable. These constants are introduced in the sections that describe the methods that use them.


View flags

Class Viewable defines a number of flags that control various aspects of viewable objects. These flags are stored in the viewFlags field. They are listed below, along with the methods that use them.

hilited

#define hilitedMask  0x80000000  

Set this flag if your viewable object is highlighted. Highlitghted objects are drawn with inverted images and labels. This flag is checked and set by the Hilited and SetHilited methods.

canMove

#define canMoveMask  0x40000000  

Set this flag if users can move your viewable object using the move tool. The CanMove method checks and the SetCanMove method sets this flag.

canStretch

#define canStretchMask  0x20000000  

Set this flag if users can stretch your viewable object using the stretch tool. The CanStretch and SetCanStretch methods use this flag.

visible

#define visibleMask  0x10000000  

Set this flag if your viewable object should be visible. The Visible and SetVisible methods use this flag.

centered

#define centeredMask  0x08000000  

Set this flag if your object should be stretched from its center. The Centered and SetCentered methods use this flag.

untouchable

#define untouchableMask  0x01000000  

Set this flag if your viewable object should be untouchable, that is, untracked by the default Tap and Touch methods. The Untouchable method returns true if this flag is set.

autoCopy

#define autoCopyMask  0x00800000  

Set this flag if your viewable object should create a copy of itself when the user touches it. The AutoCopy and SetAutoCopy methods use this flag.

touchContents

#define touchContentsMask  0x00400000  

Set this flag if a user touch on your viewable object should be a touch on its nearest subview instead. The method ChooseableTool_GetToolTarget uses this flag.

showLabel

#define showLabelMask  0x00100000  

Set this flag if your object's label should be drawn with the object. The ShowLabel and SetShowLabel methods use this flag.

labelLoc

#define labelLocMask  0x000F0000  

The labelLoc mask defines the bits used to store the viewable's label location code. See the discussion of the LabelLoc method in the Methods Description section below for a diagram of label locations.

borderLabel

#define borderLabelMask  0x00008000  

Set this flag if you'd like a border drawn around the label of your viewable object. The BorderLabel method checks and the SetBorderLabel method sets this flag.

canContain

#define canContainMask  0x00004000  

Set this flag if your viewable object can contain other objects. The CanContain and SetCanContain methods use this flag.

useScriptName

#define useScriptNameMask  0x00002000  

Set this flag to use the script name of the object as a label instead the object's name. The Label method checks this flag while constructing a label for the object. The SetUseScriptName method sets and unsets this flag. (Be sure that the viewable has a script before using its script name.)

canCopy

#define canCopyMask  0x00001000  

Set this flag if users should be able to copy your viewable object using the copy tool. The CanCopy and SetCanCopy methods use this flag.

lockContents

#define lockContentsMask  0x00000800  

Set this flag if the contents of your viewable aren't movable without the move tool. (The adjective that describes objects that can be moved without the move tool is "automove.") The CanDragContents and SetCanDragContents methods use this flag.

canDelete

#define canDeleteMask  0x00000200  

Set this flag if your viewable object can be deleted. For some objects, deletion means being dragged into the trash truck by the user. For others, it means being erased with the erase tool (or the erase button). The CanDelete and SetCanDelete methods use this flag.

mustTrack

#define mustTrackMask  0x00000100  

Set this flag for objects that should be tracked instead of copied out of the Magic Hat. For example, stamp drawers shouldn't be treated like stamps: a tap on a stamp drawer shouldn't copy the drawer! Instead, the tap should be tracked like normal, out-of-hat touches. The MustTrack method checks this flag.

disabled

#define disabledMask  0x00000080  

Set this flag if your object should be drawn in a disabled state. You can define how your viewable object should look when it's disabled in your Draw method. The Disabled and SetDisabled methods use this flag.

finePointing

#define finePointingMask  0x00000040

Set this flag to enable fine pointing. When fine pointing is off, user touches inside the image's border box are reported as touches to partImage. Hit-testing thus doesn't respect the shape of a non-rectangular image. When fine pointing is on, Viewable_InsideImage does consider the shape of an image, by attempting to distinguish between touches on the image and touches on the image's shadow. The FinePointing and SetFinePointing methods use this flag.

onScreen

#define onScreenMask  0x00000020

The AboutToShow method sets the on-screen flag and AboutToHide unsets it. As you can imagine, this flag is true when the viewable object is on the screen. (That doesn't mean it's visible, though: it might be obscured by other objects or it might be invisible.) Do not set this flag yourself. Leave it clear in your object definition files. If you set it, AboutToShow might not be called on your object, which might cause you discomfort, dismay, and disappointment. The system sets and unsets this flag automatically.

inAboutToShowinAboutToHide

#define inAboutToShowMask  0x00000010
#define inAboutToHideMask  0x00000008

These two flags are debugging flags used by AboutToShow and AboutToHide. You shouldn't use them.


Part codes

Some viewable methods perform some action on part of the object, such as the border or the label. The system uses integer constants to indicate these various parts of viewable objects, as follows:

/* part codes */
#define partNothing 0  /* outside content */
#define partLabel (-2)
#define partShadow  (-3)
#define partBorder  (-4)
#define partAltBorder (-5)
#define partTitle (-8)
#define partCoupon  (-12)  /* for LabelMaker */
#define partContent  1 /* inside content */
#define partBalloonSpout 2
#define partAltContent 3
#define partLine   5
#define partImage  6
#define partText   7
#define partTextSelection  11

Method Descriptions


Object Management

Init

overrides Init

Call: rarely
Override: often

When a new object is created, the system calls Init to allow the new object to set up its fields. The params parameter points to a structure that's declared like this:

typedef struct
  {
  ObjectID  superview;
  Dot    relativeOrigin;
  } ViewableInitParamsRec, *ViewableInitParamsPtr;

Viewable_Init sets up fields of the new viewable object as follows:

Field Initialized Initial Value
viewFlags Canmovemask | cancopymask | candeletemask | visiblemask
color rgbBlack
altColor rgbWhite
relativeOrigin If params is not nil, params>relativeorigin
superview If params> superview is not nil, params>superview

After setting up these fields, Viewable_Init calls its inherited implementation.

You should override Init if your class defines any fields that should be set up to initial values when a new object is created. See Object_Init for more information.

Copy

overrides Copy

Call: sometimes
Override: rarely

Call Copy to make a copy of the object. Copy also makes copies of all objects referenced by the object's fields (except objects defined as noCopy in the class's definition), then sets the copy's fields to refer to the new objects. Referenced objects defined as noCopy are not copied, and the new object keeps the same references as the original object. The new object is returned as the function result.

The system calls Copy to create a copy of an object. You should override Copy if you want objects of your subclass to perform some additional action when a new copy is created with Copy. Usually, this additional processing involves setting up fields of the newly-created object.

Viewable_Copy sets the newly-created object's superview field to nilObject. You should call the inherited Copy in your overriding method, usually at the beginning, to ensure that your object and the objects it references are copied.

After you call Copy to create a new Viewable object, you might want to call SetSuperview to place the new object in the view list. (If the object isn't on the screen, though, you probably don't want to call SetSuperview.) See the description of SetSuperview for more information.


Version note: If you were relying on Viewable_Copy making new viewables deletable, you should now explicitly call SetCanDelete(newViewable, true) whenever you create a new viewable by copying an existing one. Of course, if the one you copied is already deletable this is not necessary. Viewable_Init makes the new viewable deletable, as always.



Drawing the Viewable

Draw

operation Draw(canvas: Canvas; clip: Path), noMethod

Call: never
Override: almost always

When the system has to draw an object on the screen, it calls the object's Draw method. Viewable_Draw draws the object's label, and the label's frame and highlighting.

You should override Draw for every class you create that's a direct subclass of Viewable. Your overriding method should draw the object. You might not need to override Draw if you're subclassing a subclass of Viewable that already does so. In this case, you should call the inherited Draw from your overriding method to be sure that all elements handled by its superclasses are drawn.

For example, the mixin StarburstHilite overrides draw to draw the starburst image around a highlighted object. It calls its inherited method before doing its own drawing, as follows:

Method void
StarburstHilite_Draw(ObjectID self, 
   ObjectID canvas, ObjectID clip)
{
Boolean hilited = Hilited(self) && UseStarburst(self);
  if (hilited)
  {
  DontDirty();
  SetHilited(self, false);
  DoDirty();
  }
  InheritedDraw(self, canvas, clip);
  if (hilited)
  {
  Dot  origin;
  DontDirty();
  SetHilited(self, true);
  DoDirty();
  HiliteOrigin(self, &origin);
  DrawImage(iStarburst, canvas, clip, &origin);
  }
}

Class Icon inherits from StarburstHilite, but doesn't override Draw itself. So when an icon is drawn, the system calls StarburstHilite_Draw. Class Icon's inherited draw method is Stamp_Draw. So first the icon's image and shadow are drawn by Stamp_Draw, then a highlight is added if necessary by StarburstHilite_Draw.

Notice the DontDirty call in the starburst highlight example. You should also avoid dirtying viewables in your Draw methods.

When your class's implementation of Draw is called, the clipping path might be set to the content rectangle of the object's superview. If Draw is called by the redraw mechanism, the clipping path might be the intersection of the superview's contents and the dirty box. You must be sure to not to draw outside the boundaries of the clipping path passed to Draw.

Here's an example of how you could clip an image to your content box and the clipping path passed to Draw. This code fragment creates a clipping path from the viewable's content box, then draws a clipped image.

Box  content;
Dot  origin;
ObjectID   contentClip;
/* clip our image to content */
ContentBox(self, &content);
contentClip = NewBoxPath(&content);
/* intersect the contentClip with the clip passed to Draw */
SectPath(contentClip, contentClip, clip);
/* get our origin & draw the image there */
Origin(self, &origin);
DrawImage(Image(self), canvas, contentClip, &origin);
/* tidy up by destroying the path */
DestroyPath(contentClip);

You could also use your Draw method to define how your viewable looks when it's disabled.

if (Disabled(self)) {
 /* draw the object in a disabled state */
 return;
 } 

Sometimes you'll want your viewables to highlight when the user is touching them, or when they're active, or when the user has just tapped on them and they're about to perform some action. Icons, for example, highlight when they're tapped. Buttons highlight while they're touched.

You can define how your viewable is highlighted in several ways. Here are examples of two ways to highlight:

The notebook icon uses the starburst highlight. To use the starburst yourself, simply mix in class StarburstHilite with your subclass of Viewable. You don't have to write any code to draw the highlights yourself.

The discard button is a member of class SpecialButton. It does its highlighting itself, in its Draw method. Buttons highlight themselves by using a different image, using code like this:

image = Image(self);
if (Hilited(self))
  nextImage = Next(image);

You could also highlight by drawing your viewable differently. For example, when shapes are highlighted, they are drawn with a thickness one pixel larger than usual. Or you could invert your viewable. Here's an example of how you might do so:

hilited = Hilited(self);
ContentBox(self, &content);
if (hilited)
  {
  hilightBox = content;
  InvertBox(canvas, clip, &hilightBox);
  }

This example inverts the content box of the viewable. You might want to get fancy by inverting pieces of your viewable.

One final word of advice for you as you begin to write your Draw method: don't use Draw to dynamically determine which pieces of your object to draw. You could end up with update problems and incompletely drawn objects. Use Draw to draw the whole object.

DrawWithLabel

operation DrawWithLabel(canvas: Canvas; clip: Path; forRedraw: Boolean; 
first: Boolean;  drewBehind: Boolean)

Call: sometimes
Override: rarely

The system calls DrawWithLabel to draw the viewable and its label. The forRedraw parameter is true if the redrawing mechanism is calling DrawWithLabel.


Managing Content Boxes

ContentSize
SetContentSize

attribute ContentSize: Dot
// operation ContentSize(VAR size: Dot)
// operation SetContentSize(size: Dot)

Call: sometimes
Override: rarely

ContentSize returns in size the value in the contentSize field. size>h is the width of the viewable in microns, and size>v the height. SetContentSize sets the field to size. If the viewable's size has actually changed, it is redrawn the next time drawing takes place.

ContentHeight
SetContentHeight

attribute ContentHeight: Micron
// operation ContentHeight(): Micron
// operation SetContentHeight(newHeight: Micron)

Call: sometimes
Override: rarely

Call ContentHeight to get the height of the object's content box. ContentHeight calls ContentBox, then returns the difference between the bottom and the top of the content box.

Call SetContentHeight to set the height of the object's content box to the given value. The object's upper left and upper right corners remain the same; the bottom is adjusted. If the object's size changes, it is redrawn the next time drawing takes place. SetContentHeight is a convenience routine that uses SetContentSize to change just the vertical component of the viewable's size.

ContentWidth
SetContentWidth

attribute ContentWidth: Micron
// operation ContentWidth(): Micron
// operation SetContentWidth(newWidth: Micron)

Call: sometimes
Override: never

Call ContentWidth to get the width of the object's content box. ContentWidth calls ContentBox, then returns the difference between the right and the left edges of the content box.

Call SetContentWidth to set the width of the object's content box to the given value. The object's upper left and lower left corners remain the same; the right edge is adjusted. If the object's size changes, it is redrawn the next time drawing takes place. SetContentWidth is a convenience routine that uses SetContentSize to change just the horizontal size of the viewable.

ContentBox
SetContentBox

operation ContentBox(VAR content: Box)
operation SetContentBox(content: Box)

Call: often
Override: never

Call ContentBox to get the box that describes the object's content. ContentBox checks to see if the object is already cached by the system; if not, it calls CalcContentBox to compute the object's content.

Call SetContentBox to set the object's content box to the given box. You won't call SetContentBox often.

See the description of Viewable_CalcContentBox for more information.

CalcContentBox

operation CalcContentBox(VAR content: Box)

Call: never
Override: rarely

Call CalcContentBox to compute a viewable's content box. CalcContentBox uses the viewable's origin and content size to calculate the vertices of its content box. The box is returned in the content parameter.

ContentPath

operation ContentPath(content: Object)

Call: rarely
Override: rarely

Call ContentPath to get a path object that describes the contents of the object. ContentPath calls ContentBox to get the object's content box, then calls SetBoxPath to convert the box to a path.

AdjustSize

operation AdjustSize()

Call: sometimes
Override: sometimes

Call AdjustSize to make an object recalculate its content box after you've performed some action that might change the box. Viewable_AdjustSize does nothing. You should override AdjustSize if you need it. For example, class BalloonSpout overrides AdjustSize to check if its spout position dot has moved. If the dot has changed, the spout needs to be redrawn with a new shape and size.

KeepOnScreen

operation KeepOnScreen(), noFail

Call: rarely
Override: rarely

Call KeepOnScreen to move the object entirely onto the screen if any part of it is off the screen. For example, windows call KeepOnScreen before they show themselves to the world, thus ensuring they show all of their gorgeous selves.


Managing Bounds, Border, and Opaque Boxes

BoundsBox

operation BoundsBox(VAR bounds: Box)

Call: sometimes
Override: never

Call BoundsBox to get the smallest box that encloses all the parts of the object that are drawn, including its content, shadow, and label. BoundsBox calls CalcBoundsBox to calculate the object's box. If the object isn't visible, BoundsBox returns the empty box.

BorderBox

operation BorderBox(VAR outsideBorder: Box)

Call: sometimes
Override: rarely

Call BorderBox to get the box that forms the outer edge of the object's border box. Viewable_BorderBox calls CalcBorderBox to perform its action.

OpaqueBox

operation OpaqueBox(VAR opaque: Box)

Call: rarely
Override: never

When the system redraws, it calls OpaqueBox to get the box that describes the opaque area of the object. Objects behind this box don't need to be redrawn. You should not override OpaqueBox to define the opaque areas of your subclass. Instead, use CalcOpaqueBox to do so.

CalcOpaqueBox

operation CalcOpaqueBox(VAR opaque: Box)

Call: rarely
Override: sometimes

You should override CalcOpaqueBox to specify what part of object is opaque (that is, objects behind this box do not show through). Overriding CalcOpaqueBox allows the system to optimize its drawing. If you don't override CalcOpaqueBox, all your drawing will work correctly, but it will take longer than if you provide a version of CalcOpaqueBox. The larger the box you can return from CalcOpaqueBox, the more you can speed up drawing.


Getting Clipping Paths

ClipPath

operation ClipPath(clipping: Object)

Call: sometimes
Override: rarely

Call ClipPath to get a path that describes the object with objects in front of the object removed. This path can then be used for drawing operations that require a path describing the object, such as InvertBox.

See the description of Canvas_InvertBox for more information.


Redrawing the Viewable

The Magic Cap system's redrawing mechanism has two sets of methods: methods that control how objects are marked as dirty (needing redraws), and methods that do the redrawing. In general, you'll call the dirtying methods sometimes, and the redraw methods rarely if ever.

For most changes you make to your viewable objects, you won't need to worry about dirtying. For example, calls like SetOrigin correctly mark the object as dirty for you. If you're subclassing a subclass of Viewable, you're probably inheriting draw methods that handle dirtying correctly. If you are creating a substantially different subclass of class Viewable, though, you might need to start worrying about dirtying. You'll use dirty calls directly if you're drawing new viewable features, moving viewables around, or changing visual aspects of an object without using standard system calls.

RedrawNow

intrinsic RedrawNow; safe; common

Call: sometimes
Override: never

Call RedrawNow to perform all pending redrawing.

RedrawNowWithEffect

intrinsic RedrawNowWithEffect(effect: Unsigned;  effectBox: Box;
frames: Unsigned; delay: Unsigned; modifier: Micron), safe;

Call: rarely
Override: never

Call RedrawNowWithEffect to perform all pending redrawing with a visual effect.

DontDirty
DoDirty

intrinsic DontDirty()
intrinsic DoDirty()

Call: sometimes
Override: never

The DontDirty and DoDirty methods are always called in pairs. They can help you optimize redrawing your object by allowing you to make a number of changes to a viewable then redraw it just once.

Here's an example of a pair of DontDirty/DoDirty calls, used by class ShapeToolButton to draw the current shape as the button's image:

DontDirty();
  Unlink(shape);
  if (hilited) SetHilited(shape, true);
  SetSuperview(shape, Superview(self));
  ContentBox(self, &content);
  SetContentBox(shape, &content);
  Draw(shape, canvas, clip);
  Unlink(shape);
  if (hilited) SetHilited(shape, false);
DoDirty();

WARNING! If you fail to close a DontDirty call with a DoDirty call, your viewables won't be redrawn when they need to and Joel, Crow, and Tom Servo will make fun of your software on national TV.


ShouldDirty

intrinsic ShouldDirty(): Boolean

Call: sometimes
Override: never

ShouldDirty returns true if optional dirtying should be respected, by keeping track of your DontDirty and DoDirty calls. If a viewable's visual appearance has changed and ShouldDirty returns true, the viewable should be redrawn. The various methods that comprise the redraw mechanism use ShouldDirty, so you'll rarely need to call it yourself.

DirtyBounds

operation DirtyBounds(), noFail

Call: sometimes
Override: never

Call DirtyBounds when the interior appearance of your viewable has changed, but its shape hasn't. (If your viewable's shape has changed, you'll need to use DirtyHide.) Calling DirtyBounds is equivalent to calling DirtyBox on the viewable's bounds box.

Here's an example of the kind of circumstances in which you'll use DirtyBounds, taken from Viewable_SetPartColor:

if (partCode == partContent) {
  SetField(self, color, color);
  DirtyBounds(self);
}

If the viewable's content color has changed, the color field should be updated. The viewable needs to be redrawn with its new color. Since its shape hasn't changed, DirtyBounds is the right dirtying method to call.

DirtyBox

operation DirtyBox(dirtyBox: Box)

Call: sometimes
Override: never

Call DirtyBox to request a redraw for a specific box within your viewable. A call to DirtyBox with a nil box is the same as a call to DirtyBounds. If you know which part of your viewable needs to be redrawn, you can call DirtyBox instead of DirtyBounds for better performance.

DirtyContent

operation DirtyContent(), noFail, scriptable, safe

Call: sometimes
Override: never

Call DirtyContent to request a redraw for the content box of your viewable. Calling DirtyContent is equivalent to calling DirtyBox on the content box of your viewable.

DirtyHide

operation DirtyHide(), noFail

Call: sometimes
Override: never

If the shape of your viewable object has changedbecause it's been rotated, or stretched, or otherwise mutatedyou need to mark the area behind the viewable dirty, in addition to marking the viewable itself. The DirtyHide method does this job for you. (Think of it as marking the "hidden" portion of the screen "dirty".) You should follow a DirtyHide call with a DirtyShow call. Here's how you'll use it:

DirtyHide();
 /* make shape-shifting changes to your viewable */
DirtyShow();

Here's how class Stamp uses DirtyHide in its SetImage method to accept a new image:

DirtyHide(self);
  SetField(self, image, newImage);
  BoundsChanged(self);
  SetFinePointing(self, FinePointing(newImage));
DirtyShow(self);

You can nest a DontDirty/DoDirty pair inside your Hide/Show pair if you want. Doing so might optimize your redrawing, but it's not required.

DirtyShow

operation DirtyShow(), noFail

Call: sometimes
Override: never

Call DirtyShow to request a redraw of a viewable, usually to make it appear for the first time. You'll most often call DirtyShow in conjunction with DirtyHide, but there are circumstances in which you'll call it on its own. Just creating a new viewable object of your subclass and adding it to the view hierarchy is not enough to make it appear on the screen. You'll have to call DirtyShow with code that looks like this:

DontDirty();
 /* set up your viewable, set its superview, etc. */
DoDirty();
DirtyShow(yourViewable);

Here's an example that demonstrates how class Gadget creates a new viewable in its Press method:

DontDirty();
  StartPoint(touchInput, &startLoc);
  if (pullOutCopy != LatestOptionKey(touchInput))
  {
  if (CanCopy(viewable))
  {
  PlaySound(iCopySound); 
  /* copy the viewable */
  viewable = CopyNear(viewable, iScreen); 
  SetAutoCopy(viewable, false);
  SetCanDelete(viewable, true);
  }
  else
  {

  Honk();  /* can't copy, let the user know */
  DoDirty(); /* close the DontDirty */
  return;
  }
  }
  else
  { 
  PlaySound(iChangedContainer); 
  Unlink(viewable); 
  }
  /* set the new viewable's superview & origin */
  SetSuperview(viewable, iScreen); /
  SetOrigin(viewable, &startLoc);
DoDirty();   /* turn on dirtying again */
DirtyShow(viewable); /* make the new viewable appear */

When you destroy a viewable, you don't have to jump through all these hoops again, because the Unlink method calls DirtyHide for you.

BoundsChanged

operation BoundsChanged()

Call: sometimes
Override: never

BoundsChanged marks the bounds cache as invalid. Call it when you have changed the bounds of your viewable.

If you've changed bounds explicitly, using system calls, you probably don't need to call BoundsChanged. For example, SetContentBox changes the content box explicitly. If you call that method, you don't need to do any dirty-marking work yourself. If you override routines like CalcContentBox for your subclass, though, you'll need to call BoundsChanged. Your code will look like this:

DirtyHide();
 /* changes to viewable */
 BoundsChanged();
DirtyShow();

For example, class Viewable calls BoundsChanged in its SetLabelLoc method, in code that looks much like the model:

DirtyHide(self);
 SetField(self, viewFlags, (newLoc << 16) | 
   (0xFFF0FFFF & flags));
 BoundsChanged(self);
DirtyShow(self);

Because the object's label has moved, the object's bounding box has changed, and thus its entry in the view cache is invalid.


Drawing Images

Image
SetImage

attribute Image: Image
// operation Image(): Image
// operation SetImage(newImage: Image)

Call: sometimes
Override: sometimes

Call Image to return the image that's associated with the object. Viewable_Image always returns the nil object, because objects of class Viewable don't have an image associated with them.

You should override Image to return your object's image if your class associates images with its objects.

Call SetImage to set the image that's associated with the image. Viewable_SetImage does nothing, because objects of class Viewable don't have an image associated with them.

You should override SetImage to set your object's image to the given value if your subclass associates images with its objects. You should redraw the object if necessary in your overriding method. If you override SetImage, you'll probably override Image also.

If you override one of Image and SetImage, you'll probably override the other also. You might not need to override at all, though: simply adding the line

field image: Image, getter, setter;

to your subclass's definition file provides you with your own versions of the methods.

DrawShadowedImage

operation DrawShadowedImage(canvas: Canvas; clip: Path)

Call: sometimes
Override: rarely

Call DrawShadowedImage to draw the object's image and shadow using the given canvas and clipping path. Usually, you'll call DrawShadowedImage from your Draw method if your object has a shadow, passing the canvas and clipping path that were passed in to your Draw method by the system.

InsideImage

operation InsideImage(probe: Dot): Signed

Call: rarely
Override: rarely

Call InsideImage to test whether the given dot is in the object's image, its shadow, or neither. InsideImage returns one of the constants partNothing, partImage, or partShadow. See the discussion of part codes in the section on class Viewable's constants for more infomation.

FinePointing

operation FinePointing

Call: rarely
Override: rarely

FinePointing returns the value of the fine pointing flag, by comparing finePointingMask to the view flags. See the discussion of the findPointingMask view flag for more information.


Drawing Shadows

Shadow
SetShadow

attribute Shadow: Shadow
// operation Shadow(): Shadow
// operation SetShadow(newShadow: Object)

Call: sometimes
Override: rarely

Call Shadow to get the object's shadow. Viewable_Shadow simply returns the value in the object's shadow field.

Call SetShadow to set the object's shadow to the given object. The object is redrawn the next time drawing takes place.

ShadowOffset
SetShadowOffset

attribute ShadowOffset: Micron, safe, common
// operation ShadowOffset(): Micron
// operation SetShadowOffset(newOffset: Integer)

Call: sometimes
Override: rarely

Call ShadowOffset to get the object's shadow's offset, which is the distance in pixels between the object and the inner edge of its shadow.

Call SetShadowOffset to set the object's shadow's offset to the given value. The object is redrawn the next time drawing takes place.


Growing the viewable

ExtendBottom

operation ExtendBottom(delta: micron)

Call: rarely
Override: sometimes

The system calls ExtendBottom to add more space to the bottom of the object and other objects near the bottom, as when increasing the size of a card. Viewable_ExtendBottom calls CanExtendBottom; if it's true, the viewable's bottom is extended by the given amount and the viewable is scrolled to show the new area. Then, each subview is given a chance to extend its bottom.

You should override ExtendBottom if you want to perform some additional action when your object's bottom is expanded. For example, class Card overrides ExtendBottom to extend the bottom of the associated form when the card's bottom is extended.


Getting Part Colors

PartColor

operation PartColor(part: Signed): Color; noFail

Call: sometimes
Override: sometimes

Call PartColor to get an object that describes the color for the given part of the object. The part parameter, which should one of the values described under Constants Used with Viewable Objects earlier in this chapter (or an additional constant defined by a subclass of Viewable), indicates which part of the object to check.

Viewable_PartColor returns the color of the object's label or shadow if the part parameter is partLabel or partShadow, respectively. If the part parameter is partAltContent, the return value is the object's altColor field. Otherwise, Viewable_PartColor returns the value of the object's color field.

You should override PartColor (and SetPartColor; see below) if objects of your class define additional parts that can be colored. You should return the color of the given part in your overriding method. You should call the inherited PartColor from your overriding method to be sure that parts defined by superclasses are colored correctly.

SetPartColor

operation SetPartColor(color: Color; part: Signed)

Call: rarely
Override: sometimes

The system calls SetPartColor to set part of the object to the given color. The object is redrawn with the new color the next time drawing takes place. Viewable_SetPartColor sets the color for the object's content, label, and shadow parts.

You should override SetPartColor (and PartColor) if objects of your class define additional parts that can be colored. You should set the color of the part indicated by part in your overriding method. You should call the inherited SetPartColor from your overriding method to be sure that parts defined by superclasses are colored correctly.


Highlighting

For a description of what highlighting is and how to draw your viewables in a highlighted state, see the description of the Draw method.

Hilited
SetHilited

attribute Hilited: Boolean, safe, common
// operation Hilited(): Boolean
// operation SetHilited(newValue: Boolean)

Call: sometimes
Override: rarely

Call Hilited to test whether the object is highlighted. Hilited simply tests the appropriate view flag of the object, the hilited flag.

Call SetHilited to highlight or remove highlighting from the object. If the object's appearance changes, the object is redrawn the next time drawing takes place. SetHilited simply sets the appropriate view flag of the object.

ContentsCanHilite

operation ContentsCanHilite(): Boolean

Call: rarely
Override: rarely

ContentsCanHilite returns true if the viewable's contents can be highlighted. This method returns true by default. You should override to return false if the contents of your subclass can't highlight, or to perform a test if they can sometimes highlight.


Changing Orientation

ChangeOrientation

intrinsic ChangeOrientation(changeCode: UnsignedShort; oldOrientation: 
UnsignedShort): UnsignedShort

Call: rarely
Override: never

Call ChangeOrientation to get the new orientation for the viewable if it's flipped or rotated according to the given change code. You must pass the object's current orientation in the oldOrientation parameter; you can get this value by calling Viewable_Orientation. ChangeOrientation returns the object's new orientation as the function result. ChangeOrientation has a misleading name, since it doesn't actually change the object's orientation. You must do so yourself by calling SetOrientation with the new orientation.

The system defines constants for the change codes in the file Utilities.h. Here's a chart showing the constants and their meanings for change codes:

Constant Value Meaning
changeFlipHorizontal 1 Flip horizontal
changeFlipVertical 2 Flip vertical
changeRotateRight 3 Rotate right
changeRotateLeft 4 Rotate left

Orientation

attribute Orientation: UnsignedShort; safe
// operation Orientation(): UnsignedShort

Call: sometimes
Override: rarely

Call Orientation to get a value representing the object's orientation.

Viewable_Orientation simply returns zero. You should override Orientation to return an orientation from 0 to 7 if objects of your class have an orientation setting.

/* bits of orientation */
#define rotateBit   2
#define hFlipBit  1
#define vFlipBit  0
/* image orientation bitMasks */
#define rotateMask  (1 << rotateBit)
#define hFlipMask  (1 << hFlipBit)
#define vFlipMask  (1 << vFlipBit)

SetOrientation

attribute Orientation: UnsignedShort; safe
// operation SetOrientation(newOrientation: UnsignedShort)

Call: rarely
Override: rarely

Call SetOrientation to set the object's orientation to the given value.

Viewable_SetOrientation does nothing. You should override SetOrientation to set the object's orientation to the given value if objects of your class have an orientation setting.


Managing the View Hierarchy

OnScreen

attribute OnScreen: Boolean, readOnly, safe, common
// operation OnScreen(): Boolean, safe, common

Call: sometimes
Override: never

Call OnScreen to test whether the object is in the view list (that is, it's the screen or a subview, possibly recursively, of the screen). OnScreen returns true if the object is in the view list and false otherwise. Note that the object might actually be positioned off the screen, but still return true to OnScreen if it's in the view list.

SuperviewSetSuperview

operation Superview: Viewable, noFail
operation SetSuperview(newSuperview: Viewable), noFail

Call: sometimes
Override: rarely

Call Superview to get the object's container. Superview simply returns the object's superview field.

Call SetSuperview to make the given viewable be the superview of the object. If the object has a non-nil next link, all peer views of the object have their superview set to the given viewable.

SendToBack

operation SendToBack()

Call: rarely
Override: rarely

Call SendToBack to make the object the rearmost subview of its superview. The rearmost subview is the one that is drawn first.

BringToFront

operation BringToFront()

Call: rarely
Override: rarely

Call BringToFront to make the object the frontmost subview of its superview. (The frontmost subview is the one that is drawn last.) BringToFront calls CanBringToFront to test whether the object can be brought to the front; if CanBringToFront returns false, BringToFront returns without moving the object to the front.

See the description of Viewable_CanBringToFront for more information.

CanBringToFront

attribute CanBringToFront: Boolean; readOnly
// operation CanBringToFront(): Boolean

Call: rarely
Override: sometimes

Call CanBringToFront to test if a viewable can be brought to the front.

When the user drags an object, the object is usually brought to the front of the container that serves as its superview. Just before bringing it to the front, the system calls the object's CanBringToFront method. If CanBringToFront returns true, the object is brought to the front of its container.

Viewable_CanBringToFront always returns true, indicating that viewable objects should be brought to the front when they're dragged. You should override CanBringToFront if you ever want to prevent objects of your class from coming to the front of their superviews when they're dragged. For example, class Card overrides CanBringToFront to always return false, preventing card objects from ever being brought to the front.


Managing Subviews

FirstSubview

operation FirstSubview(): Viewable, noFail

Call: sometimes
Override: rarely

Call FirstSubview to get the object's rearmost subview. FirstSubview simply returns the object's subview field.

SetSubview

operation SetSubview(newSubview: Viewable)

Call: sometimes
Override: rarely

Call SetSubview to make newSubview be the rearmost subview of the object. If the new subview's previous field isn't nilObject, SetSubview fails. Any peer views or subviews of newSubview are retained.

IsSubviewOf

operation IsSubviewOf(candidateSuperview: Viewable): Boolean

Call: rarely
Override: rarely

Call IsSubviewOf to test whether the object is a subview of the given viewable. IsSubviewOf returns true if the object is a subview of the given viewable and false otherwise.

EachSubview

operation EachSubview(doToView: EachFunction; 
  VAR parameters: Parameters): Object

Call: sometimes
Override: rarely

Call EachSubview when you want to invoke a function repeatedly for every viewable that's a subview of the object. The subviews are processed recursively, so every Viewable that's ultimately a subview of the object, no matter how many levels deep, is processed. If you call EachSubview, you must also define the iterative function that is called for each object, then pass a pointer to that function in the doToView parameter. If you want to send any parameters to your iterative routine, pass a pointer to the parameters in params when you call EachSubview.

EachSubview keeps calling the iterative function as long as the iterative function returns nilObject and there are still subviews that haven't been processed. When the iterative function returns an object ID, EachSubview stops calling the iterative function and exits. This is useful if you want to stop iterating when your iterative function fulfills some condition, such as successfully completing a search.

The routine that's called for each object should be declared like this:

Private ObjectID IterativeFunc (ObjectID theObject, void *params)

WARNING! You must use the Private specifier when you declare your iterative function. If you fail to do so, you'll get no warning from any tools during the build process, but your software will fail in an unpredictable way and your copy of Doom Patrol #19 will disintegrate.

The theObject parameter contains the viewable that's currently being processed. EachSubview passes the params parameter unchanged each time IterativeProc is called.

The type of the parameters parameter is defined as:

typedef struct
  {
  ObjectID  fromContext;
  ObjectID  context;
  ushort  objectCount;
  ushort  nesting;
  } Parameters;

To set up the parameters, call SetUpParameters. For more information on the method SetUpParameters, see the section on class Object.

You can add custom information to the parameters structure by defining your own structure. A parameters structure should be the first field of your new structure. Your structure should look like this:

typedef struct
  {
  Parameters params;
  … /* your additions here */
  } MyParameters;

For more information on Each functions, see the section on the mixin HasIterator.

ShallowEachSubview

operation ShallowEachSubview(doToView: EachFunction; 
  VAR parameters: Parameters): Object

Call: sometimes
Override: rarely

ShallowEachSubview calls Each on the first subview of the viewable, passing along the function pointer and the parameters. Call it to invoke a function on each subview of the viewable, but not on the subview's subviews. See the description of EachSubview for more information.

DestroySubviews

operation DestroySubviews(), noFail

Call: rarely
Override: rarely

DestroySubviews calls Destroy on all of the object's subviews. The system calls DestroySubviews to delete all the object's subviews when the object is deleted.


Changing Visiblity

VisibleSetVisible

attribute Visible: Boolean; safe; common
// operation Visible(): Boolean, safe, common
// operation SetVisible(newVisible), safe, common

Call: sometimes
Override: rarely

Call Visible to determine whether the object is visible on the screenthat is, it is drawn when drawing takes place. Visible simply returns the value of the object's visible view flag. Note that an object that's visible might be hidden by other objects in front of it (or it might even be not on screen at all, but instead in some other scene), so calling Visible does not necessarily determine whether the object can actually be seen.

Call SetVisible to set the object's visibility status according to the given value. If SetVisible changes the object's visibility, the object is redrawn the next time drawing takes place. SetVisible sets the object's visible view flag as part of its action.

ShowSubviews

operation ShowSubviews()

Call: rarely
Override: rarely

Call ShowSubviews to make all of the object's immediate subviews visible by calling SetVisible on them. ShowSubviews only processes the object's immediate subviews. It doesn't affect subviews recursively (that is, no subviews of subviews of the object are set to visible).


Manipulating Labels

Label

operation Label(VAR labelStr: String)

Call: sometimes
Override: sometimes

Call Label to get the object's name as displayed in its label.

The system calls Label to get the object's label string for display in its label. If the object has a script and the "use script name" viewable flag is set, Viewable_Label returns the script's name. Otherwise, Viewable_Label returns the object.

You should override Label if you want your subclass to use another technique for determining the text for the object's label. For example, class Piano overrides Label to use the piano's sound name as its label.

LabelBox

operation LabelBox(VAR labelBox: Box): Boolean

Call: sometimes
Override: rarely

Call LabelBox to get the box that encloses the object's label in the labelBox parameter. The function result returns whether the label should be clipped to the box.

LabelLoc

attribute LabelLoc: UnsignedShort
// operation LabelLoc(): UnsignedShort

Call: sometimes
Override: rarely

Call LabelLoc to return the location code of the object's label (a value from 0 to 15). Here's a handy diagram of label locations:

These constants have the following easily-readable names:

#define labelLocCenter   0
#define labelLocAboveLeft  1
#define labelLocAboveCenter  2
#define labelLocAboveRight   3
#define labelLocRightUpper   4
#define labelLocRightMiddle  5
#define labelLocRightLower   6
#define labelLocBelowRight   7
#define labelLocBelowCenter  8
#define labelLocBelowLeft  9
#define labelLocLeftLower   10
#define labelLocLeftMiddle  11
#define labelLocLeftUpper   12
#define labelLocOnBorderTopLeft   13
#define labelLocOnBorderTopCenter 14
#define labelLocOnBorderBottomCenter  15

SetLabelLoc

attribute LabelLoc: UnsignedShort
// operation SetLabelLoc(newLoc: UnsignedShort)

Call: rarely
Override: rarely

Call SetLabelLoc to set the location of the object's label to the given value. The value of newLoc should be between 0 and 15. If the label's new location is different from its old location, the object is redrawn the next time drawing takes place.

ShowLabelSetShowLabel

attribute ShowLabel: Boolean
// operation ShowLabel(): Boolean
// operation SetShowLabel(newValue: Boolean)

Call: sometimes
Override: rarely

Call ShowLabel to get a value that indicates if the object's label is being shown. ShowLabel returns true if both the object's show label view flag and Viewable_CanShowLabel are true.

See the description of Viewable_CanShowLabel for more information.

Call SetShowLabel to turn the object's label on or off according to the given value. Viewable_SetShowLabel sets the object's show label view flag and redraws the label if necessary.

CanShowLabel

attribute CanShowLabel: Boolean; readOnly
// operation CanShowLabel(): Boolean

Call: rarely
Override: rarely

Call CanShowLabel to determine if the object's label can ever be shown. As long as CanShowLabel is false, the object's label is never drawn. If CanShowLabel is true, the label is shown under certain circumstances (usually, if Viewable_ShowLabel is also true).

The system calls CanShowLabel to determine if the object's label can ever be shown. Viewable_CanShowLabel always returns true.

You should override CanShowLabel if your subclass defines objects whose labels should never be shown. For example, class Panel overrides CanShowLabel to always return false, indicating that panel objects never show their labels.

See the description of Viewable_ShowLabel for more information.

BorderLabelSetBorderLabel

attribute BorderLabel: Boolean
// operation BorderLabel(): Boolean
// operation SetBorderLabel(newValue: Boolean)

Call: rarely
Override: rarely

Call BorderLabel to find out if the object's label is drawn with a border around it. BorderLabel returns the setting of the object's border label view flag.

Call SetBorderLabel to draw or remove the border around the object's label, depending on the given value. Viewable_SetBorderLabel sets the object's border label view flag. The label is redrawn if necessary.


Manipulating Text and Names

SetUseScriptName

operation SetUseScriptName(newValue: Boolean)

Call: rarely
Override: rarely

Call SetUseScriptName to determine whether the object should use its script's name for its label. Viewable_SetUseScriptName sets the object's "use script name" view flag and redraws the label if necessary.

SetName

overrides SetName(name: String), noFail

Call: sometimes
Override: rarely

Call SetName to set the object's name to the given string. Most viewable objects use this name as their label. Viewable_SetName redraws the object and its label if necessary.

SetTextData

overrides SetTextData(text: HasText; index: Unsigned; 
 where: Dot)

Call: rarely
Override: sometimes

The system calls SetTextData to set the object's text when the user drops a text coupon onto an object. Class Viewable overrides SetTextData to set the object's name to the passed-in text object. Viewable_SetTextData also turns off the object's "use script name" flag. If the object's label is shown and the viewable should be redrawn, the object is redrawn with the new name as its label. The index and where parameters are ignored.

You should override SetTextData if your class defines objects that include text data other than their names. You should redraw the object if its text data is visible.

SetTextStyle

operation SetTextStyle(newTextStyle: TextStyle; part: Signed)

Call: rarely
Override: sometimes

Call SetTextStyle with part equal to partLabel to set the text style of the object. Any other value for part does nothing. The object is redrawn the next time drawing takes place.

You should override SetTextStyle if your class defines objects that include text data other than labels.


Searching

MatchText

operation MatchText(searchString: String): Boolean

Call: sometimes
Override: sometimes

Call MatchText to check for the given string in the object's label or in text in any of the object's immediate subviews.

Viewable_MatchText first compares the given text to the object's label; if they're the same, MatchText returns true. If they're not the same, Viewable_MatchText calls MatchText on each of the object's immediate subviews and returns true if there's a match. Viewable_MatchText only searches the object's immediate subviews; that is, it does not work on any subviews of subviews of the object.

You should override MatchText if objects of your class contain text that you might want to search for with MatchText. You might want to call the inherited MatchText at the start of your overriding method to search for the text using the superclasses' implementations. In your overriding method, you should return true if your object can match the given string.

MatchViewable

operation MatchViewable(searchView: Object): Boolean

Call: sometimes
Override: rarely

Call MatchViewable to see if the given viewable matches any of the object's immediate subviews.

Viewable_MatchViewable performs its action by calling MatchViewable on each of the object's immediate subviews and returns true if there's a match. Viewable_MatchViewable only searches the object's immediate subviews; that is, it does not work on any subviews of subviews of the object.

You should override MatchViewable if objects of your class use some special criteria for determining matches. You may want to call the inherited MatchViewable at the start of your overriding method to search for the object using the superclasses' methods. In your overriding method, you should return true if your object can match the given viewable.

SearchFor

operation SearchFor(searchFor: Object; searchFlags: Flags): Object, 
noFail

Call: sometimes
Override: sometimes

Call SearchFor to look for images, text, and viewables. SearchFor uses MatchText and MatchViewable to search for a wider range of objects than those two methods do.

You might override SearchFor if your subclass of class Viewable needs special processing when it's searched.

You can control some aspects of the search by setting search flags. Your override of SearchFor should respect these flags. The available flags are:

Flag name Mask Meaning
searchBackward 0x00000000 Search from the start point backward
searchForward 0x00000001 Search from the start point forward
searchWrap 0x00000002 Wrap around searching (stay within a stack of cards)
searchFromBeginning 0x00000004 Start the search from beginning
returnOnlyEndResult 0x00000008 Return only the end result, not the entire path to it
initialSearch 0x00000010 This is the first search in this scene since find was selected

The searchBackward and searchForward flags are set by the user when she initiates a search.

The searchFromBeginning and searchWrap flags work together to control searches inside stacks of cards. If the user initiates a search from the middle of a stack of cards, the searchFromBeginning flag should not be truethe search should start from the spot where the user is. The searchWrap flag should also be true, because the search should confine itself to the stack. If the user starts a search somewhere outside a stack of cardsfrom the Desk, for examplethe searchFromBeginning flag should be true and the searchWrap flag false.

SearchFor should return an object of class SearchResult. Search results include both the end result of the search and a path to the search. See the chapter on class SearchResult for more information. If the returnOnlyEndResult flag is set, though, SearchFor should return only the search's result. The returnOnlyEndResult flag should be set if the searching agent shouldn't animate its route toward the found object


Version note: Unfortunately, class SearchResult has not yet been documented. Stay tuned for those exciting pages in the next edition of this document, same bat-time, same bat-channel.

You can construct a return value for SearchFor using code that looks something like this:

searchingAgent = DirectID(iCurrentSearchAgent);
/* foundItem is the result of the search */

if (foundItem != nilObject && 
 ((searchFlags & returnOnlyEndResult) == 0))
  {
  /* make an object of class SearchResult */
  searchResult = NewNear(SearchResult_, searchingAgent,nil);
  AddFirst(searchResult, foundItem);
  }
else
  /* we want only the end result; just return the match */
  searchResult = foundItem;
return searchResult;

Your override of SearchFor might not need to construct a search result itself, if it just passes along the SearchFor call to another subclass of class Viewable. Here's an example of how class Telecard redirects the search to its envelope:

result = SearchFor(envelope, searchFor, searchFlags);
return result;

Searchable

operation Searchable

Call: never
Override: sometimes

Call Searchable to check if a viewable should be searched by the searching agent. Viewable_Searchable returns true by default.

You might override Searchable if some objects of your subclass should be searched while others shouldn't. For example, class Scene overrides Searchable to check a scene flag to see if a scene should be searched Or you might override Searchable to return false because viewables of your subclass should never be searched.


Playing Sounds

PlaySound

operation PlaySound; safe; common; noFail

Call: sometimes
Override: rarely

Call PlaySound to play the sound associated with the object. Viewable_PlaySound gets the object's sound object by calling Sound, then calls PlaySound with that sound object.

SoundSetSound

attribute Sound: Sound
// operation Sound(): Sound
// operation SetSound(newSound: Sound)

Call: sometimes
Override: rarely

Call Sound to get the sound object that's associated with the object. Usually, this is the sound that's played when the user touches the object.

Call SetSound to associate the given sound with the object.

PlaySoundWithDefault

operation PlaySoundWithDefault(defaultSound: Playable), safe

Call: sometimes
Override: rarely

Call PlaySoundWithDefault if you need to guarantee that a sound is played. PlaySoundWithDefault first tries to play the viewable's own sound, by calling Sound. If the viewable has no sound, PlaySoundWithDefault plays the sound you specified in defaultSound.


Idling, Notifying, and Timing

Idle

operation Idle(): Unsigned, scriptable

Call: never
Override: sometimes

The system calls each viewable object's Idle method when it's not busy handling events from the user, talking to the network, communicating with peripherals, or doing other things. Idle's return value is the maximum amount of time that should pass before the system calls your Idle method again. Larger values result in better system performance. Return 0 if you don't care when Idle is next called.

You should override Idle if you want your objects to perform some action when the system is idle. For example, the Clock class overrides Idle to update its time display. Make sure you call InheritedIdle from your overridden method.

SoonerIdle

operation SoonerIdle(interval1: Unsigned; interval2: Unsigned): 
Unsigned

Call: sometimes
Override: never

Call SoonerIdle to return the sooner of two idle intervals. SoonerIdle just compares the given idle intervals and returns the sooner. If one of the idle intervals is zero, SoonerIdle returns the other.

AboutToShow

operation AboutToShow(), noFail, scriptable

Call: rarely
Override: sometimes

The system calls AboutToShow on viewables that are about to appear on the screen, to give them a chance to prepare themselves. Viewable_AboutToShow calls PermitIdle, but otherwise does nothing. Override AboutToShow if objects of your subclass need to do any preparation before appearing on the screen.

For example, class Animal overrides AboutToShow to allow the animal to react when the user enters the scene. Class Clock overrides to call UpdateLevel on itself, to ensure that it displays the current time. Class ChoiceBox overrides to create a transient choice list if necessary.

Make sure to call InheritedAboutToShow from your version of the method.

AboutToHide

operation AboutToHide(), noFail, scriptable

Call: rarely
Override: sometimes

The system calls AboutToHide on viewables that are about to leave the screen. Viewable_AboutToHide does nothing. You should override it if objects of your subclass need to do any clean-up before vanishing. For example, class TextField overrides AboutToHide to turn off typing. Class ChoiceBox overrides it to destroy any transient choice lists that might be floating around. Class Animation overrides it to stop playing any sound that might be associated with the animation.

Confirm

operation Confirm(), safe, common, noFail

Call: rarely
Override: sometimes

Call Confirm to accept or process any changes made by your users that you've deferred processing. You should usually avoid defer accepting changes to objects or information made by your users. But if you do need to defer, process the changes in a Confirm method. For example, you could call Confirm when the user taps an "accept" button, or when the user has finished filling out information for an attribute step list. (If you're using an attribute step list or an attribute window, the system calls Confirm for you.)

For example, class CompanyPostalLabel uses Confirm to offer the user a company email label. Class Control's Confirm method updates levels for controls that have their updateOnConfirmOnlyBit set.

Confirmed

operation Confirmed(identifier: Object; 
confirmFlag: Boolean): scriptable, safe

Call: rarely
Override: sometimes

Call Confirmed to react to a yes/no choice made by your user. The confirmFlag parameter is true if the user tapped yes, and false if he tapped no.

For example, class TaskProxy uses Confirmed to define what happens when a user taps "yes" or "no" on, for instance, a meeting invitation. If the user taps yes, the meeting should go into the user's datebook, and if he taps no, it shouldn't. In either case, the system needs to send a message to the meeting originator with the user's answer. TaskProxy_Confirmed constructs a message with the appropriate answer, and adds the task to the datebook if necessary.

ValueChangeNotice

operation ValueChangeNotice()

Call: sometimes
Override: sometimes

The system calls ValueChangeNotice when a switch subview of the viewable changes value. Viewable_ValueChangeNotice does nothing. You should override if objects of your subclass should react to switches. (Though probably you should just use class ChooseOneBox, which is the only system class to override this method.)

SetAuthoringMode

operation SetAuthoringMode(newMode: Boolean), safe

Call: sometimes
Override: never?

The system calls SetAuthoringMode when the user level changes (that is, when the user turns authoring mode on or off). If newMode is true, authoring mode is the current mode.

Viewable_SetAuthoringMode does nothing. Override if objects of your subclass should react to a user level change. For example, the Magic Hat overrides this method to display the image appropriate for the user level: the rubber stamp image for most users, and the top hat for users who've turned on authoring.


Hit Testing

HitTest

operation HitTest(probe: Dot; skip: Viewable; 
  VAR part: Signed): Viewable

Call: sometimes
Override: never?

The system calls HitTest from various touch-processing methods to determine which viewable was touched. HitTest tests all subviews of the screen, and returns the frontmost one that contains probe. The part parameter points to the part code for the location of the hit. You might call HitTest from your overrides of methods like Press or Touch, or from methods like ConstrainHit.

ConstrainHit

operation ConstrainHit(probe: Dot; skip: Viewable): Viewable, noFail

Call: rarely
Override: rarely

Call ContrainHit to give viewables a chance to redirect touches from themselves to other viewables. ConstrainHit returns the viewable to which the touch should be redirected. Viewable_ConstrainHit does nothing, and just returns the original viewable.

Override this method if objects of your subclass should sometimes (or always) redirect touches away from themselves. For example, class ControlBar overrides ConstrainHit to redirect touches to a viewable at the center of one of its subdivisions, making sure to avoid accidentally sending a touch to an overlapping window.

InsidePart

operation InsidePart(probe: Dot): Signed

Call: rarely
Override: never

The system calls InsidePart (usually from touch-processing methods like DragTrack, Press, and HitTest) to get a value that indicates which part of the object contains the given dot. Viewable_InsidePart calls CalcInsidePart to calculate which part of the object contains the given dot.

CalcInsidePart

operation CalcInsidePart(probe: Dot): Signed

Call: never
Override: sometimes

Call CalcInsidePart to get the part code for the location of the given probe.

CalcInsidePart checks to see if probe is in the viewable's label box or border box. If it's in the label box, CalcInsidePart returns partLabel. If it's in the border box but not in the label box, CalcInsidePart returns partContent. If probe is in neither, CalcInsidePart returns partNothing.

You might override CalcInsidePart if your subclass has other parts that can be touched. For example, class ColorMatrix overrides to determine exactly which color box the user has tapped in. Class SpeedDialButton overrides to force all hits onto partLabel. Class TitledWindow overrides to add partTitle to the list of possible places to hit.


Touching

ConstrainToolTarget

operation ConstrainToolTarget(touchInput: TouchInput;
VAR tool: Tool; VAR target: Viewable)

Call: rarely
Override: sometimes

The system calls ConstrainToolTarget from ChooseableTool_GetToolTarget when the user touches a viewable while some tool is active. GetToolTarget calls ConstrainToolTarget for the target view and all its superviews, to give each a chance to change the target and/or the tool. Some viewables redirect all touches on their subviews to themselves. Others redirect touches to certain subviews.

For example, class Card overrides ConstrainToolTarget to redirect any hits on a card's form to the card itself. Class SignaturePad overrides it to coerce the current tool to be the touch tool. Here's how it does so:

InheritedConstrainToolTarget(self, touchInput, tool,
     target);

/* force the touch to us. */
if (!LatestOptionKey(touchInput))
  {
  *target = self;
  /* force touch tool so touch method gets called */
  if (IsWritingTool(*tool)) *tool = DirectID(iTouchTool); 
}

If you override ConstrainToolTarget, make sure you call the inherited method from your method, as the example above does.

MustTrack

attribute MustTrack: Boolean; readOnly
// operation MustTrack(): Boolean

Call: rarely
Override: rarely

If MustTrack returns true, the object can be touched normally in the Magic Window instead of dropping out when the user touches it. MustTrack uses mustTrackMask to return the value of the associated view flag.

TouchKind

operation TouchKind(touchInput: TouchInput): Unsigned

Call: sometimes
Override: never?

Call TouchKind to classify a touch as a press, a tap, or an unknown touch. TouchKind distinguishes among touch kinds by checking how long the user's finger was down and how much the user's finger moved. To do so, TouchKind uses the criteria returned by TapPressCriteria.

TouchKind returns the appropriate touch constant. The possible touch kind constants are:

#define dontKnow   1
#define tapKind  2
#define pressKind  3

WaitTouchKind

operation WaitTouchKind(touchInput: TouchInput): Unsigned

Call: sometimes
Override: never

Call WaitTouchKind instead of TouchKind when you absolutely positively need to know what kind of touch the touch is, and can afford to wait.WaitTouchKind calls TouchKind repeatedly until TouchKind returns something other than dontKnow.

TapPressCriteria

operation TapPressCriteria(
VAR touchModeTapDuration: Unsigned; 
VAR otherTapPressDuration: Unsigned; 
VAR dragHysteresis: Unsigned);

Call: rarely
Override: rarely

Call TapPressCriteria to get three values which you should use to distinguish taps from presses. Those values are:

Pointer Value returned Meaning
touchModeTapDuration 120 * oneSecond; Duration for press in touch mode
otherTapDuration oneSecond / 2 Duration for press in other modes
dragHysteresis 20*onePixel If this distance is exceeded, count as a press

If the touch tool is active, a press is any touch longer than 120 seconds (two minutes). If other tools are active, a press is any touch longer than half a second. Any touch, no matter what the duration, that moves more than 20 pixels away from its starting point is also a press. Taps are touches which don't fit the criteria for presses.

You might override TapPressCriteria to change the drag hysteresis for certain risky operations. For example, class ContainerIcon overrides to make the hysteresis longer:

InheritedTapPressCriteria(self, touchModeTapDuration,
    otherTapDuration, dragHysteresis);
*dragHysteresis = 40*onePixel;

The longer hysteresis makes it more difficult for users to move objects out of container icons, thus preventing accidental moves. The longer hysteresis allows sloppier touches, without interfering with users who know they want to move an object.

You should avoid changing the tap/press criteria, since your users might be confused by lots of changes to the way touches feel.

Touch

operation Touch(touchInput: TouchInput);

Call: rarely
Override: sometimes

The system calls Touch when the user touches an object. Viewable_Touch uses TouchKind to determine what sort of touch, then calls Tap or Press appropriately.

You should override Touch if you want objects of your class to perform some special action when the user touches them. Your subclass might not need to distinguish between taps and presses, for example. Or your subclass might need to perform some action on the downstroke of the touch.

You might want to call the inherited Touch method at the end of your method, though sometimes you won't need to.

Many system classes override the Touch method. Some of the overrides are quite simple, and others do lots of complex touch-tracking. Class Entrance overrides Touch to play its door-opening sound, open the door, and zoom to the entrance's destination. It does nothing with the touch input. Class Keyboard, though, uses the touch input in its override of Touch to determine which key the user just pressed.

Touching

operation Touching(), scriptable

Call: rarely
Override: sometimes

The system calls Touching repeatedly while the user is touching an object. Viewable_Touching does nothing; override if your subclass has a use for this method.

Tap

operation Tap(touchInput: TouchInput), scriptable

Call: rarely
Override: sometimes

The system calls Tap when the user taps on an object. Viewable_Tap plays the object's sound then calls Action. You should override Tap if you want to avoid playing a sound.


Version note: Previous versions of this manual recommended that you override Tap to change the action performed when a user taps. This new, improved manual changes that recommendation: you should override Action to change what happens when the user taps on objects of your subclass, unless you need positional information from the touchInput parameter.


Action

operation Action(), scriptable, safe

Call: often
Override: often

The system calls Action from Tap. Thus the Action method of any viewable defines what happens when the user taps on the viewable. As you might imagine, many subclasses of class Viewable override Action to perform a wide variety of tasks.

Press

operation Press(touchInput: TouchInput), scriptable

Call: rarely
Override: sometimes

The system calls Press when the user presses on an object.

Viewable_Press drags the touched viewable if it's auto-move (that is, if it can be moved without the move tool). Otherwise, Press calls Touching and Pressing repeatedly while the user's finger is down. When the user's finger lifts, Press calls Action if the touch was still inside the viewable. Then, Press calls Pressed.

You should override Press if you want objects of your class to perform some special action when the user presses on them. Here are some examples of how various system classes override Press: Class TitledWindow overrides Press to allow titled windows to be dragged only by their title bars. Class TextField overrides Press to use the touch input to make text selections. Class EditableList overrides Press to drag out the pressed list item.

Pressing

operation Pressing(touchInput: TouchInput; isInside: Boolean), 
scriptable

Call: rarely
Override: rarely

The system calls Pressing repeatedly while the user is pressing on an object. The isInside parameter tells whether the user's touch is still inside the object. Viewable_Pressing does nothing. You should override Pressing if you want objects of your class to perform some special action while the user is pressing on them. Class Stamp, for example, overrides Pressing to highlight stamps as the user's touch moves over them, and turn highlighting off as the touch moves away.

Pressed

operation Pressed(touchInput: TouchInput; isInside: Boolean; wasDrag: 
Boolean): Boolean, scriptable

Call: rarely
Override: rarely

The system calls Pressed after the user releases an object that's been pressed. Viewable_Pressed calls HitTest and ConstrainHit to give the object a chance to redirect the touch. If the user has dragged the object onto a new target, Pressed allows the target to swallow the objects. If the object is indeed swallowed, Pressed plays a happy swallowing sound and returns true. If the object was not swallowed, Pressed returns false.

You should override Pressed if you need to do additional press-processing on objects of your subclass. For example, class AttributeStamp overrides Pressed to check for conflicts with existing attribute stamps on an attribute stamp's new superview. Class MiniCard overrides Pressed to control what happens when minicards are dropped into various kinds of scenes.

Disabled

attribute Disabled: Boolean
// operation Disabled(): Boolean
// operation SetDisabled(newValue: Boolean);

Call: sometimes
Override: rarely

Call Disabled to find out if the object is disabled and can't be touched. Disabled returns the setting of the object's disabled view flag. SetDisabled sets the disabled view flag.

TapCenter

operation TapCenter(), safe, common

Call: rarely
Override: rarely

Call TapCenter to tap in the center of the object. This method is mainly intended for use by Magic Script scripts to cause an object to act as if the user has tapped it.


Moving and Copying

MoveTouch

operation MoveTouch(touchInput: TouchInput)

Call: rarely
Override: rarely

The system calls MoveTouch when the user touches an object while the move tool is active. Viewable_MoveTouch calls WaitTouchKind to determine if the user's touch was a tap or a press, then calls Touch or MovePress, respectively.

You should override MoveTouch if you want objects of your class to perform some other action when the user touches them with the move tool active. For example, class Corridor overrides MoveTouch to allow the user to move through the corridor by dragging with the move tool.

MovePress

operation MovePress(touchInput: TouchInput)

Call: rarely
Override: rarely

The system calls MovePress when the user presses on an object while the move tool is active. Viewable_MovePress simply calls DragTrack.

You should override MovePress if you want objects of your class to perform some other action when the user presses on them with the move tool active. For example, classes AddressPanel and PhonePanel both allow the user to move labels with the Move tool while in change mode, and otherwise call their inherited methods.

CopyTouch

operation CopyTouch(touchInput: TouchInput)

Call: rarely
Override: rarely

The system calls CopyTouch when the user touches an object while the copy tool is active. Viewable_CopyTouch calls WaitTouchKind to determine if the user's touch was a tap or a press, then calls Touch or CopyPress, respectively.

You should override CopyTouch if you want objects of your class to perform some other action when the user touches them with the copy tool active.

CopyPress

operation CopyPress(touchInput: TouchInput)

Call: rarely
Override: rarely

The system calls CopyPress when the user presses on an object while the copy tool is active. Viewable_CopyPress simply calls DragTrack.

You should override CopyPress if you want objects of your class to perform some other action when the user presses on them with the copy tool active. Class TextField, for example, overrides CopyPress to turn off typing.

DragTrack

operation DragTrack(touchInput: TouchInput; mustMove: Boolean; 
mustCopy: Boolean)

Call: sometimes
Override: rarely

The system calls DragTrack while the user is dragging an object to implement the basic move and copy features for viewable objects. Call DragTrack if you want to track the user's action while dragging an object, or if you've just created a new viewable and want to encourage the user to move it. If you call DragTrack, you'll usually call it from your class's overriding Touch implementation. If you override DragTrack, you should do so only to do additional setup before calling the inherited method.

DragAsGhost

operation DragAsGhost(): Signed

Call: rarely
Override: sometimes

Call DragAsGhost to determine whether a viewable should be drawn as a semi-transparent "ghost" when it's dragged. The ghosting depends on the value returned by DragAsGhost, as follows:

Return Value Ghostly Behavior
>0 Turn semi-transparent when dragged
0 Turn semi-transparent only when swallowed
<0 Never turn semi-transparent

Viewable_DragAsGhost returns 0, which is the behavior that suits most viewables. Override to return something different.

CanMove

attribute CanMove: Boolean
// operation CanMove(): Boolean

Call: sometimes
Override: sometimes

Call CanMove to test whether the object can be moved.

The system calls CanMove to test whether the object can be moved. Viewable_CanMove simply returns the value of the object's can move view flag.

You should override CanMove if you want objects of your class to refuse to be moved at all times. For example, class Panel ignores the object's can move view flag and overrides CanMove to always return false, indicating that panel objects can never be moved.

SetCanMove

attribute CanMove: Boolean
// operation SetCanMove(newValue: Boolean)

Call: rarely
Override: rarely

Call SetCanMove to set whether the object can move according to the given value. SetCanMove sets the object's can move view flag.

CanCopy

attribute CanCopy: Boolean
// operation CanCopy(): Boolean

Call: sometimes
Override: sometimes

Call CanCopy to test whether the object can be copied.

The system calls CanCopy to test whether the object can be copied. Viewable_CanCopy simply returns the value of the object's can copy view flag.

You should override CanCopy if you want objects of your class to refuse to be copied at all times. For example, class Card ignores the object's can copy view flag and overrides CanCopy to always return false, indicating that cards can never be copied.

SetCanCopy

attribute CanCopy: Boolean
// operation SetCanCopy(newValue: Boolean)

Call: rarely
Override: rarely

Call SetCanCopy to set whether the object can be copied according to the given value. SetCanCopy sets the object's can copy view flag.

AutoCopySetAutoCopy

attribute AutoCopy: Boolean
// operation AutoCopy(): Boolean
// operation SetAutoCopy(newValue: Boolean)

Call: rarely
Override: rarely

The system calls AutoCopy to test whether the object is auto-copyable (that is, it makes a copy when the user drags, even without the copy tool). AutoCopy tests the object's auto copy view flag.

Call SetAutoCopy to set whether the object is auto-copyable according to newValue. SetAutoCopy sets the object's auto copy view flag.

CanDeleteSetCanDelete

attribute CanDelete: Boolean
// operation CanDelete(): Boolean
// operation SetCanDelete(newValue: Boolean)

Call: rarely
Override: rarely

The system calls CanDelete to test whether the object can be thrown away. CanDelete tests the object's can delete view flag.

Call SetCanDelete to set whether the object can be thrown away. If newValue is true, the object is set to indicate that it can be deleted. If newValue is false, the object can't be deleted. SetCanDelete sets the object's canDelete view flag.

CanDragContentsSetCanDragContents

attribute CanDragContents: Boolean
// operation CanDragContents(): Boolean
// operation SetCanDragContents(newValue: Boolean)

Call: rarely
Override: rarely

Call CanDragContents to test whether the object prevents its subviews from moving. CanDragContents tests the object's lockContents view flag.

Call SetCanDragContents to set whether the object prevents its subviews from moving according to the given value. SetCanDragContents sets the object's lockContents view flag to the inverse of the given value.


Stretching

StretchTouch

operation StretchTouch(touchInput: TouchInput)

Call: rarely
Override: rarely

The system calls StretchTouch when the user touches an object while the stretch tool is active. Viewable_StretchTouch calls WaitTouchKind to determine if the user's touch was a tap or a press, then calls Touch or StretchPress, respectively.

You should override StretchTouch if you want objects of your class to perform some other action when the user touches them with the stretch tool active.

StretchPress

operation StretchPress(touchInput: TouchInput)

Call: rarely
Override: sometimes

The system calls StretchPress when the user presses on an object while the stretch tool is active. Viewable_StretchPress calls CanStretch. If CanStretch is false, StretchPress plays the error sound; otherwise it calls StretchTrack.

You should override StretchPress if you want objects of your class to perform some other action when the user presses on them with the stretch tool active. For example, your object might stretch or shrink by fixed increments.

StretchTrack

operation StretchTrack(touchInput: TouchInput)

Call: rarely
Override: never

The system calls StretchTrack while the user is stretching an object to implement the basic stretch features for viewable objects. Call StretchTrack if you want to track the user's action while stretching an object.

CanStretch
SetCanStretch

attribute CanStretch: Boolean
// operation CanStretch(): Boolean
// operation SetCanStretch(newValue: Boolean)

Call: sometimes
Override: rarely

Call CanStretch to test whether the object can be stretched. CanStretch simply returns the value of the object's can stretch view flag. You might override if objects of your subclass absolutely, positively refuse to stretch. Class Stamp is an example of viewables that won't stretch.

Call SetCanStretch to set whether the object can stretch. The newValue parameter indicates whether the object should be allowed to stretch. SetCanStretch sets the object's can stretch view flag.

Centered
SetCentered

attribute Centered: Boolean
// operation Centered(): Boolean
// operation SetCentered(newValue: Boolean)

Call: rarely
Override: rarely

Call Centered to test whether the object should be stretched from its center. Centered returns the value of the object's centered view flag.

Call SetCentered to set whether the object should be stretched from its center according to the given value. SetCentered sets the object's centered view flag.

ConstrainSize

operation ConstrainSize(VAR size: Dot)

Call: rarely
Override: sometimes

The system calls ConstrainSize when an object is being resized to ensure that its new dimensions fall within the limits allowed. Viewable_ConstrainSize makes sure that each component of the given dot is at least 12 pixels and no more than 1024 pixels.

You should override ConstrainSize if you want objects of your class to be constrained to different limits. For example, class Slider overrides ConstrainSize to constrain horizontal sliders differently from vertical sliders. The horizontal dimension of horizontal sliders can grow and shrink, but the vertical dimension can't change. The opposite is true for vertical sliders.


Tinkering and Scripting

OpeningTinkerWindow

operation OpeningTinkerWindow(tinkerWindow: TinkerWindow)


Call: never
Override: often

The system calls OpeningTinkerWindow to put the appropriate objects into a tinkering window after opening the window. Viewable_OpeningTinkerWindow puts these objects into the window:

Name of Object Description
Bytes Meter showing memory usage in bytes
Can Move On/off switch for can move setting
Can Copy On/off switch for can copy setting
Can Stretch On/off switch for can stretch setting
Show Label On/off switch for showing label
Border Label On/off switch for drawing border around label
Label Chooser Control for selecting position of label
Color Coupon showing content color
Shadow Coupon showing shadow
Script Coupon showing name of script (only in development versions)
Sound Coupon showing name of sound
Text Style Coupon showing text style

You should override OpeningTinkerWindow if your class defines any additional settings that users can manipulate while tinkering with the object. You should call the inherited OpeningTinkerWindow from your overriding method to be sure that all inherited objects are placed in the tinkering window.

For example, here's how class EditableClock overrides OpeningTinkerWindow to add a control to display or hide a second hand:

InheritedOpeningTinkerWindow(self, container);
MakeTinkerControl(container, iTinkerHasSecondHandSwitch, 
  operation_HasSecondHand);

MakeTinkerControl

intrinsic MakeTinkerControl(container: Viewable; controlPrototype: 
Viewable; attributeNumber: Unsigned)

Call: sometimes
Override: never

Call MakeTinkerControl from your override of OpeningTinkerWindow to add new controls to your custom tinker window. For the container parameter, pass the container that was passed in to your OpeningTinkerWindow method. For the attribute number, pass a constant that consists of "operation_" followed by the name of the attribute that should be associated with the control.

The file Indexicals.h contains a number of tinker control prototypes that you can pass in the controlPrototype parameter. Look for indexicals that begin with the string "iTinker."

Here are several calls to MakeTinkerControl from class Animation's OpeningTinkerWindow method:

MakeTinkerControl(container, iTinkerInMotionSwitch, 
  operation_InMotion);
MakeTinkerControl(container, iTinkerCanBounceVerticalSwitch,
  operation_CanBounceVertically);
MakeTinkerControl(container, iTinkerHorizontalVelocityMeter,
  operation_HorizontalVelocity);

ClosingTinkerWindow

operation ClosingTinkerWindow(tinkerWindow: TinkerWindow); noFail

Call: never
Override: rarely

The system calls ClosingTinkerWindow before closing a tinkering window to give the object a chance to update itself based on the settings that the user has tinkered with. Viewable_ClosingTinkerWindow updates the object's script if it finds a script coupon. Most controls, including switches, update their settings dynamically and don't have to be handled by ClosingTinkerWindow.

You should override ClosingTinkerWindow if your subclass defines any additional settings that defer their updating (this usually means that they're not switches). You should call the inherited ClosingTinkerWindow from your overriding method to be sure that all inherited settings are updated properly.


Dropping and Swallowing

CanAccept

operation CanAccept(candidate: Viewable; where: Dot): Boolean

Call: rarely
Override: sometimes

When the user drags something over the object, the system calls CanAccept to test whether the candidate object can be a subview of the object. The where parameter gives the location of the hovering candidate object. CanAccept returns a Boolean value indicating if the object can be accepted. Viewable_CanAccept returns true if CanContain(self) is true or if the candidate object is already a subview of the object.

You should override CanAccept to perform other tests if you want objects of your classes to use other tests for deciding whether to accept an object. For example, class Panel overrides CanAccept to always return true, indicating that panels always accept other objects.

CanContain

attribute CanContain: Boolean
// operation CanContain(): Boolean

Call: rarely
Override: sometimes

The system calls CanContain to test whether the object can contain other objects; that is, whether the object can have subviews. Viewable_CanContain simply returns the value of the object's can contain view flag.

You should override CanContain if you want objects of your class to use other tests for determining if they can contain objects. For example, class Snapshot overrides CanContain to ignore the can contain view flag and always return false, indicating that snapshot objects can never contain other objects.

SetCanContain

attribute CanContain: Boolean
// operation SetCanContain(newValue: Boolean)

Call: rarely
Override: rarely

Call SetCanContain to set whether the object can have subviews according to the given value. SetCanContain simply sets the object's can contain view flag.

CanAcceptCoupon

operation CanAcceptCoupon(coupon: Coupon; part: Signed): Boolean

Call: rarely
Override: often

The system calls CanAcceptCoupon when the user drags a coupon over the object to test whether the object can accept that coupon. The part parameter indicates which part of the object is beneath the hovering coupon. CanAcceptCoupon returns a Boolean value indicating if the coupon is accepted. Viewable_CanAcceptCoupon accepts view, shadow, script, color (in label, text, title, image, content, shadow, or line parts), and text or textstyle (in label, text, or title parts) coupons.

You should override CanAcceptCoupon if you want objects of your class to use different tests in deciding whether to accept coupons. You can choose to call the inherited implementation or not, depending on whether you want to add to or completely redefine the set of acceptable coupons.

DroppedFromWindow

operation DroppedFromWindow()

Call: rarely
Override: sometimes

The system calls DroppedFromWindow when a viewable has been dropped from the Magic Hat. Viewable_DroppedFromWindow hops the viewable to the trash if its enclosing card is locked. You should override if your viewable should act on its container, or hop to its proper location, or do anything at all when dropped from the Magic Hat.

For example, class AttributeStamp overrides DroppedFromWindow to check for conflicts between the new stamp and and other stamps on its superview. Many label stamp classessuch as class ElectronicMailLabelStamp and class PhoneLabelStampoverride to find a suitable subview of the enclosing card, hop themselves into position in that subview, then ask it to swallow themselves.

Swallow

operation Swallow(morsel: Object; where: Dot; realSwallow: Boolean): 
Boolean

Call: rarely
Override: sometimes

The system calls Swallow when the user drags an object (the "morsel") over a viewable to determine if the viewable can accept the dragged morsel and perform some action with itthat is, not simply add it as a subview. (You might find it helpful to think of it as digestion.) The morsel parameter is the object that the user is dragging. The where parameter gives the location of the hovering object.

If realSwallow is false, the caller is only testing to see if the object can be swallowed; Swallow doesn't actually swallow the object. If realSwallow is true, the object is swallowed if appropriate. Swallow returns a Boolean value indicating if the object can be swallowed. Viewable_Swallow always returns false, indicating that objects of class Viewable can't swallow other objects (although objects of many Viewable subclasses can swallow others).

You should override Swallow if objects of your class might ever swallow other objects. You should call the inherited Swallow if you want to retain the inherited criteria for swallowing objects.

SwallowFeedback

operation SwallowFeedback(morsel: Object; probe: Dot;
isSwallowing: Boolean; wasSwallowing: Boolean)

Call: rarely
Override: sometimes

Call SwallowFeedback to give the user visual feedback that a morsel has been swallowed (and will be properly digested). Viewable_SwallowFeedback just highlights the viewable if isSwallowing is true and wasSwallowing isn't. You should override if objects of your subclass should give swallowing feedback differently.

The isSwallowing parameter is true if the morsel is hovering over the viewable, and will actually be swallowed if the user drops it. The wasSwallowing parameter is true if the morsel was hovering the last time that SwallowFeedback was called. (So wasSwallowing is true if isSwallowing was true the last time.) So the system might call SwallowFeedback in a sequence like the following one:

Note that you can't depend on the morsel's existence, since it might have been destroyed just before the system called SwallowFeedback. Use HasObject to check for the morsel's existence if you need to use it in some way.

SpatOut

operation SpatOut(fromContainer: Viewable)

Call: rarely
Override: sometimes

The system calls SpatOut on a viewable when a container has rejected it.

Viewable_SpatOut does nothing. Override if your subclass should do something when it's spat out instead of swallowed. For example, you might want to display an announcement telling the user why the viewable was rejected.

CanChangeContainers

operation CanChangeContainers(newContainer: Viewable): Boolean

Call: rarely
Override: sometimes

The system calls CanChangeContainers when the user tries to drag an object out of its superview to test whether the object can move to a new superview. The newContainer parameter indicates the superview that the user wants to move the object to. CanChangeContainers returns a Boolean value indicating whether the object can move to the new superview. Viewable_CanChangeContainers always returns true.

You should override CanChangeContainers if you might ever want to restrict objects of your subclass from moving into other superviews. For example, class Eraser overrides CanChangeContainers to always returns false, preventing eraser objects from moving into other superviews.

ChangedContainers

operation ChangedContainers(oldContainer: Viewable; Viewable: Object)

Call: rarely
Override: sometimes

The system calls the object's ChangedContainers method when an object moves from one superview to another to give the object a chance to perform some action. The oldContainer and newContainer parameters indicate the superviews that the object has been moved from and to. Viewable_ChangedContainers does nothing.

You should override ChangedContainers if you want objects of your class to take some action when they're moved into a new superview. For example, class Animation overrides ChangedContainers to set the animation's moving flag, ensuring that the animation is moving when it's moved to a new container. This is how animations are set in motion when they're dropped from the Magic Hat. If you override ChangedContainers, be sure you call the inherited method from your override.

ChangedContents

operation ChangedContents(whatCausedChange: Viewable; intoFlag: 
Boolean); noFail

Call: rarely
Override: sometimes

The system calls ChangedContents for both superviews when a viewable object moves from one superview to another to give the superview objects a chance to perform some action. The intoFlag parameter indicates whether a viewable is moving into or out of the object: intoFlag is true if the viewable is being moved into the object and false if the viewable is moving out. Viewable_ChangedContents does nothing.

You should override ChangedContents if you want the objects of your class to take some action when their contents are changed. If you override ChangedContents, be sure you call the inherited method from your override.

MovedContents

operation MovedContents(whatMoved: Viewable), noFail

Call: rarely
Override: sometimes

The system calls MovedContents when a viewable's contents move. Viewable_MovedContents just calls NoticeChange. You should override if viewable of your subclass need to regulate how their contents move. For example, Class Corridor overrides MovedContents to align moved entrances with the corridor floor. Class ContainerWindow overrides to align moved objects with a grid, if the container window uses a grid.

FindContainerPosition

operation FindContainerPosition(margin: Dot; spacing: Dot; 
          overlap: Micron; VAR position: Dot)

Call: rarely
Override: rarely

Call FindContainerPosition to calculate an unoccupied position in the object for placing a newly-added subview. FindContainerPosition returns a dot that's suitable for a new subview in the position parameter. The margin parameter indicates the minimum spacing from the edge of the container. The spacing parameter indicates the minimum number of pixels between objects in the container.


Hopping

Hop

operation Hop(endPosition: Dot)

Call: sometimes
Override: never

Call Hop to guide a viewable through the most basic graceful hop from its starting position to the given end position. Hop calls HopFancy with the standard system hop delay, a standard acceleration, and transparency turned off. The acceleration is determined by dividing the standard horizontal and vertical accelerations by the default number of hop frames. These numbers are system constants, and are:

#define kHopFramesDefault  10
#define kHopDefaultHAcc 0
#define kHopDefaultVAcc  64*onePixel

Hop calls HopDelay on the indexical iSystem to get the system hop delay.

HopFancy

operation HopFancy(endPosition: Dot; acceleration: Dot
delayMilliseconds: Unsigned, semiTransparent: Boolean)

Call: often
Override: never

Call HopFancy to guide a viewable through a controllable hop from its starting position to the given end position. You can specify the horizontal and vertical acceleration in the acceleration parameter. The delayMilliseconds parameter determines the time interval between frames. And if the semiTransparent parameter is true, the viewable hops as a ghost.

The total number of frames in the hop is determined by the system constant kHopFramesDefault, which is defined to be 10.

PutAway

operation PutAway(), safe

Call: sometimes
Override: sometimes

Viewable_PutAway sends a PutAway call to each of the viewable's subviews, in front to back order. If objects of your subclass should tidy themselves away in some manner, you should override PutAway. For example, Class Icon overrides PutAway to move a disarrayed icon back to its native position with a fancy hop. Class Book overrides to hop a book back to its proper shelf and rearrange any other books that might have been stacked on top.


Typing and Scribbling

TypeKeys

operation TypeKeys(keys: Pointer; count: Unsigned): Unsigned

Call: rarely
Override: sometimes

The system calls TypeKeys when the user types a character on the on-screen keyboard or a physical keyboard attached to the device. If the object accepts the typing, TypeKeys returns the number of characters accepted. Viewable_TypeKeys gives the object's subviews a chance to accept the character by calling their TypeKeys methods until one of them accepts the character and returns a positive value.

You should override TypeKeys to accept the character if your object accepts keyboard typing. For example, class Calculator overrides TypeKeys to accept all characters that appear on its keyboard, such as numbers, +, *, and so on. You should call the inherited TypeKeys from your overriding method.

CanDrawIn

attribute CanDrawIn: Signed, readOnly
// operation CanDrawIn(): Signed

Call: rarely
Override: sometimes

Call CanDrawIn to check if it's okay to draw in this viewable.

The system calls the method ChooseableTool_GetToolTarget when the user touches a viewable object while a chooseable tool is active. GetToolTarget calls CanDrawIn as a part of its process of deciding how to handle the touch. CanDrawIn returns a constant that tells whether its okay to draw in this viewable, or if GetToolTarget should query elsewhere.

The constants returned by CanDrawIn are:

Name Value Description
kDontDrawHere 1 Don't allow drawing in this viewable
kAskSuperviewifCanDraw 0 Ask this viewable's superview if it allows drawing
kDrawHere 1 Go ahead and draw in this viewable
kAskUsertoDecide 2 Ask the user if she wants to change this viewable (for example, ask if the user wants to unlock a locked card)

Viewable_CanDrawIn returns kAskSuperviewifCanDraw. Override if your subclass should return something else or perform a test to decide.


Selecting

Selected

attribute Selected: Object, readOnly, safe
// operation Selected(): Object, safe, noFail

Call: sometimes
Override: sometimes

Call Selected to get the object's selection. Viewable_Selected returns the nil object, because Viewable objects don't support selection (although objects of many Viewable subclasses support selection).

You should override Selected to return the object's selection if objects of your class implement selection. For example, class ChoiceBox overrides Selected to return the item in the choice list that's the current selection. Class TaskView overrides to return the current task.

SelectFirstTextField

operation SelectFirstTextField(): TextField, safe

Call: sometimes
Override: sometimes

SelectFirstTextField returns the text field that is the "first" field in the viewable. Viewable_SelectFirstTextField returns nilObject, since the default viewable object doesn't have editable text. You should override this method if your subclass contains text fields.

Class TextField overrides this method to make the text field it's called on be the current typing target, then return itself. Class EditableList overrides to return its first edit cell.

SelectNextTextField

operation SelectNextTextField(currentField: TextField): TextField, safe

Call: sometimes
Override: sometimes

SelectNextTextField returns the text field that is "next" after the current text field. Viewable_SelectNextTextField returns nilObject, since the default viewable object doesn't have editable text. You should override this method if your subclass contains more than one text field. For example, Class EditableList overrides this method to return the field that's one column over from the current selection if one exists, or at the beginning of the next row if the current selection is at the end of a row.


Getting and Setting Entities

Entity

attribute Entity: AddressCard, safe
// operation Entity(): AddressCard, safe

Call: sometimes
Override: sometimes

Call Entity to get the entity that's associated with an object.

The system calls Entity to get the object's Entity object. Viewable_Entity returns the nil object, indicating that Viewable objects don't have an associated entity (although many Viewable subclasses have entities). You should override Entity to return the associated entity if objects of your class have an associated entity.

SetEntity

attribute Entity: AddressCard, safe
// operation SetEntity(newEntity: Object), safe

Call: sometimes
Override: sometimes

Call SetEntity to set the entity that's associated with an object to the given object.

The system calls SetEntity to set the object's entity object. Viewable_SetEntity does nothing, indicating that Viewable objects don't have an associated entity (although many Viewable subclasses have entities). You should override SetEntity to set the object's associated entity to newEntity if objects of your class have an entity.


Debugging

Validate

overrides Validate

Call: rarely
Override: sometimes

The system calls Validate to try to determine if the object is valid. If Validate detects any problem or inconsistency, it causes an exception or posts an appropriate error message.

Viewable_Validate first calls its inherited implementation, then checks the following conditions and performs the following actions if the conditions are true:

Condition Action if True
The object's superview is not a viewable Prints debug message: (id) has a bad superview: (id)
The object is not a subview of its superview Prints debug message: (id) has a bad superview: (id)
The object's subview is not a viewable Prints debug message: (id) has a bad subview: (id)
The object has invalid view flags set Prints debug message: (id) has unused view flags set: (flags)
The object's script is not a member of class Script or class CompiledScript Prints debug message: (id) has a bad script: id

Viewable_Validate also calls ValidateImplements for these object/class pairs:

Object Class
Labelstyle field TextStyle
Color field Color
Shadow field Shadow
Sound field Sound

You should override Validate if you want objects of your class to perform any additional validity checking. You should call the inherited Validate from your overriding method to ensure that the superclass' verification checks are applied.