Перевод книги Julian’а Smart’а – Глава IX – Написание собственных диалогов – Часть II

Читать первую часть главы “Написание собственных диалогов”.

Добавление помощи

Существует по крайней мере три пути как можно реализовать помощь для вашего диалога:

  • Всплывающие подсказки
  • Контекстная помощь
  • Справочная система

Кроме того у нас уже есть некоторый текст на самой панели диалога. Возможно вы захотите также использовать другие технологии, явно не поддерживаемые в wxWidgets. Например, для более сложных диалогов вы можете создать wxHtmlWindow вместо wxStaticText и загрузить в него HTML-файл, содержащий необходимое описание. В качестве альтернативы вы можете поместить маленькую кнопку помощи справа от каждого элемента управления, при нажатии на которую выводился бы некоторый текст с описанием.

Три основных типа помощи, поддерживаемые в wxWidgets, описаны далее.

Всплывающие подсказки

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

Контекстная помощь

Контекстная помощь выглядит как небольшое выскакивающее описание, похожее на всплывающие подсказки. Пользователю необходимо сначала нажать на специальную кнопку, а после на элемент управления о котором он хочет узнать или нажать F1, чтобы узнать информацию об элементе на котором в данный момент находится фокус (последнее работает только в системе Windows). В Windows вы можете также определить специальный стиль окна wxDIALOG_EX_CONTEXTHELP, чтобы создать маленькую иконку со знаком вопроса в заголовке окна. На других платформах вы можете создать wxContextHelpButton в диалоге (обычно ее располагают рядом с кнопками “OK” и “Cancel”). В вашем приложении вы должны написать:

#include "wx/cshelp.h"
...
    wxHelpProvider::Set(new wxSimpleHelpProvider);
...

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

// Устанавливаем текст помощи для элементов диалога
void PersonalRecordDialog::SetDialogHelp()
{
    wxString nameHelp = wxT("Enter your full name.");
    wxString ageHelp = wxT("Specify your age.");
    wxString sexHelp = wxT("Specify your gender, male or female.");
    wxString voteHelp = wxT("Check this if you wish to vote.");

    FindWindow(ID_NAME)->SetHelpText(nameHelp);
    FindWindow(ID_NAME)->SetToolTip(nameHelp);

    FindWindow(ID_AGE)->SetHelpText(ageHelp);
    FindWindow(ID_AGE)->SetToolTip(ageHelp);

    FindWindow(ID_SEX)->SetHelpText(sexHelp);
    FindWindow(ID_SEX)->SetToolTip(sexHelp);

    FindWindow(ID_VOTE)->SetHelpText(voteHelp);
    FindWindow(ID_VOTE)->SetToolTip(voteHelp);
}

Если вы хотите реализовать контекстную помощь самостоятельно, позволив диалогу или wxContextHelpButton перехватывать соответствующие запросы, то можно просто написать в обработчике событий:

wxContextHelp contextHelp(window);

Данная команда добавляет дополнительный цикл, который обнаруживает нажатие левой клавиши мыши на элементе управления, после чего посылает сообщение wxEVT_HELP элементу, чтобы инициировать показ контекстной помощи для данного элемента.

Однако вы не обязаны ограничивать себя только возможностями, заложенными в wxWidgets для хранения и показа текста помощи. Вы можете создать свой собственный класс-наследник от wxHelpProvider и реализовать методы GetHelp, SetHelp, AddHelp, RemoveHelp и ShowHelp.

Справочная система

Большая часть приложений поставляется с файлом помощи, в котором находятся детальные инструкции по использованию программы. В wxWidgets для этого есть элементы управления нескольких типов, которые являются наследниками от wxHelpControllerBase. Обратитесь к Главе 20 “Усовершенствование ваших приложений”, за более детальной информацией о том, как реализовать такого вида помощь.

В нашем примере мы просто используем wxMessageBox, чтобы вывести некоторое сообщение, когда пользователь нажмет на кнопку “Help” (Помощь).

BEGIN_EVENT_TABLE( PersonalRecordDialog, wxDialog )
    ...
    EVT_BUTTON( wxID_HELP, PersonalRecordDialog::OnHelpClick )
    ...
END_EVENT_TABLE()

void PersonalRecordDialog::OnHelpClick( wxCommandEvent& event )
{
    // В нормальном приложении мы должны вывести соответствующий раздел помощи
    /*
    wxGetApp().GetHelpController().DisplaySection(wxT("Personal record dialog"));
    */

    // В нашем примере мы просто выводим окно с сообщением
    wxString helpText =
      wxT("Please enter your full name, age and gender.\n")
      wxT("Also indicate your willingness to vote in general elections.\n\n")
      wxT("No non-alphabetical characters are allowed in the name field.\n")
      wxT("Try to be honest about your age.");

    wxMessageBox(helpText,
        wxT("Personal Record Dialog Help"),
        wxOK|wxICON_INFORMATION, this);
}

Полная реализация класса

