Defined in Viewable.Def Abstract Inherits from Linkable
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.
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.
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 |
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.
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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) |
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 |
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 |
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 |
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 |
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 |
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 |
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.
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.
#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.
#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.
#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.
#define visibleMask 0x10000000
Set this flag if your viewable object should be visible. The Visible and SetVisible methods use this flag.
#define centeredMask 0x08000000
Set this flag if your object should be stretched from its center. The Centered and SetCentered methods use this flag.
#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.
#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.
#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.
#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.
#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.
#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.
#define canContainMask 0x00004000
Set this flag if your viewable object can contain other objects. The CanContain and SetCanContain methods use this flag.
#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.)
#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.
#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.
#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.
#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.
#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.
#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.
#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.
#define inAboutToShowMask 0x00000010 #define inAboutToHideMask 0x00000008
These two flags are debugging flags used by AboutToShow and AboutToHide. You shouldn't use them.
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
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
intrinsic RedrawNow; safe; common Call: sometimes Override: never
Call RedrawNow to perform all pending redrawing.
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.
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. |
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
For a description of what highlighting is and how to draw your viewables in a highlighted state, see the description of the Draw method.
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.
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.
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 |
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)
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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).
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.
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.
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
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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
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;
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.)
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.
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.
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.
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.
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.
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.
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.
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
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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);
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);
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.
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.
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.
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.
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.
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.
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.
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:
SwallowFeedback(morsel, probe, true, false)
SwallowFeedback(morsel, probe, true, true)
SwallowFeedback(morsel, probe, false, true)
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.