The OpenNET Project / Index page

[ новости /+++ | форум | теги | ]

Каталог документации / Раздел "Программирование, языки" / Оглавление документа

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)






Партнёры:
PostgresPro
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2024 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру