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, с которым нам придется работать. Все, что он делает, — всего лишь обратный вызов после щелчка на кнопке.
class Button:public Widget {
public:
Button(Point xy,int ww,int hh,const string& s,Callback cb)
:Widget(xy,ww,hh,s,cb) { }
void attach(Window& win);
};
Только и всего. Весь (относительно сложный) код библиотеки FLTK содержится в функции attach(). Мы отложили ее объяснение до приложения Д (пожалуйста, не читайте его, не усвоив главы 17 и 18). А пока заметим, что определение простого подкласса Widget не представляет особого труда.
16.4.3. Классы In_box и Out_box
Для ввода и вывода текста в программе предусмотрены два класса, производных от класса Widget.
struct In_box:Widget {
In_box(Point xy,int w,int h,const string& s)
:Widget(xy,w,h,s,0) { }
int get_int();
string get_string();
void attach(Window& win);
};
struct Out_box:Widget {
Out_box(Point xy, int w, int h, const string& s)
:Widget(xy,w,h,s,0) { }
void put(int);
void put(const string&);
void attach(Window& win);
};
Объект класса In_box может принимать текст, набранный в нем, и мы можем прочитать этот текст в виде строки с помощью функции get_string() или как целое число с помощью функции get_int(). Если хотите убедиться, что текст был введен, то можете прочитать его с помощью функции get_string() и проверить, не пустая ли эта строка.