Руководство программиста в Photon (1037671), страница 63
Текст из файла (страница 63)
/* Запуск перетаскивания виджета */
/* Стандартные хеадеры */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
/* Инструментальные хеадеры */
#include <Ph.h>
#include <Pt.h>
#include <Ap.h>
/* Локальные хеадеры */
#include "globals.h"
#include "abimport.h"
#include "proto.h"
int start_dragging( PtWidget_t *widget, ApInfo_t *apinfo, PtCallbackInfo_t *cbinfo ) {
PhDim_t *dimension;
PhRect_t rect;
PhRect_t boundary;
/* предотвращает предупреждения (варнинги) об отсутствии ссылок */
widget = widget, apinfo = apinfo, cbinfo = cbinfo;
/* Установка перетаскиваемого прямоугольника в позицию и размеры перетаскиваемого виджета */
PtWidgetExtent (widget, &rect);
/* Установка границ перетаскивания по границам окна */
PtGetResource (ABW_base, Pt_ARG_DIM, &dimension, 0);
boundary.ul.x = 0;
boundary.ul.y = 0;
boundary.lr.x = dimension->w - 1;
boundary.lr.y = dimension->h - 1;
/* Инициализация контурного перетаскивания (Ph_DRAG_TRACK не задано) */
PhInitDrag (PtWidgetRid (ABW_base),
Ph_TRACK_DRAG,
&rect, &boundary,
PhInputGroup( cbinfo->event ),
NULL, NULL, NULL, NULL, NULL );
/* Сохранение указателя на перетаскиваемый виджет */
dragged_widget = widget;
return( Pt_CONTINUE );
}
Вышеописанная ответная реакция добавляется к ответной реакции Arm (Pt_CB_ARM) перетаскиваемого виджета. Это может быть использовано для перетаскивания любого виджета, так что указатель на виджет сохраняется в глобальной переменной dragged_widget.
Непрозрачное перетаскивание
Если Вы хотите использовать непрозрачное перетаскивание, добавьте к вызову PhInitDrag() флаг Ph_DRAG_TRACK():
PhInitDrag( PtWidgetRid (ABW_base),
Ph_TRACK_DRAG | Ph_DRAG_TRACK,
&rect, &boundary,
PhInputGroup( cbinfo->event ),
NULL, NULL, NULL, NULL, NULL );
Обработка событий перетаскивания
Чтобы обработать события перетаскивания (Ph_EV_DRAG), Вам надо определить необработанную (Pt_CB_RAW) или отфильтрованную (Pt_CB_FILTER) ответную реакцию.
Необработанная или отфильтрованная ответная реакция должна быть определена для виджета, чей регион передаётся функции PhInitDrag(), а не для перетаскиваемого виджета. В данном примере необработанная ответная реакция определена для базового окна.
Как описано в разделе "Обработка событий – необработанные и отфильтрованные ответные реакции" в главе "Редактирование ресурсов и ответных реакций в PhAB", чтобы указать, для каких событий вызываются ответные реакции, Вы используете маску событий. Для перетаскивания событием является Ph_EV_DRAG. Наиболее часто используемыми подтипами для этого события являются:
Ph_EV_DRAG_START | Пользователь начал перетаскивание. |
Ph_EV_DRAG_MOVE | Перетаскивание выполняется (только для непрозрачного перетаскивания). |
Ph_EV_DRAG_COMPLETE | Пользователь отпустил кнопку мыши. |
Контурное перетаскивание
Если Вы выполняете контурное перетаскивание, подтипом интересующего Вас события является Ph_EV_DRAG_COMPLETE. Когда случается событие, Ваша ответная реакция должна:
-
Получить данные, связанные с событием. Они представляют из себя структуру PhDragEvent_t, включающую в себе месторасположение перетаскиваемого прямоугольника, в абсолютных координатах. Для более полной информации см. "Справочник библиотечных функций Photon'а".
-
Вычислить новую позицию виджета относительно перетаскиваемого региона. Это позиция верхнего левого угла перетаскиваемого прямоугольника, пересчитанная на величину, заданную в области translation события.
-
Установить ресурс Pt_ARG_POS виджета в новую позицию.
Помните, что параметр widget ответной реакции является указателем на контейнер (базовое окно в нашем примере), а не на перетаскиваемый виджет. Убедитесь, что передали правильный виджет функции PtSetResources() или PtSetResource(), когда устанавливали ресурс Pt_ARG_POS.
Например, вот необработанная ответная реакция для контурного перетаскивания, инициализированного выше:
/* необработанная ответная реакция для обработки событий перетаскивания;
Задайте её для базового окна */
/* Стандартные хеадеры */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
/* Инструментальные хеадеры */
#include <Ph.h>
#include <Pt.h>
#include <Ap.h>
/* Локальные хеадеры */
#include "globals.h"
#include "abimport.h"
#include "proto.h"
int end_dragging( PtWidget_t *widget, ApInfo_t *apinfo, PtCallbackInfo_t *cbinfo ) {
PhDragEvent_t *dragData;
PhPoint_t new_pos;
/* предотвращает предупреждения (варнинги) об отсутствии ссылок */
widget = widget, apinfo = apinfo, cbinfo = cbinfo;
/* Игнорируем все события до тех пор, пока не выполнится перетаскивание */
if (cbinfo->event->subtype != Ph_EV_DRAG_COMPLETE) {
return (Pt_CONTINUE);
}
/* Получаем данные, связанные с событием */
dragData = PhGetData (cbinfo->event);
/* Прямоугольник в этих данных представляет из себя перетаскиваемый прямоугольник
в абсолютных координатах. Мы хотим вычислить новую позицию виджета относительно
перетаскиваемого региона */
new_pos.x = dragData->rect.ul.x + cbinfo->event->translation.x;
new_pos.y = dragData->rect.ul.y + cbinfo->event->translation.y;
printf ("Новая позиция: (%d, %d)\n", new_pos.x, new_pos.y);
/* Перемещаем виджет */
PtSetResource (dragged_widget, Pt_ARG_POS, &new_pos, 0);
return( Pt_CONTINUE );
}
Непрозрачное перетаскивание
Ответная реакция в случае непрозрачного перетаскивания сходна с подобной при контурном перетаскивании: единственное отличие – это подтип обработанного события:
if (cbinfo->event->subtype != Ph_EV_DRAG_MOVE) {
return (Pt_CONTINUE);
}
Глава 24. Управление окнами
Иногда Вам требуется взаимодействовать с оконным менеджером Photon'а, чтобы делать поведение Ваших окон и диалогов таким, каким бы Вам хотелось.
В этой главе обсуждается:
-
Флаги управления окнами
-
Уведомительная ответная реакция
-
Получение и установка состояния окна
-
Управление несколькими окнами
-
Функции управления окнами
-
Исполнение самостоятельного приложения
-
Модальные диалоги
Помните, что оконные и диалоговые модули PhAB'а реализованы как виджеты типа PtWindow. Тип PtWindow имеет много ресурсов, используемых для осуществления взаимодействия с оконным менеджером.
Информацию по регионам оконного менеджера см. в приложении "Архитектура Photon'а". Список относящихся к этому функций см. в разделе "Оконный менеджер" главы "Сводка функций" "Справочника библиотечных функций Photon'а".
Флаги управления окнами
Виджет PtWindow определяет различные типы флагов:
Pt_ARG_WINDOW_RENDER_FLAGS | Какая отделка окна появляется на оконной рамке |
Pt_ARG_WINDOW_MANAGED_FLAGS | Как оконный менеджер работает в окне |
Pt_ARG_WINDOW_NOTIFY_FLAGS | О каких событиях оконного менеджера хотело бы получать уведомление Ваше приложение |
Pt_ARG_WINDOW_STATE | Текущее состояние окна |
Если Вы изменили состояние окна после его реализации, Вы должны знать об этом оконном менеджеру. См. раздел "Получение и установка состояния окна" ниже в этой главе.
Флаги отображения окна
Ресурс Pt_ARG_WINDOW_RENDER_FLAGS задаёт, что появляется на рамке окна.
Чтобы отобразить: | Установите этот бит: | Умолчание |
Рамку | Ph_WM_RENDER_BORDER | Да |
Ручки изменения размеров | Ph_WM_RENDER_RESIZE | Да |
Заголовочный брусок рамки | Ph_WM_RENDER_TITLE | Да |
Кнопку меню | Ph_WM_RENDER_MENU | Да |
Кнопку закрытия | Ph_WM_RENDER_CLOSE | |
Кнопку помощи (значок вопроса) | Ph_WM_RENDER_HELP | |
Кнопку миниминизации | Ph_WM_RENDER_MIN | Да |
Кнопку максимализации | Ph_WM_RENDER_MAX | Да |
Кнопку сворачивания | Ph_WM_RENDER_COLLAPSE | Да |
Дополнительную линию внутри стандартных границ | Ph_WM_RENDER_INLINE |
Использование этих флагов для отображения элементов отделки не приводит к тому, что оконный менеджер делает что-то с этими элементами. Вам может понадобиться установить флаги управления окном и/или флаги уведомления.
Флаги управления окном
Ресурс Pt_ARG_WINDOW_MANAGED_FLAGS задаёт, какие действия должен обрабатывать оконный менеджер:
Чтобы позволить оконному менеджеру: | Установите этот бит: | Умолчание: |
Закрывать окно | Ph_WM_CLOSE | Да |
Дать фокус | Ph_WM_FOCUS | Да |
Построить и управлять оконным меню | Ph_WM_MENU | Да |
Переместить окно вперёд | Ph_WM_TOFRONT | Да |
Переместить окно назад | Ph_WM_TOBACK | Да |
Переместить окно на новую консоль, как будто пользователь переключил консоли | Ph_WM_CONSWITCH | |
Изменить размеры окна | Ph_WM_RESIZE | Да |
Переместить окно | Ph_WM_MOVE | Да |
Скрыть (т.е. минимизировать) окно | Ph_WM_HIDE | Да |
Максимизировать окно | Ph_WM_MAX | Да |
Отобразить окно как фон | Ph_WM_BACKDROP | |
Восстановить окно | Ph_WM_RESTORE | Да |
Обеспечить контекстно-чувствительной помощью | Ph_WM_HELP | |
Сделать окно принудительно передним | Ph_WM_FFRONT | |
Свернуть окно в планку заголовка | Ph_WM_COLLAPSE | |
Защитить Вас от зацикливания фокуса в окне посредством Alt-Esc, Alt-Shift-Esc или Alt-Tab | Ph_WM_NO_FOCUS_LIST |
По умолчанию, выбранными являются флаги в соответствии с набором, определённым в Ph_WM_APP_DEF_MANAGED в <PhWm.h>. Вам надо выключить флаги управления, если Вы:
-
не хотите, чтобы происходила соответствующая операция
-
хотите, чтобы соответствующая операция обрабатывалась приложением. В этом случае Вам понадобится также установить соответствующий флаг уведомления.
Оконные флаги уведомления
Ресурс Pt_ARG_WINDOW_NOTIFY_FLAGS определяет, о какой операции управления окнами должно быть уведомлено Ваше приложение. Этот ресурс использует те же самые биты, что и Pt_ARG_WINDOW_MANAGED_FLAGS:
Быть уведомленным, когда: | Установлен этот бит: | Умолчание: |
Окно было закрыто (см. ниже) | Ph_WM_CLOSE | Да |
Окно получило/потеряло фокус | Ph_WM_FOCUS | |
Оконное меню было запрошено или выключено | Ph_WM_MENU | |
Окно было перемещено вперёд | Ph_WM_TOFRONT | |
Окно было перемещено назад | Ph_WM_TOBACK | |
Окно переключило консоли | Ph_WM_CONSWITCH | |
Размеры окна были изменены | Ph_WM_RESIZE | Да |
Окно было перемещено | Ph_WM_MOVE | |
Окно было скрыто или обратно показано | Ph_WM_HIDE | |
Окно было максимизировано | Ph_WM_MAX | |
Окно было сделано фоновым | Ph_WM_BACKDROP | |
Окно было восстановлено | Ph_WM_RESTORE | |
Была нажата кнопка помощи | Ph_WM_HELP | Да |
Окно было сделано принудительно передним или это было отключено | Ph_WM_FFRONT |
Принимаемым по умолчанию набором является
Ph_WM_RESIZE | Ph_WM__CLOSE | Ph_WM_HELP.