GTK+ 2.0 Tutorial

<<< Previous

Управление выделениями (Managing Selections)

Next >>>


Замещение выделения

Замещать выделение немного сложнее. Вы должны зарегистрировать обработчики которые будут вызваны по требованию выделения. Для каждой пары selection/target делается вызов:

void gtk_selection_add_target (GtkWidget *widget, GdkAtom selection, GdkAtom target, guint info);

виджет selection и target идентифицируют запросы, которыми этот обработчик будет управлять. Когда получен сигнал о выделении, производится сигнал "selection_get". info может использоваться как нумератор, чтобы идентифицировать определенную цель в пределах функции обратного вызова.

Функция обратного вызова имеет сигнатуру:

void "selection_get" (GtkWidget *widget, GtkSelectionData *selection_data, guint info, guint time);

GtkSelectionData - то же самое как выше, но на сей раз, мы ответственны за то, чем заполнить поля type, format, data и length. ( Фактически важна здесь область формата - сервер X использует это, чтобы выяснить, должны ли данные меняться байтом или нет. Обычно это будет 8 - то есть символ - или 32 - то есть целое число.) Это выполняется вызовом функции:

void gtk_selection_data_set( GtkSelectionData *selection_data, GdkAtom type, gint format, guchar *data, gint length );

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

При запросе пользователя, требуется монопольное использование выделения, вызовом:

gboolean gtk_selection_owner_set( GtkWidget *widget, GdkAtom selection, guint32 time );

Если другое приложение будет требовать монопольного использования выделения, то вы получите "selection_clear_event".

Как пример замещения выделения, следующая программа добавляет функциональные возможности выделения к выключателю. Когда кнопка выключателя вдавлена, программа требует первичного выделения. Поддерживаются только цели "STRING" (кроме определенных целей как "TARGETS" подаваемые непосредственно GTK). Когда цель этого требует, возвращается строка представления времени.

#include <stdlib.h> #include <gtk/gtk.h> #include <time.h> #include <string.h> GtkWidget *selection_button; GtkWidget *selection_widget; /* вызов, когда пользователь переключает выбор */ void selection_toggled( GtkWidget *widget, gint *have_selection ) { if (GTK_TOGGLE_BUTTON (widget)->active) { *have_selection = gtk_selection_owner_set (selection_widget, GDK_SELECTION_PRIMARY, GDK_CURRENT_TIME); /* если требование выделения не состоялось, возвращаем кнопку в состояние выключено */ if (!*have_selection) gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), FALSE); } else { if (*have_selection) { /* Перед очисткой выделения устанавливая владельца в значение NULL, проверяем являемся ли мы фактическим владельцем */ if (gdk_selection_owner_get (GDK_SELECTION_PRIMARY) == widget->window) gtk_selection_owner_set (NULL, GDK_SELECTION_PRIMARY, GDK_CURRENT_TIME); *have_selection = FALSE; } } } /* Вызываем когда другое приложение запросило выделение */ gint selection_clear( GtkWidget *widget, GdkEventSelection *event, gint *have_selection ) { *have_selection = FALSE; gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (selection_button), FALSE); return TRUE; } /* Подставляет текущее время как выделение. */ void selection_handle( GtkWidget *widget, GtkSelectionData *selection_data, guint info, guint time_stamp, gpointer data ) { gchar *timestr; time_t current_time; current_time = time (NULL); timestr = asctime (localtime (&current_time)); /* Когда мы возвращаем единственную строку, это не должен быть нулевой предел. Это делается используя */ gtk_selection_data_set (selection_data, GDK_SELECTION_TYPE_STRING, 8, timestr, strlen (timestr)); } int main( int argc, char *argv[] ) { GtkWidget *window; static int have_selection = FALSE; gtk_init (&argc, &argv); /* Создаём окно верхнего уровня */ window = gtk_window_new (GTK_WINDOW_TOPLEVEL); gtk_window_set_title (GTK_WINDOW (window), "Event Box"); gtk_container_set_border_width (GTK_CONTAINER (window), 10); g_signal_connect (G_OBJECT (window), "destroy", G_CALLBACK (exit), NULL); /* Создаём кнопку переключатель действующую как выделение */ selection_widget = gtk_invisible_new (); selection_button = gtk_toggle_button_new_with_label ("Claim Selection"); gtk_container_add (GTK_CONTAINER (window), selection_button); gtk_widget_show (selection_button); g_signal_connect (G_OBJECT (selection_button), "toggled", G_CALLBACK (selection_toggled), (gpointer) &have_selection); g_signal_connect (G_OBJECT (selection_widget), "selection_clear_event", G_CALLBACK (selection_clear), (gpointer) &have_selection); gtk_selection_add_target (selection_widget, GDK_SELECTION_PRIMARY, GDK_SELECTION_TYPE_STRING, 1); g_signal_connect (G_OBJECT (selection_widget), "selection_get", G_CALLBACK (selection_handle), (gpointer) &have_selection); gtk_widget_show (selection_button); gtk_widget_show (window); gtk_main (); return 0; }

<<< Previous

Home

Next >>>

Retrieving the selection

Up

Drag-and-drop (DND)