Опубликован: 13.07.2012 | Доступ: свободный | Студентов: 460 / 8 | Оценка: 5.00 / 5.00 | Длительность: 18:06:00
Специальности: Программист
Лекция 8:

Ввод и отображение текстовой информации

< Лекция 7 || Лекция 8: 1234 || Лекция 9 >

Класс TextEditor

В большинстве GUI framework-ов имеются отдельные компоненты или виджеты для создания однострочного и многострочного полей ввода (например, классы QLineEdit и QTextEdit в Qt). В библиотеке Juce для этих целей используется один и тот же класс, TextEditor, внешний вид и поведение экземпляров которого может значительно различаться, в зависимости от настроек, задаваемых программистом.

Виджеты этого класса предоставляют пользователю возможности для ввода и редактирования данных, текста и чисел, а также обмена данными с буфером обмена (вырезание, копирование и вставка), что избавляет разработчика от дополнительной реализации. Текст можно выделять с помощью мыши, клавиатуры и контекстного меню.

Ввод текста пользователем в виджете TextEditor может осуществляться как в одну строку, так и в несколько строк. Режим ввода задаётся методом void TextEditor::setMultiLine(bool shouldBeMultiLine, bool shouldWordWrap = true). Эту функцию необходимо вызвать сразу же после объявления объекта класса TextEditor (впрочем, если вы хотите получить однострочное поле ввода, то её можно не вызывать). Если первый из её параметров принимает значение false, то виджет принимает вид однострочного поля ввода, а если true, то появляется возможность вводить несколько строк. Если значение второго параметра равно true, то в виджете перенос строк будет осуществляться автоматически по достижении его края при наборе текста. В противном случае перенос строки будет осуществляться исключительно по нажатию клавиши <ENTER>.

Текст, находящийся в виджете, возвращает метод const String TextEditor::getText() const. Новый текст в нём задаёт функция void TextEditor::setText(const String& newText, bool sendTextChangeMessage = true). Она очищает поле ввода и вставляет в виджет текст newText. В том случае, если параметр sendTextChangeMessage принимает значение true, то посылается сообщение об изменении текста всем слушателям (listeners) поля ввода.

Для помещения текста в область виджета, помимо метода setText, можно воспользоваться функцией void TextEditor::insertTextAtCaret(const String& textToInsert), которая вставляет текст textToInsert на текущей позиции курсора. В случае, если какой-то участок текста был выделен, то при вызове функции он заменяется на строку-параметр. Этим можно воспользоваться для программного удаления какого-либо участка текста: вызвать вначале функцию-член void TextEditor::setHighlightedRegion(const Range< int >& newSelection), чтобы выделить участок текста, а затем — метод insertTextAtCaret с путой строкой (String::empty) в качестве параметра.

Как правило, нажатие пользователем клавиши <ENTER> на клавиатуре означает завершение ввода строки и переход на новую. Однако в некоторых случаях требуется иная реакция на нажатие этой клавиши. С помощью функции void TextEditor::setReturnKeyStartsNewLine(bool shouldStartNewLine) можно изменить поведение текстового поля ввода на нажатие клавиши <ENTER>. Если параметр shouldStartNewLine принимает значение false, то нажатие на клавишу не приводит к переходу на новую строку, а сообщение об этом событии будет обработано в слушателе поля ввода (TextEditor::Listener). В случае, если поле ввода является однострочным, метод setReturnKeyStartsNewLine можно не вызывать.

Вызов метода void TextEditor::setReadOnly(bool shouldBeReadOnly) с параметром true устанавливает режим, который даёт возможность только просмотра текста, но не редактирования его пользователем. В случае необходимости изменить текст, его можно передать виджет программно, например, функцией setText.

В случае, если объект класса TextEditor используется как однострочное поле ввода, можно включить режим ввода пароля. Этот режим устанавливается в конструкторе компонента TextEditor::TextEditor(const String& componentName = String::empty, juce_wchar passwordCharacter = 0). В случае, если второй параметр принимает значение, отличное от нуля, то все вводимые пользователем символы будут замещаться каким-либо другим. Параметр passwordCharacter, собственно, и содержит код замещающего символа. Подробнее с использованием TextEditor в качестве поля ввода пароля можно познакомиться на примере, приведённом ниже.

