и всего. Весь (относительно сложный) код библиотеки 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
и проверить, не пустая ли эта строка.
string s = some_inbox.get_string;
if (s =="") {
// текст не введен
}
Объект класса
Out_box
используется для выдачи сообщений, адресованных пользователю. По аналогии с классом
In_box
, мы можем с помощью функции
put
ввести либо целые числа, либо строки. Примеры использования классов
In_box
and
Out_box
приведены в разделе 16.5.
Мы могли бы предусмотреть функции
get_floating_point
,
get_complex
и так далее, но не сделали этого, так как вы можете взять строку, поместить ее в поток
stringstream
и форматировать ввод, как захотите (см. раздел 11.4).
16.4.4. Класс Menu
Определяем очень простое меню.
struct Menu:Widget {
enum Kind { horizontal, vertical };
Menu(Point xy, int w, int h, Kind kk, const string& label);
Vector_ref<Button> selection;
Kind k;
int offset;
int attach(Button& b); // связывает кнопку с меню
int attach(Button* p); // добавляет новую кнопку в меню
void show // показывает все кнопки
{
for (int i = 0; i<selection.size; ++i)
selection[i].show;
}
void hide; // hide all buttons
void move(int dx, int dy); // перемещает все кнопки
void attach(Window& win); // связывает все кнопки с объектом win
};
По существу, объект класса
Menu
— это вектор кнопок. Как обычно, объект
Point xy
задает координаты левого верхнего угла. Ширина и высота используются для изменения размера кнопки при ее добавлении в меню. Примеры описаны в разделах 16.5 и 16.7. Каждая кнопка меню (пункт меню) — это независимый объект класса
Widget
, переданный объекту класса
Menu
как аргумент функции
attach
. В свою очередь, класс
Menu
содержит функцию
attach
, связывающую все свои кнопки с окном. Объект класса
Menu
отслеживает все свои кнопки с помощью класса
Vector_ref
(разделы 13.10 и E.4).
Если хотите создать всплывающее меню (“pop-up” menu), то сможете справиться с этой задачей самостоятельно (подробно об этом — в разделе 16.7).
16.5. Пример
Для того чтобы лучше ознакомиться с возможностями основных средств графического пользовательского интерфейса, рассмотрим окно для простого приложения, в котором происходит ввод, вывод и немного рисования.
Эта программа позволяет пользователю изобразить последовательность линий (незамкнутая ломаная; см. раздел 13.6), заданную как последовательность пар координат. Идея заключается в том, что пользователь постоянно вводит координаты (x, y) в поля ввода next x и next y; после ввода каждой пары пользователь щелкает на кнопке Next point.
Изначально поле ввода
current (x, y)
остается пустым, а программа ожидает, пока пользователь введет первую пару координат. После этого введенная пара координат появится в поле ввода
current (x, y)
, а ввод каждой новой пары координат приводит к появлению на экране новой линии, проходящей от текущей точки (координаты которой отображаются в поле ввода
current (x, y)
) до только что введенной пары (x, y), а сама точка (x, y) становится новой текущей точкой.