Наши партнеры

UnixForum





Библиотека сайта rus-linux.net

Программирование с использованием gtkmm 3. Механизм захвата и перемещения данных (Drag and Drop)

Оригинал: Programming with gtkmm 3
Авторы: Murray Cumming, Bernhard Rieder, Jonathon Jongsma, Ole Laursen, Marko Anastasov, Daniel Elstner, Chris Vine, David King, Pedro Ferreira, Kjell Ahlstedt
Дата публикации: 15 Октября 2013 г.
Перевод: А.Панин
Дата перевода: 28 марта 2014 г.

18. Механизм захвата и перемещения данных (Drag and Drop)

Класс виджета Gtk::Widget содержит реализации нескольких методов и сигналов с префиксом "drag_". Они используются механизмом захвата и перемещения данных в рамках пользовательского интерфейса.

18.1. Источники данных и направления их перемещения

Данные захватываются из источников и перемещаются по направлениям перемещения. Каждый источник данных и каждое направление перемещения данных содержит информацию о доступных для отправки и приема форматах данных, представленную с помощью объектов форматов данных на основе класса Gtk::TargetEntry. Виджет направления перемещения данных будет принимать перемещаемые данные только в том случае, если он содержит совместимый объект формата данных на основе класса Gtk::TargetEntry. После этого произойдет генерация соответствующих сигналов с передачей в обработчики сигналов информации о том, какой объект формата данных на основе класса Gtk::TargetEntry был использован.

Объекты форматов данных на основе класса Gtk::TargetEntry содержат следующую информацию:
  • target (цель): Имя, такое, как "STRING"
  • info (информация): Идентификатор, который будет передан с вашими сигналами для сообщения о том, какой объект формата данных на основе класса Gtk::TargetEntry был использован.
  • flags (флаги): Используются только для операций захвата и перемещения данных и указывают на то, могут ли данные перемещаться на сторонние виджеты и в сторонние приложения или только в одни и те же.

18.2. Методы

Виджеты могут идентифицироваться как источники данных или как направления перемещения данных с помощью следующих методов класса Gtk::Widget:
void drag_source_set(const ArrayHandle_TargetEntry& targets,
      GdkModifierType start_button_mask, GdkDragAction actions);
  • targets является контейнером для экземпляров класса формата данных Gtk::TargetEntry (например, std::list<Gtk::TargetEntry> или std::vector<Gtk::TargetEntyry>).
  • start_button_mask является комбинацией значений, сформированной с помощью побитовой операции "или" и определяющей, какой модификатор клавиатуры или какую кнопку мыши должен нажать пользователь для начала захвата.
  • actions является комбинацией значений, сформированной с помощью побитовой операции "или" и определяющей, какие операции захвата и перемещения могут быть осуществлены при работе с рассматриваемым источником данных - к примеру, копирование, перемещение или установление ссылки. Пользователь может выбрать действие с помощью модификаторов клавиатуры, таких, как модификатор Shift, который предназначен для переключения с режима копирования (copy) на режим переноса данных (move), причем на переключение режима будет указано с помощью отличающегося изображения курсора.
void drag_dest_set(const ArrayHandle_TargetEntry& targets,
    GtkDestDefaults flags, GdkDragAction actions);
  • flags является комбинацией значений, сформированной с помощью побитовой операции "или" и указывающей на то, как виджет должен визуально реагировать на получение данных посредством механизма захвата и перемещения данных.
  • actions указывает на действия в рамках механизма захвата и перемещения данных, которые данный виджет направления перемещения будет выполнять - обратитесь к описанию параметра с аналогичным названием выше.

18.3. Сигналы

После того, как виджет направления перемещения данных принимает перемещаемые данные, будут сгенерированы определенные сигналы в зависимости от того, какое действие было выбрано. Например, пользователь может удерживать клавишу Shift для выполнения операции перемещения (move) вместо копирования (copy). Помните о том, что пользователь может выбрать только те действия, которые вы установили при вызове методов drag_dest_set() и drag_source_set().

18.3.1. Копирование

Виджет источника данных будет генерировать приведенные ниже сигналы в следующем порядке:
  • drag_begin: Передается объект контекста операции DragContext.
  • drag_motion: Передается объект контекста операции DragContext и координаты. Вы можете вызывать метод drag_start() объекта DragContext для указания на то, какое направление перемещения будет использовано.
  • drag_get: Передается целочисленное значение info, указывающее на формат перемещаемых данных, а также структура данных GtkSelectionData, в которую вы должны поместить запрашиваемые данные.
  • drag_drop: Передается объект контекста операции DragContext и координаты.
  • drag_end: Передается объект контекста операции DragContext.
Виджет направления перемещения будет генерировать приведенный ниже сигнал после генерации сигнала "drag_get" виджетом источника данных:
  • drag_data_received: Передается целочисленное значение info с информацией о формате переносимых данных и структура GtkSelectionData, которая содержит переносимые данные. Вы должны вызвать метод drag_finish() объекта контекста операции DragContext для указания но то, что операция была завершена успешно.

18.3.2. Перемещение

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

18.4. Объект контекста операции DragContext

Сигналы, связанные с операциями захвата и перемещения данных, передают в обработчики объект контекста операции DragContext, который содержит некоторую информацию об операции захвата и перемещения данных и может использоваться для оказания влияния на ход процесса. Например, вы можете установить виджет источника данных или изменить иконку операции захвата и перемещения данных с помощью метода set_icon(). Еще более важным аспектом работы с объектом контекста операции является необходимость вызова метода drag_finish() в рамках вашего обработчика сигналов "drag_data_received" для указания на то, была ли операция перемещения данных успешной.

18.5. Пример

Ниже приведен простой пример, демонстрирующий методику использования механизма захвата и перемещения данных для их копирования.

Рисунок 18-1: Механизм захвата и перемещения данных
Механизм захвата и перемещения данных

Исходный код

Файл: dndwindow.h (Для использования совместно с gtkmm 3, а не с gtkmm 2)

Файл: dndwindow.cc (Для использования совместно с gtkmm 3, а не с gtkmm 2)

Файл: main.cc (Для использования совместно с gtkmm 3, а не с gtkmm 2)

Исходный код более сложного примера находится в директории examples/others/dnd.


Следующий раздел : 19. Буфер обмена.