Элементы управления. Вкладки
Цель лекции: Научиться создавать и использовать вкладки
Многостраничные панели позволяют экономить пространство окна приложения, организуя с помощью специальных компонентов, вкладок, напоминающих закладки книги, размещение на одном и том же месте окна виджетов разного содержания. При выборе одной из вкладок в окне будет отображён закреплённый за ней виджет ( рис. 16.1 ).
Для создания многостраничной панели в библиотеке Juce имеется класс TabbedComponent. Этот компонент представляет собой комбинацию из виджетов двух классов: TabbedButtonBar и TabBarButton.
TabbedButtonBar создаёт вертикальную или горизонтальную панель, содержащую то или иное число вкладок. Сами вкладки — это объекты класса TabBarButton, которые, как понятно из названия, являются разновидностью кнопок и наследуют методы класса Button (см. "Элементы управления. Кнопки" ).
Рассмотрим работу всех этих компонентов на примере простой программы ( рис. 16.1 ), компонент содержимого которой включает многостраничную панель с тремя вкладками ( пример 16.1). На каждой вкладке размещается ярлык с надписью. При выборе пользователем той или иной вкладки выводится информирующее сообщение.
#ifndef _TCentralComponent_h_ #define _TCentralComponent_h_ //--------------------------------------------------- #include "../JuceLibraryCode/JuceHeader.h" //--------------------------------------------------- // Класс компонента содержимого. // Наследует класс слушателя кнопок class TCentralComponent : public Component, public ButtonListener { public: TCentralComponent(); ~TCentralComponent(); void paint(Graphics&); void resized(); // Функция, отслеживающая щелчки по кнопке void buttonClicked(Button*); private: // Многостраничная панель TabbedComponent* pTabWidget; // Надписи вкладок панели Label* pLabel; Label* pLabel1; Label* pLabel2; // Предотвращает создание копии конструктора и оператора = TCentralComponent(const TCentralComponent&); const TCentralComponent& operator= (const TCentralComponent&); }; //------------------------------------------------ #endifЛистинг 16.1. Объявление класса компонента содержимого TCentralComponent (файл TCentralComponent.h)
При создании многостраничной панели в конструктор класса TabbedComponent передаётся информация о положении вкладок. Она кодируется идентификаторами перечислимого списка enum TabbedButtonBar::Orientation:
- TabsAtTop — вкладки располагаются сверху;
- TabsAtBottom — вкладки располагаются снизу;
- TabsAtLeft — вкладки располагаются слева;
- TabsAtRight — вкладки располагаются справа.
Поменять положение вкладок можно с помощью метода void TabbedComponent::setOrientation(TabbedButtonBar::Orientation orientation). Такой же метод есть и у класса TabbedButtonBar.
Ширину или высоту вкладок в пикселях можно установить с помощью метода void TabbedComponent::setTabBarDepth(int newDepth).
Добавим вкладки на многостраничную панель ( пример 16.2), воспользовавшись методом void TabbedComponent::addTab(const String& tabName, const Colour& tabBackgroundColour, Component* contentComponent, bool deleteComponentWhenNotNeeded, int insertIndex = -1). Метод принимает следующие параметры:
- tabName — название вкладки; именно оно будет отображаться на ней как подпись;
- tabBackgroundColour — цвет фона вкладки;
- contentComponent — ассоциированный с вкладкой виджет;
- deleteComponentWhenNotNeeded — флаг того, что виджет следует удалить после того, как в нём отпадёт необходимость;
- insertIndex — позиция добавления вкладки; если параметр принимает значение -1 (по умолчанию), то вкладки добавляются в горизонтальной позиции слева направо. При этом первая вкладка автоматически выбирается.
#include "TCentralComponent.h" //---------------------------------------------------- #define tr(s) String::fromUTF8(s) //---------------------------------------------------- TCentralComponent::TCentralComponent() : Component("Central Component"), pTabWidget(0) { // Вкладки многостраничной панели расположены сверху pTabWidget = new TabbedComponent(TabbedButtonBar::TabsAtTop); pTabWidget->setTabBarDepth(30); pLabel = new Label(L"Label0", L"Label 0"); // Шрифт надписи крупный, полужирный pLabel->setFont(Font(40.0000f, Font::bold)); pLabel->setJustificationType(Justification::centred); pLabel->setEditable(false, false, false); pLabel1 = new Label(L"Label1", L"Label 1"); pLabel1->setFont(Font(40.0000f, Font::bold)); pLabel1->setJustificationType(Justification::centred); pLabel1->setEditable(false, false, false); pLabel2 = new Label(L"Label2", L"Label 2"); pLabel2->setFont(Font(40.0000f, Font::bold)); pLabel2->setJustificationType(Justification::centred); pLabel2->setEditable(false, false, false); // Добавляем на панель вкладку голубого цвета, содержащую в качестве // виджета ярлык pLabel pTabWidget->addTab(L"Tab 0", Colours::lightblue, pLabel, true); // Добавляем компонент содержимого в качестве слушателя кнопки для вкладки pTabWidget->getTabbedButtonBar().getTabButton(0)->addListener(this); // Добавляем на панель вкладку светло-зелёного цвета, содержащую в качестве // виджета ярлык pLabel1 pTabWidget->addTab(L"Tab 1", Colours::lightgreen, pLabel1, true); pTabWidget->getTabbedButtonBar().getTabButton(1)->addListener(this); // Добавляем на панель вкладку красно-фиолетового цвета, // содержащую в качестве виджета ярлык pLabel2 pTabWidget->addTab(L"Tab 2", Colours::palevioletred, pLabel2, true); pTabWidget->getTabbedButtonBar().getTabButton(2)->addListener(this); pTabWidget->setCurrentTabIndex(0); addAndMakeVisible(pTabWidget); setSize (600, 400); }Листинг 16.2. Реализация конструктора класса компонента содержимого TCentralComponent (файл TCentralComponent.cpp)
Удалить определённую вкладку по её индексу в панели позволяет функция void TabbedComponent::removeTab(int tabIndex). Для того, чтобы удалить все имеющиеся вкладки, необходимо вызвать метод void TabbedComponent::clearTabs().
Характеристики добавленной в TabbedComponent вкладки при необходимости можно менять. Так, метод void TabbedComponent::setTabName(int tabIndex, const String& newName) позволяет изменить заголовок вкладки с индексом tabIndex на newName. Изменить цвет фона вкладки можно, обратившись к методу void TabbedComponent::setTabBackgroundColour(int tabIndex, const Colour& inewColour).
Получить индекс и заголовок текущей, т.е. выбранной пользователем вкладки позволяют методы int TabbedComponent::getCurrentTabIndex() const и const String TabbedComponent::getCurrentTabName() const, соответственно.
Вкладку можно выбрать программно, задав её индекс с помощью функции void TabbedComponent::setCurrentTabIndex(int newTabIndex, bool sendChangeMessage = true).
При необходимости выполнить какие-то действия с компонентом, ассоциированным с вкладкой, получить указатель на него позволяет метод Component* TabbedComponent::getCurrentContentComponent() const throw().
Кроме того, компонент TabbedComponent позволяет получить названия (заголовки) и число включённых в него вкладок с помощью методов StringArray TabbedComponent::getTabNames() const и int TabbedComponent::getNumTabs() const, соответственно.
Итак, в нашем примере мы добавили с помощью метода addTab на многостраничную панель три вкладки разного цвета, содержащие три ярлыка с различающимися надписями ( пример 16.2, рис. 16.1 ).
Поскольку каждая вкладка — это своеобразная кнопка, то мы можем обработать её выбор пользователем в методе buttonClicked, добавив к ней слушатель кнопок. Получить доступ к панели вкладок можно с помощью метода TabbedButtonBar& TabbedComponent::getTabbedButtonBar() const. В свою очередь, класс TabbedButtonBar включает метод TabBarButton* TabbedButtonBar::getTabButton(int index) const, позволяющий получить указатель на ту или иную вкладку панели по её индексу. Последовательным вызовом этих методов мы и воспользовались для назначения компонента содержимого в качестве слушателя кнопок для каждой из вкладок многостраничной панели ( пример 16.2).
Завершает наш пример обработчик выбора вкладки buttonClicked, в котором формируется соответствующее сообщение ( пример 16.3).
void TCentralComponent::buttonClicked(Button* pButton) { String sMessage = tr("Выбрана вкладка "); if(pButton == pTabWidget->getTabbedButtonBar().getTabButton(0)) { sMessage += "0"; } else if(pButton == pTabWidget->getTabbedButtonBar().getTabButton(1)) { sMessage += "1"; } else if(pButton == pTabWidget->getTabbedButtonBar().getTabButton(2)) { sMessage += "2"; } AlertWindow::showMessageBox(AlertWindow::InfoIcon, tr("Информация"), sMessage, tr("Да"), 0); }Листинг 16.3. Реализация метода buttonClicked класса компонента содержимого TCentralComponent (файл TCentralComponent.cpp)
Краткие итоги
В этой лекции вы познакомились с вкладками и классами, необходимыми для их создания: TabBarButton (собственно вкладка), TabbedButtonBar (компонент, который создаёт вертикальную или горизонтальную панель, содержащую то или иное число вкладок) и TabbedComponent (комбинация двух предыдущих компонентов).
Упражнение
Создайте платформ-независимый проект с помощью Introjucer на основе листингов лекции. Соберите программу, включающую окно с изменяемыми размерами для Вашей среды разработки. Поэкспериментируйте с внешним видом окна.
Дополнительные материалы
Архив с исходными текстами примера Вы можете скачать здесь.