## button-group.api
#
# Manage a group of radiobuttons
# or any similar ON/OFF widgets.
#
# "Strictly speaking, a button_group is not a widget.
# It provides a mechanism for managing a collection
# of widgets, some of which can be selected, either
# by the user or under program control. A typical
# use would involve a collection of toggle buttons,
# each setting a piece of shared program state to
# some value. Using a button_group, the user could
# change the state by clicking on one of the buttons;
# the button indicating the previous state setting
# would be automatically set off."
#
# --- p20, Gansner+Reppy's 1993 eXene widget manual,
# http://mythryl.org/pub/exene/1993-widgets.ps
#
# A button group is not a widget, may not be included
# in a widget tree, and does not make its child
# widgets visible -- all widgets in the Button_Group
# must be separately inserted into a widget-tree
# for display.
#
# Button_Group members may be any widgets; the name
# is descriptive rather than definitive. In practice
# they need to be something which graphically displays
# its on/off status for the user.
#
# Button_Group manages two two boolean state variables
# per button: 'on' and 'active'.
#
# 'on' reflects the ON/OFF state of the button.
#
# 'active' reflects whether the user is allowed
# to change the state of the button by
# clicking on it.
#
# User-supplied per-button callback functions are used
# to signal button state transitions from 'on to 'off'
# and 'active' to 'inactive'. These functions are called
# only on transitions; they are not triggered by the
# original state.
#
# User clicks on inactive buttons have no effect.
# Assuming the clicked button is active, mouse
# button 1 sets it and mouse button 2 sets 'off'.
# In more detail:
#
#
# Clicking mouse button 1 on a 'on' button does nothing.
# Clicking mouse button 1 on an 'off' button puts it
# in 'on' state. If it is in a radiobutton group (i.e.,
# at most one button permitted to be ON at a time),
# any other currently ON button has its on_off_callback()
# called with FALSE. The clicked button
# then has its on_off_callback invoked with TRUE.
#
# Clicking mouse button 2 on an OFF button does nothing.
# Clicking mouse button 2 on a ON button sets it to
# OFF, after which its on_off_callback is invoked with
# FALSE.
#
# All clicks (and all other events) are passed normally
# down the widget tree after button-group processing.
#
# Buttons may be dynamically added to a Button_Group
# using insert() and append().
# Compiled by:
#
src/lib/x-kit/widget/xkit-widget.sublib# Compiled by:
#
src/lib/x-kit/widget/xkit-widget.sublib# This api is implemented in:
#
src/lib/x-kit/widget/old/lib/button-group.pkgstipulate
package wg = widget; # widget is from
src/lib/x-kit/widget/old/basic/widget.pkg package wt = widget_types; # widget_types is from
src/lib/x-kit/widget/old/basic/widget-types.pkgherein
api Button_Group {
exception BAD_INDEX;
exception ONLY_ONE_RADIOBUTTON_MAY_BE_ON;
Button_Group;
Button_Group_Member
=
{ button: wg::Widget, # Widget to be included in Button_Group.
initial_state: wt::Button_State, # Initial state of button.
on_off_callback: Bool -> Void, # Fn to be called when widget becomes on/off.
active_callback: Bool -> Void # Fn to be called when widget becomes in/active.
};
make_button_group: wg::Root_Window -> List(Button_Group_Member) -> (Button_Group, List(wg::Widget));
make_radiobutton_group: wg::Root_Window -> List(Button_Group_Member) -> (Button_Group, List(wg::Widget));
#
# The only difference between these two calls
# is that the former allows multiple buttons
# to be in the 'on' state at the same time;
# the latter allows only one button to be 'on'
# at any given time.
#
# These functions accept a root window
# and the list widgets to be included in
# the widget-set.
#
# They return the widget set and a list
# of wrapped widgets.
#
# ONLY_ONE_RADIOBUTTON_MAY_BE_ON is raised if more
# than one of the buttons supplied to
# make_radiobutton_group is ON.
#
insert: Button_Group -> (Int, List(Button_Group_Member)) -> List(wg::Widget);
#
# Insert given List(Button_Group_Member) before the nth
# current member of the internal button list, where the first
# element is numbered 0. Impractical index values raise BAD_INDEX.
#
# ONLY_ONE_RADIOBUTTON_MAY_BE_ON will be raised if the insertion results
# in multiple buttons being ON in a radiobutton set.
append: Button_Group -> (Int, List(Button_Group_Member)) -> List(wg::Widget);
#
# append button_group (n,list) is equivalent to
# insert button_group (n+1,list)
set_button_state: Button_Group -> List((Int, Bool)) -> Void; # Set ON/OFF state of button.
#
# Set indicated buttons to given ON/OFF states.
# Both active and inactive buttons may be set.
# The list is processed sequentially, with
# actions taken just as though the user had
# clicked on the buttons; in particular, when
# a button in a radiobutton set ON, the
# previously ON button will be set OFF.
set_button_active_state: Button_Group -> List( (Int, Bool) ) -> Void; # Set ACTIVE/INACTIVE state of button.
get_on_buttons: Button_Group -> List( Int ); # Get all buttons currently 'on'.
get_button_states: Button_Group -> List( wt::Button_State ); # Get ON/OFF state of all buttons in set.
};
end;