The C64 OS Programmer's Guide is being written
This guide is being written and released and few chapters at a time. If a chapter seems to be empty, or if you click a chapter in the table of contents but it loads up Chapter 1, that's mostly likely because the chapter you've clicked doesn't exist yet.
Discussion of development topics are on-going about what to put in this guide. The discusssions are happening in the C64 OS Community Support Discord server, available to licensed C64 OS users.
C64 OS PROGRAMMER'S GUIDE
Class Reference: TKSBar:TKCtrl:TKView:TKObj
Overview
TKSBar
is a concrete subclass of TKCtrl. It
is a fairly complex class with a lot of behavior, but its configurability is limited to
horizontal or vertical.
A TKSBar
object is a scroll bar which consists of a striped background track,
a solid scroll bar nub which is proportionally sized to visually represent the length of the
scrollable content, and two buttons that come together at one end. In a vertical scroll bar
the buttons are up and down and appear together below the scroll track. In a horizontal
scroll bar the buttons are left and right and appear together to the right of the scroll
track.
A scroll bar is rarely if ever instantiated manually. It is typically paired with a
TKScroll object which performs the work of allocating,
initializing and appending the TKSBar
into the view hierarchy. It is only
necessary to work with a TKSBar
directly if you are implementing your own
kind of scrolling class, but even in that case, you could profitably subclass
TKScroll and let it handle the creation and set up of
its scroll bars.
Basic navigation with a scroll bar is as follows:
The nub may be dragged to scroll long content quickly but roughly. The track can be clicked above or below the nub to scroll the content by exactly one page. Page length is defined dynamically as the number of visible content rows minus one. Or if it's a horizontal scroll bar a "page" is the number of visible content columns minus one. The scroll buttons can be clicked to scroll the content 4 rows (or 4 columns) at a time.
There are several advanced navigation options:
Click and hold on the track above or below the nub to scroll continuously in page-sized incremements. Click and hold on the up/down or left/right buttons to scroll continuously in 4 row (or 4 column) increments. Holding LEFT-SHIFT while clicking the up/down or left/right buttons slows down the scroll speed but increases the precision, by scrolling the content only one line at a time instead of 4. LEFT-SHIFT can also be used to continuously scroll with single-line precision. Hold the COMMODORE key and click the up, down, left or right button to scroll the content all the way to that end in one step.
The mouse wheel can be rolled over a TKSBar
to scroll its content. Hold the
COMMODORE key while rolling the wheel jumps the content to the start or end in one
step. When the mouse wheel is rolled over a TKScroll
object which is coordinating with one or more scroll bars, the wheel events are routed to
the vertical scroll bar, if one exists.
Subclassing notes
TKSBar
is a very complicated and specific class. Subclassing it is possible
but practically speaking it is unlikely to be necessary.
Class Definition
//os/tk/h/:tksbar.h
Subclass Method Overrides
Init (init_)
During initialization, TKSBar
is configured as a continuous control, the
cf_cont
flag is set on the cflags
property. The repeat timer
(rtvalu
) is set to 3, which 1/20th of a second. The valtype
is
configured as a 2-byte integer (or a 16-bit word). This allows scroll bars to scroll
through up to 65,536 rows or columns of content.
The orientation of the scroll bar is passed to the init_
routine in the
accumulator. This sets the orient
property and also affects the initial
sizing and anchoring of the scroll bar.
Horizontal and vertical constants are not defined, but there is a note about them in the //os/tk/s/:tksbar.s header. Horizontal is 0 and and vertical is 1. This can be remembered by the mnemonic that "1" is a tall and narrow symbol, corresponding with the tall and narrow layout of the vertical scroll bar.
ldy #init_ jsr getmethod lda #1 ;tall and narrow = vertical jsr sysjmp
Scroll bars, vertical and horizontal, enabled and disabled.
Left Mouse Down (musdown_)
Mouse down performs a complex hit testing procedure to determine which part of the
scroll bar has been hit; the track before the nub (0), the nub (1), the track after the
nub (2), the up or left button (3), the down or right button (4). If the hit part is
the nub or either of the two buttons (1, 3 or 4) it sets the cf_hilit
flag on
the cflags
property. Clicking the track, either above or below the nub,
does not highlight any part of the scroll bar.
The hit part, nub pixel size, original mouse position and original scroll offset are recorded on class properties to assist with dragging and continuous firing calculations.
Mouse Moved (musmovd_)
Low-level left mouse tracking events are converted into calls to the musmovd_
method on TKSBar
instances. The hit part from left mouse down is consulted.
If the hit part is not the nub (1), only the superclass version of this method is called.
If the hit part was the nub (1), then a complex set of calculations are carried out to
determine the distance scrolled and compute the new position of the scroll nub which is
updated as the nub offset (noboff
) property.
The send action sendact_
method is called on this
every time
the scroll nub is dragged.
Left Mouse Up (musup_)
On mouse up the cf_hilit
flag on the cflags
property is cleared
so the scroll bar draws in its normal state again.
Left Mouse Click (musclik_)
If the cf_disab
bit of the scroll bar's cflags
property is set
then a click does nothing. The superclass method is called and no other custom behaviors
of TKSBar
occur.
The hit part from mouse down is consulted. The low-level mouse modifier flags
(musmods
) is checked for the mus_cbm
flag to perform a scroll
jump, or the mus_shft
flag to set the decrement to 1. Otherwise, the decrement
is set to 4. The nub position is recalculated, the scroll position (the value
property) is updated, and the sendact_
method is called.
Resize (resize_)
When a scroll bar is resized, it calls an internal recalc
routine which
performs a complex recalculation of all the computed properties:
- scrollable lines (
scrlns
) - nub size (
nubsz
) - nub movable lines (
nublns
) - nub offset (
nuboff
) - page size (
pagesz
)
Draw (draw_)
The draw method of TKSBar
takes the orientation into consideration. It also
takes the cf_hilit
and cf_disab
flags on the cflags
property into consideration. Finally, it takes the orient
property into
consideration.
The track and buttons are redrawn first. Then the size and position of the nub is used
to redraw it over the track. If the cf_hilit
flag is set, the appropriate
segment of the scroll bar is drawn with the selected color.
Control Methods
Method | Description | Offset |
---|---|---|
sendact_ | Send the action to the parent view | 64 |
Send the action to the parent view (sendact_)
The nub's offset is computed first. And then the superclass's sendact_
method
is called. When TKScroll instantiates the a
TKSBar
it assigns itself as the target. Thus, sendact_
targets
the coordinating object, but it is the responsibility of the coordinating object to
set itself as the target.
The action method called on the target is adjust_
. It is therefore necessary
that the coordinating object conforms to the class methods
TKScroll, insofar as having an adjust_
method at the same method offset. This would automatically be the case for any subclass
of TKScroll.
Scroll Bar Methods
Method | Description | Offset |
---|---|---|
reflect_ | Reflect content view's scroll offset | 79 |
recalc_ | Recalculate computed properties | 82 |
Reflect content view's scroll offset (reflect_)
The reflect_
method is called when the coordinating class changes the scroll
offsets of its content view.
For example, TKScroll supports keyboard commands to
scroll and page through its content. After changing the scroll offsets of its content view
it has to call reflect_
on its own TKSBar
objects. This method
then retrieves a reference to that content view by following the pointers to its parent
and then to the parent's ctntview
property.
This makes it a requirement that any coordinating class that embeds a TKSBar
must conform the TKScroll class's object definition,
insofar as having a pointer to its content view at the same object property offset. This
would automatically be the case for any subclass of
TKScroll.
reflect_
potentially moves the position of the scroll nub, but does not
recalculate the scroll nub's size.
Recalculate computed properties (recalc_)
The recalc_
method recalculates all of the computed properties:
- scrollable lines (
scrlns
) - nub size (
nubsz
) - nub movable lines (
nublns
) - nub offset (
nuboff
) - page size (
pagesz
)
This is called automatically by the TKSBar
's resize_
method.
If the size of the content changes, the size of the nub and related properties have to be
recalculated. This can be performed either by calling recalc_
directly, or
by invalidating the size of the coordinating parent class, which will force a
resize_
method call, which indirectly calls recalc_
.
This is handled by the coordinating class, TKScroll.
If you intend to implement an alternative to TKScroll
it is necessary to understand how resize_
works and when to call it. When
only the size of the content to be scrolled changes, the size of the TKSBar
does not change. The scroll offset of the nub also does not necessarily change, for example,
if the scroll offset is zero, the nub will remain at the top or left of the track. However,
the size of the nub will change, and the distance the content will be scrolled relative
to the distance that the scroll nub is moved will change. The numbers necessary to make
these calculations correct are updated when recalc_
is called.
Object Definition
//os/tk/s/:tksbar.s Object Size: 65 (+3) bytes
Display Properties
Property | Description | Size | Offset |
---|---|---|---|
orient | Orientation | 1 | 54 |
Orientation (orient)
During initialization orient
is set from the value passed in the accumulator.
This property cannot be changed in isolation. Anchoring properties are set during
init_
that correspond to the orient
property. These associated
properties would have to be changed manually if the orient
property were
ever changed.
In practice, the TKScroll class deletes and recreates
TKSBar objects from scratch when its setbar_
method is called.
The values that this property can have are not defined as constants.
Constant | Value | Notes |
---|---|---|
— | 0 | Horizontal |
— | 1 | Vertical |
Computed Properties
Property | Description | Size | Offset |
---|---|---|---|
scrlns | Scrollable Lines | 2 | 55 |
nubsz | Nub Size | 2 | 57 |
nublns | Nub Movable Lines | 2 | 59 |
nuboff | Nub Offset | 2 | 61 |
pagesz | Page Size | 2 | 63 |
None of the computed properties should ever by manually changed. These should be considered either private, or read-only.
Modifying one of these properties to anything other than the value it is set to after calling
recalc_
would result in improper display or improper behavior and could in
theory lead to crash or a lockup by infinite loop.
Relationships
Inherits from: TKCtrl
Parent Section: Class Reference
Next Section: Subclassing
Next Chapter: Writing an Application
Table of Contents
This document is subject to revision updates.
Last modified: Nov 21, 2024