Book Contents          Previous Chapter          Next Chapter

Scrolling

Scrolling

This chapter describes how to make Magic Cap viewables that scroll their contents and subviews. Most of the information in this chapter is useful only if you create new viewable subclasses and you want to customize their scrolling behavior, although the simple process of creating scrolling objects of existing classes is also discussed. Before reading this chapter, you should be familiar with viewables.

About Scrolling

Some Magic Cap viewables, such as some telecards, notebook pages, and address cards, are too large to fit on the screen. You can put scroll arrows into your viewables to allow users to scroll the viewables and see more information.

Scrolling viewables

Viewables can be scrolled if they inherit from one of Magic Cap's three mixin classes that enable various kinds of scrolling: Scroller, Scrollable, and ScrollableByMicron. Magic Cap defines many scrollable classes that inherit from these classes, such as ContainerWindow, ScrollBox, and RuleView. You can include objects of these scrollable classes in your package. In general, you can add these scrollable objects simply by including them in your view chains and adding scroll arrow objects.

When you create your own viewable subclasses, you'll probably inherit from a class that already has scrolling behavior inherited from one of the scrolling mixins. However, if your viewable subclass doesn't already inherit scrolling behavior, you should inherit from one of the scrolling mixins. To create your own subclass of scrolling viewable, you'll inherit from one of the three mixin classes that enable scrolling, then override operations that customize scrolling for your viewables.

Most viewables can only scroll vertically. Among viewables defined by Magic Cap, only corridors support horizontal scrolling.

Creating Subclasses of Scrolling Viewables

This section describes how you can use built-in mixin classes to define your own classes of scrolling viewables. Magic Cap defines three mixin classes for scrolling, as described in the following table:

----------------------------------------------------------------------------------------------------------
mixin class         kind of scrolling enabled                                                               
----------------------------------------------------------------------------------------------------------
Scroller            Whole-unit or fine scrolling; contents and subviews can scroll by microns. For          
                    example, class Corridor inherits from this class.                                       
Scrollable          Whole-unit scrolling; contents and subviews can scroll by chunks or pages. For          
                    example, class RuleView inherits from this class.                                       
ScrollableByMicron  Whole-unit or fine scrolling; contents scroll but subviews are fixed in place. You'll   
                    rarely inherit directly from this class.                                                
                                                                                                            
----------------------------------------------------------------------------------------------------------

Each of the scrolling mixin classes shown in the table above enables a different kind of scrolling. Most scrolling viewables inherit from class Scroller, the most powerful of the three. The following sections describe each kind of scrolling, as well as the hierarchy of the scrolling mixin classes.

Cards can scroll although they do not inherit from any of these classes. When the user touches a scroll arrow on a card, Magic Cap calls the scroll arrow's ScrollCard operation to scroll the card. Cards can scroll as if they were members of class Scroller; that is, they perform whole-unit or fine scrolling of the card's contents and subviews.

Hierarchy of Scrolling Classes

The three scrolling mixin classes (Scroller, Scrollable, and ScrollableByMicron) can each be mixed in with class Viewable to create subclasses that have a particular scrolling behavior. The three scrolling mixin classes are related in a surprising way: they are connected in an inheritance hierarchy:

Scroller inherits from ScrollableByMicron, which inherits from Scrollable. Class Scrollable, at the root of the hierarchy, provides the basic feature shared by all viewables that can scroll: the ability to scroll their contents in chunks. Class ScrollableByMicron adds the ability for viewables to scroll their contents to a finer degree, in increments of microns. Class Scroller, the most powerful (and least descriptively named) class of the three, scrolls the subviews of its members as well as their contents.

Whole-unit Scrolling

You should inherit from class Scrollable if you want your viewable subclass objects to scroll their contents and subviews by chunks: a page or screenful at a time. If you inherit from class Scrollable, you should override operations PageUp, PageDown (and possibly PageLeft and PageRight) to define what action should occur when the user scrolls in the given direction.

Your subclass will typically override scrolling operations to update some internal value that indicates which part of the viewable is being displayed on the screen. Your viewable's Draw method should then use that internal value to determine where to start drawing the viewable. For example, class RuleView, which draws a scene's list of rules, keeps track of which rule is scrolled into view at its top.

Most viewables don't support horizontal scrolling and so don't override PageLeft or PageRight. Class Corridor is one of the few viewables that does override these operations and supports horizontal scrolling.

Class Scrollable also defines operations to scroll the viewable to its top, bottom, left, and right extremes. You can override these operations to perform the appropriate scrolling for your viewables.

Fixed-subview Scrolling

You should inherit from class ScrollableByMicron if you want your viewable subclass objects to scroll by microns while leaving subviews unscrolled. Class ScrollableByMicron adds an attribute, ScrollOffset, to keep track of the viewable's scrolled position. You can read ScrollOffset in your Draw method to determine where to start drawing.

