Компоненты ввода и отображения текстовой, цифровой и иерархической информации. Компоненты выбора из списков
Цель лекции: Научиться применять компоненты выбора из списков
К компонентам выбора из списков относятся собственно список (ListBox), уже знакомый нам по предыдущим примерам выпадающий список (ComboBox), а также табличный список или просто таблица (TableListBox). Кроме того, в библиотеке Juce имеется специальный компонент для отображения файлов в заданной директории в виде списка — FileListComponent (унаследован от ListBox).
Все вышеперечисленные компоненты отображают списки строк, отличаясь лишь представлением данных. Так, если ListBox отображает список в раскрытом виде и автоматически добавляет полосы прокрутки, если элементы списка не помещаются в границах компонента, то ComboBox отображает строки в виде выпадающего списка, что обычно удобнее, т.к. экономит площадь окна приложения.
Обычно принято разделять саму информацию или модель данных (model) и её представление на экране (view, вид), поэтому компоненты ListBox и TableListBox предназначены лишь для отображения данных, а для их хранения и преобразования отвечают подкласс ListBoxModel и абстрактный класс TableListBoxModel.
Класс ListBox — это компонент, предоставляющий пользователю возможность выбора одного или нескольких элементов из линейного списка (строк). Возможность выбора пользователем одного или нескольких элементов списка задаётся методом void ListBox::setMultipleSelectionEnabled(bool shouldBeEnabled), где shouldBeEnabled — флаг включения (true) или выключения (false) возможности множественного выбора элементов. Множественный выбор элементов возможен с использованием клавиш <SHIFT> и <CTRL>. В первом случае выбрать прилегающие друг к другу элементы пользователь может, выделив одну из строк, и затем, нажав клавишу <SHIFT>, щёлкнуть мышью по последнему элементу выбираемого диапазона. Выделить неприлегающие друг к другу элементы пользователь может, удерживая нажатой во время выбора клавишу <CTRL>. По умолчанию пользователь может выбирать один и только один элемент.
Иногда может оказаться полезной функция void ListBox::setMouseMoveSelectsRows(bool shouldSelect), которая включает выбор элементов списка наведением на них указателя мыши в случае, если её параметр принимает значение true. Включение этой функции отменяет действие метода setMultipleSelectionEnabled.
Число отображаемых в списке элементов задаётся моделью данных (ListBoxModel), которая может быть либо передана как параметр конструктора списка ListBox::ListBox(const String &componentName = String::empty, ListBoxModel* model = 0), либо задана функцией-членом класса void ListBox::setModel(ListBoxModel* newModel).
Получить указатель на текущую модель можно с помощью функции ListBoxModel* ListBox::getModel() const throw(). Использование методов setModel и getModel полезно в случае, если один и тот же список отвечает за представление нескольких наборов данных.
Узнать, какой элемент списка выбрал пользователь, можно с помощью метода int ListBox::getLastRowSelected() const, который возвращает номер строки, выбранной пользователем последней. В случае, если разрешён множественный выбор элементов списка, то возвращается номер строки, выбранной последней из набора, а не строки с максимальным номером. Т.е., если выбраны последовательно строки 10, 12, а затем 6, то функция getLastRowSelected вернёт 6. В том случае, если ни одна строка не была выбрана, будет возвращено значение -1.
Если нам необходимо знать индексы всех выбранных пользователем элементов списка, то можно воспользоваться методом const SparseSet<int> ListBox::getSelectedRows() const, который возвращает номера выбранных строк в виде набора целых (класс SparseSet библиотеки Juce предназначен для хранения набора элементарных типов).
Узнать, сколько строк выбрал пользователь, позволяет метод int ListBox::getNumSelectedRows() const.
Ряд функций-членов класса позволяет делать программный выбор элементов списка:
- void ListBox::selectRow(int rowNumber, bool dontScrollToShowThisRow = false, bool deselectOthersFirst = true) — выбирает строку с номером rowNumber. Если параметр dontScrollToShowThisRow принимает значение false, то при выборе строки позиция выбранной строки меняется таким образом, чтобы она отображалась в видимой части списка. В случае, если параметр deselectOthersFirst принимает значение true, перед выбором заданной строки отменяется выбор ранее выбранных элементов списка. В случае, если строка с номером rowNumber уже была ранее выбрана, функция selectRow не делает ничего.
- void ListBox::selectRangeOfRows(int firstRow, int lastRow) позволяет выбрать ряд прилегающих друг к другу элементов списка в диапазоне от firstRow до lastRow.
- void ListBox::deselectRow(int rowNumber) отменяет выбор элемента с номером rowNumber. Если он не был выбран ранее, функция не делает ничего.
- void ListBox::deselectAllRows() отменяет выбор всех ранее выбранных строк.
- void ListBox::flipRowSelection(int rowNumber) выбирает элемент, если он не был ранее выбран, и наоборот.
Рассмотрим создание списка простейшем примере отображения 4-х элементов (Элемент 1, Элемент 2, Элемент 3 и Элемент 4). В качестве компонента содержимого в нашем примере будет выступать экземпляр класса TListBox, который мы унаследуем от ListBox и ListBoxModel (поскольку для нас неважно разделение данных и их представления, создаваемый класс будет выступать в качестве модели для самого себя). Объявление класса приведено в листинге 9.1 .
#ifndef _TListBox_h_ #define _TListBox_h_ //---------------------------------------------------- #include "../JuceLibraryCode/JuceHeader.h" //---------------------------------------------------- class TListBox : public ListBox, ListBoxModel { public: TListBox(const String& sName = String::empty, ListBoxModel* pModel = 0); ~TListBox(); // Получаем число строк в списке int getNumRows(); // Функция, рисующая каждый из элементов списка void paintListBoxItem(int, Graphics&, int, int, bool); private: // Предотвращает создание копии конструктора и оператора = TListBox(const TListBox&); const TListBox& operator= (const TListBox&); }; //--------------------------------------------------- #endifЛистинг 9.1. Объявление класса TListBox (файл TListBox.h)