When this program is run, the user should:
o Choose items from the Demonstration menu to view and operate the various controls. (Note
that the Small Controls item is only available when the program is run on Mac OS X.)
o On Mac OS 8/9, choose Show Balloons from the Help menu and note the information in the help
balloons as the cursor is moved over the various controls.
o On Mac OS X, hover the cursor over the various controls and note the information in the help
tags.
o Click in the Finder and then back in the window/dialog, noting control
activation/deactivation.
o In the Bevel Buttons, Image Wells, Picture Controls, and Icon Controls window:
o Click in the various controls, noting in the window header the control part code returned
by FindControl (or immediately by TrackControl in the case of the non-tracking icon
controls).
o Click in the various controls and then release the mouse button both within and outside the
control, noting the control part code returned by TrackControl.
o In the Tab, Edit Text, and Clock Controls dialog:
o In the Edit Text Controls tab:
o Change the keyboard focus using the tab key and mouse clicks.
o Enter a name, age, and password, noting the effect of the key filter function attached to
the "Age" edit text control and the behaviour of the "Password" edit text control.
o Paste some text containing characters other than alphabetic characters, the space
character, and the period character to the "Name" edit text control, noting that the edit
text validation function strips out the "illegal" characters.
o Note the cursor shape change when the cursor is over the top two edit text controls.
o Click the Extract push button to extract and display the contents of the edit text
controls.
o In the Clock Controls Tab:
o Change the keyboard focus using the tab key and mouse clicks.
o Change the clock setting by typing and by using the integral little arrows.
o Click the Extract push button to extract and display the clock settings.
o In the Group Boxes, Arrows, and Progress Bar dialog:
o Change the group box settings, the settings of the controls within the group boxes, and the
(simulated) cache size setting controlled by the little arrows, and then click the Extract
button to extract and display the settings of the various controls.
o Click the disclosure triangle to show and hide the chasing arrows and indeterminate
progress bar.
o In the Sliders and User Pane Functions dialog:
o Operate the sliders and note the difference in the appearance of the dragged indicator in
the live scrolling and non-live scrolling variants of the sliders.
o Note the appearance, in the activated and deactivated modes, of the two custom "controls"
to the right of the two horizontal sliders. Also note that these controls are re-drawn, in
the appropriate mode, when an overlaying window or help balloon is removed (Mac OS 8/9).
o In the Text Boxes dialog, observe the auto scrolling variant and scroll the
non-auto-scrolling variant.
o On Mac OS X, observe the small controls in the Small Controls floating window.
Control3.h
defines
Constants are established for the resource IDs and dialog item numbers associated with the
various demonstrations.
typedefs
A variable of type BevelDocStruc will be used to hold references to the various controls
created in the Bevel Buttons, Image Wells, Picture Controls, and Icon Controls window.
Control3.c
Controls3.c is simply the basic "engine" which supports the demonstration. There is nothing in
this file which has not featured in previous demonstration programs.
doMouseDown
In the inContent case, if a mouse-down occurs in the Bevel Buttons, Image Wells, Picture
Controls, and Icon Controls window when it is the front window, the function
doBevelImagePictIconContent is called.
In the inGoAway case, the Bevel Buttons, Image Wells, Picture Controls, and Icon Controls
window is disposed of.
doUpdate
If the Bevel Buttons, Image Wells, Picture Controls, and Icon Controls window is open,
UpdateControls is called to redraw the controls in the appropriate mode.
doActivateWindow
If the Bevel Buttons, Image Wells, Picture Controls, and Icon Controls window is open, and if
it receives an activate event, GetRootControl is called to get a reference to the window's root
control. The controls are then activated or deactivated en masse.
BevelImagePictIcon.c
BevelImagePictIcon.c contains most of the source code relating to the Bevel Buttons, Image
Wells, Picture Controls, and Icon Controls window.
doBevelImagePictIcon
doBevelImagePictIcon opens a window, creates a relocatable block for a structure of type
BevelDocStruc (to whose fields references to the various controls will be assigned) and stores
the handle to this block in the window object.
The call to GetNewCWindow then creates the window. (Note that error handling here and in other
areas of the demonstration is somewhat rudimentary in that the program simply terminates.)
NewHandle creates the block for the variable of type BevelDocStruc and SetWRefCon stores the
handle to the block as a reference constant in the window object.
Before ShowWindow is called to make the window visible, the function doGetControls is called to
create the controls.
doGetControls
doGetControls creates the controls from the various 'CNTL' resources.
At the first line, if the program is running on Mac OS 8/9, CreateRootControl is called to
create a root control for the window. On Mac OS 8/9, the first control created must be always
be the root control (which is implemented as a user pane). This call is not necessary on Mac
OS X because, on Mac OS X, root controls are created automatically for windows which have at
least one control.
A handle to the structure in which the reference to the control objects will be stored is then
retrieved. The following calls to GetNewControl create a control object for each control,
insert the reference to the object into the control list for the specified window and draw the
control. At the same time, the reference to each control object is assigned to the appropriate
field of the window's "document" structure.
At the next block, if the program is running on Mac OS X, SetControlData is called to make the
first four bevel button's corners rounded. (Mac OS X bevel buttons have square corners by
default.)
At the next block, SetControlData is called twice to cause the text in the specified bevel
buttons to be placed above the graphic.
At the next block, SetControlData is called to cause the pop-up glyph in the specified bevel
button to be centred.
At the next block, the font for the text in the specified bevel button is changed. The flags
and font fields of a control font style structure are assigned constants so that the following
call to SetControlFontStyle will set the font to the small emphasised system font.
The final line sets the value of the specified bevel button to 2, causing it to appear in the
mixed state.
doBevelImagePictIconContent
Recall that, if a mouse-down occurs in the Bevel Buttons, Image Wells, Picture Controls, and
Icon Controls window when it is the front window, doBevelImagePictIconContent is called to
further handle the event.
At the first line a handle to the structure containing references to all the control objects is
obtained.
The call to GlobalToLocal changes the coordinates at which the mouse-down occurred to the local
coordinates required by the following call to FindControl. The constant representing the part
code returned by FindControl is then drawn in the window header.
If the part code returned by FindControl is not kControlNoPart (0), meaning that an enabled
control was under the mouse cursor at the time of the mouse-down, the if block executes.
TrackControl takes control while the mouse button remains down, returning a part code when the
button is released.
In the case of the first 10 specified controls (bevel buttons), the control part code returned
by TrackControl is simply drawn in the window header.
The next four controls are bevel button with menus. In these cases, if the part code returned
indicates that the mouse button was released while the cursor was within the menu,
GetBevelButtonMenuValue is called to get the menu item number. The part code and menu item
number are then drawn in the window header. If the cursor was not in the menu when the mouse
button was released, the part code returned by TrackControl is drawn in the window header.
The 10th, 11th, and 12th bevel buttons have toggle behaviour. With some assistance from the
application, they behave like radio buttons. If the control in which the mouse-down occurred
was one of these bevel buttons, and if the cursor was still within the control when the mouse
button was released, SetControlValue is called to set the three controls to the unchecked
state, following which the selected control is set to the checked state. Either way, the part
code returned by TrackControl is drawn in the window header.
The 18th bevel button is used to demonstrate bevel button graphic alignments using a single
bevel button. A mouse-down within this button causes the function doGraphicAlignment to be
called.
The 19th bevel button is used to demonstrate bevel button text alignments using a single bevel
button. A mouse-down within this button causes the function doTextAlignment to be called.
The 20th bevel button is used to demonstrate text offsetting using a single bevel button. A
mouse-down within this button causes the function doTextOffset to be called.
The 21st bevel button is used to demonstrate bevel button text placement in relation to the
bevel button's graphic using a single bevel button. A mouse-down within this button causes the
function doTextPlacement to be called.
Finally, if the mouse-down was in an image well, picture control, or icon control, and except
for the non-tracking picture and icon control variants, the part code returned by TrackControl
is drawn in the window header.
doDrawPartCode
doDrawPartCode takes part codes and menu item numbers and assembles them into descriptive
strings for drawing in the window header. The constants used are stored in 'STR#' resources,
and are retrieved using GetIndString. In the final two lines, Draw1Control is called to redraw
the window header control (in effect erasing the current text drawn within the window header
area) and doDrawMessage is called to draw the assembled string.
doGraphicAlignment
doGraphicAlignment is called to demonstrate bevel button graphic alignment using the helper
function SetBevelButtonGraphicAlignment, which facilitates finer adjustment of graphic
placement that using SetControlData with the kControlBevelButtonGraphicAlignTag control data
tag constant. Each time around the outer for loop, the alignment constant is changed. In the
inner for loop, SetBevelButtonGraphicAlignment is called 53 times, with the two offset
parameters incremented and Draw1Control called at each call. The alignment constant used
during each pass through the outer for loop is drawn in the window header.
doTextAlignment
doTextAlignment is called to demonstrate the effect of the bevel button text alignment
constants using the helper function SetBevelButtonTextAlignment, which facilitates finer
adjustment of text placement that using SetControlData with the
kControlBevelButtonGraphicAlignTag control data tag constant. Each time around the outer for
loop, the alignment constant is changed. In the inner for loop, SetBevelButtonTextAlignmentis
called 41 times, with the offset parameter incremented and Draw1Control called at each call.
The alignment constant used during each pass through the outer for loop is drawn in the window
header.
doTextOffset
doTextOffset is called to demonstrate text offsetting from the left and the right within a
bevel button. For the purposes of the demonstration, two animations involving incrementing
offsets values are used. Prior to first animation, SetControlData is called with the
kControlBevelButtonTextOffsetTag tag to align the text on the left. Prior to second animation,
SetControlData is called with the kControlBevelButtonTextOffsetTag tag to align the text on the
right. Within the for loops, SetControlData is called with the
kControlBevelButtonTextOffsetTag tag to offset the text from the left or right by the specified
number of pixels, and Draw1Control re-draws the control.
doTextPlacement
doTextPlacement is called to demonstrate the effect of the bevel button text placement
constants. Within a for loop which increments the text placement constant,
SetBevelButtonTextPlacement is called and Draw1Control re-draws the control.
doDrawMessage and doDrawLegends
doDrawMessage and doDrawLegends are incidental to the demonstration. Both functions draw text
in the window in either black or gray depending on whether the window is currently in front or
in the background.
TabEditClock.c
TabEditClock.c creates a movable modal dialog in which is demonstrated a tab control, edit text
controls and clock controls. A numeric key filter function is attached to the second edit text
control. The third edit text control is for password input. The controls displayed by each
tab are embedded in user panes.
The kDialogFlagsUsesControlHierarchy flag is set in the 'dlgx' resources for all dialogs used
in the demonstration. Recall that this means that the Dialog Manager creates a root control in
the dialog and establishes an embedding hierarchy, that all dialog items automatically become
controls, and that the Dialog Manager uses AutoEmbedControl to position dialog items in an
embedding hierarchy based on both visual containment and their item list number.
The dialog item list used by the dialog created by TabEditClock.c is shown in the following, in
which the indentation represents the embedding hierarchy:
1. OK push button primitive.
2. Tab control (kTabControlLargeProc variant).
Visually contains the two user panes (items 3 and 12) and thus automatically embeds
those items.
3. User pane control with kControlSupportsEmbedding feature bit set (initial value set
to 2).
Visually contains items 4 to 11 and thus automatically embeds those items.
4. Static text primitive "Name:".
5 Edit text primitive.
6. Static text primitive "Age:".
7. Edit text primitive.
8. Static text primitive "Password:".
9. Edit text control (kControlEditTextPasswordProc variant).
10. Extract push button primitive.
11. Image well control.
12. User pane control with kControlSupportsEmbedding feature bit set (initial value set
to 2).
Visually contains items 13 to 20 and thus automatically embeds those items.
13. Static text primitive "Hours, Mins, Secs:".
14. Clock control (kControlClockTimeSecondsProc variant).
15. Static text primitive "Date, Month, Year:".
16. Clock control (kControlClockDateProc variant).
17. Static text primitive "Month, Year:".
18. Clock control (kControlClockMonthYearProc variant).
19. Extract push button primitive.
20. Image well control.
21. Clock control (kControlClockTimeSecondsProc variant, live, display only.)
22. Group box (kControlGroupBoxSecondaryTextTitleProc variant).
Visually contains item 23 and thus automatically embeds that item:
23. Static text primitive.
doTabEditClock
doTabEditClock creates the dialog, calls ModalDialog to handle events in the dialog, and
disposes of the dialog when the user hits the OK push button.
Firstly, and as is always required when a dialog is to be displayed, the front window (if one
exists) is explicitly deactivated.
The call to GetNewDialog creates the dialog. The call to SetWTitle sets the window's title so
as to force an association with the 'hrct' resource containing the help balloons for the Edit
Text Control tab. (Later calls to SetWTitle in this function are used for similar purposes.)
SetDialogDefaultItem tells the Dialog Manager which is the default push button item, to alias
the Return and Enter keys to that item, and to draw the default ring around that item (Mac OS
8/9) or make it pulsing blue (Mac OS X). SetDialogTracksCursor will cause the Dialog Manager
to change the cursor shape to the I-Beam cursor whenever the cursor is over an edit text item
specified in the 'DITL' as an edit text primitive.
The first call to GetDialogItemAsControl gets a reference to the user pane used for the clocks
tab. HideControls hides this user pane and all the controls automatically embedded within it.
At the next block, SetControlData is called with the kControlEditTextTextTag tag to assign some
text to the first edit text control. The fields of an edit text selection structure are then
assigned values which will cause the following call to SetControlData to select the entire edit
text control.
The next block creates universal procedure pointers for event filter, key filter, and edit text
validator callback functions. (The event filter function is defined in the source code file
Callbacks.c.) SetControlData is then called with the kControlEditTextValidationProcTag tag to
attach the edit text validation function to the first edit text control. SetControlData is
then called again with the kControlEditTextKeyFilterTag tag to attach the key filter function
to the second edit text control.
With those preliminaries attended to, ShowWindow is called to display the window, following
which the ModalDialog loop is entered. The loop will execute until the user hits the OK push
button. Note that the previously created UPP is passed in the filterProc parameter of
ModalDialog.
When a mouse-down event occurs in an enabled item, ModalDialog returns the item number of the
item hit. If the item hit was the tab item, GetDialogItemAsControl is called to get a
reference to the tab control and GetControlValue is called to determine which of the two tabs
was hit. If the tab hit was the Edit Text Controls tab, the Clock Controls user pane is
hidden, the Edit Text Controls user pane is shown, and the keyboard focus is set to the first
edit text control. If the tab hit was the Clock Controls tab, the Edit Text Controls user pane
is hidden, the Clock Controls user pane is shown, and the keyboard focus is set to the first
clock control.
If the item hit was the Extract push button in the Edit Text Controls pane, the image well
control is re-drawn to erase any previous text and a function is called to extract and display
the contents of the edit text controls.
If the item hit was the Extract push button in the Clock Controls pane, the image well control
is re-drawn to erase any previous text and a function is called to extract and display the
contents of the clock controls.
When the user hits the OK button, DisposeDialog closes the dialog and disposes of the
associated memory, and the universal procedure pointers associated with the event filter
function and key filter function are disposed of.
doExtractEditText
doExtractEditText extracts the text from the edit text controls and draws it in the image well
area. In the case of the Password edit text control, the text extracted is the actual password
typed, not the bullet text.
In the case of the first two edit text controls, GetDialogItem is used to get the handle to the
hText field of the TERec structure used by the item. This is where the characters are located.
(Exactly what is returned in the iHandle field of a GetDialogItem call depends on the item
type.) GetDialogItemText then copies these characters to a variable of type Str255.
In the case of the third (password) edit text control, GetDialogItemAsControl gets a reference
to the control. GetControlDataSize is then called with the kControlEditTextTextTag tag to get
the number of characters and GetControlData is called with the kControlEditTextPasswordTag to
get the clear password text from the control.
doExtractDateTime
doExtractDateTime gets the settings in the three clock controls into a long date structure,
extracts the content of the relevant fields of that structure, and draws that content in the
image well area.
For each clock, GetControlData is called with the kControlClockLongDateTag tag to get the
information into a long date structure. The rest of the code simply converts the values in the
relevant fields of this structure to strings, which are concatenated with other identifying
strings prior to being drawn in the image well.
numericFilter
numericFilter is the key filter function attached to the second edit text control.
The character code and modifiers parameters passed to this function by the control are first
examined to determine whether (1) the character code represents the numeric characters between
0 and 9 inclusive or (2) whether the Command key was down. If either of these conditions is
true, the function returns kControlKeyFilterPassKey. This means that, if the character is
between 0 and 9 inclusive, it will be accepted. It also means that, if the Command key was
down, non-numeric characters will be accepted as well. This latter is necessary to ensure that
the user can edit the text in the edit text control using the usual Edit menu Command-key
equivalents.
If a return does not occur at that point, the character code is further examined to determine
whether it represents one of the arrow keys, the backspace key or the delete key. If so,
kControlKeyFilterPassKey is returned. If not, the system alert sound is played and
kControlKeyFilterBlockKey is returned, meaning that the character is to be rejected.
editTextValidator
editTextValidator is the edit text validation callback function attached to the first edit text
control.
The call to GetControlData gets the text to be examined from the control into the variable
oldText. The next block sets the length byte in oldText to the actual number of characters in
the text, limited to 255 characters. The for loop then examines each character and, if it is
an alphabetic character, the space character, or the period character, inserts it into the
newText variable and increments a variable which is eventually used to set the length byte of
newText. When the if loop exits, the length byte is set and SetControlData is called to put
the replacement text into the control. Finally, Draw1Control redraws the control.
GroupArrowsProgress.c
GroupArrowsProgress.c creates a movable modal dialog in which is demonstrated a checkbox group
box, a pop-up group box, little arrows, a disclosure triangle, chasing arrows, and an
indeterminate progress bar.
The checkbox group box contains a static text item and three radio buttons. The radio buttons
are embedded in a radio group. The pop-up group box contains two user panes. Embedded in each
user pane are a checkbox and a radio group. Embedded in each radio group are two radio
buttons.
The dialog item list used by the dialog created by GroupArrowsProgress.c is shown in the
following, in which the indentation represents the embedding hierarchy:
1. Push button primitive.
2. Group box control (kControlGroupBoxCheckboxProc variant).
3. Radio group control.
4. Radio button primitive.
5. Radio button primitive.
6. Radio button primitive.
7. Checkbox primitive.
8. Group box control(kControlGroupBoxPopupButtonProc variant).
9. User pane control with kControlSupportsEmbedding feature bit set (initial value set
to 2).
10. Radio group control
11. Radio button primitive.
12. Radio button primitive.
13. Checkbox primitive.
14. Static text primitive.
15. User pane control with kControlSupportsEmbedding feature bit set (initial value set
to 2).
16. Radio group control
17. Radio button primitive.
18. Radio button primitive.
19. Checkbox primitive.
20. Static text primitive.
21. Group box control (kControlGroupBoxSecondaryTextTitleProc variant).
22. Static text primitive.
23. Group box control (kControlGroupBoxSecondaryTextTitleProc variant).
24. Static text primitive.
25. Placard control.
26. Static text primitive.
27. Little arrows control.
28. Extract push button primitive.
29. Image well
30. Separator line
31. Disclosure triangle (kControlTriangleProc variant).
32. Static text primitive.
A second dialog item list resource, containing a chasing arrows control and a progress bar
control, is appended to the dialog when the disclosure triangle is clicked.
doGroupArrowsProgress
doGroupArrowsProgress creates the dialog, calls ModalDialog to handle events until the user
hits the OK push button, and then disposes of the dialog.
At the first two lines, if the Bevel Buttons, Image Wells, Picture Controls, and Icon Controls
window is open, it is explicitly deactivated.
The call to GetNewDialog creates the dialog and SetDialogDefaultItem establishes the OK push
button as the default push button.
The next two lines create universal procedure pointers for the application-defined event filter
(callback) function and an application-defined action function for the little arrows control.
(The event filter function is in the source code file Callbacks.c.)
The next block sets the initial value of the checkbox group box to 1 (checked).
The little arrows are used to set a (simulated) cache size, which is displayed in a static text
item overlayed on a placard item. The little arrows initial value is set in the 'CNTL'
resource to 96. The first three lines of the next block extract this value, convert it to a
string and append the character "K". SetControlData is then called with the
kControlStaticTextTextTag to set this string in the static text item.
The second user pane in the pop-up group box is then hidden before the call to ShowWindow,
following which the ModalDialog loop is entered. Note that the UPP associated with the
application-defined event filter function is passed in the filterProc parameter of ModalDialog.
If ModalDialog reports that the item hit was the checkbox group box's checkbox or the pop-up
group box's pop-up menu, functions are called to further handle the hit.
if the item hit was one of the checkboxes within the pop-up group box, the control's control
value is set so that the control is checked if it was unchecked, or unchecked if it was
checked.
If the item hit was the disclosure triangle, an function is called to further handle the hit.
If the item hit was the Extract push button, Draw1Control is called to redraw the image well,
thus erasing any previous text in the well, and a function is called to extract the control
settings and draw them in the image well area.
Note that hits on the radio buttons will be handled automatically by the radio group controls
in which they are embedded. The radio group control will set the new control values according
to which radio button is hit, and will change the checked/unchecked appearance of the radio
buttons to match.
Note also that mouse-down events in the little arrows are detected and handled in the event
filter function. (See the source code file Callbacks.c.)
When the OK button is hit, the loop exits, DisposeDialog closes the dialog and disposes of the
associated memory, and the two previously created universal procedure pointers are disposed of.
In addition, the global variable which flags that the dialog was open is set to false.
doCheckBoxGroupBox
doCheckBoxGroupBox further handles a hit in the checkbox group box's checkbox.
The first three lines flip the control's value; that is, if the control's value was 1
(checked), it is set to 0 (unchecked), and vice versa.
If the new value of the control is 0 (unchecked), the radio group and checkbox within the group
box are deactivated. Since the radio buttons are embedded in the radio group, they will also
be deactivated when the radio group is deactivated.
If the new value of the control is 1 (checked), the radio group and checkbox within the group
box are activated. Since the radio buttons are embedded in the radio group, they will also be
activated when the radio group is activated.
doPopupGroupBox
doPopupGroupBox further handles a hit in the pop-up group box's pop-up menu button.
The first two lines get the control's value, which represents the menu item chosen. Depending
on the item chosen, the appropriate user panes are hidden or shown, thus hiding or showing all
controls embedded in each user pane.
doChasingAndProgress
doChasingAndProgress further handles a hit in the disclosure triangle.
The first three lines flip the control's value; that is, if the control's value was 1
(expanded), it is set to 0 (collapsed), and vice versa.
If the new control value is 1 (expanded), GetResource is called to load the item list resource
containing the chasing arrows and progress bar items. AppendDITL is then called to append
these items to the end of the dialog's item list. The constant passed in the third parameter
of this call causes the dialog to be expanded downwards to accommodate the new items.
SetControlData is then called with the kControlProgressBarIndeterminateTag tag to make the
progress bar an indeterminate progress bar.
Not previously mentioned is the fact that the appended 'DITL' resource contains a static text
item, with no text, the function of which is simply to expand the dialog further downwards to
accommodate a move of the OK push button. The call to MoveControl moves the OK push button to
a position below the chasing arrows and progress bar.
Finally, SetControlData is called with the kControlStaticTextTextTag tag to change the text in
the static text control adjacent to the disclosure triangle. Draw1Control re-draws the control
to display the changed text.
If the new disclosure triangle control value is 0 (collapsed), the OK button is moved back to
its previous location, SizeWindow is called to resize the window to its previous size,
SetControlData is called with the kControlStaticTextTextTag tag to change the text in the
static text control adjacent to the disclosure triangle, and Draw1Control re-draws the control
to display the changed text.
doExtractCurrentStatus
doExtractCurrentStatus is called when the Extract push button is hit. It simply extracts the
values of the various controls, builds up strings based on those values, and draws those
strings in the image well area.
Note in the second last block that the value of the little arrows control represents the
current (simulated) cache size. The little arrows control value is set within the action
function arrowsActionFunction in the source code file Callbacks.c.
Sliders.c
Sliders.c creates a movable modal dialog in which is demonstrated various slider control
variants and two simple user pane functions.
doSliderUserPane
doSliderUserPane creates the dialog, calls ModalDialog to handle events until the user hits the
OK push button, and then disposes of the dialog.
At the first two lines, if the Bevel Buttons, Image Wells, Picture Controls, and Icon Controls
window is open, it is explicitly deactivated.
The call to GetNewDialog creates the dialog and SetDialogDefaultItem establishes the OK push
button as the default push button.
The next three lines create universal procedure pointers for the application-defined event
filter (callback) function and two application-defined action functions for the live-feedback
slider variants, one for the two at top right of the dialog and one for the two horizontal
sliders. (The event filter function and the action functions are in the source code file
Callbacks.c.)
The next two blocks creates universal procedure pointers for two user pane functions (one a
draw function and one an activate function), and attach these functions to a user pane located
immediately to the right of the two horizontal sliders.
The next block assigns references to the first four sliders to global variables and call a
function to draw the respective control values in static text items located immediately below
the sliders.
The following four lines assign references to the horizontal sliders to global variables and
assign a value based on the current slider control values to the red and blue fields of two
global variables of type RGBColor.
The call to ShowWindow makes the dialog visible before the ModalDialog loop is entered. This
loop executes until the OK button is hit, at which time DisposeDialog is called to remove the
dialog and dispose of its associated memory, the previously created universal procedure
pointers are disposed of, and the global variable which flags that the Sliders dialog is open
is assigned false.
doDrawSliderValues
doDrawSliderValue is called by doSliderUserPane to draw the initial control values of the four
top sliders in the static text controls immediately below the sliders.
The first line gets the control's value and converts it to a string. The next block
determines, on the basis of the received control reference, which is the target static text
item. SetControlData is then called with the kControlStaticTextTextTag tag to set the text,
and Draw1Control re-draws the static text control.
As will be seen, this function is also called from within the event filter function when a
mouse-down has been detected within the two non-live-scrolling sliders.
userPaneDrawFunction
userPaneDrawFunction will be called whenever an update event is received. This will occur when
the dialog is opened and, subsequently, when an overlaying window or help balloon is removed
from the area occupied by the user pane (to the immediate right of the horizontal sliders).
The two calls to DrawThemePlacard draw two Appearance Manager placard primitives to the right
of the horizontal sliders. The global variable gDrawActivated determines whether the primitive
is drawn with an activated or deactivated appearance.
If the global variable gDrawActivated indicates that the interior of the placard should be
drawn, the foreground colour for each interior is set to that stored in global variables and
PaintRect is called to paint the interior in that colour. (As will be seen, the value stored
in these global variables is changed by the action function called while the mouse button
remains down in the slider's indicators.)
If gDrawActivated indicates that the interior of the placard should be displayed with a
deactivated appearance, the interior is left as drawn by DrawThemePlacard.
userPaneActivateFunction
The kControlWantsActivate feature bit is set in the user pane on creation, that is, the
control's minimum value in the 'CNTL' resource is set to 16. This ensures that this function
will be called when the dialog receives activate events.
Depending on whether the dialog is about to be activated or deactivated, the global variable
gDrawActivated is set to true or false. As has been seen, this global variable controls the
way in which the placard primitive and its interior is drawn.
TextBox.c
doTextBox is called when the user chooses TextBoxes from the Demonstration menu. It opens a
movable modal dialog containing standard and scrolling text box controls.
Callbacks.c
Callbacks.c contains the event filter (callback) function used by all movable modal dialogs and
three action functions, one for the little arrows, one for the vertical live-feedback sliders,
and one for the horizontal live-feedback sliders.
eventFilter
The event filter function eventFilter is identical to the event filter function introduced at
Chapter 8 except that it intercepts mouse-down events in the little arrows and sliders and
informs ModalDialog that it has handled those events.
After the call to SetPortDialogPort, if the Group Boxes, Arrows, and Progress Bar dialog is
currently open, and if the event is a mouse-down event, the location of the mouse-down is
extracted from the where field of the event structure and converted to the local coordinates
required by the following call to FindControl. If FindControl determines that there is an
enabled control under the mouse cursor, and if that control is the little arrows control,
TrackControl is called to handle all user interaction while the mouse button remains down.
While the mouse button remains down, TrackControl continually calls the action function pointed
to by the UPP passed in the third parameter. When the mouse button is released, the function
exits with true being returned to ModalDialog.
If, on the other hand, the Sliders and User Pane Functions dialog is open, and if the event is
a mouse-down event, and if FindControl reports an enabled control, and if that control is one
of the two non-live-feedback sliders, TrackControl is called to handle all user interaction
while the mouse button remains down. When the mouse button is released, the function
doDrawSliderValues is called to draw the new control value in the static text item below the
slider. Once again, the function then exits with true being returned to ModalDialog.
If the mouse-down was in one of the two live-feedback sliders at the top right of the dialog,
TrackControl is called with a UPP to the first slider action function passed in the third
parameter.
If the mouse-down was in one of the two horizontal live-feedback sliders, TrackControl is
called with a UPP to the second slider action function passed in the third parameter.
arrowsActionFunction
arrowsActionFunction is the action function for the little arrows. It is called continually by
TrackControl while the mouse button remains down.
if the mouse cursor is still within the control, GetControlValue is called to get the current
control value. The function then switches according to the part code. If the cursor is in the
top arrow, the control's value is increased by 32 unless this would cause the value to exceed
the control's maximum value (set in the 'CNTL' resource to 7680). If the cursor is in the
bottom arrow, the control's value is decreased by 32 unless this would cause the value to be
lower that the control's minimum value (set in the 'CNTL' resource to 96).
If the control's value was increased or decreased within the switch, SetControlValue is called
to set the new control value, and the final block sets the new text for the Cache size static
text item and re-draws the item.
sliderActionFunction1
sliderActionFunction1 is the action function for the live-feedback sliders at the top right of
the dialog. It is called continually by TrackControl while the mouse button remains down.
GetControlValue gets the control's current value and NumToString converts it to a string for
display. The next line gets the reference to the control's owning window required by the call
to GetDialogItemAsControl. The if block determines which of the two sliders the mouse is down
in. The last two lines set the text in the appropriate static text control and redraw the
control.
sliderActionFunction2
sliderActionFunction3 is the action function for the horizontal live-feedback sliders. It is
called continually by TrackControl while the mouse button remains down.
GetControlValue gets the control's current value. If the slider is the top horizontal slider,
the red field of the RGBColor global variable gRedColor is assigned a new value based on the
control's current value, and the local Rect variable is assigned coordinates based on the
placard at the right of the slider. If the slider is the bottom horizontal slider, the blue
field of the RGBColor global variable gBlueColor is assigned a new value based on the control's
current value, and the local Rect variable is assigned coordinates based on the placard at the
right of the slider.
Finally, PaintRect is called to paint the interior area of the relevant image well in the new
colour.
SmallControls.c
doSmallControls
doSmallControls is called when the user chooses the Small Controls item in the Demonstration
menu (Mac OS X only). It opens a floating window in which those controls with small versions
are displayed.
Note that:
o A call to SetControlData with the kControlSizeTag tag is required to make the scroll bars
small.
o The value passed in the third parameter of the CreateTabsControl call makes the tab control
small.
o A call to SetControlData with the kControlSizeTag tag is required to make the slider control
small.
o A call to SetControlData with the kControlSizeTag tag is required to make the radio button
and checkbox controls small. In addition, a call to SetControlFontStyle is required to make
the title small.
o The only way to create a pop-up menu button with both the menu and the title small is to
create the control from a 'CNTL' resource, specifying the "use window font" variant. (Note
that the window font is set to the small system font.)
o The edit text control is made small by, firstly, making the control's rectangle 12 pixels
high and, secondly, changing the font to the small system font by passing the address of a
ControlFontStyleRec structure in the sixth parameter of the CreateEditTextControl call.
o The push button is made small by, firstly, making the control's rectangle 17 pixels high and,
secondly, calling SetControlFontStyle is to make the title small.