When the user touches a scroll arrow, Magic Cap checks the arrow's scrollFlags field to determine whether to use fine scrolling; that is, scrolling by microns. Scroll arrows should set the following flag to use fine scrolling:

#define kUseScrollAmountMask	0x00000001

If this flag is set, the arrow's target will scroll by the number of microns indicated in the scroll arrow's scrollAmount field. Otherwise, Magic Cap will call one of the target's page-scrolling operations.

When you create a scrollable object, its contents should include scroll arrows that the user can touch. If you create a viewable subclass that inherits from class ScrollableByMicron, you should override its ArrowState operation to indicate whether the scroll arrows should be drawn, indicating that the user can scroll to see more of the viewable. Your overridden ArrowState method should check the viewable's ScrollOffset attribute or any other criteria to determine whether the scroll arrows should appear. You can use the following constants in your ArrowState return value to indicate which arrows should be shown:

// Return values for ArrowState

#define kScrollDownMask     0x10000000     // show down arrow
#define kScrollUpMask       0x01000000     // show up arrow
#define kScrollRightMask    0x00100000     // show right arrow
#define kScrollLeftMask     0x00010000     // show left arrow
#define kAllDirectionsMask  0x11110000     // show all arrows

Class ScrollableByMicron overrides PageUp, PageDown, PageLeft, and PageRight to scroll the viewable by 3/4 of its contents in the given direction and set the scroll offset accordingly. You can override any or all of these operations to customize your viewables' scrolling.

You should override MinimumScrollOffset and MaximumScrollOffset to set the limits you want to allow your viewables to scroll.

The implementation of ArrowState provided by class ScrollableByMicron uses the values returned by ScrollOffset, MinimumScrollOffset, and MaximumScrollOffset to determine whether to show the scroll arrows.

Fine Scrolling

Most scrolling viewables inherit from class Scroller. You should inherit from class Scroller if you want your viewables to perform fine scrolling, positioning their contents and subviews by microns. Examples of built-in classes that inherit from Scroller include Corridor, ScrollBox, and ContainerWindow.

Class Scroller defines no operations, attributes, or fields, and only overrides three operations, all to provide scrolling for subviews. Class Scroller inherits an attribute, ScrollOffset, to keep track of the viewable's scrolled position. You can read ScrollOffset in your Draw method to determine where to start drawing.

If you inherit from class Scroller, you should override ArrowState to indicate whether the scroll arrows should be drawn, indicating that the user can scroll to see more of the viewable. Your overridden ArrowState method should check the viewable's ScrollOffset attribute or any other criteria to determine whether the scroll arrows should appear. See the constants in the preceding section for possible ArrowState return values.

Class Scroller defines PageUp, PageDown, PageLeft, and PageRight to scroll the viewable by 3/4 of its contents in the given direction and set the scroll offset accordingly. You can override any or all of these operations to customize your viewables' scrolling.

You should override MinimumScrollOffset and MaximumScrollOffset to set the limits you want to allow your viewables to scroll.

Creating Objects

Creating Scrolling Viewables

To include objects of scrollable classes in your package, declare the scrollable object in your instance definition file, along with two scroll arrow objects, one for scrolling up and one for scrolling down. Your scroll arrows will typically be subviews of the scrolling viewable, but they need not be. Set the scroll arrows' image field to iScrollDownArrow or iScrollUpArrow. Set the arrows' scrollFlags fields to one of the following (these are also used as return values for ArrowState):

// scrollFlags values for ScrollArrow objects

#define kScrollDownMask     0x10000000	// show down arrow
#define kScrollUpMask       0x01000000	// show up arrow
#define kScrollRightMask    0x00100000	// show right arrow
#define kScrollLeftMask     0x00010000	// show left arrow
#define kAllDirectionsMask  0x11110000	// show all arrows

Magic Cap provides images only for vertical scroll arrows. In addition to these flags, you should set the following flag if you want the target to scroll finely when the user touches the arrow:

#define kUseScrollAmountMask	0x00000001

If you set this flag to enable fine scrolling, you should set the arrow's scrollAmount flag to indicate the number of microns to scroll. This flag only works for objects that support fine scrolling, which are cards and objects that inherit from ScrollableByMicron and Scroller.

The scroll arrows' target fields should refer to the viewable they scroll.

List View Scrolling

Magic Cap list views provide a special form of scrolling that doesn't use scroll arrow objects. You can make your list views scrollable by setting the listViewArrowMask flag in your list view. For more information, see the ListView chapter of Magic Cap Class and Method Reference.

Reference

For more information, see these topics in Magic Cap Class and Method Reference:

class Scroller

class Scrollable

operations and attributes:

PageDown
PageLeft
PageRight
PageUp

class ScrollableByMicron

operations and attributes:

ArrowState
MaximumScrollOffset
MinimumScrollOffset
ScrollOffset

indexicals:

iScrollDownArrow
iScrollUpArrow

Book Contents          Previous Chapter          Next Chapter