Мы не касаемся довольно сложного и запутанного вопроса, связанного с внешним видом кнопки (и других элементов управления окном) на экране. Проблема заключается в том, что выбор внешнего вида элементов управления окном практически бесконечен, причем некоторые стили диктуются конкретными операционными системами. Кроме того, с точки зрения технологии программирования в описании внешнего вида кнопок нет ничего нового. Если вы расстроились, то обратите внимание на то, что размещение фигуры поверх кнопки не влияет на ее функционирование, а как нарисовать фигуру, вам уже известно.
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) становится новой текущей точкой.
Так рисуется незамкнутая ломаная. Когда пользователь устанет, он щелкнет на кнопке Quit. Следуя этой простой логике, программа использует несколько полезных средств графического пользовательского интерфейса: ввод и вывод текста, рисование линии и многочисленные кнопки. Окно, показанное выше, демонстрирует результат после ввода двух пар координат. После семи шагов на экране отобразится следующий рисунок.
Определим класс для рисования таких окон. Он довольно прост.