The two methods for note-task-selection-change make a number of changes to the GUI of the task list manager, to ensure that the correct information is displayed to the user. In particular, they perform any changes necessary after an item in the task list has been selected or deselected. They ensure that the correct priority is displayed in the radio box, depending on whether there is a task currently selected, and they also enable or disable the Remove task button and its equivalent command in the Task menu, depending on whether there is a task selected or not (if there is no task selected, then the button and menu command should both be disabled).
There are two methods defined, one on an instance of <task-frame>, and one on an instance of <gadget>. The Task List 1 project requires both of these methods. For the Task List 2 project, however, the first method requires a slightly different definition, and the second method is not required at all.
The note-task-selection-change method defined on <task-frame> is called by refresh-task-frame, described at the end of this section. For the Task List 1 project, the note-task-selection-change method is defined:
define method note-task-selection-change
(frame :: <task-frame>) => ()
let task = frame-selected-task(frame);
if (task)
frame.priority-box.gadget-value := task.task-priority;
end;
let selection? = (task ~= #f);
frame.remove-button.gadget-enabled? := selection?;
frame.remove-menu-button.gadget-enabled? := selection?;
end method note-task-selection-change;
For the Task List 2 project the note-task-selection-change method is defined:
define method note-task-selection-change
(frame :: <task-frame>) => ()
let task = frame-selected-task(frame);
if (task)
frame.priority-box.gadget-value := task.task-priority;
end;
command-enabled?(frame-remove-task, frame) := task ~= #f;
end method note-task-selection-change;
The method takes an instance of <task-frame> as an argument, and returns no values. It works by calling frame-selected-task to determine which, if any, task is currently selected, and sets that to a local variable, task.
The expression
if (task) frame.priority-box.gadget-value := task.task-priority; end;
sets the gadget value of the priority-box pane in the task list manager to the value of the task-priority slot of the selected task, if a task is selected. This ensures that if a task is selected, its priority is displayed correctly beneath the list of tasks. Note that priority-box may take the same set of values as the task-priority slot, namely #"low", #"medium", and #"high", so it is straightforward to make this kind of assignment.
The rest of the method deals with enabling or disabling gadgets that let the user remove a task from the task list. If there is no task selected, then remove-button and remove-menu-button need to be disabled. If there is a task selected, then they need to be enabled. This behavior is achieved by converting the value of the variable task, which can take a value of false-or(<task>), into a boolean value, called selection?. This is done in the expression
let selection? = (task ~= #f);
This sets selection? to the result of performing an inequality comparison on task and #f. Thus, if task is #f (there is no task selected), then selection? is #f, but if task is an instance of <task> (there is a task selected), then selection? is #t.
The two calls to gadget-enabled? then set the gadget-enabled slot of the appropriate gadgets to the value of selection?, enabling or disabling each gadget as appropriate.
The second method for note-task-selection-change is defined for an instance of <gadget>, as follows:
define method note-task-selection-change
(gadget :: <gadget>) => ()
let frame = gadget.sheet-frame;
note-task-selection-change(frame)
end method note-task-selection-change;
This takes a gadget as an argument. It simply finds the frame that the gadget belongs to, and calls the other method for note-task-selection-change on that frame.
The second method for note-task-selection-change needs to be used as the value-changed callback of the task-list pane in the definition of <task-frame>; a value-changed callback is invoked whenever the gadget-value of a gadget changes. Because the gadget-value of a list box is the currently selected item, whenever a different item is selected in the list box, note-task-selection-change is called.
In order to achieve this, a small change is needed to the definition of the task-list pane in frame.dylan. In this definition for the Task List 1 project, change the line that reads:
activate-callback: not-yet-implemented);
to
value-changed-callback: note-task-selection-change);
and for the Task List 2 project change the line to
value-changed-callback: method (gadget)
note-task-selection-change(frame) end);
to give a final definition for this pane as follows:
// definition of list
pane task-list (frame)
make (<list-box>,
items: frame.frame-task-list.task-list-tasks,
label-key: task-name,
lines: 15,
value-changed-callback: note-task-selection-change);
Add the code for these methods to frame.dylan.