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

Элементы управления. Кнопки

< Лекция 11 || Лекция 12: 1234 || Лекция 13 >

Обратите внимание, что метод changeWidthToFitText должен вызываться дважды: в обработчике щелчка по кнопке buttonClicked, и в функции resized; в противном случае при каждом изменении размеров окна, например, растягивании, кнопка будет возвращаться к начальной форме, заданной параметрами метода setBounds.

Зачастую в надписи на кнопке один из символов подчеркнут. Это означает, что пользователь может нажать комбинацию клавиш <ALT>+<S>, где <S> - это подчеркнутый символ, и это будет эквивалентно щелчку по кнопке. Добиться этого можно с помощью метода void Button::addShortcut(const KeyPress& key), где key — код "горячей" клавиши с или без модификатора (<CTRL>, <ALT>, <SHIFT> и т.п.). Например, если нам нужно, чтобы обработчик щелчка по кнопке pCloseButton срабатывал при нажатии клавиш <ALT>+<Q>, необходимо вызвать метод addShortcut следующим образом:

pCloseButton->addShortcut(KeyPress('q', ModifierKeys::altModifier, 0))

В этом примере мы создали новый объект класса KeyPress, отслеживающего нажатие клавиш клавиатуры, в конструктор которого в качестве параметров передали код "горячей" клавиши ('q') и ее модификатора. Третий параметр — печатаемый символ (в нашем случае равен нулю, т.к. вызывающий виджет не является полем ввода).

В свою очередь, созданный объект класса KeyPress передается в метод addShortcut в качестве параметра. Ниже приведены некоторые идентификаторы перечислимого типа enum ModifierKeys:

  • shiftModifier — флаг нажатия на клавишу <SHIFT>;
  • ctrlModifier — флаг нажатия на клавишу <CTRL>;
  • altModifier — флаг нажатия на клавишу <ALT>.

Помимо этого, ModifierKeys содержит модификаторы, связанные с различными манипуляциями кнопками мыши.

Разумеется, можно зарегистрировать для кнопки "горячую" клавишу безо всякого модификатора. Например, если в качестве параметра в метод addShortcut кнопки "Отменить" передать в качестве параметра KeyPress::escapeKey, то нажатие пользователем клавиши <ESC> будет эквивалентно щелчку по данной кнопке. Это целесообразно делать в различных диалоговых окнах, чтобы пользователь мог их закрывать без использования мыши.

Для того, чтобы отключить все "горячие" клавиши, зарегистрированные для данной кнопки, используют метод void Button::clearShortcuts().

Основное событие любой кнопки — это щелчок по ней. При этом вызывается виртуальный защищенный метод virtual void Button::clicked(). Отслеживает событие щелчка по кнопке ее слушатель, Button::Listener. Именно в его методе virtual void Button::Listener::buttonClicked(Button* button) записываются все операторы, которые должны выполняться при щелчке пользователя по кнопке (см., например, пример 12.1). Метод является чистой виртуальной (pure virtual) функцией и должен быть обязательно переопределен в производном классе.

Практически все, сказанное выше, относится и к другим кнопкам.

ArrowButton — это кнопка со стрелкой в виде треугольника. Поскольку внешний вид (цвет, направление) стрелки задаются один раз при создании кнопки, последняя выполняет исключительно декоративные функции ( рис. 12.2).

Внешний вид кнопки со стрелкой (параметр конструктора arrowDirection принимает значение 0.75; arrowColour — Colours::blue)

Рис. 12.2. Внешний вид кнопки со стрелкой (параметр конструктора arrowDirection принимает значение 0.75; arrowColour — Colours::blue)

Конструктор кнопки ArrowButton::ArrowButton(const String& buttonName, float arrowDirection, const Colour& arrowColour) принимает три параметра:

  • buttonName — имя кнопки;
  • arrowDirection — направление кнопки, где при принимаемом значении 0.0 стрелка направлена вправо, 0.25 — вниз, 0.5 — влево, а 0.75 — вверх;
  • arrowColour — цвет стрелки.

DrawableButton — это кнопка, которая отображает один или несколько объектов класса, производного от Drawable. Drawable — это базовый класс для объектов, которые могут рисовать сами на себе графические примитивы (полигоны) или изображения (например, загруженные из файла). Поскольку Drawable является абстрактным классом, включающим ряд чистых виртуальных функций-членов, на практике используют производный от него класс, DrawableImage объект которого представляет собой битовое изображение (bitmap).

При необходимости возможно использование других производных от Drawable классов, например, DrawableShape или DrawableText.

Конструктор DrawableButton::DrawableButton(const String& buttonName, ButtonStyle buttonStyle) создает "пустую", т.е. не содержащую никаких изображений кнопку.

