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