• Задать константы, соответствующие разным цветам.
• Обеспечить простую реализацию прозрачности (видимый или невидимый).
Цвет можно выбрать следующим образом.
• Выбрать константу из списка, например
Color::dark_blue
.
• Выбрать цвет из небольшой палитры, которую большинство программ выводит на экран (им соответствуют значения в диапазоне от 0–255; например, выражение
Color(99)
означает темно-зеленый цвет). Пример такой программы приведен в разделе 13.9.
• Выбрать значение в системе RGB (Red, Green, Blue —
красный, зеленый, синий), которую мы здесь обсуждать не будем. При необходимости читатели сами в ней разберутся. В частности, можно просто ввести запрос “RGB color” в поисковую веб-машину. Среди прочих вы получите ссылки www.hyperso-lutions.org/rgb.html и www.pitt.edu/~nisg/cis/web/cgi/rgb.html. См. также упр. 13 и 14.
Обратите внимание на конструкторы класса
Color
, позволяющие создавать объекты как из объектов типа
Color_type
, так и из обычных чисел типа
int
. Каждый конструктор инициализирует член
c
. Вы можете возразить, что переменная c названа слишком коротко и непонятно, но, поскольку она используется в очень небольшой части класса
Color
и не предназначена для широкого использования, это не является недостатком. Мы поместили член
c
в закрытый раздел, чтобы защитить его от непосредственного обращения пользователей. Для представления члена c мы используем тип
Fl_Color
, определенный в библиотеке FLTK, который хотели бы скрыть от пользователей. Однако очень часто этот тип интерпретируется как целочисленное представление значения RGB (или другого значения), поэтому на этот случай мы предусмотрели функцию
as_int
. Обратите внимание на то, что функция
as_int
является константной функцией-членом, поскольку она не изменяет объект класса
Color
, который ее использует.
Прозрачность задается членом
v
, который может принимать значения
Color::visible
и
Color::invisible
, имеющие очевидный смысл. Вы можете удивиться: зачем нужен “невидимый цвет”. Оказывается, он может быть очень полезен для того, чтобы скрыть часть фигуры на экране.
13.5. Класс Line_style
Нарисовав на экране несколько линий, мы можем различать их по цвету, стилю или по обоим этим признакам. Стиль линии — это шаблон, задающий ее внешний вид. Класс
Line_style
используется приблизительно так:
grid.set_style(Line_style::dot);
Эта инструкция выводит на экран линии, заданные в объекте
grid
, как последовательность точек, а не как сплошную линию.
Это сделает сетку немного тоньше, зато более незаметной. Настраивая ширину (толщину) линий, можем придать сетке требуемый вид.
Класс
Line_style
выглядит так:
struct Line_style {
enum Line_style_type {
solid=FL_SOLID, // -------
dash=FL_DASH, // - - - -
dot=FL_DOT, // .......
dashdot=FL_DASHDOT, // - . – .
dashdotdot=FL_DASHDOTDOT, // -..-..
};
Line_style(Line_style_type ss):s(ss), w(0) { }
Line_style(Line_style_type lst, int ww):s(lst), w(ww) { }
Line_style(int ss):s(ss), w(0) { }
int width const { return w; }
int style const { return s; }
private:
int s;
int w;
};
Методы
программирования, использованные для определения класса
Line_style
, ничем не отличаются от методов, использованных для класса
Color
. Здесь мы снова скрываем тот факт, что для представления стилей линии библиотека FKTK использует тип
int
. Почему стоит скрывать эту информацию? Потому что эти способы представления при модификации библиотеки могут измениться. В следующей версии библиотеки FLTK может появиться тип
Fl_linestyle
, да и мы сами можем перенастроить наш интерфейс на другую библиотеку. В любом случае не стоит замусоривать свой код переменными типа
int
только потому, что мы знаем, как они задают стиль линий.
Как правило, мы не заботимся о стиле вообще; мы просто полагаемся на параметры, заданные по умолчанию (сплошные линии, ширина которых задана по умолчанию). Если мы не указываем ширину линии явно, то она задается конструктором. Установка значений по умолчанию — это одно из предназначений конструктора, а правильно выбранные значения, задаваемые по умолчанию, могут значительно облегчить работу пользователей.
Класс
Line_style
состоит из двух “компонентов”: характеристики стиля (например, пунктирные или сплошные линии) и ширины (толщина линий). Ширина измеряется в целых числах. По умолчанию ширина равна единице. Если нам нужна более широкая линия, то ее толщину можно задать следующим образом:
grid.set_style(Line_style(Line_style::dash,2));
В итоге получим следующее изображение:
Обратите внимание на то, что цвет и стиль относятся ко всем линиям, образующим фигуру. Это одно из преимуществ группирования нескольких линий в один графический объект, например класса
Lines
,
Open_polyline
или
Polygon
. Если мы хотим управлять цветом или стилем линий по отдельности, то их следует задать как отдельные объекты класса
Line
. Рассмотрим пример.
horizontal.set_color(Color::red);
vertical.set_color(Color::green);
На экране откроется окно, приведенное ниже.
13.6. Класс Open_polyline
Класс
Open_polyline
определяет фигуру, состоящую из ряда отрезков линий, соединенных между собой и заданных последовательностью точек. Слово
poly
имеет греческое происхождение и означает “много”, а
polyline
— это удобное имя для фигуры, состоящей из многих линий. Рассмотрим пример.
Open_polyline opl;
opl.add(Point(100,100));
opl.add(Point(150,200));
opl.add(Point(250,250));
opl.add(Point(300,200));
Этот фрагмент кода создает фигуру, которую можно нарисовать, соединяя следующие точки.
В принципе
Open_polyline
— это выдуманное слово, которое мы позаимствовали из детской игры “Connect the Dots” (“Соедини точки”).