В качестве параметров конструктор принимает строку — имя кнопки (buttonName) и ее стиль, идентификатор перечислимого типа enum DrawableButton::ButtonStyle.

Стили у DrawableButton могут быть следующими:

  • ImageFitted — кнопка отображает объекты Drawable, изменяя их размеры таким образом, чтобы изображения помещались внутри кнопки;
  • ImageRaw — кнопка показывает изображения с их исходными размерами;
  • ImageAboveTextLabel — кнопка отображает надпись, заданную методом setButtonText, и объект Drawable с размерами, измененными таким образом, чтобы изображение поместилось над надписью рис. 12.4
  • ImageOnButtonBackground — рисуется стандартная для Juce кнопка с наложенным поверх изображением Drawable.

Следует помнить, что программист должен сам позаботиться о соответствии размеров изображения, отображаемого DrawableImage и размеров кнопки DrawableButton.

Рассмотрим использование DrawableButton на простейшем примере, когда кнопка отображает заранее созданные с помощью графического редактора GIMP изображения, загружаемые из файлов в формате *.png, находящихся в каталоге нашей программы ( рис. 12.3).

Изображения для кнопки DrawableButton, подготовленные в GIMP и cохраненные в виде файлов *.png

Рис. 12.3. Изображения для кнопки DrawableButton, подготовленные в GIMP и cохраненные в виде файлов *.png

В качестве основы для нашей программы используем код из вышеприведенного примера, заменив класс у pCloseButton с TextButton на DrawableButton пример 12.2 .

#include "TCentralComponent.h"
//---------------------------------------------------------------------
#define tr(s) String::fromUTF8(s)
//---------------------------------------------------------------------
TCentralComponent::TCentralComponent() : Component ("Central Component"),
                     pHelloLabel(0),
                     pCloseButton(0)
{
  pHelloLabel = new Label("Hello Label", tr("Привет, мир!"));
  addAndMakeVisible(pHelloLabel);
  pHelloLabel->setFont(Font(38.0000f, Font::bold));
  pHelloLabel->setJustificationType(Justification::centred);
  pHelloLabel->setEditable(false, false, false);
  pHelloLabel->setColour(Label::textColourId, Colours::blue);
  pHelloLabel->setColour(TextEditor::textColourId, Colours::black);
  pHelloLabel->setColour(TextEditor::backgroundColourId, Colours::azure);

  // Получаем рабочий каталог программы и сохраняем путь к нему
  // в виде строки
  String sPath = File::getCurrentWorkingDirectory().getFullPathName();
  // Полное имя файла изображения ненажатой кнопки
  String sUp;
  // Полное имя файла изображения нажатой кнопки
  String sDown;

  // Получаем полные имена файлов изображений для Windows и Linux
  #if JUCE_WINDOWS
    sUp = sPath + "\\gimpbutton-up.png";
    sDown = sPath + "\\gimpbutton-down.png";
  #elif JUCE_LINUX
    sUp = sPath + "/gimpbutton-up.png";
    sDown = sPath + "/gimpbutton-down.png";
  #endif

  // Изображение для ненажатой кнопки
  DrawableImage UpImage;
  // Изображение для нажатой кнопки
  DrawableImage DownImage;
  // Загружаем изображение в DrawableImage из соответствующего файла
  UpImage.setImage(ImageCache::getFromFile(File(sUp)));
  DownImage.setImage(ImageCache::getFromFile(File(sDown)));

  // Создаем пустую DrawableButton
  pCloseButton = new DrawableButton("CloseButton",
                    DrawableButton::ImageAboveTextLabel);
  // Устанавливаем изображения для различных состояний кнопки
  pCloseButton->setImages(& UpImage, & UpImage, & DownImage);
  addAndMakeVisible(pCloseButton);
  pCloseButton->setButtonText(tr("Закрыть"));
  pCloseButton->addListener(this);

  setSize (400, 200);
}
//---------------------------------------------------------------------
TCentralComponent::~TCentralComponent()
{
  deleteAllChildren();
}
//---------------------------------------------------------------------
void TCentralComponent::paint(Graphics& Canvas)
{
  Canvas.fillAll(Colours::azure);
}
//---------------------------------------------------------------------
void TCentralComponent::resized()
{
  pHelloLabel->setBounds(0, 0, proportionOfWidth(1.0000f), proportionOfHeight(0.9000f));
  pCloseButton->setBounds(getWidth() - 10 - 204, getHeight() - 60, 204, 53);
}
//---------------------------------------------------------------------
void TCentralComponent::buttonClicked(Button* pButton)
{
  if (pButton == pCloseButton)
  {
    JUCEApplication::quit();
  }
}
//---------------------------------------------------------------------
Листинг 12.2. Реализация класса компонента содержимого TCentralComponent (файл TCentralComponent.cpp)
< Лекция 11 || Лекция 12: 1234 || Лекция 13 >