⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gtk_tut_it-20.html

📁 gtk是linux一款强大的夸平台的图形化开发工具
💻 HTML
📖 第 1 页 / 共 3 页
字号:
      inputd = gtk_input_dialog_new();      gtk_signal_connect (GTK_OBJECT(inputd), "destroy",                          (GtkSignalFunc)input_dialog_destroy, &amp;inputd);      gtk_signal_connect_object (GTK_OBJECT(GTK_INPUT_DIALOG(inputd)->close_button),                                 "clicked",                                 (GtkSignalFunc)gtk_widget_hide,                                 GTK_OBJECT(inputd));      gtk_widget_hide ( GTK_INPUT_DIALOG(inputd)->save_button);      gtk_widget_show (inputd);    }  else    {      if (!GTK_WIDGET_MAPPED(inputd))        gtk_widget_show(inputd);      else        gdk_window_raise(inputd->window);    }}</PRE></CODE></BLOCKQUOTE><P>(Notate come gestiamo questo dialogo. Con la connessione del segnale``destroy'' ci assicuriamo di non tenerci in giro il puntatore al dialogodopo che lo abbiamo distrutto, cosa che potrebbe portare ad un errore disegmentazione.)<P><P>L'InputDialog ha due pulsanti, ``Close'' e ``Save'', i quali non hanno alcunaazione predefinita assegnata ad essi. Nella funzione precedente, abbiamofatto in modo che ``Close'' nasconda la finestra di dialogo, e abbiamo nascostoil pulsante ``Save'' dal momento che in questo programma non implementiamo ilsalvataggio delle opzioni di XInput.<P><H3>Usare le informazioni estese</H3><P>Una volta abilitato il dipositivo, possiamo usare le informazioni esteseche si trovano nei corrispondenti campi delle strutture che descrivono glieventi. A dire il vero, l'utilizzo di questi campi &egrave; sempre sicuro, perch&eacute;sono tutti posti per difetto a valori ragionevoli ancje quando la gestionedegli eventi estesi non &egrave; abilitata.<P><P>Un cambiamento che dobbiamo fare &egrave; di chiamare <CODE>gdk_input_window_get_pointer()</CODE>invece di <CODE>gdk_window_get_pointer</CODE>. Ci&ograve; si rende necessario perch&eacute;<CODE>gdk_window_get_pointer</CODE> non restituisce le informazioni esetese.<P><BLOCKQUOTE><CODE><PRE>void gdk_input_window_get_pointer     (GdkWindow       *window,                                       guint32         deviceid,                                       gdouble         *x,                                       gdouble         *y,                                       gdouble         *pressure,                                       gdouble         *xtilt,                                       gdouble         *ytilt,                                       GdkModifierType *mask);</PRE></CODE></BLOCKQUOTE><P>Quando chiamiamo questa funzione, dobbiamo specificare l'identificativodel dispositivo e la finestra. Normalmente questo identificativo lo siottiene dal campo <CODE>deviceid</CODE> della struttura dell'evento.Questa funzione restituir&agrave; valori ragionevoli nel caso che la gestionedegli eventi estesi non sia attivata (in questo caso, <CODE>event->deviceid</CODE>avr&agrave; il valore <CODE>GDK_CORE_POINTER</CODE>).<P>Quindi, la struttura di base dei gestori degli eventi relativi allapressione di bottoni e ai movomenti non cambia molto - abbiamo solobisogno di aggiungere il codice necessario per tenere conto delleinformazioni estese.<P><BLOCKQUOTE><CODE><PRE>static gintbutton_press_event (GtkWidget *widget, GdkEventButton *event){  print_button_press (event->deviceid);    if (event->button == 1 &amp;&amp; pixmap != NULL)    draw_brush (widget, event->source, event->x, event->y, event->pressure);  return TRUE;}static gintmotion_notify_event (GtkWidget *widget, GdkEventMotion *event){  gdouble x, y;  gdouble pressure;  GdkModifierType state;  if (event->is_hint)    gdk_input_window_get_pointer (event->window, event->deviceid,                                  &amp;x, &amp;y, &amp;pressure, NULL, NULL, &amp;state);  else    {      x = event->x;      y = event->y;      pressure = event->pressure;      state = event->state;    }      if (state &amp; GDK_BUTTON1_MASK &amp;&amp; pixmap != NULL)    draw_brush (widget, event->source, x, y, pressure);    return TRUE;}</PRE></CODE></BLOCKQUOTE><P>Avremo anche bisogno di fare qualcosa con queste nuove informazioni. Lanostra nuova funzione <CODE>draw_brush</CODE> disegna con un colore diverso perogni <CODE>event->source</CODE> e cambia la dimensione della linea in funzionedella pressione.<P><BLOCKQUOTE><CODE><PRE>/* Disegna un rettangolo sullo schermo, con la dimensione dipendente   dalla pressione e il colore dipendente dal tipo di dispositivo */static voiddraw_brush (GtkWidget *widget, GdkInputSource source,            gdouble x, gdouble y, gdouble pressure){  GdkGC *gc;  GdkRectangle update_rect;  switch (source)    {    case GDK_SOURCE_MOUSE:      gc = widget->style->dark_gc[GTK_WIDGET_STATE (widget)];      break;    case GDK_SOURCE_PEN:      gc = widget->style->black_gc;      break;    case GDK_SOURCE_ERASER:      gc = widget->style->white_gc;      break;    default:      gc = widget->style->light_gc[GTK_WIDGET_STATE (widget)];    }  update_rect.x = x - 10 * pressure;  update_rect.y = y - 10 * pressure;  update_rect.width = 20 * pressure;  update_rect.height = 20 * pressure;  gdk_draw_rectangle (pixmap, gc, TRUE,                      update_rect.x, update_rect.y,                      update_rect.width, update_rect.height);  gtk_widget_draw (widget, &amp;update_rect);}</PRE></CODE></BLOCKQUOTE><P><H3>Trovare ulteriori informazioni su di un dispositivo</H3><P>Come esempio del modo di trovare altre informazioni su di un dispositivo,il nostro programma stamper&agrave; il nome di ogni dispositivo che genera unevento di pressione di un pulsante. Per avere il nome di un dispositivo,chiamiamo la funzione<P><BLOCKQUOTE><CODE><PRE>GList *gdk_input_list_devices               (void);</PRE></CODE></BLOCKQUOTE><P>che restituisce una GList (un tipo di lista collegata che si trova nellalibreria glib) di strutture di tipo GdkDeviceInfo. La definizione diGdkDeviceInfo &egrave; la seguente:<P><BLOCKQUOTE><CODE><PRE>struct _GdkDeviceInfo{  guint32 deviceid;  gchar *name;  GdkInputSource source;  GdkInputMode mode;  gint has_cursor;  gint num_axes;  GdkAxisUse *axes;  gint num_keys;  GdkDeviceKey *keys;};</PRE></CODE></BLOCKQUOTE><P>La maggior parte di questi campi rappresentano informazioni di configurazioneche potete ignorare a meno che non implementiate il salvataggio dellaconfigurazione di un XInput. Quelle che ci interessano sono <CODE>name</CODE>, che&egrave; semplicemente il nome che X assegna al dispositivo, e <CODE>has_cursor</CODE>. Anche<CODE>has_cursor</CODE> non &egrave; informazione di configurazione, e indica, nel casoabbia valore ``falso'', che dobbiamo disegnare da soli il nostro cursore. Madal momento che abbiamo specificato <CODE>GDK_EXTENSION_EVENTS_CURSOR</CODE>,possiamo anche non preoccuparcene.<P><P><P>La nostra funzione <CODE>print_button_press()</CODE> scorre semplicemente la listache &egrave; stata restituita finch&eacute; non trova il valore corretto, e poi stampail nome del dispositivo.<P><BLOCKQUOTE><CODE><PRE>static voidprint_button_press (guint32 deviceid){  GList *tmp_list;  /* gdk_input_list_devices restituisce una lista interna, cos&igrave; poi     non dobbiamo liberarla */  tmp_list = gdk_input_list_devices();  while (tmp_list)    {      GdkDeviceInfo *info = (GdkDeviceInfo *)tmp_list->data;      if (info->deviceid == deviceid)        {          printf("Button press on device '%s'\n", info->name);          return;        }      tmp_list = tmp_list->next;    }}</PRE></CODE></BLOCKQUOTE>Questo completa i cambiamenti necessari per usare gli XInput nel nostroprogramma. Come per la prima versione, i sorgenti completi sono prelevabilida dove avete prelevato questo tutorial, oppure da:<P><A HREF="http://www.msc.cornell.edu/~otaylor/gtk-gimp/tutorial">http://www.msc.cornell.edu/~otaylor/gtk-gimp/tutorial</A><P><H3><A NAME="sec_Further_Sophistications"></A> Ulteriori sofisticazioni </H3><P>Anche se ora il nostro programma supporta XInput pittosto bene, gli mancanoalcune caratteristiche che probabilmente vorremmo mettere in una applicazionecompleta. In primo luogo, probabilmente all'utente non far&agrave; piacere doverconfigurare i propri dispositivi ogni volta che lanciano il programma, percui dovremmo dare la possibilit&agrave; di salvare la configurazione dei dispositivi.Ci&ograve; pu&ograve; essere fatto scorrendo la lista restituita da <CODE>gdk_input_list_devices()</CODE>e scrivendo la configurazione su di un file.<P><P>Per tornare allo stato salvato la prossima volta che il programma vieneeseguito, GDK mette a disposizione delle funzioni per cambiare la configurazionedei dispositivi:<P><BLOCKQUOTE><CODE><PRE>gdk_input_set_extension_events()gdk_input_set_source()gdk_input_set_mode()gdk_input_set_axes()gdk_input_set_key()</PRE></CODE></BLOCKQUOTE><P>(La lista restituita da <CODE>gdk_input_list_devices()</CODE> non dovrebbeessere modificata direttamente.) Un esempio di come fare pu&ograve; esseretrovato nel programma di disegno gsumi (disponibile da <A HREF="http://www.msc.cornell.edu/~otaylor/gsumi/">http://www.msc.cornell.edu/~otaylor/gsumi/</A>). Sarebbe belloavere alla fine un modo standard di recuperare le informazioni per tuttele applicazioni. Questo probabilmente appartiene ad un livello un po'pi&ugrave; elevato ripetto a GTK, forse alla libreria GNOME.<P><P>Un'altra notevole omissione a cui abbiamo accennato precedentemente &egrave; ilfatto di non disegnare il cursore direttamente. Piattaforme diverse daXFree86 non permettono in questo momento di usare contemporaneamente undispositivo sia come puntatore principale sia direttamente da unaapplicazione. Vedere  <A HREF="http://www.msc.cornell.edu/~otaylor/xinput/XInput-HOWTO.html">XInput-HOWTO</A> per ulteriori informazioni. Ci&ograve; significa che leapplicazioni che vogliono rivolgersi al pubblico pi&ugrave; ampio dovranno prevederedi disegnare esse stesse il proprio cursore.<P><P>Un'applicazione che voglia disegnare il proprio cursore dovr&agrave; fare due cose:determinare se il dispositivo corrente necessita che venga disegnato uncursore, e determinare se il dispositivo corrente &egrave; in prossimit&agrave;. (Se ildispositivo &egrave; una tavoletta grafica, un tocco di finezza &egrave; fare sparireil puntatore quando lo stilo viene sollevato dalla tavoletta. Quando c'&egrave;contatto fra lo stilo e la tavoletta, si dice che il dispositivo &egrave; ``inprossimit&agrave;".) La prima cosa viene fatta scorrendo la lista dei dispositivi,come abbiamo fatto per trovare il nome del dispositivo. La seconda cosaviene ottenuta selezionando gli eventi ``proximity_out''. Un esempio didisegno del proprio cursore si trova nel programma 'testinput' incluso nelladistribuzione di GTK.<P><HR NOSHADE><A HREF="gtk_tut_it-21.html">Avanti</A><A HREF="gtk_tut_it-19.html">Indietro</A><A HREF="gtk_tut_it.html#toc20">Indice</A></BODY></HTML>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -