Шрифт:
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
, с которым нам придется работать. Все, что он делает, — всего лишь обратный вызов после щелчка на кнопке.
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
не представляет особого труда.