- Любовные романы
- Фантастика и фэнтези
- Ненаучная фантастика
- Ироническое фэнтези
- Научная Фантастика
- Фэнтези
- Ужасы и Мистика
- Боевая фантастика
- Альтернативная история
- Космическая фантастика
- Попаданцы
- Юмористическая фантастика
- Героическая фантастика
- Детективная фантастика
- Социально-психологическая
- Боевое фэнтези
- Русское фэнтези
- Киберпанк
- Романтическая фантастика
- Городская фантастика
- Технофэнтези
- Мистика
- Разная фантастика
- Иностранное фэнтези
- Историческое фэнтези
- LitRPG
- Эпическая фантастика
- Зарубежная фантастика
- Городское фентези
- Космоопера
- Разное фэнтези
- Книги магов
- Любовное фэнтези
- Постапокалипсис
- Бизнес
- Историческая фантастика
- Социально-философская фантастика
- Сказочная фантастика
- Стимпанк
- Романтическое фэнтези
- Ироническая фантастика
- Детективы и Триллеры
- Проза
- Юмор
- Феерия
- Новелла
- Русская классическая проза
- Современная проза
- Повести
- Контркультура
- Русская современная проза
- Историческая проза
- Проза
- Классическая проза
- Советская классическая проза
- О войне
- Зарубежная современная проза
- Рассказы
- Зарубежная классика
- Очерки
- Антисоветская литература
- Магический реализм
- Разное
- Сентиментальная проза
- Афоризмы
- Эссе
- Эпистолярная проза
- Семейный роман/Семейная сага
- Поэзия, Драматургия
- Приключения
- Детская литература
- Загадки
- Книга-игра
- Детская проза
- Детские приключения
- Сказка
- Прочая детская литература
- Детская фантастика
- Детские стихи
- Детская образовательная литература
- Детские остросюжетные
- Учебная литература
- Зарубежные детские книги
- Детский фольклор
- Буквари
- Книги для подростков
- Школьные учебники
- Внеклассное чтение
- Книги для дошкольников
- Детская познавательная и развивающая литература
- Детские детективы
- Домоводство, Дом и семья
- Юмор
- Документальные книги
- Бизнес
- Работа с клиентами
- Тайм-менеджмент
- Кадровый менеджмент
- Экономика
- Менеджмент и кадры
- Управление, подбор персонала
- О бизнесе популярно
- Интернет-бизнес
- Личные финансы
- Делопроизводство, офис
- Маркетинг, PR, реклама
- Поиск работы
- Бизнес
- Банковское дело
- Малый бизнес
- Ценные бумаги и инвестиции
- Краткое содержание
- Бухучет и аудит
- Ораторское искусство / риторика
- Корпоративная культура, бизнес
- Финансы
- Государственное и муниципальное управление
- Менеджмент
- Зарубежная деловая литература
- Продажи
- Переговоры
- Личная эффективность
- Торговля
- Научные и научно-популярные книги
- Биофизика
- География
- Экология
- Биохимия
- Рефераты
- Культурология
- Техническая литература
- История
- Психология
- Медицина
- Прочая научная литература
- Юриспруденция
- Биология
- Политика
- Литературоведение
- Религиоведение
- Научпоп
- Психология, личное
- Математика
- Психотерапия
- Социология
- Воспитание детей, педагогика
- Языкознание
- Беременность, ожидание детей
- Транспорт, военная техника
- Детская психология
- Науки: разное
- Педагогика
- Зарубежная психология
- Иностранные языки
- Филология
- Радиотехника
- Деловая литература
- Физика
- Альтернативная медицина
- Химия
- Государство и право
- Обществознание
- Образовательная литература
- Учебники
- Зоология
- Архитектура
- Науки о космосе
- Ботаника
- Астрология
- Ветеринария
- История Европы
- География
- Зарубежная публицистика
- О животных
- Шпаргалки
- Разная литература
- Зарубежная литература о культуре и искусстве
- Пословицы, поговорки
- Боевые искусства
- Прочее
- Периодические издания
- Фанфик
- Военное
- Цитаты из афоризмов
- Гиды, путеводители
- Литература 19 века
- Зарубежная образовательная литература
- Военная история
- Кино
- Современная литература
- Военная техника, оружие
- Культура и искусство
- Музыка, музыканты
- Газеты и журналы
- Современная зарубежная литература
- Визуальные искусства
- Отраслевые издания
- Шахматы
- Недвижимость
- Великолепные истории
- Музыка, танцы
- Авто и ПДД
- Изобразительное искусство, фотография
- Истории из жизни
- Готические новеллы
- Начинающие авторы
- Спецслужбы
- Подростковая литература
- Зарубежная прикладная литература
- Религия и духовность
- Старинная литература
- Справочная литература
- Компьютеры и Интернет
- Блог
Программирование. Принципы и практика использования C++ Исправленное издание - Бьёрн Страуструп
Шрифт:
Интервал:
Закладка:
: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. Следуя этой простой логике, программа использует несколько полезных средств графического пользовательского интерфейса: ввод и вывод текста, рисование линии и многочисленные кнопки. Окно, показанное выше, демонстрирует результат после ввода двух пар координат. После семи шагов на экране отобразится следующий рисунок.
Определим класс для рисования таких окон. Он довольно прост.
struct Lines_window:Window {
Lines_window(Point xy,int w,int h,const string& title );
Open_polyline lines;
private:
Button next_button; // добавляет пару (next_x,next_y)
// в объект lines
Button quit_button;
In_box next_x;
In_box next_y;
Out_box xy_out;
static void cb_next(Address, Address); // обратный вызов
// next_button
void next();
static void cb_quit(Address, Address); // обратный вызов
// quit_button
void quit();
};
Линия изображается как объект класса Open_polyline. Кнопки и поля ввода-вывода объявляются как объекты классов Button, In_box и Out_box, и для каждой кнопки в них предусмотрены функции-члены, реализующие желательное действие вместе с шаблонным обратным вызовом функции.
Конструктор класса Lines_window инициализирует все его члены.
Lines_window::Lines_window(Point xy,int w,int h,const string& title)
:Window(xy,w,h,title),
next_button(Point(x_max()–150,0),70,20,"Next point",cb_next),
quit_button(Point(x_max()–70,0),70,20,"Quit",cb_quit),
next_x(Point(x_max()–310,0),50,20,"next x: "),
next_y(Point(x_max()–210,0),50,20,"next y: "),
xy_out(Point(100,0),100,20,"current (x,y): ")
{
attach(next_button);
attach(quit_button);
attach(next_x);
attach(next_y);
attach(xy_out);
attach(lines);
}
Иначе говоря, каждый элемент управления окном сначала создается, а потом связывается с окном.
Обработка кнопки Quit тривиальна.
void Lines_window::cb_quit(Address, Address pw) // "как обычно"
{
reference_to<Lines_window>(pw).quit();
}
void Lines_window::quit()
{
hide(); // любопытная идиома библиотеки FLTK для удаления окна
}
Все как обычно: функция обратного вызова (в данном случае cb_quit()) передается функции (в данном случае quit()), выполняющей реальную работу (удаляющей объект класса Window). Для этого используется любопытная идиома библиотеки FLTK, которая просто скрывает окно.
Вся реальная работа выполняется кнопкой Next point. Ее функция обратного вызова устроена как обычно.
void Lines_window::cb_next(Address, Address pw) // " как обычно "
{
reference_to<Lines_window>(pw).next();
}
Функция next() определяет действие, которое действительно выполняется после щелчка на кнопке Next point: она считывает пару координат, обновляет объект Open_polyline и позицию считывания, а также перерисовывает окно.
void Lines_window::next()
{
int x = next_x.get_int();
int y = next_y.get_int();
lines.add(Point(x,y));
// обновляем текущую позицию считывания:

