замещение
выделения
замещать выделение немного сложнее. вы
должны зарегистрировать обработчики
которые будут вызваны по требованию
выделения. для каждой пары 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 (¤t_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;
}
|
|