В случае, если вы используете объект класса TextEditor в качестве многострочного поля ввода, отображаемый текст может превышать размеры виджета. При этом просмотр текста возможен с помощью полос прокрутки. Для их автоматического отображения необходимо вызвать метод void TextEditor::setScrollbarsShown(bool shouldBeEnabled) с параметром true. Если толщина полос прокрутки по умолчанию вас по каким-либо причинам не устраивает, её можно задать программно вызовом функции void TextEditor::setScrollBarThickness(int newThicknessPixels), где параметр — толщина используемых полос прокрутки в пикселях.

Класс TextEditor включает ряд методов для работы с буфером обмена:

  • void TextEditor::copy() - копирует выделенную область в буфер обмена;
  • void TextEditor::cut() - также копирует выделенную область в буфер обмена, но с последующим её удалением;
  • void TextEditor::paste() - вставляет содержимое буфера обмена в поле ввода за позицией курсора.
  • Также класс TextEditor включает ряд методов редактирования текста:
  • void TextEditor::doUndoRedo(bool isRedo) — в зависимости от параметра повторяет или отменяет проделанное действие пользователя по редактированию;
  • void TextEditor::setSelectAllWhenFocused(bool b) — выделяет весь текст в поле ввода, когда оно в фокусе (параметр должен принимать значение true);
  • void TextEditor::clear() - очищает поле ввода.

Зачастую возникает ситуация, когда необходимо разрешить пользователю ввод только определённого набора символов (шаблон или маска ввода). Задать маску ввода можно вызовом метода void TextEditor::setInputRestrictions(int maxTextLength, const String& allowedCharacters = String::empty), где maxTextLength — максимально допустимая длина вводимого текста (в символах), а allowedCharacters — строка, содержащая допустимые символы. В случае, если первый параметр принимает значение 0, ограничений на длину ввода нет. Подробнее с использованием маски ввода можно познакомиться на примере, приведённом ниже.

Рассмотрим использование компонентов Label и TextEditor на примере программы, внешний вид которой показан на рисунке 8.1 .

Программа, демонстрирующая ввод и отображение текстовой информации

Рис. 8.1. Программа, демонстрирующая ввод и отображение текстовой информации

Окно программы разделено на три секции. В качестве разделителей используются два объекта класса Label, pSeparator и pSeparator1. Для того, чтобы ярлыки были видны в виде тонких серых полосок, мы задали соответствующий цвет их контура вызовом функции setColour, а высоту виджетов в методе resized класса TCentralComponent установили равной 1 пикселю ( пример 8.2).

// Создание ярлыка, надпись которого содержит пустую строку
pSeparator = new Label("Separator", String::empty);
// Запрет на редактирование
pSeparator->setEditable(false, false, false);
// Задаём цвет контура ярлыка
pSeparator->setColour(Label::backgroundColourId, Colour(0x3d000000));
addAndMakeVisible(pSeparator);

// Реализация метода TCentralComponent::resize();
// Высота виджета — 1 пиксель
pSeparator->setBounds(8, 136, 704, 1);
Листинг 8.2. Пример использования объекта класса Label в качестве линии — разделителя (файл TCentralComponent.cpp)

Первая секция нашей программы будет содержать многострочное поле ввода без возможности непосредственного редактирования текста пользователем (только чтение), TextEditor* pTextEditor; однострочное поле, TextEditor* pAppendTextEdit, для ввода пользователем текста, который будет добавляться в TextEditor после нажатия на кнопку, а также сами кнопки:

  • TextButton* pClearButton — очищает поле ввода;
  • TextButton* pAppendTextButton — добавляет текст из pAppendTextEdit в конец имеющегося в компоненте pTextEditor;
  • TextButton* pSetTextButton — замещает текст компонента pTextEditor текстом из pAppendTextEdit.
  • Кроме того, в секции имеется выпадающий список ComboBox* pFontSelectionBox выбора шрифта для задания атрибутов текста в pTextEditor ( пример 8.3).