Полная реализация класса приводится в приложении J “Исходники”, а также в каталоге examples/chap09 на нашем CD-ROM.

Вызов диалога

Теперь, когда диалог поностью закончен, мы можем его вызвать:

PersonalRecordDialog dialog(NULL, ID_PERSONAL_RECORD,
    wxT("Personal Record"));
dialog.SetName(wxEmptyString);
dialog.SetAge(30);
dialog.SetSex(0);
dialog.SetVote(true);
if (dialog.ShowModal() == wxID_OK)
{
    wxString name = dialog.GetName();
    int age = dialog.GetAge();
    bool sex = dialog.GetSex();
    bool vote = dialog.GetVote();
}

Адаптация диалогов для портативных устройств

wxWidgets можно использовать для мобильных и других встраиваемых устройств, используя для этого порты GTK+, X11 и Windows CE (или иные в будущем). Самым важной особенностью таких устройств является ограниченный размер экрана, который для некоторых смартфонов может быть не больше 176×220 пикселей.

Многие диалоги нуждаются в альтернативном (адаптированном для маленьких экранов) размещении элементов, а некоторые элементы управления могут быть объеденены или удалены, особенно в связи с тем, что мобильные версии более ограниченны по сравнению с их десктопными версиями. С помощью метода wxSystemSettings::GetScreenType можно получить полный размер экрана. Например:

#include "wx/settings.h"
bool isPda = (wxSystemSettings::GetScreenType() < = wxSYS_SCREEN_PDA);
[/sourcecode]
GetScreenType возвращает одно из значений, указанных в таблице. Так как целочисленное значение типа растет вместе с величиной экрана, то вы можете использовать оператор целочисленного сравнения, чтобы ограничить работоспособность программы на некоторых платформах, как это сделано, например, в нашем прошлом примере.
  • wxSYS_SCREEN_NONE - Неизвестный тип экрана
  • wxSYS_SCREEN_TINY - Миниатюрный экран, менее 320x240
  • wxSYS_SCREEN_PDA - Экран наладонника, 320x240 или больше, но менее 640x480
  • wxSYS_SCREEN_SMALL - Маленький экран, 640x480 или больше, но менее 800x600
  • wxSYS_SCREEN_DESKTOP - Обычный экран, 800x600 или больше
Если вам необходимо получить точный размер экрана, то существует три способа получить его:
  • Использовать функцию wxSystemSettings::GetMetric[i], передав ей [i]wxSYS_SCREEN_X или wxSYS_SCREEN_Y.
  • Вызвать wxGetDisplaySize, которая возвратит объект типа wxSize.
  • Создать объект wxDisplay и вызвать метод GetGeometry, который возвратит wxRect, содержащий координаты прямоугольника для дисплея.
Теперь, когда вы умеете получать размер экрана, как можно использовать эту информацию? Вот несколько стратегий, которые можно использовать:
  • Заменить весь макет диалога с помощью его загрузки из другого XRC-файла или выполнения другой процедуры создания. Если у элементов не изменится тип, то вам даже не понадобится менять обработчик событий.
  • Уменьшить число элементов управления и расстоянием между ними.
  • Изменить тип некоторых элементов управления, чтобы они занимали на экране меньше места (например, с wxListBox в wxComboBox). Это потребует некоторой модификации кода обработчиков событий.
  • Изменить ориентацию одного или нескольких сайзеров. Некоторые портативные устройства имеют гораздо больше пространства в одном направлении, чем в другом.
Кроме того вам необходимо использовать расширения API для некоторых платформ. Смартфоны Microsoft имею две специальные кнопки, которым можно присвоить некоторые метки, такие как "OK" и "Cancel". На таких платформах вместо создания двух объектов типа wxButton вы должны вызвать wxDialog::SetLeftMenu и wxDialog::SetRightMenu с соответствующим идентификатором, меткой и, возможно, меню. Так как эти функции имеются только в портах для смартфонов, то необходимо добавить операторы включения в ваш код. Например: #ifdef __SMARTPHONE__ SetLeftMenu(wxID_OK, wxT("OK")); SetRightMenu(wxID_OK, wxT("Cancel")); #else wxBoxSizer* buttonSizer = new wxBoxSizer(wxHORIZONTAL); GetTopSizer()->Add(buttonSizer, 0, wxALL|wxGROW, 0); buttonSizer->Add(new wxButton(this, wxID_OK), 0, wxALL, 5); buttonSizer->Add(new wxButton(this, wxID_CANCEL), 0, wxALL, 5); #endif

Читать третью часть главы “Написание собственных диалогов”

2 comments

  1. Pingback: Перевод книги Julian’а Smart’а - Глава IX - Написание собственных диалогов - Часть III | Cross-Platform Programming with wxWidgets

  2. Pingback: Перевод книги Julian’а Smart’а - Глава IX - Написание собственных диалогов - Часть I | Cross-Platform Programming with wxWidgets

Leave a Reply

Your email address will not be published. Required fields are marked *

Please leave these two fields as-is: