Элементы управления. Кнопки
В конструкторе класса компонента содержимого мы создаем "пустую" кнопку DrawableButton, которая будет показывать надпись "Закрыть" под отображаемыми картинками.
Для того, чтобы наша кнопка pCloseButton могла показывать изображения, созданные в GIMP, мы должны получить их из объектов класса DrawableImage с помощью метода
void DrawableButton::setImages( const Drawable* normalImage, const Drawable* overImage = 0, const Drawable* downImage = 0, const Drawable* disabledImage = 0, const Drawable* normalImageOn = 0, const Drawable* overImageOn = 0, const Drawable* downImageOn = 0, const Drawable* disabledImageOn = 0 ).
Смысл передаваемых параметров понятен из их названий:
- normalImage — изображение кнопки в ее "нормальном", ненажатом состоянии. Единственный параметр, значение которого не может быть равным нулю;
- overImage — изображение кнопки при наведении на нее мыши. В случае, если параметр принимает нулевое значение, для отрисовки этого состояния будет использовано изображение normalImage;
- downImage — изображение кнопки в нажатом состоянии. В случае, если параметр принимает нулевое значение, для отрисовки этого состояния будет использовано изображение overImage;
- disabledImage — изображение кнопки в недоступном состоянии. В случае, если параметр принимает нулевое значение, для отрисовки этого состояния будет использовано изображение normalImage с увеличенной прозрачностью;
- normalImageOn — то же самое, что и normalImage, но используется в том случае, если кнопка с фиксацией нажатого состояния находится в режиме "включено" (on). В случае, если параметр принимает нулевое значение, для отрисовки этого состояния будет использовано изображение normalImage;
- overImageOn — то же самое, что и overImage, но используется в том случае, если кнопка с фиксацией нажатого состояния находится в режиме "включено" (on). В случае, если параметр принимает нулевое значение, для отрисовки этого состояния будет использовано изображение normalImageOn;
- downImageOn — то же самое, что и downImage, но используется в том случае, если кнопка с фиксацией нажатого состояния находится в режиме "включено" (on). В случае, если параметр принимает нулевое значение, для отрисовки этого состояния будет использовано изображение overImageOn;
- disabledImageOn — то же самое, что и disabledImage, но используется в том случае, если кнопка с фиксацией нажатого состояния находится в режиме "включено" (on). В случае, если параметр принимает нулевое значение, для отрисовки этого состояния будет использовано нормальное изображение с увеличенной прозрачностью.
Поскольку мы подготовили лишь два файла изображений для кнопки рис. 12.3, то, соответственно, мы будем передавать в метод setImages лишь два объекта класса DrawableImae — UpImage для ненажатой и DownImage — для нажатой кнопки.
Загружать изображения из графических файлов в объекты DrawableImage мы будем с помощью метода void DrawableImage::setImage(const Image& imageToUse). В качестве параметра в функцию передается объект класса Image, служащего для хранения данных изображения фиксированного размера. Этот класс предназначен лишь для хранения данных изображения и не имеет методов для их загрузки из файла или памяти. Для этого предназначен класс ImageCache. Мы воспользовались его методом static const Image ImageCache::getFromFile(const File& file) для того, чтобы загрузить данные изображений из графических файлов и передать возвращаемое значение в качестве параметра в метод setImage объектов UpImage и DownImage пример 12.2.
В свою очередь, метод getFromFile в качестве параметра получает объект класса File, предназначенного для манипуляций с локальными файлами и директориями. В качестве параметра конструктора объект класса получает строку, содержащую абсолютный путь к файлу.
Чтобы сформировать эту строку, мы получаем вначале текущую рабочую папку нашей программы (напомним, что файлы загружаемых изображений должны находиться именно в ней) с помощью метода static const File File::getCurrentWorkingDirectory(), а затем получаем путь к ней с помощью функции const String& File::getFullPathName() const throw(). После этого добавляем к полученному пути названия графических файлов через слеш. Поскольку в Windows и Linux использование прямого и обратного слешей в полных именах файлов различается, воспользуемся директивами условной компиляции пример 12.2 .
Внешний вид работающей программы показан на рисунке 12.4 .
Наша программа имеет ряд мелких, но существенных недостатков: во-первых, есть риск что используемые файлы изображений могут быть удалены по ошибке, а во-вторых, метод getCurrentWorkingDirectory() может возвращать разные значения в зависимости от условий запуска исполняемого файла нашей программы: например, в в Windows при запуске для отладки в среде разработки; в Linux — при запуске не из командной строки, а щелчком мышью по значку файла. Все это, хоть и не вызовет краха программы, но приведет к неправильному отображению закрывающей кнопки.
Поэтому удобнее, если загружаемые изображения будут "зашиты" в самом исполняемом файле программы.
Добавлять те или иные изображения в программу в виде платформо-независимых ресурсов в Juce можно двумя способами: во-первых, если вы остановились на визуальном проектировании компонента, можно воспользоваться возможностями jucer и, во-вторых, можно использовать консольную утилиту BinaryBuilder, входящую в поставку Juce.
В первом случае бинарные ресурсы, описывающие изображения, будут добавлены в класс создаваемого компонента в виде его членов, а во втором — для них будет создано отдельное пространство имен (namespace).
Для того, чтобы добавить бинарный ресурс в класс компонента, нужно в jucer создать новый компонент (File > New Component), перейти на вкладку Resources, нажать на кнопку "Add new resource..." и в появившемся диалоговом окне выбрать нужный файл изображения ) рис. 12.5). В объявление класса будут добавлены две переменнные (static const char* и static const int), описывающие само изображение и его размер, и соответствующие имени ресурса, отображаемого на вкладке jucer. Например, если вы выбрали изображение picture.png, то название ресурса будет picture_png, а имена переменных static const char* picture_png и static const int picture_pngSize.
Для того, чтобы добавить бинарные ресурсы в виде отдельного пространства имен, как упоминалось выше, необходимо использовать консольную утилиту BinaryBuilder. Она находится в папке <каталог Juce>/juce/extras/binarybuilder. Как и другие утилиты, входящие в поставку juce, BinaryBuilder распространяется в виде исходных текстов, поэтому программу требуется предварительно откомпилировать.
Запущенная без параметров, утилита BinaryBuilder выводит краткую справку по своему использованию. Запускать программу следует со следующими параметрами:
BinaryBuilder sourcedirectory targetdirectory targetclassnam
где
- sourcedirectory — папка, в которой находятся добавляемые изображения или другие бинарные ресурсы;
- targetdirectory — папка, в которой будут сохранены генерируемые файлы исходных текстов;
- targetclassname — название пространства имен бинарных ресурсов.
И в том, и в другом случае бинарные данные графического файла переводятся в форму обычного массива C++ пример 12.3.
static const unsigned char ucGimpbuttondown_png[] = {137,80,78,71,13,10,26,10,0,0 ...Листинг 12.3. Бинарный ресурс в виде массива C++ (фрагмент кода)