Компоненты ввода и отображения текстовой, цифровой и иерархической информации. Компоненты отображения состояния
Использование класса ToggleButton для создания переключателей (радиокнопок)
В отличие от флажка, из группы переключателей может быть выбран (отмечен) один и только один. Именно поэтому второе название виджета — радиокнопка, по аналогии с кнопками на панели радиоприёмника. Нажатие на одну из его кнопок приводит к тому, что в группе автоматически отключается кнопка, нажатая до этого.
Переключатель представляет собой виджет, который может находиться в одном из двух состояний: включено или выключено, т.е., так же, как и флажок представляет собой кнопку выключателя. Поэтому для создания радиокнопок в Juce используется всё тот же класс, ToggleButton.
Применение класса ToggleButton для создания радиокнопок рассматривалось нами в примерах, приведённых в лекциях 6 и 8.
Повторим лишь, что для объединения переключателей в одну группу, необходимо воспользоваться методом void Button::setRadioGroupId(int newGroupId). Если метод у нескольких радиокнопок принимает в качестве параметра какое-либо одно, отличное от нуля, целое число, то эти кнопки начинают действовать как единая радиогруппа, т.е. возможно включение одной и только одной кнопки из набора.
Класс GroupComponent
Предоставляет возможность группировки любых кнопок (чаще всего), а также прочих компонентов управления и ввода-вывода информации. GroupComponent рисует группирующую рамку с краткой поясняющей надписью вверху. Никаких иных функций, помимо декоративных, компонент не несёт (см. "Шрифты и строки" ).
Текст поясняющей надписи может быть задан либо в конструкторе GroupComponent при объявлении экземпляра класса (GroupComponent::GroupComponent(const String& componentName = String::empty, const String& labelText = String::empty)), либо с использованием метода void GroupComponent::setText(const String& newText).
Программно получить текст надписи позволяет функция-член const String GroupComponent::getText() const.
По умолчанию текст надписи GroupComponent ориентирован влево. Изменить ориентацию позволяет метод void GroupComponent::setTextLabelPosition(const Justification& justification), где justification — флаг выравнивания текста (класс Justification). Понятно, что в случае виджета-рамки целесообразно пользоваться флагами Justification::left (влево), Justification::right (вправо) и Justification::centred (по центру).
Полоса состояния имеется во многих современных программах. Она располагается в нижней части главного окна приложения и отображает информацию о состоянии программы, подсказки от виджетов при наведении на них указателя мыши и т.п.
К сожалению, в библиотеке Juce нет стандартного компонента для создания полосы состояния, но класс подобного виджета несложно написать самим.
Пусть наша полоса состояния отображает следующую информацию: выводит текущие дату и время, а также подсказки от виджетов компонента содержимого. Для упрощения задачи в качестве основы для нашего приложения воспользуемся уже готовым примером из "Разработка собственных компонентов" (см. листинги пример 4.1 и пример 4.2).
Объявим класс полосы состояния TStatusBar, который унаследуем от классов Component и Timer ( пример 11.3).
#ifndef _TStatusBar_h_ #define _TStatusBar_h_ //------------------------------------------------------- #include "../JuceLibraryCode/JuceHeader.h" //------------------------------------------------------- // Наследуем класс полосы состояния от класса таймера class TStatusBar : public Component, public Timer { public: TStatusBar(); ~TStatusBar(); void paint(Graphics&); void resized(); // Периодически вызываемая функция (временной интервал вызова // функции задаётся методом startTimer) void timerCallback(); // Функция, выводящая подсказку на pMessagesLabel void ShowHint(String); private: Label* pMessagesLabel; Label* pDateTimeLabel; String sFormatDate(int); }; //-------------------------------------------------------- #endifЛистинг 11.3. Объявление класса полосы состояния TStatusBar (файл TStatusBar.h
Мы унаследовали класс виджета полосы состояния от класса таймера (Timer), который включает чистую виртуальную функцию virtual void Timer::timerCallback(). Именно эта функция будет ответственна в нашем примере за отображение даты и времени.
Кроме того, наш виджет будет включать два компонента: ярлыки pMessagesLabel, на который будет выводиться текст подсказок, и pDateTimeLabel, который будет отображать дату и время.
Предусмотрим в нашем классе метод, который будет отвечать за отображение подсказок на pMessageLabel — void TStatusBar::ShowHint(String).
Рассмотрим реализацию нашего класса ( пример 11.4).
#include "TStatusBar.h" #include "../JuceLibraryCode/JuceHeader.h" //------------------------------------------------ TStatusBar::TStatusBar() : Component("StatusBar"), Timer() { pMessagesLabel = new Label("MessagesLabel", ""); addAndMakeVisible(pMessagesLabel); pMessagesLabel->setColour(Label::backgroundColourId, Colours::azure); pDateTimeLabel = new Label("DateTimeLabel", ""); addAndMakeVisible(pDateTimeLabel); // Дата и время отображаются у правого края окна программы pDateTimeLabel->setJustificationType(Justification::right); pDateTimeLabel->setColour(Label::backgroundColourId, Colours::azure); // В первый раз отображаем дату и время this->timerCallback(); // Вызываем функцию timerCallback каждую секунду this->startTimer(1000); } //---------------------------------------------------- TStatusBar::~TStatusBar() { // При завершении работы останавливаем таймер this->stopTimer(); deleteAllChildren(); } //---------------------------------------------------- void TStatusBar::paint(Graphics& Canvas) { Canvas.fillAll(Colours::azure); } //---------------------------------------------------- void TStatusBar::resized() { pMessagesLabel->setBounds(0, proportionOfHeight(1.0000f) — 25, proportionOfWidth(0.6000f), 25); pDateTimeLabel->setBounds(proportionOfWidth(0.6500f), proportionOfHeight(1.0000f) - 25, proportionOfWidth(0.3500f), 25); } //---------------------------------------------------- // Функция форматирования даты (выводит предшествующий ноль в однозначных цифрах) String TStatusBar::sFormatDate(int iNumber) { // Преобразуем число в соответствующую строку String sNumber = String(iNumber); switch(iNumber) { case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 8: case 9: { // Если число в диапазоне от 0 до 9, // добавим в начало соответствующей ему строки ноль sNumber = (String("0") += sNumber); break; } default: { break; } } return sNumber; } //--------------------------------------------------------- void TStatusBar::timerCallback() { // Получаем текущую дату и время Time DateTime = Time::getCurrentTime(); // Форматируем день (число месяца) String sDay = sFormatDate(DateTime.getDayOfMonth()); // Форматируем месяц String sMonth = sFormatDate(DateTime.getMonth() + 1); // Получаем год в виде строки String sYear = String(DateTime.getYear()); // Форматируем час, минуты и секунды текущей даты String sHours = sFormatDate(DateTime.getHours()); String sMinutes = sFormatDate(DateTime.getMinutes()); String sSeconds = sFormatDate(DateTime.getSeconds()); // Формируем результирующую строку String sDateTime = sDay + "." + sMonth + "." + sYear + " - " + sHours + ":" + sMinutes + ":" + sSeconds; // Отображаем отформатированные дату и время pDateTimeLabel->setText(sDateTime, false); } //------------------------------------------------------ void TStatusBar::ShowHint(String sHint) { // Отображаем строку подсказки, полученную в качестве параметра pMessagesLabel->setText(sHint, false); } //-----------------------------------------------------Листинг 11.4. Реализация класса полосы состояния TStatusBar (файл TStatusBar.cpp)