Расширение файла используется для того, чтобы определить вид объекта, создаваемого для хранения изображения ( Fl_JPEG_Image или Fl_GIF_Image). Этот объект создается с помощью оператора
new
и связывается с указателем. Подробности его реализации (в главе 17 рассматривается оператор new и указатели) связаны с организацией библиотеки FLTK и не имеют для нас большого значения.
Теперь настало время реализовать функцию
can_open()
, проверяющую, можно ли открыть файл для чтения.
bool can_open(const string& s)
// проверка, существует ли файл s и можно ли его открыть
// для чтения
{
ifstream ff(s.c_str());
return ff;
}
Открыть файл, а затем закрыть его, — довольно примитивный способ проверки, позволяющий отделить ошибки, связанные с невозможностью открыть файл, от ошибок, обусловленных неприемлемым форматированием данных.
Если хотите, можете посмотреть на определение функции
get_encoding()
: она просто анализирует суффикс и ищет соответствие в таблице заранее заданных суффиксов. Эта таблица реализована с помощью стандартного типа
map
(подробнее об этом — в разделе 21.6).
Задание
1. Создайте объект класса
Simple_window
размером 800×1000 пикселей.
2. Разместите сетку размером 88 пикселей в левой части окна размером 800 на 800 пикселей (так что каждый квадрат сетки имеет размер 100×100 пикселей).
3. Создайте восемь красных квадратов, расположенных по диагонали, начиная с левого верхнего угла (используйте класс
Rectangle
).
4. Подберите изображение размером 200×200 пикселей (в формате JPEG или GIF) и разместите три его копии поверх сетки (каждое изображение покроет четыре квадрата). Если вы не найдете изображения, размеры которого точно равнялись бы 200 пикселям, то, используя функцию
set_mask()
, вырежьте соответствующий фрагмент более крупного изображения. Не закрывайте красные квадраты.
5. Добавьте изображение размером 100×100 пикселей. Перемещайте его с одного квадрата на другой, щелкая на кнопке Next. Для этого поместите вызов функции
wait_for_button()
в цикл, сопроводив его командами, выбирающими новый квадрат для вашего изображения.
Контрольные вопросы
1. Почему мы просто не используем какую-нибудь коммерческую или бесплатную графическую библиотеку?
2. Сколько классов из библиотеки графического интерфейса нам понадобится, чтобы создать простой вывод графической информации?
3. Какие заголовочные файлы нужны для использования библиотеки графического интерфейса?
4. Какие классы определяют замкнутые фигуры?
5. Почему мы не используем класс
Line
для рисования любой фигуры?
6. Что означают аргументы конструктора класса
Point
?
7. Перечислите компоненты класса
Line_style
.
8. Перечислите компоненты класса
Color
.
9. Что такое система RGB?
10. В чем заключается разница между двумя объектами класса
Line
и объектом
Lines
, содержащим две линии?
11. Какие свойства можно задать для любого объекта класса
Shape
?
12. Сколько сторон объекта класса
Closed_polyline
определяются пятью объектами класса
Point
?
13. Что мы увидим на экране, если определим объект класса
Shape
, но не свяжем его с объектом класса
Window
?
14. Чем объект класса
Rectangle
отличается от объекта класса
Polygon
с четырьмя объектами класса
Point
(углами)?
15. Чем объект класса
Polygon
отличается от объекта класса
Closed_polyline
?
16. Что расположено сверху: заполненная цветом область или границы фигуры?
17. Почему мы не определили класс
Triangle
(ведь мы определили класс
Rectangle
)?
18. Как переместить объект класса
Shape
в другое место окна?
19. Как пометить объект класса
Shape
строкой текста?
20. Какие свойства текстовой строки можно задать в классе
Text
?
21. Что такое шрифт и зачем он нужен?
22. Для чего нужен класс
Vector_ref
и как его использовать?
23. В чем заключается разница между классами
Circle
и
Ellipse
?
24. Что произойдет, если мы попытаемся изобразить объект класса
Image
с заданным именем файла, а заданное имя файла не относится к файлу, содержащему изображение?
25. Как вывести на экран часть изображения?
Термины
Упражнения
Для каждого упражнения, в котором требуется определить класс, выведите на экран несколько объектов данного класса и продемонстрируйте, как они работают.
1. Определите класс
Arc
, рисующий часть эллипса. Подсказка:
fl_arc()
.
2. Нарисуйте окно с закругленными углами. Определите класс Box, состоящий из четырех линий и четырех дуг.
3. Определите класс
Arrow
, рисующий стрелки.
4. Определите функции
n()
,
s()
,
e()
,
w()
,
center()
,
ne()
,
se()
,
sw()
и
nw()
. Каждая из них должна получать аргумент типа
Rectangle
и возвращать объект типа
Point
. Эти функции должны определять точки соединения, расположенные на границах и внутри прямоугольника. Например,
nw(r)
— это левый верхний угол объекта класса
Rectangle
с именем
r
.
5. Определите функции из упр. 4 для классов
Circle
и
Ellipse
. Поместите точки соединения на границах и внутри этих фигур, но не за пределами окаймляющего их прямоугольника.
6. Напишите программу, рисующую диаграмму классов, похожую на ту, которая изображена в разделе 12.6. Программировать будет проще, если начать с определения класса
Box
, объект которого представляет собой прямоугольник с текстовой меткой.