#include "TCentralComponent.h"
//----------------------------------------------------
#define tr(s) String::fromUTF8(s)
//----------------------------------------------------
TCentralComponent::TCentralComponent() : Component("Central Component"),
            pTextEditor(0),
            pAppendTextEdit(0),
            pFontSelectionBox(0),
            pClearButton(0),
            pAppendTextButton(0),
            pSetTextButton(0),
            pSeparator(0),
            pLabel(0),
            pLabelGroup(0),
            pReadOnlyButton(0),
            pEditByOneClickButton(0),
            pEditByDoubleClickButton(0),
            pSeparator1(0)
{
  // Создаём новое поле ввода (текстовый редактор)
  pTextEditor = new TextEditor("TextEditor");
  // Разрешаем ввод более одной строки
  // и разрешаем автоматический перенос строк
  pTextEditor->setMultiLine(true, true);
  // Запрет на редактирование
  pTextEditor->setReadOnly(true);
  // Показываем полосы прокрутки
  pTextEditor->setScrollbarsShown(true);
  addAndMakeVisible(pTextEditor);

  // Шрифт для ранее созданного поля ввода
  Font TextEditorFont;
  // Гарнитура - шрифт Sans-Serif по умолчанию
  TextEditorFont.setTypefaceName(Font::getDefaultSerifFontName());
  TextEditorFont.setHeight(20);
  // Устанавливаем шрифт TextEditorFont в качестве
  // шрифта поля ввода
  pTextEditor->setFont(TextEditorFont);
  pTextEditor->setTextToShowWhenEmpty("Text Editor", Colours::grey);

  // Создаём поле ввода для текста, добавляемого
  // в многострочное поле pTextEditor
  pAppendTextEdit = new TextEditor("AppendTextEdit");
  // Ввод текста - в одну строку
  pAppendTextEdit->setMultiLine(false);
  // Разрешаем ввод текста
  pAppendTextEdit->setReadOnly(false);
  // Показываем полосы прокрутки
  pAppendTextEdit->setScrollbarsShown(false);
  // Делаем видимым курсор
  pAppendTextEdit->setCaretVisible(true);
  // Разрешаем стандартное контекстное меню
  pAppendTextEdit->setPopupMenuEnabled(true);
  // Текст поля - пустая строка
  pAppendTextEdit->setText(String::empty);
  addAndMakeVisible(pAppendTextEdit);

  // Выпадающий список выбора шрифта
  pFontSelectionBox = new ComboBox("FontSelectionBox");
  pFontSelectionBox->setEditableText(false);
  pFontSelectionBox->setJustificationType(Justification::centredLeft);
  pFontSelectionBox->setTextWhenNothingSelected(tr("Выбрать"));
  // Устанавливаем в качестве слушателя выпадающего списка
  // сам компонент-контейнер
  pFontSelectionBox->addListener(this);
  addAndMakeVisible(pFontSelectionBox);

  // Получаем имена системных шрифтов, сохраняем их 
  // в строковом массиве...
  StringArray sSystemFonts = Font::findAllTypefaceNames();
  // и добавляем в выпадающий список
  for(int i = 0; i < sSystemFonts.size(); i++)
  {
    pFontSelectionBox->addItem(sSystemFonts[i], i + 1);
  }

  // Кнопка, очищающая поле pTextEditor
  pClearButton = new TextButton("ClearButton");
  pClearButton->setButtonText(tr("Очистить"));
  // Устанавливаем в качестве слушателя кнопки
  // сам компонент-контейнер
  pClearButton->addListener(this);
  addAndMakeVisible(pClearButton);

  // Кнопка, добавляющая текст в поле pTextEditor
  pAppendTextButton = new TextButton("AppendTextButton");
  pAppendTextButton->setButtonText(tr("Добавить текст"));
  pAppendTextButton->addListener(this);
  addAndMakeVisible(pAppendTextButton);

  // Кнопка, замещающая текст в поле pTextEditor
  pSetTextButton = new TextButton("SetTextButton");
  pSetTextButton->setButtonText(tr("Заменить текст"));
  pSetTextButton->addListener(this);
  addAndMakeVisible(pSetTextButton);
Листинг 8.3. Часть реализации конструктора класса TCentralComponent (1-я секция демонстрационной программы ввода и отображения текстовой информации, файл TCentralComponent.cpp)
< Лекция 7 || Лекция 8: 1234 || Лекция 9 >