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: TKButton:TKCtrl:TKView:TKObj
Overview
TKButton is a concrete subclass of TKCtrl.
It draws a single line button with text and optionally a icon on the left end, depending
on how it's configured.
A TKButton object can be configured as a standard push button, a cycle button,
a checkbox or a radio button. Push buttons and cycle buttons may optionally be configured
as continuous, allowing the user to click and hold on the button and its action is triggered
repeated until the mouse button is released.
There are several configurable options to customize a TKButton to fit the
requirements of the user interface.
Subclassing notes
TKButton already has a fair number of configurable options and modes. It
could be subclassed to add other options, but this is not usually required.
Class Definition
//os/tk/h/:tkbutton.h
Subclass Method Overrides
Init (init_)
During initialization, TKButton is anchored top, left with a height of 1.
It defaults to a push button (bt_psh) with a title of "Button". It has a
default left padding of 1. This puts a single space between the start of the button
and the start of the button text. This can be adjusted later for tight contexts where
the button text needs to fill the button.
Default and adjusted TKButton left padding
Left Mouse Down (musdown_)
Mouse down sets the cf_hilit flag on the cflags property so the
button draws in a highlighted color.
The state of the COMMODORE key is also read from the mouse down event and affects a cycle direction flag. Without the COMMODORE key the cycle direction value is +1, with the COMMODORE key held down the cycle direction value is -1. This flag is only relevant if the button configured as a cycle button.
Left Mouse Up (musup_)
On mouse up the cf_hilit flag on the cflags property is cleared
so the button draws in its normal state again.
Left Mouse Click (musclik_)
A click event has several different behaviors depending on how the button is configured.
If the cf_disab bit of the button's cflags property is set
then a click does nothing. The superclass method is called and no other custom behaviors
of TKButton occur.
If the button is a checkbox, bt_chk, the cf_state bit is toggled
on the cflags property.
If the button is a radio button, bt_rad, the method setstate_ is
called on this button. The setstate_ method is used because there is logic
that affects the state of the other radio buttons in a circularly linked set.
A cycle button, bt_cyc, must have its value set to a single byte.
In the current implementation cycle buttons are limited to an 8-bit unsigned range. The
value is read and the cycle direction value which was determined during mouse
down is added to the value. A range check is then performed. If value is
greater than maxval it is replaced by minval. If value
is less than minval it is replaced by maxval.
Lastly, the button's action is triggered. The state of a radio button or a checkbox being toggled, or the value of a cycle button being incremented or decremented, is independent of the button's action being fired.
For a cycle button, it is the responsibility of the action method to update the cycle button's title based on its new value.
For example, you may configure a TKButton as a cycle button with the intention
of using it to show the months of the year. January may have a value of 0 and December
a value of 11. The controlling code should have a string store for months of the year.
When the button is instantiated it should be given a minval of 0 and a
maxval of 11. It should then be assigned a current value that falls within
that range.
To set the initial title of the button, call the settitle_ method. The
initial value should be used to retrieve a string pointer from the string
store and that pointer can be passed to the settitle_ method. Later, when
the button is clicked, its value is automatically cycled and kept within the min/max
range, but its title is not updated automatically. The action routine must call the
settitle_ method on the sender, and use its current value
to lookup the string pointer for its new title.
Draw (draw_)
The draw method of TKButton takes many state and configuration properties into
consideration.
Radio buttons and checkboxes do not draw a bounding box. Therefore, they have the appearence of a radio or checkbox icon to the left of what appears to be a label. However, because that label is the title of the button object, clicking anywhere inside the bounds of the button triggers that button's behavior. This is why clicking a checkbox's label toggles its checked state.
A radio button or checkbox may be in a surrounding context that is reversed or not reversed.
TKButton as radio buttons and checkboxes in reversed and non-reversed contexts
When a radio button or checkbox will be drawn in a reversed context, such as on a Utility
panel as shown above, the cf_rvrs bit of the cflags should be
set. The bcolor property must be set to match surrounding context.
All other button types have a bounding box which necessitates drawing in reverse. The button text and any icon are always drawn in the global background color. The foreground of the bounding box depends on the state of the button. When disabled it uses the disabled color from the system's color theme. When highlighted it uses the selected color from the color theme.
Push buttons and cycle buttons may also optionally be flagged as the default control by
setting the cf_deflt bit on the cflags property. A button that
is not disabled and not highlighted (i.e., the mouse button is not held down on it) use
either the button color or the default button color from the system's color theme.
When a radio button or checkbox is drawn in the highlighted state, only the icon is drawn with the highlighted color.
Radio buttons are drawn with the radio button icon first, checkboxes with the checkbox icon,
both have checked and unchecked versions depending on the cf_state bit of
cflags. Cycle buttons draw the cycle icon first.
Left padding, defined by the lpad property, is drawn following any icon.
The title of a button is drawn immediately after the left padding, and thus always left aligned. The title text of the button goes to the end of the string and then the remainder of the button's width is padded with spaces. If the button's width is too narrow to show the full title text, the title is automatically clipped at the right end of the button. There is currently no option for fixed right padding. Therefore, clipped button title text always ends up flush with the right end of the button.
Button Methods
| Method | Description | Offset |
|---|---|---|
| settitle_ | Set title string pointer | 79 |
| setstate_ | Set button's state | 82 |
Set title string pointer (settitle_)
| Input | Description |
|---|---|
| RegPtr → String Pointer | Null-terminated button title string |
| Output | Description |
| - | None |
Sets the string pointer into the title property. Marks the button dirty.
This method must be called by the action routine of a cycle button in order to update the title on the button to match the new value.
Set the button's state (setstate_)
| Input | Description |
|---|---|
| A → 0 | Uncheck the button |
| A → !0 | Check the button |
| Output | Description |
| - | None |
Changing the state of a button sets or unsets the cf_state bit on the
cflags property. Any button so affected by this method is also marked as
dirty.
If the button is a checkbox, bt_chk, this method affects this object only.
If the button is a radio button, bt_rad, this method affects this button
object first. If the state of this button object becomes unchecked then no other buttons
are affected. If the state of this button becomes checked, then all the other button objects
in the circularly linked chain of related buttons is unchecked and marked dirty.
When creating TKButton objects of type bt_rad it is necessary
to link the objects together that belong to a set. See the description of the
bnext property below.
Object Definition
//os/tk/s/:tkbutton.s Object Size: 62 (+3) bytes
Action Properties
| Property | Description | Size | Offset |
|---|---|---|---|
| btype | Button type | 1 | 54 |
| title | Button title | 2 | 55 |
| lpad | Left padding | 1 | 57 |
| bnext | Next button | 2 | 58 |
| minval | Minimum value | 1 | 60 |
| maxval | Maximum value | 1 | 61 |
Button type (btype)
During initialization btype is set to bt_psh making the object
a push button.
This property can be changed after initialization to select which type this button object should be.
#setobj8 this,btype,bt_cyc
| Constant | Value | Notes |
|---|---|---|
| bt_rad | 0 | Radio button |
| bt_chk | 1 | Checkbox |
| bt_cyc | 2 | Cycle button |
| bt_mnu | 3 | Menu button (not implemented) |
| bt_psh | 4 | Push button |
Button title (title)
This property holds the pointer to the button's title string. This property should only be
set with the settitle_ method.
Left padding (lpad)
This property holds the fixed number of columns of padding between the icon, if there is an icon, and the start of the button's title. The default is 1.
#setobj8 this,lpad,0 #setobj8 this,lpad,2
Next button (bnext)
Radio buttons affect each other. They must therefore by linked together in a group. This
property is the mechanism of grouping them together. By default bnext is set
to null, indicating that it is not part of a group of buttons.
The bnext property of one radio button object must be pointed to the next
radio button object in the set. The last radio button in the set must have its
bnext property pointed back to the first in the set, forming a circular,
singly-linked list.
;Link 3 Radio Buttons linkrad .macro #storeget views,\1 #stxy this ldy #bnext lda views+(\2*2)+0 sta (this),y iny lda views+(\2*2)+1 sta (this),y .endm ;rad0.bnext = rad1 #linkrad 0,1 ;rad1.bnext = rad2 #linkrad 1,2 ;rad2.bnext = rad0 (close the loop) #linkrad 2,0
This linking procedure benefits from a macro, but you'll need to customize the macro for the object pointer store you're using.
Minimum and Maximum value (minval and maxval)
Only cycle buttons make use of a minimum value. It's used to help automate the most common
case of cycling through a numeric range. If cycling forward would exceed the
maxval the value is set to minval instead. If cycling
in reverse would fall below minval the value is set to
maxval instead.
If value is manually set to something outside the min/max range, it will
be moved back to within the min/max range the first time the user clicks it. If minval
is set larger than maxval the behavior is undefined.
The minval and maxval are 8-bit unsigned integers. Therefore,
cycle buttons only support cycling from 0 to 255.
#setobj8 this,minval,5 #setobj8 this,maxval,12
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: Oct 11, 2024
