Итак, когда кто-то щелкает на кнопке Next, функция
wait
вызывает функцию
cb_next
и возвращает управление (нашему циклу ожидания). Для того чтобы сделать это в функции
wait_for_button
, функция
next
должна просто присвоить булевой переменной
button_pushed
значение
true
. Это просто.
void Simple_window::next
{
button_pushed = true;
}
Разумеется, мы также должны где-то определить
переменную
button_pushed
.
bool button_pushed; // Инициализируется в конструкторе
// значением false
После определенного периода ожидания функция
wait_for_button
должна восстановить прежнее значение переменной
button_pushed
и вызвать функцию
redraw
, чтобы все внесенные изменения были видны на экране. Именно это мы и сделали.
16.4. Класс Button и другие разновидности класса Widget
Определим класс, описывающий кнопку.
struct Button:Widget {
Button(Point xy, int w, int h, const string& label, Callback cb);
void attach(Window&);
};
Класс
Button
является производным от класса
Widget
с координатами
xy
, размерами
w
и
h
, текстовой меткой
label
и обратным вызовом
cb
. В принципе все, что появляется на экране в результате какого-то действия (например, обратный вызов), является объектом класса
Widget
.
16.4.1. Класс Widget
Виджет (widget) — это технический термин. У него есть более информативный, но менее эффектный синоним — элемент управления окном (control). Такой элемент используется для определения форм взаимодействия с программой через графический пользовательский интерфейс. Определение класса
Widget
приведено ниже.
class Widget {
// Класс Widget — это дескриптор класса Fl_widget,
// он не является классом Fl_widget;
// мы стараемся, чтобы наши интерфейсные классы отличались
// от FLTK
public:
Widget(Point xy, int w, int h, const string& s, Callback cb);
virtual void move(int dx,int dy);
virtual void hide;
virtual void show;
virtual void attach(Window&) = 0;
Point loc;
int width;
int height;
string label;
Callback do_it;
protected:
Window* own; // каждый объект класса Widget принадлежит
Window
Fl_Widget* pw; // связь с классом Widget из библиотеки FLTK
};
Класс
Widget
имеет две интересные
функции, которые можно применить в классе
Button
(а также в любом другом классе, производном от класса
Widget
, например
Menu
; см. раздел 16.7).
• Функция
hide
делает объект класса
Widget
невидимым.
• Функция
show
делает объект класса
Widget
снова видимым.
Изначально объект класса
Widget
является видимым.
Как и в классе
Shape
, мы можем с помощью функции
move
перемещать объект класса
Widget
в окне и должны связать этот объект с окном, вызвав функцию
attach
перед тем, как использовать. Обратите внимание на то, что мы объявили функцию
attach
чисто виртуальной (см. раздел 16.3.5): каждый класс, производный от класса
Widget
, должен самостоятельно определить, что означает его связывание с объектом класса
Window
. Фактически системные элементы управления окном создаются в функции
attach
. Функция
attach
вызывается из объекта класса
Window
как часть реализации его собственной функции
attach
. В принципе связывание окна и элемента управления окном — это очень тонкое дело, в котором каждая из сторон выполняет свое задание. В результате окно знает о существовании своих элементов управления, а каждый элемент управления знает о своем окне.
Обратите внимание на то, что объект класса
Window
не знает о том, какая разновидность класса
Widget
с ним взаимодействует. Как описано в разделах 16.4 и 16.5, объектно-ориентированное программирование позволяет объектам класса
Window
взаимодействовать с любыми разновидностями класса
Widget
. Аналогично, классу
Widget
не известно, с какой разновидностью класса
Window
он имеет дело.
Мы проявили небольшую неаккуратность, оставив открытыми данные-члены. Члены
own
и
pw
предназначены исключительно для реализации производных классов, поэтому мы объявили из в разделе
protected
.
Определения класса
Widget
и его конкретных разновидностей (
Button
,
Menu
и т.д.) содержатся в файле
GUI.h
.
16.4.2. Класс Button
Класс
Button
— это простейший класс
Widget
, с которым нам придется работать. Все, что он делает, — всего лишь обратный вызов после щелчка на кнопке.